summaryrefslogtreecommitdiffstats
path: root/tests/auto
diff options
context:
space:
mode:
authorVaL Doroshchuk <valentyn.doroshchuk@qt.io>2019-10-22 14:29:44 +0200
committerVaL Doroshchuk <valentyn.doroshchuk@qt.io>2020-01-05 16:05:47 +0100
commit8c9676fb0bb145704b7e8bdaf7832c03f14b47de (patch)
tree427519b54a43ab063531c9a7d3d1f8181e9ca0de /tests/auto
parente530c303d8d9164888f8d6e1a935b81cda8bf426 (diff)
Expose video surfaces in rendering components
* Currently QVideoWidget, QGraphicsVideoItem and QML Video Output tightly depend on QMediaPlayer, QMediaService etc. Since QMediaService is deprecated and will be removed from Qt6, its usage must be removed from rendering components. * Also it is a part of a task to make all components independent, e.g. without dependencies to another components, like the media player, or video producer. These video consumer components should be reusable without QMediaPlayer too, which today is not possible, and should have responsibility for a single part of the functionality. * It is a part of a task to allow users to decide how to render video, using either video surface or native windows. Introducing QVideoWidget::videoSurface() QGraphicsVideoItem::videoSurface() QDeclarativeVideoOutput::videoSurface() that create a surface, if necessary, and returns the underlying video surface which provides a possibility to render video frames without knowledge of any services and controls. Can be used like: QMediaPlayer->setVideoOutput(QVideoWidget->videoSurface()); or QMediaPlayer->setVideoOutput(QGraphicsVideoItem->videoSurface()); This allows QMediaPlayer to get video frames from a backend, without using QVideoWidget/QGraphicsVideoItem, and to present these frames to provided surface. Moreover, now it is possible to render video frames without QMediaPlayer: QVideoSurfaceFormat format(img.size(), QVideoFrame::Format_ARGB32); videoWidget->videoSurface()->start(format); videoWidget->videoSurface()->present(img); [ChangeLog] Introduced videoSurface property to QVideoWidget, QGraphicsVideoItem and QDeclarativeVideoOutput. Task-number: QTBUG-80431 Change-Id: I49641750537160832e29c297279e72b8288e974c Reviewed-by: Paul Wicking <paul.wicking@qt.io>
Diffstat (limited to 'tests/auto')
-rw-r--r--tests/auto/integration/qdeclarativevideooutput/tst_qdeclarativevideooutput.cpp41
-rw-r--r--tests/auto/unit/qgraphicsvideoitem/tst_qgraphicsvideoitem.cpp43
-rw-r--r--tests/auto/unit/qpaintervideosurface/tst_qpaintervideosurface.cpp8
-rw-r--r--tests/auto/unit/qvideowidget/tst_qvideowidget.cpp29
4 files changed, 117 insertions, 4 deletions
diff --git a/tests/auto/integration/qdeclarativevideooutput/tst_qdeclarativevideooutput.cpp b/tests/auto/integration/qdeclarativevideooutput/tst_qdeclarativevideooutput.cpp
index 798b63f96..27c7d85de 100644
--- a/tests/auto/integration/qdeclarativevideooutput/tst_qdeclarativevideooutput.cpp
+++ b/tests/auto/integration/qdeclarativevideooutput/tst_qdeclarativevideooutput.cpp
@@ -32,6 +32,7 @@
#include <QtQml/qqmlengine.h>
#include <QtQml/qqmlcomponent.h>
+#include <QQuickView>
#include "private/qdeclarativevideooutput_p.h"
@@ -109,6 +110,7 @@ private slots:
void flushMode();
void orientation();
void surfaceSource();
+ void paintSurface();
void sourceRect();
void contentRect();
@@ -349,6 +351,45 @@ void tst_QDeclarativeVideoOutput::surfaceSource()
delete videoOutput2;
}
+static const uchar rgb32ImageData[] =
+{// B G R A
+ 0x00, 0x01, 0x02, 0xff, 0x03, 0x04, 0x05, 0xff,
+ 0x06, 0x07, 0x08, 0xff, 0x09, 0x0a, 0x0b, 0xff
+};
+
+void tst_QDeclarativeVideoOutput::paintSurface()
+{
+ QQuickView window;
+ window.setSource(QUrl("qrc:/main.qml"));
+ window.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&window));
+
+ auto videoOutput = qobject_cast<QDeclarativeVideoOutput *>(window.rootObject());
+ QVERIFY(videoOutput);
+
+ auto surface = videoOutput->property("videoSurface").value<QAbstractVideoSurface *>();
+ QVERIFY(surface);
+ QVERIFY(!surface->isActive());
+ videoOutput->setSize(QSize(2, 2));
+ QVideoSurfaceFormat format(QSize(2, 2), QVideoFrame::Format_RGB32);
+ QVERIFY(surface->isFormatSupported(format));
+ QVERIFY(surface->start(format));
+ QVERIFY(surface->isActive());
+
+ QImage img(rgb32ImageData, 2, 2, 8, QImage::Format_RGB32);
+ QVERIFY(surface->present(img));
+
+ if (QGuiApplication::platformName() == QLatin1String("offscreen")
+ || QGuiApplication::platformName() == QLatin1String("minimal"))
+ return;
+
+ QImage capture = window.grabWindow();
+ QCOMPARE(capture.pixelColor(0, 0), QColor(rgb32ImageData[2], rgb32ImageData[1], rgb32ImageData[0], rgb32ImageData[3]));
+ QCOMPARE(capture.pixelColor(1, 0), QColor(rgb32ImageData[6], rgb32ImageData[5], rgb32ImageData[4], rgb32ImageData[7]));
+ QCOMPARE(capture.pixelColor(0, 1), QColor(rgb32ImageData[10], rgb32ImageData[9], rgb32ImageData[8], rgb32ImageData[11]));
+ QCOMPARE(capture.pixelColor(1, 1), QColor(rgb32ImageData[14], rgb32ImageData[13], rgb32ImageData[12], rgb32ImageData[15]));
+}
+
void tst_QDeclarativeVideoOutput::sourceRect()
{
QQmlComponent component(&m_engine);
diff --git a/tests/auto/unit/qgraphicsvideoitem/tst_qgraphicsvideoitem.cpp b/tests/auto/unit/qgraphicsvideoitem/tst_qgraphicsvideoitem.cpp
index f4759bbf7..41805f49a 100644
--- a/tests/auto/unit/qgraphicsvideoitem/tst_qgraphicsvideoitem.cpp
+++ b/tests/auto/unit/qgraphicsvideoitem/tst_qgraphicsvideoitem.cpp
@@ -70,6 +70,7 @@ private slots:
void boundingRect();
void paint();
+ void paintSurface();
};
Q_DECLARE_METATYPE(const uchar *)
@@ -656,6 +657,48 @@ void tst_QGraphicsVideoItem::paint()
QCOMPARE(surface->isReady(), true);
}
+void tst_QGraphicsVideoItem::paintSurface()
+{
+ QtTestGraphicsVideoItem *item = new QtTestGraphicsVideoItem;
+ QVERIFY(item->videoSurface());
+
+ QGraphicsScene graphicsScene;
+ graphicsScene.addItem(item);
+ QGraphicsView graphicsView(&graphicsScene);
+ graphicsView.show();
+ QVERIFY(item->waitForPaint(1));
+
+ QPainterVideoSurface *surface = qobject_cast<QPainterVideoSurface *>(
+ item->videoSurface());
+ if (!surface)
+ QSKIP("QGraphicsVideoItem is not QPainterVideoSurface based");
+
+ QVideoSurfaceFormat format(QSize(2, 2), QVideoFrame::Format_RGB32);
+
+ QVERIFY(surface->start(format));
+ QCOMPARE(surface->isActive(), true);
+ QCOMPARE(surface->isReady(), true);
+
+ QVERIFY(item->waitForPaint(1));
+
+ QCOMPARE(surface->isActive(), true);
+ QCOMPARE(surface->isReady(), true);
+
+ QVideoFrame frame(sizeof(rgb32ImageData), QSize(2, 2), 8, QVideoFrame::Format_RGB32);
+
+ frame.map(QAbstractVideoBuffer::WriteOnly);
+ memcpy(frame.bits(), rgb32ImageData, frame.mappedBytes());
+ frame.unmap();
+
+ QVERIFY(surface->present(frame));
+ QCOMPARE(surface->isActive(), true);
+ QCOMPARE(surface->isReady(), false);
+
+ QVERIFY(item->waitForPaint(1));
+
+ QCOMPARE(surface->isActive(), true);
+ QCOMPARE(surface->isReady(), true);
+}
QTEST_MAIN(tst_QGraphicsVideoItem)
diff --git a/tests/auto/unit/qpaintervideosurface/tst_qpaintervideosurface.cpp b/tests/auto/unit/qpaintervideosurface/tst_qpaintervideosurface.cpp
index 7ba631e58..6aaeab855 100644
--- a/tests/auto/unit/qpaintervideosurface/tst_qpaintervideosurface.cpp
+++ b/tests/auto/unit/qpaintervideosurface/tst_qpaintervideosurface.cpp
@@ -481,8 +481,7 @@ void tst_QPainterVideoSurface::present()
QCOMPARE(surface.isActive(), true);
QCOMPARE(surface.isReady(), false);
- // Not ready.
- QVERIFY(!surface.present(frameA));
+ QVERIFY(surface.present(frameA));
QCOMPARE(frameSpy.count(), 1);
surface.setReady(true);
@@ -1093,8 +1092,9 @@ void tst_QPainterVideoSurface::shaderPresent()
QCOMPARE(surface.isActive(), true);
QCOMPARE(surface.isReady(), false);
- // Not ready.
- QVERIFY(!surface.present(frameA));
+ // If present() fails for any other reason the surface should immediately enter the stopped state
+ // and an error() value will be set.
+ QVERIFY(surface.present(frameA));
QCOMPARE(frameSpy.count(), 1);
surface.setReady(true);
diff --git a/tests/auto/unit/qvideowidget/tst_qvideowidget.cpp b/tests/auto/unit/qvideowidget/tst_qvideowidget.cpp
index 3baa72281..bcc4acb3a 100644
--- a/tests/auto/unit/qvideowidget/tst_qvideowidget.cpp
+++ b/tests/auto/unit/qvideowidget/tst_qvideowidget.cpp
@@ -100,6 +100,7 @@ private slots:
void saturationRendererControl();
void paintRendererControl();
+ void paintSurface();
private:
void sizeHint_data();
@@ -1609,6 +1610,34 @@ void tst_QVideoWidget::paintRendererControl()
QCOMPARE(surface->isReady(), true);
}
+void tst_QVideoWidget::paintSurface()
+{
+ QtTestVideoWidget widget;
+ widget.resize(640,480);
+ widget.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&widget));
+
+ QVERIFY(widget.videoSurface());
+ auto surface = qobject_cast<QPainterVideoSurface *>(
+ widget.videoSurface());
+ QVERIFY(surface);
+
+ QVideoSurfaceFormat format(QSize(2, 2), QVideoFrame::Format_RGB32);
+ QVERIFY(surface->start(format));
+ QCOMPARE(surface->isActive(), true);
+
+ QVideoFrame frame(sizeof(rgb32ImageData), QSize(2, 2), 8, QVideoFrame::Format_RGB32);
+ frame.map(QAbstractVideoBuffer::WriteOnly);
+ memcpy(frame.bits(), rgb32ImageData, frame.mappedBytes());
+ frame.unmap();
+
+ QVERIFY(surface->present(frame));
+ QCOMPARE(surface->isReady(), false);
+ QTRY_COMPARE(surface->isReady(), true);
+ QCOMPARE(surface->isActive(), true);
+ QCOMPARE(surface->isReady(), true);
+}
+
QTEST_MAIN(tst_QVideoWidget)
#include "tst_qvideowidget.moc"