mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	audio_core: hle: mf: conform to RAII as possible
This commit is contained in:
		
							parent
							
								
									f0e041e27a
								
							
						
					
					
						commit
						6178cc08b7
					
				
					 3 changed files with 38 additions and 59 deletions
				
			
		|  | @ -16,14 +16,12 @@ public: | |||
| private: | ||||
|     std::optional<BinaryResponse> Initalize(const BinaryRequest& request); | ||||
| 
 | ||||
|     void Clear(); | ||||
| 
 | ||||
|     std::optional<BinaryResponse> Decode(const BinaryRequest& request); | ||||
| 
 | ||||
|     MFOutputState DecodingLoop(ADTSData adts_header, std::array<std::vector<u8>, 2>& out_streams); | ||||
| 
 | ||||
|     bool initialized = false; | ||||
|     bool selected = false; | ||||
|     bool transform_initialized = false; | ||||
|     bool format_selected = false; | ||||
| 
 | ||||
|     Memory::MemorySystem& memory; | ||||
| 
 | ||||
|  | @ -32,10 +30,35 @@ private: | |||
|     DWORD out_stream_id = 0; | ||||
| }; | ||||
| 
 | ||||
| WMFDecoder::Impl::Impl(Memory::MemorySystem& memory) : memory(memory) {} | ||||
| WMFDecoder::Impl::Impl(Memory::MemorySystem& memory) : memory(memory) { | ||||
|     HRESULT hr = S_OK; | ||||
|     hr = CoInitialize(NULL); | ||||
|     // 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); | ||||
|     } | ||||
| 
 | ||||
|     // lite startup is faster and all what we need is included
 | ||||
|     hr = MFStartup(MF_VERSION, MFSTARTUP_LITE); | ||||
|     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); | ||||
|     } | ||||
| 
 | ||||
|     LOG_INFO(Audio_DSP, "Media Foundation activated"); | ||||
| } | ||||
| 
 | ||||
| WMFDecoder::Impl::~Impl() { | ||||
|     Clear(); | ||||
|     if (transform_initialized) { | ||||
|         MFFlush(transform.get()); | ||||
|         // delete the transform object before shutting down MF
 | ||||
|         // otherwise access violation will occur
 | ||||
|         transform.reset(); | ||||
|         MFShutdown(); | ||||
|         CoUninitialize(); | ||||
|     } | ||||
|     transform_initialized = false; | ||||
|     format_selected = false; | ||||
| } | ||||
| 
 | ||||
