summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPiotr Srebrny <piotr.srebrny@qt.io>2022-03-23 12:33:59 +0100
committerPiotr Srebrny <piotr.srebrny@qt.io>2022-03-24 14:15:15 +0100
commit0f93554536655e8841d137a330f7048e747d0989 (patch)
tree3fdb9c77f229b51a57eef4ab0306ceb76562727f
parent71ff0feb8b6fee4182c90ff94be56c9b73e1c615 (diff)
downloadqtmultimedia-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.cpp6
-rw-r--r--src/multimedia/video/qabstractvideobuffer_p.h4
-rw-r--r--src/multimedia/video/qvideoframe.cpp7
-rw-r--r--src/plugins/multimedia/windows/evr/evrd3dpresentengine.cpp46
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)