summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorGareth Stockwell <ext-gareth.stockwell@nokia.com>2011-11-11 13:34:23 +0000
committerGareth Stockwell <ext-gareth.stockwell@nokia.com>2011-11-25 16:43:12 +0000
commitf7c1dda00aabb3931cebd6375741f96306ff65f3 (patch)
tree0b8d917c885a75e6fe071ea0dd76df7cb2bab265 /tests
parenta9d8bf0d92a9ad171461fdcce0922e4de3bea08b (diff)
Add EGL video rendering path on Symbian
This change adds support for rendering video and camera viewfinder frames via EGL, as an alternative to the existing rendering path in which frames are sent directly to the compositing window manager. Rendering via EGL rather than directly to the compositor has a number of advantages, including: * Elimination of artefacts. The direct rendering path requires content on the video and UI surfaces to be synchronized; in the EGL rendering path, this synchronization is deferred to the OpenGLES/OpenVG implementation. * Full support for QGraphicsView and QML APIs. The direct rendering path does not support operations such as free rotation and shear transformations; these are supported by both OpenGLES and OpenVG. * Ability to transform video content using OpenGLES. Making video frames available to EGL means that they can be transformed using shader effects, or rendered into 3D scenes. It also has some disadvantages: * Greater memory consumption * Lower-quality scaling Due to these drawbacks, it is desirable to use the direct rendering path for 'standard' full-screen video playback / viewfinder display. The QGraphicsVideoItem implementation by defaut switches automatically between the two rendering paths; see comments in qgraphicsvideoitem_symbian.cpp for details. The EGL rendering path is implemented using the EGL_NOK_image_endpoint2 extension. If this is not available, QGraphicsVideoItem falls back to using the direct rendering path. If creation of the EGL endpoint fails, QGraphicsVideoItem falls back to using the direct rendering path. Task-number: QTMOBILITY-1818 Task-number: MOBILITY-3084 Reviewed-by: mread
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/multimedia.pro1
-rw-r--r--tests/auto/qgraphicsvideoitem_symbian/qgraphicsvideoitem_symbian.pro9
-rw-r--r--tests/auto/qgraphicsvideoitem_symbian/tst_qgraphicsvideoitem_symbian.cpp362
3 files changed, 372 insertions, 0 deletions
diff --git a/tests/auto/multimedia.pro b/tests/auto/multimedia.pro
index d4176dd05c..8c94d37f66 100644
--- a/tests/auto/multimedia.pro
+++ b/tests/auto/multimedia.pro
@@ -50,6 +50,7 @@ SUBDIRS += \
# doesn't believe it's an untested directory
# qmultimedia_common
+symbian: SUBDIRS += qgraphicsvideoitem_symbian
contains (QT_CONFIG, declarative) {
SUBDIRS += \
diff --git a/tests/auto/qgraphicsvideoitem_symbian/qgraphicsvideoitem_symbian.pro b/tests/auto/qgraphicsvideoitem_symbian/qgraphicsvideoitem_symbian.pro
new file mode 100644
index 0000000000..217fded1cc
--- /dev/null
+++ b/tests/auto/qgraphicsvideoitem_symbian/qgraphicsvideoitem_symbian.pro
@@ -0,0 +1,9 @@
+!symbian: error("This test should only be built on Symbian")
+TARGET = tst_qgraphicsvideoitem_symbian
+CONFIG += testcase mobility
+MOBILITY = multimedia
+INCLUDEPATH += ../../../src/multimedia
+SOURCES += tst_qgraphicsvideoitem_symbian.cpp
+LIBS += -lcone -lavkon
+include (../../../common.pri)
+
diff --git a/tests/auto/qgraphicsvideoitem_symbian/tst_qgraphicsvideoitem_symbian.cpp b/tests/auto/qgraphicsvideoitem_symbian/tst_qgraphicsvideoitem_symbian.cpp
new file mode 100644
index 0000000000..8ba74ab796
--- /dev/null
+++ b/tests/auto/qgraphicsvideoitem_symbian/tst_qgraphicsvideoitem_symbian.cpp
@@ -0,0 +1,362 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 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$
+** GNU Lesser General Public License Usage
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qgraphicsvideoitem.h"
+#include "qmediaplayer.h"
+
+#include <QtCore/QFile>
+#include <QtGui/QApplication>
+#include <QtGui/QDesktopWidget>
+#include <QtGui/QGraphicsScene>
+#include <QtGui/QGraphicsView>
+#include <QtGui/QPaintEngine>
+#include <QtTest/QtTest>
+
+#include <eikenv.h>
+#include <eikappui.h>
+#include <aknenv.h>
+#include <aknappui.h>
+
+QT_USE_NAMESPACE
+
+static const QString FileName = "e:/test.mp4";
+
+class QtTestGraphicsView;
+class QtTestGraphicsVideoItem;
+
+enum PreferredRenderingPath
+{
+ PreferredRenderingPathAuto,
+ PreferredRenderingPathRenderer,
+ PreferredRenderingPathDirect
+};
+
+Q_DECLARE_METATYPE(PreferredRenderingPath)
+
+#define WAIT_FOR_CONDITION(condition, ms) \
+{ \
+ Q_ASSERT(QCoreApplication::instance()); \
+ QElapsedTimer timer; \
+ timer.start(); \
+ do { \
+ QCoreApplication::processEvents(QEventLoop::AllEvents, ms); \
+ QTest::qSleep(10); \
+ } while (!(condition) && (timer.elapsed() < ms)); \
+}
+
+#define CHECKED_WAIT_FOR_CONDITION(condition, ms) \
+ WAIT_FOR_CONDITION(condition, ms); \
+ QVERIFY(condition);
+
+class tst_QGraphicsVideoItemSymbian : public QObject
+{
+ Q_OBJECT
+public slots:
+ void initTestCase();
+ void init();
+ void cleanup();
+
+ void play();
+ void mediaPlayerError(QMediaPlayer::Error error);
+ void resetInactivityTime();
+
+private:
+ void lockOrientation();
+ void disableScreenSaver();
+ void setPreferredRenderingPath(PreferredRenderingPath path);
+ void setFullScreen(bool enabled);
+
+ enum ActualRenderingPath
+ {
+ ActualRenderingPathNone,
+ ActualRenderingPathRenderer = PreferredRenderingPathRenderer,
+ ActualRenderingPathDirect = PreferredRenderingPathDirect
+ };
+ ActualRenderingPath actualRenderingPath() const;
+
+private slots:
+ void specifyPreferredRenderingPath();
+ void specifyPreferredRenderingPath_data();
+ void autoFullScreenIn();
+ void autoFullScreenOut();
+
+private:
+ QMediaPlayer *m_mediaPlayer;
+ QtTestGraphicsView *m_view;
+ QGraphicsScene *m_scene;
+ QtTestGraphicsVideoItem *m_videoItem;
+};
+
+class QtTestGraphicsView : public QGraphicsView
+{
+public:
+ QtTestGraphicsView(QWidget *parent = 0)
+ : QGraphicsView(parent)
+ , m_paintEngineType(QPaintEngine::MaxUser)
+ {
+
+ }
+
+ void drawBackground(QPainter *painter, const QRectF &rect)
+ {
+ m_paintEngineType = painter->paintEngine()->type();
+ QGraphicsView::drawBackground(painter, rect);
+ }
+
+ QPaintEngine::Type paintEngineType() const
+ {
+ return m_paintEngineType;
+ }
+
+private:
+ QPaintEngine::Type m_paintEngineType;
+};
+
+class QtTestGraphicsVideoItem : public QGraphicsVideoItem
+{
+public:
+ QtTestGraphicsVideoItem(QGraphicsItem *parent = 0)
+ : QGraphicsVideoItem(parent)
+ , m_prevPaintCount(0)
+ , m_paintCount(0)
+ {
+
+ }
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+ {
+ ++m_paintCount;
+ QTestEventLoop::instance().exitLoop();
+ QGraphicsVideoItem::paint(painter, option, widget);
+ }
+
+ void savePaintCount()
+ {
+ m_prevPaintCount = m_paintCount;
+ }
+
+ void waitForPaint(bool save = false)
+ {
+ if (save)
+ savePaintCount();
+ static const int required = 2;
+ static const int secs = 5;
+ CHECKED_WAIT_FOR_CONDITION(m_paintCount >= m_prevPaintCount + required, secs * 1000);
+ m_prevPaintCount = m_paintCount;
+ }
+
+ int paintCount() const { return m_paintCount; }
+
+private:
+ int m_prevPaintCount;
+ int m_paintCount;
+};
+
+void tst_QGraphicsVideoItemSymbian::initTestCase()
+{
+ lockOrientation();
+ disableScreenSaver();
+ m_mediaPlayer = 0;
+ m_view = 0;
+ m_scene = 0;
+ m_videoItem = 0;
+ qRegisterMetaType<PreferredRenderingPath>();
+}
+
+void tst_QGraphicsVideoItemSymbian::init()
+{
+ // Framework does not automatically call cleanup() if previous case skipped
+ cleanup();
+ if (QFile::exists(FileName)) {
+ QVERIFY(!m_mediaPlayer);
+ QVERIFY(!m_view);
+ QVERIFY(!m_scene);
+ QVERIFY(!m_videoItem);
+ m_mediaPlayer = new QMediaPlayer();
+ connect(m_mediaPlayer, SIGNAL(error(QMediaPlayer::Error)),
+ this, SLOT(mediaPlayerError(QMediaPlayer::Error)));
+ m_view = new QtTestGraphicsView();
+ m_view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ m_view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ m_scene = new QGraphicsScene();
+ m_videoItem = new QtTestGraphicsVideoItem();
+ m_videoItem->setSize(QSizeF(200, 200));
+ m_view->setScene(m_scene);
+ m_view->setBackgroundBrush(Qt::blue);
+ m_view->showFullScreen();
+ QTest::qWaitForWindowShown(m_view);
+ const QPaintEngine::Type type = m_view->paintEngineType();
+ if (QPaintEngine::OpenGL != type && QPaintEngine::OpenVG != type)
+ QSKIP(QString("Test case is only valid when using opengl or openvg graphics system (paint engine type %1)").arg(type).toAscii(), SkipAll);
+ } else {
+ QSKIP(QString("Test file %1 not found").arg(FileName).toAscii(), SkipAll);
+ }
+}
+
+void tst_QGraphicsVideoItemSymbian::cleanup()
+{
+ delete m_videoItem;
+ m_videoItem = 0;
+ delete m_scene;
+ m_scene = 0;
+ delete m_view;
+ m_view = 0;
+ delete m_mediaPlayer;
+ m_mediaPlayer = 0;
+}
+
+void tst_QGraphicsVideoItemSymbian::play()
+{
+ m_mediaPlayer->setMedia(QUrl::fromLocalFile(FileName));
+ m_mediaPlayer->setVideoOutput(m_videoItem);
+ m_scene->addItem(m_videoItem);
+ m_view->centerOn(m_videoItem);
+ m_mediaPlayer->play();
+ CHECKED_WAIT_FOR_CONDITION(QMediaPlayer::BufferedMedia == m_mediaPlayer->mediaStatus(), 3000);
+}
+
+void tst_QGraphicsVideoItemSymbian::mediaPlayerError(QMediaPlayer::Error error)
+{
+ QVERIFY(QMediaPlayer::NoError == error);
+}
+
+void tst_QGraphicsVideoItemSymbian::setPreferredRenderingPath(PreferredRenderingPath path)
+{
+ static const QString property = "_q_preferredVideoRenderingPath";
+ QString value;
+ switch (path) {
+ case PreferredRenderingPathAuto:
+ value = "auto";
+ break;
+ case PreferredRenderingPathRenderer:
+ value = "renderer";
+ break;
+ case PreferredRenderingPathDirect:
+ value = "direct";
+ break;
+ }
+ m_videoItem->setProperty(property.toAscii(), value);
+}
+
+void tst_QGraphicsVideoItemSymbian::setFullScreen(bool enabled)
+{
+ const QSizeF size = enabled ? QApplication::desktop()->size() : QSizeF(200, 200);
+ m_videoItem->setSize(size);
+ const Qt::AspectRatioMode mode = enabled ? Qt::IgnoreAspectRatio : Qt::KeepAspectRatio;
+ m_videoItem->setAspectRatioMode(mode);
+}
+
+tst_QGraphicsVideoItemSymbian::ActualRenderingPath tst_QGraphicsVideoItemSymbian::actualRenderingPath() const
+{
+ ActualRenderingPath path = ActualRenderingPathNone;
+ static const QString property = "_q_currentVideoRenderingPath";
+ const QString value = m_videoItem->property(property.toAscii()).value<QString>();
+ if ("direct" == value)
+ path = ActualRenderingPathDirect;
+ else if ("renderer" == value)
+ path = ActualRenderingPathRenderer;
+ return path;
+}
+
+void tst_QGraphicsVideoItemSymbian::lockOrientation()
+{
+ CAknAppUi* appUi = dynamic_cast<CAknAppUi*>(CEikonEnv::Static()->AppUi());
+ QVERIFY(appUi);
+ TRAPD(err, appUi->SetOrientationL(CAknAppUi::EAppUiOrientationLandscape));
+ QVERIFY(!err);
+}
+
+void tst_QGraphicsVideoItemSymbian::disableScreenSaver()
+{
+ QTimer *timer = new QTimer(this);
+ connect(timer, SIGNAL(timeout()), this, SLOT(resetInactivityTime()));
+ timer->start(100);
+ resetInactivityTime();
+}
+
+void tst_QGraphicsVideoItemSymbian::resetInactivityTime()
+{
+ User::ResetInactivityTime();
+}
+
+void tst_QGraphicsVideoItemSymbian::specifyPreferredRenderingPath()
+{
+ QFETCH(PreferredRenderingPath, preferredRenderingPath);
+ setPreferredRenderingPath(preferredRenderingPath);
+ play();
+ QVERIFY(actualRenderingPath() == preferredRenderingPath);
+}
+
+void tst_QGraphicsVideoItemSymbian::specifyPreferredRenderingPath_data()
+{
+ QTest::addColumn<PreferredRenderingPath>("preferredRenderingPath");
+ QTest::newRow("direct") << PreferredRenderingPathDirect;
+ QTest::newRow("renderer") << PreferredRenderingPathRenderer;
+}
+
+void tst_QGraphicsVideoItemSymbian::autoFullScreenIn()
+{
+ setPreferredRenderingPath(PreferredRenderingPathAuto);
+ play();
+ QVERIFY(actualRenderingPath() == ActualRenderingPathRenderer);
+ m_videoItem->savePaintCount();
+ setFullScreen(true);
+ m_videoItem->waitForPaint();
+ QVERIFY(actualRenderingPath() == ActualRenderingPathDirect);
+}
+
+void tst_QGraphicsVideoItemSymbian::autoFullScreenOut()
+{
+ setPreferredRenderingPath(PreferredRenderingPathAuto);
+ play();
+ setFullScreen(true);
+ m_videoItem->waitForPaint();
+ QVERIFY(actualRenderingPath() == ActualRenderingPathDirect);
+ m_videoItem->savePaintCount();
+ setFullScreen(false);
+ m_videoItem->waitForPaint();
+ QVERIFY(actualRenderingPath() == ActualRenderingPathRenderer);
+}
+
+QTEST_MAIN(tst_QGraphicsVideoItemSymbian)
+
+#include "tst_qgraphicsvideoitem_symbian.moc"
+