diff --git a/plugins/win-mf/mf-h264-encoder.cpp b/plugins/win-mf/mf-h264-encoder.cpp index 6d18c35c7..9229a466e 100644 --- a/plugins/win-mf/mf-h264-encoder.cpp +++ b/plugins/win-mf/mf-h264-encoder.cpp @@ -71,10 +71,26 @@ H264Encoder::H264Encoder(const obs_encoder_t *encoder, H264Encoder::~H264Encoder() { - // Make sure all events have finished before releasing. + HRESULT hr; + + if (!descriptor->Async() || !eventGenerator || !pendingRequests) + return; + + // Make sure all events have finished before releasing, and drain + // all output requests until it makes an input request. // If you do not do this, you risk it releasing while there's still // encoder activity, which can cause a crash with certain interfaces. - DrainEvent(true); + while (inputRequests == 0) { + hr = ProcessOutput(); + if (hr != MF_E_TRANSFORM_NEED_MORE_INPUT && FAILED(hr)) { + MF_LOG_COM(LOG_ERROR, "H264Encoder::~H264Encoder: " + "ProcessOutput()", hr); + break; + } + + if (inputRequests == 0) + Sleep(1); + } } HRESULT H264Encoder::CreateMediaTypes(ComPtr &i, @@ -603,6 +619,8 @@ bool H264Encoder::ProcessInput(UINT8 **data, UINT32 *linesize, UINT64 pts, HRC(ProcessInput(sample)); + pendingRequests++; + *status = SUCCESS; return true; @@ -746,5 +764,7 @@ bool H264Encoder::ProcessOutput(UINT8 **data, UINT32 *dataLength, *keyframe = activeFrame.get()->Keyframe(); *status = SUCCESS; + pendingRequests--; + return true; } diff --git a/plugins/win-mf/mf-h264-encoder.hpp b/plugins/win-mf/mf-h264-encoder.hpp index fcf8f4872..67bc7241a 100644 --- a/plugins/win-mf/mf-h264-encoder.hpp +++ b/plugins/win-mf/mf-h264-encoder.hpp @@ -170,6 +170,6 @@ namespace MF { ComPtr eventGenerator; std::atomic inputRequests = 0; std::atomic outputRequests = 0; - + std::atomic pendingRequests = 0; }; }