tests/auto/qgraphicsvideoitem/tst_qgraphicsvideoitem.cpp
changeset 0 876b1a06bc25
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/auto/qgraphicsvideoitem/tst_qgraphicsvideoitem.cpp	Wed Aug 25 15:49:42 2010 +0300
@@ -0,0 +1,638 @@
+/****************************************************************************
+**
+** 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 Qt Mobility Components.
+**
+** $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 <qmobilityglobal.h>
+#include "qgraphicsvideoitem.h"
+#include <QtTest/QtTest>
+#include "qmediaobject.h"
+#include "qmediaservice.h"
+#include "qpaintervideosurface_p.h"
+#include "qvideorenderercontrol.h"
+
+#include <qabstractvideosurface.h>
+#include <qvideosurfaceformat.h>
+
+#include <QtGui/qapplication.h>
+#include <QtGui/qgraphicsscene.h>
+#include <QtGui/qgraphicsview.h>
+
+QT_USE_NAMESPACE
+class tst_QGraphicsVideoItem : public QObject
+{
+    Q_OBJECT
+public slots:
+    void initTestCase();
+
+private slots:
+    void nullObject();
+    void nullService();
+    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 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(
+            QtTestRendererControl *renderer)
+        : QMediaService(0)
+        , rendererRef(0)
+        , rendererControl(renderer)
+    {
+    }
+
+    ~QtTestVideoService()
+    {
+        delete rendererControl;
+    }
+
+    QMediaControl *requestControl(const char *name)
+    {
+        if (qstrcmp(name, QVideoRendererControl_iid) == 0 && rendererControl) {
+            rendererRef += 1;
+
+            return rendererControl;
+        } else {
+            return 0;
+        }
+    }
+
+    void releaseControl(QMediaControl *control)
+    {
+        Q_ASSERT(control);
+
+        if (control == rendererControl)
+            rendererRef -= 1;
+    }
+
+    int rendererRef;
+    QtTestRendererControl *rendererControl;
+};
+
+class QtTestVideoObject : public QMediaObject
+{
+    Q_OBJECT
+public:
+    QtTestVideoObject(QtTestRendererControl *renderer)
+        : QMediaObject(0, new QtTestVideoService(renderer))
+    {
+        testService = qobject_cast<QtTestVideoService*>(service());
+    }
+
+    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<Qt::AspectRatioMode>();
+}
+
+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;
+    object.bind(item);
+
+    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;
+    object.bind(item);
+
+    QVERIFY(item->boundingRect().isEmpty());
+
+    item->hide();
+    item->show();
+
+    QGraphicsScene graphicsScene;
+    graphicsScene.addItem(item);
+    QGraphicsView graphicsView(&graphicsScene);
+    graphicsView.show();
+}
+
+void tst_QGraphicsVideoItem::serviceDestroyed()
+{
+    QtTestVideoObject object(new QtTestRendererControl);
+
+    QGraphicsVideoItem item;
+    object.bind(&item);
+
+    QCOMPARE(object.testService->rendererRef, 1);
+
+    QtTestVideoService *service = object.testService;
+    object.testService = 0;
+
+    delete service;
+   
+    QCOMPARE(item.mediaObject(), static_cast<QMediaObject *>(&object));
+    QVERIFY(item.boundingRect().isEmpty());
+}
+
+void tst_QGraphicsVideoItem::mediaObjectDestroyed()
+{
+    QtTestVideoObject *object = new QtTestVideoObject(new QtTestRendererControl);
+
+    QGraphicsVideoItem item;
+    object->bind(&item);
+
+    QCOMPARE(object->testService->rendererRef, 1);
+
+    delete object;
+    object = 0;
+
+    QCOMPARE(item.mediaObject(), static_cast<QMediaObject *>(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->rendererRef, 0);
+
+    object.bind(&item);
+    QCOMPARE(item.mediaObject(), static_cast<QMediaObject *>(&object));
+    QCOMPARE(object.testService->rendererRef, 1);
+    QVERIFY(object.testService->rendererControl->surface() != 0);
+
+    object.unbind(&item);
+    QCOMPARE(item.mediaObject(), nullObject);
+
+    QCOMPARE(object.testService->rendererRef, 0);
+
+    item.setVisible(false);
+
+    object.bind(&item);
+    QCOMPARE(item.mediaObject(), static_cast<QMediaObject *>(&object));
+    QCOMPARE(object.testService->rendererRef, 1);
+    QVERIFY(object.testService->rendererControl->surface() != 0);
+}
+
+void tst_QGraphicsVideoItem::show()
+{    
+    QtTestVideoObject object(new QtTestRendererControl);
+    QtTestGraphicsVideoItem *item = new QtTestGraphicsVideoItem;
+    object.bind(item);
+
+    // Graphics items are visible by default
+    QCOMPARE(object.testService->rendererRef, 1);
+    QVERIFY(object.testService->rendererControl->surface() != 0);
+
+    item->hide();
+    QCOMPARE(object.testService->rendererRef, 1);
+
+    item->show();
+    QCOMPARE(object.testService->rendererRef, 1);
+    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<QSize>("frameSize");
+    QTest::addColumn<QRect>("viewport");
+    QTest::addColumn<QSize>("pixelAspectRatio");
+    QTest::addColumn<QSizeF>("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;
+    object.bind(&item);
+
+    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<QSize>("frameSize");
+    QTest::addColumn<QPointF>("offset");
+    QTest::addColumn<QSizeF>("size");
+    QTest::addColumn<Qt::AspectRatioMode>("aspectRatioMode");
+    QTest::addColumn<QRectF>("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;
+    object.bind(&item);
+
+    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;
+    object.bind(item);
+    
+    QGraphicsScene graphicsScene;
+    graphicsScene.addItem(item);
+    QGraphicsView graphicsView(&graphicsScene);
+    graphicsView.show();
+
+    QPainterVideoSurface *surface = qobject_cast<QPainterVideoSurface *>(
+            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"