diff options
-rw-r--r-- | src/gsttools/qgstutils.cpp | 2 | ||||
-rw-r--r-- | src/multimedia/video/qvideoframe.cpp | 17 | ||||
-rw-r--r-- | src/multimedia/video/qvideoframe.h | 1 | ||||
-rw-r--r-- | src/qtmultimediaquicktools/qsgvideonode_yuv.cpp | 19 | ||||
-rw-r--r-- | tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp | 1 |
5 files changed, 29 insertions, 11 deletions
diff --git a/src/gsttools/qgstutils.cpp b/src/gsttools/qgstutils.cpp index 06f277766..258cbb404 100644 --- a/src/gsttools/qgstutils.cpp +++ b/src/gsttools/qgstutils.cpp @@ -1034,6 +1034,7 @@ struct VideoFormat static const VideoFormat qt_videoFormatLookup[] = { { QVideoFrame::Format_YUV420P, GST_VIDEO_FORMAT_I420 }, + { QVideoFrame::Format_YUV422P, GST_VIDEO_FORMAT_Y42B }, { QVideoFrame::Format_YV12 , GST_VIDEO_FORMAT_YV12 }, { QVideoFrame::Format_UYVY , GST_VIDEO_FORMAT_UYVY }, { QVideoFrame::Format_YUYV , GST_VIDEO_FORMAT_YUY2 }, @@ -1086,6 +1087,7 @@ struct YuvFormat static const YuvFormat qt_yuvColorLookup[] = { { QVideoFrame::Format_YUV420P, GST_MAKE_FOURCC('I','4','2','0'), 8 }, + { QVideoFrame::Format_YUV422P, GST_MAKE_FOURCC('Y','4','2','B'), 8 }, { QVideoFrame::Format_YV12, GST_MAKE_FOURCC('Y','V','1','2'), 8 }, { QVideoFrame::Format_UYVY, GST_MAKE_FOURCC('U','Y','V','Y'), 16 }, { QVideoFrame::Format_YUYV, GST_MAKE_FOURCC('Y','U','Y','2'), 16 }, diff --git a/src/multimedia/video/qvideoframe.cpp b/src/multimedia/video/qvideoframe.cpp index e94b838f9..dfc6ad3ee 100644 --- a/src/multimedia/video/qvideoframe.cpp +++ b/src/multimedia/video/qvideoframe.cpp @@ -227,6 +227,11 @@ private: horizontally and vertically sub-sampled, i.e. the height and width of the U and V planes are half that of the Y plane. + \value Format_YUV422P + The frame is stored using an 8-bit per component planar YUV format with the U and V planes + horizontally sub-sampled, i.e. the width of the U and V planes are + half that of the Y plane, and height of U and V planes is the same as Y. + \value Format_YV12 The frame is stored using an 8-bit per component planar YVU format with the V and U planes horizontally and vertically sub-sampled, i.e. the height and width of the V and U planes are @@ -638,6 +643,7 @@ bool QVideoFrame::map(QAbstractVideoBuffer::MapMode mode) // Single plane or opaque format. break; case Format_YUV420P: + case Format_YUV422P: case Format_YV12: { // The UV stride is usually half the Y stride and is 32-bit aligned. // However it's not always the case, at least on Windows where the @@ -646,13 +652,14 @@ bool QVideoFrame::map(QAbstractVideoBuffer::MapMode mode) // have a correct stride. const int height = d->size.height(); const int yStride = d->bytesPerLine[0]; - const int uvStride = (d->mappedBytes - (yStride * height)) / height; + const int uvHeight = d->pixelFormat == Format_YUV422P ? height : height / 2; + const int uvStride = (d->mappedBytes - (yStride * height)) / uvHeight / 2; - // Three planes, the second and third vertically and horizontally subsampled. + // Three planes, the second and third vertically (and horizontally for other than Format_YUV422P formats) subsampled. d->planeCount = 3; d->bytesPerLine[2] = d->bytesPerLine[1] = uvStride; d->data[1] = d->data[0] + (yStride * height); - d->data[2] = d->data[1] + (uvStride * height / 2); + d->data[2] = d->data[1] + (uvStride * uvHeight); break; } case Format_NV12: @@ -1001,6 +1008,7 @@ QImage::Format QVideoFrame::imageFormatFromPixelFormat(PixelFormat format) case Format_AYUV444_Premultiplied: case Format_YUV444: case Format_YUV420P: + case Format_YUV422P: case Format_YV12: case Format_UYVY: case Format_YUYV: @@ -1058,6 +1066,7 @@ static VideoFrameConvertFunc qConvertFuncs[QVideoFrame::NPixelFormats] = { /* Format_AYUV444_Premultiplied */ nullptr, /* Format_YUV444 */ qt_convert_YUV444_to_ARGB32, /* Format_YUV420P */ qt_convert_YUV420P_to_ARGB32, + /* Format_YUV422P */ nullptr, /* Format_YV12 */ qt_convert_YV12_to_ARGB32, /* Format_UYVY */ qt_convert_UYVY_to_ARGB32, /* Format_YUYV */ qt_convert_YUYV_to_ARGB32, @@ -1191,6 +1200,8 @@ QDebug operator<<(QDebug dbg, QVideoFrame::PixelFormat pf) return dbg << "Format_YUV444"; case QVideoFrame::Format_YUV420P: return dbg << "Format_YUV420P"; + case QVideoFrame::Format_YUV422P: + return dbg << "Format_YUV422P"; case QVideoFrame::Format_YV12: return dbg << "Format_YV12"; case QVideoFrame::Format_UYVY: diff --git a/src/multimedia/video/qvideoframe.h b/src/multimedia/video/qvideoframe.h index 375f80dac..b0710cd27 100644 --- a/src/multimedia/video/qvideoframe.h +++ b/src/multimedia/video/qvideoframe.h @@ -86,6 +86,7 @@ public: Format_AYUV444_Premultiplied, Format_YUV444, Format_YUV420P, + Format_YUV422P, Format_YV12, Format_UYVY, Format_YUYV, diff --git a/src/qtmultimediaquicktools/qsgvideonode_yuv.cpp b/src/qtmultimediaquicktools/qsgvideonode_yuv.cpp index 8e4ea01a1..f07362bf1 100644 --- a/src/qtmultimediaquicktools/qsgvideonode_yuv.cpp +++ b/src/qtmultimediaquicktools/qsgvideonode_yuv.cpp @@ -74,7 +74,7 @@ QList<QVideoFrame::PixelFormat> QSGVideoNodeFactory_YUV::supportedPixelFormats( QList<QVideoFrame::PixelFormat> formats; if (handleType == QAbstractVideoBuffer::NoHandle) { - formats << QVideoFrame::Format_YUV420P << QVideoFrame::Format_YV12 + formats << QVideoFrame::Format_YUV420P << QVideoFrame::Format_YV12 << QVideoFrame::Format_YUV422P << QVideoFrame::Format_NV12 << QVideoFrame::Format_NV21 << QVideoFrame::Format_UYVY << QVideoFrame::Format_YUYV; } @@ -235,7 +235,7 @@ public: return &uyvyType; case QVideoFrame::Format_YUYV: return &yuyvType; - default: // Currently: YUV420P and YV12 + default: // Currently: YUV420P, YUV422P and YV12 return &triPlanarType; } } @@ -250,7 +250,7 @@ public: return new QSGVideoMaterialShader_UYVY; case QVideoFrame::Format_YUYV: return new QSGVideoMaterialShader_YUYV; - default: // Currently: YUV420P and YV12 + default: // Currently: YUV420P, YUV422P and YV12 return new QSGVideoMaterialShader_YUV_TriPlanar; } } @@ -308,6 +308,7 @@ QSGVideoMaterial_YUV::QSGVideoMaterial_YUV(const QVideoSurfaceFormat &format) : break; case QVideoFrame::Format_YUV420P: case QVideoFrame::Format_YV12: + case QVideoFrame::Format_YUV422P: m_planeCount = 3; break; case QVideoFrame::Format_UYVY: @@ -408,18 +409,20 @@ void QSGVideoMaterial_YUV::bind() functions->glActiveTexture(GL_TEXTURE0); // Finish with 0 as default texture unit bindTexture(m_textureIds[0], m_frame.bytesPerLine(y), fh, m_frame.bits(y), texFormat1); - } else { // YUV420P || YV12 + } else { // YUV420P || YV12 || YUV422P const int y = 0; - const int u = m_frame.pixelFormat() == QVideoFrame::Format_YUV420P ? 1 : 2; - const int v = m_frame.pixelFormat() == QVideoFrame::Format_YUV420P ? 2 : 1; + const int u = m_frame.pixelFormat() == QVideoFrame::Format_YV12 ? 2 : 1; + const int v = m_frame.pixelFormat() == QVideoFrame::Format_YV12 ? 1 : 2; m_planeWidth[0] = qreal(fw) / m_frame.bytesPerLine(y); m_planeWidth[1] = m_planeWidth[2] = qreal(fw) / (2 * m_frame.bytesPerLine(u)); + const int uvHeight = m_frame.pixelFormat() == QVideoFrame::Format_YUV422P ? fh : fh / 2; + functions->glActiveTexture(GL_TEXTURE1); - bindTexture(m_textureIds[1], m_frame.bytesPerLine(u), fh / 2, m_frame.bits(u), texFormat1); + bindTexture(m_textureIds[1], m_frame.bytesPerLine(u), uvHeight, m_frame.bits(u), texFormat1); functions->glActiveTexture(GL_TEXTURE2); - bindTexture(m_textureIds[2], m_frame.bytesPerLine(v), fh / 2, m_frame.bits(v), texFormat1); + bindTexture(m_textureIds[2], m_frame.bytesPerLine(v), uvHeight, m_frame.bits(v), texFormat1); functions->glActiveTexture(GL_TEXTURE0); // Finish with 0 as default texture unit bindTexture(m_textureIds[0], m_frame.bytesPerLine(y), fh, m_frame.bits(y), texFormat1); } diff --git a/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp b/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp index 25430a189..a776602a0 100644 --- a/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp +++ b/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp @@ -1348,6 +1348,7 @@ void tst_QMediaPlayerBackend::surfaceTest_data() QList<QVideoFrame::PixelFormat> formatsYUV; formatsYUV << QVideoFrame::Format_YUV420P + << QVideoFrame::Format_YUV422P << QVideoFrame::Format_YV12 << QVideoFrame::Format_UYVY << QVideoFrame::Format_YUYV |