From 49dc6dc45956daa2b30ea3c56a5e5dfaac8ad9a1 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Tue, 23 Sep 2014 14:46:22 +0200 Subject: WMF: fix crash on media player destruction. A race condition could cause a frame to be presented even after the QAbstractVideoSurface was deleted. We now check that the surface is valid before presenting a frame. Task-number: QTBUG-41158 Change-Id: If593469a8267583e499e781336af38d3fbf318fd Reviewed-by: Christian Stromme --- src/plugins/wmf/evrd3dpresentengine.cpp | 48 +++++++++++++++++---------------- 1 file changed, 25 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/plugins/wmf/evrd3dpresentengine.cpp b/src/plugins/wmf/evrd3dpresentengine.cpp index 2aa9d0d64..42d0dea4e 100644 --- a/src/plugins/wmf/evrd3dpresentengine.cpp +++ b/src/plugins/wmf/evrd3dpresentengine.cpp @@ -330,34 +330,36 @@ void D3DPresentEngine::presentSample(void *opaque, qint64) IMFMediaBuffer* buffer = NULL; IDirect3DSurface9* surface = NULL; - if (sample) { - // Get the buffer from the sample. - hr = sample->GetBufferByIndex(0, &buffer); - if (FAILED(hr)) - goto done; + if (m_surface && m_surface->isActive()) { + if (sample) { + // Get the buffer from the sample. + hr = sample->GetBufferByIndex(0, &buffer); + if (FAILED(hr)) + goto done; + + // Get the surface from the buffer. + hr = MFGetService(buffer, MR_BUFFER_SERVICE, IID_PPV_ARGS(&surface)); + if (FAILED(hr)) + goto done; + } - // Get the surface from the buffer. - hr = MFGetService(buffer, MR_BUFFER_SERVICE, IID_PPV_ARGS(&surface)); - if (FAILED(hr)) - goto done; - } + if (surface && updateTexture(surface)) { + QVideoFrame frame = QVideoFrame(new TextureVideoBuffer(m_glTexture), + m_surfaceFormat.frameSize(), + m_surfaceFormat.pixelFormat()); - if (surface && updateTexture(surface)) { - QVideoFrame frame = QVideoFrame(new TextureVideoBuffer(m_glTexture), - m_surfaceFormat.frameSize(), - m_surfaceFormat.pixelFormat()); + // WMF uses 100-nanosecond units, Qt uses microseconds + LONGLONG startTime = -1; + if (SUCCEEDED(sample->GetSampleTime(&startTime))) { + frame.setStartTime(startTime * 0.1); - // WMF uses 100-nanosecond units, Qt uses microseconds - LONGLONG startTime = -1; - if (SUCCEEDED(sample->GetSampleTime(&startTime))) { - frame.setStartTime(startTime * 0.1); + LONGLONG duration = -1; + if (SUCCEEDED(sample->GetSampleDuration(&duration))) + frame.setEndTime((startTime + duration) * 0.1); + } - LONGLONG duration = -1; - if (SUCCEEDED(sample->GetSampleDuration(&duration))) - frame.setEndTime((startTime + duration) * 0.1); + m_surface->present(frame); } - - m_surface->present(frame); } done: -- cgit v1.2.3