mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	audio_core: hle: mf: address another batch of reviews from @B3N30
This commit is contained in:
		
							parent
							
								
									7f5b54fda4
								
							
						
					
					
						commit
						c03861c2d9
					
				
					 6 changed files with 39 additions and 43 deletions
				
			
		|  | @ -4,6 +4,8 @@ add_library(audio_core STATIC | ||||||
|     codec.h |     codec.h | ||||||
|     dsp_interface.cpp |     dsp_interface.cpp | ||||||
|     dsp_interface.h |     dsp_interface.h | ||||||
|  |     hle/adts.h | ||||||
|  |     hle/adts_reader.cpp | ||||||
|     hle/common.h |     hle/common.h | ||||||
|     hle/decoder.cpp |     hle/decoder.cpp | ||||||
|     hle/decoder.h |     hle/decoder.h | ||||||
|  | @ -30,7 +32,7 @@ add_library(audio_core STATIC | ||||||
|     $<$<BOOL:${SDL2_FOUND}>:sdl2_sink.cpp sdl2_sink.h> |     $<$<BOOL:${SDL2_FOUND}>:sdl2_sink.cpp sdl2_sink.h> | ||||||
|     $<$<BOOL:${ENABLE_CUBEB}>:cubeb_sink.cpp cubeb_sink.h> |     $<$<BOOL:${ENABLE_CUBEB}>:cubeb_sink.cpp cubeb_sink.h> | ||||||
|     $<$<BOOL:${FFMPEG_FOUND}>:hle/ffmpeg_decoder.cpp hle/ffmpeg_decoder.h hle/ffmpeg_dl.cpp hle/ffmpeg_dl.h> |     $<$<BOOL:${FFMPEG_FOUND}>:hle/ffmpeg_decoder.cpp hle/ffmpeg_decoder.h hle/ffmpeg_dl.cpp hle/ffmpeg_dl.h> | ||||||
|     $<$<BOOL:${ENABLE_MF}>:hle/wmf_decoder.cpp hle/wmf_decoder.h hle/wmf_decoder_utils.cpp hle/wmf_decoder_utils.h hle/adts_reader.cpp> |     $<$<BOOL:${ENABLE_MF}>:hle/wmf_decoder.cpp hle/wmf_decoder.h hle/wmf_decoder_utils.cpp hle/wmf_decoder_utils.h> | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| create_target_directory_groups(audio_core) | create_target_directory_groups(audio_core) | ||||||
|  |  | ||||||
|  | @ -17,14 +17,6 @@ struct ADTSData { | ||||||
|     u32 samplerate; |     u32 samplerate; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| typedef struct ADTSData ADTSData; |  | ||||||
| 
 |  | ||||||
| #ifdef __cplusplus |  | ||||||
| extern "C" { |  | ||||||
| #endif // __cplusplus
 |  | ||||||
| u32 parse_adts(char* buffer, struct ADTSData* out); | u32 parse_adts(char* buffer, struct ADTSData* out); | ||||||
| // last two bytes of MF AAC decoder user data
 | // last two bytes of MF AAC decoder user data
 | ||||||
| u16 mf_get_aac_tag(struct ADTSData input); | u16 mf_get_aac_tag(struct ADTSData input); | ||||||
| #ifdef __cplusplus |  | ||||||
| } |  | ||||||
| #endif // __cplusplus
 |  | ||||||
|  |  | ||||||
|  | @ -73,7 +73,7 @@ std::optional<BinaryResponse> WMFDecoder::Impl::Initalize(const BinaryRequest& r | ||||||
|     std::memcpy(&response, &request, sizeof(response)); |     std::memcpy(&response, &request, sizeof(response)); | ||||||
|     response.unknown1 = 0x0; |     response.unknown1 = 0x0; | ||||||
| 
 | 
 | ||||||
|     if (MFDecoderInit(&transform) != 0) { |     if (!MFDecoderInit(&transform)) { | ||||||
|         LOG_CRITICAL(Audio_DSP, "Can't init decoder"); |         LOG_CRITICAL(Audio_DSP, "Can't init decoder"); | ||||||
|         return response; |         return response; | ||||||
|     } |     } | ||||||
|  | @ -104,7 +104,7 @@ void WMFDecoder::Impl::Clear() { | ||||||
| 
 | 
 | ||||||
| int WMFDecoder::Impl::DecodingLoop(ADTSData adts_header, | int WMFDecoder::Impl::DecodingLoop(ADTSData adts_header, | ||||||
|                                    std::array<std::vector<u8>, 2>& out_streams) { |                                    std::array<std::vector<u8>, 2>& out_streams) { | ||||||
|     int output_status = 0; |     MFOutputState output_status = OK; | ||||||
|     char* output_buffer = nullptr; |     char* output_buffer = nullptr; | ||||||
|     DWORD output_len = 0; |     DWORD output_len = 0; | ||||||
|     IMFSample* output = nullptr; |     IMFSample* output = nullptr; | ||||||
|  | @ -113,7 +113,7 @@ int WMFDecoder::Impl::DecodingLoop(ADTSData adts_header, | ||||||
|         output_status = ReceiveSample(transform, out_stream_id, &output); |         output_status = ReceiveSample(transform, out_stream_id, &output); | ||||||
| 
 | 
 | ||||||
|         // 0 -> okay; 3 -> okay but more data available (buffer too small)
 |         // 0 -> okay; 3 -> okay but more data available (buffer too small)
 | ||||||
|         if (output_status == 0 || output_status == 3) { |         if (output_status == OK || output_status == HAVE_MORE_DATA) { | ||||||
|             CopySampleToBuffer(output, (void**)&output_buffer, &output_len); |             CopySampleToBuffer(output, (void**)&output_buffer, &output_len); | ||||||
| 
 | 
 | ||||||
|             // the following was taken from ffmpeg version of the decoder
 |             // the following was taken from ffmpeg version of the decoder
 | ||||||
|  | @ -133,20 +133,21 @@ int WMFDecoder::Impl::DecodingLoop(ADTSData adts_header, | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // in case of "ok" only, just return quickly
 |         // in case of "ok" only, just return quickly
 | ||||||
|         if (output_status == 0) |         if (output_status == OK) | ||||||
|             return 0; |             return 0; | ||||||
| 
 | 
 | ||||||
|         // for status = 2, reset MF
 |         // for status = 2, reset MF
 | ||||||
|         if (output_status == 2) { |         if (output_status == NEED_RECONFIG) { | ||||||
|             Clear(); |             Clear(); | ||||||
|             return -1; |             return -1; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // for status = 3, try again with new buffer
 |         // for status = 3, try again with new buffer
 | ||||||
|         if (output_status == 3) |         if (output_status == HAVE_MORE_DATA) | ||||||
|             continue; |             continue; | ||||||
| 
 | 
 | ||||||
|         return output_status; // return on other status
 |         LOG_ERROR(Audio_DSP, "Errors occurred when receiving output: {}", output_status); | ||||||
|  |         return -1; // return on other status
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return -1; |     return -1; | ||||||
|  |  | ||||||
|  | @ -22,7 +22,7 @@ void ReportError(std::string msg, HRESULT hr) { | ||||||
|     LOG_CRITICAL(Audio_DSP, "{}: {:08x}", msg, hr); |     LOG_CRITICAL(Audio_DSP, "{}: {:08x}", msg, hr); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int MFCoInit() { | bool MFCoInit() { | ||||||
|     HRESULT hr = S_OK; |     HRESULT hr = S_OK; | ||||||
| 
 | 
 | ||||||
|     // lite startup is faster and all what we need is included
 |     // lite startup is faster and all what we need is included
 | ||||||
|  | @ -30,15 +30,15 @@ int MFCoInit() { | ||||||
|     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); | ||||||
|         return -1; |         return false; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     LOG_INFO(Audio_DSP, "Media Foundation activated"); |     LOG_INFO(Audio_DSP, "Media Foundation activated"); | ||||||
| 
 | 
 | ||||||
|     return 0; |     return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int MFDecoderInit(IMFTransform** transform, GUID audio_format) { | bool MFDecoderInit(IMFTransform** transform, GUID audio_format) { | ||||||
|     HRESULT hr = S_OK; |     HRESULT hr = S_OK; | ||||||
|     MFT_REGISTER_TYPE_INFO reg = {0}; |     MFT_REGISTER_TYPE_INFO reg = {0}; | ||||||
|     GUID category = MFT_CATEGORY_AUDIO_DECODER; |     GUID category = MFT_CATEGORY_AUDIO_DECODER; | ||||||
|  | @ -54,7 +54,7 @@ int MFDecoderInit(IMFTransform** transform, GUID audio_format) { | ||||||
|     if (FAILED(hr) || num_activate < 1) { |     if (FAILED(hr) || num_activate < 1) { | ||||||
|         ReportError("Failed to enumerate decoders", hr); |         ReportError("Failed to enumerate decoders", hr); | ||||||
|         CoTaskMemFree(activate); |         CoTaskMemFree(activate); | ||||||
|         return -1; |         return false; | ||||||
|     } |     } | ||||||
|     LOG_INFO(Audio_DSP, "Windows(R) Media Foundation found {} suitable decoder(s)", num_activate); |     LOG_INFO(Audio_DSP, "Windows(R) Media Foundation found {} suitable decoder(s)", num_activate); | ||||||
|     for (unsigned int n = 0; n < num_activate; n++) { |     for (unsigned int n = 0; n < num_activate; n++) { | ||||||
|  | @ -66,10 +66,10 @@ int MFDecoderInit(IMFTransform** transform, GUID audio_format) { | ||||||
|     if (*transform == nullptr) { |     if (*transform == nullptr) { | ||||||
|         ReportError("Failed to initialize MFT", hr); |         ReportError("Failed to initialize MFT", hr); | ||||||
|         CoTaskMemFree(activate); |         CoTaskMemFree(activate); | ||||||
|         return -1; |         return false; | ||||||
|     } |     } | ||||||
|     CoTaskMemFree(activate); |     CoTaskMemFree(activate); | ||||||
|     return 0; |     return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void MFDeInit(IMFTransform** transform) { | void MFDeInit(IMFTransform** transform) { | ||||||
|  | @ -117,7 +117,7 @@ IMFSample* CreateSample(void* data, DWORD len, DWORD alignment, LONGLONG duratio | ||||||
|     return sample; |     return sample; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool SelectInputMediaType(IMFTransform* transform, int in_stream_id, ADTSData adts, | bool SelectInputMediaType(IMFTransform* transform, int in_stream_id, const ADTSData& adts, | ||||||
|                           UINT8* user_data, UINT32 user_data_len, GUID audio_format) { |                           UINT8* user_data, UINT32 user_data_len, GUID audio_format) { | ||||||
|     HRESULT hr = S_OK; |     HRESULT hr = S_OK; | ||||||
|     IMFMediaType* t; |     IMFMediaType* t; | ||||||
|  | @ -261,8 +261,7 @@ int SendSample(IMFTransform* transform, DWORD in_stream_id, IMFSample* in_sample | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // return: 0: okay; 1: needs more sample; 2: needs reconfiguring; 3: more data available
 | MFOutputState ReceiveSample(IMFTransform* transform, DWORD out_stream_id, IMFSample** out_sample) { | ||||||
| int ReceiveSample(IMFTransform* transform, DWORD out_stream_id, IMFSample** out_sample) { |  | ||||||
|     HRESULT hr; |     HRESULT hr; | ||||||
|     MFT_OUTPUT_DATA_BUFFER out_buffers; |     MFT_OUTPUT_DATA_BUFFER out_buffers; | ||||||
|     IMFSample* sample = nullptr; |     IMFSample* sample = nullptr; | ||||||
|  | @ -272,14 +271,14 @@ int ReceiveSample(IMFTransform* transform, DWORD out_stream_id, IMFSample** out_ | ||||||
| 
 | 
 | ||||||
|     if (!out_sample) { |     if (!out_sample) { | ||||||
|         ReportError("nullptr pointer passed to receive_sample()", MF_E_SAMPLE_NOT_WRITABLE); |         ReportError("nullptr pointer passed to receive_sample()", MF_E_SAMPLE_NOT_WRITABLE); | ||||||
|         return -1; |         return FATAL_ERROR; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     hr = transform->GetOutputStreamInfo(out_stream_id, &out_info); |     hr = transform->GetOutputStreamInfo(out_stream_id, &out_info); | ||||||
| 
 | 
 | ||||||
|     if (FAILED(hr)) { |     if (FAILED(hr)) { | ||||||
|         ReportError("MFT: Failed to get stream info", hr); |         ReportError("MFT: Failed to get stream info", hr); | ||||||
|         return -1; |         return FATAL_ERROR; | ||||||
|     } |     } | ||||||
|     mft_create_sample = (out_info.dwFlags & MFT_OUTPUT_STREAM_PROVIDES_SAMPLES) || |     mft_create_sample = (out_info.dwFlags & MFT_OUTPUT_STREAM_PROVIDES_SAMPLES) || | ||||||
|                         (out_info.dwFlags & MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES); |                         (out_info.dwFlags & MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES); | ||||||
|  | @ -293,7 +292,7 @@ int ReceiveSample(IMFTransform* transform, DWORD out_stream_id, IMFSample** out_ | ||||||
|             sample = CreateSample(nullptr, out_info.cbSize, out_info.cbAlignment); |             sample = CreateSample(nullptr, out_info.cbSize, out_info.cbAlignment); | ||||||
|             if (!sample) { |             if (!sample) { | ||||||
|                 ReportError("MFT: Unable to allocate memory for samples", hr); |                 ReportError("MFT: Unable to allocate memory for samples", hr); | ||||||
|                 return -1; |                 return FATAL_ERROR; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | @ -309,12 +308,12 @@ int ReceiveSample(IMFTransform* transform, DWORD out_stream_id, IMFSample** out_ | ||||||
| 
 | 
 | ||||||
|         if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) { |         if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) { | ||||||
|             // Most likely reasons: data corrupted; your actions not expected by MFT
 |             // Most likely reasons: data corrupted; your actions not expected by MFT
 | ||||||
|             return 1; |             return NEED_MORE_INPUT; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (hr == MF_E_TRANSFORM_STREAM_CHANGE) { |         if (hr == MF_E_TRANSFORM_STREAM_CHANGE) { | ||||||
|             ReportError("MFT: stream format changed, re-configuration required", hr); |             ReportError("MFT: stream format changed, re-configuration required", hr); | ||||||
|             return 2; |             return NEED_RECONFIG; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         break; |         break; | ||||||
|  | @ -322,15 +321,15 @@ int ReceiveSample(IMFTransform* transform, DWORD out_stream_id, IMFSample** out_ | ||||||
| 
 | 
 | ||||||
|     if (out_buffers.dwStatus & MFT_OUTPUT_DATA_BUFFER_INCOMPLETE) { |     if (out_buffers.dwStatus & MFT_OUTPUT_DATA_BUFFER_INCOMPLETE) { | ||||||
|         // this status is also unreliable but whatever
 |         // this status is also unreliable but whatever
 | ||||||
|         return 3; |         return HAVE_MORE_DATA; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (*out_sample == nullptr) { |     if (*out_sample == nullptr) { | ||||||
|         ReportError("MFT: decoding failure", hr); |         ReportError("MFT: decoding failure", hr); | ||||||
|         return -1; |         return FATAL_ERROR; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return 0; |     return OK; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int CopySampleToBuffer(IMFSample* sample, void** output, DWORD* len) { | int CopySampleToBuffer(IMFSample* sample, void** output, DWORD* len) { | ||||||
|  |  | ||||||
|  | @ -19,6 +19,8 @@ | ||||||
| 
 | 
 | ||||||
| #include "adts.h" | #include "adts.h" | ||||||
| 
 | 
 | ||||||
|  | enum MFOutputState { FATAL_ERROR = -1, OK = 0, NEED_MORE_INPUT, NEED_RECONFIG, HAVE_MORE_DATA }; | ||||||
|  | 
 | ||||||
| // utility functions
 | // utility functions
 | ||||||
| template <class T> | template <class T> | ||||||
| void SafeRelease(T** ppT) { | void SafeRelease(T** ppT) { | ||||||
|  | @ -31,11 +33,11 @@ void SafeRelease(T** ppT) { | ||||||
| void ReportError(std::string msg, HRESULT hr); | void ReportError(std::string msg, HRESULT hr); | ||||||
| 
 | 
 | ||||||
| // exported functions
 | // exported functions
 | ||||||
| int MFCoInit(); | bool MFCoInit(); | ||||||
| int MFDecoderInit(IMFTransform** transform, GUID audio_format = MFAudioFormat_AAC); | bool MFDecoderInit(IMFTransform** transform, GUID audio_format = MFAudioFormat_AAC); | ||||||
| void MFDeInit(IMFTransform** transform); | void MFDeInit(IMFTransform** transform); | ||||||
| IMFSample* CreateSample(void* data, DWORD len, DWORD alignment = 1, LONGLONG duration = 0); | IMFSample* CreateSample(void* data, DWORD len, DWORD alignment = 1, LONGLONG duration = 0); | ||||||
| bool SelectInputMediaType(IMFTransform* transform, int in_stream_id, ADTSData adts, | bool SelectInputMediaType(IMFTransform* transform, int in_stream_id, const ADTSData& adts, | ||||||
|                           UINT8* user_data, UINT32 user_data_len, |                           UINT8* user_data, UINT32 user_data_len, | ||||||
|                           GUID audio_format = MFAudioFormat_AAC); |                           GUID audio_format = MFAudioFormat_AAC); | ||||||
| int DetectMediaType(char* buffer, size_t len, ADTSData* output, char** aac_tag); | int DetectMediaType(char* buffer, size_t len, ADTSData* output, char** aac_tag); | ||||||
|  | @ -43,5 +45,5 @@ bool SelectOutputMediaType(IMFTransform* transform, int out_stream_id, | ||||||
|                            GUID audio_format = MFAudioFormat_PCM); |                            GUID audio_format = MFAudioFormat_PCM); | ||||||
| void MFFlush(IMFTransform** transform); | void MFFlush(IMFTransform** transform); | ||||||
| int SendSample(IMFTransform* transform, DWORD in_stream_id, IMFSample* in_sample); | int SendSample(IMFTransform* transform, DWORD in_stream_id, IMFSample* in_sample); | ||||||
| int ReceiveSample(IMFTransform* transform, DWORD out_stream_id, IMFSample** out_sample); | MFOutputState ReceiveSample(IMFTransform* transform, DWORD out_stream_id, IMFSample** out_sample); | ||||||
| int CopySampleToBuffer(IMFSample* sample, void** output, DWORD* len); | int CopySampleToBuffer(IMFSample* sample, void** output, DWORD* len); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue