Improve aac decoder selection
This commit is contained in:
parent
b395efe804
commit
337ac73915
|
@ -56,6 +56,9 @@ class DecoderBase {
|
||||||
public:
|
public:
|
||||||
virtual ~DecoderBase();
|
virtual ~DecoderBase();
|
||||||
virtual std::optional<BinaryResponse> ProcessRequest(const BinaryRequest& request) = 0;
|
virtual std::optional<BinaryResponse> ProcessRequest(const BinaryRequest& request) = 0;
|
||||||
|
/// Return true if this Decoder can be loaded. Return false if the system cannot create the
|
||||||
|
/// decoder
|
||||||
|
virtual bool IsValid() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class NullDecoder final : public DecoderBase {
|
class NullDecoder final : public DecoderBase {
|
||||||
|
@ -63,6 +66,9 @@ public:
|
||||||
NullDecoder();
|
NullDecoder();
|
||||||
~NullDecoder() override;
|
~NullDecoder() override;
|
||||||
std::optional<BinaryResponse> ProcessRequest(const BinaryRequest& request) override;
|
std::optional<BinaryResponse> ProcessRequest(const BinaryRequest& request) override;
|
||||||
|
bool IsValid() const override {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::HLE
|
} // namespace AudioCore::HLE
|
||||||
|
|
|
@ -12,6 +12,9 @@ public:
|
||||||
explicit Impl(Memory::MemorySystem& memory);
|
explicit Impl(Memory::MemorySystem& memory);
|
||||||
~Impl();
|
~Impl();
|
||||||
std::optional<BinaryResponse> ProcessRequest(const BinaryRequest& request);
|
std::optional<BinaryResponse> ProcessRequest(const BinaryRequest& request);
|
||||||
|
bool IsValid() const {
|
||||||
|
return initalized;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::optional<BinaryResponse> Initalize(const BinaryRequest& request);
|
std::optional<BinaryResponse> Initalize(const BinaryRequest& request);
|
||||||
|
@ -261,4 +264,8 @@ std::optional<BinaryResponse> FFMPEGDecoder::ProcessRequest(const BinaryRequest&
|
||||||
return impl->ProcessRequest(request);
|
return impl->ProcessRequest(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FFMPEGDecoder::IsValid() const {
|
||||||
|
return impl->IsValid();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::HLE
|
} // namespace AudioCore::HLE
|
||||||
|
|
|
@ -13,6 +13,7 @@ public:
|
||||||
explicit FFMPEGDecoder(Memory::MemorySystem& memory);
|
explicit FFMPEGDecoder(Memory::MemorySystem& memory);
|
||||||
~FFMPEGDecoder() override;
|
~FFMPEGDecoder() override;
|
||||||
std::optional<BinaryResponse> ProcessRequest(const BinaryRequest& request) override;
|
std::optional<BinaryResponse> ProcessRequest(const BinaryRequest& request) override;
|
||||||
|
bool IsValid() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Impl;
|
class Impl;
|
||||||
|
|
|
@ -87,15 +87,27 @@ DspHle::Impl::Impl(DspHle& parent_, Memory::MemorySystem& memory) : parent(paren
|
||||||
source.SetMemory(memory);
|
source.SetMemory(memory);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_MF
|
#if defined(HAVE_MF) && defined(HAVE_FFMPEG)
|
||||||
decoder = std::make_unique<HLE::WMFDecoder>(memory);
|
decoder = std::make_unique<HLE::WMFDecoder>(memory);
|
||||||
#elif HAVE_FFMPEG
|
if (!decoder->IsValid()) {
|
||||||
|
LOG_WARNING(Audio_DSP, "Unable to load MediaFoundation. Attempting to load FFMPEG instead");
|
||||||
|
decoder = std::make_unique<HLE::FFMPEGDecoder>(memory);
|
||||||
|
}
|
||||||
|
#elif defined(HAVE_MF)
|
||||||
|
decoder = std::make_unique<HLE::WMFDecoder>(memory);
|
||||||
|
#elif defined(HAVE_FFMPEG)
|
||||||
decoder = std::make_unique<HLE::FFMPEGDecoder>(memory);
|
decoder = std::make_unique<HLE::FFMPEGDecoder>(memory);
|
||||||
#else
|
#else
|
||||||
LOG_WARNING(Audio_DSP, "No decoder found, this could lead to missing audio");
|
LOG_WARNING(Audio_DSP, "No decoder found, this could lead to missing audio");
|
||||||
decoder = std::make_unique<HLE::NullDecoder>();
|
decoder = std::make_unique<HLE::NullDecoder>();
|
||||||
#endif // HAVE_MF
|
#endif // HAVE_MF
|
||||||
|
|
||||||
|
if (!decoder->IsValid()) {
|
||||||
|
LOG_WARNING(Audio_DSP,
|
||||||
|
"Unable to load any decoders, this could cause missing audio in some games");
|
||||||
|
decoder = std::make_unique<HLE::NullDecoder>();
|
||||||
|
}
|
||||||
|
|
||||||
Core::Timing& timing = Core::System::GetInstance().CoreTiming();
|
Core::Timing& timing = Core::System::GetInstance().CoreTiming();
|
||||||
tick_event =
|
tick_event =
|
||||||
timing.RegisterEvent("AudioCore::DspHle::tick_event", [this](u64, s64 cycles_late) {
|
timing.RegisterEvent("AudioCore::DspHle::tick_event", [this](u64, s64 cycles_late) {
|
||||||
|
|
|
@ -14,6 +14,9 @@ public:
|
||||||
explicit Impl(Memory::MemorySystem& memory);
|
explicit Impl(Memory::MemorySystem& memory);
|
||||||
~Impl();
|
~Impl();
|
||||||
std::optional<BinaryResponse> ProcessRequest(const BinaryRequest& request);
|
std::optional<BinaryResponse> ProcessRequest(const BinaryRequest& request);
|
||||||
|
bool IsValid() const {
|
||||||
|
return is_valid;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::optional<BinaryResponse> Initalize(const BinaryRequest& request);
|
std::optional<BinaryResponse> Initalize(const BinaryRequest& request);
|
||||||
|
@ -30,6 +33,9 @@ private:
|
||||||
unique_mfptr<IMFTransform> transform;
|
unique_mfptr<IMFTransform> transform;
|
||||||
DWORD in_stream_id = 0;
|
DWORD in_stream_id = 0;
|
||||||
DWORD out_stream_id = 0;
|
DWORD out_stream_id = 0;
|
||||||
|
bool is_valid = false;
|
||||||
|
bool mf_started = false;
|
||||||
|
bool coinited = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
WMFDecoder::Impl::Impl(Memory::MemorySystem& memory) : memory(memory) {
|
WMFDecoder::Impl::Impl(Memory::MemorySystem& memory) : memory(memory) {
|
||||||
|
@ -45,6 +51,8 @@ WMFDecoder::Impl::Impl(Memory::MemorySystem& memory) : memory(memory) {
|
||||||
// S_FALSE will be returned when COM has already been initialized
|
// S_FALSE will be returned when COM has already been initialized
|
||||||
if (hr != S_OK && hr != S_FALSE) {
|
if (hr != S_OK && hr != S_FALSE) {
|
||||||
ReportError("Failed to start COM components", hr);
|
ReportError("Failed to start COM components", hr);
|
||||||
|
} else {
|
||||||
|
coinited = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// lite startup is faster and all what we need is included
|
// lite startup is faster and all what we need is included
|
||||||
|
@ -52,6 +60,8 @@ WMFDecoder::Impl::Impl(Memory::MemorySystem& memory) : memory(memory) {
|
||||||
if (hr != S_OK) {
|
if (hr != S_OK) {
|
||||||
// Do you know you can't initialize MF in test mode or safe mode?
|
// Do you know you can't initialize MF in test mode or safe mode?
|
||||||
ReportError("Failed to initialize Media Foundation", hr);
|
ReportError("Failed to initialize Media Foundation", hr);
|
||||||
|
} else {
|
||||||
|
mf_started = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_INFO(Audio_DSP, "Media Foundation activated");
|
LOG_INFO(Audio_DSP, "Media Foundation activated");
|
||||||
|
@ -73,6 +83,7 @@ WMFDecoder::Impl::Impl(Memory::MemorySystem& memory) : memory(memory) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
transform_initialized = true;
|
transform_initialized = true;
|
||||||
|
is_valid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
WMFDecoder::Impl::~Impl() {
|
WMFDecoder::Impl::~Impl() {
|
||||||
|
@ -82,8 +93,12 @@ WMFDecoder::Impl::~Impl() {
|
||||||
// otherwise access violation will occur
|
// otherwise access violation will occur
|
||||||
transform.reset();
|
transform.reset();
|
||||||
}
|
}
|
||||||
MFDecoder::MFShutdown();
|
if (mf_started) {
|
||||||
CoUninitialize();
|
MFDecoder::MFShutdown();
|
||||||
|
}
|
||||||
|
if (coinited) {
|
||||||
|
CoUninitialize();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<BinaryResponse> WMFDecoder::Impl::ProcessRequest(const BinaryRequest& request) {
|
std::optional<BinaryResponse> WMFDecoder::Impl::ProcessRequest(const BinaryRequest& request) {
|
||||||
|
@ -121,8 +136,8 @@ std::optional<BinaryResponse> WMFDecoder::Impl::Initalize(const BinaryRequest& r
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
MFDecoder::MFOutputState WMFDecoder::Impl::DecodingLoop(
|
MFOutputState WMFDecoder::Impl::DecodingLoop(ADTSData adts_header,
|
||||||
ADTSData adts_header, std::array<std::vector<u8>, 2>& out_streams) {
|
std::array<std::vector<u8>, 2>& out_streams) {
|
||||||
MFOutputState output_status = MFOutputState::OK;
|
MFOutputState output_status = MFOutputState::OK;
|
||||||
std::optional<std::vector<f32>> output_buffer;
|
std::optional<std::vector<f32>> output_buffer;
|
||||||
unique_mfptr<IMFSample> output;
|
unique_mfptr<IMFSample> output;
|
||||||
|
@ -280,4 +295,8 @@ std::optional<BinaryResponse> WMFDecoder::ProcessRequest(const BinaryRequest& re
|
||||||
return impl->ProcessRequest(request);
|
return impl->ProcessRequest(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool WMFDecoder::IsValid() const {
|
||||||
|
return impl->IsValid();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::HLE
|
} // namespace AudioCore::HLE
|
||||||
|
|
|
@ -13,6 +13,7 @@ public:
|
||||||
explicit WMFDecoder(Memory::MemorySystem& memory);
|
explicit WMFDecoder(Memory::MemorySystem& memory);
|
||||||
~WMFDecoder() override;
|
~WMFDecoder() override;
|
||||||
std::optional<BinaryResponse> ProcessRequest(const BinaryRequest& request) override;
|
std::optional<BinaryResponse> ProcessRequest(const BinaryRequest& request) override;
|
||||||
|
bool IsValid() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Impl;
|
class Impl;
|
||||||
|
|
Reference in New Issue