Improve aac decoder selection

This commit is contained in:
James Rowe 2019-12-08 14:19:19 -07:00
parent b395efe804
commit 337ac73915
6 changed files with 52 additions and 6 deletions

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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) {

View file

@ -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,9 +93,13 @@ WMFDecoder::Impl::~Impl() {
// otherwise access violation will occur // otherwise access violation will occur
transform.reset(); transform.reset();
} }
if (mf_started) {
MFDecoder::MFShutdown(); MFDecoder::MFShutdown();
}
if (coinited) {
CoUninitialize(); CoUninitialize();
} }
}
std::optional<BinaryResponse> WMFDecoder::Impl::ProcessRequest(const BinaryRequest& request) { std::optional<BinaryResponse> WMFDecoder::Impl::ProcessRequest(const BinaryRequest& request) {
if (request.codec != DecoderCodec::AAC) { if (request.codec != DecoderCodec::AAC) {
@ -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

View file

@ -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;