/**************************************************************************** ** ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include class tst_QGraphicsVideoItem : public QObject { Q_OBJECT public slots: void initTestCase(); private slots: void nullObject(); void nullService(); void nullOutputControl(); void noOutputs(); void serviceDestroyed(); void mediaObjectDestroyed(); void setMediaObject(); void show(); void aspectRatioMode(); void offset(); void size(); void nativeSize_data(); void nativeSize(); void boundingRect_data(); void boundingRect(); void paint(); }; Q_DECLARE_METATYPE(const uchar *) Q_DECLARE_METATYPE(Qt::AspectRatioMode) class QtTestOutputControl : public QVideoOutputControl { public: QtTestOutputControl() : m_output(NoOutput) {} QList availableOutputs() const { return m_outputs; } void setAvailableOutputs(const QList outputs) { m_outputs = outputs; } Output output() const { return m_output; } virtual void setOutput(Output output) { m_output = output; } private: Output m_output; QList m_outputs; }; class QtTestRendererControl : public QVideoRendererControl { public: QtTestRendererControl() : m_surface(0) { } QAbstractVideoSurface *surface() const { return m_surface; } void setSurface(QAbstractVideoSurface *surface) { m_surface = surface; } private: QAbstractVideoSurface *m_surface; }; class QtTestVideoService : public QMediaService { Q_OBJECT public: QtTestVideoService( QtTestOutputControl *output, QtTestRendererControl *renderer) : QMediaService(0) , outputControl(output) , rendererControl(renderer) { } ~QtTestVideoService() { delete outputControl; delete rendererControl; } QMediaControl *control(const char *name) const { if (qstrcmp(name, QVideoOutputControl_iid) == 0) return outputControl; else if (qstrcmp(name, QVideoRendererControl_iid) == 0) return rendererControl; else return 0; } QtTestOutputControl *outputControl; QtTestRendererControl *rendererControl; }; class QtTestVideoObject : public QMediaObject { Q_OBJECT public: QtTestVideoObject(QtTestRendererControl *renderer): QMediaObject(0, new QtTestVideoService(new QtTestOutputControl, renderer)) { testService = qobject_cast(service()); QList outputs; if (renderer) outputs.append(QVideoOutputControl::RendererOutput); testService->outputControl->setAvailableOutputs(outputs); } QtTestVideoObject(QtTestVideoService *service): QMediaObject(0, service), testService(service) { } ~QtTestVideoObject() { delete testService; } QtTestVideoService *testService; }; class QtTestGraphicsVideoItem : public QGraphicsVideoItem { public: QtTestGraphicsVideoItem(QGraphicsItem *parent = 0) : QGraphicsVideoItem(parent) , m_paintCount(0) { } void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { ++m_paintCount; QTestEventLoop::instance().exitLoop(); QGraphicsVideoItem::paint(painter, option, widget); } bool waitForPaint(int secs) { const int paintCount = m_paintCount; QTestEventLoop::instance().enterLoop(secs); return m_paintCount != paintCount; } int paintCount() const { return m_paintCount; } private: int m_paintCount; }; void tst_QGraphicsVideoItem::initTestCase() { qRegisterMetaType(); } void tst_QGraphicsVideoItem::nullObject() { QGraphicsVideoItem item(0); QVERIFY(item.boundingRect().isEmpty()); } void tst_QGraphicsVideoItem::nullService() { QtTestVideoService *service = 0; QtTestVideoObject object(service); QtTestGraphicsVideoItem *item = new QtTestGraphicsVideoItem; item->setMediaObject(&object); QVERIFY(item->boundingRect().isEmpty()); item->hide(); item->show(); QGraphicsScene graphicsScene; graphicsScene.addItem(item); QGraphicsView graphicsView(&graphicsScene); graphicsView.show(); } void tst_QGraphicsVideoItem::nullOutputControl() { QtTestVideoObject object(new QtTestVideoService(0, 0)); QtTestGraphicsVideoItem *item = new QtTestGraphicsVideoItem; item->setMediaObject(&object); QVERIFY(item->boundingRect().isEmpty()); item->hide(); item->show(); QGraphicsScene graphicsScene; graphicsScene.addItem(item); QGraphicsView graphicsView(&graphicsScene); graphicsView.show(); } void tst_QGraphicsVideoItem::noOutputs() { QtTestRendererControl *control = 0; QtTestVideoObject object(control); QtTestGraphicsVideoItem *item = new QtTestGraphicsVideoItem; item->setMediaObject(&object); QVERIFY(item->boundingRect().isEmpty()); item->hide(); QCOMPARE(object.testService->outputControl->output(), QVideoOutputControl::NoOutput); item->show(); QCOMPARE(object.testService->outputControl->output(), QVideoOutputControl::NoOutput); QGraphicsScene graphicsScene; graphicsScene.addItem(item); QGraphicsView graphicsView(&graphicsScene); graphicsView.show(); } void tst_QGraphicsVideoItem::serviceDestroyed() { QtTestVideoObject object(new QtTestRendererControl); QGraphicsVideoItem item; item.setMediaObject(&object); QtTestVideoService *service = object.testService; object.testService = 0; delete service; QCOMPARE(item.mediaObject(), static_cast(&object)); QVERIFY(item.boundingRect().isEmpty()); } void tst_QGraphicsVideoItem::mediaObjectDestroyed() { QtTestVideoObject *object = new QtTestVideoObject(new QtTestRendererControl); QGraphicsVideoItem item; item.setMediaObject(object); delete object; object = 0; QCOMPARE(item.mediaObject(), static_cast(object)); QVERIFY(item.boundingRect().isEmpty()); } void tst_QGraphicsVideoItem::setMediaObject() { QMediaObject *nullObject = 0; QtTestVideoObject object(new QtTestRendererControl); QGraphicsVideoItem item; QCOMPARE(item.mediaObject(), nullObject); QCOMPARE(object.testService->outputControl->output(), QVideoOutputControl::NoOutput); item.setMediaObject(&object); QCOMPARE(item.mediaObject(), static_cast(&object)); QCOMPARE(object.testService->outputControl->output(), QVideoOutputControl::RendererOutput); QVERIFY(object.testService->rendererControl->surface() != 0); item.setMediaObject(0); QCOMPARE(item.mediaObject(), nullObject); QCOMPARE(object.testService->outputControl->output(), QVideoOutputControl::NoOutput); item.setVisible(false); item.setMediaObject(&object); QCOMPARE(item.mediaObject(), static_cast(&object)); QCOMPARE(object.testService->outputControl->output(), QVideoOutputControl::NoOutput); QVERIFY(object.testService->rendererControl->surface() != 0); } void tst_QGraphicsVideoItem::show() { QtTestVideoObject object(new QtTestRendererControl); QtTestGraphicsVideoItem *item = new QtTestGraphicsVideoItem; item->setMediaObject(&object); // Graphics items are visible by default QCOMPARE(object.testService->outputControl->output(), QVideoOutputControl::RendererOutput); QVERIFY(object.testService->rendererControl->surface() != 0); item->hide(); QCOMPARE(object.testService->outputControl->output(), QVideoOutputControl::RendererOutput); item->show(); QCOMPARE(object.testService->outputControl->output(), QVideoOutputControl::RendererOutput); QVERIFY(object.testService->rendererControl->surface() != 0); QVERIFY(item->boundingRect().isEmpty()); QVideoSurfaceFormat format(QSize(320,240),QVideoFrame::Format_RGB32); QVERIFY(object.testService->rendererControl->surface()->start(format)); QVERIFY(!item->boundingRect().isEmpty()); QGraphicsScene graphicsScene; graphicsScene.addItem(item); QGraphicsView graphicsView(&graphicsScene); graphicsView.show(); QVERIFY(item->paintCount() || item->waitForPaint(1)); } void tst_QGraphicsVideoItem::aspectRatioMode() { QGraphicsVideoItem item; QCOMPARE(item.aspectRatioMode(), Qt::KeepAspectRatio); item.setAspectRatioMode(Qt::IgnoreAspectRatio); QCOMPARE(item.aspectRatioMode(), Qt::IgnoreAspectRatio); item.setAspectRatioMode(Qt::KeepAspectRatioByExpanding); QCOMPARE(item.aspectRatioMode(), Qt::KeepAspectRatioByExpanding); item.setAspectRatioMode(Qt::KeepAspectRatio); QCOMPARE(item.aspectRatioMode(), Qt::KeepAspectRatio); } void tst_QGraphicsVideoItem::offset() { QGraphicsVideoItem item; QCOMPARE(item.offset(), QPointF(0, 0)); item.setOffset(QPointF(-32.4, 43.0)); QCOMPARE(item.offset(), QPointF(-32.4, 43.0)); item.setOffset(QPointF(1, 1)); QCOMPARE(item.offset(), QPointF(1, 1)); item.setOffset(QPointF(12, -30.4)); QCOMPARE(item.offset(), QPointF(12, -30.4)); item.setOffset(QPointF(-90.4, -75)); QCOMPARE(item.offset(), QPointF(-90.4, -75)); } void tst_QGraphicsVideoItem::size() { QGraphicsVideoItem item; QCOMPARE(item.size(), QSizeF(320, 240)); item.setSize(QSizeF(542.5, 436.3)); QCOMPARE(item.size(), QSizeF(542.5, 436.3)); item.setSize(QSizeF(-43, 12)); QCOMPARE(item.size(), QSizeF(0, 0)); item.setSize(QSizeF(54, -9)); QCOMPARE(item.size(), QSizeF(0, 0)); item.setSize(QSizeF(-90, -65)); QCOMPARE(item.size(), QSizeF(0, 0)); item.setSize(QSizeF(1000, 1000)); QCOMPARE(item.size(), QSizeF(1000, 1000)); } void tst_QGraphicsVideoItem::nativeSize_data() { QTest::addColumn("frameSize"); QTest::addColumn("viewport"); QTest::addColumn("pixelAspectRatio"); QTest::addColumn("nativeSize"); QTest::newRow("640x480") << QSize(640, 480) << QRect(0, 0, 640, 480) << QSize(1, 1) << QSizeF(640, 480); QTest::newRow("800x600, (80,60, 640x480) viewport") << QSize(800, 600) << QRect(80, 60, 640, 480) << QSize(1, 1) << QSizeF(640, 480); QTest::newRow("800x600, (80,60, 640x480) viewport, 4:3") << QSize(800, 600) << QRect(80, 60, 640, 480) << QSize(4, 3) << QSizeF(853, 480); } void tst_QGraphicsVideoItem::nativeSize() { QFETCH(QSize, frameSize); QFETCH(QRect, viewport); QFETCH(QSize, pixelAspectRatio); QFETCH(QSizeF, nativeSize); QtTestVideoObject object(new QtTestRendererControl); QGraphicsVideoItem item; item.setMediaObject(&object); QCOMPARE(item.nativeSize(), QSizeF()); QSignalSpy spy(&item, SIGNAL(nativeSizeChanged(QSizeF))); QVideoSurfaceFormat format(frameSize, QVideoFrame::Format_ARGB32); format.setViewport(viewport); format.setPixelAspectRatio(pixelAspectRatio); QVERIFY(object.testService->rendererControl->surface()->start(format)); QCOMPARE(item.nativeSize(), nativeSize); QCOMPARE(spy.count(), 1); QCOMPARE(spy.last().first().toSizeF(), nativeSize); object.testService->rendererControl->surface()->stop(); QCOMPARE(item.nativeSize(), QSizeF(0, 0)); QCOMPARE(spy.count(), 2); QCOMPARE(spy.last().first().toSizeF(), QSizeF(0, 0)); } void tst_QGraphicsVideoItem::boundingRect_data() { QTest::addColumn("frameSize"); QTest::addColumn("offset"); QTest::addColumn("size"); QTest::addColumn("aspectRatioMode"); QTest::addColumn("expectedRect"); QTest::newRow("640x480: (0,0 640x480), Keep") << QSize(640, 480) << QPointF(0, 0) << QSizeF(640, 480) << Qt::KeepAspectRatio << QRectF(0, 0, 640, 480); QTest::newRow("800x600, (0,0, 640x480), Keep") << QSize(800, 600) << QPointF(0, 0) << QSizeF(640, 480) << Qt::KeepAspectRatio << QRectF(0, 0, 640, 480); QTest::newRow("800x600, (0,0, 640x480), KeepByExpanding") << QSize(800, 600) << QPointF(0, 0) << QSizeF(640, 480) << Qt::KeepAspectRatioByExpanding << QRectF(0, 0, 640, 480); QTest::newRow("800x600, (0,0, 640x480), Ignore") << QSize(800, 600) << QPointF(0, 0) << QSizeF(640, 480) << Qt::IgnoreAspectRatio << QRectF(0, 0, 640, 480); QTest::newRow("800x600, (100,100, 640x480), Keep") << QSize(800, 600) << QPointF(100, 100) << QSizeF(640, 480) << Qt::KeepAspectRatio << QRectF(100, 100, 640, 480); QTest::newRow("800x600, (100,-100, 640x480), KeepByExpanding") << QSize(800, 600) << QPointF(100, -100) << QSizeF(640, 480) << Qt::KeepAspectRatioByExpanding << QRectF(100, -100, 640, 480); QTest::newRow("800x600, (-100,-100, 640x480), Ignore") << QSize(800, 600) << QPointF(-100, -100) << QSizeF(640, 480) << Qt::IgnoreAspectRatio << QRectF(-100, -100, 640, 480); QTest::newRow("800x600, (0,0, 1920x1024), Keep") << QSize(800, 600) << QPointF(0, 0) << QSizeF(1920, 1024) << Qt::KeepAspectRatio << QRectF(832.0 / 3, 0, 4096.0 / 3, 1024); QTest::newRow("800x600, (0,0, 1920x1024), KeepByExpanding") << QSize(800, 600) << QPointF(0, 0) << QSizeF(1920, 1024) << Qt::KeepAspectRatioByExpanding << QRectF(0, 0, 1920, 1024); QTest::newRow("800x600, (0,0, 1920x1024), Ignore") << QSize(800, 600) << QPointF(0, 0) << QSizeF(1920, 1024) << Qt::IgnoreAspectRatio << QRectF(0, 0, 1920, 1024); QTest::newRow("800x600, (100,100, 1920x1024), Keep") << QSize(800, 600) << QPointF(100, 100) << QSizeF(1920, 1024) << Qt::KeepAspectRatio << QRectF(100 + 832.0 / 3, 100, 4096.0 / 3, 1024); QTest::newRow("800x600, (100,-100, 1920x1024), KeepByExpanding") << QSize(800, 600) << QPointF(100, -100) << QSizeF(1920, 1024) << Qt::KeepAspectRatioByExpanding << QRectF(100, -100, 1920, 1024); QTest::newRow("800x600, (-100,-100, 1920x1024), Ignore") << QSize(800, 600) << QPointF(-100, -100) << QSizeF(1920, 1024) << Qt::IgnoreAspectRatio << QRectF(-100, -100, 1920, 1024); } void tst_QGraphicsVideoItem::boundingRect() { QFETCH(QSize, frameSize); QFETCH(QPointF, offset); QFETCH(QSizeF, size); QFETCH(Qt::AspectRatioMode, aspectRatioMode); QFETCH(QRectF, expectedRect); QtTestVideoObject object(new QtTestRendererControl); QGraphicsVideoItem item; item.setMediaObject(&object); item.setOffset(offset); item.setSize(size); item.setAspectRatioMode(aspectRatioMode); QVideoSurfaceFormat format(frameSize, QVideoFrame::Format_ARGB32); QVERIFY(object.testService->rendererControl->surface()->start(format)); QCOMPARE(item.boundingRect(), expectedRect); } static const uchar rgb32ImageData[] = { 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00 }; void tst_QGraphicsVideoItem::paint() { QtTestVideoObject object(new QtTestRendererControl); QtTestGraphicsVideoItem *item = new QtTestGraphicsVideoItem; item->setMediaObject(&object); QGraphicsScene graphicsScene; graphicsScene.addItem(item); QGraphicsView graphicsView(&graphicsScene); graphicsView.show(); QPainterVideoSurface *surface = qobject_cast( object.testService->rendererControl->surface()); 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) #include "tst_qgraphicsvideoitem.moc"