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.
master
jp9000 2015-09-17 13:31:31 -07:00
parent 672378d202
commit 88996aef73
2 changed files with 23 additions and 3 deletions

View File

@ -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<IMFMediaType> &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;
}

View File

@ -170,6 +170,6 @@ namespace MF {
ComPtr<IMFMediaEventGenerator> eventGenerator;
std::atomic<UINT32> inputRequests = 0;
std::atomic<UINT32> outputRequests = 0;
std::atomic<UINT32> pendingRequests = 0;
};
}