| std::optional<BinaryResponse> WMFDecoder::Impl::ProcessRequest(const BinaryRequest& request) { | ||||
|  | @ -65,17 +88,13 @@ std::optional<BinaryResponse> WMFDecoder::Impl::ProcessRequest(const BinaryReque | |||
| } | ||||
| 
 | ||||
| std::optional<BinaryResponse> WMFDecoder::Impl::Initalize(const BinaryRequest& request) { | ||||
|     if (!initialized) { | ||||
|         MFCoInit(); | ||||
|     } | ||||
| 
 | ||||
|     BinaryResponse response; | ||||
|     std::memcpy(&response, &request, sizeof(response)); | ||||
|     response.unknown1 = 0x0; | ||||
|     transform = MFDecoderInit(); | ||||
| 
 | ||||
|     if (transform == nullptr) { | ||||
|         LOG_CRITICAL(Audio_DSP, "Can't init decoder"); | ||||
|         LOG_CRITICAL(Audio_DSP, "Can't initialize decoder"); | ||||
|         return response; | ||||
|     } | ||||
| 
 | ||||
|  | @ -89,22 +108,11 @@ std::optional<BinaryResponse> WMFDecoder::Impl::Initalize(const BinaryRequest& r | |||
|         return response; | ||||
|     } | ||||
| 
 | ||||
|     initialized = true; | ||||
|     transform_initialized = true; | ||||
|     format_selected = false;  // select format again if application request initialize the DSP
 | ||||
|     return response; | ||||
| } | ||||
| 
 | ||||
| void WMFDecoder::Impl::Clear() { | ||||
|     if (initialized) { | ||||
|         MFFlush(transform.get()); | ||||
|         // delete the transform object before shutting down MF
 | ||||
|         // otherwise access violation will occur
 | ||||
|         transform.reset(); | ||||
|         MFDestroy(); | ||||
|     } | ||||
|     initialized = false; | ||||
|     selected = false; | ||||
| } | ||||
| 
 | ||||
| MFOutputState WMFDecoder::Impl::DecodingLoop(ADTSData adts_header, | ||||
|                                              std::array<std::vector<u8>, 2>& out_streams) { | ||||
|     MFOutputState output_status = MFOutputState::OK; | ||||
|  | @ -138,7 +146,7 @@ MFOutputState WMFDecoder::Impl::DecodingLoop(ADTSData adts_header, | |||
| 
 | ||||
|         // for status = 2, reset MF
 | ||||
|         if (output_status == MFOutputState::NeedReconfig) { | ||||
|             Clear(); | ||||
|             format_selected = false; | ||||
|             return MFOutputState::NeedReconfig; | ||||
|         } | ||||
| 
 | ||||
|  | @ -164,7 +172,7 @@ std::optional<BinaryResponse> WMFDecoder::Impl::Decode(const BinaryRequest& requ | |||
|     response.num_channels = 2; | ||||
|     response.num_samples = 1024; | ||||
| 
 | ||||
|     if (!initialized) { | ||||
|     if (!transform_initialized) { | ||||
|         LOG_DEBUG(Audio_DSP, "Decoder not initialized"); | ||||
|         // This is a hack to continue games when decoder failed to initialize
 | ||||
|         return response; | ||||
|  | @ -190,7 +198,7 @@ std::optional<BinaryResponse> WMFDecoder::Impl::Decode(const BinaryRequest& requ | |||
| 
 | ||||
|     response.num_channels = adts_meta->ADTSHeader.channels; | ||||
| 
 | ||||
|     if (!selected) { | ||||
|     if (!format_selected) { | ||||
|         LOG_DEBUG(Audio_DSP, "New ADTS stream: channels = {}, sample rate = {}", | ||||
|                   adts_meta->ADTSHeader.channels, adts_meta->ADTSHeader.samplerate); | ||||
|         SelectInputMediaType(transform.get(), in_stream_id, adts_meta->ADTSHeader, | ||||
|  | @ -200,7 +208,7 @@ std::optional<BinaryResponse> WMFDecoder::Impl::Decode(const BinaryRequest& requ | |||
|         // cache the result from detect_mediatype and call select_*_mediatype only once
 | ||||
|         // This could increase performance very slightly
 | ||||
|         transform->ProcessMessage(MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0); | ||||
|         selected = true; | ||||
|         format_selected = true; | ||||
|     } | ||||
| 
 | ||||
|     sample = CreateSample((void*)data, request.size, 1, 0); | ||||
|  | @ -222,8 +230,8 @@ std::optional<BinaryResponse> WMFDecoder::Impl::Decode(const BinaryRequest& requ | |||
|             LOG_ERROR(Audio_DSP, "Errors occurred when receiving output"); | ||||
|             return response; | ||||
|         } else if (output_status == MFOutputState::NeedReconfig) { | ||||
|             // re-initialize the whole thing to adapt to new parameters
 | ||||
|             this->Initalize(request); | ||||
|             // flush the transform
 | ||||
|             MFFlush(transform.get()); | ||||
|             // decode again
 | ||||
|             return this->Decode(request); | ||||
|         } | ||||
|  |  | |||
|  | @ -25,28 +25,6 @@ void ReportError(std::string msg, HRESULT hr) { | |||
|     LOG_CRITICAL(Audio_DSP, "{}: {:08x}", msg, hr); | ||||
| } | ||||
| 
 | ||||
| bool MFCoInit() { | ||||
|     HRESULT hr = S_OK; | ||||
|     hr = CoInitialize(NULL); | ||||
|     // 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); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     // lite startup is faster and all what we need is included
 | ||||
|     hr = MFStartup(MF_VERSION, MFSTARTUP_LITE); | ||||
|     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); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     LOG_INFO(Audio_DSP, "Media Foundation activated"); | ||||
| 
 | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| unique_mfptr<IMFTransform> MFDecoderInit(GUID audio_format) { | ||||
|     HRESULT hr = S_OK; | ||||
|     MFT_REGISTER_TYPE_INFO reg = {0}; | ||||
|  | @ -84,11 +62,6 @@ unique_mfptr<IMFTransform> MFDecoderInit(GUID audio_format) { | |||
|     return std::move(transform); | ||||
| } | ||||
| 
 | ||||
| void MFDestroy() { | ||||
|     MFShutdown(); | ||||
|     CoUninitialize(); | ||||
| } | ||||
| 
 | ||||
| unique_mfptr<IMFSample> CreateSample(void* data, DWORD len, DWORD alignment, LONGLONG duration) { | ||||
|     HRESULT hr = S_OK; | ||||
|     unique_mfptr<IMFMediaBuffer> buf; | ||||
|  |  | |||
|  | @ -73,9 +73,7 @@ struct ADTSMeta { | |||
| }; | ||||
| 
 | ||||
| // exported functions
 | ||||
| bool MFCoInit(); | ||||
| unique_mfptr<IMFTransform> MFDecoderInit(GUID audio_format = MFAudioFormat_AAC); | ||||
| void MFDestroy(); | ||||
| unique_mfptr<IMFSample> CreateSample(void* data, DWORD len, DWORD alignment = 1, | ||||
|                                      LONGLONG duration = 0); | ||||
| bool SelectInputMediaType(IMFTransform* transform, int in_stream_id, const ADTSData& adts, | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue