From 7ebd95868747b304f1695fe1e7f25df73774b1dc Mon Sep 17 00:00:00 2001 From: VaL Doroshchuk Date: Sat, 29 Aug 2020 15:28:34 +0200 Subject: Quick: Introduce multiple textures for NV12/NV21 video frames For QVideoFrame::Format_NV12 and Format_NV21 formats added a possibility to provide the video frames in QAbstractVideoBuffer::GLTextureHandle, MTLTextureHandle multiple textures. Currently QVideoFrame::handle() is used to have only one texture. Which limits the video frames only for RGBA format. NV12/NV21 requires 2 textures, one for chroma and for luma components. So QVideoFrane::handle() must return a list with 2 native handlers. The patch allows to render the video frames in NV12/NV21 formats with multiple textures, using current QSGTexture's to avoid uploading/downloading the data. Change-Id: I3e6e734948a43dc77bfd2dcacb69cf8ffefdb813 Reviewed-by: Laszlo Agocs --- src/qtmultimediaquicktools/qsgvideonode_yuv.cpp | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/qtmultimediaquicktools/qsgvideonode_yuv.cpp b/src/qtmultimediaquicktools/qsgvideonode_yuv.cpp index 40eed8fbb..bce757584 100644 --- a/src/qtmultimediaquicktools/qsgvideonode_yuv.cpp +++ b/src/qtmultimediaquicktools/qsgvideonode_yuv.cpp @@ -52,6 +52,10 @@ QList QSGVideoNodeFactory_YUV::supportedPixelFormats( formats << QVideoFrame::Format_YUV420P << QVideoFrame::Format_YV12 << QVideoFrame::Format_YUV422P << QVideoFrame::Format_NV12 << QVideoFrame::Format_NV21 << QVideoFrame::Format_UYVY << QVideoFrame::Format_YUYV; + } else if (handleType == QAbstractVideoBuffer::GLTextureHandle) { + formats << QVideoFrame::Format_NV12 << QVideoFrame::Format_NV21; + } else if (handleType == QAbstractVideoBuffer::MTLTextureHandle) { + formats << QVideoFrame::Format_NV12 << QVideoFrame::Format_NV21; } return formats; @@ -311,7 +315,25 @@ void QSGVideoMaterialRhiShader_YUV_YV::mapFrame(QSGVideoMaterial_YUV *m) void QSGVideoMaterialRhiShader_NV12::mapFrame(QSGVideoMaterial_YUV *m) { - if (!m->m_frame.isValid() || !m->m_frame.map(QAbstractVideoBuffer::ReadOnly)) + if (!m->m_frame.isValid()) + return; + + if (m->m_frame.handleType() == QAbstractVideoBuffer::GLTextureHandle || m->m_frame.handleType() == QAbstractVideoBuffer::MTLTextureHandle) { + m->m_planeWidth[0] = m->m_planeWidth[1] = 1; + auto textures = m->m_frame.handle().toList(); + if (!textures.isEmpty()) { + auto w = m->m_frame.size().width(); + auto h = m->m_frame.size().height(); + m->m_textures[0]->setNativeObject(textures[0].toULongLong(), {w, h}); + m->m_textures[1]->setNativeObject(textures[1].toULongLong(), {w / 2, h / 2}); + } else { + qWarning() << "NV12/NV21 requires 2 textures"; + } + + return; + } + + if (!m->m_frame.map(QAbstractVideoBuffer::ReadOnly)) return; int y = 0; -- cgit v1.2.3