summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPiotr Srebrny <piotr.srebrny@qt.io>2021-11-29 10:42:28 +0100
committerPiotr Srebrny <piotr.srebrny@qt.io>2021-12-02 09:43:42 +0100
commit7e6331ebce21b38169e76d60748e813f1d6395e2 (patch)
tree1abfd07e07e7251733f1d6538b34f638aa8a1adb
parent5cc076819278a1a039dc3fe8358535d01591539a (diff)
Enable zero copy for WMF player
Zero copy requires delivering texture handles of video frames. These handles should point to D3D11 texture as this Direct3D version is used by RHI. Since WMF works by default with D3D9 surfaces, we first have to create a D3D9 texture and obtain a surface from it that the WMF player will render a picture on. The D3D9 texture is then shared with D3D11 RHI device to get D3D11 texture. The texture sharing can only happen when both D3D9 and D3D11 devices are located on the same GPU. Pick-to: 6.2 Change-Id: Iff962ee61c5745b87e9f45584783e485ece638d0 Reviewed-by: André de la Rocha <andre.rocha@qt.io> Reviewed-by: Lars Knoll <lars.knoll@qt.io>
-rw-r--r--src/multimedia/platform/windows/evr/evrcustompresenter.cpp21
-rw-r--r--src/multimedia/platform/windows/evr/evrd3dpresentengine.cpp306
-rw-r--r--src/multimedia/platform/windows/evr/evrd3dpresentengine_p.h26
-rw-r--r--src/multimedia/platform/windows/evr/evrhelpers.cpp2
-rw-r--r--src/multimedia/platform/windows/player/mfvideorenderercontrol.cpp12
5 files changed, 201 insertions, 166 deletions
diff --git a/src/multimedia/platform/windows/evr/evrcustompresenter.cpp b/src/multimedia/platform/windows/evr/evrcustompresenter.cpp
index d5561d378..4acf56c75 100644
--- a/src/multimedia/platform/windows/evr/evrcustompresenter.cpp
+++ b/src/multimedia/platform/windows/evr/evrcustompresenter.cpp
@@ -556,7 +556,7 @@ EVRCustomPresenter::EVRCustomPresenter(QVideoSink *sink)
, m_prerolled(false)
, m_endStreaming(false)
, m_playbackRate(1.0f)
- , m_presentEngine(new D3DPresentEngine)
+ , m_presentEngine(new D3DPresentEngine(sink))
, m_clock(0)
, m_mixer(0)
, m_mediaEventSink(0)
@@ -1026,21 +1026,15 @@ void EVRCustomPresenter::supportedFormatsChanged()
const std::lock_guard<QRecursiveMutex> locker(m_mutex);
m_canRenderToSurface = false;
- m_presentEngine->setHint(D3DPresentEngine::RenderToTexture, false);
// check if we can render to the surface (compatible formats)
if (m_videoSink) {
- if (m_presentEngine->supportsTextureRendering() && m_videoSink->rhi() && m_videoSink->rhi()->backend() == QRhi::OpenGLES2) {
- m_presentEngine->setHint(D3DPresentEngine::RenderToTexture, true);
- m_canRenderToSurface = true;
- } else {
- for (int f = 0; f < QVideoFrameFormat::NPixelFormats; ++f) {
- // ### set a better preference order
- QVideoFrameFormat::PixelFormat format = QVideoFrameFormat::PixelFormat(f);
- if (SUCCEEDED(m_presentEngine->checkFormat(qt_evr_D3DFormatFromPixelFormat(format)))) {
- m_canRenderToSurface = true;
- break;
- }
+ for (int f = 0; f < QVideoFrameFormat::NPixelFormats; ++f) {
+ // ### set a better preference order
+ QVideoFrameFormat::PixelFormat format = QVideoFrameFormat::PixelFormat(f);
+ if (SUCCEEDED(m_presentEngine->checkFormat(qt_evr_D3DFormatFromPixelFormat(format)))) {
+ m_canRenderToSurface = true;
+ break;
}
}
}
@@ -1052,6 +1046,7 @@ void EVRCustomPresenter::setSink(QVideoSink *sink)
{
m_mutex.lock();
m_videoSink = sink;
+ m_presentEngine->setSink(sink);
m_mutex.unlock();
supportedFormatsChanged();
diff --git a/src/multimedia/platform/windows/evr/evrd3dpresentengine.cpp b/src/multimedia/platform/windows/evr/evrd3dpresentengine.cpp
index fa1a8dbc4..002d52f3f 100644
--- a/src/multimedia/platform/windows/evr/evrd3dpresentengine.cpp
+++ b/src/multimedia/platform/windows/evr/evrd3dpresentengine.cpp
@@ -45,68 +45,90 @@
#include <qvideoframe.h>
#include <QDebug>
#include <qthread.h>
-#include <QOffscreenSurface>
+#include <qvideosink.h>
+#include <qloggingcategory.h>
+
+#include <d3d11_1.h>
+
+#include <private/qrhi_p.h>
+#include <private/qrhid3d11_p.h>
-static const int PRESENTER_BUFFER_COUNT = 3;
QT_BEGIN_NAMESPACE
+Q_LOGGING_CATEGORY(qLcEvrD3DPresentEngine, "qt.multimedia.evrd3dpresentengine")
+
class IMFSampleVideoBuffer: public QAbstractVideoBuffer
{
public:
- IMFSampleVideoBuffer(D3DPresentEngine *engine, IMFSample *sample, QVideoFrame::HandleType handleType)
- : QAbstractVideoBuffer(handleType)
- , m_sample(sample)
- , m_surface(0)
+ IMFSampleVideoBuffer(QWindowsIUPointer<IDirect3DDevice9Ex> device,
+ IMFSample *sample,
+ QWindowsIUPointer<ID3D11Texture2D> d2d11tex)
+ : QAbstractVideoBuffer(d2d11tex ? QVideoFrame::RhiTextureHandle : QVideoFrame::NoHandle)
+ , m_device(device)
+ , m_d2d11tex(d2d11tex)
, m_mapMode(QVideoFrame::NotMapped)
{
- Q_UNUSED(engine);
- if (m_sample) {
- m_sample->AddRef();
-
- IMFMediaBuffer *buffer;
- if (SUCCEEDED(m_sample->GetBufferByIndex(0, &buffer))) {
- MFGetService(buffer,
- MR_BUFFER_SERVICE,
- IID_IDirect3DSurface9,
- reinterpret_cast<void **>(&m_surface));
- buffer->Release();
- }
- }
+ sample->AddRef();
+ m_sample.reset(sample);
}
~IMFSampleVideoBuffer() override
{
- if (m_surface) {
- if (m_mapMode != QVideoFrame::NotMapped)
- m_surface->UnlockRect();
- m_surface->Release();
- }
- if (m_sample)
- m_sample->Release();
+ if (m_memSurface && m_mapMode != QVideoFrame::NotMapped)
+ m_memSurface->UnlockRect();
}
QVideoFrame::MapMode mapMode() const override { return m_mapMode; }
MapData map(QVideoFrame::MapMode mode) override;
void unmap() override;
+ void mapTextures() override {}
+ quint64 textureHandle(int /*plane*/) const override { return quint64(m_d2d11tex.get()); }
+
private:
- IMFSample *m_sample;
- IDirect3DSurface9 *m_surface;
+ QWindowsIUPointer<IDirect3DDevice9Ex> m_device;
+ QWindowsIUPointer<ID3D11Texture2D> m_d2d11tex;
+ QWindowsIUPointer<IMFSample> m_sample;
+ QWindowsIUPointer<IDirect3DSurface9> m_memSurface;
QVideoFrame::MapMode m_mapMode;
};
IMFSampleVideoBuffer::MapData IMFSampleVideoBuffer::map(QVideoFrame::MapMode mode)
{
- if (!m_surface || m_mapMode != QVideoFrame::NotMapped)
+ if (!m_sample || m_mapMode != QVideoFrame::NotMapped || mode != QVideoFrame::ReadOnly)
return {};
D3DSURFACE_DESC desc;
- if (FAILED(m_surface->GetDesc(&desc)))
- return {};
+ if (m_memSurface) {
+ if (FAILED(m_memSurface->GetDesc(&desc)))
+ return {};
+
+ } else {
+ QWindowsIUPointer<IMFMediaBuffer> buffer;
+ HRESULT hr = m_sample->GetBufferByIndex(0, buffer.address());
+ if (FAILED(hr))
+ return {};
+
+ QWindowsIUPointer<IDirect3DSurface9> surface;
+ hr = MFGetService(buffer.get(), MR_BUFFER_SERVICE, IID_IDirect3DSurface9, (void **)(surface.address()));
+ if (FAILED(hr))
+ return {};
+
+ if (FAILED(surface->GetDesc(&desc)))
+ return {};
+
+ if (FAILED(m_device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, m_memSurface.address(), nullptr)))
+ return {};
+
+ if (FAILED(m_device->GetRenderTargetData(surface.get(), m_memSurface.get()))) {
+ m_memSurface.reset();
+ return {};
+ }
+ }
D3DLOCKED_RECT rect;
- if (FAILED(m_surface->LockRect(&rect, NULL, mode == QVideoFrame::ReadOnly ? D3DLOCK_READONLY : 0)))
+ if (FAILED(m_memSurface->LockRect(&rect, NULL, mode == QVideoFrame::ReadOnly ? D3DLOCK_READONLY : 0)))
return {};
m_mapMode = mode;
@@ -125,121 +147,145 @@ void IMFSampleVideoBuffer::unmap()
return;
m_mapMode = QVideoFrame::NotMapped;
- m_surface->UnlockRect();
+ if (m_memSurface)
+ m_memSurface->UnlockRect();
}
-D3DPresentEngine::D3DPresentEngine()
+D3DPresentEngine::D3DPresentEngine(QVideoSink *sink)
: m_deviceResetToken(0)
- , m_D3D9(0)
- , m_device(0)
- , m_devices(0)
- , m_useTextureRendering(false)
{
ZeroMemory(&m_displayMode, sizeof(m_displayMode));
+ setSink(sink);
+}
+
+D3DPresentEngine::~D3DPresentEngine()
+{
+ releaseResources();
+}
+
+void D3DPresentEngine::setSink(QVideoSink *sink)
+{
+ if (sink == m_sink)
+ return;
+
+ m_sink = sink;
+
+ releaseResources();
+ m_device.reset();
+ m_devices.reset();
+ m_D3D9.reset();
+
+ if (!m_sink)
+ return;
HRESULT hr = initializeD3D();
if (SUCCEEDED(hr)) {
- hr = createD3DDevice();
- if (FAILED(hr))
- qWarning("Failed to create D3D device");
+ hr = createD3DDevice();
+ if (FAILED(hr))
+ qWarning("Failed to create D3D device");
} else {
qWarning("Failed to initialize D3D");
}
}
-D3DPresentEngine::~D3DPresentEngine()
-{
- releaseResources();
-
- qt_evr_safe_release(&m_device);
- qt_evr_safe_release(&m_devices);
- qt_evr_safe_release(&m_D3D9);
-}
-
HRESULT D3DPresentEngine::initializeD3D()
{
- HRESULT hr = Direct3DCreate9Ex(D3D_SDK_VERSION, &m_D3D9);
+ HRESULT hr = Direct3DCreate9Ex(D3D_SDK_VERSION, m_D3D9.address());
if (SUCCEEDED(hr))
- hr = DXVA2CreateDirect3DDeviceManager9(&m_deviceResetToken, &m_devices);
+ hr = DXVA2CreateDirect3DDeviceManager9(&m_deviceResetToken, m_devices.address());
return hr;
}
HRESULT D3DPresentEngine::createD3DDevice()
{
- HRESULT hr = S_OK;
- HWND hwnd = NULL;
- UINT uAdapterID = D3DADAPTER_DEFAULT;
- DWORD vp = 0;
+ if (!m_D3D9 || !m_devices)
+ return MF_E_NOT_INITIALIZED;
+
+ m_useTextureRendering = false;
+ UINT adapterID = 0;
+ if (m_sink->rhi()) {
+ if (m_sink->rhi()->backend() == QRhi::D3D11) {
+ auto nh = static_cast<const QRhiD3D11NativeHandles*>(m_sink->rhi()->nativeHandles());
+ if (nh) {
+ for (auto i = 0u; i < m_D3D9->GetAdapterCount(); ++i) {
+ LUID luid = {};
+ m_D3D9->GetAdapterLUID(i, &luid);
+ if (luid.LowPart == nh->adapterLuidLow && luid.HighPart == nh->adapterLuidHigh) {
+ adapterID = i;
+ m_useTextureRendering = true;
+ break;
+ }
+ }
+ }
+ } else {
+ qCDebug(qLcEvrD3DPresentEngine) << "Not supported RHI backend type";
+ }
+ } else {
+ qCDebug(qLcEvrD3DPresentEngine) << "No RHI associated with this sink";
+ adapterID = 0;
+ }
+
+ if (!m_useTextureRendering)
+ qCDebug(qLcEvrD3DPresentEngine) << "Could not find compatible RHI adapter, zero copy disabled";
D3DCAPS9 ddCaps;
ZeroMemory(&ddCaps, sizeof(ddCaps));
- IDirect3DDevice9Ex* device = NULL;
-
- if (!m_D3D9 || !m_devices)
- return MF_E_NOT_INITIALIZED;
+ HRESULT hr = m_D3D9->GetDeviceCaps(adapterID, D3DDEVTYPE_HAL, &ddCaps);
+ if (FAILED(hr))
+ return hr;
- hwnd = ::GetShellWindow();
+ DWORD vp = 0;
+ if (ddCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
+ vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
+ else
+ vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
D3DPRESENT_PARAMETERS pp;
ZeroMemory(&pp, sizeof(pp));
pp.BackBufferWidth = 1;
pp.BackBufferHeight = 1;
- pp.BackBufferFormat = D3DFMT_UNKNOWN;
pp.BackBufferCount = 1;
pp.Windowed = TRUE;
pp.SwapEffect = D3DSWAPEFFECT_DISCARD;
pp.BackBufferFormat = D3DFMT_UNKNOWN;
- pp.hDeviceWindow = hwnd;
+ pp.hDeviceWindow = nullptr;
pp.Flags = D3DPRESENTFLAG_VIDEO;
pp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
- hr = m_D3D9->GetDeviceCaps(uAdapterID, D3DDEVTYPE_HAL, &ddCaps);
- if (FAILED(hr))
- goto done;
-
- if (ddCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
- vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
- else
- vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
+ QWindowsIUPointer<IDirect3DDevice9Ex> device;
hr = m_D3D9->CreateDeviceEx(
- uAdapterID,
+ adapterID,
D3DDEVTYPE_HAL,
pp.hDeviceWindow,
vp | D3DCREATE_NOWINDOWCHANGES | D3DCREATE_MULTITHREADED | D3DCREATE_FPU_PRESERVE,
&pp,
NULL,
- &device
+ device.address()
);
if (FAILED(hr))
- goto done;
+ return hr;
- hr = m_D3D9->GetAdapterDisplayMode(uAdapterID, &m_displayMode);
+ hr = m_D3D9->GetAdapterDisplayMode(adapterID, &m_displayMode);
if (FAILED(hr))
- goto done;
+ return hr;
- hr = m_devices->ResetDevice(device, m_deviceResetToken);
+ hr = m_devices->ResetDevice(device.get(), m_deviceResetToken);
if (FAILED(hr))
- goto done;
-
- qt_evr_safe_release(&m_device);
+ return hr;
m_device = device;
- m_device->AddRef();
-
-done:
- qt_evr_safe_release(&device);
return hr;
}
bool D3DPresentEngine::isValid() const
{
- return m_device != NULL;
+ return m_device.get() != nullptr;
}
void D3DPresentEngine::releaseResources()
@@ -252,10 +298,10 @@ HRESULT D3DPresentEngine::getService(REFGUID, REFIID riid, void** ppv)
HRESULT hr = S_OK;
if (riid == __uuidof(IDirect3DDeviceManager9)) {
- if (m_devices == NULL) {
+ if (!m_devices) {
hr = MF_E_UNSUPPORTED_SERVICE;
} else {
- *ppv = m_devices;
+ *ppv = m_devices.get();
m_devices->AddRef();
}
} else {
@@ -291,36 +337,15 @@ HRESULT D3DPresentEngine::checkFormat(D3DFORMAT format)
D3DRTYPE_SURFACE,
format);
- if (m_useTextureRendering && format != D3DFMT_X8R8G8B8 && format != D3DFMT_A8R8G8B8) {
- // The texture is always in RGB32 so the d3d driver must support conversion from the
- // requested format to RGB32.
- hr = m_D3D9->CheckDeviceFormatConversion(uAdapter, type, format, D3DFMT_X8R8G8B8);
- }
-
return hr;
}
-bool D3DPresentEngine::supportsTextureRendering() const
-{
- return false;
-}
-
-void D3DPresentEngine::setHint(Hint hint, bool enable)
-{
- if (hint == RenderToTexture)
- m_useTextureRendering = enable && supportsTextureRendering();
-}
-
HRESULT D3DPresentEngine::createVideoSamples(IMFMediaType *format, QList<IMFSample*> &videoSampleQueue)
{
- if (!format)
+ if (!format || !m_device)
return MF_E_UNEXPECTED;
HRESULT hr = S_OK;
-
- IDirect3DSurface9 *surface = NULL;
- IMFSample *videoSample = NULL;
-
releaseResources();
UINT32 width = 0, height = 0;
@@ -333,49 +358,66 @@ HRESULT D3DPresentEngine::createVideoSamples(IMFMediaType *format, QList<IMFSamp
if (FAILED(hr))
return hr;
- // Create the video samples.
+ // FIXME: RHI defines only RGBA, thus add the alpha channel to the selected format
+ if (d3dFormat == D3DFMT_X8R8G8B8)
+ d3dFormat = D3DFMT_A8R8G8B8;
+ else if (d3dFormat == D3DFMT_X8B8G8R8)
+ d3dFormat = D3DFMT_A8B8G8R8;
+
for (int i = 0; i < PRESENTER_BUFFER_COUNT; i++) {
- hr = m_device->CreateRenderTarget(width, height,
- (D3DFORMAT)d3dFormat,
- D3DMULTISAMPLE_NONE,
- 0,
- TRUE,
- &surface, NULL);
+ IDirect3DTexture9 *texture = nullptr;
+ HANDLE sharedHandle = nullptr;
+ hr = m_device->CreateTexture(width, height, 1, D3DUSAGE_RENDERTARGET, (D3DFORMAT)d3dFormat, D3DPOOL_DEFAULT, &texture, &sharedHandle);
if (FAILED(hr))
- goto done;
+ break;
- hr = MFCreateVideoSampleFromSurface(surface, &videoSample);
+ QWindowsIUPointer<IDirect3DSurface9> surface;
+ hr = texture->GetSurfaceLevel(0, surface.address());
if (FAILED(hr))
- goto done;
+ break;
- videoSample->AddRef();
- videoSampleQueue.append(videoSample);
+ QWindowsIUPointer<IMFSample> videoSample;
+ hr = MFCreateVideoSampleFromSurface(surface.get(), videoSample.address());
+ if (FAILED(hr))
+ break;
- qt_evr_safe_release(&videoSample);
- qt_evr_safe_release(&surface);
+ m_sampleTextureHandle[i] = {videoSample.get(), sharedHandle};
+ videoSampleQueue.append(videoSample.release());
}
-done:
if (SUCCEEDED(hr)) {
- m_surfaceFormat = QVideoFrameFormat(QSize(width, height),
- m_useTextureRendering ? QVideoFrameFormat::Format_BGRX8888
- : qt_evr_pixelFormatFromD3DFormat(d3dFormat));
+ m_surfaceFormat = QVideoFrameFormat(QSize(width, height), qt_evr_pixelFormatFromD3DFormat(d3dFormat));
} else {
releaseResources();
}
- qt_evr_safe_release(&videoSample);
- qt_evr_safe_release(&surface);
return hr;
}
QVideoFrame D3DPresentEngine::makeVideoFrame(IMFSample *sample)
{
if (!sample)
- return QVideoFrame();
+ return {};
+
+ HANDLE sharedHandle = nullptr;
+ for (const auto &p : m_sampleTextureHandle)
+ if (p.first == sample)
+ sharedHandle = p.second;
+
+ QWindowsIUPointer<ID3D11Texture2D> d3d11tex;
+ if (m_useTextureRendering && sharedHandle && m_sink->rhi()) {
+ auto nh = static_cast<const QRhiD3D11NativeHandles*>(m_sink->rhi()->nativeHandles());
+ if (nh) {
+ auto dev = reinterpret_cast<ID3D11Device *>(nh->dev);
+ if (dev) {
+ HRESULT hr = dev->OpenSharedResource(sharedHandle, __uuidof(ID3D11Texture2D), (void**)(d3d11tex.address()));
+ if (FAILED(hr))
+ qWarning() << "Failed to obtain D3D11Texture2D from D3D9Texture2D handle";
+ }
+ }
+ }
- QVideoFrame frame(new IMFSampleVideoBuffer(this, sample, (m_useTextureRendering ? QVideoFrame::RhiTextureHandle : QVideoFrame::NoHandle)),
- m_surfaceFormat);
+ QVideoFrame frame(new IMFSampleVideoBuffer(m_device, sample, d3d11tex), m_surfaceFormat);
// WMF uses 100-nanosecond units, Qt uses microseconds
LONGLONG startTime = 0;
diff --git a/src/multimedia/platform/windows/evr/evrd3dpresentengine_p.h b/src/multimedia/platform/windows/evr/evrd3dpresentengine_p.h
index 6b8353c53..1ab0af26c 100644
--- a/src/multimedia/platform/windows/evr/evrd3dpresentengine_p.h
+++ b/src/multimedia/platform/windows/evr/evrd3dpresentengine_p.h
@@ -53,6 +53,7 @@
#include <QMutex>
#include <QVideoFrameFormat>
+#include <private/qwindowsiupointer_p.h>
#include <d3d9.h>
@@ -66,6 +67,7 @@ struct IMFMediaType;
QT_BEGIN_NAMESPACE
class QVideoFrame;
+class QVideoSink;
QT_END_NAMESPACE
// Randomly generated GUIDs
@@ -110,45 +112,41 @@ class D3DPresentEngine
{
Q_DISABLE_COPY(D3DPresentEngine)
public:
- enum Hint
- {
- RenderToTexture
- };
-
- D3DPresentEngine();
+ D3DPresentEngine(QVideoSink *sink);
virtual ~D3DPresentEngine();
bool isValid() const;
- void setHint(Hint hint, bool enable = true);
HRESULT getService(REFGUID guidService, REFIID riid, void** ppv);
HRESULT checkFormat(D3DFORMAT format);
UINT refreshRate() const { return m_displayMode.RefreshRate; }
- bool supportsTextureRendering() const;
- bool isTextureRenderingEnabled() const { return m_useTextureRendering; }
-
HRESULT createVideoSamples(IMFMediaType *format, QList<IMFSample*>& videoSampleQueue);
QVideoFrameFormat videoSurfaceFormat() const { return m_surfaceFormat; }
QVideoFrame makeVideoFrame(IMFSample* sample);
void releaseResources();
+ void setSink(QVideoSink *sink);
private:
+ static const int PRESENTER_BUFFER_COUNT = 3;
+
HRESULT initializeD3D();
HRESULT createD3DDevice();
+ std::pair<IMFSample *, HANDLE> m_sampleTextureHandle[PRESENTER_BUFFER_COUNT] = {};
UINT m_deviceResetToken;
D3DDISPLAYMODE m_displayMode;
- IDirect3D9Ex *m_D3D9;
- IDirect3DDevice9Ex *m_device;
- IDirect3DDeviceManager9 *m_devices;
+ QWindowsIUPointer<IDirect3D9Ex> m_D3D9;
+ QWindowsIUPointer<IDirect3DDevice9Ex> m_device;
+ QWindowsIUPointer<IDirect3DDeviceManager9> m_devices;
QVideoFrameFormat m_surfaceFormat;
- bool m_useTextureRendering;
+ class QVideoSink *m_sink = nullptr;
+ bool m_useTextureRendering = false;
#ifdef MAYBE_ANGLE
unsigned int updateTexture(IDirect3DSurface9 *src);
diff --git a/src/multimedia/platform/windows/evr/evrhelpers.cpp b/src/multimedia/platform/windows/evr/evrhelpers.cpp
index 3f2059585..53e68d619 100644
--- a/src/multimedia/platform/windows/evr/evrhelpers.cpp
+++ b/src/multimedia/platform/windows/evr/evrhelpers.cpp
@@ -147,6 +147,8 @@ QVideoFrameFormat::PixelFormat qt_evr_pixelFormatFromD3DFormat(DWORD format)
D3DFORMAT qt_evr_D3DFormatFromPixelFormat(QVideoFrameFormat::PixelFormat format)
{
switch (format) {
+ case QVideoFrameFormat::Format_ARGB8888:
+ return D3DFMT_A8B8G8R8;
case QVideoFrameFormat::Format_BGRA8888:
return D3DFMT_A8R8G8B8;
case QVideoFrameFormat::Format_BGRX8888:
diff --git a/src/multimedia/platform/windows/player/mfvideorenderercontrol.cpp b/src/multimedia/platform/windows/player/mfvideorenderercontrol.cpp
index 3124391d4..0c028933c 100644
--- a/src/multimedia/platform/windows/player/mfvideorenderercontrol.cpp
+++ b/src/multimedia/platform/windows/player/mfvideorenderercontrol.cpp
@@ -2127,7 +2127,7 @@ namespace
class EVRCustomPresenterActivate : public MFAbstractActivate
{
public:
- EVRCustomPresenterActivate();
+ EVRCustomPresenterActivate(QVideoSink *sink);
~EVRCustomPresenterActivate()
{ }
@@ -2235,7 +2235,7 @@ IMFActivate* MFVideoRendererControl::createActivate()
if (m_sink) {
// Create the EVR media sink, but replace the presenter with our own
if (SUCCEEDED(MFCreateVideoRendererActivate(::GetShellWindow(), &m_currentActivate))) {
- m_presenterActivate = new EVRCustomPresenterActivate;
+ m_presenterActivate = new EVRCustomPresenterActivate(m_sink);
m_currentActivate->SetUnknown(MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_ACTIVATE, m_presenterActivate);
} else {
m_currentActivate = new VideoRendererActivate(this);
@@ -2248,10 +2248,10 @@ IMFActivate* MFVideoRendererControl::createActivate()
}
-EVRCustomPresenterActivate::EVRCustomPresenterActivate()
+EVRCustomPresenterActivate::EVRCustomPresenterActivate(QVideoSink *sink)
: MFAbstractActivate()
, m_presenter(0)
- , m_videoSink(0)
+ , m_videoSink(sink)
{ }
HRESULT EVRCustomPresenterActivate::ActivateObject(REFIID riid, void **ppv)
@@ -2260,9 +2260,7 @@ HRESULT EVRCustomPresenterActivate::ActivateObject(REFIID riid, void **ppv)
return E_INVALIDARG;
QMutexLocker locker(&m_mutex);
if (!m_presenter) {
- m_presenter = new EVRCustomPresenter;
- if (m_videoSink)
- m_presenter->setSink(m_videoSink);
+ m_presenter = new EVRCustomPresenter(m_videoSink);
}
return m_presenter->QueryInterface(riid, ppv);
}