mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	audio_core: hle: mf: make DetectMediaType return a struct
This commit is contained in:
		
							parent
							
								
									168f2ee79a
								
							
						
					
					
						commit
						ab1f47ed15
					
				
					 3 changed files with 23 additions and 16 deletions
				
			
		|  | @ -163,7 +163,7 @@ std::optional<BinaryResponse> WMFDecoder::Impl::Decode(const BinaryRequest& requ | ||||||
| 
 | 
 | ||||||
|     if (!initalized) { |     if (!initalized) { | ||||||
|         LOG_DEBUG(Audio_DSP, "Decoder not initalized"); |         LOG_DEBUG(Audio_DSP, "Decoder not initalized"); | ||||||
|         // This is a hack to continue games that are not compiled with the aac codec
 |         // This is a hack to continue games when decoder failed to initialize
 | ||||||
|         return response; |         return response; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -176,21 +176,21 @@ std::optional<BinaryResponse> WMFDecoder::Impl::Decode(const BinaryRequest& requ | ||||||
| 
 | 
 | ||||||
|     std::array<std::vector<u8>, 2> out_streams; |     std::array<std::vector<u8>, 2> out_streams; | ||||||
|     unique_mfptr<IMFSample> sample; |     unique_mfptr<IMFSample> sample; | ||||||
|     ADTSData adts_header; |  | ||||||
|     char* aac_tag = (char*)calloc(1, 14); |  | ||||||
|     MFInputState input_status = MFInputState::OK; |     MFInputState input_status = MFInputState::OK; | ||||||
|  |     std::optional<ADTSMeta> adts_meta = DetectMediaType((char*)data, request.size); | ||||||
| 
 | 
 | ||||||
|     if (DetectMediaType((char*)data, request.size, &adts_header, &aac_tag) != 0) { |     if (!adts_meta) { | ||||||
|         LOG_ERROR(Audio_DSP, "Unable to deduce decoding parameters from ADTS stream"); |         LOG_ERROR(Audio_DSP, "Unable to deduce decoding parameters from ADTS stream"); | ||||||
|         return response; |         return response; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     response.num_channels = adts_header.channels; |     response.num_channels = adts_meta->ADTSHeader.channels; | ||||||
| 
 | 
 | ||||||
|     if (!selected) { |     if (!selected) { | ||||||
|         LOG_DEBUG(Audio_DSP, "New ADTS stream: channels = {}, sample rate = {}", |         LOG_DEBUG(Audio_DSP, "New ADTS stream: channels = {}, sample rate = {}", | ||||||
|                   adts_header.channels, adts_header.samplerate); |                   adts_meta->ADTSHeader.channels, adts_meta->ADTSHeader.samplerate); | ||||||
|         SelectInputMediaType(transform.get(), in_stream_id, adts_header, (UINT8*)aac_tag, 14); |         SelectInputMediaType(transform.get(), in_stream_id, adts_meta->ADTSHeader, | ||||||
|  |                              adts_meta->AACTag, 14); | ||||||
|         SelectOutputMediaType(transform.get(), out_stream_id); |         SelectOutputMediaType(transform.get(), out_stream_id); | ||||||
|         SendSample(transform.get(), in_stream_id, nullptr); |         SendSample(transform.get(), in_stream_id, nullptr); | ||||||
|         // cache the result from detect_mediatype and call select_*_mediatype only once
 |         // cache the result from detect_mediatype and call select_*_mediatype only once
 | ||||||
|  | @ -205,7 +205,7 @@ std::optional<BinaryResponse> WMFDecoder::Impl::Decode(const BinaryRequest& requ | ||||||
|     while (true) { |     while (true) { | ||||||
|         input_status = SendSample(transform.get(), in_stream_id, sample.get()); |         input_status = SendSample(transform.get(), in_stream_id, sample.get()); | ||||||
| 
 | 
 | ||||||
|         if (DecodingLoop(adts_header, out_streams) == MFOutputState::FatalError) { |         if (DecodingLoop(adts_meta->ADTSHeader, out_streams) == MFOutputState::FatalError) { | ||||||
|             // if the decode issues are caused by MFT not accepting new samples, try again
 |             // if the decode issues are caused by MFT not accepting new samples, try again
 | ||||||
|             // NOTICE: you are required to check the output even if you already knew/guessed
 |             // NOTICE: you are required to check the output even if you already knew/guessed
 | ||||||
|             // MFT didn't accept the input sample
 |             // MFT didn't accept the input sample
 | ||||||
|  |  | ||||||
|  | @ -209,17 +209,18 @@ bool SelectOutputMediaType(IMFTransform* transform, int out_stream_id, GUID audi | ||||||
|     return false; |     return false; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int DetectMediaType(char* buffer, size_t len, ADTSData* output, char** aac_tag) { | std::optional<ADTSMeta> DetectMediaType(char* buffer, size_t len) { | ||||||
|     if (len < 7) { |     if (len < 7) { | ||||||
|         return -1; |         return std::nullopt; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     ADTSData tmp; |     ADTSData tmp; | ||||||
|  |     ADTSMeta result; | ||||||
|     // see https://docs.microsoft.com/en-us/windows/desktop/api/mmreg/ns-mmreg-heaacwaveinfo_tag
 |     // see https://docs.microsoft.com/en-us/windows/desktop/api/mmreg/ns-mmreg-heaacwaveinfo_tag
 | ||||||
|     // for the meaning of the byte array below
 |     // for the meaning of the byte array below
 | ||||||
| 
 | 
 | ||||||
|     // it might be a good idea to wrap the parameters into a struct
 |     // it might be a good idea to wrap the parameters into a struct
 | ||||||
|     // and pass that struct into the function but this will lead to messier code
 |     // and pass that struct into the function but doing that will lead to messier code
 | ||||||
|     // const UINT8 aac_data[] = { 0x01, 0x00, 0xfe, 00, 00, 00, 00, 00, 00, 00, 00, 00, 0x11, 0x90
 |     // const UINT8 aac_data[] = { 0x01, 0x00, 0xfe, 00, 00, 00, 00, 00, 00, 00, 00, 00, 0x11, 0x90
 | ||||||
|     // }; first byte: 0: raw aac 1: adts 2: adif 3: latm/laos
 |     // }; first byte: 0: raw aac 1: adts 2: adif 3: latm/laos
 | ||||||
|     UINT8 aac_tmp[] = {0x01, 0x00, 0xfe, 00, 00, 00, 00, 00, 00, 00, 00, 00, 0x00, 0x00}; |     UINT8 aac_tmp[] = {0x01, 0x00, 0xfe, 00, 00, 00, 00, 00, 00, 00, 00, 00, 0x00, 0x00}; | ||||||
|  | @ -227,15 +228,15 @@ int DetectMediaType(char* buffer, size_t len, ADTSData* output, char** aac_tag) | ||||||
| 
 | 
 | ||||||
|     tmp = ParseADTS(buffer); |     tmp = ParseADTS(buffer); | ||||||
|     if (tmp.length == 0) { |     if (tmp.length == 0) { | ||||||
|         return -1; |         return std::nullopt; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     tag = MFGetAACTag(tmp); |     tag = MFGetAACTag(tmp); | ||||||
|     aac_tmp[12] |= (tag & 0xff00) >> 8; |     aac_tmp[12] |= (tag & 0xff00) >> 8; | ||||||
|     aac_tmp[13] |= (tag & 0x00ff); |     aac_tmp[13] |= (tag & 0x00ff); | ||||||
|     std::memcpy(*aac_tag, aac_tmp, 14); |     std::memcpy(&(result.ADTSHeader), &tmp, sizeof(ADTSData)); | ||||||
|     std::memcpy(output, &tmp, sizeof(ADTSData)); |     std::memcpy(&(result.AACTag), aac_tmp, 14); | ||||||
|     return 0; |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void MFFlush(IMFTransform* transform) { | void MFFlush(IMFTransform* transform) { | ||||||
|  |  | ||||||
|  | @ -58,6 +58,12 @@ auto Amp(SmartPtr& smart_ptr) { | ||||||
| // convient function for formatting error messages
 | // convient function for formatting error messages
 | ||||||
| void ReportError(std::string msg, HRESULT hr); | void ReportError(std::string msg, HRESULT hr); | ||||||
| 
 | 
 | ||||||
|  | // data type for transferring ADTS metadata between functions
 | ||||||
|  | struct ADTSMeta { | ||||||
|  |     ADTSData ADTSHeader; | ||||||
|  |     u8 AACTag[14]; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| // exported functions
 | // exported functions
 | ||||||
| bool MFCoInit(); | bool MFCoInit(); | ||||||
| unique_mfptr<IMFTransform> MFDecoderInit(GUID audio_format = MFAudioFormat_AAC); | unique_mfptr<IMFTransform> MFDecoderInit(GUID audio_format = MFAudioFormat_AAC); | ||||||
|  | @ -67,7 +73,7 @@ unique_mfptr<IMFSample> CreateSample(void* data, DWORD len, DWORD alignment = 1, | ||||||
| bool SelectInputMediaType(IMFTransform* transform, int in_stream_id, const 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); | std::optional<ADTSMeta> DetectMediaType(char* buffer, size_t len); | ||||||
| bool SelectOutputMediaType(IMFTransform* transform, int out_stream_id, | 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); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue