From 88996aef73ac08ea7f2909c26ea7b4ac77974dca Mon Sep 17 00:00:00 2001 From: jp9000 Date: Thu, 17 Sep 2015 13:31:31 -0700 Subject: [PATCH] win-mf: Fix more issues on encoder shutdown The previous commit (672378d20) was supposed to fix issues with the encoder releasing while data was still being processed, but did not account for when the encoder has never started up. That was my fault. Furthermore, the way in which it was waiting to drain events was incorrect. The encoder may still be active even though there aren't any events queued. The proper way to wait for an async encoder to finish up is to process output samples until it requests more input samples. --- plugins/win-mf/mf-h264-encoder.cpp | 24 ++++++++++++++++++++++-- plugins/win-mf/mf-h264-encoder.hpp | 2 +- 2 files changed, 23 insertions(+), 3 deletions(-) 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; }; }