mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	Improve aac decoder selection
This commit is contained in:
		
							parent
							
								
									b395efe804
								
							
						
					
					
						commit
						337ac73915
					
				
					 6 changed files with 52 additions and 6 deletions
				
			
		|  | @ -56,6 +56,9 @@ class DecoderBase { | |||
| public: | ||||
|     virtual ~DecoderBase(); | ||||
|     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 { | ||||
|  | @ -63,6 +66,9 @@ public: | |||
|     NullDecoder(); | ||||
|     ~NullDecoder() override; | ||||
|     std::optional<BinaryResponse> ProcessRequest(const BinaryRequest& request) override; | ||||
|     bool IsValid() const override { | ||||
|         return true; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| } // namespace AudioCore::HLE
 | ||||
|  |  | |||
|  | @ -12,6 +12,9 @@ public: | |||
|     explicit Impl(Memory::MemorySystem& memory); | ||||
|     ~Impl(); | ||||
|     std::optional<BinaryResponse> ProcessRequest(const BinaryRequest& request); | ||||
|     bool IsValid() const { | ||||
|         return initalized; | ||||
|     } | ||||
| 
 | ||||
| private: | ||||
|     std::optional<BinaryResponse> Initalize(const BinaryRequest& request); | ||||
|  | @ -261,4 +264,8 @@ std::optional<BinaryResponse> FFMPEGDecoder::ProcessRequest(const BinaryRequest& | |||
|     return impl->ProcessRequest(request); | ||||
| } | ||||
| 
 | ||||
| bool FFMPEGDecoder::IsValid() const { | ||||
|     return impl->IsValid(); | ||||
| } | ||||
| 
 | ||||
| } // namespace AudioCore::HLE
 | ||||
|  |  | |||
|  | @ -13,6 +13,7 @@ public: | |||
|     explicit FFMPEGDecoder(Memory::MemorySystem& memory); | ||||
|     ~FFMPEGDecoder() override; | ||||
|     std::optional<BinaryResponse> ProcessRequest(const BinaryRequest& request) override; | ||||
|     bool IsValid() const override; | ||||
| 
 | ||||
| private: | ||||
|     class Impl; | ||||
|  |  | |||
|  | @ -87,15 +87,27 @@ DspHle::Impl::Impl(DspHle& parent_, Memory::MemorySystem& memory) : parent(paren | |||
|         source.SetMemory(memory); | ||||
|     } | ||||
| 
 | ||||
| #ifdef HAVE_MF | ||||
| #if defined(HAVE_MF) && defined(HAVE_FFMPEG) | ||||
|     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); | ||||
| #else | ||||
|     LOG_WARNING(Audio_DSP, "No decoder found, this could lead to missing audio"); | ||||
|     decoder = std::make_unique<HLE::NullDecoder>(); | ||||
| #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(); | ||||
|     tick_event = | ||||
|         timing.RegisterEvent("AudioCore::DspHle::tick_event", [this](u64, s64 cycles_late) { | ||||
|  |  | |||
|  | @ -14,6 +14,9 @@ public: | |||
|     explicit Impl(Memory::MemorySystem& memory); | ||||
|     ~Impl(); | ||||
|     std::optional<BinaryResponse> ProcessRequest(const BinaryRequest& request); | ||||
|     bool IsValid() const { | ||||
|         return is_valid; | ||||
|     } | ||||
| 
 | ||||
| private: | ||||
|     std::optional<BinaryResponse> Initalize(const BinaryRequest& request); | ||||
|  | @ -30,6 +33,9 @@ private: | |||
|     unique_mfptr<IMFTransform> transform; | ||||
|     DWORD in_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) { | ||||
|  | @ -45,6 +51,8 @@ WMFDecoder::Impl::Impl(Memory::MemorySystem& memory) : memory(memory) { | |||
|     // S_FALSE will be returned when COM has already been initialized
 | ||||
|     if (hr != S_OK && hr != S_FALSE) { | ||||
|         ReportError("Failed to start COM components", hr); | ||||
|     } else { | ||||
|         coinited = true; | ||||
|     } | ||||
| 
 | ||||
|     // 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) { | ||||
|         // Do you know you can't initialize MF in test mode or safe mode?
 | ||||
|         ReportError("Failed to initialize Media Foundation", hr); | ||||
|     } else { | ||||
|         mf_started = true; | ||||
|     } | ||||
| 
 | ||||
|     LOG_INFO(Audio_DSP, "Media Foundation activated"); | ||||
|  | @ -73,6 +83,7 @@ WMFDecoder::Impl::Impl(Memory::MemorySystem& memory) : memory(memory) { | |||
|         return; | ||||
|     } | ||||
|     transform_initialized = true; | ||||
|     is_valid = true; | ||||
| } | ||||
| 
 | ||||
| WMFDecoder::Impl::~Impl() { | ||||
|  | @ -82,8 +93,12 @@ WMFDecoder::Impl::~Impl() { | |||
|         // otherwise access violation will occur
 | ||||
|         transform.reset(); | ||||
|     } | ||||
|     MFDecoder::MFShutdown(); | ||||
|     CoUninitialize(); | ||||
|     if (mf_started) { | ||||
|         MFDecoder::MFShutdown(); | ||||
|     } | ||||
|     if (coinited) { | ||||
|         CoUninitialize(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| std::optional<BinaryResponse> WMFDecoder::Impl::ProcessRequest(const BinaryRequest& request) { | ||||
|  | @ -121,8 +136,8 @@ std::optional<BinaryResponse> WMFDecoder::Impl::Initalize(const BinaryRequest& r | |||
|     return response; | ||||
| } | ||||
| 
 | ||||
| MFDecoder::MFOutputState WMFDecoder::Impl::DecodingLoop( | ||||
|     ADTSData adts_header, std::array<std::vector<u8>, 2>& out_streams) { | ||||
| MFOutputState WMFDecoder::Impl::DecodingLoop(ADTSData adts_header, | ||||
|                                              std::array<std::vector<u8>, 2>& out_streams) { | ||||
|     MFOutputState output_status = MFOutputState::OK; | ||||
|     std::optional<std::vector<f32>> output_buffer; | ||||
|     unique_mfptr<IMFSample> output; | ||||
|  | @ -280,4 +295,8 @@ std::optional<BinaryResponse> WMFDecoder::ProcessRequest(const BinaryRequest& re | |||
|     return impl->ProcessRequest(request); | ||||
| } | ||||
| 
 | ||||
| bool WMFDecoder::IsValid() const { | ||||
|     return impl->IsValid(); | ||||
| } | ||||
| 
 | ||||
| } // namespace AudioCore::HLE
 | ||||
|  |  | |||
|  | @ -13,6 +13,7 @@ public: | |||
|     explicit WMFDecoder(Memory::MemorySystem& memory); | ||||
|     ~WMFDecoder() override; | ||||
|     std::optional<BinaryResponse> ProcessRequest(const BinaryRequest& request) override; | ||||
|     bool IsValid() const override; | ||||
| 
 | ||||
| private: | ||||
|     class Impl; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue