diff options
Diffstat (limited to 'tests/auto/integration/qdeclarativevideooutput/tst_qdeclarativevideooutput.cpp')
-rw-r--r-- | tests/auto/integration/qdeclarativevideooutput/tst_qdeclarativevideooutput.cpp | 740 |
1 files changed, 0 insertions, 740 deletions
diff --git a/tests/auto/integration/qdeclarativevideooutput/tst_qdeclarativevideooutput.cpp b/tests/auto/integration/qdeclarativevideooutput/tst_qdeclarativevideooutput.cpp deleted file mode 100644 index b31947738..000000000 --- a/tests/auto/integration/qdeclarativevideooutput/tst_qdeclarativevideooutput.cpp +++ /dev/null @@ -1,740 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//TESTED_COMPONENT=plugins/declarative/multimedia - -#include <QtTest/QtTest> - -#include <QtQml/qqmlengine.h> -#include <QtQml/qqmlcomponent.h> -#include <QQuickView> - -#include "private/qdeclarativevideooutput_p.h" - -#include <qabstractvideosurface.h> -#include <qvideorenderercontrol.h> -#include <qvideosurfaceformat.h> - -#include <qmediaobject.h> - -class SurfaceHolder : public QObject -{ - Q_OBJECT - Q_PROPERTY(QAbstractVideoSurface *videoSurface READ videoSurface WRITE setVideoSurface) -public: - SurfaceHolder(QObject *parent) - : QObject(parent) - , m_surface(0) - { - } - - QAbstractVideoSurface *videoSurface() const - { - return m_surface; - } - void setVideoSurface(QAbstractVideoSurface *surface) - { - if (m_surface != surface && m_surface && m_surface->isActive()) { - m_surface->stop(); - } - m_surface = surface; - } - - void presentDummyFrame(const QSize &size); - -private: - QAbstractVideoSurface *m_surface; - -}; - -// Starts the surface and puts a frame -void SurfaceHolder::presentDummyFrame(const QSize &size) -{ - if (m_surface && m_surface->supportedPixelFormats().count() > 0) { - QVideoFrame::PixelFormat pixelFormat = m_surface->supportedPixelFormats().value(0); - QVideoSurfaceFormat format(size, pixelFormat); - QVideoFrame frame(size.width() * size.height() * 4, size, size.width() * 4, pixelFormat); - - if (!m_surface->isActive()) - m_surface->start(format); - m_surface->present(frame); - - // Have to spin an event loop or two for the surfaceFormatChanged() signal - qApp->processEvents(); - } -} - -class tst_QDeclarativeVideoOutput : public QObject -{ - Q_OBJECT -public: - tst_QDeclarativeVideoOutput(); - - ~tst_QDeclarativeVideoOutput() - { - delete m_mappingOutput; - delete m_mappingSurface; - delete m_mappingComponent; - } - -public slots: - void initTestCase(); - -private slots: - void fillMode(); - void flushMode(); - void orientation(); - void surfaceSource(); - void paintSurface(); - void sourceRect(); - - void contentRect(); - void contentRect_data(); - - void mappingPoint(); - void mappingPoint_data(); - void mappingRect(); - void mappingRect_data(); - - // XXX May be worth adding tests that the surface activeChanged signals are sent appropriately - // to holder? - -private: - QQmlEngine m_engine; - - // Variables used for the mapping test - QQmlComponent *m_mappingComponent; - QObject *m_mappingOutput; - SurfaceHolder *m_mappingSurface; - - void updateOutputGeometry(QObject *output); - - QRectF invokeR2R(QObject *object, const char *signature, const QRectF &rect); - QPointF invokeP2P(QObject *object, const char *signature, const QPointF &point); -}; - -void tst_QDeclarativeVideoOutput::initTestCase() -{ - // We initialize the mapping vars here - m_mappingComponent = new QQmlComponent(&m_engine); - m_mappingComponent->loadUrl(QUrl("qrc:/main.qml")); - m_mappingSurface = new SurfaceHolder(this); - - m_mappingOutput = m_mappingComponent->create(); - QVERIFY(m_mappingOutput != 0); - - m_mappingOutput->setProperty("source", QVariant::fromValue(static_cast<QObject*>(m_mappingSurface))); - - m_mappingSurface->presentDummyFrame(QSize(200,100)); // this should start m_surface - updateOutputGeometry(m_mappingOutput); -} - -Q_DECLARE_METATYPE(QDeclarativeVideoOutput::FillMode) -Q_DECLARE_METATYPE(QDeclarativeVideoOutput::FlushMode) - -tst_QDeclarativeVideoOutput::tst_QDeclarativeVideoOutput() - : m_mappingComponent(0) - , m_mappingOutput(0) - , m_mappingSurface(0) -{ - qRegisterMetaType<QDeclarativeVideoOutput::FillMode>(); -} - -void tst_QDeclarativeVideoOutput::fillMode() -{ - QQmlComponent component(&m_engine); - component.loadUrl(QUrl("qrc:/main.qml")); - - QObject *videoOutput = component.create(); - QVERIFY(videoOutput != 0); - - QSignalSpy propSpy(videoOutput, SIGNAL(fillModeChanged(QDeclarativeVideoOutput::FillMode))); - - // Default is preserveaspectfit - QCOMPARE(videoOutput->property("fillMode").value<QDeclarativeVideoOutput::FillMode>(), QDeclarativeVideoOutput::PreserveAspectFit); - QCOMPARE(propSpy.count(), 0); - - videoOutput->setProperty("fillMode", QVariant(int(QDeclarativeVideoOutput::PreserveAspectCrop))); - QCOMPARE(videoOutput->property("fillMode").value<QDeclarativeVideoOutput::FillMode>(), QDeclarativeVideoOutput::PreserveAspectCrop); - QCOMPARE(propSpy.count(), 1); - - videoOutput->setProperty("fillMode", QVariant(int(QDeclarativeVideoOutput::Stretch))); - QCOMPARE(videoOutput->property("fillMode").value<QDeclarativeVideoOutput::FillMode>(), QDeclarativeVideoOutput::Stretch); - QCOMPARE(propSpy.count(), 2); - - videoOutput->setProperty("fillMode", QVariant(int(QDeclarativeVideoOutput::Stretch))); - QCOMPARE(videoOutput->property("fillMode").value<QDeclarativeVideoOutput::FillMode>(), QDeclarativeVideoOutput::Stretch); - QCOMPARE(propSpy.count(), 2); - - delete videoOutput; -} - -void tst_QDeclarativeVideoOutput::flushMode() -{ - QQmlComponent component(&m_engine); - component.loadUrl(QUrl("qrc:/main.qml")); - - QObject *videoOutput = component.create(); - QVERIFY(videoOutput != 0); - - QSignalSpy propSpy(videoOutput, SIGNAL(flushModeChanged())); - - QCOMPARE(videoOutput->property("flushMode").value<QDeclarativeVideoOutput::FlushMode>(), QDeclarativeVideoOutput::EmptyFrame); - QCOMPARE(propSpy.count(), 0); - - videoOutput->setProperty("flushMode", QVariant(int(QDeclarativeVideoOutput::FirstFrame))); - QCOMPARE(videoOutput->property("fillMode").value<QDeclarativeVideoOutput::FlushMode>(), QDeclarativeVideoOutput::FirstFrame); - QCOMPARE(propSpy.count(), 1); -} - -void tst_QDeclarativeVideoOutput::orientation() -{ - QQmlComponent component(&m_engine); - component.loadUrl(QUrl("qrc:/main.qml")); - - QObject *videoOutput = component.create(); - QVERIFY(videoOutput != 0); - - QSignalSpy propSpy(videoOutput, SIGNAL(orientationChanged())); - - // Default orientation is 0 - QCOMPARE(videoOutput->property("orientation").toInt(), 0); - QCOMPARE(propSpy.count(), 0); - - videoOutput->setProperty("orientation", QVariant(90)); - QCOMPARE(videoOutput->property("orientation").toInt(), 90); - QCOMPARE(propSpy.count(), 1); - - videoOutput->setProperty("orientation", QVariant(180)); - QCOMPARE(videoOutput->property("orientation").toInt(), 180); - QCOMPARE(propSpy.count(), 2); - - videoOutput->setProperty("orientation", QVariant(270)); - QCOMPARE(videoOutput->property("orientation").toInt(), 270); - QCOMPARE(propSpy.count(), 3); - - videoOutput->setProperty("orientation", QVariant(360)); - QCOMPARE(videoOutput->property("orientation").toInt(), 360); - QCOMPARE(propSpy.count(), 4); - - // More than 360 should be fine - videoOutput->setProperty("orientation", QVariant(540)); - QCOMPARE(videoOutput->property("orientation").toInt(), 540); - QCOMPARE(propSpy.count(), 5); - - // Negative should be fine - videoOutput->setProperty("orientation", QVariant(-180)); - QCOMPARE(videoOutput->property("orientation").toInt(), -180); - QCOMPARE(propSpy.count(), 6); - - // Same value should not reemit - videoOutput->setProperty("orientation", QVariant(-180)); - QCOMPARE(videoOutput->property("orientation").toInt(), -180); - QCOMPARE(propSpy.count(), 6); - - // Non multiples of 90 should not work - videoOutput->setProperty("orientation", QVariant(-1)); - QCOMPARE(videoOutput->property("orientation").toInt(), -180); - QCOMPARE(propSpy.count(), 6); - - delete videoOutput; -} - -void tst_QDeclarativeVideoOutput::surfaceSource() -{ - QQmlComponent component(&m_engine); - component.loadUrl(QUrl("qrc:/main.qml")); - - QObject *videoOutput = component.create(); - QVERIFY(videoOutput != 0); - - SurfaceHolder holder(this); - - QCOMPARE(holder.videoSurface(), static_cast<QAbstractVideoSurface*>(0)); - - videoOutput->setProperty("source", QVariant::fromValue(static_cast<QObject*>(&holder))); - - QVERIFY(holder.videoSurface() != 0); - - // Now we could do things with the surface.. - const QList<QVideoFrame::PixelFormat> formats = holder.videoSurface()->supportedPixelFormats(); - QVERIFY(formats.count() > 0); - - // See if we can start and stop each pixel format (..) - for (QVideoFrame::PixelFormat format : formats) { - QVideoSurfaceFormat surfaceFormat(QSize(200,100), format); - QVERIFY(holder.videoSurface()->isFormatSupported(surfaceFormat)); // This does kind of depend on node factories - - QVERIFY(holder.videoSurface()->start(surfaceFormat)); - QVERIFY(holder.videoSurface()->surfaceFormat() == surfaceFormat); - QVERIFY(holder.videoSurface()->isActive()); - - holder.videoSurface()->stop(); - - QVERIFY(!holder.videoSurface()->isActive()); - } - - delete videoOutput; - - // This should clear the surface - QCOMPARE(holder.videoSurface(), static_cast<QAbstractVideoSurface*>(0)); - - // Also, creating two sources, setting them in order, and destroying the first - // should not zero holder.videoSurface() - videoOutput = component.create(); - videoOutput->setProperty("source", QVariant::fromValue(static_cast<QObject*>(&holder))); - - QAbstractVideoSurface *surface = holder.videoSurface(); - QVERIFY(holder.videoSurface()); - - QObject *videoOutput2 = component.create(); - QVERIFY(videoOutput2); - videoOutput2->setProperty("source", QVariant::fromValue(static_cast<QObject*>(&holder))); - QVERIFY(holder.videoSurface()); - QVERIFY(holder.videoSurface() != surface); // Surface should have changed - surface = holder.videoSurface(); - - // Now delete first one - delete videoOutput; - QVERIFY(holder.videoSurface()); - QVERIFY(holder.videoSurface() == surface); // Should not have changed surface - - // Now create a second surface and assign it as the source - // The old surface holder should be zeroed - SurfaceHolder holder2(this); - videoOutput2->setProperty("source", QVariant::fromValue(static_cast<QObject*>(&holder2))); - - QCOMPARE(holder.videoSurface(), static_cast<QAbstractVideoSurface*>(0)); - QVERIFY(holder2.videoSurface() != 0); - - // Finally a combination - set the same source to two things, then assign a new source - // to the first output - should not reset the first source - videoOutput = component.create(); - videoOutput->setProperty("source", QVariant::fromValue(static_cast<QObject*>(&holder2))); - - // Both vo and vo2 were pointed to holder2 - setting vo2 should not clear holder2 - QVERIFY(holder2.videoSurface() != 0); - QVERIFY(holder.videoSurface() == 0); - videoOutput2->setProperty("source", QVariant::fromValue(static_cast<QObject*>(&holder))); - QVERIFY(holder2.videoSurface() != 0); - QVERIFY(holder.videoSurface() != 0); - - // They should also be independent - QVERIFY(holder.videoSurface() != holder2.videoSurface()); - - delete videoOutput; - 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)); -} - -void tst_QDeclarativeVideoOutput::sourceRect() -{ - QQmlComponent component(&m_engine); - component.loadUrl(QUrl("qrc:/main.qml")); - - QObject *videoOutput = component.create(); - QVERIFY(videoOutput != 0); - - SurfaceHolder holder(this); - - QSignalSpy propSpy(videoOutput, SIGNAL(sourceRectChanged())); - - videoOutput->setProperty("source", QVariant::fromValue(static_cast<QObject*>(&holder))); - - QRectF invalid(0,0,-1,-1); - - QCOMPARE(videoOutput->property("sourceRect").toRectF(), invalid); - - holder.presentDummyFrame(QSize(200,100)); - - QCOMPARE(videoOutput->property("sourceRect").toRectF(), QRectF(0, 0, 200, 100)); - QCOMPARE(propSpy.count(), 1); - - // Another frame shouldn't cause a source rect change - holder.presentDummyFrame(QSize(200,100)); - QCOMPARE(propSpy.count(), 1); - QCOMPARE(videoOutput->property("sourceRect").toRectF(), QRectF(0, 0, 200, 100)); - - // Changing orientation and stretch modes should not affect this - videoOutput->setProperty("orientation", QVariant(90)); - updateOutputGeometry(videoOutput); - QCOMPARE(videoOutput->property("sourceRect").toRectF(), QRectF(0, 0, 200, 100)); - - videoOutput->setProperty("orientation", QVariant(180)); - updateOutputGeometry(videoOutput); - QCOMPARE(videoOutput->property("sourceRect").toRectF(), QRectF(0, 0, 200, 100)); - - videoOutput->setProperty("orientation", QVariant(270)); - updateOutputGeometry(videoOutput); - QCOMPARE(videoOutput->property("sourceRect").toRectF(), QRectF(0, 0, 200, 100)); - - videoOutput->setProperty("orientation", QVariant(-90)); - updateOutputGeometry(videoOutput); - QCOMPARE(videoOutput->property("sourceRect").toRectF(), QRectF(0, 0, 200, 100)); - - videoOutput->setProperty("fillMode", QVariant(int(QDeclarativeVideoOutput::PreserveAspectCrop))); - updateOutputGeometry(videoOutput); - QCOMPARE(videoOutput->property("sourceRect").toRectF(), QRectF(0, 0, 200, 100)); - - videoOutput->setProperty("fillMode", QVariant(int(QDeclarativeVideoOutput::Stretch))); - updateOutputGeometry(videoOutput); - QCOMPARE(videoOutput->property("sourceRect").toRectF(), QRectF(0, 0, 200, 100)); - - videoOutput->setProperty("fillMode", QVariant(int(QDeclarativeVideoOutput::Stretch))); - updateOutputGeometry(videoOutput); - QCOMPARE(videoOutput->property("sourceRect").toRectF(), QRectF(0, 0, 200, 100)); - - delete videoOutput; -} - -void tst_QDeclarativeVideoOutput::mappingPoint() -{ - QFETCH(QPointF, point); - QFETCH(int, orientation); - QFETCH(QDeclarativeVideoOutput::FillMode, fillMode); - QFETCH(QPointF, expected); - - QVERIFY(m_mappingOutput); - m_mappingOutput->setProperty("orientation", QVariant(orientation)); - m_mappingOutput->setProperty("fillMode", QVariant::fromValue(fillMode)); - - updateOutputGeometry(m_mappingOutput); - - QPointF output = invokeP2P(m_mappingOutput, "mapPointToItem", point); - QPointF reverse = invokeP2P(m_mappingOutput, "mapPointToSource", output); - - QCOMPARE(output, expected); - QCOMPARE(reverse, point); - - // Now the normalized versions - // Source rectangle is 200x100 - QPointF normal(point.x() / 200, point.y() / 100); - - output = invokeP2P(m_mappingOutput, "mapNormalizedPointToItem", normal); - reverse = invokeP2P(m_mappingOutput, "mapPointToSourceNormalized", output); - - QCOMPARE(output, expected); - QCOMPARE(reverse, normal); -} - -void tst_QDeclarativeVideoOutput::mappingPoint_data() -{ - QTest::addColumn<QPointF>("point"); - QTest::addColumn<int>("orientation"); - QTest::addColumn<QDeclarativeVideoOutput::FillMode>("fillMode"); - QTest::addColumn<QPointF>("expected"); - - QDeclarativeVideoOutput::FillMode stretch = QDeclarativeVideoOutput::Stretch; - QDeclarativeVideoOutput::FillMode fit = QDeclarativeVideoOutput::PreserveAspectFit; - QDeclarativeVideoOutput::FillMode crop = QDeclarativeVideoOutput::PreserveAspectCrop; - - // First make sure the component has processed the frame - QCOMPARE(m_mappingOutput->property("sourceRect").toRectF(), QRectF(0,0,200,100)); - - // 200x100 -> 150,100 stretch, 150x75 fit @ 12.5f, 200x100 @-25,0 crop - - // Corners, then the center, then a point in the middle somewhere - QTest::newRow("s0-0") << QPointF(0,0) << 0 << stretch << QPointF(0,0); - QTest::newRow("s1-0") << QPointF(200,0) << 0 << stretch << QPointF(150,0); - QTest::newRow("s2-0") << QPointF(0,100) << 0 << stretch << QPointF(0,100); - QTest::newRow("s3-0") << QPointF(200,100) << 0 << stretch << QPointF(150,100); - QTest::newRow("s4-0") << QPointF(100,50) << 0 << stretch << QPointF(75,50); - QTest::newRow("s5-0") << QPointF(40,80) << 0 << stretch << QPointF(30,80); - - QTest::newRow("f0-0") << QPointF(0,0) << 0 << fit << QPointF(0,12.5f); - QTest::newRow("f1-0") << QPointF(200,0) << 0 << fit << QPointF(150,12.5f); - QTest::newRow("f2-0") << QPointF(0,100) << 0 << fit << QPointF(0,87.5f); - QTest::newRow("f3-0") << QPointF(200,100) << 0 << fit << QPointF(150,87.5f); - QTest::newRow("f4-0") << QPointF(100,50) << 0 << stretch << QPointF(75,50); - QTest::newRow("f5-0") << QPointF(40,80) << 0 << stretch << QPointF(30,80); - - QTest::newRow("c0-0") << QPointF(0,0) << 0 << crop << QPointF(-25,0); - QTest::newRow("c1-0") << QPointF(200,0) << 0 << crop << QPointF(175,0); - QTest::newRow("c2-0") << QPointF(0,100) << 0 << crop << QPointF(-25,100); - QTest::newRow("c3-0") << QPointF(200,100) << 0 << crop << QPointF(175,100); - QTest::newRow("c4-0") << QPointF(100,50) << 0 << stretch << QPointF(75,50); - QTest::newRow("c5-0") << QPointF(40,80) << 0 << stretch << QPointF(30,80); - - // 90 degrees (anti clockwise) - QTest::newRow("s0-90") << QPointF(0,0) << 90 << stretch << QPointF(0,100); - QTest::newRow("s1-90") << QPointF(200,0) << 90 << stretch << QPointF(0,0); - QTest::newRow("s2-90") << QPointF(0,100) << 90 << stretch << QPointF(150,100); - QTest::newRow("s3-90") << QPointF(200,100) << 90 << stretch << QPointF(150,0); - QTest::newRow("s4-90") << QPointF(100,50) << 90 << stretch << QPointF(75,50); - QTest::newRow("s5-90") << QPointF(40,80) << 90 << stretch << QPointF(120,80); - - QTest::newRow("f0-90") << QPointF(0,0) << 90 << fit << QPointF(50,100); - QTest::newRow("f1-90") << QPointF(200,0) << 90 << fit << QPointF(50,0); - QTest::newRow("f2-90") << QPointF(0,100) << 90 << fit << QPointF(100,100); - QTest::newRow("f3-90") << QPointF(200,100) << 90 << fit << QPointF(100,0); - QTest::newRow("f4-90") << QPointF(100,50) << 90 << fit << QPointF(75,50); - QTest::newRow("f5-90") << QPointF(40,80) << 90 << fit << QPointF(90,80); - - QTest::newRow("c0-90") << QPointF(0,0) << 90 << crop << QPointF(0,200); - QTest::newRow("c1-90") << QPointF(200,0) << 90 << crop << QPointF(0,-100); - QTest::newRow("c2-90") << QPointF(0,100) << 90 << crop << QPointF(150,200); - QTest::newRow("c3-90") << QPointF(200,100) << 90 << crop << QPointF(150,-100); - QTest::newRow("c4-90") << QPointF(100,50) << 90 << crop << QPointF(75,50); - QTest::newRow("c5-90") << QPointF(40,80) << 90 << crop << QPointF(120,140); - - // 180 - QTest::newRow("s0-180") << QPointF(0,0) << 180 << stretch << QPointF(150,100); - QTest::newRow("s1-180") << QPointF(200,0) << 180 << stretch << QPointF(0,100); - QTest::newRow("s2-180") << QPointF(0,100) << 180 << stretch << QPointF(150,0); - QTest::newRow("s3-180") << QPointF(200,100) << 180 << stretch << QPointF(0,0); - QTest::newRow("s4-180") << QPointF(100,50) << 180 << stretch << QPointF(75,50); - QTest::newRow("s5-180") << QPointF(40,80) << 180 << stretch << QPointF(120,20); - - QTest::newRow("f0-180") << QPointF(0,0) << 180 << fit << QPointF(150,87.5f); - QTest::newRow("f1-180") << QPointF(200,0) << 180 << fit << QPointF(0,87.5f); - QTest::newRow("f2-180") << QPointF(0,100) << 180 << fit << QPointF(150,12.5f); - QTest::newRow("f3-180") << QPointF(200,100) << 180 << fit << QPointF(0,12.5f); - QTest::newRow("f4-180") << QPointF(100,50) << 180 << fit << QPointF(75,50); - QTest::newRow("f5-180") << QPointF(40,80) << 180 << fit << QPointF(120,27.5f); - - QTest::newRow("c0-180") << QPointF(0,0) << 180 << crop << QPointF(175,100); - QTest::newRow("c1-180") << QPointF(200,0) << 180 << crop << QPointF(-25,100); - QTest::newRow("c2-180") << QPointF(0,100) << 180 << crop << QPointF(175,0); - QTest::newRow("c3-180") << QPointF(200,100) << 180 << crop << QPointF(-25,0); - QTest::newRow("c4-180") << QPointF(100,50) << 180 << crop << QPointF(75,50); - QTest::newRow("c5-180") << QPointF(40,80) << 180 << crop << QPointF(135,20); - - // 270 - QTest::newRow("s0-270") << QPointF(0,0) << 270 << stretch << QPointF(150,0); - QTest::newRow("s1-270") << QPointF(200,0) << 270 << stretch << QPointF(150,100); - QTest::newRow("s2-270") << QPointF(0,100) << 270 << stretch << QPointF(0,0); - QTest::newRow("s3-270") << QPointF(200,100) << 270 << stretch << QPointF(0,100); - QTest::newRow("s4-270") << QPointF(100,50) << 270 << stretch << QPointF(75,50); - QTest::newRow("s5-270") << QPointF(40,80) << 270 << stretch << QPointF(30,20); - - QTest::newRow("f0-270") << QPointF(0,0) << 270 << fit << QPointF(100,0); - QTest::newRow("f1-270") << QPointF(200,0) << 270 << fit << QPointF(100,100); - QTest::newRow("f2-270") << QPointF(0,100) << 270 << fit << QPointF(50,0); - QTest::newRow("f3-270") << QPointF(200,100) << 270 << fit << QPointF(50,100); - QTest::newRow("f4-270") << QPointF(100,50) << 270 << fit << QPointF(75,50); - QTest::newRow("f5-270") << QPointF(40,80) << 270 << fit << QPointF(60,20); - - QTest::newRow("c0-270") << QPointF(0,0) << 270 << crop << QPointF(150,-100); - QTest::newRow("c1-270") << QPointF(200,0) << 270 << crop << QPointF(150,200); - QTest::newRow("c2-270") << QPointF(0,100) << 270 << crop << QPointF(0,-100); - QTest::newRow("c3-270") << QPointF(200,100) << 270 << crop << QPointF(0,200); - QTest::newRow("c4-270") << QPointF(100,50) << 270 << crop << QPointF(75,50); - QTest::newRow("c5-270") << QPointF(40,80) << 270 << crop << QPointF(30,-40); -} - -/* Test all rectangle mapping */ -void tst_QDeclarativeVideoOutput::mappingRect() -{ - QFETCH(QRectF, rect); - QFETCH(int, orientation); - QFETCH(QDeclarativeVideoOutput::FillMode, fillMode); - QFETCH(QRectF, expected); - - QVERIFY(m_mappingOutput); - m_mappingOutput->setProperty("orientation", QVariant(orientation)); - m_mappingOutput->setProperty("fillMode", QVariant::fromValue(fillMode)); - - updateOutputGeometry(m_mappingOutput); - - QRectF output = invokeR2R(m_mappingOutput, "mapRectToItem", rect); - QRectF reverse = invokeR2R(m_mappingOutput, "mapRectToSource", output); - - QCOMPARE(output, expected); - QCOMPARE(reverse, rect); - - // Now the normalized versions - // Source rectangle is 200x100 - QRectF normal(rect.x() / 200, rect.y() / 100, rect.width() / 200, rect.height() / 100); - - output = invokeR2R(m_mappingOutput, "mapNormalizedRectToItem", normal); - reverse = invokeR2R(m_mappingOutput, "mapRectToSourceNormalized", output); - - QCOMPARE(output, expected); - QCOMPARE(reverse, normal); -} - -void tst_QDeclarativeVideoOutput::mappingRect_data() -{ - QTest::addColumn<QRectF>("rect"); - QTest::addColumn<int>("orientation"); - QTest::addColumn<QDeclarativeVideoOutput::FillMode>("fillMode"); - QTest::addColumn<QRectF>("expected"); - - // First make sure the component has processed the frame - QCOMPARE(m_mappingOutput->property("sourceRect").toRectF(), QRectF(0,0,200,100)); - - QDeclarativeVideoOutput::FillMode stretch = QDeclarativeVideoOutput::Stretch; - QDeclarativeVideoOutput::FillMode fit = QDeclarativeVideoOutput::PreserveAspectFit; - QDeclarativeVideoOutput::FillMode crop = QDeclarativeVideoOutput::PreserveAspectCrop; - - // Full rectangle mapping - // Stretch - QTest::newRow("s0") << QRectF(0,0, 200, 100) << 0 << stretch << QRectF(0,0,150,100); - QTest::newRow("s90") << QRectF(0,0, 200, 100) << 90 << stretch << QRectF(0,0,150,100); - QTest::newRow("s180") << QRectF(0,0, 200, 100) << 180 << stretch << QRectF(0,0,150,100); - QTest::newRow("s270") << QRectF(0,0, 200, 100) << 270 << stretch << QRectF(0,0,150,100); - - // Fit - QTest::newRow("f0") << QRectF(0,0, 200, 100) << 0 << fit << QRectF(0,12.5f,150,75); - QTest::newRow("f90") << QRectF(0,0, 200, 100) << 90 << fit << QRectF(50,0,50,100); - QTest::newRow("f180") << QRectF(0,0, 200, 100) << 180 << fit << QRectF(0,12.5f,150,75); - QTest::newRow("f270") << QRectF(0,0, 200, 100) << 270 << fit << QRectF(50,0,50,100); - - // Crop - QTest::newRow("c0") << QRectF(0,0, 200, 100) << 0 << crop << QRectF(-25,0,200,100); - QTest::newRow("c90") << QRectF(0,0, 200, 100) << 90 << crop << QRectF(0,-100,150,300); - QTest::newRow("c180") << QRectF(0,0, 200, 100) << 180 << crop << QRectF(-25,0,200,100); - QTest::newRow("c270") << QRectF(0,0, 200, 100) << 270 << crop << QRectF(0,-100,150,300); - - // Partial rectangle mapping - // Stretch - // 50-130 in x (0.25 - 0.65), 25-50 (0.25 - 0.5) in y (out of 200, 100) -> 150x100 - QTest::newRow("p-s0") << QRectF(50, 25, 80, 25) << 0 << stretch << QRectF(37.5f,25,60,25); - QTest::newRow("p-s90") << QRectF(50, 25, 80, 25) << 90 << stretch << QRectF(37.5f,35,37.5f,40); - QTest::newRow("p-s180") << QRectF(50, 25, 80, 25) << 180 << stretch << QRectF(52.5f,50,60,25); - QTest::newRow("p-s270") << QRectF(50, 25, 80, 25) << 270 << stretch << QRectF(75,25,37.5f,40); - - // Fit - QTest::newRow("p-f0") << QRectF(50, 25, 80, 25) << 0 << fit << QRectF(37.5f,31.25f,60,18.75f); - QTest::newRow("p-f90") << QRectF(50, 25, 80, 25) << 90 << fit << QRectF(62.5f,35,12.5f,40); - QTest::newRow("p-f180") << QRectF(50, 25, 80, 25) << 180 << fit << QRectF(52.5f,50,60,18.75f); - QTest::newRow("p-f270") << QRectF(50, 25, 80, 25) << 270 << fit << QRectF(75,25,12.5f,40); - - // Crop - QTest::newRow("p-c0") << QRectF(50, 25, 80, 25) << 0 << crop << QRectF(25,25,80,25); - QTest::newRow("p-c90") << QRectF(50, 25, 80, 25) << 90 << crop << QRectF(37.5f,5,37.5f,120); - QTest::newRow("p-c180") << QRectF(50, 25, 80, 25) << 180 << crop << QRectF(45,50,80,25); - QTest::newRow("p-c270") << QRectF(50, 25, 80, 25) << 270 << crop << QRectF(75,-25,37.5f,120); -} - -void tst_QDeclarativeVideoOutput::updateOutputGeometry(QObject *output) -{ - // Since the object isn't visible, update() doesn't do anything - // so we manually force this - QMetaObject::invokeMethod(output, "_q_updateGeometry"); -} - -void tst_QDeclarativeVideoOutput::contentRect() -{ - QFETCH(int, orientation); - QFETCH(QDeclarativeVideoOutput::FillMode, fillMode); - QFETCH(QRectF, expected); - - QVERIFY(m_mappingOutput); - m_mappingOutput->setProperty("orientation", QVariant(orientation)); - m_mappingOutput->setProperty("fillMode", QVariant::fromValue(fillMode)); - - updateOutputGeometry(m_mappingOutput); - - QRectF output = m_mappingOutput->property("contentRect").toRectF(); - QCOMPARE(output, expected); -} - -void tst_QDeclarativeVideoOutput::contentRect_data() -{ - QTest::addColumn<int>("orientation"); - QTest::addColumn<QDeclarativeVideoOutput::FillMode>("fillMode"); - QTest::addColumn<QRectF>("expected"); - - // First make sure the component has processed the frame - QCOMPARE(m_mappingOutput->property("sourceRect").toRectF(), QRectF(0,0,200,100)); - - QDeclarativeVideoOutput::FillMode stretch = QDeclarativeVideoOutput::Stretch; - QDeclarativeVideoOutput::FillMode fit = QDeclarativeVideoOutput::PreserveAspectFit; - QDeclarativeVideoOutput::FillMode crop = QDeclarativeVideoOutput::PreserveAspectCrop; - - // Stretch just keeps the full render rect regardless of orientation - QTest::newRow("s0") << 0 << stretch << QRectF(0,0,150,100); - QTest::newRow("s90") << 90 << stretch << QRectF(0,0,150,100); - QTest::newRow("s180") << 180 << stretch << QRectF(0,0,150,100); - QTest::newRow("s270") << 270 << stretch << QRectF(0,0,150,100); - - // Fit depends on orientation - // Source is 200x100, fitting in 150x100 -> 150x75 - // or 100x200 -> 50x100 - QTest::newRow("f0") << 0 << fit << QRectF(0,12.5f,150,75); - QTest::newRow("f90") << 90 << fit << QRectF(50,0,50,100); - QTest::newRow("f180") << 180 << fit << QRectF(0,12.5,150,75); - QTest::newRow("f270") << 270 << fit << QRectF(50,0,50,100); - - // Crop also depends on orientation, may go outside render rect - // 200x100 -> -25,0 200x100 - // 100x200 -> 0,-100 150x300 - QTest::newRow("c0") << 0 << crop << QRectF(-25,0,200,100); - QTest::newRow("c90") << 90 << crop << QRectF(0,-100,150,300); - QTest::newRow("c180") << 180 << crop << QRectF(-25,0,200,100); - QTest::newRow("c270") << 270 << crop << QRectF(0,-100,150,300); -} - - -QRectF tst_QDeclarativeVideoOutput::invokeR2R(QObject *object, const char *signature, const QRectF &rect) -{ - QRectF r; - QMetaObject::invokeMethod(object, signature, Q_RETURN_ARG(QRectF, r), Q_ARG(QRectF, rect)); - return r; -} - -QPointF tst_QDeclarativeVideoOutput::invokeP2P(QObject *object, const char *signature, const QPointF &point) -{ - QPointF p; - QMetaObject::invokeMethod(object, signature, Q_RETURN_ARG(QPointF, p), Q_ARG(QPointF, point)); - return p; -} - - -QTEST_MAIN(tst_QDeclarativeVideoOutput) - -#include "tst_qdeclarativevideooutput.moc" |