From 59d0683c999bec5612f6ba91867bde4d02185204 Mon Sep 17 00:00:00 2001 From: VaL Doroshchuk Date: Fri, 11 Oct 2019 11:51:14 +0200 Subject: Introduce QVideoFrame::image() Since QVideoFrame::pixelFormat's do not 100% match QImage::Format's, introducing converstion function. Returns an image based on current frame. Converts data if needed to supported QImage format. Change-Id: I3331578c01cf9c999a380efc4a83bf9eddb07901 (cherry picked from commit 93f966335e1ed8ed47b7e8b32452d43c2f8a7bb1) Reviewed-by: Daniel Smith Reviewed-by: Volker Hilsheimer --- .../qcamerabackend/tst_qcamerabackend.cpp | 5 +- tests/auto/unit/qvideoframe/BLACKLIST | 2 + tests/auto/unit/qvideoframe/tst_qvideoframe.cpp | 169 +++++++++++++++++++++ 3 files changed, 173 insertions(+), 3 deletions(-) create mode 100644 tests/auto/unit/qvideoframe/BLACKLIST (limited to 'tests') diff --git a/tests/auto/integration/qcamerabackend/tst_qcamerabackend.cpp b/tests/auto/integration/qcamerabackend/tst_qcamerabackend.cpp index 894486230..27fc014aa 100644 --- a/tests/auto/integration/qcamerabackend/tst_qcamerabackend.cpp +++ b/tests/auto/integration/qcamerabackend/tst_qcamerabackend.cpp @@ -49,7 +49,6 @@ #include #include #include -#include QT_USE_NAMESPACE @@ -451,7 +450,7 @@ void tst_QCameraBackend::testCaptureToBuffer() QCOMPARE(imageAvailableSignal.first().first().toInt(), id); QVideoFrame frame = imageAvailableSignal.first().last().value(); - QVERIFY(!qt_imageFromVideoFrame(frame).isNull()); + QVERIFY(!frame.image().isNull()); frame = QVideoFrame(); capturedSignal.clear(); @@ -509,7 +508,7 @@ void tst_QCameraBackend::testCaptureToBuffer() QCOMPARE(imageAvailableSignal.first().first().toInt(), id); frame = imageAvailableSignal.first().last().value(); - QVERIFY(!qt_imageFromVideoFrame(frame).isNull()); + QVERIFY(!frame.image().isNull()); QString fileName = savedSignal.first().last().toString(); QVERIFY(QFileInfo(fileName).exists()); diff --git a/tests/auto/unit/qvideoframe/BLACKLIST b/tests/auto/unit/qvideoframe/BLACKLIST new file mode 100644 index 000000000..1fa752da5 --- /dev/null +++ b/tests/auto/unit/qvideoframe/BLACKLIST @@ -0,0 +1,2 @@ +[image:64x64 AYUV444,64x64 YUV444,64x64 YUV420P,64x64 YV12,64x64 UYVY,64x64 YUYV,64x64 NV12,64x64 NV21] +windows-10 ci diff --git a/tests/auto/unit/qvideoframe/tst_qvideoframe.cpp b/tests/auto/unit/qvideoframe/tst_qvideoframe.cpp index 6be039108..de9295c33 100644 --- a/tests/auto/unit/qvideoframe/tst_qvideoframe.cpp +++ b/tests/auto/unit/qvideoframe/tst_qvideoframe.cpp @@ -85,6 +85,9 @@ private slots: void isMapped(); void isReadable(); void isWritable(); + + void image_data(); + void image(); }; Q_DECLARE_METATYPE(QImage::Format) @@ -1128,6 +1131,172 @@ void tst_QVideoFrame::isWritable() frame.unmap(); } +void tst_QVideoFrame::image_data() +{ + QTest::addColumn("size"); + QTest::addColumn("pixelFormat"); + QTest::addColumn("bytes"); + QTest::addColumn("bytesPerLine"); + QTest::addColumn("imageFormat"); + + QTest::newRow("64x64 ARGB32") + << QSize(64, 64) + << QVideoFrame::Format_ARGB32 + << 16384 + << 256 + << QImage::Format_ARGB32; + + QTest::newRow("64x64 ARGB32_Premultiplied") + << QSize(64, 64) + << QVideoFrame::Format_ARGB32_Premultiplied + << 16384 + << 256 + << QImage::Format_ARGB32_Premultiplied; + + QTest::newRow("64x64 RGB32") + << QSize(64, 64) + << QVideoFrame::Format_RGB32 + << 16384 + << 256 + << QImage::Format_RGB32; + + QTest::newRow("64x64 RGB24") + << QSize(64, 64) + << QVideoFrame::Format_RGB24 + << 16384 + << 192 + << QImage::Format_RGB888; + + QTest::newRow("64x64 RGB565") + << QSize(64, 64) + << QVideoFrame::Format_RGB565 + << 16384 + << 128 + << QImage::Format_RGB16; + + QTest::newRow("64x64 RGB555") + << QSize(64, 64) + << QVideoFrame::Format_RGB555 + << 16384 + << 128 + << QImage::Format_RGB555; + + QTest::newRow("64x64 BGRA32") + << QSize(64, 64) + << QVideoFrame::Format_BGRA32 + << 16384 + << 256 + << QImage::Format_ARGB32; + + QTest::newRow("64x64 BGRA32_Premultiplied") + << QSize(64, 64) + << QVideoFrame::Format_BGRA32_Premultiplied + << 16384 + << 256 + << QImage::Format_ARGB32; + + QTest::newRow("64x64 BGR32") + << QSize(64, 64) + << QVideoFrame::Format_BGR32 + << 16384 + << 256 + << QImage::Format_ARGB32; + + QTest::newRow("64x64 BGR24") + << QSize(64, 64) + << QVideoFrame::Format_BGR24 + << 16384 + << 256 + << QImage::Format_ARGB32; + + QTest::newRow("64x64 BGR565") + << QSize(64, 64) + << QVideoFrame::Format_BGR565 + << 16384 + << 256 + << QImage::Format_ARGB32; + + QTest::newRow("64x64 BGR555") + << QSize(64, 64) + << QVideoFrame::Format_BGR555 + << 16384 + << 256 + << QImage::Format_ARGB32; + + QTest::newRow("64x64 AYUV444") + << QSize(64, 64) + << QVideoFrame::Format_AYUV444 + << 16384 + << 256 + << QImage::Format_ARGB32; + + QTest::newRow("64x64 YUV444") + << QSize(64, 64) + << QVideoFrame::Format_YUV444 + << 16384 + << 256 + << QImage::Format_ARGB32; + + QTest::newRow("64x64 YUV420P") + << QSize(64, 64) + << QVideoFrame::Format_YUV420P + << 13288 + << 256 + << QImage::Format_ARGB32; + + QTest::newRow("64x64 YV12") + << QSize(64, 64) + << QVideoFrame::Format_YV12 + << 16384 + << 256 + << QImage::Format_ARGB32; + + QTest::newRow("64x64 UYVY") + << QSize(64, 64) + << QVideoFrame::Format_UYVY + << 16384 + << 256 + << QImage::Format_ARGB32; + + QTest::newRow("64x64 YUYV") + << QSize(64, 64) + << QVideoFrame::Format_YUYV + << 16384 + << 256 + << QImage::Format_ARGB32; + + QTest::newRow("64x64 NV12") + << QSize(64, 64) + << QVideoFrame::Format_NV12 + << 16384 + << 256 + << QImage::Format_ARGB32; + + QTest::newRow("64x64 NV21") + << QSize(64, 64) + << QVideoFrame::Format_NV21 + << 16384 + << 256 + << QImage::Format_ARGB32; +} + +void tst_QVideoFrame::image() +{ + QFETCH(QSize, size); + QFETCH(QVideoFrame::PixelFormat, pixelFormat); + QFETCH(int, bytes); + QFETCH(int, bytesPerLine); + QFETCH(QImage::Format, imageFormat); + + QVideoFrame frame(bytes, size, bytesPerLine, pixelFormat); + QImage img = frame.image(); + + QVERIFY(!img.isNull()); + QCOMPARE(img.format(), imageFormat); + QCOMPARE(img.size(), size); + QCOMPARE(img.bytesPerLine(), bytesPerLine); +} + QTEST_MAIN(tst_QVideoFrame) #include "tst_qvideoframe.moc" -- cgit v1.2.3 From cb8f5067a2fdf73f4f5b71ab3c7bcc65dc13c387 Mon Sep 17 00:00:00 2001 From: VaL Doroshchuk Date: Mon, 28 Oct 2019 12:23:15 +0100 Subject: Introduce rendering to multiple surfaces QAbstractVideoSurface is used to retrieve and render video frames in particular pixel format. I.e. a backend takes one video surface which asks to provide video frames in one of the supported formats returned from QAbstractVideoSurface::supportedPixelFormats(). So currently there is one source of the video frames and only one video output possible. Introducing QMediaPlayer::setVideoOutput(const QVector &) This func takes a list of surfaces, that support at least one shared pixel format, and presents video frames to all of them at the same time. Several surfaces, which do not have any shared pixel formats, will fail to work. Task-number: QTBUG-32939 Change-Id: Ifbdaf692755353fbd5bf3ad74baba1820e3d0237 Reviewed-by: Volker Hilsheimer --- .../tst_qmediaplayerbackend.cpp | 28 ++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'tests') diff --git a/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp b/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp index 9cd3b7fa9..f1be070e8 100644 --- a/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp +++ b/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp @@ -78,6 +78,7 @@ private slots: void playlistObject(); void surfaceTest_data(); void surfaceTest(); + void multipleSurfaces(); void metadata(); void playerStateAtEOS(); @@ -1393,6 +1394,33 @@ void tst_QMediaPlayerBackend::surfaceTest() QVERIFY2(surface.m_totalFrames >= 25, qPrintable(QString("Expected >= 25, got %1").arg(surface.m_totalFrames))); } +void tst_QMediaPlayerBackend::multipleSurfaces() +{ + if (localVideoFile.isNull()) + QSKIP("No supported video file"); + + QList formats1; + formats1 << QVideoFrame::Format_RGB32 + << QVideoFrame::Format_ARGB32; + QList formats2; + formats2 << QVideoFrame::Format_YUV420P + << QVideoFrame::Format_RGB32; + + TestVideoSurface surface1(false); + surface1.setSupportedFormats(formats1); + TestVideoSurface surface2(false); + surface2.setSupportedFormats(formats2); + + QMediaPlayer player; + player.setVideoOutput(QVector() << &surface1 << &surface2); + player.setMedia(localVideoFile); + player.play(); + QTRY_VERIFY(player.position() >= 1000); + QVERIFY2(surface1.m_totalFrames >= 25, qPrintable(QString("Expected >= 25, got %1").arg(surface1.m_totalFrames))); + QVERIFY2(surface2.m_totalFrames >= 25, qPrintable(QString("Expected >= 25, got %1").arg(surface2.m_totalFrames))); + QCOMPARE(surface1.m_totalFrames, surface2.m_totalFrames); +} + void tst_QMediaPlayerBackend::metadata() { if (localFileWithMetadata.isNull()) -- cgit v1.2.3