diff --git a/src/audio_core/CMakeLists.txt b/src/audio_core/CMakeLists.txt index 937b0faee..8d6e256a5 100644 --- a/src/audio_core/CMakeLists.txt +++ b/src/audio_core/CMakeLists.txt @@ -4,6 +4,8 @@ add_library(audio_core STATIC codec.h dsp_interface.cpp dsp_interface.h + hle/adts.h + hle/adts_reader.cpp hle/common.h hle/decoder.cpp hle/decoder.h @@ -28,7 +30,7 @@ add_library(audio_core STATIC $<$:sdl2_sink.cpp sdl2_sink.h> $<$:cubeb_sink.cpp cubeb_sink.h> $<$:hle/ffmpeg_decoder.cpp hle/ffmpeg_decoder.h hle/ffmpeg_dl.cpp hle/ffmpeg_dl.h> - $<$:hle/wmf_decoder.cpp hle/wmf_decoder.h hle/wmf_decoder_utils.cpp hle/wmf_decoder_utils.h hle/adts_reader.cpp> + $<$:hle/wmf_decoder.cpp hle/wmf_decoder.h hle/wmf_decoder_utils.cpp hle/wmf_decoder_utils.h> ) create_target_directory_groups(audio_core) diff --git a/src/audio_core/hle/adts.h b/src/audio_core/hle/adts.h index c806e2d82..c2f5304fa 100644 --- a/src/audio_core/hle/adts.h +++ b/src/audio_core/hle/adts.h @@ -17,14 +17,6 @@ struct ADTSData { u32 samplerate; }; -typedef struct ADTSData ADTSData; - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus u32 parse_adts(char* buffer, struct ADTSData* out); // last two bytes of MF AAC decoder user data u16 mf_get_aac_tag(struct ADTSData input); -#ifdef __cplusplus -} -#endif // __cplusplus diff --git a/src/audio_core/hle/adts_reader.cpp b/src/audio_core/hle/adts_reader.cpp index ce3d1eda4..540aed577 100644 --- a/src/audio_core/hle/adts_reader.cpp +++ b/src/audio_core/hle/adts_reader.cpp @@ -4,7 +4,7 @@ #include "adts.h" constexpr std::array freq_table = {96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, - 16000, 12000, 11025, 8000, 7350, 0, 0, 0}; + 16000, 12000, 11025, 8000, 7350, 0, 0, 0}; constexpr std::array channel_table = {0, 1, 2, 3, 4, 5, 6, 8}; u32 parse_adts(char* buffer, struct ADTSData* out) { diff --git a/src/audio_core/hle/wmf_decoder.cpp b/src/audio_core/hle/wmf_decoder.cpp index 390ccd8dc..5dd28b7b5 100644 --- a/src/audio_core/hle/wmf_decoder.cpp +++ b/src/audio_core/hle/wmf_decoder.cpp @@ -73,7 +73,7 @@ std::optional WMFDecoder::Impl::Initalize(const BinaryRequest& r std::memcpy(&response, &request, sizeof(response)); response.unknown1 = 0x0; - if (MFDecoderInit(&transform) != 0) { + if (!MFDecoderInit(&transform)) { LOG_CRITICAL(Audio_DSP, "Can't init decoder"); return response; } @@ -104,7 +104,7 @@ void WMFDecoder::Impl::Clear() { int WMFDecoder::Impl::DecodingLoop(ADTSData adts_header, std::array, 2>& out_streams) { - int output_status = 0; + MFOutputState output_status = OK; char* output_buffer = nullptr; DWORD output_len = 0; IMFSample* output = nullptr; @@ -113,7 +113,7 @@ int WMFDecoder::Impl::DecodingLoop(ADTSData adts_header, output_status = ReceiveSample(transform, out_stream_id, &output); // 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); // 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 - if (output_status == 0) + if (output_status == OK) return 0; // for status = 2, reset MF - if (output_status == 2) { + if (output_status == NEED_RECONFIG) { Clear(); return -1; } // for status = 3, try again with new buffer - if (output_status == 3) + if (output_status == HAVE_MORE_DATA) 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; diff --git a/src/audio_core/hle/wmf_decoder_utils.cpp b/src/audio_core/hle/wmf_decoder_utils.cpp index 50a8a5554..459f5322c 100644 --- a/src/audio_core/hle/wmf_decoder_utils.cpp +++ b/src/audio_core/hle/wmf_decoder_utils.cpp @@ -22,7 +22,7 @@ void ReportError(std::string msg, HRESULT hr) { LOG_CRITICAL(Audio_DSP, "{}: {:08x}", msg, hr); } -int MFCoInit() { +bool MFCoInit() { HRESULT hr = S_OK; // lite startup is faster and all what we need is included @@ -30,15 +30,15 @@ int MFCoInit() { 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 -1; + return false; } 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; MFT_REGISTER_TYPE_INFO reg = {0}; GUID category = MFT_CATEGORY_AUDIO_DECODER; @@ -54,7 +54,7 @@ int MFDecoderInit(IMFTransform** transform, GUID audio_format) { if (FAILED(hr) || num_activate < 1) { ReportError("Failed to enumerate decoders", hr); CoTaskMemFree(activate); - return -1; + return false; } LOG_INFO(Audio_DSP, "Windows(R) Media Foundation found {} suitable decoder(s)", num_activate); for (unsigned int n = 0; n < num_activate; n++) { @@ -66,10 +66,10 @@ int MFDecoderInit(IMFTransform** transform, GUID audio_format) { if (*transform == nullptr) { ReportError("Failed to initialize MFT", hr); CoTaskMemFree(activate); - return -1; + return false; } CoTaskMemFree(activate); - return 0; + return true; } void MFDeInit(IMFTransform** transform) { @@ -117,8 +117,8 @@ IMFSample* CreateSample(void* data, DWORD len, DWORD alignment, LONGLONG duratio return sample; } -bool SelectInputMediaType(IMFTransform* transform, int in_stream_id, ADTSData adts, - UINT8* user_data, UINT32 user_data_len, GUID audio_format) { +bool SelectInputMediaType(IMFTransform* transform, int in_stream_id, const ADTSData& adts, + UINT8* user_data, UINT32 user_data_len, GUID audio_format) { HRESULT hr = S_OK; IMFMediaType* t; @@ -261,8 +261,7 @@ int SendSample(IMFTransform* transform, DWORD in_stream_id, IMFSample* in_sample return 0; } -// return: 0: okay; 1: needs more sample; 2: needs reconfiguring; 3: more data available -int ReceiveSample(IMFTransform* transform, DWORD out_stream_id, IMFSample** out_sample) { +MFOutputState ReceiveSample(IMFTransform* transform, DWORD out_stream_id, IMFSample** out_sample) { HRESULT hr; MFT_OUTPUT_DATA_BUFFER out_buffers; IMFSample* sample = nullptr; @@ -272,14 +271,14 @@ int ReceiveSample(IMFTransform* transform, DWORD out_stream_id, IMFSample** out_ if (!out_sample) { 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); if (FAILED(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) || (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); if (!sample) { 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) { // Most likely reasons: data corrupted; your actions not expected by MFT - return 1; + return NEED_MORE_INPUT; } if (hr == MF_E_TRANSFORM_STREAM_CHANGE) { ReportError("MFT: stream format changed, re-configuration required", hr); - return 2; + return NEED_RECONFIG; } break; @@ -322,15 +321,15 @@ int ReceiveSample(IMFTransform* transform, DWORD out_stream_id, IMFSample** out_ if (out_buffers.dwStatus & MFT_OUTPUT_DATA_BUFFER_INCOMPLETE) { // this status is also unreliable but whatever - return 3; + return HAVE_MORE_DATA; } if (*out_sample == nullptr) { ReportError("MFT: decoding failure", hr); - return -1; + return FATAL_ERROR; } - return 0; + return OK; } int CopySampleToBuffer(IMFSample* sample, void** output, DWORD* len) { diff --git a/src/audio_core/hle/wmf_decoder_utils.h b/src/audio_core/hle/wmf_decoder_utils.h index 128c30477..49b443fc2 100644 --- a/src/audio_core/hle/wmf_decoder_utils.h +++ b/src/audio_core/hle/wmf_decoder_utils.h @@ -19,6 +19,8 @@ #include "adts.h" +enum MFOutputState { FATAL_ERROR = -1, OK = 0, NEED_MORE_INPUT, NEED_RECONFIG, HAVE_MORE_DATA }; + // utility functions template void SafeRelease(T** ppT) { @@ -31,17 +33,17 @@ void SafeRelease(T** ppT) { void ReportError(std::string msg, HRESULT hr); // exported functions -int MFCoInit(); -int MFDecoderInit(IMFTransform** transform, GUID audio_format = MFAudioFormat_AAC); +bool MFCoInit(); +bool MFDecoderInit(IMFTransform** transform, GUID audio_format = MFAudioFormat_AAC); void MFDeInit(IMFTransform** transform); IMFSample* CreateSample(void* data, DWORD len, DWORD alignment = 1, LONGLONG duration = 0); -bool SelectInputMediaType(IMFTransform* transform, int in_stream_id, ADTSData adts, - UINT8* user_data, UINT32 user_data_len, - GUID audio_format = MFAudioFormat_AAC); +bool SelectInputMediaType(IMFTransform* transform, int in_stream_id, const ADTSData& adts, + UINT8* user_data, UINT32 user_data_len, + GUID audio_format = MFAudioFormat_AAC); int DetectMediaType(char* buffer, size_t len, ADTSData* output, char** aac_tag); bool SelectOutputMediaType(IMFTransform* transform, int out_stream_id, - GUID audio_format = MFAudioFormat_PCM); + GUID audio_format = MFAudioFormat_PCM); void MFFlush(IMFTransform** transform); 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);