[host] dxgi: fixed MFT memory leak and re-init failure

This commit is contained in:
Geoffrey McRae 2017-12-30 13:34:50 +11:00
parent 076a45acc5
commit 9ef9f60505
2 changed files with 46 additions and 18 deletions

View file

@ -249,8 +249,10 @@ bool DXGI::InitH264Capture()
ID3D10MultithreadPtr mt(m_device);
mt->SetMultithreadProtected(TRUE);
SafeRelease(&mt);
m_encodeEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
m_encodeEvent = CreateEvent(NULL, TRUE , FALSE, NULL);
m_shutdownEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
InitializeCriticalSection(&m_encodeCS);
typeInfo.guidMajorType = MFMediaType_Video;
@ -285,14 +287,15 @@ bool DXGI::InitH264Capture()
delete[] name;
}
status = activationPointers[0]->ActivateObject(IID_PPV_ARGS(&m_mfTransform));
m_mfActivation = activationPointers[0];
CoTaskMemFree(activationPointers);
status = m_mfActivation->ActivateObject(IID_PPV_ARGS(&m_mfTransform));
if (FAILED(status))
{
CoTaskMemFree(activationPointers);
DEBUG_WINERROR("Failed to create H264 encoder MFT", status);
return false;
}
CoTaskMemFree(activationPointers);
IMFAttributesPtr attribs;
m_mfTransform->GetAttributes(&attribs);
@ -348,7 +351,7 @@ bool DXGI::InitH264Capture()
outType->SetGUID (MF_MT_SUBTYPE , MFVideoFormat_H264);
outType->SetUINT32(MF_MT_AVG_BITRATE , 240000);
outType->SetUINT32(MF_MT_INTERLACE_MODE , MFVideoInterlace_Progressive);
outType->SetUINT32(MF_MT_MPEG2_PROFILE , eAVEncH264VProfile_444);
outType->SetUINT32(MF_MT_MPEG2_PROFILE , eAVEncH264VProfile_422);
outType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
MFSetAttributeSize (outType, MF_MT_FRAME_SIZE , m_width, m_height);
@ -356,6 +359,7 @@ bool DXGI::InitH264Capture()
MFSetAttributeRatio(outType, MF_MT_PIXEL_ASPECT_RATIO, 1, 1);
status = m_mfTransform->SetOutputType(0, outType, 0);
SafeRelease(&outType);
if (FAILED(status))
{
DEBUG_WINERROR("Failed to set the output media type on the H264 encoder MFT", status);
@ -375,6 +379,7 @@ bool DXGI::InitH264Capture()
MFSetAttributeRatio(inType, MF_MT_PIXEL_ASPECT_RATIO, 1 , 1);
status = m_mfTransform->SetInputType(0, inType, 0);
SafeRelease(&inType);
if (FAILED(status))
{
DEBUG_WINERROR("Failed to set the input media type on the H264 encoder MFT", status);
@ -408,6 +413,14 @@ bool DXGI::InitH264Capture()
void DXGI::DeInitialize()
{
if (m_mediaEventGen)
{
m_mfTransform->ProcessMessage(MFT_MESSAGE_NOTIFY_END_OF_STREAM, NULL);
m_mfTransform->ProcessMessage(MFT_MESSAGE_COMMAND_DRAIN, NULL);
while (WaitForSingleObject(m_shutdownEvent, INFINITE) != WAIT_OBJECT_0) {}
m_mfTransform->DeleteInputStream(0);
}
if (m_releaseFrame)
{
m_releaseFrame = false;
@ -427,23 +440,32 @@ void DXGI::DeInitialize()
m_surfaceMapped = false;
}
SafeRelease(&m_mediaEventGen);
SafeRelease(&m_mfTransform);
SafeRelease(&m_mfDeviceManager);
SafeRelease(&m_texture);
SafeRelease(&m_dup);
SafeRelease(&m_output);
SafeRelease(&m_deviceContext);
SafeRelease(&m_device);
SafeRelease(&m_dxgiFactory);
SafeRelease(&m_mfTransform);
SafeRelease(&m_mfDeviceManager);
SafeRelease(&m_mediaEventGen);
if (m_encodeEvent)
{
CloseHandle(m_encodeEvent);
m_encodeEvent = NULL;
CloseHandle(m_encodeEvent );
CloseHandle(m_shutdownEvent);
m_encodeEvent = NULL;
m_shutdownEvent = NULL;
DeleteCriticalSection(&m_encodeCS);
}
if (m_mfActivation)
{
m_mfActivation->ShutdownObject();
SafeRelease(&m_mfActivation);
}
m_initialized = false;
}
@ -523,7 +545,9 @@ STDMETHODIMP Capture::DXGI::Invoke(IMFAsyncResult * pAsyncResult)
DEBUG_WINERROR("MFT_MESSAGE_COMMAND_FLUSH", status);
return status;
}
break;
SetEvent(m_shutdownEvent);
return S_OK;
}
case MEError:
@ -662,19 +686,19 @@ GrabStatus Capture::DXGI::GrabFrameTexture(FrameInfo & frame, ID3D11Texture2DPtr
switch (shapeInfo.Type)
{
case DXGI_OUTDUPL_POINTER_SHAPE_TYPE_COLOR: frame.cursor.type = CURSOR_TYPE_COLOR; break;
case DXGI_OUTDUPL_POINTER_SHAPE_TYPE_COLOR : frame.cursor.type = CURSOR_TYPE_COLOR; break;
case DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MASKED_COLOR: frame.cursor.type = CURSOR_TYPE_MASKED_COLOR; break;
case DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MONOCHROME: frame.cursor.type = CURSOR_TYPE_MONOCHROME; break;
case DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MONOCHROME : frame.cursor.type = CURSOR_TYPE_MONOCHROME; break;
default:
DEBUG_ERROR("Invalid cursor type");
return GRAB_STATUS_ERROR;
}
frame.cursor.hasShape = true;
frame.cursor.shape = m_pointer;
frame.cursor.w = shapeInfo.Width;
frame.cursor.h = shapeInfo.Height;
frame.cursor.pitch = shapeInfo.Pitch;
frame.cursor.shape = m_pointer;
frame.cursor.w = shapeInfo.Width;
frame.cursor.h = shapeInfo.Height;
frame.cursor.pitch = shapeInfo.Pitch;
frame.cursor.dataSize = m_pointerSize;
}
@ -815,6 +839,7 @@ GrabStatus Capture::DXGI::GrabFrameH264(FrameInfo & frame)
status = MFCreateDXGISurfaceBuffer(__uuidof(ID3D11Texture2D), src, 0, FALSE, &buffer);
if (FAILED(status))
{
SafeRelease(&src);
DEBUG_WINERROR("Failed to create DXGI surface buffer from texture", status);
return GRAB_STATUS_ERROR;
}

View file

@ -143,11 +143,14 @@ namespace Capture
bool m_surfaceMapped;
HANDLE m_encodeEvent;
bool m_encodeNeedsData, m_encodeHasData;
HANDLE m_shutdownEvent;
bool m_encodeNeedsData;
bool m_encodeHasData;
CRITICAL_SECTION m_encodeCS;
UINT m_resetToken;
IMFDXGIDeviceManagerPtr m_mfDeviceManager;
IMFActivatePtr m_mfActivation;
IMFTransformPtr m_mfTransform;
IMFMediaEventGeneratorPtr m_mediaEventGen;