diff --git a/src/audio_core/hle/wmf_decoder.cpp b/src/audio_core/hle/wmf_decoder.cpp index 4d649349a..8599b206d 100644 --- a/src/audio_core/hle/wmf_decoder.cpp +++ b/src/audio_core/hle/wmf_decoder.cpp @@ -16,14 +16,12 @@ public: private: std::optional Initalize(const BinaryRequest& request); - void Clear(); - std::optional Decode(const BinaryRequest& request); MFOutputState DecodingLoop(ADTSData adts_header, std::array, 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 WMFDecoder::Impl::ProcessRequest(const BinaryRequest& request) { @@ -65,17 +88,13 @@ std::optional WMFDecoder::Impl::ProcessRequest(const BinaryReque } std::optional 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 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, 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 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 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 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 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); } diff --git a/src/audio_core/hle/wmf_decoder_utils.cpp b/src/audio_core/hle/wmf_decoder_utils.cpp index 7dec97abf..e4055bfb2 100644 --- a/src/audio_core/hle/wmf_decoder_utils.cpp +++ b/src/audio_core/hle/wmf_decoder_utils.cpp @@ -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 MFDecoderInit(GUID audio_format) { HRESULT hr = S_OK; MFT_REGISTER_TYPE_INFO reg = {0}; @@ -84,11 +62,6 @@ unique_mfptr MFDecoderInit(GUID audio_format) { return std::move(transform); } -void MFDestroy() { - MFShutdown(); - CoUninitialize(); -} - unique_mfptr CreateSample(void* data, DWORD len, DWORD alignment, LONGLONG duration) { HRESULT hr = S_OK; unique_mfptr buf; diff --git a/src/audio_core/hle/wmf_decoder_utils.h b/src/audio_core/hle/wmf_decoder_utils.h index ac114edc9..f9a75af79 100644 --- a/src/audio_core/hle/wmf_decoder_utils.h +++ b/src/audio_core/hle/wmf_decoder_utils.h @@ -73,9 +73,7 @@ struct ADTSMeta { }; // exported functions -bool MFCoInit(); unique_mfptr MFDecoderInit(GUID audio_format = MFAudioFormat_AAC); -void MFDestroy(); unique_mfptr CreateSample(void* data, DWORD len, DWORD alignment = 1, LONGLONG duration = 0); bool SelectInputMediaType(IMFTransform* transform, int in_stream_id, const ADTSData& adts,