diff options
author | Piotr Srebrny <piotr.srebrny@qt.io> | 2022-03-23 12:33:59 +0100 |
---|---|---|
committer | Piotr Srebrny <piotr.srebrny@qt.io> | 2022-03-24 14:15:15 +0100 |
commit | 0f93554536655e8841d137a330f7048e747d0989 (patch) | |
tree | 3fdb9c77f229b51a57eef4ab0306ceb76562727f | |
parent | 71ff0feb8b6fee4182c90ff94be56c9b73e1c615 (diff) | |
download | qtmultimedia-0f93554536655e8841d137a330f7048e747d0989.tar.gz |
Provide QRhiTexture from QVideoFrame on windows backend
This patch implements a converion of OpenGL and D3D11 texture handles
to QRhiTexture in when creating the QVideoFrame on the Windows backend.
Additional, the patch explicitly states that the only supported fromats
are RGB8. D3D9 can use also RGB5 and RGB10A2. However, the RHI side
does not support RGB5. RGB10A2 could be added if required.
Change-Id: I4fa46988e7402926c99159ca5fbd597f1821eab0
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
-rw-r--r-- | src/multimedia/video/qabstractvideobuffer.cpp | 6 | ||||
-rw-r--r-- | src/multimedia/video/qabstractvideobuffer_p.h | 4 | ||||
-rw-r--r-- | src/multimedia/video/qvideoframe.cpp | 7 | ||||
-rw-r--r-- | src/plugins/multimedia/windows/evr/evrd3dpresentengine.cpp | 46 |
4 files changed, 56 insertions, 7 deletions
diff --git a/src/multimedia/video/qabstractvideobuffer.cpp b/src/multimedia/video/qabstractvideobuffer.cpp index b97a28fe1..dc6f77212 100644 --- a/src/multimedia/video/qabstractvideobuffer.cpp +++ b/src/multimedia/video/qabstractvideobuffer.cpp @@ -40,6 +40,7 @@ #include "qabstractvideobuffer_p.h" #include <qvariant.h> +#include <private/qrhi_p.h> #include <QDebug> @@ -135,6 +136,11 @@ QVideoFrame::HandleType QAbstractVideoBuffer::handleType() const return m_type; } +std::unique_ptr<QRhiTexture> QAbstractVideoBuffer::texture(int /*plane*/) const +{ + return {}; +} + /*! \fn uchar *QAbstractVideoBuffer::map(MapMode mode, int *numBytes, int *bytesPerLine) Independently maps the planes of a video buffer to memory. diff --git a/src/multimedia/video/qabstractvideobuffer_p.h b/src/multimedia/video/qabstractvideobuffer_p.h index f8cf74a28..af9af5b75 100644 --- a/src/multimedia/video/qabstractvideobuffer_p.h +++ b/src/multimedia/video/qabstractvideobuffer_p.h @@ -58,11 +58,14 @@ #include <QtGui/qmatrix4x4.h> #include <QtCore/private/qglobal_p.h> +#include <memory> + QT_BEGIN_NAMESPACE class QVariant; class QRhi; +class QRhiTexture; class Q_MULTIMEDIA_EXPORT QAbstractVideoBuffer { @@ -86,6 +89,7 @@ public: virtual void mapTextures() {} virtual quint64 textureHandle(int /*plane*/) const { return 0; } + virtual std::unique_ptr<QRhiTexture> texture(int /*plane*/) const; virtual QMatrix4x4 externalTextureMatrix() const { return {}; } protected: diff --git a/src/multimedia/video/qvideoframe.cpp b/src/multimedia/video/qvideoframe.cpp index b639bafae..6ad601c5e 100644 --- a/src/multimedia/video/qvideoframe.cpp +++ b/src/multimedia/video/qvideoframe.cpp @@ -655,9 +655,12 @@ quint64 QVideoFrame::textureHandle(int plane) const \internal Returns a QRhiTexture of the video frame */ -std::unique_ptr<QRhiTexture> QVideoFrame::rhiTexture(int /* plane */) const +std::unique_ptr<QRhiTexture> QVideoFrame::rhiTexture(int plane) const { - return {}; + if (!d || !d->buffer) + return {}; + d->buffer->mapTextures(); + return d->buffer->texture(plane); } /*! diff --git a/src/plugins/multimedia/windows/evr/evrd3dpresentengine.cpp b/src/plugins/multimedia/windows/evr/evrd3dpresentengine.cpp index 38733734a..88bb8ebb8 100644 --- a/src/plugins/multimedia/windows/evr/evrd3dpresentengine.cpp +++ b/src/plugins/multimedia/windows/evr/evrd3dpresentengine.cpp @@ -159,9 +159,23 @@ public: , m_d2d11tex(d2d11tex) {} - quint64 textureHandle(int plane) const override + std::unique_ptr<QRhiTexture> texture(int plane) const override { - return plane == 0 ? quint64(m_d2d11tex.get()) : 0; + if (!rhi || !m_d2d11tex || plane > 0) + return {}; + D3D11_TEXTURE2D_DESC desc = {}; + m_d2d11tex->GetDesc(&desc); + QRhiTexture::Format format; + if (desc.Format == DXGI_FORMAT_B8G8R8A8_UNORM) + format = QRhiTexture::BGRA8; + else if (desc.Format == DXGI_FORMAT_R8G8B8A8_UNORM) + format = QRhiTexture::RGBA8; + else + return {}; + + std::unique_ptr<QRhiTexture> tex(rhi->newTexture(format, QSize{int(desc.Width), int(desc.Height)}, 1, {})); + tex->createFrom({quint64(m_d2d11tex.get()), 0}); + return tex; } private: @@ -258,9 +272,24 @@ public: } } - quint64 textureHandle(int plane) const override + std::unique_ptr<QRhiTexture> texture(int plane) const override { - return plane == 0 ? quint64(m_glTextureName) : 0; + if (!rhi || !m_texture || plane > 0) + return {}; + + D3DSURFACE_DESC desc; + m_texture->GetLevelDesc(0, &desc); + QRhiTexture::Format format; + if (desc.Format == D3DFMT_A8R8G8B8) + format = QRhiTexture::BGRA8; + else if (desc.Format == D3DFMT_A8B8G8R8) + format = QRhiTexture::RGBA8; + else + return {}; + + std::unique_ptr<QRhiTexture> tex(rhi->newTexture(format, QSize{int(desc.Width), int(desc.Height)}, 1, {})); + tex->createFrom({quint64(m_glTextureName), 0}); + return tex; } private: @@ -507,8 +536,15 @@ HRESULT D3DPresentEngine::checkFormat(D3DFORMAT format) D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, format); + if (FAILED(hr)) + return hr; - return hr; + bool ok = format == D3DFMT_X8R8G8B8 + || format == D3DFMT_A8R8G8B8 + || format == D3DFMT_X8B8G8R8 + || format == D3DFMT_A8B8G8R8; + + return ok ? S_OK : D3DERR_NOTAVAILABLE; } HRESULT D3DPresentEngine::createVideoSamples(IMFMediaType *format, QList<IMFSample*> &videoSampleQueue) |