summaryrefslogtreecommitdiffstats
path: root/src/multimedia/mediaservices
diff options
context:
space:
mode:
Diffstat (limited to 'src/multimedia/mediaservices')
-rw-r--r--src/multimedia/mediaservices/base/base.pri69
-rw-r--r--src/multimedia/mediaservices/base/qgraphicsvideoitem.cpp442
-rw-r--r--src/multimedia/mediaservices/base/qgraphicsvideoitem.h115
-rw-r--r--src/multimedia/mediaservices/base/qlocalmediaplaylistprovider.cpp196
-rw-r--r--src/multimedia/mediaservices/base/qlocalmediaplaylistprovider.h87
-rw-r--r--src/multimedia/mediaservices/base/qmediacontent.cpp242
-rw-r--r--src/multimedia/mediaservices/base/qmediacontent.h93
-rw-r--r--src/multimedia/mediaservices/base/qmediacontrol.cpp140
-rw-r--r--src/multimedia/mediaservices/base/qmediacontrol.h82
-rw-r--r--src/multimedia/mediaservices/base/qmediacontrol_p.h74
-rw-r--r--src/multimedia/mediaservices/base/qmediaobject.cpp419
-rw-r--r--src/multimedia/mediaservices/base/qmediaobject.h121
-rw-r--r--src/multimedia/mediaservices/base/qmediaobject_p.h95
-rw-r--r--src/multimedia/mediaservices/base/qmediaplaylist.cpp724
-rw-r--r--src/multimedia/mediaservices/base/qmediaplaylist.h147
-rw-r--r--src/multimedia/mediaservices/base/qmediaplaylist_p.h172
-rw-r--r--src/multimedia/mediaservices/base/qmediaplaylistcontrol.cpp204
-rw-r--r--src/multimedia/mediaservices/base/qmediaplaylistcontrol.h97
-rw-r--r--src/multimedia/mediaservices/base/qmediaplaylistioplugin.cpp192
-rw-r--r--src/multimedia/mediaservices/base/qmediaplaylistioplugin.h126
-rw-r--r--src/multimedia/mediaservices/base/qmediaplaylistnavigator.cpp545
-rw-r--r--src/multimedia/mediaservices/base/qmediaplaylistnavigator.h116
-rw-r--r--src/multimedia/mediaservices/base/qmediaplaylistprovider.cpp308
-rw-r--r--src/multimedia/mediaservices/base/qmediaplaylistprovider.h114
-rw-r--r--src/multimedia/mediaservices/base/qmediaplaylistprovider_p.h75
-rw-r--r--src/multimedia/mediaservices/base/qmediapluginloader.cpp135
-rw-r--r--src/multimedia/mediaservices/base/qmediapluginloader_p.h92
-rw-r--r--src/multimedia/mediaservices/base/qmediaresource.cpp399
-rw-r--r--src/multimedia/mediaservices/base/qmediaresource.h134
-rw-r--r--src/multimedia/mediaservices/base/qmediaservice.cpp140
-rw-r--r--src/multimedia/mediaservices/base/qmediaservice.h90
-rw-r--r--src/multimedia/mediaservices/base/qmediaservice_p.h75
-rw-r--r--src/multimedia/mediaservices/base/qmediaserviceprovider.cpp738
-rw-r--r--src/multimedia/mediaservices/base/qmediaserviceprovider.h174
-rw-r--r--src/multimedia/mediaservices/base/qmediaserviceproviderplugin.h125
-rw-r--r--src/multimedia/mediaservices/base/qmediatimerange.cpp708
-rw-r--r--src/multimedia/mediaservices/base/qmediatimerange.h135
-rw-r--r--src/multimedia/mediaservices/base/qmetadatacontrol.cpp185
-rw-r--r--src/multimedia/mediaservices/base/qmetadatacontrol.h92
-rw-r--r--src/multimedia/mediaservices/base/qpaintervideosurface.cpp1565
-rw-r--r--src/multimedia/mediaservices/base/qpaintervideosurface_mac.mm283
-rw-r--r--src/multimedia/mediaservices/base/qpaintervideosurface_mac_p.h100
-rw-r--r--src/multimedia/mediaservices/base/qpaintervideosurface_p.h178
-rw-r--r--src/multimedia/mediaservices/base/qtmedianamespace.h194
-rw-r--r--src/multimedia/mediaservices/base/qtmedianamespace.qdoc214
-rw-r--r--src/multimedia/mediaservices/base/qvideodevicecontrol.cpp155
-rw-r--r--src/multimedia/mediaservices/base/qvideodevicecontrol.h90
-rw-r--r--src/multimedia/mediaservices/base/qvideooutputcontrol.cpp135
-rw-r--r--src/multimedia/mediaservices/base/qvideooutputcontrol.h91
-rw-r--r--src/multimedia/mediaservices/base/qvideorenderercontrol.cpp124
-rw-r--r--src/multimedia/mediaservices/base/qvideorenderercontrol.h77
-rw-r--r--src/multimedia/mediaservices/base/qvideowidget.cpp944
-rw-r--r--src/multimedia/mediaservices/base/qvideowidget.h131
-rw-r--r--src/multimedia/mediaservices/base/qvideowidget_p.h271
-rw-r--r--src/multimedia/mediaservices/base/qvideowidgetcontrol.cpp235
-rw-r--r--src/multimedia/mediaservices/base/qvideowidgetcontrol.h105
-rw-r--r--src/multimedia/mediaservices/base/qvideowindowcontrol.cpp275
-rw-r--r--src/multimedia/mediaservices/base/qvideowindowcontrol.h111
-rw-r--r--src/multimedia/mediaservices/effects/effects.pri26
-rw-r--r--src/multimedia/mediaservices/effects/qsoundeffect.cpp207
-rw-r--r--src/multimedia/mediaservices/effects/qsoundeffect_p.h109
-rw-r--r--src/multimedia/mediaservices/effects/qsoundeffect_pulse_p.cpp499
-rw-r--r--src/multimedia/mediaservices/effects/qsoundeffect_pulse_p.h137
-rw-r--r--src/multimedia/mediaservices/effects/qsoundeffect_qmedia_p.cpp132
-rw-r--r--src/multimedia/mediaservices/effects/qsoundeffect_qmedia_p.h103
-rw-r--r--src/multimedia/mediaservices/effects/qsoundeffect_qsound_p.cpp131
-rw-r--r--src/multimedia/mediaservices/effects/qsoundeffect_qsound_p.h102
-rw-r--r--src/multimedia/mediaservices/effects/wavedecoder_p.cpp151
-rw-r--r--src/multimedia/mediaservices/effects/wavedecoder_p.h133
-rw-r--r--src/multimedia/mediaservices/mediaservices.pro21
-rw-r--r--src/multimedia/mediaservices/playback/playback.pri11
-rw-r--r--src/multimedia/mediaservices/playback/qmediaplayer.cpp996
-rw-r--r--src/multimedia/mediaservices/playback/qmediaplayer.h203
-rw-r--r--src/multimedia/mediaservices/playback/qmediaplayercontrol.cpp378
-rw-r--r--src/multimedia/mediaservices/playback/qmediaplayercontrol.h131
75 files changed, 16965 insertions, 0 deletions
diff --git a/src/multimedia/mediaservices/base/base.pri b/src/multimedia/mediaservices/base/base.pri
new file mode 100644
index 0000000..49eca49
--- /dev/null
+++ b/src/multimedia/mediaservices/base/base.pri
@@ -0,0 +1,69 @@
+
+QT += network
+contains(QT_CONFIG, opengl):QT += opengl
+
+HEADERS += \
+ $$PWD/qmediaresource.h \
+ $$PWD/qmediacontent.h \
+ $$PWD/qmediaobject.h \
+ $$PWD/qmediaobject_p.h \
+ $$PWD/qmediapluginloader_p.h \
+ $$PWD/qmediaservice.h \
+ $$PWD/qmediaservice_p.h \
+ $$PWD/qmediaserviceprovider.h \
+ $$PWD/qmediaserviceproviderplugin.h \
+ $$PWD/qmediacontrol.h \
+ $$PWD/qmediacontrol_p.h \
+ $$PWD/qmetadatacontrol.h \
+ $$PWD/qvideooutputcontrol.h \
+ $$PWD/qvideowindowcontrol.h \
+ $$PWD/qvideorenderercontrol.h \
+ $$PWD/qvideodevicecontrol.h \
+ $$PWD/qvideowidgetcontrol.h \
+ $$PWD/qvideowidget.h \
+ $$PWD/qvideowidget_p.h \
+ $$PWD/qgraphicsvideoitem.h \
+ $$PWD/qmediaplaylistcontrol.h \
+ $$PWD/qmediaplaylist.h \
+ $$PWD/qmediaplaylist_p.h \
+ $$PWD/qmediaplaylistprovider.h \
+ $$PWD/qmediaplaylistprovider_p.h \
+ $$PWD/qmediaplaylistioplugin.h \
+ $$PWD/qlocalmediaplaylistprovider.h \
+ $$PWD/qmediaplaylistnavigator.h \
+ $$PWD/qpaintervideosurface_p.h \
+ $$PWD/qmediatimerange.h \
+ $$PWD/qtmedianamespace.h
+
+SOURCES += \
+ $$PWD/qmediaresource.cpp \
+ $$PWD/qmediacontent.cpp \
+ $$PWD/qmediaobject.cpp \
+ $$PWD/qmediapluginloader.cpp \
+ $$PWD/qmediaservice.cpp \
+ $$PWD/qmediaserviceprovider.cpp \
+ $$PWD/qmediacontrol.cpp \
+ $$PWD/qmetadatacontrol.cpp \
+ $$PWD/qvideooutputcontrol.cpp \
+ $$PWD/qvideowindowcontrol.cpp \
+ $$PWD/qvideorenderercontrol.cpp \
+ $$PWD/qvideodevicecontrol.cpp \
+ $$PWD/qvideowidgetcontrol.cpp \
+ $$PWD/qvideowidget.cpp \
+ $$PWD/qgraphicsvideoitem.cpp \
+ $$PWD/qmediaplaylistcontrol.cpp \
+ $$PWD/qmediaplaylist.cpp \
+ $$PWD/qmediaplaylistprovider.cpp \
+ $$PWD/qmediaplaylistioplugin.cpp \
+ $$PWD/qlocalmediaplaylistprovider.cpp \
+ $$PWD/qmediaplaylistnavigator.cpp \
+ $$PWD/qpaintervideosurface.cpp \
+ $$PWD/qmediatimerange.cpp
+
+mac {
+ HEADERS += $$PWD/qpaintervideosurface_mac_p.h
+ OBJECTIVE_SOURCES += $$PWD/qpaintervideosurface_mac.mm
+
+ LIBS += -framework AppKit -framework QuartzCore -framework QTKit
+
+}
diff --git a/src/multimedia/mediaservices/base/qgraphicsvideoitem.cpp b/src/multimedia/mediaservices/base/qgraphicsvideoitem.cpp
new file mode 100644
index 0000000..d80dec5
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qgraphicsvideoitem.cpp
@@ -0,0 +1,442 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaservies module 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 <QtMediaServices/qgraphicsvideoitem.h>
+
+#include <QtMediaServices/qmediaobject.h>
+#include <QtMediaServices/qmediaservice.h>
+#include <QtMediaServices/private/qpaintervideosurface_p.h>
+#include <QtMediaServices/qvideooutputcontrol.h>
+#include <QtMediaServices/qvideorenderercontrol.h>
+#include <QtMultimedia/qvideosurfaceformat.h>
+
+#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_1_CL) && !defined(QT_OPENGL_ES_1)
+#include <QtOpenGL/qgl.h>
+#endif
+
+#ifndef QT_NO_GRAPHICSVIEW
+
+QT_BEGIN_NAMESPACE
+
+
+class QGraphicsVideoItemPrivate
+{
+public:
+ QGraphicsVideoItemPrivate()
+ : q_ptr(0)
+ , surface(0)
+ , mediaObject(0)
+ , service(0)
+ , outputControl(0)
+ , rendererControl(0)
+ , aspectRatioMode(Qt::KeepAspectRatio)
+ , updatePaintDevice(true)
+ , rect(0.0, 0.0, 320, 240)
+ {
+ }
+
+ QGraphicsVideoItem *q_ptr;
+
+ QPainterVideoSurface *surface;
+ QMediaObject *mediaObject;
+ QMediaService *service;
+ QVideoOutputControl *outputControl;
+ QVideoRendererControl *rendererControl;
+ Qt::AspectRatioMode aspectRatioMode;
+ bool updatePaintDevice;
+ QRectF rect;
+ QRectF boundingRect;
+ QRectF sourceRect;
+ QSizeF nativeSize;
+
+ void clearService();
+ void updateRects();
+
+ void _q_present();
+ void _q_formatChanged(const QVideoSurfaceFormat &format);
+ void _q_serviceDestroyed();
+ void _q_mediaObjectDestroyed();
+};
+
+void QGraphicsVideoItemPrivate::clearService()
+{
+ if (outputControl) {
+ outputControl->setOutput(QVideoOutputControl::NoOutput);
+ outputControl = 0;
+ }
+ if (rendererControl) {
+ surface->stop();
+ rendererControl->setSurface(0);
+ rendererControl = 0;
+ }
+ if (service) {
+ QObject::disconnect(service, SIGNAL(destroyed()), q_ptr, SLOT(_q_serviceDestroyed()));
+ service = 0;
+ }
+}
+
+void QGraphicsVideoItemPrivate::updateRects()
+{
+ q_ptr->prepareGeometryChange();
+
+ if (nativeSize.isEmpty()) {
+ boundingRect = QRectF();
+ } else if (aspectRatioMode == Qt::IgnoreAspectRatio) {
+ boundingRect = rect;
+ sourceRect = QRectF(0, 0, 1, 1);
+ } else if (aspectRatioMode == Qt::KeepAspectRatio) {
+ QSizeF size = nativeSize;
+ size.scale(rect.size(), Qt::KeepAspectRatio);
+
+ boundingRect = QRectF(0, 0, size.width(), size.height());
+ boundingRect.moveCenter(rect.center());
+
+ sourceRect = QRectF(0, 0, 1, 1);
+ } else if (aspectRatioMode == Qt::KeepAspectRatioByExpanding) {
+ boundingRect = rect;
+
+ QSizeF size = rect.size();
+ size.scale(nativeSize, Qt::KeepAspectRatio);
+
+ sourceRect = QRectF(
+ 0, 0, size.width() / nativeSize.width(), size.height() / nativeSize.height());
+ sourceRect.moveCenter(QPointF(0.5, 0.5));
+ }
+}
+
+void QGraphicsVideoItemPrivate::_q_present()
+{
+ if (q_ptr->isObscured()) {
+ q_ptr->update(boundingRect);
+ surface->setReady(true);
+ } else {
+ q_ptr->update(boundingRect);
+ }
+}
+
+void QGraphicsVideoItemPrivate::_q_formatChanged(const QVideoSurfaceFormat &format)
+{
+ nativeSize = format.sizeHint();
+
+ updateRects();
+
+ emit q_ptr->nativeSizeChanged(nativeSize);
+}
+
+void QGraphicsVideoItemPrivate::_q_serviceDestroyed()
+{
+ rendererControl = 0;
+ outputControl = 0;
+ service = 0;
+
+ surface->stop();
+}
+
+void QGraphicsVideoItemPrivate::_q_mediaObjectDestroyed()
+{
+ mediaObject = 0;
+
+ clearService();
+}
+
+/*!
+ \class QGraphicsVideoItem
+ \brief The QGraphicsVideoItem class provides a graphics item which display video produced by a QMediaObject.
+
+ \since 4.7
+
+ \ingroup multimedia
+
+ Attaching a QGraphicsVideoItem to a QMediaObject allows it to display
+ the video or image output of that media object. A QGraphicsVideoItem
+ is attached to a media object by passing a pointer to the QMediaObject
+ to the setMediaObject() function.
+
+ \code
+ player = new QMediaPlayer(this);
+
+ QGraphicsVideoItem *item = new QGraphicsVideoItem;
+ item->setMediaObject(player);
+ graphicsView->scence()->addItem(item);
+ graphicsView->show();
+
+ player->setMedia(video);
+ player->play();
+ \endcode
+
+ \bold {Note}: Only a single display output can be attached to a media
+ object at one time.
+
+ \sa QMediaObject, QMediaPlayer, QVideoWidget
+*/
+
+/*!
+ Constructs a graphics item that displays video.
+
+ The \a parent is passed to QGraphicsItem.
+*/
+QGraphicsVideoItem::QGraphicsVideoItem(QGraphicsItem *parent)
+ : QGraphicsObject(parent)
+ , d_ptr(new QGraphicsVideoItemPrivate)
+{
+ d_ptr->q_ptr = this;
+ d_ptr->surface = new QPainterVideoSurface;
+
+ connect(d_ptr->surface, SIGNAL(frameChanged()), this, SLOT(_q_present()));
+ connect(d_ptr->surface, SIGNAL(surfaceFormatChanged(QVideoSurfaceFormat)),
+ this, SLOT(_q_formatChanged(QVideoSurfaceFormat)));
+}
+
+/*!
+ Destroys a video graphics item.
+*/
+QGraphicsVideoItem::~QGraphicsVideoItem()
+{
+ if (d_ptr->outputControl)
+ d_ptr->outputControl->setOutput(QVideoOutputControl::NoOutput);
+
+ if (d_ptr->rendererControl)
+ d_ptr->rendererControl->setSurface(0);
+
+ delete d_ptr->surface;
+ delete d_ptr;
+}
+
+/*!
+ \property QGraphicsVideoItem::mediaObject
+ \brief the media object which provides the video displayed by a graphics
+ item.
+*/
+
+QMediaObject *QGraphicsVideoItem::mediaObject() const
+{
+ return d_func()->mediaObject;
+}
+
+void QGraphicsVideoItem::setMediaObject(QMediaObject *object)
+{
+ Q_D(QGraphicsVideoItem);
+
+ if (object == d->mediaObject)
+ return;
+
+ d->clearService();
+
+ if (d->mediaObject) {
+ disconnect(d->mediaObject, SIGNAL(destroyed()), this, SLOT(_q_mediaObjectDestroyed()));
+ d->mediaObject->unbind(this);
+ }
+
+ d->mediaObject = object;
+
+ if (d->mediaObject) {
+ d->mediaObject->bind(this);
+
+ connect(d->mediaObject, SIGNAL(destroyed()), this, SLOT(_q_mediaObjectDestroyed()));
+
+ d->service = d->mediaObject->service();
+
+ if (d->service) {
+ connect(d->service, SIGNAL(destroyed()), this, SLOT(_q_serviceDestroyed()));
+
+ d->outputControl = qobject_cast<QVideoOutputControl *>(
+ d->service->control(QVideoOutputControl_iid));
+ d->rendererControl = qobject_cast<QVideoRendererControl *>(
+ d->service->control(QVideoRendererControl_iid));
+
+ if (d->outputControl != 0 && d->rendererControl != 0) {
+ d->rendererControl->setSurface(d->surface);
+
+ if (isVisible())
+ d->outputControl->setOutput(QVideoOutputControl::RendererOutput);
+ }
+ }
+ }
+}
+
+/*!
+ \property QGraphicsVideoItem::aspectRatioMode
+ \brief how a video is scaled to fit the graphics item's size.
+*/
+
+Qt::AspectRatioMode QGraphicsVideoItem::aspectRatioMode() const
+{
+ return d_func()->aspectRatioMode;
+}
+
+void QGraphicsVideoItem::setAspectRatioMode(Qt::AspectRatioMode mode)
+{
+ Q_D(QGraphicsVideoItem);
+
+ d->aspectRatioMode = mode;
+ d->updateRects();
+}
+
+/*!
+ \property QGraphicsVideoItem::offset
+ \brief the video item's offset.
+
+ QGraphicsVideoItem will draw video using the offset for its top left
+ corner.
+*/
+
+QPointF QGraphicsVideoItem::offset() const
+{
+ return d_func()->rect.topLeft();
+}
+
+void QGraphicsVideoItem::setOffset(const QPointF &offset)
+{
+ Q_D(QGraphicsVideoItem);
+
+ d->rect.moveTo(offset);
+ d->updateRects();
+}
+
+/*!
+ \property QGraphicsVideoItem::size
+ \brief the video item's size.
+
+ QGraphicsVideoItem will draw video scaled to fit size according to its
+ fillMode.
+*/
+
+QSizeF QGraphicsVideoItem::size() const
+{
+ return d_func()->rect.size();
+}
+
+void QGraphicsVideoItem::setSize(const QSizeF &size)
+{
+ Q_D(QGraphicsVideoItem);
+
+ d->rect.setSize(size.isValid() ? size : QSizeF(0, 0));
+ d->updateRects();
+}
+
+/*!
+ \property QGraphicsVideoItem::nativeSize
+ \brief the native size of the video.
+*/
+
+QSizeF QGraphicsVideoItem::nativeSize() const
+{
+ return d_func()->nativeSize;
+}
+
+/*!
+ \fn QGraphicsVideoItem::nativeSizeChanged(const QSizeF &size)
+
+ Signals that the native \a size of the video has changed.
+*/
+
+/*!
+ \reimp
+*/
+QRectF QGraphicsVideoItem::boundingRect() const
+{
+ return d_func()->boundingRect;
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsVideoItem::paint(
+ QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+ Q_D(QGraphicsVideoItem);
+
+ Q_UNUSED(option);
+ Q_UNUSED(widget);
+
+ if (d->surface && d->surface->isActive()) {
+ d->surface->paint(painter, d->boundingRect, d->sourceRect);
+ d->surface->setReady(true);
+#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_1_CL) && !defined(QT_OPENGL_ES_1)
+ } else if (d->updatePaintDevice && (painter->paintEngine()->type() == QPaintEngine::OpenGL
+ || painter->paintEngine()->type() == QPaintEngine::OpenGL2)) {
+ d->updatePaintDevice = false;
+
+ d->surface->setGLContext(const_cast<QGLContext *>(QGLContext::currentContext()));
+ if (d->surface->supportedShaderTypes() & QPainterVideoSurface::GlslShader) {
+ d->surface->setShaderType(QPainterVideoSurface::GlslShader);
+ } else {
+ d->surface->setShaderType(QPainterVideoSurface::FragmentProgramShader);
+ }
+#endif
+ }
+}
+
+/*!
+ \reimp
+
+ \internal
+*/
+QVariant QGraphicsVideoItem::itemChange(GraphicsItemChange change, const QVariant &value)
+{
+ return QGraphicsObject::itemChange(change, value);
+}
+
+/*!
+ \reimp
+
+ \internal
+*/
+bool QGraphicsVideoItem::event(QEvent *event)
+{
+ return QGraphicsObject::event(event);
+}
+
+/*!
+ \reimp
+
+ \internal
+*/
+bool QGraphicsVideoItem::sceneEvent(QEvent *event)
+{
+ return QGraphicsObject::sceneEvent(event);
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_GRAPHICSVIEW
+
+#include "moc_qgraphicsvideoitem.cpp"
diff --git a/src/multimedia/mediaservices/base/qgraphicsvideoitem.h b/src/multimedia/mediaservices/base/qgraphicsvideoitem.h
new file mode 100644
index 0000000..679b353
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qgraphicsvideoitem.h
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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$
+**
+****************************************************************************/
+
+#ifndef QGRAPHICSVIDEOITEM_H
+#define QGRAPHICSVIDEOITEM_H
+
+#include <QtGui/qgraphicsitem.h>
+
+#include <QtMediaServices/qvideowidget.h>
+
+#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+class QVideoSurfaceFormat;
+
+class QGraphicsVideoItemPrivate;
+class Q_MEDIASERVICES_EXPORT QGraphicsVideoItem : public QGraphicsObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QMediaObject* mediaObject READ mediaObject WRITE setMediaObject)
+ Q_PROPERTY(Qt::AspectRatioMode aspectRatioMode READ aspectRatioMode WRITE setAspectRatioMode)
+ Q_PROPERTY(QPointF offset READ offset WRITE setOffset)
+ Q_PROPERTY(QSizeF size READ size WRITE setSize)
+ Q_PROPERTY(QSizeF nativeSize READ nativeSize NOTIFY nativeSizeChanged)
+public:
+ QGraphicsVideoItem(QGraphicsItem *parent = 0);
+ ~QGraphicsVideoItem();
+
+ QMediaObject *mediaObject() const;
+ void setMediaObject(QMediaObject *object);
+
+ Qt::AspectRatioMode aspectRatioMode() const;
+ void setAspectRatioMode(Qt::AspectRatioMode mode);
+
+ QPointF offset() const;
+ void setOffset(const QPointF &offset);
+
+ QSizeF size() const;
+ void setSize(const QSizeF &size);
+
+ QSizeF nativeSize() const;
+
+ QRectF boundingRect() const;
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+Q_SIGNALS:
+ void nativeSizeChanged(const QSizeF &size);
+
+protected:
+ bool event(QEvent *event);
+ bool sceneEvent(QEvent *event);
+
+ QVariant itemChange(GraphicsItemChange change, const QVariant &value);
+
+ QGraphicsVideoItemPrivate *d_ptr;
+
+private:
+ Q_DECLARE_PRIVATE(QGraphicsVideoItem)
+ Q_PRIVATE_SLOT(d_func(), void _q_present())
+ Q_PRIVATE_SLOT(d_func(), void _q_formatChanged(const QVideoSurfaceFormat &))
+ Q_PRIVATE_SLOT(d_func(), void _q_serviceDestroyed())
+ Q_PRIVATE_SLOT(d_func(), void _q_mediaObjectDestroyed())
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QT_NO_GRAPHICSVIEW
+
+#endif
diff --git a/src/multimedia/mediaservices/base/qlocalmediaplaylistprovider.cpp b/src/multimedia/mediaservices/base/qlocalmediaplaylistprovider.cpp
new file mode 100644
index 0000000..51e3bfb
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qlocalmediaplaylistprovider.cpp
@@ -0,0 +1,196 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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 <QtMediaServices/qlocalmediaplaylistprovider.h>
+#include "qmediaplaylistprovider_p.h"
+#include <QtMediaServices/qmediacontent.h>
+
+
+QT_BEGIN_NAMESPACE
+
+class QLocalMediaPlaylistProviderPrivate: public QMediaPlaylistProviderPrivate
+{
+public:
+ QList<QMediaContent> resources;
+};
+
+QLocalMediaPlaylistProvider::QLocalMediaPlaylistProvider(QObject *parent)
+ :QMediaPlaylistProvider(*new QLocalMediaPlaylistProviderPrivate, parent)
+{
+}
+
+QLocalMediaPlaylistProvider::~QLocalMediaPlaylistProvider()
+{
+}
+
+bool QLocalMediaPlaylistProvider::isReadOnly() const
+{
+ return false;
+}
+
+int QLocalMediaPlaylistProvider::mediaCount() const
+{
+ return d_func()->resources.size();
+}
+
+QMediaContent QLocalMediaPlaylistProvider::media(int pos) const
+{
+ return d_func()->resources.value(pos);
+}
+
+bool QLocalMediaPlaylistProvider::addMedia(const QMediaContent &content)
+{
+ Q_D(QLocalMediaPlaylistProvider);
+
+ int pos = d->resources.count();
+
+ emit mediaAboutToBeInserted(pos, pos);
+ d->resources.append(content);
+ emit mediaInserted(pos, pos);
+
+ return true;
+}
+
+bool QLocalMediaPlaylistProvider::addMedia(const QList<QMediaContent> &items)
+{
+ Q_D(QLocalMediaPlaylistProvider);
+
+ if (items.isEmpty())
+ return true;
+
+ int pos = d->resources.count();
+ int end = pos+items.count()-1;
+
+ emit mediaAboutToBeInserted(pos, end);
+ d->resources.append(items);
+ emit mediaInserted(pos, end);
+
+ return true;
+}
+
+
+bool QLocalMediaPlaylistProvider::insertMedia(int pos, const QMediaContent &content)
+{
+ Q_D(QLocalMediaPlaylistProvider);
+
+ emit mediaAboutToBeInserted(pos, pos);
+ d->resources.insert(pos, content);
+ emit mediaInserted(pos,pos);
+
+ return true;
+}
+
+bool QLocalMediaPlaylistProvider::insertMedia(int pos, const QList<QMediaContent> &items)
+{
+ Q_D(QLocalMediaPlaylistProvider);
+
+ if (items.isEmpty())
+ return true;
+
+ const int last = pos+items.count()-1;
+
+ emit mediaAboutToBeInserted(pos, last);
+ for (int i=0; i<items.count(); i++)
+ d->resources.insert(pos+i, items.at(i));
+ emit mediaInserted(pos, last);
+
+ return true;
+}
+
+bool QLocalMediaPlaylistProvider::removeMedia(int fromPos, int toPos)
+{
+ Q_D(QLocalMediaPlaylistProvider);
+
+ Q_ASSERT(fromPos >= 0);
+ Q_ASSERT(fromPos <= toPos);
+ Q_ASSERT(toPos < mediaCount());
+
+ emit mediaAboutToBeRemoved(fromPos, toPos);
+ d->resources.erase(d->resources.begin()+fromPos, d->resources.begin()+toPos+1);
+ emit mediaRemoved(fromPos, toPos);
+
+ return true;
+}
+
+bool QLocalMediaPlaylistProvider::removeMedia(int pos)
+{
+ Q_D(QLocalMediaPlaylistProvider);
+
+ emit mediaAboutToBeRemoved(pos, pos);
+ d->resources.removeAt(pos);
+ emit mediaRemoved(pos, pos);
+
+ return true;
+}
+
+bool QLocalMediaPlaylistProvider::clear()
+{
+ Q_D(QLocalMediaPlaylistProvider);
+ if (!d->resources.isEmpty()) {
+ int lastPos = mediaCount()-1;
+ emit mediaAboutToBeRemoved(0, lastPos);
+ d->resources.clear();
+ emit mediaRemoved(0, lastPos);
+ }
+
+ return true;
+}
+
+void QLocalMediaPlaylistProvider::shuffle()
+{
+ Q_D(QLocalMediaPlaylistProvider);
+ if (!d->resources.isEmpty()) {
+ QList<QMediaContent> resources;
+
+ while (!d->resources.isEmpty()) {
+ resources.append(d->resources.takeAt(qrand() % d->resources.size()));
+ }
+
+ d->resources = resources;
+ emit mediaChanged(0, mediaCount()-1);
+ }
+
+}
+
+#include "moc_qlocalmediaplaylistprovider.cpp"
+
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/mediaservices/base/qlocalmediaplaylistprovider.h b/src/multimedia/mediaservices/base/qlocalmediaplaylistprovider.h
new file mode 100644
index 0000000..4dd53df
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qlocalmediaplaylistprovider.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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$
+**
+****************************************************************************/
+
+#ifndef QLOCALMEDIAPAYLISTPROVIDER_H
+#define QLOCALMEDIAPAYLISTPROVIDER_H
+
+#include <QtMediaServices/qmediaplaylistprovider.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QLocalMediaPlaylistProviderPrivate;
+class Q_MEDIASERVICES_EXPORT QLocalMediaPlaylistProvider : public QMediaPlaylistProvider
+{
+ Q_OBJECT
+
+public:
+ QLocalMediaPlaylistProvider(QObject *parent=0);
+ virtual ~QLocalMediaPlaylistProvider();
+
+ virtual int mediaCount() const;
+ virtual QMediaContent media(int pos) const;
+
+ virtual bool isReadOnly() const;
+
+ virtual bool addMedia(const QMediaContent &content);
+ virtual bool addMedia(const QList<QMediaContent> &items);
+ virtual bool insertMedia(int pos, const QMediaContent &content);
+ virtual bool insertMedia(int pos, const QList<QMediaContent> &items);
+ virtual bool removeMedia(int pos);
+ virtual bool removeMedia(int start, int end);
+ virtual bool clear();
+
+public Q_SLOTS:
+ virtual void shuffle();
+
+private:
+ Q_DECLARE_PRIVATE(QLocalMediaPlaylistProvider)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QLOCALMEDIAPAYLISTSOURCE_H
diff --git a/src/multimedia/mediaservices/base/qmediacontent.cpp b/src/multimedia/mediaservices/base/qmediacontent.cpp
new file mode 100644
index 0000000..50d8e46
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qmediacontent.cpp
@@ -0,0 +1,242 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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 <QtCore/qurl.h>
+#include <QtCore/qvariant.h>
+
+#include <QtMediaServices/qmediacontent.h>
+
+
+QT_BEGIN_NAMESPACE
+
+
+class QMediaContentPrivate : public QSharedData
+{
+public:
+ QMediaContentPrivate() {}
+ QMediaContentPrivate(const QMediaResourceList &r):
+ resources(r) {}
+
+ QMediaContentPrivate(const QMediaContentPrivate &other):
+ QSharedData(other),
+ resources(other.resources)
+ {}
+
+ bool operator==(const QMediaContentPrivate &other) const
+ {
+ return resources == other.resources;
+ }
+
+ QMediaResourceList resources;
+
+private:
+ QMediaContentPrivate& operator=(const QMediaContentPrivate &other);
+};
+
+
+/*!
+ \class QMediaContent
+ \preliminary
+ \brief The QMediaContent class provides access to the resources relating to a media content.
+ \since 4.7
+
+ \ingroup multimedia
+
+ QMediaContent is used within the multimedia framework as the logical handle
+ to media content. A QMediaContent object is composed of one or more
+ \l {QMediaResource}s where each resource provides the URL and format
+ information of a different encoding of the content.
+
+ A non-null QMediaContent will always have a primary or canonical reference to
+ the content available through the canonicalUrl() or canonicalResource()
+ methods, any additional resources are optional.
+*/
+
+
+/*!
+ Constructs a null QMediaContent.
+*/
+
+QMediaContent::QMediaContent()
+{
+}
+
+/*!
+ Constructs a media content with \a url providing a reference to the content.
+*/
+
+QMediaContent::QMediaContent(const QUrl &url):
+ d(new QMediaContentPrivate)
+{
+ d->resources << QMediaResource(url);
+}
+
+/*!
+ Constructs a media content with \a request providing a reference to the content.
+
+ This constructor can be used to reference media content via network protocols such as HTTP.
+ This may include additional information required to obtain the resource, such as Cookies or HTTP headers.
+*/
+
+QMediaContent::QMediaContent(const QNetworkRequest &request):
+ d(new QMediaContentPrivate)
+{
+ d->resources << QMediaResource(request);
+}
+
+/*!
+ Constructs a media content with \a resource providing a reference to the content.
+*/
+
+QMediaContent::QMediaContent(const QMediaResource &resource):
+ d(new QMediaContentPrivate)
+{
+ d->resources << resource;
+}
+
+/*!
+ Constructs a media content with \a resources providing a reference to the content.
+*/
+
+QMediaContent::QMediaContent(const QMediaResourceList &resources):
+ d(new QMediaContentPrivate(resources))
+{
+}
+
+/*!
+ Constructs a copy of the media content \a other.
+*/
+
+QMediaContent::QMediaContent(const QMediaContent &other):
+ d(other.d)
+{
+}
+
+/*!
+ Destroys the media content object.
+*/
+
+QMediaContent::~QMediaContent()
+{
+}
+
+/*!
+ Assigns the value of \a other to this media content.
+*/
+
+QMediaContent& QMediaContent::operator=(const QMediaContent &other)
+{
+ d = other.d;
+ return *this;
+}
+
+/*!
+ Returns true if \a other is equivalent to this media content; false otherwise.
+*/
+
+bool QMediaContent::operator==(const QMediaContent &other) const
+{
+ return (d.constData() == 0 && other.d.constData() == 0) ||
+ (d.constData() != 0 && other.d.constData() != 0 &&
+ *d.constData() == *other.d.constData());
+}
+
+/*!
+ Returns true if \a other is not equivalent to this media content; false otherwise.
+*/
+
+bool QMediaContent::operator!=(const QMediaContent &other) const
+{
+ return !(*this == other);
+}
+
+/*!
+ Returns true if this media content is null (uninitialized); false otherwise.
+*/
+
+bool QMediaContent::isNull() const
+{
+ return d.constData() == 0;
+}
+
+/*!
+ Returns a QUrl that represents that canonical resource for this media content.
+*/
+
+QUrl QMediaContent::canonicalUrl() const
+{
+ return canonicalResource().url();
+}
+
+/*!
+ Returns a QNetworkRequest that represents that canonical resource for this media content.
+*/
+
+QNetworkRequest QMediaContent::canonicalRequest() const
+{
+ return canonicalResource().request();
+}
+
+/*!
+ Returns a QMediaResource that represents that canonical resource for this media content.
+*/
+
+QMediaResource QMediaContent::canonicalResource() const
+{
+ return d.constData() != 0
+ ? d->resources.value(0)
+ : QMediaResource();
+}
+
+/*!
+ Returns a list of alternative resources for this media content. The first item in this list
+ is always the canonical resource.
+*/
+
+QMediaResourceList QMediaContent::resources() const
+{
+ return d.constData() != 0
+ ? d->resources
+ : QMediaResourceList();
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/mediaservices/base/qmediacontent.h b/src/multimedia/mediaservices/base/qmediacontent.h
new file mode 100644
index 0000000..c00e443
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qmediacontent.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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$
+**
+****************************************************************************/
+
+#ifndef QMEDIACONTENT_H
+#define QMEDIACONTENT_H
+
+#include <QtCore/qmetatype.h>
+#include <QtCore/qshareddata.h>
+
+#include <QtMediaServices/qmediaresource.h>
+#include <QtNetwork/qnetworkrequest.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+class QMediaContentPrivate;
+class Q_MEDIASERVICES_EXPORT QMediaContent
+{
+public:
+ QMediaContent();
+ QMediaContent(const QUrl &contentUrl);
+ QMediaContent(const QNetworkRequest &contentRequest);
+ QMediaContent(const QMediaResource &contentResource);
+ QMediaContent(const QMediaResourceList &resources);
+ QMediaContent(const QMediaContent &other);
+ ~QMediaContent();
+
+ QMediaContent& operator=(const QMediaContent &other);
+
+ bool operator==(const QMediaContent &other) const;
+ bool operator!=(const QMediaContent &other) const;
+
+ bool isNull() const;
+
+ QUrl canonicalUrl() const;
+ QNetworkRequest canonicalRequest() const;
+ QMediaResource canonicalResource() const;
+
+ QMediaResourceList resources() const;
+
+private:
+ QSharedDataPointer<QMediaContentPrivate> d;
+};
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QMediaContent)
+
+QT_END_HEADER
+
+#endif // QMEDIACONTENT_H
diff --git a/src/multimedia/mediaservices/base/qmediacontrol.cpp b/src/multimedia/mediaservices/base/qmediacontrol.cpp
new file mode 100644
index 0000000..09996c8
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qmediacontrol.cpp
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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 <QtCore/qmetaobject.h>
+#include <QtCore/qtimer.h>
+
+#include <QtMediaServices//qmediacontrol.h>
+#include <QtMediaServices/private/qmediacontrol_p.h>
+
+
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QMediaControl
+ \ingroup multimedia-serv
+ \since 4.7
+
+ \preliminary
+ \brief The QMediaControl class provides a base interface for media service controls.
+
+ Media controls provide an interface to individual features provided by a media service. Most
+ services implement a principal control which exposes the core functionality of the service and
+ a number optional controls which expose any additional functionality.
+
+ A pointer to a control implemented by a media service can be obtained using the
+ \l {QMediaService::control()}{control()} member of QMediaService. If the service doesn't
+ implement a control it will instead return a null pointer.
+
+ \code
+ QMediaPlayerControl *control = qobject_cast<QMediaPlayerControl *>(
+ service->control("com.nokia.Qt.QMediaPlayerControl/1.0"));
+ \endcode
+
+ Alternatively if the IId of the control has been declared using Q_MEDIA_DECLARE_CONTROL
+ the template version of QMediaService::control() can be used to request the service without
+ explicitly passing the IId.
+
+ \code
+ QMediaPlayerControl *control = service->control<QMediaPlayerControl *>();
+ \endcode
+
+ Most application code will not interface directly with a media service's controls, instead the
+ QMediaObject which owns the service acts as an intermeditary between one or more controls and
+ the application.
+
+ \sa QMediaService, QMediaObject
+*/
+
+/*!
+ \macro Q_MEDIA_DECLARE_CONTROL(Class, IId)
+ \relates QMediaControl
+
+ The Q_MEDIA_DECLARE_CONTROL macro declares an \a IId for a \a Class that inherits from
+ QMediaControl.
+
+ Declaring an IId for a QMediaControl allows an instance of that control to be requested from
+ QMediaService::control() without explicitly passing the IId.
+
+ \code
+ QMediaPlayerControl *control = service->control<QMediaPlayerControl *>();
+ \endcode
+
+ \sa QMediaService::control()
+*/
+
+/*!
+ Destroys a media control.
+*/
+
+QMediaControl::~QMediaControl()
+{
+ delete d_ptr;
+}
+
+/*!
+ Constructs a media control with the given \a parent.
+*/
+
+QMediaControl::QMediaControl(QObject *parent)
+ : QObject(parent)
+ , d_ptr(new QMediaControlPrivate)
+{
+ d_ptr->q_ptr = this;
+}
+
+/*!
+ \internal
+*/
+
+QMediaControl::QMediaControl(QMediaControlPrivate &dd, QObject *parent)
+ : QObject(parent)
+ , d_ptr(&dd)
+
+{
+ d_ptr->q_ptr = this;
+}
+
+#include "moc_qmediacontrol.cpp"
+
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/mediaservices/base/qmediacontrol.h b/src/multimedia/mediaservices/base/qmediacontrol.h
new file mode 100644
index 0000000..941c004
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qmediacontrol.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTMEDIACONTROL_H
+#define QABSTRACTMEDIACONTROL_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qvariant.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+class QMediaControlPrivate;
+class Q_MEDIASERVICES_EXPORT QMediaControl : public QObject
+{
+ Q_OBJECT
+
+public:
+ ~QMediaControl();
+
+protected:
+ QMediaControl(QObject *parent = 0);
+ QMediaControl(QMediaControlPrivate &dd, QObject *parent = 0);
+
+ QMediaControlPrivate *d_ptr;
+
+private:
+ Q_DECLARE_PRIVATE(QMediaControl)
+};
+
+template <typename T> const char *qmediacontrol_iid() { return 0; }
+
+#define Q_MEDIA_DECLARE_CONTROL(Class, IId) \
+ template <> inline const char *qmediacontrol_iid<Class *>() { return IId; }
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QABSTRACTMEDIACONTROL_H
diff --git a/src/multimedia/mediaservices/base/qmediacontrol_p.h b/src/multimedia/mediaservices/base/qmediacontrol_p.h
new file mode 100644
index 0000000..3f9755b
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qmediacontrol_p.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTMEDIACONTROL_P_H
+#define QABSTRACTMEDIACONTROL_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QMediaControl;
+
+class QMediaControlPrivate
+{
+public:
+ virtual ~QMediaControlPrivate() {}
+
+ QMediaControl *q_ptr;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/multimedia/mediaservices/base/qmediaobject.cpp b/src/multimedia/mediaservices/base/qmediaobject.cpp
new file mode 100644
index 0000000..68fb29e
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qmediaobject.cpp
@@ -0,0 +1,419 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaservics module 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 <QtCore/qmetaobject.h>
+
+#include "qmediaobject_p.h"
+
+#include <QtMediaServices/qmediaservice.h>
+#include <QtMediaServices/qmetadatacontrol.h>
+
+
+QT_BEGIN_NAMESPACE
+
+void QMediaObjectPrivate::_q_notify()
+{
+ Q_Q(QMediaObject);
+
+ const QMetaObject* m = q->metaObject();
+
+ foreach (int pi, notifyProperties) {
+ QMetaProperty p = m->property(pi);
+ p.notifySignal().invoke(
+ q, QGenericArgument(QMetaType::typeName(p.userType()), p.read(q).data()));
+ }
+}
+
+
+/*!
+ \class QMediaObject
+ \preliminary
+ \brief The QMediaObject class provides a common base for multimedia objects.
+ \since 4.7
+
+ \ingroup multimedia
+
+ QMediaObject derived classes provide access to the functionality of a
+ QMediaService. Each media object hosts a QMediaService and uses the
+ QMediaControl interfaces implemented by the service to implement its
+ API. Most media objects when constructed will request a new
+ QMediaService instance from a QMediaServiceProvider, but some like
+ QMediaRecorder will share a service with another object.
+
+ QMediaObject itself provides an API for accessing a media service's \l {metaData()}{meta-data} and a means of connecting other media objects,
+ and peripheral classes like QVideoWidget and QMediaPlaylist.
+
+ \sa QMediaService, QMediaControl
+*/
+
+/*!
+ Destroys a media object.
+*/
+
+QMediaObject::~QMediaObject()
+{
+ delete d_ptr;
+}
+
+/*!
+ Returns the service availability error state.
+*/
+
+QtMediaServices::AvailabilityError QMediaObject::availabilityError() const
+{
+ return QtMediaServices::ServiceMissingError;
+}
+
+/*!
+ Returns true if the service is available for use.
+*/
+
+bool QMediaObject::isAvailable() const
+{
+ return false;
+}
+
+/*!
+ Returns the media service that provides the functionality of a multimedia object.
+*/
+
+QMediaService* QMediaObject::service() const
+{
+ return d_func()->service;
+}
+
+int QMediaObject::notifyInterval() const
+{
+ return d_func()->notifyTimer->interval();
+}
+
+void QMediaObject::setNotifyInterval(int milliSeconds)
+{
+ Q_D(QMediaObject);
+
+ if (d->notifyTimer->interval() != milliSeconds) {
+ d->notifyTimer->setInterval(milliSeconds);
+
+ emit notifyIntervalChanged(milliSeconds);
+ }
+}
+
+/*!
+ \internal
+*/
+void QMediaObject::bind(QObject*)
+{
+}
+
+/*!
+ \internal
+*/
+void QMediaObject::unbind(QObject*)
+{
+}
+
+
+/*!
+ Constructs a media object which uses the functionality provided by a media \a service.
+
+ The \a parent is passed to QObject.
+
+ This class is meant as a base class for Multimedia objects so this
+ constructor is protected.
+*/
+
+QMediaObject::QMediaObject(QObject *parent, QMediaService *service):
+ QObject(parent),
+ d_ptr(new QMediaObjectPrivate)
+
+{
+ Q_D(QMediaObject);
+
+ d->q_ptr = this;
+
+ d->notifyTimer = new QTimer(this);
+ d->notifyTimer->setInterval(1000);
+ connect(d->notifyTimer, SIGNAL(timeout()), SLOT(_q_notify()));
+
+ d->service = service;
+
+ setupMetaData();
+}
+
+/*!
+ \internal
+*/
+
+QMediaObject::QMediaObject(QMediaObjectPrivate &dd, QObject *parent,
+ QMediaService *service):
+ QObject(parent),
+ d_ptr(&dd)
+{
+ Q_D(QMediaObject);
+ d->q_ptr = this;
+
+ d->notifyTimer = new QTimer(this);
+ d->notifyTimer->setInterval(1000);
+ connect(d->notifyTimer, SIGNAL(timeout()), SLOT(_q_notify()));
+
+ d->service = service;
+
+ setupMetaData();
+}
+
+/*!
+ Watch the property \a name. The property's notify signal will be emitted
+ once every notifyInterval milliseconds.
+
+ \sa notifyInterval
+*/
+
+void QMediaObject::addPropertyWatch(QByteArray const &name)
+{
+ Q_D(QMediaObject);
+
+ const QMetaObject* m = metaObject();
+
+ int index = m->indexOfProperty(name.constData());
+
+ if (index != -1 && m->property(index).hasNotifySignal()) {
+ d->notifyProperties.insert(index);
+
+ if (!d->notifyTimer->isActive())
+ d->notifyTimer->start();
+ }
+}
+
+/*!
+ Remove property \a name from the list of properties whose changes are
+ regularly signaled.
+
+ \sa notifyInterval
+*/
+
+void QMediaObject::removePropertyWatch(QByteArray const &name)
+{
+ Q_D(QMediaObject);
+
+ int index = metaObject()->indexOfProperty(name.constData());
+
+ if (index != -1) {
+ d->notifyProperties.remove(index);
+
+ if (d->notifyProperties.isEmpty())
+ d->notifyTimer->stop();
+ }
+}
+
+/*!
+ \property QMediaObject::notifyInterval
+
+ The interval at which notifiable properties will update.
+
+ The interval is expressed in milliseconds, the default value is 1000.
+
+ \sa addPropertyWatch(), removePropertyWatch()
+*/
+
+/*!
+ \fn void QMediaObject::notifyIntervalChanged(int milliseconds)
+
+ Signal a change in the notify interval period to \a milliseconds.
+*/
+
+/*!
+ \property QMediaObject::metaDataAvailable
+ \brief whether access to a media object's meta-data is available.
+
+ If this is true there is meta-data available, otherwise there is no meta-data available.
+*/
+
+bool QMediaObject::isMetaDataAvailable() const
+{
+ Q_D(const QMediaObject);
+
+ return d->metaDataControl
+ ? d->metaDataControl->isMetaDataAvailable()
+ : false;
+}
+
+/*!
+ \fn QMediaObject::metaDataAvailableChanged(bool available)
+
+ Signals that the \a available state of a media object's meta-data has changed.
+*/
+
+/*!
+ \property QMediaObject::metaDataWritable
+ \brief whether a media object's meta-data is writable.
+
+ If this is true the meta-data is writable, otherwise the meta-data is read-only.
+*/
+
+bool QMediaObject::isMetaDataWritable() const
+{
+ Q_D(const QMediaObject);
+
+ return d->metaDataControl
+ ? d->metaDataControl->isWritable()
+ : false;
+}
+
+/*!
+ \fn QMediaObject::metaDataWritableChanged(bool writable)
+
+ Signals that the \a writable state of a media object's meta-data has changed.
+*/
+
+/*!
+ Returns the value associated with a meta-data \a key.
+*/
+QVariant QMediaObject::metaData(QtMediaServices::MetaData key) const
+{
+ Q_D(const QMediaObject);
+
+ return d->metaDataControl
+ ? d->metaDataControl->metaData(key)
+ : QVariant();
+}
+
+/*!
+ Sets a \a value for a meta-data \a key.
+*/
+void QMediaObject::setMetaData(QtMediaServices::MetaData key, const QVariant &value)
+{
+ Q_D(QMediaObject);
+
+ if (d->metaDataControl)
+ d->metaDataControl->setMetaData(key, value);
+}
+
+/*!
+ Returns a list of keys there is meta-data available for.
+*/
+QList<QtMediaServices::MetaData> QMediaObject::availableMetaData() const
+{
+ Q_D(const QMediaObject);
+
+ return d->metaDataControl
+ ? d->metaDataControl->availableMetaData()
+ : QList<QtMediaServices::MetaData>();
+}
+
+/*!
+ \fn QMediaObject::metaDataChanged()
+
+ Signals that a media object's meta-data has changed.
+*/
+
+/*!
+ Returns the value associated with a meta-data \a key.
+
+ The naming and type of extended meta-data is not standardized, so the values and meaning
+ of keys may vary between backends.
+*/
+QVariant QMediaObject::extendedMetaData(const QString &key) const
+{
+ Q_D(const QMediaObject);
+
+ return d->metaDataControl
+ ? d->metaDataControl->extendedMetaData(key)
+ : QVariant();
+}
+
+/*!
+ Sets a \a value for a meta-data \a key.
+
+ The naming and type of extended meta-data is not standardized, so the values and meaning
+ of keys may vary between backends.
+*/
+void QMediaObject::setExtendedMetaData(const QString &key, const QVariant &value)
+{
+ Q_D(QMediaObject);
+
+ if (d->metaDataControl)
+ d->metaDataControl->setExtendedMetaData(key, value);
+}
+
+/*!
+ Returns a list of keys there is extended meta-data available for.
+*/
+QStringList QMediaObject::availableExtendedMetaData() const
+{
+ Q_D(const QMediaObject);
+
+ return d->metaDataControl
+ ? d->metaDataControl->availableExtendedMetaData()
+ : QStringList();
+}
+
+
+void QMediaObject::setupMetaData()
+{
+ Q_D(QMediaObject);
+
+ if (d->service != 0) {
+ d->metaDataControl =
+ qobject_cast<QMetaDataControl*>(d->service->control(QMetaDataControl_iid));
+
+ if (d->metaDataControl) {
+ connect(d->metaDataControl, SIGNAL(metaDataChanged()), SIGNAL(metaDataChanged()));
+ connect(d->metaDataControl,
+ SIGNAL(metaDataAvailableChanged(bool)),
+ SIGNAL(metaDataAvailableChanged(bool)));
+ connect(d->metaDataControl,
+ SIGNAL(writableChanged(bool)),
+ SIGNAL(metaDataWritableChanged(bool)));
+ }
+ }
+}
+
+/*!
+ \fn QMediaObject::availabilityChanged(bool available)
+
+ Signal emitted when the availability state has changed to \a available
+*/
+
+
+#include "moc_qmediaobject.cpp"
+
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/mediaservices/base/qmediaobject.h b/src/multimedia/mediaservices/base/qmediaobject.h
new file mode 100644
index 0000000..067bb56
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qmediaobject.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTMEDIAOBJECT_H
+#define QABSTRACTMEDIAOBJECT_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qstringlist.h>
+
+#include <QtMediaServices/qtmedianamespace.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+class QMediaService;
+
+class QMediaObjectPrivate;
+class Q_MEDIASERVICES_EXPORT QMediaObject : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(int notifyInterval READ notifyInterval WRITE setNotifyInterval NOTIFY notifyIntervalChanged)
+ Q_PROPERTY(bool metaDataAvailable READ isMetaDataAvailable NOTIFY metaDataAvailableChanged)
+ Q_PROPERTY(bool metaDataWritable READ isMetaDataWritable NOTIFY metaDataWritableChanged)
+
+public:
+ ~QMediaObject();
+
+ virtual bool isAvailable() const;
+ virtual QtMediaServices::AvailabilityError availabilityError() const;
+
+ virtual QMediaService* service() const;
+
+ int notifyInterval() const;
+ void setNotifyInterval(int milliSeconds);
+
+ virtual void bind(QObject*);
+ virtual void unbind(QObject*);
+
+ bool isMetaDataAvailable() const;
+ bool isMetaDataWritable() const;
+
+ QVariant metaData(QtMediaServices::MetaData key) const;
+ void setMetaData(QtMediaServices::MetaData key, const QVariant &value);
+ QList<QtMediaServices::MetaData> availableMetaData() const;
+
+ QVariant extendedMetaData(const QString &key) const;
+ void setExtendedMetaData(const QString &key, const QVariant &value);
+ QStringList availableExtendedMetaData() const;
+
+Q_SIGNALS:
+ void notifyIntervalChanged(int milliSeconds);
+
+ void metaDataAvailableChanged(bool available);
+ void metaDataWritableChanged(bool writable);
+ void metaDataChanged();
+
+ void availabilityChanged(bool available);
+
+protected:
+ QMediaObject(QObject *parent, QMediaService *service);
+ QMediaObject(QMediaObjectPrivate &dd, QObject *parent, QMediaService *service);
+
+ void addPropertyWatch(QByteArray const &name);
+ void removePropertyWatch(QByteArray const &name);
+
+ QMediaObjectPrivate *d_ptr;
+
+private:
+ void setupMetaData();
+
+ Q_DECLARE_PRIVATE(QMediaObject)
+ Q_PRIVATE_SLOT(d_func(), void _q_notify())
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif // QABSTRACTMEDIAOBJECT_H
diff --git a/src/multimedia/mediaservices/base/qmediaobject_p.h b/src/multimedia/mediaservices/base/qmediaobject_p.h
new file mode 100644
index 0000000..c31ad46
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qmediaobject_p.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTMEDIAOBJECT_P_H
+#define QABSTRACTMEDIAOBJECT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qbytearray.h>
+#include <QtCore/qset.h>
+#include <QtCore/qtimer.h>
+
+#include <QtMediaServices/qmediaobject.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QMetaDataControl;
+
+#define Q_DECLARE_NON_CONST_PUBLIC(Class) \
+ inline Class* q_func() { return static_cast<Class *>(q_ptr); } \
+ friend class Class;
+
+
+class QMediaObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QMediaObject)
+
+public:
+ QMediaObjectPrivate():metaDataControl(0), notifyTimer(0) {}
+ virtual ~QMediaObjectPrivate() {}
+
+ void _q_notify();
+
+ QMediaService *service;
+ QMetaDataControl *metaDataControl;
+ QTimer* notifyTimer;
+ QSet<int> notifyProperties;
+
+ QMediaObject *q_ptr;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/multimedia/mediaservices/base/qmediaplaylist.cpp b/src/multimedia/mediaservices/base/qmediaplaylist.cpp
new file mode 100644
index 0000000..93278fe
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qmediaplaylist.cpp
@@ -0,0 +1,724 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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 <QtCore/qlist.h>
+#include <QtCore/qfile.h>
+#include <QtCore/qurl.h>
+#include <QtCore/qcoreevent.h>
+#include <QtCore/qcoreapplication.h>
+
+#include <QtMediaServices/qmediaplaylist.h>
+#include "qmediaplaylist_p.h"
+#include <QtMediaServices/qmediaplaylistprovider.h>
+#include <QtMediaServices/qlocalmediaplaylistprovider.h>
+#include <QtMediaServices/qmediaplaylistioplugin.h>
+#include <QtMediaServices/qmediaservice.h>
+#include <QtMediaServices/qmediaplaylistcontrol.h>
+#include <QtMediaServices/qmediaplayercontrol.h>
+
+#include "qmediapluginloader_p.h"
+
+
+QT_BEGIN_NAMESPACE
+
+Q_GLOBAL_STATIC_WITH_ARGS(QMediaPluginLoader, playlistIOLoader,
+ (QMediaPlaylistIOInterface_iid, QLatin1String("/playlistformats"), Qt::CaseInsensitive))
+
+
+/*!
+ \class QMediaPlaylist
+ \ingroup multimedia
+ \since 4.7
+
+ \preliminary
+ \brief The QMediaPlaylist class provides a list of media content to play.
+
+ QMediaPlaylist is intended to be used with other media objects,
+ like QMediaPlayer or QMediaImageViewer.
+ QMediaPlaylist allows to access the service intrinsic playlist functionality
+ if available, otherwise it provides the the local memory playlist implementation.
+
+\code
+ player = new QMediaPlayer;
+
+ playlist = new QMediaPlaylist;
+ playlist->setMediaObject(player);
+ playlist->append(QUrl("http://example.com/movie1.mp4"));
+ playlist->append(QUrl("http://example.com/movie2.mp4"));
+ playlist->append(QUrl("http://example.com/movie3.mp4"));
+
+ playlist->setCurrentIndex(1);
+
+ player->play();
+\endcode
+
+ Depending on playlist source implementation,
+ most of playlist modifcation operations can be asynchronous.
+
+ \sa QMediaContent
+*/
+
+
+/*!
+ \enum QMediaPlaylist::PlaybackMode
+
+ The QMediaPlaylist::PlaybackMode describes the order items in playlist are played.
+
+ \value CurrentItemOnce The current item is played only once.
+
+ \value CurrentItemInLoop The current item is played in the loop.
+
+ \value Linear Playback starts from the first to the last items and stops.
+ next item is a null item when the last one is currently playing.
+
+ \value Loop Playback continues from the first item after the last one finished playing.
+
+ \value Random Play items in random order.
+*/
+
+
+
+/*!
+ Create a new playlist object for with the given \a parent.
+*/
+
+QMediaPlaylist::QMediaPlaylist(QObject *parent)
+ : QObject(parent)
+ , d_ptr(new QMediaPlaylistPrivate)
+{
+ Q_D(QMediaPlaylist);
+
+ d->q_ptr = this;
+ d->localPlaylistControl = new QLocalMediaPlaylistControl(this);
+
+ setMediaObject(0);
+}
+
+/*!
+ Destroys the playlist.
+ */
+
+QMediaPlaylist::~QMediaPlaylist()
+{
+ Q_D(QMediaPlaylist);
+
+ if (d->mediaObject)
+ d->mediaObject->unbind(this);
+
+ delete d_ptr;
+}
+
+/*!
+ Returns the QMediaObject that is being used to play the contents of this playlist.
+*/
+
+QMediaObject *QMediaPlaylist::mediaObject() const
+{
+ return d_func()->mediaObject;
+}
+
+/*!
+ If \a mediaObject is null or doesn't have an intrinsic playlist,
+ internal local memory playlist source will be created.
+*/
+void QMediaPlaylist::setMediaObject(QMediaObject *mediaObject)
+{
+ Q_D(QMediaPlaylist);
+
+ if (mediaObject && mediaObject == d->mediaObject)
+ return;
+
+ QMediaService *service = mediaObject
+ ? mediaObject->service() : 0;
+
+ QMediaPlaylistControl *newControl = 0;
+
+ if (service)
+ newControl = qobject_cast<QMediaPlaylistControl*>(service->control(QMediaPlaylistControl_iid));
+
+ if (!newControl)
+ newControl = d->localPlaylistControl;
+
+ if (d->control != newControl) {
+ int oldSize = 0;
+ if (d->control) {
+ QMediaPlaylistProvider *playlist = d->control->playlistProvider();
+ oldSize = playlist->mediaCount();
+ disconnect(playlist, SIGNAL(loadFailed(QMediaPlaylist::Error,QString)),
+ this, SLOT(_q_loadFailed(QMediaPlaylist::Error,QString)));
+
+ disconnect(playlist, SIGNAL(mediaChanged(int,int)), this, SIGNAL(mediaChanged(int,int)));
+ disconnect(playlist, SIGNAL(mediaAboutToBeInserted(int,int)), this, SIGNAL(mediaAboutToBeInserted(int,int)));
+ disconnect(playlist, SIGNAL(mediaInserted(int,int)), this, SIGNAL(mediaInserted(int,int)));
+ disconnect(playlist, SIGNAL(mediaAboutToBeRemoved(int,int)), this, SIGNAL(mediaAboutToBeRemoved(int,int)));
+ disconnect(playlist, SIGNAL(mediaRemoved(int,int)), this, SIGNAL(mediaRemoved(int,int)));
+
+ disconnect(playlist, SIGNAL(loaded()), this, SIGNAL(loaded()));
+
+ disconnect(d->control, SIGNAL(playbackModeChanged(QMediaPlaylist::PlaybackMode)),
+ this, SIGNAL(playbackModeChanged(QMediaPlaylist::PlaybackMode)));
+ disconnect(d->control, SIGNAL(currentIndexChanged(int)),
+ this, SIGNAL(currentIndexChanged(int)));
+ disconnect(d->control, SIGNAL(currentMediaChanged(QMediaContent)),
+ this, SIGNAL(currentMediaChanged(QMediaContent)));
+ }
+
+ d->control = newControl;
+ QMediaPlaylistProvider *playlist = d->control->playlistProvider();
+ connect(playlist, SIGNAL(loadFailed(QMediaPlaylist::Error,QString)),
+ this, SLOT(_q_loadFailed(QMediaPlaylist::Error,QString)));
+
+ connect(playlist, SIGNAL(mediaChanged(int,int)), this, SIGNAL(mediaChanged(int,int)));
+ connect(playlist, SIGNAL(mediaAboutToBeInserted(int,int)), this, SIGNAL(mediaAboutToBeInserted(int,int)));
+ connect(playlist, SIGNAL(mediaInserted(int,int)), this, SIGNAL(mediaInserted(int,int)));
+ connect(playlist, SIGNAL(mediaAboutToBeRemoved(int,int)), this, SIGNAL(mediaAboutToBeRemoved(int,int)));
+ connect(playlist, SIGNAL(mediaRemoved(int,int)), this, SIGNAL(mediaRemoved(int,int)));
+
+ connect(playlist, SIGNAL(loaded()), this, SIGNAL(loaded()));
+
+ connect(d->control, SIGNAL(playbackModeChanged(QMediaPlaylist::PlaybackMode)),
+ this, SIGNAL(playbackModeChanged(QMediaPlaylist::PlaybackMode)));
+ connect(d->control, SIGNAL(currentIndexChanged(int)),
+ this, SIGNAL(currentIndexChanged(int)));
+ connect(d->control, SIGNAL(currentMediaChanged(QMediaContent)),
+ this, SIGNAL(currentMediaChanged(QMediaContent)));
+
+ if (oldSize)
+ emit mediaRemoved(0, oldSize-1);
+
+ if (playlist->mediaCount()) {
+ emit mediaAboutToBeInserted(0,playlist->mediaCount()-1);
+ emit mediaInserted(0,playlist->mediaCount()-1);
+ }
+ }
+
+ if (d->mediaObject)
+ d->mediaObject->unbind(this);
+
+ d->mediaObject = mediaObject;
+ if (d->mediaObject)
+ d->mediaObject->bind(this);
+}
+
+/*!
+ \property QMediaPlaylist::playbackMode
+
+ This property defines the order, items in playlist are played.
+
+ \sa QMediaPlaylist::PlaybackMode
+*/
+
+QMediaPlaylist::PlaybackMode QMediaPlaylist::playbackMode() const
+{
+ return d_func()->control->playbackMode();
+}
+
+void QMediaPlaylist::setPlaybackMode(QMediaPlaylist::PlaybackMode mode)
+{
+ Q_D(QMediaPlaylist);
+ d->control->setPlaybackMode(mode);
+}
+
+/*!
+ Returns position of the current media source in the playlist.
+*/
+int QMediaPlaylist::currentIndex() const
+{
+ return d_func()->control->currentIndex();
+}
+
+/*!
+ Returns the current media content.
+*/
+
+QMediaContent QMediaPlaylist::currentMedia() const
+{
+ return d_func()->playlist()->media(currentIndex());
+}
+
+/*!
+ Returns the index of item, which were current after calling next()
+ \a steps times.
+
+ Returned value depends on the size of playlist, current position
+ and playback mode.
+
+ \sa QMediaPlaylist::playbackMode
+*/
+int QMediaPlaylist::nextIndex(int steps) const
+{
+ return d_func()->control->nextIndex(steps);
+}
+
+/*!
+ Returns the index of item, which were current after calling previous()
+ \a steps times.
+
+ \sa QMediaPlaylist::playbackMode
+*/
+
+int QMediaPlaylist::previousIndex(int steps) const
+{
+ return d_func()->control->previousIndex(steps);
+}
+
+
+/*!
+ Returns the number of items in the playlist.
+
+ \sa isEmpty()
+ */
+int QMediaPlaylist::mediaCount() const
+{
+ return d_func()->playlist()->mediaCount();
+}
+
+/*!
+ Returns true if the playlist contains no items; otherwise returns false.
+ \sa mediaCount()
+ */
+bool QMediaPlaylist::isEmpty() const
+{
+ return mediaCount() == 0;
+}
+
+/*!
+ Returns true if the playlist can be modified; otherwise returns false.
+ \sa mediaCount()
+ */
+bool QMediaPlaylist::isReadOnly() const
+{
+ return d_func()->playlist()->isReadOnly();
+}
+
+/*!
+ Returns the media content at \a index in the playlist.
+*/
+
+QMediaContent QMediaPlaylist::media(int index) const
+{
+ return d_func()->playlist()->media(index);
+}
+
+/*!
+ Append the media \a content to the playlist.
+
+ Returns true if the operation is successfull, other wise return false.
+ */
+bool QMediaPlaylist::addMedia(const QMediaContent &content)
+{
+ return d_func()->control->playlistProvider()->addMedia(content);
+}
+
+/*!
+ Append multiple media content \a items to the playlist.
+
+ Returns true if the operation is successfull, other wise return false.
+ */
+bool QMediaPlaylist::addMedia(const QList<QMediaContent> &items)
+{
+ return d_func()->control->playlistProvider()->addMedia(items);
+}
+
+/*!
+ Insert the media \a content to the playlist at position \a pos.
+
+ Returns true if the operation is successful, otherwise false.
+*/
+
+bool QMediaPlaylist::insertMedia(int pos, const QMediaContent &content)
+{
+ return d_func()->playlist()->insertMedia(pos, content);
+}
+
+/*!
+ Insert multiple media content \a items to the playlist at position \a pos.
+
+ Returns true if the operation is successful, otherwise false.
+*/
+
+bool QMediaPlaylist::insertMedia(int pos, const QList<QMediaContent> &items)
+{
+ return d_func()->playlist()->insertMedia(pos, items);
+}
+
+/*!
+ Remove the item from the playlist at position \a pos.
+
+ Returns true if the operation is successfull, other wise return false.
+ */
+bool QMediaPlaylist::removeMedia(int pos)
+{
+ Q_D(QMediaPlaylist);
+ return d->playlist()->removeMedia(pos);
+}
+
+/*!
+ Remove the items from the playlist from position \a start to \a end inclusive.
+
+ Returns true if the operation is successfull, other wise return false.
+ */
+bool QMediaPlaylist::removeMedia(int start, int end)
+{
+ Q_D(QMediaPlaylist);
+ return d->playlist()->removeMedia(start, end);
+}
+
+/*!
+ Remove all the items from the playlist.
+
+ Returns true if the operation is successfull, other wise return false.
+ */
+bool QMediaPlaylist::clear()
+{
+ Q_D(QMediaPlaylist);
+ return d->playlist()->clear();
+}
+
+bool QMediaPlaylistPrivate::readItems(QMediaPlaylistReader *reader)
+{
+ while (!reader->atEnd())
+ playlist()->addMedia(reader->readItem());
+
+ return true;
+}
+
+bool QMediaPlaylistPrivate::writeItems(QMediaPlaylistWriter *writer)
+{
+ for (int i=0; i<playlist()->mediaCount(); i++) {
+ if (!writer->writeItem(playlist()->media(i)))
+ return false;
+ }
+ writer->close();
+ return true;
+}
+
+/*!
+ Load playlist from \a location. If \a format is specified, it is used,
+ otherwise format is guessed from location name and data.
+
+ New items are appended to playlist.
+
+ QMediaPlaylist::loaded() signal is emited if playlist was loaded succesfully,
+ otherwise the playlist emits loadFailed().
+*/
+void QMediaPlaylist::load(const QUrl &location, const char *format)
+{
+ Q_D(QMediaPlaylist);
+
+ d->error = NoError;
+ d->errorString.clear();
+
+ if (d->playlist()->load(location,format))
+ return;
+
+ if (isReadOnly()) {
+ d->error = AccessDeniedError;
+ d->errorString = tr("Could not add items to read only playlist.");
+ emit loadFailed();
+ return;
+ }
+
+ foreach (QString const& key, playlistIOLoader()->keys()) {
+ QMediaPlaylistIOInterface* plugin = qobject_cast<QMediaPlaylistIOInterface*>(playlistIOLoader()->instance(key));
+ if (plugin && plugin->canRead(location,format)) {
+ QMediaPlaylistReader *reader = plugin->createReader(location,QByteArray(format));
+ if (reader && d->readItems(reader)) {
+ delete reader;
+ emit loaded();
+ return;
+ }
+ delete reader;
+ }
+ }
+
+ d->error = FormatNotSupportedError;
+ d->errorString = tr("Playlist format is not supported");
+ emit loadFailed();
+
+ return;
+}
+
+/*!
+ Load playlist from QIODevice \a device. If \a format is specified, it is used,
+ otherwise format is guessed from device data.
+
+ New items are appended to playlist.
+
+ QMediaPlaylist::loaded() signal is emited if playlist was loaded succesfully,
+ otherwise the playlist emits loadFailed().
+*/
+void QMediaPlaylist::load(QIODevice * device, const char *format)
+{
+ Q_D(QMediaPlaylist);
+
+ d->error = NoError;
+ d->errorString.clear();
+
+ if (d->playlist()->load(device,format))
+ return;
+
+ if (isReadOnly()) {
+ d->error = AccessDeniedError;
+ d->errorString = tr("Could not add items to read only playlist.");
+ emit loadFailed();
+ return;
+ }
+
+ foreach (QString const& key, playlistIOLoader()->keys()) {
+ QMediaPlaylistIOInterface* plugin = qobject_cast<QMediaPlaylistIOInterface*>(playlistIOLoader()->instance(key));
+ if (plugin && plugin->canRead(device,format)) {
+ QMediaPlaylistReader *reader = plugin->createReader(device,QByteArray(format));
+ if (reader && d->readItems(reader)) {
+ delete reader;
+ emit loaded();
+ return;
+ }
+ delete reader;
+ }
+ }
+
+ d->error = FormatNotSupportedError;
+ d->errorString = tr("Playlist format is not supported");
+ emit loadFailed();
+
+ return;
+}
+
+/*!
+ Save playlist to \a location. If \a format is specified, it is used,
+ otherwise format is guessed from location name.
+
+ Returns true if playlist was saved succesfully, otherwise returns false.
+ */
+bool QMediaPlaylist::save(const QUrl &location, const char *format)
+{
+ Q_D(QMediaPlaylist);
+
+ d->error = NoError;
+ d->errorString.clear();
+
+ if (d->playlist()->save(location,format))
+ return true;
+
+ QFile file(location.toLocalFile());
+
+ if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
+ d->error = AccessDeniedError;
+ d->errorString = tr("The file could not be accessed.");
+ return false;
+ }
+
+ return save(&file, format);
+}
+
+/*!
+ Save playlist to QIODevice \a device using format \a format.
+
+ Returns true if playlist was saved succesfully, otherwise returns false.
+*/
+bool QMediaPlaylist::save(QIODevice * device, const char *format)
+{
+ Q_D(QMediaPlaylist);
+
+ d->error = NoError;
+ d->errorString.clear();
+
+ if (d->playlist()->save(device,format))
+ return true;
+
+ foreach (QString const& key, playlistIOLoader()->keys()) {
+ QMediaPlaylistIOInterface* plugin = qobject_cast<QMediaPlaylistIOInterface*>(playlistIOLoader()->instance(key));
+ if (plugin && plugin->canWrite(device,format)) {
+ QMediaPlaylistWriter *writer = plugin->createWriter(device,QByteArray(format));
+ if (writer && d->writeItems(writer)) {
+ delete writer;
+ return true;
+ }
+ delete writer;
+ }
+ }
+
+ d->error = FormatNotSupportedError;
+ d->errorString = tr("Playlist format is not supported.");
+
+ return false;
+}
+
+/*!
+ Returns the last error condition.
+*/
+QMediaPlaylist::Error QMediaPlaylist::error() const
+{
+ return d_func()->error;
+}
+
+/*!
+ Returns the string describing the last error condition.
+*/
+QString QMediaPlaylist::errorString() const
+{
+ return d_func()->errorString;
+}
+
+/*!
+ Shuffle items in the playlist.
+*/
+void QMediaPlaylist::shuffle()
+{
+ d_func()->playlist()->shuffle();
+}
+
+
+/*!
+ Advance to the next media content in playlist.
+*/
+void QMediaPlaylist::next()
+{
+ d_func()->control->next();
+}
+
+/*!
+ Return to the previous media content in playlist.
+*/
+void QMediaPlaylist::previous()
+{
+ d_func()->control->previous();
+}
+
+/*!
+ Activate media content from playlist at position \a playlistPosition.
+*/
+
+void QMediaPlaylist::setCurrentIndex(int playlistPosition)
+{
+ d_func()->control->setCurrentIndex(playlistPosition);
+}
+
+/*!
+ \fn void QMediaPlaylist::mediaInserted(int start, int end)
+
+ This signal is emitted after media has been inserted into the playlist.
+ The new items are those between \a start and \a end inclusive.
+ */
+
+/*!
+ \fn void QMediaPlaylist::mediaRemoved(int start, int end)
+
+ This signal is emitted after media has been removed from the playlist.
+ The removed items are those between \a start and \a end inclusive.
+ */
+
+/*!
+ \fn void QMediaPlaylist::mediaChanged(int start, int end)
+
+ This signal is emitted after media has been changed in the playlist
+ between \a start and \a end positions inclusive.
+ */
+
+/*!
+ \fn void QMediaPlaylist::currentIndexChanged(int position)
+
+ Signal emitted when playlist position changed to \a position.
+*/
+
+/*!
+ \fn void QMediaPlaylist::playbackModeChanged(QMediaPlaylist::PlaybackMode mode)
+
+ Signal emitted when playback mode changed to \a mode.
+*/
+
+/*!
+ \fn void QMediaPlaylist::mediaAboutToBeInserted(int start, int end)
+
+ Signal emitted when item to be inserted at \a start and ending at \a end.
+*/
+
+/*!
+ \fn void QMediaPlaylist::mediaAboutToBeRemoved(int start, int end)
+
+ Signal emitted when item to de deleted ar \a start and ending at \a end.
+*/
+
+/*!
+ \fn void QMediaPlaylist::currentMediaChanged(const QMediaContent &content)
+
+ Signal emitted when current media changes to \a content.
+*/
+
+/*!
+ \property QMediaPlaylist::currentIndex
+ \brief Current position.
+*/
+
+/*!
+ \property QMediaPlaylist::currentMedia
+ \brief Current media content.
+*/
+
+/*!
+ \fn QMediaPlaylist::loaded()
+
+ Signal emitted when playlist finished loading.
+*/
+
+/*!
+ \fn QMediaPlaylist::loadFailed()
+
+ Signal emitted if failed to load playlist.
+*/
+
+/*!
+ \enum QMediaPlaylist::Error
+
+ This enum describes the QMediaPlaylist error codes.
+
+ \value NoError No errors.
+ \value FormatError Format error.
+ \value FormatNotSupportedError Format not supported.
+ \value NetworkError Network error.
+ \value AccessDeniedError Access denied error.
+*/
+
+QT_END_NAMESPACE
+
+#include "moc_qmediaplaylist.cpp"
+#include "moc_qmediaplaylist_p.cpp"
diff --git a/src/multimedia/mediaservices/base/qmediaplaylist.h b/src/multimedia/mediaservices/base/qmediaplaylist.h
new file mode 100644
index 0000000..6cae7c5
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qmediaplaylist.h
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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$
+**
+****************************************************************************/
+
+#ifndef QMEDIAPLAYLIST_H
+#define QMEDIAPLAYLIST_H
+
+#include <QtCore/qobject.h>
+
+#include <QtMediaServices/qmediacontent.h>
+#include <QtMediaServices/qmediaobject.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+class QMediaPlaylistProvider;
+
+class QMediaPlaylistPrivate;
+class Q_MEDIASERVICES_EXPORT QMediaPlaylist : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QMediaPlaylist::PlaybackMode playbackMode READ playbackMode WRITE setPlaybackMode NOTIFY playbackModeChanged)
+ Q_PROPERTY(QMediaContent currentMedia READ currentMedia NOTIFY currentMediaChanged)
+ Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged)
+ Q_ENUMS(PlaybackMode Error)
+
+public:
+ enum PlaybackMode { CurrentItemOnce, CurrentItemInLoop, Linear, Loop, Random };
+ enum Error { NoError, FormatError, FormatNotSupportedError, NetworkError, AccessDeniedError };
+
+ QMediaPlaylist(QObject *parent = 0);
+ virtual ~QMediaPlaylist();
+
+ QMediaObject *mediaObject() const;
+ void setMediaObject(QMediaObject *object);
+
+ PlaybackMode playbackMode() const;
+ void setPlaybackMode(PlaybackMode mode);
+
+ int currentIndex() const;
+ QMediaContent currentMedia() const;
+
+ int nextIndex(int steps = 1) const;
+ int previousIndex(int steps = 1) const;
+
+ QMediaContent media(int index) const;
+
+ int mediaCount() const;
+ bool isEmpty() const;
+ bool isReadOnly() const;
+
+ bool addMedia(const QMediaContent &content);
+ bool addMedia(const QList<QMediaContent> &items);
+ bool insertMedia(int index, const QMediaContent &content);
+ bool insertMedia(int index, const QList<QMediaContent> &items);
+ bool removeMedia(int pos);
+ bool removeMedia(int start, int end);
+ bool clear();
+
+ void load(const QUrl &location, const char *format = 0);
+ void load(QIODevice * device, const char *format = 0);
+
+ bool save(const QUrl &location, const char *format = 0);
+ bool save(QIODevice * device, const char *format);
+
+ Error error() const;
+ QString errorString() const;
+
+public Q_SLOTS:
+ void shuffle();
+
+ void next();
+ void previous();
+
+ void setCurrentIndex(int index);
+
+Q_SIGNALS:
+ void currentIndexChanged(int index);
+ void playbackModeChanged(QMediaPlaylist::PlaybackMode mode);
+ void currentMediaChanged(const QMediaContent&);
+
+ void mediaAboutToBeInserted(int start, int end);
+ void mediaInserted(int start, int end);
+ void mediaAboutToBeRemoved(int start, int end);
+ void mediaRemoved(int start, int end);
+ void mediaChanged(int start, int end);
+
+ void loaded();
+ void loadFailed();
+
+protected:
+ QMediaPlaylistPrivate *d_ptr;
+
+private:
+ Q_DECLARE_PRIVATE(QMediaPlaylist)
+ Q_PRIVATE_SLOT(d_func(), void _q_loadFailed(QMediaPlaylist::Error, const QString &))
+};
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QMediaPlaylist::PlaybackMode)
+Q_DECLARE_METATYPE(QMediaPlaylist::Error)
+
+QT_END_HEADER
+
+#endif // QMEDIAPLAYLIST_H
diff --git a/src/multimedia/mediaservices/base/qmediaplaylist_p.h b/src/multimedia/mediaservices/base/qmediaplaylist_p.h
new file mode 100644
index 0000000..a5f290e
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qmediaplaylist_p.h
@@ -0,0 +1,172 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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$
+**
+****************************************************************************/
+
+#ifndef QMEDIAPLAYLIST_P_H
+#define QMEDIAPLAYLIST_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtMediaServices/qmediaplaylist.h>
+#include <QtMediaServices/qmediaplaylistcontrol.h>
+#include <QtMediaServices/qmediaplayer.h>
+#include <QtMediaServices/qmediaplayercontrol.h>
+#include <QtMediaServices/qlocalmediaplaylistprovider.h>
+#include "qmediaobject_p.h"
+
+#include <QtCore/qdebug.h>
+
+#ifdef Q_MOC_RUN
+# pragma Q_MOC_EXPAND_MACROS
+#endif
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QMediaPlaylistControl;
+class QMediaPlaylistProvider;
+class QMediaPlaylistReader;
+class QMediaPlaylistWriter;
+class QMediaPlayerControl;
+
+class QMediaPlaylistPrivate
+{
+ Q_DECLARE_PUBLIC(QMediaPlaylist)
+public:
+ QMediaPlaylistPrivate()
+ :mediaObject(0),
+ control(0),
+ localPlaylistControl(0),
+ error(QMediaPlaylist::NoError)
+ {
+ }
+
+ virtual ~QMediaPlaylistPrivate() {}
+
+ void _q_loadFailed(QMediaPlaylist::Error error, const QString &errorString)
+ {
+ this->error = error;
+ this->errorString = errorString;
+
+ emit q_ptr->loadFailed();
+ }
+
+ void _q_mediaObjectDeleted()
+ {
+ Q_Q(QMediaPlaylist);
+ mediaObject = 0;
+ if (control != localPlaylistControl)
+ control = 0;
+ q->setMediaObject(0);
+ }
+
+ QMediaObject *mediaObject;
+
+ QMediaPlaylistControl *control;
+ QMediaPlaylistProvider *playlist() const { return control->playlistProvider(); }
+
+ QMediaPlaylistControl *localPlaylistControl;
+
+ bool readItems(QMediaPlaylistReader *reader);
+ bool writeItems(QMediaPlaylistWriter *writer);
+
+ QMediaPlaylist::Error error;
+ QString errorString;
+
+ QMediaPlaylist *q_ptr;
+};
+
+
+class QLocalMediaPlaylistControl : public QMediaPlaylistControl
+{
+ Q_OBJECT
+public:
+ QLocalMediaPlaylistControl(QObject *parent)
+ :QMediaPlaylistControl(parent)
+ {
+ QMediaPlaylistProvider *playlist = new QLocalMediaPlaylistProvider(this);
+ m_navigator = new QMediaPlaylistNavigator(playlist,this);
+ m_navigator->setPlaybackMode(QMediaPlaylist::Linear);
+
+ connect(m_navigator, SIGNAL(currentIndexChanged(int)), SIGNAL(currentIndexChanged(int)));
+ connect(m_navigator, SIGNAL(activated(QMediaContent)), SIGNAL(currentMediaChanged(QMediaContent)));
+ }
+
+ virtual ~QLocalMediaPlaylistControl() {};
+
+ QMediaPlaylistProvider* playlistProvider() const { return m_navigator->playlist(); }
+ bool setPlaylistProvider(QMediaPlaylistProvider *mediaPlaylist)
+ {
+ m_navigator->setPlaylist(mediaPlaylist);
+ emit playlistProviderChanged();
+ return true;
+ }
+
+ int currentIndex() const { return m_navigator->currentIndex(); }
+ void setCurrentIndex(int position) { m_navigator->jump(position); }
+ int nextIndex(int steps) const { return m_navigator->nextIndex(steps); }
+ int previousIndex(int steps) const { return m_navigator->previousIndex(steps); }
+
+ void next() { m_navigator->next(); }
+ void previous() { m_navigator->previous(); }
+
+ QMediaPlaylist::PlaybackMode playbackMode() const { return m_navigator->playbackMode(); }
+ void setPlaybackMode(QMediaPlaylist::PlaybackMode mode) { m_navigator->setPlaybackMode(mode); }
+
+private:
+ QMediaPlaylistNavigator *m_navigator;
+};
+
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QMEDIAPLAYLIST_P_H
diff --git a/src/multimedia/mediaservices/base/qmediaplaylistcontrol.cpp b/src/multimedia/mediaservices/base/qmediaplaylistcontrol.cpp
new file mode 100644
index 0000000..016c55d
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qmediaplaylistcontrol.cpp
@@ -0,0 +1,204 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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 <QtMediaServices/qmediaplaylistcontrol.h>
+#include "qmediacontrol_p.h"
+
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QMediaPlaylistControl
+ \ingroup multimedia-serv
+ \since 4.7
+
+ \preliminary
+ \brief The QMediaPlaylistControl class provides access to the playlist functionality of a
+ QMediaService.
+
+ If a QMediaService contains an internal playlist it will implement QMediaPlaylistControl. This
+ control provides access to the contents of the \l {playlistProvider()}{playlist}, as well as the
+ \l {currentIndex()}{position} of the current media, and a means of navigating to the
+ \l {next()}{next} and \l {previous()}{previous} media.
+
+ The functionality provided by the control is exposed to application code through the
+ QMediaPlaylist class.
+
+ The interface name of QMediaPlaylistControl is \c com.nokia.Qt.QMediaPlaylistControl/1.0 as
+ defined in QMediaPlaylistControl_iid.
+
+ \sa QMediaService::control(), QMediaPlayer
+*/
+
+/*!
+ \macro QMediaPlaylistControl_iid
+
+ \c com.nokia.Qt.QMediaPlaylistControl/1.0
+
+ Defines the interface name of the QMediaPlaylistControl class.
+
+ \relates QMediaPlaylistControl
+*/
+
+/*!
+ Create a new playlist control object with the given \a parent.
+*/
+QMediaPlaylistControl::QMediaPlaylistControl(QObject *parent):
+ QMediaControl(*new QMediaControlPrivate, parent)
+{
+}
+
+/*!
+ Destroys the playlist control.
+*/
+QMediaPlaylistControl::~QMediaPlaylistControl()
+{
+}
+
+
+/*!
+ \fn QMediaPlaylistControl::playlistProvider() const
+
+ Returns the playlist used by this media player.
+*/
+
+/*!
+ \fn QMediaPlaylistControl::setPlaylistProvider(QMediaPlaylistProvider *playlist)
+
+ Set the playlist of this media player to \a playlist.
+
+ In many cases it is possible just to use the playlist
+ constructed by player, but sometimes replacing the whole
+ playlist allows to avoid copyting of all the items bettween playlists.
+
+ Returns true if player can use this passed playlist; otherwise returns false.
+
+*/
+
+/*!
+ \fn QMediaPlaylistControl::currentIndex() const
+
+ Returns position of the current media source in the playlist.
+*/
+
+/*!
+ \fn QMediaPlaylistControl::setCurrentIndex(int position)
+
+ Jump to the item at the given \a position.
+*/
+
+/*!
+ \fn QMediaPlaylistControl::nextIndex(int step) const
+
+ Returns the index of item, which were current after calling next()
+ \a step times.
+
+ Returned value depends on the size of playlist, current position
+ and playback mode.
+
+ \sa QMediaPlaylist::playbackMode
+*/
+
+/*!
+ \fn QMediaPlaylistControl::previousIndex(int step) const
+
+ Returns the index of item, which were current after calling previous()
+ \a step times.
+
+ \sa QMediaPlaylist::playbackMode
+*/
+
+/*!
+ \fn QMediaPlaylistControl::next()
+
+ Moves to the next item in playlist.
+*/
+
+/*!
+ \fn QMediaPlaylistControl::previous()
+
+ Returns to the previous item in playlist.
+*/
+
+/*!
+ \fn QMediaPlaylistControl::playbackMode() const
+
+ Returns the playlist navigation mode.
+
+ \sa QMediaPlaylist::PlaybackMode
+*/
+
+/*!
+ \fn QMediaPlaylistControl::setPlaybackMode(QMediaPlaylist::PlaybackMode mode)
+
+ Sets the playback \a mode.
+
+ \sa QMediaPlaylist::PlaybackMode
+*/
+
+/*!
+ \fn QMediaPlaylistControl::playlistProviderChanged()
+
+ Signal emited when the playlist provider has changed.
+*/
+
+/*!
+ \fn QMediaPlaylistControl::currentIndexChanged(int position)
+
+ Signal emited when the playlist \a position is changed.
+*/
+
+/*!
+ \fn QMediaPlaylistControl::playbackModeChanged(QMediaPlaylist::PlaybackMode mode)
+
+ Signal emited when the playback \a mode is changed.
+*/
+
+/*!
+ \fn QMediaPlaylistControl::currentMediaChanged(const QMediaContent& content)
+
+ Signal emitted when current media changes to \a content.
+*/
+
+#include "moc_qmediaplaylistcontrol.cpp"
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/mediaservices/base/qmediaplaylistcontrol.h b/src/multimedia/mediaservices/base/qmediaplaylistcontrol.h
new file mode 100644
index 0000000..2dc4575
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qmediaplaylistcontrol.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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$
+**
+****************************************************************************/
+
+
+#ifndef QMEDIAPLAYLISTCONTROL_H
+#define QMEDIAPLAYLISTCONTROL_H
+
+#include <QtMediaServices/qmediacontrol.h>
+#include <QtMediaServices/qmediaplaylistnavigator.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QMediaPlaylistProvider;
+
+class Q_MEDIASERVICES_EXPORT QMediaPlaylistControl : public QMediaControl
+{
+ Q_OBJECT
+
+public:
+ virtual ~QMediaPlaylistControl();
+
+ virtual QMediaPlaylistProvider* playlistProvider() const = 0;
+ virtual bool setPlaylistProvider(QMediaPlaylistProvider *playlist) = 0;
+
+ virtual int currentIndex() const = 0;
+ virtual void setCurrentIndex(int position) = 0;
+ virtual int nextIndex(int steps) const = 0;
+ virtual int previousIndex(int steps) const = 0;
+
+ virtual void next() = 0;
+ virtual void previous() = 0;
+
+ virtual QMediaPlaylist::PlaybackMode playbackMode() const = 0;
+ virtual void setPlaybackMode(QMediaPlaylist::PlaybackMode mode) = 0;
+
+Q_SIGNALS:
+ void playlistProviderChanged();
+ void currentIndexChanged(int position);
+ void currentMediaChanged(const QMediaContent&);
+ void playbackModeChanged(QMediaPlaylist::PlaybackMode mode);
+
+protected:
+ QMediaPlaylistControl(QObject* parent = 0);
+};
+
+#define QMediaPlaylistControl_iid "com.nokia.Qt.QMediaPlaylistControl/1.0"
+Q_MEDIA_DECLARE_CONTROL(QMediaPlaylistControl, QMediaPlaylistControl_iid)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QMEDIAPLAYLISTCONTROL_H
diff --git a/src/multimedia/mediaservices/base/qmediaplaylistioplugin.cpp b/src/multimedia/mediaservices/base/qmediaplaylistioplugin.cpp
new file mode 100644
index 0000000..60e80e5
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qmediaplaylistioplugin.cpp
@@ -0,0 +1,192 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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 <QtMediaServices/qmediaplaylistioplugin.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QMediaPlaylistReader
+ \preliminary
+ \since 4.7
+ \brief The QMediaPlaylistReader class provides an interface for reading a playlist file.
+
+ \sa QMediaPlaylistIOPlugin
+*/
+
+/*!
+ Destroys a media playlist reader.
+*/
+QMediaPlaylistReader::~QMediaPlaylistReader()
+{
+}
+
+/*!
+ \fn QMediaPlaylistReader::atEnd() const
+
+ Identifies if a playlist reader has reached the end of its input.
+
+ Returns true if the reader has reached the end; and false otherwise.
+*/
+
+/*!
+ \fn QMediaPlaylistReader::readItem()
+
+ Reads an item of media from a playlist file.
+
+ Returns the read media, or a null QMediaContent if no more media is available.
+*/
+
+/*!
+ \fn QMediaPlaylistReader::close()
+
+ Closes a playlist reader's input device.
+*/
+
+/*!
+ \class QMediaPlaylistWriter
+ \preliminary
+ \since 4.7
+ \brief The QMediaPlaylistWriter class provides an interface for writing a playlist file.
+
+ \sa QMediaPlaylistIOPlugin
+*/
+
+/*!
+ Destroys a media playlist writer.
+*/
+QMediaPlaylistWriter::~QMediaPlaylistWriter()
+{
+}
+
+/*!
+ \fn QMediaPlaylistWriter::writeItem(const QMediaContent &media)
+
+ Writes an item of \a media to a playlist file.
+
+ Returns true if the media was written succesfully; and false otherwise.
+*/
+
+/*!
+ \fn QMediaPlaylistWriter::close()
+
+ Finalizes the writing of a playlist and closes the output device.
+*/
+
+/*!
+ \class QMediaPlaylistIOPlugin
+ \since 4.7
+ \brief The QMediaPlaylistIOPlugin class provides an interface for media playlist I/O plug-ins.
+*/
+
+/*!
+ Constructs a media playlist I/O plug-in with the given \a parent.
+*/
+QMediaPlaylistIOPlugin::QMediaPlaylistIOPlugin(QObject *parent)
+ :QObject(parent)
+{
+}
+
+/*!
+ Destroys a media playlist I/O plug-in.
+*/
+QMediaPlaylistIOPlugin::~QMediaPlaylistIOPlugin()
+{
+}
+
+/*!
+ \fn QMediaPlaylistIOPlugin::canRead(QIODevice *device, const QByteArray &format) const
+
+ Identifies if plug-in can read \a format data from an I/O \a device.
+
+ Returns true if the data can be read; and false otherwise.
+*/
+
+/*!
+ \fn QMediaPlaylistIOPlugin::canRead(const QUrl& location, const QByteArray &format) const
+
+ Identifies if a plug-in can read \a format data from a URL \a location.
+
+ Returns true if the data can be read; and false otherwise.
+*/
+
+/*!
+ \fn QMediaPlaylistIOPlugin::canWrite(QIODevice *device, const QByteArray &format) const
+
+ Identifies if a plug-in can write \a format data to an I/O \a device.
+
+ Returns true if the data can be written; and false otherwise.
+*/
+
+/*!
+ \fn QMediaPlaylistIOPlugin::keys() const
+
+ Returns a list of format keys supported by a plug-in.
+*/
+
+/*!
+ \fn QMediaPlaylistIOPlugin::createReader(QIODevice *device, const QByteArray &format)
+
+ Returns a new QMediaPlaylistReader which reads \a format data from an I/O \a device.
+
+ If the device is invalid or the format is unsupported this will return a null pointer.
+*/
+
+/*!
+ \fn QMediaPlaylistIOPlugin::createReader(const QUrl& location, const QByteArray &format)
+
+ Returns a new QMediaPlaylistReader which reads \a format data from a URL \a location.
+
+ If the location or the format is unsupported this will return a null pointer.
+*/
+
+/*!
+ \fn QMediaPlaylistIOPlugin::createWriter(QIODevice *device, const QByteArray &format)
+
+ Returns a new QMediaPlaylistWriter which writes \a format data to an I/O \a device.
+
+ If the device is invalid or the format is unsupported this will return a null pointer.
+*/
+
+QT_END_NAMESPACE
+
+#include "moc_qmediaplaylistioplugin.cpp"
+
diff --git a/src/multimedia/mediaservices/base/qmediaplaylistioplugin.h b/src/multimedia/mediaservices/base/qmediaplaylistioplugin.h
new file mode 100644
index 0000000..ed8e832
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qmediaplaylistioplugin.h
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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$
+**
+****************************************************************************/
+
+#ifndef QMEDIAPLAYLISTIOPLUGIN_H
+#define QMEDIAPLAYLISTIOPLUGIN_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qplugin.h>
+#include <QtCore/qfactoryinterface.h>
+
+#include <QtMediaServices/qmediacontent.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QString;
+class QUrl;
+class QByteArray;
+class QIODevice;
+class QStringList;
+
+class Q_MEDIASERVICES_EXPORT QMediaPlaylistReader
+{
+public:
+ virtual ~QMediaPlaylistReader();
+
+ virtual bool atEnd() const = 0;
+ virtual QMediaContent readItem() = 0;
+ virtual void close() = 0;
+};
+
+class Q_MEDIASERVICES_EXPORT QMediaPlaylistWriter
+{
+public:
+ virtual ~QMediaPlaylistWriter();
+
+ virtual bool writeItem(const QMediaContent &content) = 0;
+ virtual void close() = 0;
+};
+
+struct Q_MEDIASERVICES_EXPORT QMediaPlaylistIOInterface : public QFactoryInterface
+{
+ virtual bool canRead(QIODevice *device, const QByteArray &format = QByteArray() ) const = 0;
+ virtual bool canRead(const QUrl& location, const QByteArray &format = QByteArray()) const = 0;
+
+ virtual bool canWrite(QIODevice *device, const QByteArray &format) const = 0;
+
+ virtual QMediaPlaylistReader *createReader(QIODevice *device, const QByteArray &format = QByteArray()) = 0;
+ virtual QMediaPlaylistReader *createReader(const QUrl& location, const QByteArray &format = QByteArray()) = 0;
+
+ virtual QMediaPlaylistWriter *createWriter(QIODevice *device, const QByteArray &format) = 0;
+};
+
+#define QMediaPlaylistIOInterface_iid "com.nokia.Qt.QMediaPlaylistIOInterface"
+Q_DECLARE_INTERFACE(QMediaPlaylistIOInterface, QMediaPlaylistIOInterface_iid);
+
+class Q_MEDIASERVICES_EXPORT QMediaPlaylistIOPlugin : public QObject, public QMediaPlaylistIOInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QMediaPlaylistIOInterface:QFactoryInterface)
+
+public:
+ explicit QMediaPlaylistIOPlugin(QObject *parent = 0);
+ virtual ~QMediaPlaylistIOPlugin();
+
+ virtual bool canRead(QIODevice *device, const QByteArray &format = QByteArray() ) const = 0;
+ virtual bool canRead(const QUrl& location, const QByteArray &format = QByteArray()) const = 0;
+
+ virtual bool canWrite(QIODevice *device, const QByteArray &format) const = 0;
+
+ virtual QStringList keys() const = 0;
+
+ virtual QMediaPlaylistReader *createReader(QIODevice *device, const QByteArray &format = QByteArray()) = 0;
+ virtual QMediaPlaylistReader *createReader(const QUrl& location, const QByteArray &format = QByteArray()) = 0;
+
+ virtual QMediaPlaylistWriter *createWriter(QIODevice *device, const QByteArray &format) = 0;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QMEDIAPLAYLISTIOPLUGIN_H
diff --git a/src/multimedia/mediaservices/base/qmediaplaylistnavigator.cpp b/src/multimedia/mediaservices/base/qmediaplaylistnavigator.cpp
new file mode 100644
index 0000000..e3eec5e
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qmediaplaylistnavigator.cpp
@@ -0,0 +1,545 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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 <QtMediaServices/qmediaplaylistnavigator.h>
+#include <QtMediaServices/qmediaplaylistprovider.h>
+#include <QtMediaServices/qmediaplaylist.h>
+#include "qmediaobject_p.h"
+
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+class QMediaPlaylistNullProvider : public QMediaPlaylistProvider
+{
+public:
+ QMediaPlaylistNullProvider() :QMediaPlaylistProvider() {}
+ virtual ~QMediaPlaylistNullProvider() {}
+ virtual int mediaCount() const {return 0;}
+ virtual QMediaContent media(int) const { return QMediaContent(); }
+};
+
+Q_GLOBAL_STATIC(QMediaPlaylistNullProvider, _q_nullMediaPlaylist)
+
+class QMediaPlaylistNavigatorPrivate
+{
+ Q_DECLARE_NON_CONST_PUBLIC(QMediaPlaylistNavigator)
+public:
+ QMediaPlaylistNavigatorPrivate()
+ :playlist(0),
+ currentPos(-1),
+ lastValidPos(-1),
+ playbackMode(QMediaPlaylist::Linear),
+ randomPositionsOffset(-1)
+ {
+ }
+
+ QMediaPlaylistProvider *playlist;
+ int currentPos;
+ int lastValidPos; //to be used with CurrentItemOnce playback mode
+ QMediaPlaylist::PlaybackMode playbackMode;
+ QMediaContent currentItem;
+
+ mutable QList<int> randomModePositions;
+ mutable int randomPositionsOffset;
+
+ int nextItemPos(int steps = 1) const;
+ int previousItemPos(int steps = 1) const;
+
+ void _q_mediaInserted(int start, int end);
+ void _q_mediaRemoved(int start, int end);
+ void _q_mediaChanged(int start, int end);
+
+ QMediaPlaylistNavigator *q_ptr;
+};
+
+
+int QMediaPlaylistNavigatorPrivate::nextItemPos(int steps) const
+{
+ if (playlist->mediaCount() == 0)
+ return -1;
+
+ if (steps == 0)
+ return currentPos;
+
+ switch (playbackMode) {
+ case QMediaPlaylist::CurrentItemOnce:
+ return /*currentPos == -1 ? lastValidPos :*/ -1;
+ case QMediaPlaylist::CurrentItemInLoop:
+ return currentPos;
+ case QMediaPlaylist::Linear:
+ {
+ int nextPos = currentPos+steps;
+ return nextPos < playlist->mediaCount() ? nextPos : -1;
+ }
+ case QMediaPlaylist::Loop:
+ return (currentPos+steps) % playlist->mediaCount();
+ case QMediaPlaylist::Random:
+ {
+ //TODO: limit the history size
+
+ if (randomPositionsOffset == -1) {
+ randomModePositions.clear();
+ randomModePositions.append(currentPos);
+ randomPositionsOffset = 0;
+ }
+
+ while (randomModePositions.size() < randomPositionsOffset+steps+1)
+ randomModePositions.append(-1);
+ int res = randomModePositions[randomPositionsOffset+steps];
+ if (res<0 || res >= playlist->mediaCount()) {
+ res = qrand() % playlist->mediaCount();
+ randomModePositions[randomPositionsOffset+steps] = res;
+ }
+
+ return res;
+ }
+ }
+
+ return -1;
+}
+
+int QMediaPlaylistNavigatorPrivate::previousItemPos(int steps) const
+{
+ if (playlist->mediaCount() == 0)
+ return -1;
+
+ if (steps == 0)
+ return currentPos;
+
+ switch (playbackMode) {
+ case QMediaPlaylist::CurrentItemOnce:
+ return /*currentPos == -1 ? lastValidPos :*/ -1;
+ case QMediaPlaylist::CurrentItemInLoop:
+ return currentPos;
+ case QMediaPlaylist::Linear:
+ {
+ int prevPos = currentPos == -1 ? playlist->mediaCount() - steps : currentPos - steps;
+ return prevPos>=0 ? prevPos : -1;
+ }
+ case QMediaPlaylist::Loop:
+ {
+ int prevPos = currentPos - steps;
+ while (prevPos<0)
+ prevPos += playlist->mediaCount();
+ return prevPos;
+ }
+ case QMediaPlaylist::Random:
+ {
+ //TODO: limit the history size
+
+ if (randomPositionsOffset == -1) {
+ randomModePositions.clear();
+ randomModePositions.append(currentPos);
+ randomPositionsOffset = 0;
+ }
+
+ while (randomPositionsOffset-steps < 0) {
+ randomModePositions.prepend(-1);
+ randomPositionsOffset++;
+ }
+
+ int res = randomModePositions[randomPositionsOffset-steps];
+ if (res<0 || res >= playlist->mediaCount()) {
+ res = qrand() % playlist->mediaCount();
+ randomModePositions[randomPositionsOffset-steps] = res;
+ }
+
+ return res;
+ }
+ }
+
+ return -1;
+}
+
+/*!
+ \class QMediaPlaylistNavigator
+ \preliminary
+ \since 4.7
+ \brief The QMediaPlaylistNavigator class provides navigation for a media playlist.
+
+ \sa QMediaPlaylist, QMediaPlaylistProvider
+*/
+
+
+/*!
+ Constructs a media playlist navigator for a \a playlist.
+
+ The \a parent is passed to QObject.
+ */
+QMediaPlaylistNavigator::QMediaPlaylistNavigator(QMediaPlaylistProvider *playlist, QObject *parent)
+ : QObject(parent)
+ , d_ptr(new QMediaPlaylistNavigatorPrivate)
+{
+ d_ptr->q_ptr = this;
+
+ setPlaylist(playlist ? playlist : _q_nullMediaPlaylist());
+}
+
+/*!
+ Destroys a media playlist navigator.
+ */
+
+QMediaPlaylistNavigator::~QMediaPlaylistNavigator()
+{
+ delete d_ptr;
+}
+
+
+/*! \property QMediaPlaylistNavigator::playbackMode
+ Contains the playback mode.
+ */
+QMediaPlaylist::PlaybackMode QMediaPlaylistNavigator::playbackMode() const
+{
+ return d_func()->playbackMode;
+}
+
+/*!
+ Sets the playback \a mode.
+ */
+void QMediaPlaylistNavigator::setPlaybackMode(QMediaPlaylist::PlaybackMode mode)
+{
+ Q_D(QMediaPlaylistNavigator);
+ if (d->playbackMode == mode)
+ return;
+
+ if (mode == QMediaPlaylist::Random) {
+ d->randomPositionsOffset = 0;
+ d->randomModePositions.append(d->currentPos);
+ } else if (d->playbackMode == QMediaPlaylist::Random) {
+ d->randomPositionsOffset = -1;
+ d->randomModePositions.clear();
+ }
+
+ d->playbackMode = mode;
+
+ emit playbackModeChanged(mode);
+ emit surroundingItemsChanged();
+}
+
+/*!
+ Returns the playlist being navigated.
+*/
+
+QMediaPlaylistProvider *QMediaPlaylistNavigator::playlist() const
+{
+ return d_func()->playlist;
+}
+
+/*!
+ Sets the \a playlist to navigate.
+*/
+void QMediaPlaylistNavigator::setPlaylist(QMediaPlaylistProvider *playlist)
+{
+ Q_D(QMediaPlaylistNavigator);
+
+ if (d->playlist == playlist)
+ return;
+
+ if (d->playlist) {
+ d->playlist->disconnect(this);
+ }
+
+ if (playlist) {
+ d->playlist = playlist;
+ } else {
+ //assign to shared readonly null playlist
+ d->playlist = _q_nullMediaPlaylist();
+ }
+
+ connect(d->playlist, SIGNAL(mediaInserted(int,int)), SLOT(_q_mediaInserted(int,int)));
+ connect(d->playlist, SIGNAL(mediaRemoved(int,int)), SLOT(_q_mediaRemoved(int,int)));
+ connect(d->playlist, SIGNAL(mediaChanged(int,int)), SLOT(_q_mediaChanged(int,int)));
+
+ d->randomPositionsOffset = -1;
+ d->randomModePositions.clear();
+
+ if (d->currentPos != -1) {
+ d->currentPos = -1;
+ emit currentIndexChanged(-1);
+ }
+
+ if (!d->currentItem.isNull()) {
+ d->currentItem = QMediaContent();
+ emit activated(d->currentItem); //stop playback
+ }
+}
+
+/*! \property QMediaPlaylistNavigator::currentItem
+
+ Contains the media at the current position in the playlist.
+
+ \sa currentIndex()
+*/
+
+QMediaContent QMediaPlaylistNavigator::currentItem() const
+{
+ return itemAt(d_func()->currentPos);
+}
+
+/*! \fn QMediaContent QMediaPlaylistNavigator::nextItem(int steps) const
+
+ Returns the media that is \a steps positions ahead of the current
+ position in the playlist.
+
+ \sa nextIndex()
+*/
+QMediaContent QMediaPlaylistNavigator::nextItem(int steps) const
+{
+ return itemAt(nextIndex(steps));
+}
+
+/*!
+ Returns the media that is \a steps positions behind the current
+ position in the playlist.
+
+ \sa previousIndex()
+ */
+QMediaContent QMediaPlaylistNavigator::previousItem(int steps) const
+{
+ return itemAt(previousIndex(steps));
+}
+
+/*!
+ Returns the media at a \a position in the playlist.
+ */
+QMediaContent QMediaPlaylistNavigator::itemAt(int position) const
+{
+ return d_func()->playlist->media(position);
+}
+
+/*! \property QMediaPlaylistNavigator::currentIndex
+
+ Contains the position of the current media.
+
+ If no media is current, the property contains -1.
+
+ \sa nextIndex(), previousIndex()
+*/
+
+int QMediaPlaylistNavigator::currentIndex() const
+{
+ return d_func()->currentPos;
+}
+
+/*!
+ Returns a position \a steps ahead of the current position
+ accounting for the playbackMode().
+
+ If the position is beyond the end of the playlist, this value
+ returned is -1.
+
+ \sa currentIndex(), previousIndex(), playbackMode()
+*/
+
+int QMediaPlaylistNavigator::nextIndex(int steps) const
+{
+ return d_func()->nextItemPos(steps);
+}
+
+/*!
+
+ Returns a position \a steps behind the current position accounting
+ for the playbackMode().
+
+ If the position is prior to the beginning of the playlist this will
+ return -1.
+
+ \sa currentIndex(), nextIndex(), playbackMode()
+*/
+int QMediaPlaylistNavigator::previousIndex(int steps) const
+{
+ return d_func()->previousItemPos(steps);
+}
+
+/*!
+ Advances to the next item in the playlist.
+
+ \sa previous(), jump(), playbackMode()
+ */
+void QMediaPlaylistNavigator::next()
+{
+ Q_D(QMediaPlaylistNavigator);
+
+ int nextPos = d->nextItemPos();
+
+ if ( playbackMode() == QMediaPlaylist::Random )
+ d->randomPositionsOffset++;
+
+ jump(nextPos);
+}
+
+/*!
+ Returns to the previous item in the playlist,
+
+ \sa next(), jump(), playbackMode()
+ */
+void QMediaPlaylistNavigator::previous()
+{
+ Q_D(QMediaPlaylistNavigator);
+
+ int prevPos = d->previousItemPos();
+ if ( playbackMode() == QMediaPlaylist::Random )
+ d->randomPositionsOffset--;
+
+ jump(prevPos);
+}
+
+/*!
+ Jumps to a new \a position in the playlist.
+ */
+void QMediaPlaylistNavigator::jump(int position)
+{
+ Q_D(QMediaPlaylistNavigator);
+
+ if (position<-1 || position>=d->playlist->mediaCount()) {
+ qWarning() << "QMediaPlaylistNavigator: Jump outside playlist range";
+ position = -1;
+ }
+
+ if (position != -1)
+ d->lastValidPos = position;
+
+ if (playbackMode() == QMediaPlaylist::Random) {
+ if (d->randomModePositions[d->randomPositionsOffset] != position) {
+ d->randomModePositions.clear();
+ d->randomModePositions.append(position);
+ d->randomPositionsOffset = 0;
+ }
+ }
+
+ if (position != -1)
+ d->currentItem = d->playlist->media(position);
+ else
+ d->currentItem = QMediaContent();
+
+ if (position != d->currentPos) {
+ d->currentPos = position;
+ emit currentIndexChanged(d->currentPos);
+ emit surroundingItemsChanged();
+ }
+
+ emit activated(d->currentItem);
+}
+
+/*!
+ \internal
+*/
+void QMediaPlaylistNavigatorPrivate::_q_mediaInserted(int start, int end)
+{
+ Q_Q(QMediaPlaylistNavigator);
+
+ if (currentPos >= start) {
+ currentPos = end-start+1;
+ q->jump(currentPos);
+ }
+
+ //TODO: check if they really changed
+ emit q->surroundingItemsChanged();
+}
+
+/*!
+ \internal
+*/
+void QMediaPlaylistNavigatorPrivate::_q_mediaRemoved(int start, int end)
+{
+ Q_Q(QMediaPlaylistNavigator);
+
+ if (currentPos > end) {
+ currentPos = currentPos - end-start+1;
+ q->jump(currentPos);
+ } else if (currentPos >= start) {
+ //current item was removed
+ currentPos = qMin(start, playlist->mediaCount()-1);
+ q->jump(currentPos);
+ }
+
+ //TODO: check if they really changed
+ emit q->surroundingItemsChanged();
+}
+
+/*!
+ \internal
+*/
+void QMediaPlaylistNavigatorPrivate::_q_mediaChanged(int start, int end)
+{
+ Q_Q(QMediaPlaylistNavigator);
+
+ if (currentPos >= start && currentPos<=end) {
+ QMediaContent src = playlist->media(currentPos);
+ if (src != currentItem) {
+ currentItem = src;
+ emit q->activated(src);
+ }
+ }
+
+ //TODO: check if they really changed
+ emit q->surroundingItemsChanged();
+}
+
+/*!
+ \fn QMediaPlaylistNavigator::activated(const QMediaContent &media)
+
+ Signals that the current \a media has changed.
+*/
+
+/*!
+ \fn QMediaPlaylistNavigator::currentIndexChanged(int position)
+
+ Signals the \a position of the current media has changed.
+*/
+
+/*!
+ \fn QMediaPlaylistNavigator::playbackModeChanged(QMediaPlaylist::PlaybackMode mode)
+
+ Signals that the playback \a mode has changed.
+*/
+
+/*!
+ \fn QMediaPlaylistNavigator::surroundingItemsChanged()
+
+ Signals that media immediately surrounding the current position has changed.
+*/
+
+#include "moc_qmediaplaylistnavigator.cpp"
+
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/mediaservices/base/qmediaplaylistnavigator.h b/src/multimedia/mediaservices/base/qmediaplaylistnavigator.h
new file mode 100644
index 0000000..42c76f9
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qmediaplaylistnavigator.h
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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$
+**
+****************************************************************************/
+
+#ifndef QMEDIAPLAYLISTNAVIGATOR_H
+#define QMEDIAPLAYLISTNAVIGATOR_H
+
+#include <QtCore/qobject.h>
+
+#include <QtMediaServices/qmediaplaylistprovider.h>
+#include <QtMediaServices/qmediaplaylist.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QMediaPlaylistNavigatorPrivate;
+class Q_MEDIASERVICES_EXPORT QMediaPlaylistNavigator : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QMediaPlaylist::PlaybackMode playbackMode READ playbackMode WRITE setPlaybackMode NOTIFY playbackModeChanged)
+ Q_PROPERTY(int currentIndex READ currentIndex WRITE jump NOTIFY currentIndexChanged)
+ Q_PROPERTY(QMediaContent currentItem READ currentItem NOTIFY currentItemChanged)
+
+public:
+ QMediaPlaylistNavigator(QMediaPlaylistProvider *playlist, QObject *parent = 0);
+ virtual ~QMediaPlaylistNavigator();
+
+ QMediaPlaylistProvider *playlist() const;
+ void setPlaylist(QMediaPlaylistProvider *playlist);
+
+ QMediaPlaylist::PlaybackMode playbackMode() const;
+
+ QMediaContent currentItem() const;
+ QMediaContent nextItem(int steps = 1) const;
+ QMediaContent previousItem(int steps = 1) const;
+
+ QMediaContent itemAt(int position) const;
+
+ int currentIndex() const;
+ int nextIndex(int steps = 1) const;
+ int previousIndex(int steps = 1) const;
+
+public Q_SLOTS:
+ void next();
+ void previous();
+
+ void jump(int);
+
+ void setPlaybackMode(QMediaPlaylist::PlaybackMode mode);
+
+Q_SIGNALS:
+ void activated(const QMediaContent &content);
+ void currentIndexChanged(int);
+ void playbackModeChanged(QMediaPlaylist::PlaybackMode mode);
+
+ void surroundingItemsChanged();
+
+protected:
+ QMediaPlaylistNavigatorPrivate *d_ptr;
+
+private:
+ Q_DISABLE_COPY(QMediaPlaylistNavigator)
+ Q_DECLARE_PRIVATE(QMediaPlaylistNavigator)
+
+ Q_PRIVATE_SLOT(d_func(), void _q_mediaInserted(int start, int end))
+ Q_PRIVATE_SLOT(d_func(), void _q_mediaRemoved(int start, int end))
+ Q_PRIVATE_SLOT(d_func(), void _q_mediaChanged(int start, int end))
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QMEDIAPLAYLISTNAVIGATOR_H
diff --git a/src/multimedia/mediaservices/base/qmediaplaylistprovider.cpp b/src/multimedia/mediaservices/base/qmediaplaylistprovider.cpp
new file mode 100644
index 0000000..3cd766b
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qmediaplaylistprovider.cpp
@@ -0,0 +1,308 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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 <QtCore/qurl.h>
+
+#include <QtMediaServices/qmediaplaylistprovider.h>
+#include "qmediaplaylistprovider_p.h"
+
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QMediaPlaylistProvider
+ \preliminary
+ \since 4.7
+ \brief The QMediaPlaylistProvider class provides an abstract list of media.
+
+ \sa QMediaPlaylist
+*/
+
+/*!
+ Constructs a playlist provider with the given \a parent.
+*/
+QMediaPlaylistProvider::QMediaPlaylistProvider(QObject *parent)
+ :QObject(parent), d_ptr(new QMediaPlaylistProviderPrivate)
+{
+}
+
+/*!
+ \internal
+*/
+QMediaPlaylistProvider::QMediaPlaylistProvider(QMediaPlaylistProviderPrivate &dd, QObject *parent)
+ :QObject(parent), d_ptr(&dd)
+{
+}
+
+/*!
+ Destroys a playlist provider.
+*/
+QMediaPlaylistProvider::~QMediaPlaylistProvider()
+{
+ delete d_ptr;
+}
+
+/*!
+ \fn QMediaPlaylistProvider::mediaCount() const;
+
+ Returns the size of playlist.
+*/
+
+/*!
+ \fn QMediaPlaylistProvider::media(int index) const;
+
+ Returns the media at \a index in the playlist.
+
+ If the index is invalid this will return a null media content.
+*/
+
+
+/*!
+ Loads a playlist from from a URL \a location. If no playlist \a format is specified the loader
+ will inspect the URL or probe the headers to guess the format.
+
+ New items are appended to playlist.
+
+ Returns true if the provider supports the format and loading from the locations URL protocol,
+ otherwise this will return false.
+*/
+bool QMediaPlaylistProvider::load(const QUrl &location, const char *format)
+{
+ Q_UNUSED(location);
+ Q_UNUSED(format);
+ return false;
+}
+
+/*!
+ Loads a playlist from from an I/O \a device. If no playlist \a format is specified the loader
+ will probe the headers to guess the format.
+
+ New items are appended to playlist.
+
+ Returns true if the provider supports the format and loading from an I/O device, otherwise this
+ will return false.
+*/
+bool QMediaPlaylistProvider::load(QIODevice * device, const char *format)
+{
+ Q_UNUSED(device);
+ Q_UNUSED(format);
+ return false;
+}
+
+/*!
+ Saves the contents of a playlist to a URL \a location. If no playlist \a format is specified
+ the writer will inspect the URL to guess the format.
+
+ Returns true if the playlist was saved succesfully; and false otherwise.
+ */
+bool QMediaPlaylistProvider::save(const QUrl &location, const char *format)
+{
+ Q_UNUSED(location);
+ Q_UNUSED(format);
+ return false;
+}
+
+/*!
+ Saves the contents of a playlist to an I/O \a device in the specified \a format.
+
+ Returns true if the playlist was saved succesfully; and false otherwise.
+*/
+bool QMediaPlaylistProvider::save(QIODevice * device, const char *format)
+{
+ Q_UNUSED(device);
+ Q_UNUSED(format);
+ return false;
+}
+
+/*!
+ Returns true if a playlist is read-only; otherwise returns false.
+*/
+bool QMediaPlaylistProvider::isReadOnly() const
+{
+ return true;
+}
+
+/*!
+ Append \a media to a playlist.
+
+ Returns true if the media was appended; and false otherwise.
+*/
+bool QMediaPlaylistProvider::addMedia(const QMediaContent &media)
+{
+ Q_UNUSED(media);
+ return false;
+}
+
+/*!
+ Append multiple media \a items to a playlist.
+
+ Returns true if the media items were appended; and false otherwise.
+*/
+bool QMediaPlaylistProvider::addMedia(const QList<QMediaContent> &items)
+{
+ foreach(const QMediaContent &item, items) {
+ if (!addMedia(item))
+ return false;
+ }
+
+ return true;
+}
+
+/*!
+ Inserts \a media into a playlist at \a position.
+
+ Returns true if the media was inserted; and false otherwise.
+*/
+bool QMediaPlaylistProvider::insertMedia(int position, const QMediaContent &media)
+{
+ Q_UNUSED(position);
+ Q_UNUSED(media);
+ return false;
+}
+
+/*!
+ Inserts multiple media \a items into a playlist at \a position.
+
+ Returns true if the media \a items were inserted; and false otherwise.
+*/
+bool QMediaPlaylistProvider::insertMedia(int position, const QList<QMediaContent> &items)
+{
+ for (int i=0; i<items.count(); i++) {
+ if (!insertMedia(position+i,items.at(i)))
+ return false;
+ }
+
+ return true;
+}
+
+
+/*!
+ Removes the media at \a position from a playlist.
+
+ Returns true if the media was removed; and false otherwise.
+*/
+bool QMediaPlaylistProvider::removeMedia(int position)
+{
+ Q_UNUSED(position);
+ return false;
+}
+
+/*!
+ Removes the media between the given \a start and \a end positions from a playlist.
+
+ Returns true if the media was removed; and false otherwise.
+ */
+bool QMediaPlaylistProvider::removeMedia(int start, int end)
+{
+ for (int pos=start; pos<=end; pos++) {
+ if (!removeMedia(pos))
+ return false;
+ }
+
+ return true;
+}
+
+/*!
+ Removes all media from a playlist.
+
+ Returns true if the media was removed; and false otherwise.
+*/
+bool QMediaPlaylistProvider::clear()
+{
+ return removeMedia(0, mediaCount()-1);
+}
+
+/*!
+ Shuffles the contents of a playlist.
+*/
+void QMediaPlaylistProvider::shuffle()
+{
+}
+
+/*!
+ \fn void QMediaPlaylistProvider::mediaAboutToBeInserted(int start, int end);
+
+ Signals that new media is about to be inserted into a playlist between the \a start and \a end
+ positions.
+*/
+
+/*!
+ \fn void QMediaPlaylistProvider::mediaInserted(int start, int end);
+
+ Signals that new media has been inserted into a playlist between the \a start and \a end
+ positions.
+*/
+
+/*!
+ \fn void QMediaPlaylistProvider::mediaAboutToBeRemoved(int start, int end);
+
+ Signals that media is about to be removed from a playlist between the \a start and \a end
+ positions.
+*/
+
+/*!
+ \fn void QMediaPlaylistProvider::mediaRemoved(int start, int end);
+
+ Signals that media has been removed from a playlist between the \a start and \a end positions.
+*/
+
+/*!
+ \fn void QMediaPlaylistProvider::mediaChanged(int start, int end);
+
+ Signals that media in playlist between the \a start and \a end positions inclusive has changed.
+*/
+
+/*!
+ \fn void QMediaPlaylistProvider::loaded()
+
+ Signals that a load() finished successfully.
+*/
+
+/*!
+ \fn void QMediaPlaylistProvider::loadFailed(QMediaPlaylist::Error error, const QString& errorMessage)
+
+ Signals that a load failed() due to an \a error. The \a errorMessage provides more information.
+*/
+
+#include "moc_qmediaplaylistprovider.cpp"
+
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/mediaservices/base/qmediaplaylistprovider.h b/src/multimedia/mediaservices/base/qmediaplaylistprovider.h
new file mode 100644
index 0000000..c68ed89
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qmediaplaylistprovider.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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$
+**
+****************************************************************************/
+
+#ifndef QMEDIAPLAYLISTPROVIDER_H
+#define QMEDIAPLAYLISTPROVIDER_H
+
+#include <QtCore/qobject.h>
+
+#include <QtMediaServices/qmediacontent.h>
+#include <QtMediaServices/qmediaplaylist.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+class QString;
+
+
+class QMediaPlaylistProviderPrivate;
+class Q_MEDIASERVICES_EXPORT QMediaPlaylistProvider : public QObject
+{
+ Q_OBJECT
+
+public:
+ QMediaPlaylistProvider(QObject *parent=0);
+ virtual ~QMediaPlaylistProvider();
+
+ virtual bool load(const QUrl &location, const char *format = 0);
+ virtual bool load(QIODevice * device, const char *format = 0);
+ virtual bool save(const QUrl &location, const char *format = 0);
+ virtual bool save(QIODevice * device, const char *format);
+
+ virtual int mediaCount() const = 0;
+ virtual QMediaContent media(int index) const = 0;
+
+ virtual bool isReadOnly() const;
+
+ virtual bool addMedia(const QMediaContent &content);
+ virtual bool addMedia(const QList<QMediaContent> &contentList);
+ virtual bool insertMedia(int index, const QMediaContent &content);
+ virtual bool insertMedia(int index, const QList<QMediaContent> &content);
+ virtual bool removeMedia(int pos);
+ virtual bool removeMedia(int start, int end);
+ virtual bool clear();
+
+public Q_SLOTS:
+ virtual void shuffle();
+
+Q_SIGNALS:
+ void mediaAboutToBeInserted(int start, int end);
+ void mediaInserted(int start, int end);
+
+ void mediaAboutToBeRemoved(int start, int end);
+ void mediaRemoved(int start, int end);
+
+ void mediaChanged(int start, int end);
+
+ void loaded();
+ void loadFailed(QMediaPlaylist::Error, const QString& errorMessage);
+
+protected:
+ QMediaPlaylistProviderPrivate *d_ptr;
+ QMediaPlaylistProvider(QMediaPlaylistProviderPrivate &dd, QObject *parent);
+
+private:
+ Q_DECLARE_PRIVATE(QMediaPlaylistProvider)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QMEDIAPLAYLISTPROVIDER_H
diff --git a/src/multimedia/mediaservices/base/qmediaplaylistprovider_p.h b/src/multimedia/mediaservices/base/qmediaplaylistprovider_p.h
new file mode 100644
index 0000000..00d1cca
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qmediaplaylistprovider_p.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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$
+**
+****************************************************************************/
+
+#ifndef QMEDIAPLAYLISTPROVIDER_P_H
+#define QMEDIAPLAYLISTPROVIDER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtMediaServices/qmediaplaylist.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QMediaPlaylistProviderPrivate
+{
+public:
+ QMediaPlaylistProviderPrivate()
+ {}
+ virtual ~QMediaPlaylistProviderPrivate()
+ {}
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QMEDIAPLAYLISTSOURCE_P_H
diff --git a/src/multimedia/mediaservices/base/qmediapluginloader.cpp b/src/multimedia/mediaservices/base/qmediapluginloader.cpp
new file mode 100644
index 0000000..d6da0ba
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qmediapluginloader.cpp
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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 "qmediapluginloader_p.h"
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qpluginloader.h>
+#include <QtCore/qdir.h>
+#include <QtCore/qdebug.h>
+
+#include <QtMediaServices/qmediaserviceproviderplugin.h>
+
+
+QT_BEGIN_NAMESPACE
+
+
+typedef QMap<QString,QObjectList> ObjectListMap;
+Q_GLOBAL_STATIC(ObjectListMap, staticMediaPlugins);
+
+QMediaPluginLoader::QMediaPluginLoader(const char *iid, const QString &location, Qt::CaseSensitivity):
+ m_iid(iid)
+{
+ m_location = location + QLatin1String("/");
+ load();
+}
+
+QStringList QMediaPluginLoader::keys() const
+{
+ return m_instances.keys();
+}
+
+QObject* QMediaPluginLoader::instance(QString const &key)
+{
+ return m_instances.value(key);
+}
+
+QList<QObject*> QMediaPluginLoader::instances(QString const &key)
+{
+ return m_instances.values(key);
+}
+
+//to be used for testing purposes only
+void QMediaPluginLoader::setStaticPlugins(const QString &location, const QObjectList& objects)
+{
+ staticMediaPlugins()->insert(location + QLatin1String("/"), objects);
+}
+
+void QMediaPluginLoader::load()
+{
+ if (!m_instances.isEmpty())
+ return;
+
+ if (staticMediaPlugins() && staticMediaPlugins()->contains(m_location)) {
+ foreach(QObject *o, staticMediaPlugins()->value(m_location)) {
+ if (o != 0 && o->qt_metacast(m_iid) != 0) {
+ QFactoryInterface* p = qobject_cast<QFactoryInterface*>(o);
+ if (p != 0) {
+ foreach (QString const &key, p->keys())
+ m_instances.insertMulti(key, o);
+ }
+ }
+ }
+ } else {
+#ifndef QT_NO_LIBRARY
+ QStringList paths = QCoreApplication::libraryPaths();
+
+ foreach (QString const &path, paths) {
+ QString pluginPathName(path + m_location);
+ QDir pluginDir(pluginPathName);
+
+ if (!pluginDir.exists())
+ continue;
+
+ foreach (QString pluginLib, pluginDir.entryList(QDir::Files)) {
+ QPluginLoader loader(pluginPathName + pluginLib);
+
+ QObject *o = loader.instance();
+ if (o != 0 && o->qt_metacast(m_iid) != 0) {
+ QFactoryInterface* p = qobject_cast<QFactoryInterface*>(o);
+ if (p != 0) {
+ foreach (QString const &key, p->keys())
+ m_instances.insertMulti(key, o);
+ }
+
+ continue;
+ } else {
+ qWarning() << "QMediaPluginLoader: Failed to load plugin: " << pluginLib << loader.errorString();
+ }
+ delete o;
+ loader.unload();
+ }
+ }
+#endif
+ }
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/mediaservices/base/qmediapluginloader_p.h b/src/multimedia/mediaservices/base/qmediapluginloader_p.h
new file mode 100644
index 0000000..d911180
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qmediapluginloader_p.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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$
+**
+****************************************************************************/
+
+#ifndef QMEDIAPLUGINLOADER_H
+#define QMEDIAPLUGINLOADER_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qobject.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qmap.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QMediaServiceProviderPlugin;
+
+class Q_AUTOTEST_EXPORT QMediaPluginLoader
+{
+public:
+ QMediaPluginLoader(const char *iid,
+ const QString &suffix = QString(),
+ Qt::CaseSensitivity = Qt::CaseSensitive);
+
+ QStringList keys() const;
+ QObject* instance(QString const &key);
+ QList<QObject*> instances(QString const &key);
+
+ static void setStaticPlugins(const QString &location, const QObjectList& objects);
+
+private:
+ void load();
+
+ QByteArray m_iid;
+ QString m_location;
+ QMap<QString, QObject*> m_instances;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QMEDIAPLUGINLOADER_H
diff --git a/src/multimedia/mediaservices/base/qmediaresource.cpp b/src/multimedia/mediaservices/base/qmediaresource.cpp
new file mode 100644
index 0000000..33bd396
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qmediaresource.cpp
@@ -0,0 +1,399 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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 <QtCore/qsize.h>
+#include <QtCore/qurl.h>
+#include <QtCore/qvariant.h>
+
+#include <QtMediaServices/qmediaresource.h>
+
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QMediaResource
+ \preliminary
+ \since 4.7
+ \brief The QMediaResource class provides a description of a media resource.
+ \ingroup multimedia
+
+ A media resource is composed of a \l {url()}{URL} containing the
+ location of the resource and a set of properties that describe the
+ format of the resource. The properties provide a means to assess a
+ resource without first attempting to load it, and in situations where
+ media be represented by multiple alternative representations provide a
+ means to select the appropriate resource.
+
+ Media made available by a remote services can often be available in
+ multiple encodings or quality levels, this allows a client to select
+ an appropriate resource based on considerations such as codecs supported,
+ network bandwidth, and display constraints. QMediaResource includes
+ information such as the \l {mimeType()}{MIME type}, \l {audioCodec()}{audio}
+ and \l {videoCodec()}{video} codecs, \l {audioBitRate()}{audio} and
+ \l {videoBitRate()}{video} bit rates, and \l {resolution()}{resolution}
+ so these constraints and others can be evaluated.
+
+ The only mandatory property of a QMediaResource is the url().
+
+ \sa QMediaContent
+*/
+
+/*!
+ \typedef QMediaResourceList
+
+ Synonym for \c QList<QMediaResource>
+*/
+
+/*!
+ Constructs a null media resource.
+*/
+QMediaResource::QMediaResource()
+{
+}
+
+/*!
+ Constructs a media resource with the given \a mimeType from a \a url.
+*/
+QMediaResource::QMediaResource(const QUrl &url, const QString &mimeType)
+{
+ values.insert(Url, url);
+ values.insert(MimeType, mimeType);
+}
+
+/*!
+ Constructs a media resource with the given \a mimeType from a network \a request.
+*/
+QMediaResource::QMediaResource(const QNetworkRequest &request, const QString &mimeType)
+{
+ values.insert(Request, QVariant::fromValue(request));
+ values.insert(Url, request.url());
+ values.insert(MimeType, mimeType);
+}
+
+/*!
+ Constructs a copy of a media resource \a other.
+*/
+QMediaResource::QMediaResource(const QMediaResource &other)
+ : values(other.values)
+{
+}
+
+/*!
+ Assigns the value of \a other to a media resource.
+*/
+QMediaResource &QMediaResource::operator =(const QMediaResource &other)
+{
+ values = other.values;
+
+ return *this;
+}
+
+/*!
+ Destroys a media resource.
+*/
+QMediaResource::~QMediaResource()
+{
+}
+
+
+/*!
+ Compares a media resource to \a other.
+
+ Returns true if the resources are identical, and false otherwise.
+*/
+bool QMediaResource::operator ==(const QMediaResource &other) const
+{
+ return values == other.values;
+}
+
+/*!
+ Compares a media resource to \a other.
+
+ Returns true if they are different, and false otherwise.
+*/
+bool QMediaResource::operator !=(const QMediaResource &other) const
+{
+ return values != other.values;
+}
+
+/*!
+ Identifies if a media resource is null.
+
+ Returns true if the resource is null, and false otherwise.
+*/
+bool QMediaResource::isNull() const
+{
+ return values.isEmpty();
+}
+
+/*!
+ Returns the URL of a media resource.
+*/
+QUrl QMediaResource::url() const
+{
+ return qvariant_cast<QUrl>(values.value(Url));
+}
+
+/*!
+ Returns the network request associated with this media resource.
+*/
+QNetworkRequest QMediaResource::request() const
+{
+ if(values.contains(Request))
+ return qvariant_cast<QNetworkRequest>(values.value(Request));
+
+ return QNetworkRequest(url());
+}
+
+/*!
+ Returns the MIME type of a media resource.
+
+ This may be null if the MIME type is unknown.
+*/
+QString QMediaResource::mimeType() const
+{
+ return qvariant_cast<QString>(values.value(MimeType));
+}
+
+/*!
+ Returns the language of a media resource as an ISO 639-2 code.
+
+ This may be null if the language is unknown.
+*/
+QString QMediaResource::language() const
+{
+ return qvariant_cast<QString>(values.value(Language));
+}
+
+/*!
+ Sets the \a language of a media resource.
+*/
+void QMediaResource::setLanguage(const QString &language)
+{
+ if (!language.isNull())
+ values.insert(Language, language);
+ else
+ values.remove(Language);
+}
+
+/*!
+ Returns the audio codec of a media resource.
+
+ This may be null if the media resource does not contain an audio stream, or the codec is
+ unknown.
+*/
+QString QMediaResource::audioCodec() const
+{
+ return qvariant_cast<QString>(values.value(AudioCodec));
+}
+
+/*!
+ Sets the audio \a codec of a media resource.
+*/
+void QMediaResource::setAudioCodec(const QString &codec)
+{
+ if (!codec.isNull())
+ values.insert(AudioCodec, codec);
+ else
+ values.remove(AudioCodec);
+}
+
+/*!
+ Returns the video codec of a media resource.
+
+ This may be null if the media resource does not contain a video stream, or the codec is
+ unknonwn.
+*/
+QString QMediaResource::videoCodec() const
+{
+ return qvariant_cast<QString>(values.value(VideoCodec));
+}
+
+/*!
+ Sets the video \a codec of media resource.
+*/
+void QMediaResource::setVideoCodec(const QString &codec)
+{
+ if (!codec.isNull())
+ values.insert(VideoCodec, codec);
+ else
+ values.remove(VideoCodec);
+}
+
+/*!
+ Returns the size in bytes of a media resource.
+
+ This may be zero if the size is unknown.
+*/
+qint64 QMediaResource::dataSize() const
+{
+ return qvariant_cast<qint64>(values.value(DataSize));
+}
+
+/*!
+ Sets the \a size in bytes of a media resource.
+*/
+void QMediaResource::setDataSize(const qint64 size)
+{
+ if (size != 0)
+ values.insert(DataSize, size);
+ else
+ values.remove(DataSize);
+}
+
+/*!
+ Returns the bit rate in bits per second of a media resource's audio stream.
+
+ This may be zero if the bit rate is unknown, or the resource contains no audio stream.
+*/
+int QMediaResource::audioBitRate() const
+{
+ return values.value(AudioBitRate).toInt();
+}
+
+/*!
+ Sets the bit \a rate in bits per second of a media resource's video stream.
+*/
+void QMediaResource::setAudioBitRate(int rate)
+{
+ if (rate != 0)
+ values.insert(AudioBitRate, rate);
+ else
+ values.remove(AudioBitRate);
+}
+
+/*!
+ Returns the audio sample rate of a media resource.
+
+ This may be zero if the sample size is unknown, or the resource contains no audio stream.
+*/
+int QMediaResource::sampleRate() const
+{
+ return qvariant_cast<int>(values.value(SampleRate));
+}
+
+/*!
+ Sets the audio \a sampleRate of a media resource.
+*/
+void QMediaResource::setSampleRate(int sampleRate)
+{
+ if (sampleRate != 0)
+ values.insert(SampleRate, sampleRate);
+ else
+ values.remove(SampleRate);
+}
+
+/*!
+ Returns the number of audio channels in a media resource.
+
+ This may be zero if the sample size is unknown, or the resource contains no audio stream.
+*/
+int QMediaResource::channelCount() const
+{
+ return qvariant_cast<int>(values.value(ChannelCount));
+}
+
+/*!
+ Sets the number of audio \a channels in a media resource.
+*/
+void QMediaResource::setChannelCount(int channels)
+{
+ if (channels != 0)
+ values.insert(ChannelCount, channels);
+ else
+ values.remove(ChannelCount);
+}
+
+/*!
+ Returns the bit rate in bits per second of a media resource's video stream.
+
+ This may be zero if the bit rate is unknown, or the resource contains no video stream.
+*/
+int QMediaResource::videoBitRate() const
+{
+ return values.value(VideoBitRate).toInt();
+}
+
+/*!
+ Sets the bit \a rate in bits per second of a media resource's video stream.
+*/
+void QMediaResource::setVideoBitRate(int rate)
+{
+ if (rate != 0)
+ values.insert(VideoBitRate, rate);
+ else
+ values.remove(VideoBitRate);
+}
+
+/*!
+ Returns the resolution in pixels of a media resource.
+
+ This may be null is the resolution is unknown, or the resource contains no pixel data (i.e. the
+ resource is an audio stream.
+*/
+QSize QMediaResource::resolution() const
+{
+ return qvariant_cast<QSize>(values.value(Resolution));
+}
+
+/*!
+ Sets the \a resolution in pixels of a media resource.
+*/
+void QMediaResource::setResolution(const QSize &resolution)
+{
+ if (resolution.width() != -1 || resolution.height() != -1)
+ values.insert(Resolution, resolution);
+ else
+ values.remove(Resolution);
+}
+
+/*!
+ Sets the \a width and \a height in pixels of a media resource.
+*/
+void QMediaResource::setResolution(int width, int height)
+{
+ if (width != -1 || height != -1)
+ values.insert(Resolution, QSize(width, height));
+ else
+ values.remove(Resolution);
+}
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/mediaservices/base/qmediaresource.h b/src/multimedia/mediaservices/base/qmediaresource.h
new file mode 100644
index 0000000..0ecf008
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qmediaresource.h
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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$
+**
+****************************************************************************/
+
+#ifndef QMEDIARESOURCE_H
+#define QMEDIARESOURCE_H
+
+#include <QtCore/qmap.h>
+#include <QtCore/qmetatype.h>
+#include <QtNetwork/qnetworkrequest.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class Q_MEDIASERVICES_EXPORT QMediaResource
+{
+public:
+ QMediaResource();
+ QMediaResource(const QUrl &url, const QString &mimeType = QString());
+ QMediaResource(const QNetworkRequest &request, const QString &mimeType = QString());
+ QMediaResource(const QMediaResource &other);
+ QMediaResource &operator =(const QMediaResource &other);
+ ~QMediaResource();
+
+ bool isNull() const;
+
+ bool operator ==(const QMediaResource &other) const;
+ bool operator !=(const QMediaResource &other) const;
+
+ QUrl url() const;
+ QNetworkRequest request() const;
+ QString mimeType() const;
+
+ QString language() const;
+ void setLanguage(const QString &language);
+
+ QString audioCodec() const;
+ void setAudioCodec(const QString &codec);
+
+ QString videoCodec() const;
+ void setVideoCodec(const QString &codec);
+
+ qint64 dataSize() const;
+ void setDataSize(const qint64 size);
+
+ int audioBitRate() const;
+ void setAudioBitRate(int rate);
+
+ int sampleRate() const;
+ void setSampleRate(int frequency);
+
+ int channelCount() const;
+ void setChannelCount(int channels);
+
+ int videoBitRate() const;
+ void setVideoBitRate(int rate);
+
+ QSize resolution() const;
+ void setResolution(const QSize &resolution);
+ void setResolution(int width, int height);
+
+
+private:
+ enum Property
+ {
+ Url,
+ Request,
+ MimeType,
+ Language,
+ AudioCodec,
+ VideoCodec,
+ DataSize,
+ AudioBitRate,
+ VideoBitRate,
+ SampleRate,
+ ChannelCount,
+ Resolution
+ };
+ QMap<int, QVariant> values;
+};
+
+typedef QList<QMediaResource> QMediaResourceList;
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QMediaResource)
+Q_DECLARE_METATYPE(QMediaResourceList)
+
+QT_END_HEADER
+
+
+#endif
diff --git a/src/multimedia/mediaservices/base/qmediaservice.cpp b/src/multimedia/mediaservices/base/qmediaservice.cpp
new file mode 100644
index 0000000..b343887
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qmediaservice.cpp
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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 <QtCore/qtimer.h>
+
+#include <QtMediaServices/qmediaservice.h>
+#include "qmediaservice_p.h"
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+/*!
+ \class QMediaService
+ \brief The QMediaService class provides a common base class for media
+ service implementations.
+ \ingroup multimedia-serv
+ \preliminary
+ \since 4.7
+
+ Media services provide implementations of the functionality promised
+ by media objects, and allow multiple providers to implement a QMediaObject.
+
+ To provide the functionality of a QMediaObject media services implement
+ QMediaControl interfaces. Services typically implement one core media
+ control which provides the core feature of a media object, and some
+ number of additional controls which provide either optional features of
+ the media object, or features of a secondary media object or peripheral
+ object.
+
+ A pointer to media service's QMediaControl implementation can be
+ obtained by passing the control's interface name to the control() function.
+
+ \code
+ QMediaPlayerControl *control = qobject_cast<QMediaPlayerControl *>(
+ service->control("com.nokia.Qt.QMediaPlayerControl/1.0"));
+ \endcode
+
+ Media objects can use services loaded dynamically from plug-ins or
+ implemented statically within an applications. Plug-in based services
+ should also implement the QMediaServiceProviderPlugin interface. Static
+ services should implement the QMediaServiceProvider interface.
+
+ \sa QMediaObject, QMediaControl, QMediaServiceProvider, QMediaServiceProviderPlugin
+*/
+
+/*!
+ Construct a media service with the given \a parent. This class is meant as a
+ base class for Multimedia services so this constructor is protected.
+*/
+
+QMediaService::QMediaService(QObject *parent)
+ : QObject(parent)
+ , d_ptr(new QMediaServicePrivate)
+{
+ d_ptr->q_ptr = this;
+}
+
+/*!
+ \internal
+*/
+QMediaService::QMediaService(QMediaServicePrivate &dd, QObject *parent)
+ : QObject(parent)
+ , d_ptr(&dd)
+{
+ d_ptr->q_ptr = this;
+}
+
+/*!
+ Destroys a media service.
+*/
+
+QMediaService::~QMediaService()
+{
+ delete d_ptr;
+}
+
+/*!
+ \fn QMediaService::control(const char *interface) const
+
+ Returns a pointer to the media control implementing \a interface.
+
+ If the service does not implement the control a null pointer is returned instead.
+*/
+
+/*!
+ \fn QMediaService::control() const
+
+ Returns a pointer to the media control of type T implemented by a media service.
+
+ If the service does not implment the control a null pointer is returned instead.
+*/
+
+#include "moc_qmediaservice.cpp"
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
diff --git a/src/multimedia/mediaservices/base/qmediaservice.h b/src/multimedia/mediaservices/base/qmediaservice.h
new file mode 100644
index 0000000..5df3fd7
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qmediaservice.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTMEDIASERVICE_H
+#define QABSTRACTMEDIASERVICE_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qstringlist.h>
+
+#include <QtMediaServices/qmediacontrol.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+class QMediaServicePrivate;
+class Q_MEDIASERVICES_EXPORT QMediaService : public QObject
+{
+ Q_OBJECT
+
+public:
+ ~QMediaService();
+
+ virtual QMediaControl* control(const char *name) const = 0;
+
+#ifndef QT_NO_MEMBER_TEMPLATES
+ template <typename T> inline T control() const {
+ if (QObject *object = control(qmediacontrol_iid<T>())) {
+ return qobject_cast<T>(object);
+ }
+ return 0;
+ }
+#endif
+
+protected:
+ QMediaService(QObject* parent);
+ QMediaService(QMediaServicePrivate &dd, QObject *parent);
+
+ QMediaServicePrivate *d_ptr;
+
+private:
+ Q_DECLARE_PRIVATE(QMediaService)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QABSTRACTMEDIASERVICE_H
+
diff --git a/src/multimedia/mediaservices/base/qmediaservice_p.h b/src/multimedia/mediaservices/base/qmediaservice_p.h
new file mode 100644
index 0000000..bebae11
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qmediaservice_p.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTMEDIASERVICE_P_H
+#define QABSTRACTMEDIASERVICE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QAudioDeviceControl;
+
+class QMediaServicePrivate
+{
+public:
+ QMediaServicePrivate(): q_ptr(0) {}
+ virtual ~QMediaServicePrivate() {}
+
+ QMediaService *q_ptr;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/multimedia/mediaservices/base/qmediaserviceprovider.cpp b/src/multimedia/mediaservices/base/qmediaserviceprovider.cpp
new file mode 100644
index 0000000..f27628b
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qmediaserviceprovider.cpp
@@ -0,0 +1,738 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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 <QtCore/qdebug.h>
+#include <QtCore/qmap.h>
+
+#include <QtMediaServices/qmediaservice.h>
+#include <QtMediaServices/qmediaserviceprovider.h>
+#include <QtMediaServices/qmediaserviceproviderplugin.h>
+#include "qmediapluginloader_p.h"
+#include <QtMediaServices/qmediaplayer.h>
+
+QT_BEGIN_NAMESPACE
+
+class QMediaServiceProviderHintPrivate : public QSharedData
+{
+public:
+ QMediaServiceProviderHintPrivate(QMediaServiceProviderHint::Type type)
+ :type(type), features(0)
+ {
+ }
+
+ QMediaServiceProviderHintPrivate(const QMediaServiceProviderHintPrivate &other)
+ :QSharedData(other),
+ type(other.type),
+ device(other.device),
+ mimeType(other.mimeType),
+ codecs(other.codecs),
+ features(other.features)
+ {
+ }
+
+ ~QMediaServiceProviderHintPrivate()
+ {
+ }
+
+ QMediaServiceProviderHint::Type type;
+ QByteArray device;
+ QString mimeType;
+ QStringList codecs;
+ QMediaServiceProviderHint::Features features;
+};
+
+/*!
+ \class QMediaServiceProviderHint
+ \preliminary
+ \since 4.7
+ \brief The QMediaServiceProviderHint class describes what is required of a QMediaService.
+
+ \ingroup multimedia-serv
+
+ The QMediaServiceProvider class uses hints to select an appropriate media service.
+*/
+
+/*!
+ \enum QMediaServiceProviderHint::Feature
+
+ Enumerates features a media service may provide.
+
+ \value LowLatencyPlayback
+ The service is expected to play simple audio formats,
+ but playback should start without significant delay.
+ Such playback service can be used for beeps, ringtones, etc.
+
+ \value RecordingSupport
+ The service provides audio or video recording functions.
+
+ \value StreamPlayback
+ The service is capable of playing QIODevice based streams.
+*/
+
+/*!
+ \enum QMediaServiceProviderHint::Type
+
+ Enumerates the possible types of media service provider hint.
+
+ \value Null En empty hint, use the default service.
+ \value ContentType Select media service most suitable for certain content type.
+ \value Device Select media service which supports certain device.
+ \value SupportedFeatures Select media service supporting the set of optional features.
+*/
+
+
+/*!
+ Constructs an empty media service provider hint.
+*/
+QMediaServiceProviderHint::QMediaServiceProviderHint()
+ :d(new QMediaServiceProviderHintPrivate(Null))
+{
+}
+
+/*!
+ Constructs a ContentType media service provider hint.
+
+ This type of hint describes a service that is able to play content of a specific MIME \a type
+ encoded with one or more of the listed \a codecs.
+*/
+QMediaServiceProviderHint::QMediaServiceProviderHint(const QString &type, const QStringList& codecs)
+ :d(new QMediaServiceProviderHintPrivate(ContentType))
+{
+ d->mimeType = type;
+ d->codecs = codecs;
+}
+
+/*!
+ Constructs a Device media service provider hint.
+
+ This type of hint describes a media service that utilizes a specific \a device.
+*/
+QMediaServiceProviderHint::QMediaServiceProviderHint(const QByteArray &device)
+ :d(new QMediaServiceProviderHintPrivate(Device))
+{
+ d->device = device;
+}
+
+/*!
+ Constructs a SupportedFeatures media service provider hint.
+
+ This type of hint describes a service which supports a specific set of \a features.
+*/
+QMediaServiceProviderHint::QMediaServiceProviderHint(QMediaServiceProviderHint::Features features)
+ :d(new QMediaServiceProviderHintPrivate(SupportedFeatures))
+{
+ d->features = features;
+}
+
+/*!
+ Constructs a copy of the media service provider hint \a other.
+*/
+QMediaServiceProviderHint::QMediaServiceProviderHint(const QMediaServiceProviderHint &other)
+ :d(other.d)
+{
+}
+
+/*!
+ Destroys a media service provider hint.
+*/
+QMediaServiceProviderHint::~QMediaServiceProviderHint()
+{
+}
+
+/*!
+ Assigns the value \a other to a media service provider hint.
+*/
+QMediaServiceProviderHint& QMediaServiceProviderHint::operator=(const QMediaServiceProviderHint &other)
+{
+ d = other.d;
+ return *this;
+}
+
+/*!
+ Identifies if \a other is of equal value to a media service provider hint.
+
+ Returns true if the hints are equal, and false if they are not.
+*/
+bool QMediaServiceProviderHint::operator == (const QMediaServiceProviderHint &other) const
+{
+ return (d == other.d) ||
+ (d->type == other.d->type &&
+ d->device == other.d->device &&
+ d->mimeType == other.d->mimeType &&
+ d->codecs == other.d->codecs &&
+ d->features == other.d->features);
+}
+
+/*!
+ Identifies if \a other is not of equal value to a media service provider hint.
+
+ Returns true if the hints are not equal, and false if they are.
+*/
+bool QMediaServiceProviderHint::operator != (const QMediaServiceProviderHint &other) const
+{
+ return !(*this == other);
+}
+
+/*!
+ Returns true if a media service provider is null.
+*/
+bool QMediaServiceProviderHint::isNull() const
+{
+ return d->type == Null;
+}
+
+/*!
+ Returns the type of a media service provider hint.
+*/
+QMediaServiceProviderHint::Type QMediaServiceProviderHint::type() const
+{
+ return d->type;
+}
+
+/*!
+ Returns the mime type of the media a service is expected to be able play.
+*/
+QString QMediaServiceProviderHint::mimeType() const
+{
+ return d->mimeType;
+}
+
+/*!
+ Returns a list of codes a media service is expected to be able to decode.
+*/
+QStringList QMediaServiceProviderHint::codecs() const
+{
+ return d->codecs;
+}
+
+/*!
+ Returns the name of a device a media service is expected to utilize.
+*/
+QByteArray QMediaServiceProviderHint::device() const
+{
+ return d->device;
+}
+
+/*!
+ Returns a set of features a media service is expected to provide.
+*/
+QMediaServiceProviderHint::Features QMediaServiceProviderHint::features() const
+{
+ return d->features;
+}
+
+
+Q_GLOBAL_STATIC_WITH_ARGS(QMediaPluginLoader, loader,
+ (QMediaServiceProviderFactoryInterface_iid, QLatin1String("/mediaservices"), Qt::CaseInsensitive))
+
+
+class QPluginServiceProvider : public QMediaServiceProvider
+{
+ QMap<QMediaService*, QMediaServiceProviderPlugin*> pluginMap;
+
+public:
+ QMediaService* requestService(const QByteArray &type, const QMediaServiceProviderHint &hint)
+ {
+ QString key(QString::fromLatin1(type.constData(),type.length()));
+
+ QList<QMediaServiceProviderPlugin *>plugins;
+ foreach (QObject *obj, loader()->instances(key)) {
+ QMediaServiceProviderPlugin *plugin =
+ qobject_cast<QMediaServiceProviderPlugin*>(obj);
+ if (plugin)
+ plugins << plugin;
+ }
+
+ if (!plugins.isEmpty()) {
+ QMediaServiceProviderPlugin *plugin = 0;
+
+ switch (hint.type()) {
+ case QMediaServiceProviderHint::Null:
+ plugin = plugins[0];
+ //special case for media player, if low latency was not asked,
+ //prefer services not offering it, since they are likely to support
+ //more formats
+ if (type == QByteArray(Q_MEDIASERVICE_MEDIAPLAYER)) {
+ foreach (QMediaServiceProviderPlugin *currentPlugin, plugins) {
+ QMediaServiceFeaturesInterface *iface =
+ qobject_cast<QMediaServiceFeaturesInterface*>(currentPlugin);
+
+ if (!iface || !(iface->supportedFeatures(type) &
+ QMediaServiceProviderHint::LowLatencyPlayback)) {
+ plugin = currentPlugin;
+ break;
+ }
+
+ }
+ }
+ break;
+ case QMediaServiceProviderHint::SupportedFeatures:
+ plugin = plugins[0];
+ foreach (QMediaServiceProviderPlugin *currentPlugin, plugins) {
+ QMediaServiceFeaturesInterface *iface =
+ qobject_cast<QMediaServiceFeaturesInterface*>(currentPlugin);
+
+ if (iface) {
+ if ((iface->supportedFeatures(type) & hint.features()) == hint.features()) {
+ plugin = currentPlugin;
+ break;
+ }
+ }
+ }
+ break;
+ case QMediaServiceProviderHint::Device: {
+ foreach (QMediaServiceProviderPlugin *currentPlugin, plugins) {
+ QMediaServiceSupportedDevicesInterface *iface =
+ qobject_cast<QMediaServiceSupportedDevicesInterface*>(currentPlugin);
+
+ if (!iface) {
+ // the plugin may support the device,
+ // but this choice still can be overridden
+ plugin = currentPlugin;
+ } else {
+ if (iface->devices(type).contains(hint.device())) {
+ plugin = currentPlugin;
+ break;
+ }
+ }
+ }
+ }
+ break;
+ case QMediaServiceProviderHint::ContentType: {
+ QtMediaServices::SupportEstimate estimate = QtMediaServices::NotSupported;
+ foreach (QMediaServiceProviderPlugin *currentPlugin, plugins) {
+ QtMediaServices::SupportEstimate currentEstimate = QtMediaServices::MaybeSupported;
+ QMediaServiceSupportedFormatsInterface *iface =
+ qobject_cast<QMediaServiceSupportedFormatsInterface*>(currentPlugin);
+
+ if (iface)
+ currentEstimate = iface->hasSupport(hint.mimeType(), hint.codecs());
+
+ if (currentEstimate > estimate) {
+ estimate = currentEstimate;
+ plugin = currentPlugin;
+
+ if (currentEstimate == QtMediaServices::PreferredService)
+ break;
+ }
+ }
+ }
+ break;
+ }
+
+ if (plugin != 0) {
+ QMediaService *service = plugin->create(key);
+ if (service != 0)
+ pluginMap.insert(service, plugin);
+
+ return service;
+ }
+ }
+
+ qWarning() << "defaultServiceProvider::requestService(): no service found for -" << key;
+ return 0;
+ }
+
+ void releaseService(QMediaService *service)
+ {
+ if (service != 0) {
+ QMediaServiceProviderPlugin *plugin = pluginMap.take(service);
+
+ if (plugin != 0)
+ plugin->release(service);
+ }
+ }
+
+ QtMediaServices::SupportEstimate hasSupport(const QByteArray &serviceType,
+ const QString &mimeType,
+ const QStringList& codecs,
+ int flags) const
+ {
+ QList<QObject*> instances = loader()->instances(
+ QString::fromLatin1(serviceType.constData(),serviceType.length()));
+
+ if (instances.isEmpty())
+ return QtMediaServices::NotSupported;
+
+ bool allServicesProvideInterface = true;
+ QtMediaServices::SupportEstimate supportEstimate = QtMediaServices::NotSupported;
+
+ foreach(QObject *obj, instances) {
+ QMediaServiceSupportedFormatsInterface *iface =
+ qobject_cast<QMediaServiceSupportedFormatsInterface*>(obj);
+
+
+ if (flags) {
+ QMediaServiceFeaturesInterface *iface =
+ qobject_cast<QMediaServiceFeaturesInterface*>(obj);
+
+ if (iface) {
+ QMediaServiceProviderHint::Features features = iface->supportedFeatures(serviceType);
+
+ //if low latency playback was asked, skip services known
+ //not to provide low latency playback
+ if ((flags & QMediaPlayer::LowLatency) &&
+ !(features & QMediaServiceProviderHint::LowLatencyPlayback))
+ continue;
+
+ //the same for QIODevice based streams support
+ if ((flags & QMediaPlayer::StreamPlayback) &&
+ !(features & QMediaServiceProviderHint::StreamPlayback))
+ continue;
+ }
+ }
+
+ if (iface)
+ supportEstimate = qMax(supportEstimate, iface->hasSupport(mimeType, codecs));
+ else
+ allServicesProvideInterface = false;
+ }
+
+ //don't return PreferredService
+ supportEstimate = qMin(supportEstimate, QtMediaServices::ProbablySupported);
+
+ //Return NotSupported only if no services are available of serviceType
+ //or all the services returned NotSupported, otherwise return at least MaybeSupported
+ if (!allServicesProvideInterface)
+ supportEstimate = qMax(QtMediaServices::MaybeSupported, supportEstimate);
+
+ return supportEstimate;
+ }
+
+ QStringList supportedMimeTypes(const QByteArray &serviceType, int flags) const
+ {
+ QList<QObject*> instances = loader()->instances(
+ QString::fromLatin1(serviceType.constData(),serviceType.length()));
+
+ QStringList supportedTypes;
+
+ foreach(QObject *obj, instances) {
+ QMediaServiceSupportedFormatsInterface *iface =
+ qobject_cast<QMediaServiceSupportedFormatsInterface*>(obj);
+
+
+ if (flags & QMediaPlayer::LowLatency) {
+ QMediaServiceFeaturesInterface *iface =
+ qobject_cast<QMediaServiceFeaturesInterface*>(obj);
+
+ if (iface) {
+ QMediaServiceProviderHint::Features features = iface->supportedFeatures(serviceType);
+
+ // If low latency playback was asked for, skip MIME types from services known
+ // not to provide low latency playback
+ if ((flags & QMediaPlayer::LowLatency) &&
+ !(features & QMediaServiceProviderHint::LowLatencyPlayback))
+ continue;
+
+ //the same for QIODevice based streams support
+ if ((flags & QMediaPlayer::StreamPlayback) &&
+ !(features & QMediaServiceProviderHint::StreamPlayback))
+ continue;
+ }
+ }
+
+ if (iface) {
+ supportedTypes << iface->supportedMimeTypes();
+ }
+ }
+
+ // Multiple services may support the same MIME type
+ supportedTypes.removeDuplicates();
+
+ return supportedTypes;
+ }
+
+ QList<QByteArray> devices(const QByteArray &serviceType) const
+ {
+ QList<QByteArray> res;
+
+ foreach(QObject *obj, loader()->instances(
+ QString::fromLatin1(serviceType.constData(),serviceType.length()))) {
+ QMediaServiceSupportedDevicesInterface *iface =
+ qobject_cast<QMediaServiceSupportedDevicesInterface*>(obj);
+
+ if (iface) {
+ res.append(iface->devices(serviceType));
+ }
+ }
+
+ return res;
+ }
+
+ QString deviceDescription(const QByteArray &serviceType, const QByteArray &device)
+ {
+ foreach(QObject *obj, loader()->instances(
+ QString::fromLatin1(serviceType.constData(),serviceType.length()))) {
+ QMediaServiceSupportedDevicesInterface *iface =
+ qobject_cast<QMediaServiceSupportedDevicesInterface*>(obj);
+
+ if (iface) {
+ if (iface->devices(serviceType).contains(device))
+ return iface->deviceDescription(serviceType, device);
+ }
+ }
+
+ return QString();
+ }
+};
+
+Q_GLOBAL_STATIC(QPluginServiceProvider, pluginProvider);
+
+/*!
+ \class QMediaServiceProvider
+ \preliminary
+ \since 4.7
+ \brief The QMediaServiceProvider class provides an abstract allocator for media services.
+*/
+
+/*!
+ \fn QMediaServiceProvider::requestService(const QByteArray &type, const QMediaServiceProviderHint &hint)
+
+ Requests an instance of a \a type service which best matches the given \a hint.
+
+ Returns a pointer to the requested service, or a null pointer if there is no suitable service.
+
+ The returned service must be released with releaseService when it is finished with.
+*/
+
+/*!
+ \fn QMediaServiceProvider::releaseService(QMediaService *service)
+
+ Releases a media \a service requested with requestService().
+*/
+
+/*!
+ \fn QtMediaServices::SupportEstimate QMediaServiceProvider::hasSupport(const QByteArray &serviceType, const QString &mimeType, const QStringList& codecs, int flags) const
+
+ Returns how confident a media service provider is that is can provide a \a serviceType
+ service that is able to play media of a specific \a mimeType that is encoded using the listed
+ \a codecs while adhearing to constraints identified in \a flags.
+*/
+QtMediaServices::SupportEstimate QMediaServiceProvider::hasSupport(const QByteArray &serviceType,
+ const QString &mimeType,
+ const QStringList& codecs,
+ int flags) const
+{
+ Q_UNUSED(serviceType);
+ Q_UNUSED(mimeType);
+ Q_UNUSED(codecs);
+ Q_UNUSED(flags);
+
+ return QtMediaServices::MaybeSupported;
+}
+
+/*!
+ \fn QStringList QMediaServiceProvider::supportedMimeTypes(const QByteArray &serviceType, int flags) const
+
+ Returns a list of MIME types supported by the service provider for the specified \a serviceType.
+
+ The resultant list is restricted to MIME types which can be supported given the constraints in \a flags.
+*/
+QStringList QMediaServiceProvider::supportedMimeTypes(const QByteArray &serviceType, int flags) const
+{
+ Q_UNUSED(serviceType);
+ Q_UNUSED(flags);
+
+ return QStringList();
+}
+
+/*!
+ Returns the list of devices related to \a service type.
+*/
+QList<QByteArray> QMediaServiceProvider::devices(const QByteArray &service) const
+{
+ Q_UNUSED(service);
+ return QList<QByteArray>();
+}
+
+/*!
+ Returns the description of \a device related to \a serviceType,
+ suitable to be displayed to user.
+*/
+QString QMediaServiceProvider::deviceDescription(const QByteArray &serviceType, const QByteArray &device)
+{
+ Q_UNUSED(serviceType);
+ Q_UNUSED(device);
+ return QString();
+}
+
+
+#ifdef QT_BUILD_INTERNAL
+
+static QMediaServiceProvider *qt_defaultMediaServiceProvider = 0;
+
+/*!
+ Sets a media service \a provider as the default.
+
+ \internal
+*/
+void QMediaServiceProvider::setDefaultServiceProvider(QMediaServiceProvider *provider)
+{
+ qt_defaultMediaServiceProvider = provider;
+}
+
+#endif
+
+/*!
+ Returns a default provider of media services.
+*/
+QMediaServiceProvider *QMediaServiceProvider::defaultServiceProvider()
+{
+#ifdef QT_BUILD_INTERNAL
+ return qt_defaultMediaServiceProvider != 0
+ ? qt_defaultMediaServiceProvider
+ : static_cast<QMediaServiceProvider *>(pluginProvider());
+#else
+ return pluginProvider();
+#endif
+}
+
+/*!
+ \class QMediaServiceProviderPlugin
+ \preliminary
+ \since 4.7
+ \brief The QMediaServiceProviderPlugin class interface provides an interface for QMediaService
+ plug-ins.
+
+ A media service provider plug-in may implement one or more of
+ QMediaServiceSupportedFormatsInterface, QMediaServiceSupportedDevicesInterface,
+ and QMediaServiceFeaturesInterface to identify the features it supports.
+*/
+
+/*!
+ \fn QMediaServiceProviderPlugin::keys() const
+
+ Returns a list of keys for media services a plug-in can create.
+*/
+
+/*!
+ \fn QMediaServiceProviderPlugin::create(const QString &key)
+
+ Constructs a new instance of the QMediaService identified by \a key.
+
+ The QMediaService returned must be destroyed with release().
+*/
+
+/*!
+ \fn QMediaServiceProviderPlugin::release(QMediaService *service)
+
+ Destroys a media \a service constructed with create().
+*/
+
+
+/*!
+ \class QMediaServiceSupportedFormatsInterface
+ \brief The QMediaServiceSupportedFormatsInterface class interface
+ identifies if a media service plug-in supports a media format.
+ \since 4.7
+
+ A QMediaServiceProviderPlugin may implement this interface.
+*/
+
+/*!
+ \fn QMediaServiceSupportedFormatsInterface::~QMediaServiceSupportedFormatsInterface()
+
+ Destroys a media service supported formats interface.
+*/
+
+/*!
+ \fn QMediaServiceSupportedFormatsInterface::hasSupport(const QString &mimeType, const QStringList& codecs) const
+
+ Returns the level of support a media service plug-in has for a \a mimeType and set of \a codecs.
+*/
+
+/*!
+ \fn QMediaServiceSupportedFormatsInterface::supportedMimeTypes() const
+
+ Returns a list of MIME types supported by the media service plug-in.
+*/
+
+/*!
+ \class QMediaServiceSupportedDevicesInterface
+ \brief The QMediaServiceSupportedDevicesInterface class interface
+ identifies the devices supported by a media service plug-in.
+ \since 4.7
+
+ A QMediaServiceProviderPlugin may implement this interface.
+*/
+
+/*!
+ \fn QMediaServiceSupportedDevicesInterface::~QMediaServiceSupportedDevicesInterface()
+
+ Destroys a media service supported devices interface.
+*/
+
+/*!
+ \fn QMediaServiceSupportedDevicesInterface::devices(const QByteArray &service) const
+
+ Returns a list of devices supported by a plug-in \a service.
+*/
+
+/*!
+ \fn QMediaServiceSupportedDevicesInterface::deviceDescription(const QByteArray &service, const QByteArray &device)
+
+ Returns a description of a \a device supported by a plug-in \a service.
+*/
+
+/*!
+ \class QMediaServiceFeaturesInterface
+ \brief The QMediaServiceFeaturesInterface class interface identifies
+ features supported by a media service plug-in.
+ \since 4.7
+
+ A QMediaServiceProviderPlugin may implement this interface.
+*/
+
+/*!
+ \fn QMediaServiceFeaturesInterface::~QMediaServiceFeaturesInterface()
+
+ Destroys a media service features interface.
+*/
+/*!
+ \fn QMediaServiceFeaturesInterface::supportedFeatures(const QByteArray &service) const
+
+ Returns a set of features supported by a plug-in \a service.
+*/
+
+QT_END_NAMESPACE
+
+#include "moc_qmediaserviceprovider.cpp"
+#include "moc_qmediaserviceproviderplugin.cpp"
diff --git a/src/multimedia/mediaservices/base/qmediaserviceprovider.h b/src/multimedia/mediaservices/base/qmediaserviceprovider.h
new file mode 100644
index 0000000..eeea5d2
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qmediaserviceprovider.h
@@ -0,0 +1,174 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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$
+**
+****************************************************************************/
+
+#ifndef QMEDIASERVICEPROVIDER_H
+#define QMEDIASERVICEPROVIDER_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qshareddata.h>
+
+#include <QtMediaServices/qtmedianamespace.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QMediaService;
+
+class QMediaServiceProviderHintPrivate;
+class Q_MEDIASERVICES_EXPORT QMediaServiceProviderHint
+{
+public:
+ enum Type { Null, ContentType, Device, SupportedFeatures };
+
+ enum Feature {
+ LowLatencyPlayback = 0x01,
+ RecordingSupport = 0x02,
+ StreamPlayback = 0x04
+ };
+ Q_DECLARE_FLAGS(Features, Feature)
+
+ QMediaServiceProviderHint();
+ QMediaServiceProviderHint(const QString &mimeType, const QStringList& codecs);
+ QMediaServiceProviderHint(const QByteArray &device);
+ QMediaServiceProviderHint(Features features);
+ QMediaServiceProviderHint(const QMediaServiceProviderHint &other);
+ ~QMediaServiceProviderHint();
+
+ QMediaServiceProviderHint& operator=(const QMediaServiceProviderHint &other);
+
+ bool operator == (const QMediaServiceProviderHint &other) const;
+ bool operator != (const QMediaServiceProviderHint &other) const;
+
+ bool isNull() const;
+
+ Type type() const;
+
+ QString mimeType() const;
+ QStringList codecs() const;
+
+ QByteArray device() const;
+
+ Features features() const;
+
+ //to be extended, if necessary
+
+private:
+ QSharedDataPointer<QMediaServiceProviderHintPrivate> d;
+};
+
+class Q_MEDIASERVICES_EXPORT QMediaServiceProvider : public QObject
+{
+ Q_OBJECT
+
+public:
+ virtual QMediaService* requestService(const QByteArray &type, const QMediaServiceProviderHint &hint = QMediaServiceProviderHint()) = 0;
+ virtual void releaseService(QMediaService *service) = 0;
+
+ virtual QtMediaServices::SupportEstimate hasSupport(const QByteArray &serviceType,
+ const QString &mimeType,
+ const QStringList& codecs,
+ int flags = 0) const;
+ virtual QStringList supportedMimeTypes(const QByteArray &serviceType, int flags = 0) const;
+
+ virtual QList<QByteArray> devices(const QByteArray &serviceType) const;
+ virtual QString deviceDescription(const QByteArray &serviceType, const QByteArray &device);
+
+ static QMediaServiceProvider* defaultServiceProvider();
+
+#ifdef QT_BUILD_INTERNAL
+ static void setDefaultServiceProvider(QMediaServiceProvider *provider);
+#endif
+};
+
+/*!
+ Service with support for media playback
+ Required Controls: QMediaPlayerControl
+ Optional Controls: QMediaPlaylistControl, QAudioDeviceControl
+ Video Output Controls (used by QWideoWidget and QGraphicsVideoItem):
+ Required: QVideoOutputControl
+ Optional: QVideoWindowControl, QVideoRendererControl, QVideoWidgetControl
+*/
+#define Q_MEDIASERVICE_MEDIAPLAYER "com.nokia.qt.mediaplayer"
+
+/*!
+ Service with support for recording from audio sources
+ Required Controls: QAudioDeviceControl
+ Recording Controls (QMediaRecorder):
+ Required: QMediaRecorderControl
+ Recommended: QAudioEncoderControl
+ Optional: QMediaContainerControl
+*/
+#define Q_MEDIASERVICE_AUDIOSOURCE "com.nokia.qt.audiosource"
+
+/*!
+ Service with support for camera use.
+ Required Controls: QCameraControl
+ Optional Controls: QCameraExposureControl, QCameraFocusControl, QImageProcessingControl
+ Still Capture Controls: QImageCaptureControl
+ Recording Controls (QMediaRecorder):
+ Required: QMediaRecorderControl
+ Recommended: QAudioEncoderControl, QVideoEncoderControl, QMediaContainerControl
+ Viewfinder Video Output Controls (used by QWideoWidget and QGraphicsVideoItem):
+ Required: QVideoOutputControl
+ Optional: QVideoWindowControl, QVideoRendererControl, QVideoWidgetControl
+*/
+#define Q_MEDIASERVICE_CAMERA "com.nokia.qt.camera"
+
+/*!
+ Service with support for radio tuning.
+ Required Controls: QRadioTunerControl
+ Recording Controls (Optional, used by QMediaRecorder):
+ Required: QMediaRecorderControl
+ Recommended: QAudioEncoderControl
+ Optional: QMediaContainerControl
+*/
+#define Q_MEDIASERVICE_RADIO "com.nokia.qt.radio"
+
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QMEDIASERVICEPROVIDER_H
diff --git a/src/multimedia/mediaservices/base/qmediaserviceproviderplugin.h b/src/multimedia/mediaservices/base/qmediaserviceproviderplugin.h
new file mode 100644
index 0000000..ca25f91
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qmediaserviceproviderplugin.h
@@ -0,0 +1,125 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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$
+**
+****************************************************************************/
+
+#ifndef QMEDIASERVICEPROVIDERPLUGIN_H
+#define QMEDIASERVICEPROVIDERPLUGIN_H
+
+#include <QtCore/qstringlist.h>
+#include <QtCore/qplugin.h>
+#include <QtCore/qfactoryinterface.h>
+
+#include <QtMediaServices/qmediaserviceprovider.h>
+
+#ifdef Q_MOC_RUN
+# pragma Q_MOC_EXPAND_MACROS
+#endif
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+class QMediaService;
+
+
+struct Q_MEDIASERVICES_EXPORT QMediaServiceProviderFactoryInterface : public QFactoryInterface
+{
+ virtual QStringList keys() const = 0;
+ virtual QMediaService* create(QString const& key) = 0;
+ virtual void release(QMediaService *service) = 0;
+};
+
+#define QMediaServiceProviderFactoryInterface_iid \
+ "com.nokia.Qt.QMediaServiceProviderFactoryInterface/1.0"
+Q_DECLARE_INTERFACE(QMediaServiceProviderFactoryInterface, QMediaServiceProviderFactoryInterface_iid)
+
+
+struct Q_MEDIASERVICES_EXPORT QMediaServiceSupportedFormatsInterface
+{
+ virtual ~QMediaServiceSupportedFormatsInterface() {}
+ virtual QtMediaServices::SupportEstimate hasSupport(const QString &mimeType, const QStringList& codecs) const = 0;
+ virtual QStringList supportedMimeTypes() const = 0;
+};
+
+#define QMediaServiceSupportedFormatsInterface_iid \
+ "com.nokia.Qt.QMediaServiceSupportedFormatsInterface/1.0"
+Q_DECLARE_INTERFACE(QMediaServiceSupportedFormatsInterface, QMediaServiceSupportedFormatsInterface_iid)
+
+
+struct Q_MEDIASERVICES_EXPORT QMediaServiceSupportedDevicesInterface
+{
+ virtual ~QMediaServiceSupportedDevicesInterface() {}
+ virtual QList<QByteArray> devices(const QByteArray &service) const = 0;
+ virtual QString deviceDescription(const QByteArray &service, const QByteArray &device) = 0;
+};
+
+#define QMediaServiceSupportedDevicesInterface_iid \
+ "com.nokia.Qt.QMediaServiceSupportedDevicesInterface/1.0"
+Q_DECLARE_INTERFACE(QMediaServiceSupportedDevicesInterface, QMediaServiceSupportedDevicesInterface_iid)
+
+
+struct Q_MEDIASERVICES_EXPORT QMediaServiceFeaturesInterface
+{
+ virtual ~QMediaServiceFeaturesInterface() {}
+ virtual QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const = 0;
+};
+
+#define QMediaServiceFeaturesInterface_iid \
+ "com.nokia.Qt.QMediaServiceFeaturesInterface/1.0"
+Q_DECLARE_INTERFACE(QMediaServiceFeaturesInterface, QMediaServiceFeaturesInterface_iid)
+
+class Q_MEDIASERVICES_EXPORT QMediaServiceProviderPlugin : public QObject, public QMediaServiceProviderFactoryInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QMediaServiceProviderFactoryInterface:QFactoryInterface)
+
+public:
+ virtual QStringList keys() const = 0;
+ virtual QMediaService* create(const QString& key) = 0;
+ virtual void release(QMediaService *service) = 0;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QMEDIASERVICEPROVIDERPLUGIN_H
diff --git a/src/multimedia/mediaservices/base/qmediatimerange.cpp b/src/multimedia/mediaservices/base/qmediatimerange.cpp
new file mode 100644
index 0000000..2dba20c
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qmediatimerange.cpp
@@ -0,0 +1,708 @@
+/****************************************************************************
+**
+** 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 QtMediaServices module 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 <QtMediaServices/qmediatimerange.h>
+
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QMediaTimeInterval
+ \brief The QMediaTimeInterval class represents a time interval with integer precision.
+ \ingroup multimedia
+ \since 4.7
+
+ An interval is specified by an inclusive start() and end() time.
+ These must be set in the constructor, as this is an immutable class.
+ The specific units of time represented by the class have not been defined -
+ it is suitable for any times which can be represented by a signed 64 bit integer.
+
+ The isNormal() method determines if a time interval is normal
+ (a normal time interval has start() <= end()). An abnormal interval can be converted
+ in to a normal interval by calling the normalized() method.
+
+ The contains() method determines if a specified time lies within
+ the time interval.
+
+ The translated() method returns a time interval which has been translated
+ forwards or backwards through time by a specified offset.
+
+ \sa QMediaTimeRange
+*/
+
+/*!
+ \fn QMediaTimeInterval::QMediaTimeInterval()
+
+ Constructs an empty interval.
+*/
+QMediaTimeInterval::QMediaTimeInterval()
+ : s(0)
+ , e(0)
+{
+
+}
+
+/*!
+ \fn QMediaTimeInterval::QMediaTimeInterval(qint64 start, qint64 end)
+
+ Constructs an interval with the specified \a start and \a end times.
+*/
+QMediaTimeInterval::QMediaTimeInterval(qint64 start, qint64 end)
+ : s(start)
+ , e(end)
+{
+
+}
+
+/*!
+ \fn QMediaTimeInterval::QMediaTimeInterval(const QMediaTimeInterval &other)
+
+ Constructs an interval by taking a copy of \a other.
+*/
+QMediaTimeInterval::QMediaTimeInterval(const QMediaTimeInterval &other)
+ : s(other.s)
+ , e(other.e)
+{
+
+}
+
+/*!
+ \fn QMediaTimeInterval::start() const
+
+ Returns the start time of the interval.
+
+ \sa end()
+*/
+qint64 QMediaTimeInterval::start() const
+{
+ return s;
+}
+
+/*!
+ \fn QMediaTimeInterval::end() const
+
+ Returns the end time of the interval.
+
+ \sa start()
+*/
+qint64 QMediaTimeInterval::end() const
+{
+ return e;
+}
+
+/*!
+ \fn QMediaTimeInterval::contains(qint64 time) const
+
+ Returns true if the time interval contains the specified \a time.
+ That is, start() <= time <= end().
+*/
+bool QMediaTimeInterval::contains(qint64 time) const
+{
+ return isNormal() ? (s <= time && time <= e)
+ : (e <= time && time <= s);
+}
+
+/*!
+ \fn QMediaTimeInterval::isNormal() const
+
+ Returns true if this time interval is normal.
+ A normal time interval has start() <= end().
+
+ \sa normalized()
+*/
+bool QMediaTimeInterval::isNormal() const
+{
+ return s <= e;
+}
+
+/*!
+ \fn QMediaTimeInterval::normalized() const
+
+ Returns a normalized version of this interval.
+
+ If the start() time of the interval is greater than the end() time,
+ then the returned interval has the start and end times swapped.
+*/
+QMediaTimeInterval QMediaTimeInterval::normalized() const
+{
+ if(s > e)
+ return QMediaTimeInterval(e, s);
+
+ return *this;
+}
+
+/*!
+ \fn QMediaTimeInterval::translated(qint64 offset) const
+
+ Returns a copy of this time interval, translated by a value of \a offset.
+ An interval can be moved forward through time with a positive offset, or backward
+ through time with a negative offset.
+*/
+QMediaTimeInterval QMediaTimeInterval::translated(qint64 offset) const
+{
+ return QMediaTimeInterval(s + offset, e + offset);
+}
+
+/*!
+ \fn operator==(const QMediaTimeInterval &a, const QMediaTimeInterval &b)
+ \relates QMediaTimeRange
+
+ Returns true if \a a is exactly equal to \a b.
+*/
+bool operator==(const QMediaTimeInterval &a, const QMediaTimeInterval &b)
+{
+ return a.start() == b.start() && a.end() == b.end();
+}
+
+/*!
+ \fn operator!=(const QMediaTimeInterval &a, const QMediaTimeInterval &b)
+ \relates QMediaTimeRange
+
+ Returns true if \a a is not exactly equal to \a b.
+*/
+bool operator!=(const QMediaTimeInterval &a, const QMediaTimeInterval &b)
+{
+ return a.start() != b.start() || a.end() != b.end();
+}
+
+class QMediaTimeRangePrivate : public QSharedData
+{
+public:
+
+ QMediaTimeRangePrivate();
+ QMediaTimeRangePrivate(const QMediaTimeRangePrivate &other);
+ QMediaTimeRangePrivate(const QMediaTimeInterval &interval);
+
+ QList<QMediaTimeInterval> intervals;
+
+ void addInterval(const QMediaTimeInterval &interval);
+ void removeInterval(const QMediaTimeInterval &interval);
+};
+
+QMediaTimeRangePrivate::QMediaTimeRangePrivate()
+ : QSharedData()
+{
+
+}
+
+QMediaTimeRangePrivate::QMediaTimeRangePrivate(const QMediaTimeRangePrivate &other)
+ : QSharedData()
+ , intervals(other.intervals)
+{
+
+}
+
+QMediaTimeRangePrivate::QMediaTimeRangePrivate(const QMediaTimeInterval &interval)
+ : QSharedData()
+{
+ if(interval.isNormal())
+ intervals << interval;
+}
+
+void QMediaTimeRangePrivate::addInterval(const QMediaTimeInterval &interval)
+{
+ // Handle normalized intervals only
+ if(!interval.isNormal())
+ return;
+
+ // Find a place to insert the interval
+ int i;
+ for (i = 0; i < intervals.count(); i++) {
+ // Insert before this element
+ if(interval.s < intervals[i].s) {
+ intervals.insert(i, interval);
+ break;
+ }
+ }
+
+ // Interval needs to be added to the end of the list
+ if (i == intervals.count())
+ intervals.append(interval);
+
+ // Do we need to correct the element before us?
+ if(i > 0 && intervals[i - 1].e >= interval.s - 1)
+ i--;
+
+ // Merge trailing ranges
+ while (i < intervals.count() - 1
+ && intervals[i].e >= intervals[i + 1].s - 1) {
+ intervals[i].e = qMax(intervals[i].e, intervals[i + 1].e);
+ intervals.removeAt(i + 1);
+ }
+}
+
+void QMediaTimeRangePrivate::removeInterval(const QMediaTimeInterval &interval)
+{
+ // Handle normalized intervals only
+ if(!interval.isNormal())
+ return;
+
+ for (int i = 0; i < intervals.count(); i++) {
+ QMediaTimeInterval r = intervals[i];
+
+ if (r.e < interval.s) {
+ // Before the removal interval
+ continue;
+ } else if (interval.e < r.s) {
+ // After the removal interval - stop here
+ break;
+ } else if (r.s < interval.s && interval.e < r.e) {
+ // Split case - a single range has a chunk removed
+ intervals[i].e = interval.s -1;
+ addInterval(QMediaTimeInterval(interval.e + 1, r.e));
+ break;
+ } else if (r.s < interval.s) {
+ // Trimming Tail Case
+ intervals[i].e = interval.s - 1;
+ } else if (interval.e < r.e) {
+ // Trimming Head Case - we can stop after this
+ intervals[i].s = interval.e + 1;
+ break;
+ } else {
+ // Complete coverage case
+ intervals.removeAt(i);
+ --i;
+ }
+ }
+}
+
+/*!
+ \class QMediaTimeRange
+ \brief The QMediaTimeRange class represents a set of zero or more disjoint
+ time intervals.
+ \ingroup multimedia
+ \since 4.7
+
+ \reentrant
+
+ The earliestTime(), latestTime(), intervals() and isEmpty()
+ methods are used to get information about the current time range.
+
+ The addInterval(), removeInterval() and clear() methods are used to modify
+ the current time range.
+
+ When adding or removing intervals from the time range, existing intervals
+ within the range may be expanded, trimmed, deleted, merged or split to ensure
+ that all intervals within the time range remain distinct and disjoint. As a
+ consequence, all intervals added or removed from a time range must be
+ \l{QMediaTimeInterval::isNormal()}{normal}.
+
+ \sa QMediaTimeInterval
+*/
+
+/*!
+ \fn QMediaTimeRange::QMediaTimeRange()
+
+ Constructs an empty time range.
+*/
+QMediaTimeRange::QMediaTimeRange()
+ : d(new QMediaTimeRangePrivate)
+{
+
+}
+
+/*!
+ \fn QMediaTimeRange::QMediaTimeRange(qint64 start, qint64 end)
+
+ Constructs a time range that contains an initial interval from
+ \a start to \a end inclusive.
+
+ If the interval is not \l{QMediaTimeInterval::isNormal()}{normal},
+ the resulting time range will be empty.
+
+ \sa addInterval()
+*/
+QMediaTimeRange::QMediaTimeRange(qint64 start, qint64 end)
+ : d(new QMediaTimeRangePrivate(QMediaTimeInterval(start, end)))
+{
+
+}
+
+/*!
+ \fn QMediaTimeRange::QMediaTimeRange(const QMediaTimeInterval &interval)
+
+ Constructs a time range that contains an intitial interval, \a interval.
+
+ If \a interval is not \l{QMediaTimeInterval::isNormal()}{normal},
+ the resulting time range will be empty.
+
+ \sa addInterval()
+*/
+QMediaTimeRange::QMediaTimeRange(const QMediaTimeInterval &interval)
+ : d(new QMediaTimeRangePrivate(interval))
+{
+
+}
+
+/*!
+ \fn QMediaTimeRange::QMediaTimeRange(const QMediaTimeRange &range)
+
+ Constructs a time range by copying another time \a range.
+*/
+QMediaTimeRange::QMediaTimeRange(const QMediaTimeRange &range)
+ : d(range.d)
+{
+
+}
+
+/*!
+ \fn QMediaTimeRange::~QMediaTimeRange()
+
+ Destructor.
+*/
+QMediaTimeRange::~QMediaTimeRange()
+{
+
+}
+
+/*!
+ \fn QMediaTimeRange::operator=(const QMediaTimeRange &other)
+
+ Takes a copy of the \a other time range and returns itself.
+*/
+QMediaTimeRange &QMediaTimeRange::operator=(const QMediaTimeRange &other)
+{
+ d = other.d;
+ return *this;
+}
+
+/*!
+ \fn QMediaTimeRange::operator=(const QMediaTimeInterval &interval)
+
+ Sets the time range to a single continuous interval, \a interval.
+*/
+QMediaTimeRange &QMediaTimeRange::operator=(const QMediaTimeInterval &interval)
+{
+ d = new QMediaTimeRangePrivate(interval);
+ return *this;
+}
+
+/*!
+ \fn QMediaTimeRange::earliestTime() const
+
+ Returns the earliest time within the time range.
+
+ For empty time ranges, this value is equal to zero.
+
+ \sa latestTime()
+*/
+qint64 QMediaTimeRange::earliestTime() const
+{
+ if (!d->intervals.isEmpty())
+ return d->intervals[0].s;
+
+ return 0;
+}
+
+/*!
+ \fn QMediaTimeRange::latestTime() const
+
+ Returns the latest time within the time range.
+
+ For empty time ranges, this value is equal to zero.
+
+ \sa earliestTime()
+*/
+qint64 QMediaTimeRange::latestTime() const
+{
+ if (!d->intervals.isEmpty())
+ return d->intervals[d->intervals.count() - 1].e;
+
+ return 0;
+}
+
+/*!
+ \fn QMediaTimeRange::addInterval(qint64 start, qint64 end)
+ \overload
+
+ Adds the interval specified by \a start and \a end
+ to the time range.
+
+ \sa addInterval()
+*/
+void QMediaTimeRange::addInterval(qint64 start, qint64 end)
+{
+ d->addInterval(QMediaTimeInterval(start, end));
+}
+
+/*!
+ \fn QMediaTimeRange::addInterval(const QMediaTimeInterval &interval)
+
+ Adds the specified \a interval to the time range.
+
+ Adding intervals which are not \l{QMediaTimeInterval::isNormal()}{normal}
+ is invalid, and will be ignored.
+
+ If the specified interval is adjacent to, or overlaps existing
+ intervals within the time range, these intervals will be merged.
+
+ This operation takes \l{linear time}
+
+ \sa removeInterval()
+*/
+void QMediaTimeRange::addInterval(const QMediaTimeInterval &interval)
+{
+ d->addInterval(interval);
+}
+
+/*!
+ \fn QMediaTimeRange::addTimeRange(const QMediaTimeRange &range)
+
+ Adds each of the intervals in \a range to this time range.
+
+ Equivalent to calling addInterval() for each interval in \a range.
+*/
+void QMediaTimeRange::addTimeRange(const QMediaTimeRange &range)
+{
+ foreach(const QMediaTimeInterval &i, range.intervals()) {
+ d->addInterval(i);
+ }
+}
+
+/*!
+ \fn QMediaTimeRange::removeInterval(qint64 start, qint64 end)
+ \overload
+
+ Removes the interval specified by \a start and \a end
+ from the time range.
+
+ \sa removeInterval()
+*/
+void QMediaTimeRange::removeInterval(qint64 start, qint64 end)
+{
+ d->removeInterval(QMediaTimeInterval(start, end));
+}
+
+/*!
+ \fn QMediaTimeRange::removeInterval(const QMediaTimeInterval &interval)
+
+ Removes the specified \a interval from the time range.
+
+ Removing intervals which are not \l{QMediaTimeInterval::isNormal()}{normal}
+ is invalid, and will be ignored.
+
+ Intervals within the time range will be trimmed, split or deleted
+ such that no intervals within the time range include any part of the
+ target interval.
+
+ This operation takes \l{linear time}
+
+ \sa addInterval()
+*/
+void QMediaTimeRange::removeInterval(const QMediaTimeInterval &interval)
+{
+ d->removeInterval(interval);
+}
+
+/*!
+ \fn QMediaTimeRange::removeTimeRange(const QMediaTimeRange &range)
+
+ Removes each of the intervals in \a range from this time range.
+
+ Equivalent to calling removeInterval() for each interval in \a range.
+*/
+void QMediaTimeRange::removeTimeRange(const QMediaTimeRange &range)
+{
+ foreach(const QMediaTimeInterval &i, range.intervals()) {
+ d->removeInterval(i);
+ }
+}
+
+/*!
+ \fn QMediaTimeRange::operator+=(const QMediaTimeRange &other)
+
+ Adds each interval in \a other to the time range and returns the result.
+*/
+QMediaTimeRange& QMediaTimeRange::operator+=(const QMediaTimeRange &other)
+{
+ addTimeRange(other);
+ return *this;
+}
+
+/*!
+ \fn QMediaTimeRange::operator+=(const QMediaTimeInterval &interval)
+
+ Adds the specified \a interval to the time range and returns the result.
+*/
+QMediaTimeRange& QMediaTimeRange::operator+=(const QMediaTimeInterval &interval)
+{
+ addInterval(interval);
+ return *this;
+}
+
+/*!
+ \fn QMediaTimeRange::operator-=(const QMediaTimeRange &other)
+
+ Removes each interval in \a other from the time range and returns the result.
+*/
+QMediaTimeRange& QMediaTimeRange::operator-=(const QMediaTimeRange &other)
+{
+ removeTimeRange(other);
+ return *this;
+}
+
+/*!
+ \fn QMediaTimeRange::operator-=(const QMediaTimeInterval &interval)
+
+ Removes the specified \a interval from the time range and returns the result.
+*/
+QMediaTimeRange& QMediaTimeRange::operator-=(const QMediaTimeInterval &interval)
+{
+ removeInterval(interval);
+ return *this;
+}
+
+/*!
+ \fn QMediaTimeRange::clear()
+
+ Removes all intervals from the time range.
+
+ \sa removeInterval()
+*/
+void QMediaTimeRange::clear()
+{
+ d->intervals.clear();
+}
+
+/*!
+ \fn QMediaTimeRange::intervals() const
+
+ Returns the list of intervals covered by this time range.
+*/
+QList<QMediaTimeInterval> QMediaTimeRange::intervals() const
+{
+ return d->intervals;
+}
+
+/*!
+ \fn QMediaTimeRange::isEmpty() const
+
+ Returns true if there are no intervals within the time range.
+
+ \sa intervals()
+*/
+bool QMediaTimeRange::isEmpty() const
+{
+ return d->intervals.isEmpty();
+}
+
+/*!
+ \fn QMediaTimeRange::isContinuous() const
+
+ Returns true if the time range consists of a continuous interval.
+ That is, there is one or fewer disjoint intervals within the time range.
+*/
+bool QMediaTimeRange::isContinuous() const
+{
+ return (d->intervals.count() <= 1);
+}
+
+/*!
+ \fn QMediaTimeRange::contains(qint64 time) const
+
+ Returns true if the specified \a time lies within the time range.
+*/
+bool QMediaTimeRange::contains(qint64 time) const
+{
+ for (int i = 0; i < d->intervals.count(); i++) {
+ if (d->intervals[i].contains(time))
+ return true;
+
+ if (time < d->intervals[i].s)
+ break;
+ }
+
+ return false;
+}
+
+/*!
+ \fn operator==(const QMediaTimeRange &a, const QMediaTimeRange &b)
+ \relates QMediaTimeRange
+
+ Returns true if all intervals in \a a are present in \a b.
+*/
+bool operator==(const QMediaTimeRange &a, const QMediaTimeRange &b)
+{
+ if (a.intervals().count() != b.intervals().count())
+ return false;
+
+ for (int i = 0; i < a.intervals().count(); i++)
+ {
+ if(a.intervals()[i] != b.intervals()[i])
+ return false;
+ }
+
+ return true;
+}
+
+/*!
+ \fn operator!=(const QMediaTimeRange &a, const QMediaTimeRange &b)
+ \relates QMediaTimeRange
+
+ Returns true if one or more intervals in \a a are not present in \a b.
+*/
+bool operator!=(const QMediaTimeRange &a, const QMediaTimeRange &b)
+{
+ return !(a == b);
+}
+
+/*!
+ \fn operator+(const QMediaTimeRange &r1, const QMediaTimeRange &r2)
+
+ Returns a time range containing the union between \a r1 and \a r2.
+ */
+QMediaTimeRange operator+(const QMediaTimeRange &r1, const QMediaTimeRange &r2)
+{
+ return (QMediaTimeRange(r1) += r2);
+}
+
+/*!
+ \fn operator-(const QMediaTimeRange &r1, const QMediaTimeRange &r2)
+
+ Returns a time range containing \a r2 subtracted from \a r1.
+ */
+QMediaTimeRange operator-(const QMediaTimeRange &r1, const QMediaTimeRange &r2)
+{
+ return (QMediaTimeRange(r1) -= r2);
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/mediaservices/base/qmediatimerange.h b/src/multimedia/mediaservices/base/qmediatimerange.h
new file mode 100644
index 0000000..5983db2
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qmediatimerange.h
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** 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 QtMediaServices module 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$
+**
+****************************************************************************/
+
+#ifndef QMEDIATIMERANGE_H
+#define QMEDIATIMERANGE_H
+
+#include <QtCore/qshareddata.h>
+#include <QtMediaServices/qtmedianamespace.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+class QMediaTimeRangePrivate;
+
+class Q_MEDIASERVICES_EXPORT QMediaTimeInterval
+{
+public:
+ QMediaTimeInterval();
+ QMediaTimeInterval(qint64 start, qint64 end);
+ QMediaTimeInterval(const QMediaTimeInterval&);
+
+ qint64 start() const;
+ qint64 end() const;
+
+ bool contains(qint64 time) const;
+
+ bool isNormal() const;
+ QMediaTimeInterval normalized() const;
+ QMediaTimeInterval translated(qint64 offset) const;
+
+private:
+ friend class QMediaTimeRangePrivate;
+ friend class QMediaTimeRange;
+
+ qint64 s;
+ qint64 e;
+};
+
+Q_MEDIASERVICES_EXPORT bool operator==(const QMediaTimeInterval&, const QMediaTimeInterval&);
+Q_MEDIASERVICES_EXPORT bool operator!=(const QMediaTimeInterval&, const QMediaTimeInterval&);
+
+class Q_MEDIASERVICES_EXPORT QMediaTimeRange
+{
+public:
+
+ QMediaTimeRange();
+ QMediaTimeRange(qint64 start, qint64 end);
+ QMediaTimeRange(const QMediaTimeInterval&);
+ QMediaTimeRange(const QMediaTimeRange &range);
+ ~QMediaTimeRange();
+
+ QMediaTimeRange &operator=(const QMediaTimeRange&);
+ QMediaTimeRange &operator=(const QMediaTimeInterval&);
+
+ qint64 earliestTime() const;
+ qint64 latestTime() const;
+
+ QList<QMediaTimeInterval> intervals() const;
+ bool isEmpty() const;
+ bool isContinuous() const;
+
+ bool contains(qint64 time) const;
+
+ void addInterval(qint64 start, qint64 end);
+ void addInterval(const QMediaTimeInterval &interval);
+ void addTimeRange(const QMediaTimeRange&);
+
+ void removeInterval(qint64 start, qint64 end);
+ void removeInterval(const QMediaTimeInterval &interval);
+ void removeTimeRange(const QMediaTimeRange&);
+
+ QMediaTimeRange& operator+=(const QMediaTimeRange&);
+ QMediaTimeRange& operator+=(const QMediaTimeInterval&);
+ QMediaTimeRange& operator-=(const QMediaTimeRange&);
+ QMediaTimeRange& operator-=(const QMediaTimeInterval&);
+
+ void clear();
+
+private:
+ QSharedDataPointer<QMediaTimeRangePrivate> d;
+};
+
+Q_MEDIASERVICES_EXPORT bool operator==(const QMediaTimeRange&, const QMediaTimeRange&);
+Q_MEDIASERVICES_EXPORT bool operator!=(const QMediaTimeRange&, const QMediaTimeRange&);
+Q_MEDIASERVICES_EXPORT QMediaTimeRange operator+(const QMediaTimeRange&, const QMediaTimeRange&);
+Q_MEDIASERVICES_EXPORT QMediaTimeRange operator-(const QMediaTimeRange&, const QMediaTimeRange&);
+
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QMEDIATIMERANGE_H
diff --git a/src/multimedia/mediaservices/base/qmetadatacontrol.cpp b/src/multimedia/mediaservices/base/qmetadatacontrol.cpp
new file mode 100644
index 0000000..8bfec7e
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qmetadatacontrol.cpp
@@ -0,0 +1,185 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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 <QtMediaServices/qmetadatacontrol.h>
+#include "qmediacontrol_p.h"
+
+
+QT_BEGIN_NAMESPACE
+
+
+/*!
+ \class QMetaDataControl
+ \ingroup multimedia-serv
+ \since 4.7
+ \preliminary
+ \brief The QMetaDataControl class provides access to the meta-data of a
+ QMediaService's media.
+
+ If a QMediaService can provide read or write access to the meta-data of
+ its current media it will implement QMetaDataControl. This control
+ provides functions for both retrieving and setting meta-data values.
+ Meta-data may be addressed by the well defined keys in the
+ QtMediaServices::MetaData enumeration using the metaData() functions, or by
+ string keys using the extendedMetaData() functions.
+
+ The functionality provided by this control is exposed to application
+ code by the meta-data members of QMediaObject, and so meta-data access
+ is potentially available in any of the media object classes. Any media
+ service may implement QMetaDataControl.
+
+ The interface name of QMetaDataControl is \c com.nokia.Qt.QMetaDataControl/1.0 as
+ defined in QMetaDataControl_iid.
+
+ \sa QMediaService::control(), QMediaObject
+*/
+
+/*!
+ \macro QMetaDataControl_iid
+
+ \c com.nokia.Qt.QMetaDataControl/1.0
+
+ Defines the interface name of the QMetaDataControl class.
+
+ \relates QMetaDataControl
+*/
+
+/*!
+ Construct a QMetaDataControl with \a parent. This class is meant as a base class
+ for service specific meta data providers so this constructor is protected.
+*/
+
+QMetaDataControl::QMetaDataControl(QObject *parent):
+ QMediaControl(*new QMediaControlPrivate, parent)
+{
+}
+
+/*!
+ Destroy the meta-data object.
+*/
+
+QMetaDataControl::~QMetaDataControl()
+{
+}
+
+/*!
+ \fn bool QMetaDataControl::isMetaDataAvailable() const
+
+ Identifies if meta-data is available from a media service.
+
+ Returns true if the meta-data is available and false otherwise.
+*/
+
+/*!
+ \fn bool QMetaDataControl::isWritable() const
+
+ Identifies if a media service's meta-data can be edited.
+
+ Returns true if the meta-data is writable and false otherwise.
+*/
+
+/*!
+ \fn QVariant QMetaDataControl::metaData(QtMediaServices::MetaData key) const
+
+ Returns the meta-data for the given \a key.
+*/
+
+/*!
+ \fn void QMetaDataControl::setMetaData(QtMediaServices::MetaData key, const QVariant &value)
+
+ Sets the \a value of the meta-data element with the given \a key.
+*/
+
+/*!
+ \fn QMetaDataControl::availableMetaData() const
+
+ Returns a list of keys there is meta-data available for.
+*/
+
+/*!
+ \fn QMetaDataControl::extendedMetaData(const QString &key) const
+
+ Returns the metaData for an abitrary string \a key.
+
+ The valid selection of keys for extended meta-data is determined by the provider and the meaning
+ and type may differ between providers.
+*/
+
+/*!
+ \fn QMetaDataControl::setExtendedMetaData(const QString &key, const QVariant &value)
+
+ Change the value of the meta-data element with an abitrary string \a key to \a value.
+
+ The valid selection of keys for extended meta-data is determined by the provider and the meaning
+ and type may differ between providers.
+*/
+
+/*!
+ \fn QMetaDataControl::availableExtendedMetaData() const
+
+ Returns a list of keys there is extended meta-data available for.
+*/
+
+
+/*!
+ \fn void QMetaDataControl::metaDataChanged()
+
+ Signal the changes of meta-data.
+*/
+
+/*!
+ \fn void QMetaDataControl::metaDataAvailableChanged(bool available)
+
+ Signal the availability of meta-data has changed, \a available will
+ be true if the multimedia object has meta-data.
+*/
+
+/*!
+ \fn void QMetaDataControl::writableChanged(bool writable)
+
+ Signal a change in the writable status of meta-data, \a writable will be
+ true if meta-data elements can be added or adjusted.
+*/
+
+#include "moc_qmetadatacontrol.cpp"
+
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/mediaservices/base/qmetadatacontrol.h b/src/multimedia/mediaservices/base/qmetadatacontrol.h
new file mode 100644
index 0000000..48206fa
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qmetadatacontrol.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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$
+**
+****************************************************************************/
+
+#ifndef QMETADATACONTROL_H
+#define QMETADATACONTROL_H
+
+#include <QtMediaServices/qmediacontrol.h>
+#include <QtMediaServices/qmediaobject.h>
+#include <QtMediaServices/qmediaresource.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+class Q_MEDIASERVICES_EXPORT QMetaDataControl : public QMediaControl
+{
+ Q_OBJECT
+
+public:
+ ~QMetaDataControl();
+
+ virtual bool isWritable() const = 0;
+ virtual bool isMetaDataAvailable() const = 0;
+
+ virtual QVariant metaData(QtMediaServices::MetaData key) const = 0;
+ virtual void setMetaData(QtMediaServices::MetaData key, const QVariant &value) = 0;
+ virtual QList<QtMediaServices::MetaData> availableMetaData() const = 0;
+
+ virtual QVariant extendedMetaData(const QString &key) const = 0;
+ virtual void setExtendedMetaData(const QString &key, const QVariant &value) = 0;
+ virtual QStringList availableExtendedMetaData() const = 0;
+
+Q_SIGNALS:
+ void metaDataChanged();
+
+ void writableChanged(bool writable);
+ void metaDataAvailableChanged(bool available);
+
+protected:
+ QMetaDataControl(QObject *parent = 0);
+};
+
+#define QMetaDataControl_iid "com.nokia.Qt.QMetaDataControl/1.0"
+Q_MEDIA_DECLARE_CONTROL(QMetaDataControl, QMetaDataControl_iid)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif // QMETADATAPROVIDER_H
diff --git a/src/multimedia/mediaservices/base/qpaintervideosurface.cpp b/src/multimedia/mediaservices/base/qpaintervideosurface.cpp
new file mode 100644
index 0000000..302e772
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qpaintervideosurface.cpp
@@ -0,0 +1,1565 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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 "qpaintervideosurface_p.h"
+#include "qpaintervideosurface_mac_p.h"
+
+#include <qmath.h>
+
+#include <qpainter.h>
+#include <qvariant.h>
+#include <QtMultimedia/qvideosurfaceformat.h>
+
+#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_1_CL) && !defined(QT_OPENGL_ES_1)
+#include <qglshaderprogram.h>
+#endif
+
+#include <QtDebug>
+
+
+QT_BEGIN_NAMESPACE
+
+QVideoSurfacePainter::~QVideoSurfacePainter()
+{
+}
+
+class QVideoSurfaceRasterPainter : public QVideoSurfacePainter
+{
+public:
+ QVideoSurfaceRasterPainter();
+
+ QList<QVideoFrame::PixelFormat> supportedPixelFormats(
+ QAbstractVideoBuffer::HandleType handleType) const;
+
+ bool isFormatSupported(
+ const QVideoSurfaceFormat &format, QVideoSurfaceFormat *similar) const;
+
+ QAbstractVideoSurface::Error start(const QVideoSurfaceFormat &format);
+ void stop();
+
+ QAbstractVideoSurface::Error setCurrentFrame(const QVideoFrame &frame);
+
+ QAbstractVideoSurface::Error paint(
+ const QRectF &target, QPainter *painter, const QRectF &source);
+
+ void updateColors(int brightness, int contrast, int hue, int saturation);
+
+private:
+ QList<QVideoFrame::PixelFormat> m_imagePixelFormats;
+ QVideoFrame m_frame;
+ QSize m_imageSize;
+ QImage::Format m_imageFormat;
+ QVideoSurfaceFormat::Direction m_scanLineDirection;
+};
+
+QVideoSurfaceRasterPainter::QVideoSurfaceRasterPainter()
+ : m_imageFormat(QImage::Format_Invalid)
+ , m_scanLineDirection(QVideoSurfaceFormat::TopToBottom)
+{
+ m_imagePixelFormats
+ << QVideoFrame::Format_RGB32
+#ifndef QT_OPENGL_ES // The raster formats should be a subset of the GL formats.
+ << QVideoFrame::Format_RGB24
+#endif
+ << QVideoFrame::Format_ARGB32
+ << QVideoFrame::Format_RGB565;
+}
+
+QList<QVideoFrame::PixelFormat> QVideoSurfaceRasterPainter::supportedPixelFormats(
+ QAbstractVideoBuffer::HandleType handleType) const
+{
+ return handleType == QAbstractVideoBuffer::NoHandle
+ ? m_imagePixelFormats
+ : QList<QVideoFrame::PixelFormat>();
+}
+
+bool QVideoSurfaceRasterPainter::isFormatSupported(
+ const QVideoSurfaceFormat &format, QVideoSurfaceFormat *) const
+{
+ return format.handleType() == QAbstractVideoBuffer::NoHandle
+ && m_imagePixelFormats.contains(format.pixelFormat())
+ && !format.frameSize().isEmpty();
+}
+
+QAbstractVideoSurface::Error QVideoSurfaceRasterPainter::start(const QVideoSurfaceFormat &format)
+{
+ m_frame = QVideoFrame();
+ m_imageFormat = QVideoFrame::imageFormatFromPixelFormat(format.pixelFormat());
+ m_imageSize = format.frameSize();
+ m_scanLineDirection = format.scanLineDirection();
+
+ return format.handleType() == QAbstractVideoBuffer::NoHandle
+ && m_imageFormat != QImage::Format_Invalid
+ && !m_imageSize.isEmpty()
+ ? QAbstractVideoSurface::NoError
+ : QAbstractVideoSurface::UnsupportedFormatError;
+}
+
+void QVideoSurfaceRasterPainter::stop()
+{
+ m_frame = QVideoFrame();
+}
+
+QAbstractVideoSurface::Error QVideoSurfaceRasterPainter::setCurrentFrame(const QVideoFrame &frame)
+{
+ m_frame = frame;
+
+ return QAbstractVideoSurface::NoError;
+}
+
+QAbstractVideoSurface::Error QVideoSurfaceRasterPainter::paint(
+ const QRectF &target, QPainter *painter, const QRectF &source)
+{
+ if (m_frame.map(QAbstractVideoBuffer::ReadOnly)) {
+ QImage image(
+ m_frame.bits(),
+ m_imageSize.width(),
+ m_imageSize.height(),
+ m_frame.bytesPerLine(),
+ m_imageFormat);
+
+ if (m_scanLineDirection == QVideoSurfaceFormat::BottomToTop) {
+ const QTransform oldTransform = painter->transform();
+
+ painter->scale(1, -1);
+ painter->translate(0, -target.bottom());
+ painter->drawImage(
+ QRectF(target.x(), 0, target.width(), target.height()), image, source);
+ painter->setTransform(oldTransform);
+ } else {
+ painter->drawImage(target, image, source);
+ }
+
+ m_frame.unmap();
+ } else if (m_frame.isValid()) {
+ return QAbstractVideoSurface::IncorrectFormatError;
+ } else {
+ painter->fillRect(target, Qt::black);
+ }
+ return QAbstractVideoSurface::NoError;
+}
+
+void QVideoSurfaceRasterPainter::updateColors(int, int, int, int)
+{
+}
+
+#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_1_CL) && !defined(QT_OPENGL_ES_1)
+
+#ifndef Q_WS_MAC
+# ifndef APIENTRYP
+# ifdef APIENTRY
+# define APIENTRYP APIENTRY *
+# else
+# define APIENTRY
+# define APIENTRYP *
+# endif
+# endif
+#else
+# define APIENTRY
+# define APIENTRYP *
+#endif
+
+#ifndef GL_TEXTURE0
+# define GL_TEXTURE0 0x84C0
+# define GL_TEXTURE1 0x84C1
+# define GL_TEXTURE2 0x84C2
+#endif
+#ifndef GL_PROGRAM_ERROR_STRING_ARB
+# define GL_PROGRAM_ERROR_STRING_ARB 0x8874
+#endif
+
+#ifndef GL_UNSIGNED_SHORT_5_6_5
+# define GL_UNSIGNED_SHORT_5_6_5 33635
+#endif
+
+class QVideoSurfaceGLPainter : public QVideoSurfacePainter
+{
+public:
+ QVideoSurfaceGLPainter(QGLContext *context);
+ ~QVideoSurfaceGLPainter();
+ QList<QVideoFrame::PixelFormat> supportedPixelFormats(
+ QAbstractVideoBuffer::HandleType handleType) const;
+
+ bool isFormatSupported(
+ const QVideoSurfaceFormat &format, QVideoSurfaceFormat *similar) const;
+
+ QAbstractVideoSurface::Error setCurrentFrame(const QVideoFrame &frame);
+
+ void updateColors(int brightness, int contrast, int hue, int saturation);
+
+protected:
+ void initRgbTextureInfo(GLenum internalFormat, GLuint format, GLenum type, const QSize &size);
+ void initYuv420PTextureInfo(const QSize &size);
+ void initYv12TextureInfo(const QSize &size);
+
+#ifndef QT_OPENGL_ES
+ typedef void (APIENTRY *_glActiveTexture) (GLenum);
+ _glActiveTexture glActiveTexture;
+#endif
+
+ QList<QVideoFrame::PixelFormat> m_imagePixelFormats;
+ QList<QVideoFrame::PixelFormat> m_glPixelFormats;
+ QMatrix4x4 m_colorMatrix;
+ QVideoFrame m_frame;
+
+ QGLContext *m_context;
+ QAbstractVideoBuffer::HandleType m_handleType;
+ QVideoSurfaceFormat::Direction m_scanLineDirection;
+ GLenum m_textureFormat;
+ GLuint m_textureInternalFormat;
+ GLenum m_textureType;
+ int m_textureCount;
+ GLuint m_textureIds[3];
+ int m_textureWidths[3];
+ int m_textureHeights[3];
+ int m_textureOffsets[3];
+ bool m_yuv;
+};
+
+QVideoSurfaceGLPainter::QVideoSurfaceGLPainter(QGLContext *context)
+ : m_context(context)
+ , m_handleType(QAbstractVideoBuffer::NoHandle)
+ , m_scanLineDirection(QVideoSurfaceFormat::TopToBottom)
+ , m_textureFormat(0)
+ , m_textureInternalFormat(0)
+ , m_textureType(0)
+ , m_textureCount(0)
+ , m_yuv(false)
+{
+#ifndef QT_OPENGL_ES
+ glActiveTexture = (_glActiveTexture)m_context->getProcAddress(QLatin1String("glActiveTexture"));
+#endif
+}
+
+QVideoSurfaceGLPainter::~QVideoSurfaceGLPainter()
+{
+}
+
+QList<QVideoFrame::PixelFormat> QVideoSurfaceGLPainter::supportedPixelFormats(
+ QAbstractVideoBuffer::HandleType handleType) const
+{
+ switch (handleType) {
+ case QAbstractVideoBuffer::NoHandle:
+ return m_imagePixelFormats;
+ case QAbstractVideoBuffer::GLTextureHandle:
+ return m_glPixelFormats;
+ default:
+ return QList<QVideoFrame::PixelFormat>();
+ }
+}
+
+bool QVideoSurfaceGLPainter::isFormatSupported(
+ const QVideoSurfaceFormat &format, QVideoSurfaceFormat *) const
+{
+ if (format.frameSize().isEmpty()) {
+ return false;
+ } else {
+ switch (format.handleType()) {
+ case QAbstractVideoBuffer::NoHandle:
+ return m_imagePixelFormats.contains(format.pixelFormat());
+ case QAbstractVideoBuffer::GLTextureHandle:
+ return m_glPixelFormats.contains(format.pixelFormat());
+ default:
+ return false;
+ }
+ }
+}
+
+QAbstractVideoSurface::Error QVideoSurfaceGLPainter::setCurrentFrame(const QVideoFrame &frame)
+{
+ m_frame = frame;
+
+ if (m_handleType == QAbstractVideoBuffer::GLTextureHandle) {
+ m_textureIds[0] = frame.handle().toInt();
+ } else if (m_frame.map(QAbstractVideoBuffer::ReadOnly)) {
+ m_context->makeCurrent();
+
+ for (int i = 0; i < m_textureCount; ++i) {
+ glBindTexture(GL_TEXTURE_2D, m_textureIds[i]);
+ glTexImage2D(
+ GL_TEXTURE_2D,
+ 0,
+ m_textureInternalFormat,
+ m_textureWidths[i],
+ m_textureHeights[i],
+ 0,
+ m_textureFormat,
+ m_textureType,
+ m_frame.bits() + m_textureOffsets[i]);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ }
+ m_frame.unmap();
+ } else if (m_frame.isValid()) {
+ return QAbstractVideoSurface::IncorrectFormatError;
+ }
+
+ return QAbstractVideoSurface::NoError;
+}
+
+void QVideoSurfaceGLPainter::updateColors(int brightness, int contrast, int hue, int saturation)
+{
+ const qreal b = brightness / 200.0;
+ const qreal c = contrast / 100.0 + 1.0;
+ const qreal h = hue / 100.0;
+ const qreal s = saturation / 100.0 + 1.0;
+
+ const qreal cosH = qCos(M_PI * h);
+ const qreal sinH = qSin(M_PI * h);
+
+ const qreal h11 = 0.787 * cosH - 0.213 * sinH + 0.213;
+ const qreal h21 = -0.213 * cosH + 0.143 * sinH + 0.213;
+ const qreal h31 = -0.213 * cosH - 0.787 * sinH + 0.213;
+
+ const qreal h12 = -0.715 * cosH - 0.715 * sinH + 0.715;
+ const qreal h22 = 0.285 * cosH + 0.140 * sinH + 0.715;
+ const qreal h32 = -0.715 * cosH + 0.715 * sinH + 0.715;
+
+ const qreal h13 = -0.072 * cosH + 0.928 * sinH + 0.072;
+ const qreal h23 = -0.072 * cosH - 0.283 * sinH + 0.072;
+ const qreal h33 = 0.928 * cosH + 0.072 * sinH + 0.072;
+
+ const qreal sr = (1.0 - s) * 0.3086;
+ const qreal sg = (1.0 - s) * 0.6094;
+ const qreal sb = (1.0 - s) * 0.0820;
+
+ const qreal sr_s = sr + s;
+ const qreal sg_s = sg + s;
+ const qreal sb_s = sr + s;
+
+ const float m4 = (s + sr + sg + sb) * (0.5 - 0.5 * c + b);
+
+ m_colorMatrix(0, 0) = c * (sr_s * h11 + sg * h21 + sb * h31);
+ m_colorMatrix(0, 1) = c * (sr_s * h12 + sg * h22 + sb * h32);
+ m_colorMatrix(0, 2) = c * (sr_s * h13 + sg * h23 + sb * h33);
+ m_colorMatrix(0, 3) = m4;
+
+ m_colorMatrix(1, 0) = c * (sr * h11 + sg_s * h21 + sb * h31);
+ m_colorMatrix(1, 1) = c * (sr * h12 + sg_s * h22 + sb * h32);
+ m_colorMatrix(1, 2) = c * (sr * h13 + sg_s * h23 + sb * h33);
+ m_colorMatrix(1, 3) = m4;
+
+ m_colorMatrix(2, 0) = c * (sr * h11 + sg * h21 + sb_s * h31);
+ m_colorMatrix(2, 1) = c * (sr * h12 + sg * h22 + sb_s * h32);
+ m_colorMatrix(2, 2) = c * (sr * h13 + sg * h23 + sb_s * h33);
+ m_colorMatrix(2, 3) = m4;
+
+ m_colorMatrix(3, 0) = 0.0;
+ m_colorMatrix(3, 1) = 0.0;
+ m_colorMatrix(3, 2) = 0.0;
+ m_colorMatrix(3, 3) = 1.0;
+
+ if (m_yuv) {
+ m_colorMatrix = m_colorMatrix * QMatrix4x4(
+ 1.0, 0.000, 1.140, -0.5700,
+ 1.0, -0.394, -0.581, 0.4875,
+ 1.0, 2.028, 0.000, -1.0140,
+ 0.0, 0.000, 0.000, 1.0000);
+ }
+}
+
+void QVideoSurfaceGLPainter::initRgbTextureInfo(
+ GLenum internalFormat, GLuint format, GLenum type, const QSize &size)
+{
+ m_yuv = false;
+ m_textureInternalFormat = internalFormat;
+ m_textureFormat = format;
+ m_textureType = type;
+ m_textureCount = 1;
+ m_textureWidths[0] = size.width();
+ m_textureHeights[0] = size.height();
+ m_textureOffsets[0] = 0;
+}
+
+void QVideoSurfaceGLPainter::initYuv420PTextureInfo(const QSize &size)
+{
+ int w = (size.width() + 3) & ~3;
+ int w2 = (size.width()/2 + 3) & ~3;
+
+ m_yuv = true;
+ m_textureInternalFormat = GL_LUMINANCE;
+ m_textureFormat = GL_LUMINANCE;
+ m_textureType = GL_UNSIGNED_BYTE;
+ m_textureCount = 3;
+ m_textureWidths[0] = size.width();
+ m_textureHeights[0] = size.height();
+ m_textureOffsets[0] = 0;
+ m_textureWidths[1] = size.width() / 2;
+ m_textureHeights[1] = size.height() / 2;
+ m_textureOffsets[1] = w * size.height();
+ m_textureWidths[2] = size.width() / 2;
+ m_textureHeights[2] = size.height() / 2;
+ m_textureOffsets[2] = w * size.height() + w2 * (size.height() / 2);
+}
+
+void QVideoSurfaceGLPainter::initYv12TextureInfo(const QSize &size)
+{
+ int w = (size.width() + 3) & ~3;
+ int w2 = (size.width()/2 + 3) & ~3;
+
+ m_yuv = true;
+ m_textureInternalFormat = GL_LUMINANCE;
+ m_textureFormat = GL_LUMINANCE;
+ m_textureType = GL_UNSIGNED_BYTE;
+ m_textureCount = 3;
+ m_textureWidths[0] = size.width();
+ m_textureHeights[0] = size.height();
+ m_textureOffsets[0] = 0;
+ m_textureWidths[1] = size.width() / 2;
+ m_textureHeights[1] = size.height() / 2;
+ m_textureOffsets[1] = w * size.height() + w2 * (size.height() / 2);
+ m_textureWidths[2] = size.width() / 2;
+ m_textureHeights[2] = size.height() / 2;
+ m_textureOffsets[2] = w * size.height();
+}
+
+#ifndef QT_OPENGL_ES
+
+# ifndef GL_FRAGMENT_PROGRAM_ARB
+# define GL_FRAGMENT_PROGRAM_ARB 0x8804
+# define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875
+# endif
+
+// Paints an RGB32 frame
+static const char *qt_arbfp_xrgbShaderProgram =
+ "!!ARBfp1.0\n"
+ "PARAM matrix[4] = { program.local[0..2],"
+ "{ 0.0, 0.0, 0.0, 1.0 } };\n"
+ "TEMP xrgb;\n"
+ "TEX xrgb.xyz, fragment.texcoord[0], texture[0], 2D;\n"
+ "MOV xrgb.w, matrix[3].w;\n"
+ "DP4 result.color.x, xrgb.zyxw, matrix[0];\n"
+ "DP4 result.color.y, xrgb.zyxw, matrix[1];\n"
+ "DP4 result.color.z, xrgb.zyxw, matrix[2];\n"
+ "END";
+
+// Paints an ARGB frame.
+static const char *qt_arbfp_argbShaderProgram =
+ "!!ARBfp1.0\n"
+ "PARAM matrix[4] = { program.local[0..2],"
+ "{ 0.0, 0.0, 0.0, 1.0 } };\n"
+ "TEMP argb;\n"
+ "TEX argb, fragment.texcoord[0], texture[0], 2D;\n"
+ "MOV argb.w, matrix[3].w;\n"
+ "DP4 result.color.x, argb.zyxw, matrix[0];\n"
+ "DP4 result.color.y, argb.zyxw, matrix[1];\n"
+ "DP4 result.color.z, argb.zyxw, matrix[2];\n"
+ "TEX result.color.w, fragment.texcoord[0], texture, 2D;\n"
+ "END";
+
+// Paints an RGB(A) frame.
+static const char *qt_arbfp_rgbShaderProgram =
+ "!!ARBfp1.0\n"
+ "PARAM matrix[4] = { program.local[0..2],"
+ "{ 0.0, 0.0, 0.0, 1.0 } };\n"
+ "TEMP rgb;\n"
+ "TEX rgb, fragment.texcoord[0], texture[0], 2D;\n"
+ "MOV rgb.w, matrix[3].w;\n"
+ "DP4 result.color.x, rgb, matrix[0];\n"
+ "DP4 result.color.y, rgb, matrix[1];\n"
+ "DP4 result.color.z, rgb, matrix[2];\n"
+ "TEX result.color.w, fragment.texcoord[0], texture, 2D;\n"
+ "END";
+
+// Paints a YUV420P or YV12 frame.
+static const char *qt_arbfp_yuvPlanarShaderProgram =
+ "!!ARBfp1.0\n"
+ "PARAM matrix[4] = { program.local[0..2],"
+ "{ 0.0, 0.0, 0.0, 1.0 } };\n"
+ "TEMP yuv;\n"
+ "TEX yuv.x, fragment.texcoord[0], texture[0], 2D;\n"
+ "TEX yuv.y, fragment.texcoord[0], texture[1], 2D;\n"
+ "TEX yuv.z, fragment.texcoord[0], texture[2], 2D;\n"
+ "MOV yuv.w, matrix[3].w;\n"
+ "DP4 result.color.x, yuv, matrix[0];\n"
+ "DP4 result.color.y, yuv, matrix[1];\n"
+ "DP4 result.color.z, yuv, matrix[2];\n"
+ "END";
+
+// Paints a YUV444 frame.
+static const char *qt_arbfp_xyuvShaderProgram =
+ "!!ARBfp1.0\n"
+ "PARAM matrix[4] = { program.local[0..2],"
+ "{ 0.0, 0.0, 0.0, 1.0 } };\n"
+ "TEMP ayuv;\n"
+ "TEX ayuv, fragment.texcoord[0], texture[0], 2D;\n"
+ "MOV ayuv.x, matrix[3].w;\n"
+ "DP4 result.color.x, ayuv.yzwx, matrix[0];\n"
+ "DP4 result.color.y, ayuv.yzwx, matrix[1];\n"
+ "DP4 result.color.z, ayuv.yzwx, matrix[2];\n"
+ "END";
+
+// Paints a AYUV444 frame.
+static const char *qt_arbfp_ayuvShaderProgram =
+ "!!ARBfp1.0\n"
+ "PARAM matrix[4] = { program.local[0..2],"
+ "{ 0.0, 0.0, 0.0, 1.0 } };\n"
+ "TEMP ayuv;\n"
+ "TEX ayuv, fragment.texcoord[0], texture[0], 2D;\n"
+ "MOV ayuv.x, matrix[3].w;\n"
+ "DP4 result.color.x, ayuv.yzwx, matrix[0];\n"
+ "DP4 result.color.y, ayuv.yzwx, matrix[1];\n"
+ "DP4 result.color.z, ayuv.yzwx, matrix[2];\n"
+ "TEX result.color.w, fragment.texcoord[0], texture, 2D;\n"
+ "END";
+
+class QVideoSurfaceArbFpPainter : public QVideoSurfaceGLPainter
+{
+public:
+ QVideoSurfaceArbFpPainter(QGLContext *context);
+
+ QAbstractVideoSurface::Error start(const QVideoSurfaceFormat &format);
+ void stop();
+
+ QAbstractVideoSurface::Error paint(
+ const QRectF &target, QPainter *painter, const QRectF &source);
+
+private:
+ typedef void (APIENTRY *_glProgramStringARB) (GLenum, GLenum, GLsizei, const GLvoid *);
+ typedef void (APIENTRY *_glBindProgramARB) (GLenum, GLuint);
+ typedef void (APIENTRY *_glDeleteProgramsARB) (GLsizei, const GLuint *);
+ typedef void (APIENTRY *_glGenProgramsARB) (GLsizei, GLuint *);
+ typedef void (APIENTRY *_glProgramLocalParameter4fARB) (
+ GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat);
+ typedef void (APIENTRY *_glActiveTexture) (GLenum);
+
+ _glProgramStringARB glProgramStringARB;
+ _glBindProgramARB glBindProgramARB;
+ _glDeleteProgramsARB glDeleteProgramsARB;
+ _glGenProgramsARB glGenProgramsARB;
+ _glProgramLocalParameter4fARB glProgramLocalParameter4fARB;
+
+ GLuint m_programId;
+ QSize m_frameSize;
+};
+
+QVideoSurfaceArbFpPainter::QVideoSurfaceArbFpPainter(QGLContext *context)
+ : QVideoSurfaceGLPainter(context)
+ , m_programId(0)
+{
+ glProgramStringARB = (_glProgramStringARB) m_context->getProcAddress(
+ QLatin1String("glProgramStringARB"));
+ glBindProgramARB = (_glBindProgramARB) m_context->getProcAddress(
+ QLatin1String("glBindProgramARB"));
+ glDeleteProgramsARB = (_glDeleteProgramsARB) m_context->getProcAddress(
+ QLatin1String("glDeleteProgramsARB"));
+ glGenProgramsARB = (_glGenProgramsARB) m_context->getProcAddress(
+ QLatin1String("glGenProgramsARB"));
+ glProgramLocalParameter4fARB = (_glProgramLocalParameter4fARB) m_context->getProcAddress(
+ QLatin1String("glProgramLocalParameter4fARB"));
+
+ m_imagePixelFormats
+ << QVideoFrame::Format_RGB32
+ << QVideoFrame::Format_BGR32
+ << QVideoFrame::Format_ARGB32
+ << QVideoFrame::Format_RGB24
+ << QVideoFrame::Format_BGR24
+ << QVideoFrame::Format_RGB565
+ << QVideoFrame::Format_AYUV444
+ << QVideoFrame::Format_YUV444
+ << QVideoFrame::Format_YV12
+ << QVideoFrame::Format_YUV420P;
+ m_glPixelFormats
+ << QVideoFrame::Format_RGB32
+ << QVideoFrame::Format_ARGB32;
+}
+
+QAbstractVideoSurface::Error QVideoSurfaceArbFpPainter::start(const QVideoSurfaceFormat &format)
+{
+ Q_ASSERT(m_textureCount == 0);
+
+ QAbstractVideoSurface::Error error = QAbstractVideoSurface::NoError;
+
+ m_context->makeCurrent();
+
+ const char *program = 0;
+
+ if (format.handleType() == QAbstractVideoBuffer::NoHandle) {
+ switch (format.pixelFormat()) {
+ case QVideoFrame::Format_RGB32:
+ initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
+ program = qt_arbfp_xrgbShaderProgram;
+ break;
+ case QVideoFrame::Format_BGR32:
+ initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
+ program = qt_arbfp_rgbShaderProgram;
+ break;
+ case QVideoFrame::Format_ARGB32:
+ initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
+ program = qt_arbfp_argbShaderProgram;
+ break;
+ case QVideoFrame::Format_RGB24:
+ initRgbTextureInfo(GL_RGB8, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
+ program = qt_arbfp_rgbShaderProgram;
+ break;
+ case QVideoFrame::Format_BGR24:
+ initRgbTextureInfo(GL_RGB8, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
+ program = qt_arbfp_xrgbShaderProgram;
+ break;
+ case QVideoFrame::Format_RGB565:
+ initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, format.frameSize());
+ program = qt_arbfp_rgbShaderProgram;
+ break;
+ case QVideoFrame::Format_YUV444:
+ initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, format.frameSize());
+ program = qt_arbfp_xyuvShaderProgram;
+ m_yuv = true;
+ break;
+ case QVideoFrame::Format_AYUV444:
+ initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
+ program = qt_arbfp_ayuvShaderProgram;
+ m_yuv = true;
+ break;
+ case QVideoFrame::Format_YV12:
+ initYv12TextureInfo(format.frameSize());
+ program = qt_arbfp_yuvPlanarShaderProgram;
+ break;
+ case QVideoFrame::Format_YUV420P:
+ initYuv420PTextureInfo(format.frameSize());
+ program = qt_arbfp_yuvPlanarShaderProgram;
+ break;
+ default:
+ break;
+ }
+ } else if (format.handleType() == QAbstractVideoBuffer::GLTextureHandle) {
+ switch (format.pixelFormat()) {
+ case QVideoFrame::Format_RGB32:
+ case QVideoFrame::Format_ARGB32:
+ m_yuv = false;
+ m_textureCount = 1;
+ program = qt_arbfp_rgbShaderProgram;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (!program) {
+ error = QAbstractVideoSurface::UnsupportedFormatError;
+ } else {
+ glGenProgramsARB(1, &m_programId);
+
+ GLenum glError = glGetError();
+ if (glError != GL_NO_ERROR) {
+ qWarning("QPainterVideoSurface: ARBfb Shader allocation error %x", int(glError));
+ m_textureCount = 0;
+ m_programId = 0;
+
+ error = QAbstractVideoSurface::ResourceError;
+ } else {
+ glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, m_programId);
+ glProgramStringARB(
+ GL_FRAGMENT_PROGRAM_ARB,
+ GL_PROGRAM_FORMAT_ASCII_ARB,
+ qstrlen(program),
+ reinterpret_cast<const GLvoid *>(program));
+
+ if ((glError = glGetError()) != GL_NO_ERROR) {
+ const GLubyte* errorString = glGetString(GL_PROGRAM_ERROR_STRING_ARB);
+
+ qWarning("QPainterVideoSurface: ARBfp Shader compile error %x, %s",
+ int(glError),
+ reinterpret_cast<const char *>(errorString));
+ glDeleteProgramsARB(1, &m_programId);
+
+ m_textureCount = 0;
+ m_programId = 0;
+
+ error = QAbstractVideoSurface::ResourceError;
+ } else {
+ m_handleType = format.handleType();
+ m_scanLineDirection = format.scanLineDirection();
+ m_frameSize = format.frameSize();
+
+ if (m_handleType == QAbstractVideoBuffer::NoHandle)
+ glGenTextures(m_textureCount, m_textureIds);
+ }
+ }
+ }
+
+ return error;
+}
+
+void QVideoSurfaceArbFpPainter::stop()
+{
+ m_context->makeCurrent();
+
+ if (m_handleType != QAbstractVideoBuffer::GLTextureHandle)
+ glDeleteTextures(m_textureCount, m_textureIds);
+ glDeleteProgramsARB(1, &m_programId);
+
+ m_textureCount = 0;
+ m_programId = 0;
+ m_handleType = QAbstractVideoBuffer::NoHandle;
+}
+
+QAbstractVideoSurface::Error QVideoSurfaceArbFpPainter::paint(
+ const QRectF &target, QPainter *painter, const QRectF &source)
+{
+ if (m_frame.isValid()) {
+ bool stencilTestEnabled = glIsEnabled(GL_STENCIL_TEST);
+ bool scissorTestEnabled = glIsEnabled(GL_SCISSOR_TEST);
+
+ painter->beginNativePainting();
+
+ if (stencilTestEnabled)
+ glEnable(GL_STENCIL_TEST);
+ if (scissorTestEnabled)
+ glEnable(GL_SCISSOR_TEST);
+
+ const float txLeft = source.left() / m_frameSize.width();
+ const float txRight = source.right() / m_frameSize.width();
+ const float txTop = m_scanLineDirection == QVideoSurfaceFormat::TopToBottom
+ ? source.top() / m_frameSize.height()
+ : source.bottom() / m_frameSize.height();
+ const float txBottom = m_scanLineDirection == QVideoSurfaceFormat::TopToBottom
+ ? source.bottom() / m_frameSize.height()
+ : source.top() / m_frameSize.height();
+
+
+ const float tx_array[] =
+ {
+ txLeft , txBottom,
+ txRight, txBottom,
+ txLeft , txTop,
+ txRight, txTop
+ };
+ const float v_array[] =
+ {
+ float(target.left()) , float(target.bottom() + 1),
+ float(target.right() + 1), float(target.bottom() + 1),
+ float(target.left()) , float(target.top()),
+ float(target.right() + 1), float(target.top())
+ };
+
+ glEnable(GL_FRAGMENT_PROGRAM_ARB);
+ glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, m_programId);
+
+ glProgramLocalParameter4fARB(
+ GL_FRAGMENT_PROGRAM_ARB,
+ 0,
+ m_colorMatrix(0, 0),
+ m_colorMatrix(0, 1),
+ m_colorMatrix(0, 2),
+ m_colorMatrix(0, 3));
+ glProgramLocalParameter4fARB(
+ GL_FRAGMENT_PROGRAM_ARB,
+ 1,
+ m_colorMatrix(1, 0),
+ m_colorMatrix(1, 1),
+ m_colorMatrix(1, 2),
+ m_colorMatrix(1, 3));
+ glProgramLocalParameter4fARB(
+ GL_FRAGMENT_PROGRAM_ARB,
+ 2,
+ m_colorMatrix(2, 0),
+ m_colorMatrix(2, 1),
+ m_colorMatrix(2, 2),
+ m_colorMatrix(2, 3));
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, m_textureIds[0]);
+
+ if (m_textureCount == 3) {
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, m_textureIds[1]);
+ glActiveTexture(GL_TEXTURE2);
+ glBindTexture(GL_TEXTURE_2D, m_textureIds[2]);
+ glActiveTexture(GL_TEXTURE0);
+ }
+
+ glVertexPointer(2, GL_FLOAT, 0, v_array);
+ glTexCoordPointer(2, GL_FLOAT, 0, tx_array);
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisable(GL_FRAGMENT_PROGRAM_ARB);
+
+ painter->endNativePainting();
+ }
+ return QAbstractVideoSurface::NoError;
+}
+
+#endif
+
+static const char *qt_glsl_vertexShaderProgram =
+ "attribute highp vec4 vertexCoordArray;\n"
+ "attribute highp vec2 textureCoordArray;\n"
+ "uniform highp mat4 positionMatrix;\n"
+ "varying highp vec2 textureCoord;\n"
+ "void main(void)\n"
+ "{\n"
+ " gl_Position = positionMatrix * vertexCoordArray;\n"
+ " textureCoord = textureCoordArray;\n"
+ "}\n";
+
+// Paints an RGB32 frame
+static const char *qt_glsl_xrgbShaderProgram =
+ "uniform sampler2D texRgb;\n"
+ "uniform mediump mat4 colorMatrix;\n"
+ "varying highp vec2 textureCoord;\n"
+ "void main(void)\n"
+ "{\n"
+ " highp vec4 color = vec4(texture2D(texRgb, textureCoord.st).bgr, 1.0);\n"
+ " gl_FragColor = colorMatrix * color;\n"
+ "}\n";
+
+// Paints an ARGB frame.
+static const char *qt_glsl_argbShaderProgram =
+ "uniform sampler2D texRgb;\n"
+ "uniform mediump mat4 colorMatrix;\n"
+ "varying highp vec2 textureCoord;\n"
+ "void main(void)\n"
+ "{\n"
+ " highp vec4 color = vec4(texture2D(texRgb, textureCoord.st).bgr, 1.0);\n"
+ " color = colorMatrix * color;\n"
+ " gl_FragColor = vec4(color.rgb, texture2D(texRgb, textureCoord.st).a);\n"
+ "}\n";
+
+// Paints an RGB(A) frame.
+static const char *qt_glsl_rgbShaderProgram =
+ "uniform sampler2D texRgb;\n"
+ "uniform mediump mat4 colorMatrix;\n"
+ "varying highp vec2 textureCoord;\n"
+ "void main(void)\n"
+ "{\n"
+ " highp vec4 color = vec4(texture2D(texRgb, textureCoord.st).rgb, 1.0);\n"
+ " color = colorMatrix * color;\n"
+ " gl_FragColor = vec4(color.rgb, texture2D(texRgb, textureCoord.st).a);\n"
+ "}\n";
+
+// Paints a YUV420P or YV12 frame.
+static const char *qt_glsl_yuvPlanarShaderProgram =
+ "uniform sampler2D texY;\n"
+ "uniform sampler2D texU;\n"
+ "uniform sampler2D texV;\n"
+ "uniform mediump mat4 colorMatrix;\n"
+ "varying highp vec2 textureCoord;\n"
+ "void main(void)\n"
+ "{\n"
+ " highp vec4 color = vec4(\n"
+ " texture2D(texY, textureCoord.st).r,\n"
+ " texture2D(texU, textureCoord.st).r,\n"
+ " texture2D(texV, textureCoord.st).r,\n"
+ " 1.0);\n"
+ " gl_FragColor = colorMatrix * color;\n"
+ "}\n";
+
+// Paints a YUV444 frame.
+static const char *qt_glsl_xyuvShaderProgram =
+ "uniform sampler2D texRgb;\n"
+ "uniform mediump mat4 colorMatrix;\n"
+ "varying highp vec2 textureCoord;\n"
+ "void main(void)\n"
+ "{\n"
+ " highp vec4 color = vec4(texture2D(texRgb, textureCoord.st).gba, 1.0);\n"
+ " gl_FragColor = colorMatrix * color;\n"
+ "}\n";
+
+// Paints a AYUV444 frame.
+static const char *qt_glsl_ayuvShaderProgram =
+ "uniform sampler2D texRgb;\n"
+ "uniform mediump mat4 colorMatrix;\n"
+ "varying highp vec2 textureCoord;\n"
+ "void main(void)\n"
+ "{\n"
+ " highp vec4 color = vec4(texture2D(texRgb, textureCoord.st).gba, 1.0);\n"
+ " color = colorMatrix * color;\n"
+ " gl_FragColor = vec4(color.rgb, texture2D(texRgb, textureCoord.st).r);\n"
+ "}\n";
+
+class QVideoSurfaceGlslPainter : public QVideoSurfaceGLPainter
+{
+public:
+ QVideoSurfaceGlslPainter(QGLContext *context);
+
+ QAbstractVideoSurface::Error start(const QVideoSurfaceFormat &format);
+ void stop();
+
+ QAbstractVideoSurface::Error paint(
+ const QRectF &target, QPainter *painter, const QRectF &source);
+
+private:
+ QGLShaderProgram m_program;
+ QSize m_frameSize;
+};
+
+QVideoSurfaceGlslPainter::QVideoSurfaceGlslPainter(QGLContext *context)
+ : QVideoSurfaceGLPainter(context)
+ , m_program(context)
+{
+ m_imagePixelFormats
+ << QVideoFrame::Format_RGB32
+ << QVideoFrame::Format_BGR32
+ << QVideoFrame::Format_ARGB32
+#ifndef QT_OPENGL_ES
+ << QVideoFrame::Format_RGB24
+ << QVideoFrame::Format_BGR24
+#endif
+ << QVideoFrame::Format_RGB565
+ << QVideoFrame::Format_YUV444
+ << QVideoFrame::Format_AYUV444
+ << QVideoFrame::Format_YV12
+ << QVideoFrame::Format_YUV420P;
+ m_glPixelFormats
+ << QVideoFrame::Format_RGB32
+ << QVideoFrame::Format_ARGB32;
+}
+
+QAbstractVideoSurface::Error QVideoSurfaceGlslPainter::start(const QVideoSurfaceFormat &format)
+{
+ Q_ASSERT(m_textureCount == 0);
+
+ QAbstractVideoSurface::Error error = QAbstractVideoSurface::NoError;
+
+ m_context->makeCurrent();
+
+ const char *fragmentProgram = 0;
+
+ if (format.handleType() == QAbstractVideoBuffer::NoHandle) {
+ switch (format.pixelFormat()) {
+ case QVideoFrame::Format_RGB32:
+ initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
+ fragmentProgram = qt_glsl_xrgbShaderProgram;
+ break;
+ case QVideoFrame::Format_BGR32:
+ initRgbTextureInfo(GL_RGB, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
+ fragmentProgram = qt_glsl_rgbShaderProgram;
+ break;
+ case QVideoFrame::Format_ARGB32:
+ initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
+ fragmentProgram = qt_glsl_argbShaderProgram;
+ break;
+#ifndef QT_OPENGL_ES
+ case QVideoFrame::Format_RGB24:
+ initRgbTextureInfo(GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE, format.frameSize());
+ fragmentProgram = qt_glsl_rgbShaderProgram;
+ break;
+ case QVideoFrame::Format_BGR24:
+ initRgbTextureInfo(GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE, format.frameSize());
+ fragmentProgram = qt_glsl_argbShaderProgram;
+ break;
+#endif
+ case QVideoFrame::Format_RGB565:
+ initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, format.frameSize());
+ fragmentProgram = qt_glsl_rgbShaderProgram;
+ break;
+ case QVideoFrame::Format_YUV444:
+ initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, format.frameSize());
+ fragmentProgram = qt_glsl_xyuvShaderProgram;
+ m_yuv = true;
+ break;
+ case QVideoFrame::Format_AYUV444:
+ initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
+ fragmentProgram = qt_glsl_ayuvShaderProgram;
+ m_yuv = true;
+ break;
+ case QVideoFrame::Format_YV12:
+ initYv12TextureInfo(format.frameSize());
+ fragmentProgram = qt_glsl_yuvPlanarShaderProgram;
+ break;
+ case QVideoFrame::Format_YUV420P:
+ initYuv420PTextureInfo(format.frameSize());
+ fragmentProgram = qt_glsl_yuvPlanarShaderProgram;
+ break;
+ default:
+ break;
+ }
+ } else if (format.handleType() == QAbstractVideoBuffer::GLTextureHandle) {
+ switch (format.pixelFormat()) {
+ case QVideoFrame::Format_RGB32:
+ case QVideoFrame::Format_ARGB32:
+ m_yuv = false;
+ m_textureCount = 1;
+ fragmentProgram = qt_glsl_rgbShaderProgram;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (!fragmentProgram) {
+ error = QAbstractVideoSurface::UnsupportedFormatError;
+ } else if (!m_program.addShaderFromSourceCode(QGLShader::Vertex, qt_glsl_vertexShaderProgram)) {
+ qWarning("QPainterVideoSurface: Vertex shader compile error %s",
+ qPrintable(m_program.log()));
+ error = QAbstractVideoSurface::ResourceError;
+ } else if (!m_program.addShaderFromSourceCode(QGLShader::Fragment, fragmentProgram)) {
+ qWarning("QPainterVideoSurface: Shader compile error %s", qPrintable(m_program.log()));
+ error = QAbstractVideoSurface::ResourceError;
+ m_program.removeAllShaders();
+ } else if(!m_program.link()) {
+ qWarning("QPainterVideoSurface: Shader link error %s", qPrintable(m_program.log()));
+ m_program.removeAllShaders();
+ error = QAbstractVideoSurface::ResourceError;
+ } else {
+ m_handleType = format.handleType();
+ m_scanLineDirection = format.scanLineDirection();
+ m_frameSize = format.frameSize();
+
+ if (m_handleType == QAbstractVideoBuffer::NoHandle)
+ glGenTextures(m_textureCount, m_textureIds);
+ }
+
+ return error;
+}
+
+void QVideoSurfaceGlslPainter::stop()
+{
+ m_context->makeCurrent();
+
+ if (m_handleType != QAbstractVideoBuffer::GLTextureHandle)
+ glDeleteTextures(m_textureCount, m_textureIds);
+ m_program.removeAllShaders();
+
+ m_textureCount = 0;
+ m_handleType = QAbstractVideoBuffer::NoHandle;
+}
+
+QAbstractVideoSurface::Error QVideoSurfaceGlslPainter::paint(
+ const QRectF &target, QPainter *painter, const QRectF &source)
+{
+ if (m_frame.isValid()) {
+ bool stencilTestEnabled = glIsEnabled(GL_STENCIL_TEST);
+ bool scissorTestEnabled = glIsEnabled(GL_SCISSOR_TEST);
+
+ painter->beginNativePainting();
+
+ if (stencilTestEnabled)
+ glEnable(GL_STENCIL_TEST);
+ if (scissorTestEnabled)
+ glEnable(GL_SCISSOR_TEST);
+
+ const int width = QGLContext::currentContext()->device()->width();
+ const int height = QGLContext::currentContext()->device()->height();
+
+ const QTransform transform = painter->deviceTransform();
+
+ const GLfloat wfactor = 2.0 / width;
+ const GLfloat hfactor = -2.0 / height;
+
+ const GLfloat positionMatrix[4][4] =
+ {
+ {
+ /*(0,0)*/ GLfloat(wfactor * transform.m11() - transform.m13()),
+ /*(0,1)*/ GLfloat(hfactor * transform.m12() + transform.m13()),
+ /*(0,2)*/ 0.0,
+ /*(0,3)*/ GLfloat(transform.m13())
+ }, {
+ /*(1,0)*/ GLfloat(wfactor * transform.m21() - transform.m23()),
+ /*(1,1)*/ GLfloat(hfactor * transform.m22() + transform.m23()),
+ /*(1,2)*/ 0.0,
+ /*(1,3)*/ GLfloat(transform.m23())
+ }, {
+ /*(2,0)*/ 0.0,
+ /*(2,1)*/ 0.0,
+ /*(2,2)*/ -1.0,
+ /*(2,3)*/ 0.0
+ }, {
+ /*(3,0)*/ GLfloat(wfactor * transform.dx() - transform.m33()),
+ /*(3,1)*/ GLfloat(hfactor * transform.dy() + transform.m33()),
+ /*(3,2)*/ 0.0,
+ /*(3,3)*/ GLfloat(transform.m33())
+ }
+ };
+
+ const GLfloat vertexCoordArray[] =
+ {
+ GLfloat(target.left()) , GLfloat(target.bottom() + 1),
+ GLfloat(target.right() + 1), GLfloat(target.bottom() + 1),
+ GLfloat(target.left()) , GLfloat(target.top()),
+ GLfloat(target.right() + 1), GLfloat(target.top())
+ };
+
+ const GLfloat txLeft = source.left() / m_frameSize.width();
+ const GLfloat txRight = source.right() / m_frameSize.width();
+ const GLfloat txTop = m_scanLineDirection == QVideoSurfaceFormat::TopToBottom
+ ? source.top() / m_frameSize.height()
+ : source.bottom() / m_frameSize.height();
+ const GLfloat txBottom = m_scanLineDirection == QVideoSurfaceFormat::TopToBottom
+ ? source.bottom() / m_frameSize.height()
+ : source.top() / m_frameSize.height();
+
+ const GLfloat textureCoordArray[] =
+ {
+ txLeft , txBottom,
+ txRight, txBottom,
+ txLeft , txTop,
+ txRight, txTop
+ };
+
+ m_program.bind();
+
+ m_program.enableAttributeArray("vertexCoordArray");
+ m_program.enableAttributeArray("textureCoordArray");
+ m_program.setAttributeArray("vertexCoordArray", vertexCoordArray, 2);
+ m_program.setAttributeArray("textureCoordArray", textureCoordArray, 2);
+ m_program.setUniformValue("positionMatrix", positionMatrix);
+
+ if (m_textureCount == 3) {
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, m_textureIds[0]);
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, m_textureIds[1]);
+ glActiveTexture(GL_TEXTURE2);
+ glBindTexture(GL_TEXTURE_2D, m_textureIds[2]);
+ glActiveTexture(GL_TEXTURE0);
+
+ m_program.setUniformValue("texY", GLint(0));
+ m_program.setUniformValue("texU", GLint(1));
+ m_program.setUniformValue("texV", GLint(2));
+ } else {
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, m_textureIds[0]);
+
+ m_program.setUniformValue("texRgb", GLint(0));
+ }
+ m_program.setUniformValue("colorMatrix", m_colorMatrix);
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+ m_program.release();
+
+ painter->endNativePainting();
+ }
+ return QAbstractVideoSurface::NoError;
+}
+
+#endif
+
+/*!
+ \class QPainterVideoSurface
+ \internal
+*/
+
+/*!
+*/
+QPainterVideoSurface::QPainterVideoSurface(QObject *parent)
+ : QAbstractVideoSurface(parent)
+ , m_painter(0)
+#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_1_CL) && !defined(QT_OPENGL_ES_1)
+ , m_glContext(0)
+ , m_shaderTypes(NoShaders)
+ , m_shaderType(NoShaders)
+#endif
+ , m_brightness(0)
+ , m_contrast(0)
+ , m_hue(0)
+ , m_saturation(0)
+ , m_pixelFormat(QVideoFrame::Format_Invalid)
+ , m_colorsDirty(true)
+ , m_ready(false)
+{
+}
+
+/*!
+*/
+QPainterVideoSurface::~QPainterVideoSurface()
+{
+ if (isActive())
+ m_painter->stop();
+
+ delete m_painter;
+}
+
+/*!
+*/
+QList<QVideoFrame::PixelFormat> QPainterVideoSurface::supportedPixelFormats(
+ QAbstractVideoBuffer::HandleType handleType) const
+{
+ if (!m_painter)
+ const_cast<QPainterVideoSurface *>(this)->createPainter();
+
+ return m_painter->supportedPixelFormats(handleType);
+}
+
+/*!
+*/
+bool QPainterVideoSurface::isFormatSupported(
+ const QVideoSurfaceFormat &format, QVideoSurfaceFormat *similar) const
+{
+ if (!m_painter)
+ const_cast<QPainterVideoSurface *>(this)->createPainter();
+
+ return m_painter->isFormatSupported(format, similar);
+}
+
+/*!
+*/
+bool QPainterVideoSurface::start(const QVideoSurfaceFormat &format)
+{
+ if (isActive())
+ m_painter->stop();
+
+ if (!m_painter)
+ createPainter();
+
+ if (format.frameSize().isEmpty()) {
+ setError(UnsupportedFormatError);
+ } else {
+ QAbstractVideoSurface::Error error = m_painter->start(format);
+
+ if (error != QAbstractVideoSurface::NoError) {
+ setError(error);
+ } else {
+ m_pixelFormat = format.pixelFormat();
+ m_frameSize = format.frameSize();
+ m_sourceRect = format.viewport();
+ m_colorsDirty = true;
+ m_ready = true;
+
+ return QAbstractVideoSurface::start(format);
+ }
+ }
+
+ QAbstractVideoSurface::stop();
+
+ return false;
+}
+
+/*!
+*/
+void QPainterVideoSurface::stop()
+{
+ if (isActive()) {
+ m_painter->stop();
+ m_ready = false;
+
+ QAbstractVideoSurface::stop();
+ }
+}
+
+/*!
+*/
+bool QPainterVideoSurface::present(const QVideoFrame &frame)
+{
+ if (!m_ready) {
+ if (!isActive())
+ setError(StoppedError);
+ } else if (frame.isValid()
+ && (frame.pixelFormat() != m_pixelFormat || frame.size() != m_frameSize)) {
+ setError(IncorrectFormatError);
+
+ stop();
+ } else {
+ QAbstractVideoSurface::Error error = m_painter->setCurrentFrame(frame);
+
+ if (error != QAbstractVideoSurface::NoError) {
+ setError(error);
+
+ stop();
+ } else {
+ m_ready = false;
+
+ emit frameChanged();
+
+ return true;
+ }
+ }
+ return false;
+}
+
+/*!
+*/
+int QPainterVideoSurface::brightness() const
+{
+ return m_brightness;
+}
+
+/*!
+*/
+void QPainterVideoSurface::setBrightness(int brightness)
+{
+ m_brightness = brightness;
+
+ m_colorsDirty = true;
+}
+
+/*!
+*/
+int QPainterVideoSurface::contrast() const
+{
+ return m_contrast;
+}
+
+/*!
+*/
+void QPainterVideoSurface::setContrast(int contrast)
+{
+ m_contrast = contrast;
+
+ m_colorsDirty = true;
+}
+
+/*!
+*/
+int QPainterVideoSurface::hue() const
+{
+ return m_hue;
+}
+
+/*!
+*/
+void QPainterVideoSurface::setHue(int hue)
+{
+ m_hue = hue;
+
+ m_colorsDirty = true;
+}
+
+/*!
+*/
+int QPainterVideoSurface::saturation() const
+{
+ return m_saturation;
+}
+
+/*!
+*/
+void QPainterVideoSurface::setSaturation(int saturation)
+{
+ m_saturation = saturation;
+
+ m_colorsDirty = true;
+}
+
+/*!
+*/
+bool QPainterVideoSurface::isReady() const
+{
+ return m_ready;
+}
+
+/*!
+*/
+void QPainterVideoSurface::setReady(bool ready)
+{
+ m_ready = ready;
+}
+
+/*!
+*/
+void QPainterVideoSurface::paint(QPainter *painter, const QRectF &target, const QRectF &source)
+{
+ if (!isActive()) {
+ painter->fillRect(target, QBrush(Qt::black));
+ } else {
+ if (m_colorsDirty) {
+ m_painter->updateColors(m_brightness, m_contrast, m_hue, m_saturation);
+ m_colorsDirty = false;
+ }
+
+ const QRectF sourceRect(
+ m_sourceRect.x() + m_sourceRect.width() * source.x(),
+ m_sourceRect.y() + m_sourceRect.height() * source.y(),
+ m_sourceRect.width() * source.width(),
+ m_sourceRect.height() * source.height());
+
+ QAbstractVideoSurface::Error error = m_painter->paint(target, painter, sourceRect);
+
+ if (error != QAbstractVideoSurface::NoError) {
+ setError(error);
+
+ stop();
+ }
+ }
+}
+
+/*!
+ \fn QPainterVideoSurface::frameChanged()
+*/
+
+#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_1_CL) && !defined(QT_OPENGL_ES_1)
+
+/*!
+*/
+const QGLContext *QPainterVideoSurface::glContext() const
+{
+ return m_glContext;
+}
+
+/*!
+*/
+void QPainterVideoSurface::setGLContext(QGLContext *context)
+{
+ if (m_glContext == context)
+ return;
+
+ m_glContext = context;
+
+ m_shaderTypes = NoShaders;
+
+ if (m_glContext) {
+ m_glContext->makeCurrent();
+
+ const QByteArray extensions(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)));
+#ifndef QT_OPENGL_ES
+
+ if (extensions.contains("ARB_fragment_program"))
+ m_shaderTypes |= FragmentProgramShader;
+#endif
+
+ if (QGLShaderProgram::hasOpenGLShaderPrograms(m_glContext)
+ && extensions.contains("ARB_shader_objects"))
+ m_shaderTypes |= GlslShader;
+ }
+
+ ShaderType type = (m_shaderType & m_shaderTypes)
+ ? m_shaderType
+ : NoShaders;
+
+ if (type != m_shaderType || type != NoShaders) {
+ m_shaderType = type;
+
+ if (isActive()) {
+ m_painter->stop();
+ delete m_painter;
+ m_painter = 0;
+ m_ready = false;
+
+ setError(ResourceError);
+ QAbstractVideoSurface::stop();
+ }
+ emit supportedFormatsChanged();
+ }
+}
+
+/*!
+ \enum QPainterVideoSurface::ShaderType
+
+ \value NoShaders
+ \value FragmentProgramShader
+ \value HlslShader
+*/
+
+/*!
+ \typedef QPainterVideoSurface::ShaderTypes
+*/
+
+/*!
+*/
+QPainterVideoSurface::ShaderTypes QPainterVideoSurface::supportedShaderTypes() const
+{
+ return m_shaderTypes;
+}
+
+/*!
+*/
+QPainterVideoSurface::ShaderType QPainterVideoSurface::shaderType() const
+{
+ return m_shaderType;
+}
+
+/*!
+*/
+void QPainterVideoSurface::setShaderType(ShaderType type)
+{
+ if (!(type & m_shaderTypes))
+ type = NoShaders;
+
+ if (type != m_shaderType) {
+ m_shaderType = type;
+
+ if (isActive()) {
+ m_painter->stop();
+ delete m_painter;
+ m_painter = 0;
+ m_ready = false;
+
+ setError(ResourceError);
+ QAbstractVideoSurface::stop();
+ } else {
+ delete m_painter;
+ m_painter = 0;
+ }
+ emit supportedFormatsChanged();
+ }
+}
+
+#endif
+
+void QPainterVideoSurface::createPainter()
+{
+ Q_ASSERT(!m_painter);
+
+#ifdef Q_WS_MAC
+ if (m_glContext)
+ m_glContext->makeCurrent();
+
+ m_painter = new QVideoSurfaceCoreGraphicsPainter(m_glContext != 0);
+ return;
+#endif
+
+#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_1_CL) && !defined(QT_OPENGL_ES_1)
+ switch (m_shaderType) {
+#ifndef QT_OPENGL_ES
+ case FragmentProgramShader:
+ Q_ASSERT(m_glContext);
+ m_glContext->makeCurrent();
+ m_painter = new QVideoSurfaceArbFpPainter(m_glContext);
+ break;
+#endif
+ case GlslShader:
+ Q_ASSERT(m_glContext);
+ m_glContext->makeCurrent();
+ m_painter = new QVideoSurfaceGlslPainter(m_glContext);
+ break;
+ default:
+ m_painter = new QVideoSurfaceRasterPainter;
+ break;
+ }
+#else
+ m_painter = new QVideoSurfaceRasterPainter;
+#endif
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qpaintervideosurface_p.cpp"
+
+
diff --git a/src/multimedia/mediaservices/base/qpaintervideosurface_mac.mm b/src/multimedia/mediaservices/base/qpaintervideosurface_mac.mm
new file mode 100644
index 0000000..1154f86
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qpaintervideosurface_mac.mm
@@ -0,0 +1,283 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMultimedia module 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 "qpaintervideosurface_mac_p.h"
+
+#include <QtCore/qdatetime.h>
+
+#include <qmath.h>
+
+#include <qpainter.h>
+#include <qvariant.h>
+#include <QtMultimedia/qvideosurfaceformat.h>
+
+#include <QtDebug>
+
+#include <QuartzCore/CIContext.h>
+#include <CGLCurrent.h>
+#include <gl.h>
+
+QT_BEGIN_NAMESPACE
+
+extern CGContextRef qt_mac_cg_context(const QPaintDevice *pdev); //qpaintdevice_mac.cpp
+
+QVideoSurfaceCoreGraphicsPainter::QVideoSurfaceCoreGraphicsPainter(bool glSupported)
+ : ciContext(0)
+ , m_imageFormat(QImage::Format_Invalid)
+ , m_scanLineDirection(QVideoSurfaceFormat::TopToBottom)
+{
+ //qDebug() << "QVideoSurfaceCoreGraphicsPainter, GL supported:" << glSupported;
+ ciContext = 0;
+ m_imagePixelFormats
+ << QVideoFrame::Format_RGB32;
+
+ m_supportedHandles
+ << QAbstractVideoBuffer::NoHandle
+ << QAbstractVideoBuffer::CoreImageHandle;
+
+ if (glSupported)
+ m_supportedHandles << QAbstractVideoBuffer::GLTextureHandle;
+}
+
+QVideoSurfaceCoreGraphicsPainter::~QVideoSurfaceCoreGraphicsPainter()
+{
+ [(CIContext*)ciContext release];
+}
+
+QList<QVideoFrame::PixelFormat> QVideoSurfaceCoreGraphicsPainter::supportedPixelFormats(
+ QAbstractVideoBuffer::HandleType handleType) const
+{
+ return m_supportedHandles.contains(handleType)
+ ? m_imagePixelFormats
+ : QList<QVideoFrame::PixelFormat>();
+}
+
+bool QVideoSurfaceCoreGraphicsPainter::isFormatSupported(
+ const QVideoSurfaceFormat &format, QVideoSurfaceFormat *) const
+{
+ return m_supportedHandles.contains(format.handleType())
+ && m_imagePixelFormats.contains(format.pixelFormat())
+ && !format.frameSize().isEmpty();
+}
+
+QAbstractVideoSurface::Error QVideoSurfaceCoreGraphicsPainter::start(const QVideoSurfaceFormat &format)
+{
+ m_frame = QVideoFrame();
+ m_imageFormat = QVideoFrame::imageFormatFromPixelFormat(format.pixelFormat());
+ m_imageSize = format.frameSize();
+ m_scanLineDirection = format.scanLineDirection();
+
+ return m_supportedHandles.contains(format.handleType())
+ && m_imageFormat != QImage::Format_Invalid
+ && !m_imageSize.isEmpty()
+ ? QAbstractVideoSurface::NoError
+ : QAbstractVideoSurface::UnsupportedFormatError;
+}
+
+void QVideoSurfaceCoreGraphicsPainter::stop()
+{
+ m_frame = QVideoFrame();
+}
+
+QAbstractVideoSurface::Error QVideoSurfaceCoreGraphicsPainter::setCurrentFrame(const QVideoFrame &frame)
+{
+ m_frame = frame;
+
+ return QAbstractVideoSurface::NoError;
+}
+
+QAbstractVideoSurface::Error QVideoSurfaceCoreGraphicsPainter::paint(
+ const QRectF &target, QPainter *painter, const QRectF &source)
+{
+ if (m_frame.handleType() == QAbstractVideoBuffer::CoreImageHandle) {
+ if (painter->paintEngine()->type() == QPaintEngine::CoreGraphics ) {
+
+ CIImage *img = (CIImage*)(m_frame.handle().value<void*>());
+
+ if (img) {
+ CGContextRef cgContext = qt_mac_cg_context(painter->device());
+
+ if (cgContext) {
+ painter->beginNativePainting();
+
+ CGRect sRect = CGRectMake(source.x(), source.y(), source.width(), source.height());
+ CGRect dRect = CGRectMake(target.x(), target.y(), target.width(), target.height());
+
+ NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] initWithCIImage:img];
+
+ if (m_scanLineDirection == QVideoSurfaceFormat::TopToBottom) {
+ CGContextSaveGState( cgContext );
+ CGContextTranslateCTM(cgContext, 0, dRect.origin.y + CGRectGetMaxY(dRect));
+ CGContextScaleCTM(cgContext, 1, -1);
+
+#if (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4)
+ if (QSysInfo::MacintoshVersion > QSysInfo::MV_10_4) {
+ CGContextDrawImage(cgContext, dRect, [bitmap CGImage]);
+ }
+#endif
+
+ CGContextRestoreGState(cgContext);
+ } else {
+#if (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4)
+ if (QSysInfo::MacintoshVersion > QSysInfo::MV_10_4) {
+ CGContextDrawImage(cgContext, dRect, [bitmap CGImage]);
+ }
+#endif
+ }
+
+ [bitmap release];
+
+ painter->endNativePainting();
+
+ return QAbstractVideoSurface::NoError;
+ }
+ }
+ } else if (painter->paintEngine()->type() == QPaintEngine::OpenGL2 ||
+ painter->paintEngine()->type() == QPaintEngine::OpenGL) {
+ CIImage *img = (CIImage*)(m_frame.handle().value<void*>());
+
+ if (img) {
+ CGLContextObj cglContext = CGLGetCurrentContext();
+
+ if (cglContext) {
+
+ if (!ciContext) {
+ CGLContextObj cglContext = CGLGetCurrentContext();
+ NSOpenGLPixelFormat *nsglPixelFormat = [NSOpenGLView defaultPixelFormat];
+ CGLPixelFormatObj cglPixelFormat = static_cast<CGLPixelFormatObj>([nsglPixelFormat CGLPixelFormatObj]);
+
+ ciContext = [CIContext contextWithCGLContext:cglContext
+ pixelFormat:cglPixelFormat
+ options:nil];
+
+ [(CIContext*)ciContext retain];
+ }
+
+ CGRect sRect = CGRectMake(source.x(), source.y(), source.width(), source.height());
+ CGRect dRect = m_scanLineDirection == QVideoSurfaceFormat::TopToBottom ?
+ CGRectMake(target.x(), target.y()+target.height(), target.width(), -target.height()) :
+ CGRectMake(target.x(), target.y(), target.width(), target.height());
+
+
+ painter->beginNativePainting();
+
+ [(CIContext*)ciContext drawImage:img inRect:dRect fromRect:sRect];
+
+ painter->endNativePainting();
+
+ return QAbstractVideoSurface::NoError;
+ }
+ }
+ }
+ }
+
+ if (m_frame.handleType() == QAbstractVideoBuffer::GLTextureHandle &&
+ (painter->paintEngine()->type() == QPaintEngine::OpenGL2 ||
+ painter->paintEngine()->type() == QPaintEngine::OpenGL)) {
+
+ painter->beginNativePainting();
+ GLuint texture = m_frame.handle().toUInt();
+
+ glDisable(GL_CULL_FACE);
+ glEnable(GL_TEXTURE_2D);
+
+ glBindTexture(GL_TEXTURE_2D, texture);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ const float txLeft = source.left() / m_frame.width();
+ const float txRight = source.right() / m_frame.width();
+ const float txTop = m_scanLineDirection == QVideoSurfaceFormat::TopToBottom
+ ? source.top() / m_frame.height()
+ : source.bottom() / m_frame.height();
+ const float txBottom = m_scanLineDirection == QVideoSurfaceFormat::TopToBottom
+ ? source.bottom() / m_frame.height()
+ : source.top() / m_frame.height();
+
+ glBegin(GL_QUADS);
+ QRectF rect = target;
+ glTexCoord2f(txLeft, txBottom);
+ glVertex2f(rect.topLeft().x(), rect.topLeft().y());
+ glTexCoord2f(txRight, txBottom);
+ glVertex2f(rect.topRight().x() + 1, rect.topRight().y());
+ glTexCoord2f(txRight, txTop);
+ glVertex2f(rect.bottomRight().x() + 1, rect.bottomRight().y() + 1);
+ glTexCoord2f(txLeft, txTop);
+ glVertex2f(rect.bottomLeft().x(), rect.bottomLeft().y() + 1);
+ glEnd();
+ painter->endNativePainting();
+
+ return QAbstractVideoSurface::NoError;
+ }
+
+ //fallback case, software rendering
+ if (m_frame.map(QAbstractVideoBuffer::ReadOnly)) {
+ QImage image(
+ m_frame.bits(),
+ m_imageSize.width(),
+ m_imageSize.height(),
+ m_frame.bytesPerLine(),
+ m_imageFormat);
+
+ if (m_scanLineDirection == QVideoSurfaceFormat::BottomToTop) {
+ const QTransform oldTransform = painter->transform();
+
+ painter->scale(1, -1);
+ painter->translate(0, -target.bottom());
+ painter->drawImage(
+ QRectF(target.x(), 0, target.width(), target.height()), image, source);
+ painter->setTransform(oldTransform);
+ } else {
+ painter->drawImage(target, image, source);
+ }
+
+ m_frame.unmap();
+ } else {
+ painter->fillRect(target, Qt::black);
+ }
+ return QAbstractVideoSurface::NoError;
+}
+
+void QVideoSurfaceCoreGraphicsPainter::updateColors(int, int, int, int)
+{
+}
+
+QT_END_NAMESPACE
diff --git a/src/multimedia/mediaservices/base/qpaintervideosurface_mac_p.h b/src/multimedia/mediaservices/base/qpaintervideosurface_mac_p.h
new file mode 100644
index 0000000..4f8a7a6
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qpaintervideosurface_mac_p.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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$
+**
+****************************************************************************/
+
+#ifndef QPAINTERVIDEOSURFACE_MAC_P_H
+#define QPAINTERVIDEOSURFACE_MAC_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qpaintervideosurface_p.h"
+#include <QtMultimedia/qvideosurfaceformat.h>
+#include <QtMultimedia/qvideoframe.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QVideoSurfaceCoreGraphicsPainter : public QVideoSurfacePainter
+{
+public:
+ QVideoSurfaceCoreGraphicsPainter(bool glSupported);
+ ~QVideoSurfaceCoreGraphicsPainter();
+
+ QList<QVideoFrame::PixelFormat> supportedPixelFormats(
+ QAbstractVideoBuffer::HandleType handleType) const;
+
+ bool isFormatSupported(
+ const QVideoSurfaceFormat &format, QVideoSurfaceFormat *similar) const;
+
+ QAbstractVideoSurface::Error start(const QVideoSurfaceFormat &format);
+ void stop();
+
+ QAbstractVideoSurface::Error setCurrentFrame(const QVideoFrame &frame);
+
+ QAbstractVideoSurface::Error paint(
+ const QRectF &target, QPainter *painter, const QRectF &source);
+
+ void updateColors(int brightness, int contrast, int hue, int saturation);
+
+private:
+ void* ciContext;
+ QList<QVideoFrame::PixelFormat> m_imagePixelFormats;
+ QVideoFrame m_frame;
+ QSize m_imageSize;
+ QImage::Format m_imageFormat;
+ QVector<QAbstractVideoBuffer::HandleType> m_supportedHandles;
+ QVideoSurfaceFormat::Direction m_scanLineDirection;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/multimedia/mediaservices/base/qpaintervideosurface_p.h b/src/multimedia/mediaservices/base/qpaintervideosurface_p.h
new file mode 100644
index 0000000..07b7e01
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qpaintervideosurface_p.h
@@ -0,0 +1,178 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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$
+**
+****************************************************************************/
+
+#ifndef QPAINTERVIDEOSURFACE_P_H
+#define QPAINTERVIDEOSURFACE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qsize.h>
+#include <QtGui/qimage.h>
+#include <QtGui/qmatrix4x4.h>
+#include <QtGui/qpaintengine.h>
+#include <QtMultimedia/qabstractvideosurface.h>
+#include <QtMultimedia/qvideoframe.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QGLContext;
+
+class QVideoSurfacePainter
+{
+public:
+ virtual ~QVideoSurfacePainter();
+
+ virtual QList<QVideoFrame::PixelFormat> supportedPixelFormats(
+ QAbstractVideoBuffer::HandleType handleType) const = 0;
+
+ virtual bool isFormatSupported(
+ const QVideoSurfaceFormat &format, QVideoSurfaceFormat *similar) const = 0;
+
+ virtual QAbstractVideoSurface::Error start(const QVideoSurfaceFormat &format) = 0;
+ virtual void stop() = 0;
+
+ virtual QAbstractVideoSurface::Error setCurrentFrame(const QVideoFrame &frame) = 0;
+
+ virtual QAbstractVideoSurface::Error paint(
+ const QRectF &target, QPainter *painter, const QRectF &source) = 0;
+
+ virtual void updateColors(int brightness, int contrast, int hue, int saturation) = 0;
+};
+
+class Q_MEDIASERVICES_EXPORT QPainterVideoSurface : public QAbstractVideoSurface
+{
+ Q_OBJECT
+public:
+ explicit QPainterVideoSurface(QObject *parent = 0);
+ ~QPainterVideoSurface();
+
+ QList<QVideoFrame::PixelFormat> supportedPixelFormats(
+ QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle) const;
+
+ bool isFormatSupported(
+ const QVideoSurfaceFormat &format, QVideoSurfaceFormat *similar = 0) const;
+
+ bool start(const QVideoSurfaceFormat &format);
+ void stop();
+
+ bool present(const QVideoFrame &frame);
+
+ int brightness() const;
+ void setBrightness(int brightness);
+
+ int contrast() const;
+ void setContrast(int contrast);
+
+ int hue() const;
+ void setHue(int hue);
+
+ int saturation() const;
+ void setSaturation(int saturation);
+
+ bool isReady() const;
+ void setReady(bool ready);
+
+ void paint(QPainter *painter, const QRectF &target, const QRectF &source = QRectF(0, 0, 1, 1));
+
+#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_1_CL) && !defined(QT_OPENGL_ES_1)
+ const QGLContext *glContext() const;
+ void setGLContext(QGLContext *context);
+
+ enum ShaderType
+ {
+ NoShaders = 0x00,
+ FragmentProgramShader = 0x01,
+ GlslShader = 0x02
+ };
+
+ Q_DECLARE_FLAGS(ShaderTypes, ShaderType)
+
+ ShaderTypes supportedShaderTypes() const;
+
+ ShaderType shaderType() const;
+ void setShaderType(ShaderType type);
+#endif
+
+Q_SIGNALS:
+ void frameChanged();
+
+private:
+ void createPainter();
+
+ QVideoSurfacePainter *m_painter;
+#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_1_CL) && !defined(QT_OPENGL_ES_1)
+ QGLContext *m_glContext;
+ ShaderTypes m_shaderTypes;
+ ShaderType m_shaderType;
+#endif
+ int m_brightness;
+ int m_contrast;
+ int m_hue;
+ int m_saturation;
+
+ QVideoFrame::PixelFormat m_pixelFormat;
+ QSize m_frameSize;
+ QRect m_sourceRect;
+ bool m_colorsDirty;
+ bool m_ready;
+};
+
+#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_1_CL) && !defined(QT_OPENGL_ES_1)
+Q_DECLARE_OPERATORS_FOR_FLAGS(QPainterVideoSurface::ShaderTypes)
+#endif
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/multimedia/mediaservices/base/qtmedianamespace.h b/src/multimedia/mediaservices/base/qtmedianamespace.h
new file mode 100644
index 0000000..917c646
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qtmedianamespace.h
@@ -0,0 +1,194 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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$
+**
+****************************************************************************/
+
+#ifndef QTMEDIANAMESPACE_H
+#define QTMEDIANAMESPACE_H
+
+#include <QtCore/qpair.h>
+#include <QtCore/qmetatype.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+namespace QtMediaServices
+{
+ enum MetaData
+ {
+ // Common
+ Title,
+ SubTitle,
+ Author,
+ Comment,
+ Description,
+ Category,
+ Genre,
+ Year,
+ Date,
+ UserRating,
+ Keywords,
+ Language,
+ Publisher,
+ Copyright,
+ ParentalRating,
+ RatingOrganisation,
+
+ // Media
+ Size,
+ MediaType,
+ Duration,
+
+ // Audio
+ AudioBitRate,
+ AudioCodec,
+ AverageLevel,
+ ChannelCount,
+ PeakValue,
+ SampleRate,
+
+ // Music
+ AlbumTitle,
+ AlbumArtist,
+ ContributingArtist,
+ Composer,
+ Conductor,
+ Lyrics,
+ Mood,
+ TrackNumber,
+ TrackCount,
+
+ CoverArtUrlSmall,
+ CoverArtUrlLarge,
+
+ // Image/Video
+ Resolution,
+ PixelAspectRatio,
+
+ // Video
+ VideoFrameRate,
+ VideoBitRate,
+ VideoCodec,
+
+ PosterUrl,
+
+ // Movie
+ ChapterNumber,
+ Director,
+ LeadPerformer,
+ Writer,
+
+ // Photos
+ CameraManufacturer,
+ CameraModel,
+ Event,
+ Subject,
+ Orientation,
+ ExposureTime,
+ FNumber,
+ ExposureProgram,
+ ISOSpeedRatings,
+ ExposureBiasValue,
+ DateTimeOriginal,
+ DateTimeDigitized,
+ SubjectDistance,
+ MeteringMode,
+ LightSource,
+ Flash,
+ FocalLength,
+ ExposureMode,
+ WhiteBalance,
+ DigitalZoomRatio,
+ FocalLengthIn35mmFilm,
+ SceneCaptureType,
+ GainControl,
+ Contrast,
+ Saturation,
+ Sharpness,
+ DeviceSettingDescription,
+
+ PosterImage,
+ CoverArtImage,
+ ThumbnailImage
+
+ };
+
+ enum SupportEstimate
+ {
+ NotSupported,
+ MaybeSupported,
+ ProbablySupported,
+ PreferredService
+ };
+
+ enum EncodingQuality
+ {
+ VeryLowQuality,
+ LowQuality,
+ NormalQuality,
+ HighQuality,
+ VeryHighQuality
+ };
+
+ enum EncodingMode
+ {
+ ConstantQualityEncoding,
+ ConstantBitRateEncoding,
+ AverageBitRateEncoding,
+ TwoPassEncoding
+ };
+
+ enum AvailabilityError
+ {
+ NoError,
+ ServiceMissingError,
+ BusyError,
+ ResourceError
+ };
+
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/multimedia/mediaservices/base/qtmedianamespace.qdoc b/src/multimedia/mediaservices/base/qtmedianamespace.qdoc
new file mode 100644
index 0000000..277b1a5
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qtmedianamespace.qdoc
@@ -0,0 +1,214 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMultimedia module 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$
+**
+****************************************************************************/
+
+/*!
+ \namespace QtMultimedia
+ \ingroup multimedia
+
+ \brief The QtMultimedia namespace contains miscellaneous identifiers used
+ throughout the Qt Multimedia library.
+*/
+
+/*!
+ \enum QtMultimedia::MetaData
+
+ This enum provides identifiers for meta-data attributes.
+
+ Common attributes
+ \value Title The title of the media. QString.
+ \value SubTitle The sub-title of the media. QString.
+ \value Author The authors of the media. QStringList.
+ \value Comment A user comment about the media. QString.
+ \value Description A description of the media. QString
+ \value Category The category of the media. QStringList.
+ \value Genre The genre of the media. QStringList.
+ \value Year The year of release of the media. int.
+ \value Date The date of the media. QDate.
+ \value UserRating A user rating of the media. int [0..100].
+ \value Keywords A list of keywords describing the media. QStringList.
+ \value Language The language of media, as an ISO 639-2 code.
+
+ \value Publisher The publisher of the media. QString.
+ \value Copyright The media's copyright notice. QString.
+ \value ParentalRating The parental rating of the media. QString.
+ \value RatingOrganisation The organisation responsible for the parental rating of the media.
+ QString.
+
+ Media attributes
+ \value Size The size in bytes of the media. qint64
+ \value MediaType The type of the media (audio, video, etc). QString.
+ \value Duration The duration in millseconds of the media. qint64.
+
+ Audio attributes
+ \value AudioBitRate The bit rate of the media's audio stream in bits per second. int.
+ \value AudioCodec The codec of the media's audio stream. QString.
+ \value AverageLevel The average volume level of the media. int.
+ \value ChannelCount The number of channels in the media's audio stream. int.
+ \value PeakValue The peak volume of the media's audio stream. int
+ \value SampleRate The sample rate of the media's audio stream in hertz. int
+
+ Music attributes
+ \value AlbumTitle The title of the album the media belongs to. QString.
+ \value AlbumArtist The principal artist of the album the media belongs to. QString.
+ \value ContributingArtist The artists contributing to the media. QStringList.
+ \value Composer The composer of the media. QStringList.
+ \value Conductor The conductor of the media. QString.
+ \value Lyrics The lyrics to the media. QString.
+ \value Mood The mood of the media. QString.
+ \value TrackNumber The track number of the media. int.
+ \value TrackCount The number of tracks on the album containing the media. int.
+
+ \value CoverArtUrlSmall The URL of a small cover art image. QUrl.
+ \value CoverArtUrlLarge The URL of a large cover art image. QUrl.
+ \value CoverArtImage An embedded cover art image. QImage.
+
+ Image and video attributes
+ \value Resolution The dimensions of an image or video. QSize.
+ \value PixelAspectRatio The pixel aspect ratio of an image or video. QSize.
+
+ Video attributes
+ \value VideoFrameRate The frame rate of the media's video stream. qreal.
+ \value VideoBitRate The bit rate of the media's video stream in bits per second. int.
+ \value VideoCodec The codec of the media's video stream. QString.
+
+ \value PosterUrl The URL of a poster image. QUrl.
+ \value PosterImage An embedded poster image. QImage.
+
+ Movie attributes
+ \value ChapterNumber The chapter number of the media. int.
+ \value Director The director of the media. QString.
+ \value LeadPerformer The lead performer in the media. QStringList.
+ \value Writer The writer of the media. QStringList.
+
+ Photo attributes.
+ \value CameraManufacturer The manufacturer of the camera used to capture the media. QString.
+ \value CameraModel The model of the camera used to capture the media. QString.
+ \value Event The event during which the media was captured. QString.
+ \value Subject The subject of the media. QString.
+ \value Orientation Orientation of image.
+ \value ExposureTime Exposure time, given in seconds.
+ \value FNumber The F Number.
+ \value ExposureProgram
+ The class of the program used by the camera to set exposure when the picture is taken.
+ \value ISOSpeedRatings
+ Indicates the ISO Speed and ISO Latitude of the camera or input device as specified in ISO 12232.
+ \value ExposureBiasValue
+ The exposure bias.
+ The unit is the APEX (Additive System of Photographic Exposure) setting.
+ \value DateTimeOriginal The date and time when the original image data was generated.
+ \value DateTimeDigitized The date and time when the image was stored as digital data.
+ \value SubjectDistance The distance to the subject, given in meters.
+ \value MeteringMode The metering mode.
+ \value LightSource
+ The kind of light source.
+ \value Flash
+ Status of flash when the image was shot.
+ \value FocalLength
+ The actual focal length of the lens, in mm.
+ \value ExposureMode
+ Indicates the exposure mode set when the image was shot.
+ \value WhiteBalance
+ Indicates the white balance mode set when the image was shot.
+ \value DigitalZoomRatio
+ Indicates the digital zoom ratio when the image was shot.
+ \value FocalLengthIn35mmFilm
+ Indicates the equivalent focal length assuming a 35mm film camera, in mm.
+ \value SceneCaptureType
+ Indicates the type of scene that was shot.
+ It can also be used to record the mode in which the image was shot.
+ \value GainControl
+ Indicates the degree of overall image gain adjustment.
+ \value Contrast
+ Indicates the direction of contrast processing applied by the camera when the image was shot.
+ \value Saturation
+ Indicates the direction of saturation processing applied by the camera when the image was shot.
+ \value Sharpness
+ Indicates the direction of sharpness processing applied by the camera when the image was shot.
+ \value DeviceSettingDescription
+ Exif tag, indicates information on the picture-taking conditions of a particular camera model. QString
+
+ \value ThumbnailImage An embedded thumbnail image. QImage.
+*/
+
+/*!
+ \enum QtMultimedia::SupportEstimate
+
+ Enumerates the levels of support a media service provider may have for a feature.
+
+ \value NotSupported The feature is not supported.
+ \value MaybeSupported The feature may be supported.
+ \value ProbablySupported The feature is probably supported.
+ \value PreferredService The service is the preferred provider of a service.
+*/
+
+/*!
+ \enum QtMultimedia::EncodingQuality
+
+ Enumerates quality encoding levels.
+
+ \value VeryLowQuality
+ \value LowQuality
+ \value NormalQuality
+ \value HighQuality
+ \value VeryHighQuality
+*/
+
+/*!
+ \enum QtMultimedia::EncodingMode
+
+ Enumerates encoding modes.
+
+ \value ConstantQualityEncoding
+ \value ConstantBitRateEncoding
+ \value AverageBitRateEncoding
+ \value TwoPassEncoding
+*/
+
+/*!
+ \enum QtMultimedia::AvailabilityError
+
+ Enumerates Service status errors.
+
+ \value NoError
+ \value ServiceMissingError
+ \value ResourceError
+ \value BusyError
+*/
diff --git a/src/multimedia/mediaservices/base/qvideodevicecontrol.cpp b/src/multimedia/mediaservices/base/qvideodevicecontrol.cpp
new file mode 100644
index 0000000..30c56cf
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qvideodevicecontrol.cpp
@@ -0,0 +1,155 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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 <QtMediaServices/qvideodevicecontrol.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QVideoDeviceControl
+ \preliminary
+ \since 4.7
+ \brief The QVideoDeviceControl class provides an video device selector media control.
+ \ingroup multimedia-serv
+
+ The QVideoDeviceControl class provides descriptions of the video devices
+ available on a system and allows one to be selected as the endpoint of
+ a media service.
+
+ The interface name of QVideoDeviceControl is \c com.nokia.Qt.VideoDeviceControl as
+ defined in QVideoDeviceControl_iid.
+*/
+
+/*!
+ \macro QVideoDeviceControl_iid
+
+ \c com.nokia.Qt.VideoDeviceControl
+
+ Defines the interface name of the QVideoDeviceControl class.
+
+ \relates QVideoDeviceControl
+*/
+
+/*!
+ Constructs a video device control with the given \a parent.
+*/
+QVideoDeviceControl::QVideoDeviceControl(QObject *parent)
+ :QMediaControl(parent)
+{
+}
+
+/*!
+ Destroys a video device control.
+*/
+QVideoDeviceControl::~QVideoDeviceControl()
+{
+}
+
+/*!
+ \fn QVideoDeviceControl::deviceCount() const
+
+ Returns the number of available video devices;
+*/
+
+/*!
+ \fn QVideoDeviceControl::deviceName(int index) const
+
+ Returns the name of the video device at \a index.
+*/
+
+/*!
+ \fn QVideoDeviceControl::deviceDescription(int index) const
+
+ Returns a description of the video device at \a index.
+*/
+
+/*!
+ \fn QVideoDeviceControl::deviceIcon(int index) const
+
+ Returns an icon for the video device at \a index.
+*/
+
+/*!
+ \fn QVideoDeviceControl::defaultDevice() const
+
+ Returns the index of the default video device.
+*/
+
+/*!
+ \fn QVideoDeviceControl::selectedDevice() const
+
+ Returns the index of the selected video device.
+*/
+
+/*!
+ \fn QVideoDeviceControl::setSelectedDevice(int index)
+
+ Sets the selected video device \a index.
+*/
+
+/*!
+ \fn QVideoDeviceControl::devicesChanged()
+
+ Signals that the list of available video devices has changed.
+*/
+
+/*!
+ \fn QVideoDeviceControl::selectedDeviceChanged(int index)
+
+ Signals that the selected video device \a index has changed.
+*/
+
+/*!
+ \fn QVideoDeviceControl::selectedDeviceChanged(const QString &name)
+
+ Signals that the selected video device \a name has changed.
+*/
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#include "moc_qvideodevicecontrol.cpp"
+
+
diff --git a/src/multimedia/mediaservices/base/qvideodevicecontrol.h b/src/multimedia/mediaservices/base/qvideodevicecontrol.h
new file mode 100644
index 0000000..0b9235b
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qvideodevicecontrol.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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$
+**
+****************************************************************************/
+
+#ifndef QVIDEODEVICECONTROL_H
+#define QVIDEODEVICECONTROL_H
+
+#include <QtMediaServices/qmediacontrol.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+class Q_MEDIASERVICES_EXPORT QVideoDeviceControl : public QMediaControl
+{
+ Q_OBJECT
+
+public:
+ virtual ~QVideoDeviceControl();
+
+ virtual int deviceCount() const = 0;
+
+ virtual QString deviceName(int index) const = 0;
+ virtual QString deviceDescription(int index) const = 0;
+ virtual QIcon deviceIcon(int index) const = 0;
+
+ virtual int defaultDevice() const = 0;
+ virtual int selectedDevice() const = 0;
+
+public Q_SLOTS:
+ virtual void setSelectedDevice(int index) = 0;
+
+Q_SIGNALS:
+ void selectedDeviceChanged(int index);
+ void selectedDeviceChanged(const QString &deviceName);
+ void devicesChanged();
+
+protected:
+ QVideoDeviceControl(QObject *parent = 0);
+};
+
+#define QVideoDeviceControl_iid "com.nokia.Qt.QVideoDeviceControl/1.0"
+Q_MEDIA_DECLARE_CONTROL(QVideoDeviceControl, QVideoDeviceControl_iid)
+
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QVIDEODEVICECONTROL_H
diff --git a/src/multimedia/mediaservices/base/qvideooutputcontrol.cpp b/src/multimedia/mediaservices/base/qvideooutputcontrol.cpp
new file mode 100644
index 0000000..532c892
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qvideooutputcontrol.cpp
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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 <QtMediaServices/qvideooutputcontrol.h>
+
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QVideoOutputControl
+ \preliminary
+ \since 4.7
+ \brief The QVideoOutputControl class provides a means of selecting the
+ active video output control.
+
+ \ingroup multimedia-serv
+
+ There are multiple controls which a QMediaService may use to output
+ video ony one of which may be active at one time, QVideoOutputControl
+ is the means by which this active control is selected.
+
+ The possible output controls are QVideoRendererControl,
+ QVideoWindowControl, and QVideoWidgetControl.
+
+ The interface name of QVideoOutputControl is \c com.nokia.Qt.QVideoOutputControl/1.0 as
+ defined in QVideoOutputControl_iid.
+
+ \sa QMediaService::control(), QVideoWidget, QVideoRendererControl,
+ QVideoWindowControl, QVideoWidgetControl
+*/
+
+/*!
+ \macro QVideoOutputControl_iid
+
+ \c com.nokia.Qt.QVideoOutputControl/1.0
+
+ Defines the interface name of the QVideoOutputControl class.
+
+ \relates QVideoOutputControl
+*/
+
+/*!
+ \enum QVideoOutputControl::Output
+
+ Identifies the possible render targets of a video output.
+
+ \value NoOutput Video is not rendered.
+ \value WindowOutput Video is rendered to the target of a QVideoWindowControl.
+ \value RendererOutput Video is rendered to the target of a QVideoRendererControl.
+ \value WidgetOutput Video is rendered to a QWidget provided by QVideoWidgetControl.
+ \value UserOutput Start value for user defined video targets.
+ \value MaxUserOutput End value for user defined video targets.
+*/
+
+/*!
+ Constructs a new video output control with the given \a parent.
+*/
+QVideoOutputControl::QVideoOutputControl(QObject *parent)
+ : QMediaControl(parent)
+{
+}
+
+/*!
+ Destroys a video output control.
+*/
+QVideoOutputControl::~QVideoOutputControl()
+{
+}
+
+/*!
+ \fn QList<QVideoOutputControl::Output> QVideoOutputControl::availableOutputs() const
+
+ Returns a list of available video output targets.
+*/
+
+/*!
+ \fn QVideoOutputControl::output() const
+
+ Returns the current video output target.
+*/
+
+/*!
+ \fn QVideoOutputControl::setOutput(Output output)
+
+ Sets the current video \a output target.
+*/
+
+/*!
+ \fn QVideoOutputControl::availableOutputsChanged(const QList<QVideoOutputControl::Output> &outputs)
+
+ Signals that available set of video \a outputs has changed.
+*/
+
+#include "moc_qvideooutputcontrol.cpp"
+
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/mediaservices/base/qvideooutputcontrol.h b/src/multimedia/mediaservices/base/qvideooutputcontrol.h
new file mode 100644
index 0000000..f87bb3c
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qvideooutputcontrol.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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$
+**
+****************************************************************************/
+
+#ifndef QVIDEOOUTPUTCONTROL_H
+#define QVIDEOOUTPUTCONTROL_H
+
+#include <QtMediaServices/qmediacontrol.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class Q_MEDIASERVICES_EXPORT QVideoOutputControl : public QMediaControl
+{
+ Q_OBJECT
+
+public:
+ enum Output
+ {
+ NoOutput,
+ WindowOutput,
+ RendererOutput,
+ WidgetOutput,
+ UserOutput = 100,
+ MaxUserOutput = 1000
+ };
+
+ ~QVideoOutputControl();
+
+ virtual QList<Output> availableOutputs() const = 0;
+
+ virtual Output output() const = 0;
+ virtual void setOutput(Output output) = 0;
+
+Q_SIGNALS:
+ void availableOutputsChanged(const QList<QVideoOutputControl::Output> &outputs);
+
+protected:
+ QVideoOutputControl(QObject *parent = 0);
+};
+
+#define QVideoOutputControl_iid "com.nokia.Qt.QVideoOutputControl/1.0"
+Q_MEDIA_DECLARE_CONTROL(QVideoOutputControl, QVideoOutputControl_iid)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/multimedia/mediaservices/base/qvideorenderercontrol.cpp b/src/multimedia/mediaservices/base/qvideorenderercontrol.cpp
new file mode 100644
index 0000000..6cc3138
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qvideorenderercontrol.cpp
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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 <QtMediaServices/qvideorenderercontrol.h>
+
+#include "qmediacontrol_p.h"
+
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QVideoRendererControl
+ \preliminary
+ \since 4.7
+ \brief The QVideoRendererControl class provides a control for rendering
+ to a video surface.
+
+ \ingroup multimedia-serv
+
+ Using the surface() property of QVideoRendererControl a QAbstractVideoSurface
+ may be set as the video render target of a QMediaService.
+
+ \code
+ QVideoRendererControl *rendererControl = mediaService->control<QVideoRendererControl *>();
+ rendererControl->setSurface(myVideoSurface);
+ \endcode
+
+ QVideoRendererControl is one of number of possible video output controls,
+ in order to receive video it must be made the active video output
+ control by setting the output property of QVideoOutputControl to
+ \l {QVideoOutputControl::RendererOutput}{RendererOutput}. Consequently any
+ QMediaService that implements QVideoRendererControl must also implement
+ QVideoOutputControl.
+
+ \code
+ QVideoOutputControl *outputControl = mediaService->control<QVideoOutputControl *>();
+ outputControl->setOutput(QVideoOutputControl::RendererOutput);
+ \endcode
+
+ The interface name of QVideoRendererControl is \c com.nokia.Qt.QVideoRendererControl/1.0 as
+ defined in QVideoRendererControl_iid.
+
+ \sa QMediaService::control(), QVideoOutputControl, QVideoWidget
+*/
+
+/*!
+ \macro QVideoRendererControl_iid
+
+ \c com.nokia.Qt.QVideoRendererControl/1.0
+
+ Defines the interface name of the QVideoRendererControl class.
+
+ \relates QVideoRendererControl
+*/
+
+/*!
+ Constructs a new video renderer media end point with the given \a parent.
+*/
+QVideoRendererControl::QVideoRendererControl(QObject *parent)
+ : QMediaControl(parent)
+{
+}
+
+/*!
+ Destroys a video renderer media end point.
+*/
+QVideoRendererControl::~QVideoRendererControl()
+{
+}
+
+/*!
+ \fn QVideoRendererControl::surface() const
+
+ Returns the surface a video producer renders to.
+*/
+
+/*!
+ \fn QVideoRendererControl::setSurface(QAbstractVideoSurface *surface)
+
+ Sets the \a surface a video producer renders to.
+*/
+
+#include "moc_qvideorenderercontrol.cpp"
+
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/mediaservices/base/qvideorenderercontrol.h b/src/multimedia/mediaservices/base/qvideorenderercontrol.h
new file mode 100644
index 0000000..28e3d85
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qvideorenderercontrol.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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$
+**
+****************************************************************************/
+
+#ifndef QVIDEORENDERERCONTROL_H
+#define QVIDEORENDERERCONTROL_H
+
+#include <QtMediaServices/qmediacontrol.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QAbstractVideoSurface;
+
+class Q_MEDIASERVICES_EXPORT QVideoRendererControl : public QMediaControl
+{
+ Q_OBJECT
+
+public:
+ ~QVideoRendererControl();
+
+ virtual QAbstractVideoSurface *surface() const = 0;
+ virtual void setSurface(QAbstractVideoSurface *surface) = 0;
+
+protected:
+ QVideoRendererControl(QObject *parent = 0);
+};
+
+#define QVideoRendererControl_iid "com.nokia.Qt.QVideoRendererControl/1.0"
+Q_MEDIA_DECLARE_CONTROL(QVideoRendererControl, QVideoRendererControl_iid)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QVIDEORENDERERCONTROL_H
diff --git a/src/multimedia/mediaservices/base/qvideowidget.cpp b/src/multimedia/mediaservices/base/qvideowidget.cpp
new file mode 100644
index 0000000..d39b1f4
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qvideowidget.cpp
@@ -0,0 +1,944 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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 "qvideowidget_p.h"
+
+#include <QtMediaServices/qmediaobject.h>
+#include <QtMediaServices/qmediaservice.h>
+#include <QtMediaServices/qvideooutputcontrol.h>
+#include <QtMediaServices/qvideowindowcontrol.h>
+#include <QtMediaServices/qvideowidgetcontrol.h>
+
+#include "qpaintervideosurface_p.h"
+#include <QtMediaServices/qvideorenderercontrol.h>
+#include <QtMultimedia/qvideosurfaceformat.h>
+#include <qpainter.h>
+
+#include <qapplication.h>
+#include <qevent.h>
+#include <qdialog.h>
+#include <qboxlayout.h>
+#include <qnamespace.h>
+
+
+QT_BEGIN_NAMESPACE
+
+QVideoWidgetControlBackend::QVideoWidgetControlBackend(
+ QVideoWidgetControl *control, QWidget *widget)
+ : m_widgetControl(control)
+{
+ connect(control, SIGNAL(brightnessChanged(int)), widget, SLOT(_q_brightnessChanged(int)));
+ connect(control, SIGNAL(contrastChanged(int)), widget, SLOT(_q_contrastChanged(int)));
+ connect(control, SIGNAL(hueChanged(int)), widget, SLOT(_q_hueChanged(int)));
+ connect(control, SIGNAL(saturationChanged(int)), widget, SLOT(_q_saturationChanged(int)));
+ connect(control, SIGNAL(fullScreenChanged(bool)), widget, SLOT(_q_fullScreenChanged(bool)));
+
+ QBoxLayout *layout = new QVBoxLayout;
+ layout->setMargin(0);
+ layout->setSpacing(0);
+ layout->addWidget(control->videoWidget());
+
+ widget->setLayout(layout);
+}
+
+void QVideoWidgetControlBackend::setBrightness(int brightness)
+{
+ m_widgetControl->setBrightness(brightness);
+}
+
+void QVideoWidgetControlBackend::setContrast(int contrast)
+{
+ m_widgetControl->setContrast(contrast);
+}
+
+void QVideoWidgetControlBackend::setHue(int hue)
+{
+ m_widgetControl->setHue(hue);
+}
+
+void QVideoWidgetControlBackend::setSaturation(int saturation)
+{
+ m_widgetControl->setSaturation(saturation);
+}
+
+void QVideoWidgetControlBackend::setFullScreen(bool fullScreen)
+{
+ m_widgetControl->setFullScreen(fullScreen);
+}
+
+
+Qt::AspectRatioMode QVideoWidgetControlBackend::aspectRatioMode() const
+{
+ return m_widgetControl->aspectRatioMode();
+}
+
+void QVideoWidgetControlBackend::setAspectRatioMode(Qt::AspectRatioMode mode)
+{
+ m_widgetControl->setAspectRatioMode(mode);
+}
+
+QRendererVideoWidgetBackend::QRendererVideoWidgetBackend(
+ QVideoRendererControl *control, QWidget *widget)
+ : m_rendererControl(control)
+ , m_widget(widget)
+ , m_surface(new QPainterVideoSurface)
+ , m_aspectRatioMode(Qt::KeepAspectRatio)
+ , m_updatePaintDevice(true)
+{
+ connect(this, SIGNAL(brightnessChanged(int)), m_widget, SLOT(_q_brightnessChanged(int)));
+ connect(this, SIGNAL(contrastChanged(int)), m_widget, SLOT(_q_contrastChanged(int)));
+ connect(this, SIGNAL(hueChanged(int)), m_widget, SLOT(_q_hueChanged(int)));
+ connect(this, SIGNAL(saturationChanged(int)), m_widget, SLOT(_q_saturationChanged(int)));
+ connect(m_surface, SIGNAL(frameChanged()), this, SLOT(frameChanged()));
+ connect(m_surface, SIGNAL(surfaceFormatChanged(QVideoSurfaceFormat)),
+ this, SLOT(formatChanged(QVideoSurfaceFormat)));
+
+ m_rendererControl->setSurface(m_surface);
+}
+
+QRendererVideoWidgetBackend::~QRendererVideoWidgetBackend()
+{
+ delete m_surface;
+}
+
+void QRendererVideoWidgetBackend::clearSurface()
+{
+ m_rendererControl->setSurface(0);
+}
+
+void QRendererVideoWidgetBackend::setBrightness(int brightness)
+{
+ m_surface->setBrightness(brightness);
+
+ emit brightnessChanged(brightness);
+}
+
+void QRendererVideoWidgetBackend::setContrast(int contrast)
+{
+ m_surface->setContrast(contrast);
+
+ emit contrastChanged(contrast);
+}
+
+void QRendererVideoWidgetBackend::setHue(int hue)
+{
+ m_surface->setHue(hue);
+
+ emit hueChanged(hue);
+}
+
+void QRendererVideoWidgetBackend::setSaturation(int saturation)
+{
+ m_surface->setSaturation(saturation);
+
+ emit saturationChanged(saturation);
+}
+
+Qt::AspectRatioMode QRendererVideoWidgetBackend::aspectRatioMode() const
+{
+ return m_aspectRatioMode;
+}
+
+void QRendererVideoWidgetBackend::setAspectRatioMode(Qt::AspectRatioMode mode)
+{
+ m_aspectRatioMode = mode;
+
+ m_widget->updateGeometry();
+}
+
+void QRendererVideoWidgetBackend::setFullScreen(bool)
+{
+}
+
+QSize QRendererVideoWidgetBackend::sizeHint() const
+{
+ return m_surface->surfaceFormat().sizeHint();
+}
+
+void QRendererVideoWidgetBackend::showEvent()
+{
+}
+
+void QRendererVideoWidgetBackend::hideEvent(QHideEvent *)
+{
+#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_1_CL) && !defined(QT_OPENGL_ES_1)
+ m_updatePaintDevice = true;
+ m_surface->setGLContext(0);
+#endif
+}
+
+void QRendererVideoWidgetBackend::resizeEvent(QResizeEvent *)
+{
+ updateRects();
+}
+
+void QRendererVideoWidgetBackend::moveEvent(QMoveEvent *)
+{
+}
+
+void QRendererVideoWidgetBackend::paintEvent(QPaintEvent *event)
+{
+ QPainter painter(m_widget);
+
+ if (m_widget->testAttribute(Qt::WA_OpaquePaintEvent)) {
+ QRegion borderRegion = event->region();
+ borderRegion = borderRegion.subtracted(m_boundingRect);
+
+ QBrush brush = m_widget->palette().window();
+
+ QVector<QRect> rects = borderRegion.rects();
+ for (QVector<QRect>::iterator it = rects.begin(), end = rects.end(); it != end; ++it) {
+ painter.fillRect(*it, brush);
+ }
+ }
+
+ if (m_surface->isActive() && m_boundingRect.intersects(event->rect())) {
+ m_surface->paint(&painter, m_boundingRect, m_sourceRect);
+
+ m_surface->setReady(true);
+ } else {
+ #if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_1_CL) && !defined(QT_OPENGL_ES_1)
+ if (m_updatePaintDevice && (painter.paintEngine()->type() == QPaintEngine::OpenGL
+ || painter.paintEngine()->type() == QPaintEngine::OpenGL2)) {
+ m_updatePaintDevice = false;
+
+ m_surface->setGLContext(const_cast<QGLContext *>(QGLContext::currentContext()));
+ if (m_surface->supportedShaderTypes() & QPainterVideoSurface::GlslShader) {
+ m_surface->setShaderType(QPainterVideoSurface::GlslShader);
+ } else {
+ m_surface->setShaderType(QPainterVideoSurface::FragmentProgramShader);
+ }
+ }
+#endif
+ }
+
+}
+
+void QRendererVideoWidgetBackend::formatChanged(const QVideoSurfaceFormat &format)
+{
+ m_nativeSize = format.sizeHint();
+
+ updateRects();
+
+ m_widget->updateGeometry();
+ m_widget->update();
+}
+
+void QRendererVideoWidgetBackend::frameChanged()
+{
+ m_widget->update(m_boundingRect);
+}
+
+void QRendererVideoWidgetBackend::updateRects()
+{
+ QRect rect = m_widget->rect();
+
+ if (m_nativeSize.isEmpty()) {
+ m_boundingRect = QRect();
+ } else if (m_aspectRatioMode == Qt::IgnoreAspectRatio) {
+ m_boundingRect = rect;
+ m_sourceRect = QRectF(0, 0, 1, 1);
+ } else if (m_aspectRatioMode == Qt::KeepAspectRatio) {
+ QSize size = m_nativeSize;
+ size.scale(rect.size(), Qt::KeepAspectRatio);
+
+ m_boundingRect = QRect(0, 0, size.width(), size.height());
+ m_boundingRect.moveCenter(rect.center());
+
+ m_sourceRect = QRectF(0, 0, 1, 1);
+ } else if (m_aspectRatioMode == Qt::KeepAspectRatioByExpanding) {
+ m_boundingRect = rect;
+
+ QSizeF size = rect.size();
+ size.scale(m_nativeSize, Qt::KeepAspectRatio);
+
+ m_sourceRect = QRectF(
+ 0, 0, size.width() / m_nativeSize.width(), size.height() / m_nativeSize.height());
+ m_sourceRect.moveCenter(QPointF(0.5, 0.5));
+ }
+}
+
+QWindowVideoWidgetBackend::QWindowVideoWidgetBackend(QVideoWindowControl *control, QWidget *widget)
+ : m_windowControl(control)
+ , m_widget(widget)
+ , m_aspectRatioMode(Qt::KeepAspectRatio)
+{
+ connect(control, SIGNAL(brightnessChanged(int)), m_widget, SLOT(_q_brightnessChanged(int)));
+ connect(control, SIGNAL(contrastChanged(int)), m_widget, SLOT(_q_contrastChanged(int)));
+ connect(control, SIGNAL(hueChanged(int)), m_widget, SLOT(_q_hueChanged(int)));
+ connect(control, SIGNAL(saturationChanged(int)), m_widget, SLOT(_q_saturationChanged(int)));
+ connect(control, SIGNAL(fullScreenChanged(bool)), m_widget, SLOT(_q_fullScreenChanged(bool)));
+ connect(control, SIGNAL(nativeSizeChanged()), m_widget, SLOT(_q_dimensionsChanged()));
+}
+
+QWindowVideoWidgetBackend::~QWindowVideoWidgetBackend()
+{
+}
+
+void QWindowVideoWidgetBackend::setBrightness(int brightness)
+{
+ m_windowControl->setBrightness(brightness);
+}
+
+void QWindowVideoWidgetBackend::setContrast(int contrast)
+{
+ m_windowControl->setContrast(contrast);
+}
+
+void QWindowVideoWidgetBackend::setHue(int hue)
+{
+ m_windowControl->setHue(hue);
+}
+
+void QWindowVideoWidgetBackend::setSaturation(int saturation)
+{
+ m_windowControl->setSaturation(saturation);
+}
+
+void QWindowVideoWidgetBackend::setFullScreen(bool fullScreen)
+{
+ m_windowControl->setFullScreen(fullScreen);
+}
+
+Qt::AspectRatioMode QWindowVideoWidgetBackend::aspectRatioMode() const
+{
+ return m_windowControl->aspectRatioMode();
+}
+
+void QWindowVideoWidgetBackend::setAspectRatioMode(Qt::AspectRatioMode mode)
+{
+ m_windowControl->setAspectRatioMode(mode);
+}
+
+QSize QWindowVideoWidgetBackend::sizeHint() const
+{
+ return m_windowControl->nativeSize();
+}
+
+void QWindowVideoWidgetBackend::showEvent()
+{
+ m_windowControl->setWinId(m_widget->winId());
+
+ m_windowControl->setDisplayRect(m_widget->rect());
+}
+
+void QWindowVideoWidgetBackend::hideEvent(QHideEvent *)
+{
+}
+
+void QWindowVideoWidgetBackend::moveEvent(QMoveEvent *)
+{
+ m_windowControl->setDisplayRect(m_widget->rect());
+}
+
+void QWindowVideoWidgetBackend::resizeEvent(QResizeEvent *)
+{
+ m_windowControl->setDisplayRect(m_widget->rect());
+}
+
+void QWindowVideoWidgetBackend::paintEvent(QPaintEvent *event)
+{
+ if (m_widget->testAttribute(Qt::WA_OpaquePaintEvent)) {
+ QPainter painter(m_widget);
+
+ painter.fillRect(event->rect(), m_widget->palette().window());
+ }
+
+ m_windowControl->repaint();
+
+ event->accept();
+}
+
+void QVideoWidgetPrivate::setCurrentControl(QVideoWidgetControlInterface *control)
+{
+ if (currentControl != control) {
+ currentControl = control;
+
+ currentControl->setBrightness(brightness);
+ currentControl->setContrast(contrast);
+ currentControl->setHue(hue);
+ currentControl->setSaturation(saturation);
+ currentControl->setAspectRatioMode(aspectRatioMode);
+ }
+}
+
+void QVideoWidgetPrivate::show()
+{
+ if (outputControl) {
+ if (widgetBackend != 0) {
+ setCurrentControl(widgetBackend);
+ outputControl->setOutput(QVideoOutputControl::WidgetOutput);
+ } else if (windowBackend != 0 && (q_func()->window() == 0
+ || !q_func()->window()->testAttribute(Qt::WA_DontShowOnScreen))) {
+ windowBackend->showEvent();
+ currentBackend = windowBackend;
+ setCurrentControl(windowBackend);
+ outputControl->setOutput(QVideoOutputControl::WindowOutput);
+ } else if (rendererBackend != 0) {
+ rendererBackend->showEvent();
+ currentBackend = rendererBackend;
+ setCurrentControl(rendererBackend);
+ outputControl->setOutput(QVideoOutputControl::RendererOutput);
+ } else {
+ outputControl->setOutput(QVideoOutputControl::NoOutput);
+ }
+ }
+}
+
+void QVideoWidgetPrivate::clearService()
+{
+ if (service) {
+ QObject::disconnect(service, SIGNAL(destroyed()), q_func(), SLOT(_q_serviceDestroyed()));
+
+ if (outputControl)
+ outputControl->setOutput(QVideoOutputControl::NoOutput);
+
+ if (widgetBackend) {
+ QLayout *layout = q_func()->layout();
+
+ for (QLayoutItem *item = layout->takeAt(0); item; item = layout->takeAt(0)) {
+ item->widget()->setParent(0);
+ delete item;
+ }
+ delete layout;
+
+ delete widgetBackend;
+ widgetBackend = 0;
+ }
+
+ delete windowBackend;
+ windowBackend = 0;
+
+ if (rendererBackend) {
+ rendererBackend->clearSurface();
+
+ delete rendererBackend;
+ rendererBackend = 0;
+ }
+
+ currentBackend = 0;
+ currentControl = 0;
+ outputControl = 0;
+ service = 0;
+ }
+}
+
+void QVideoWidgetPrivate::_q_serviceDestroyed()
+{
+ if (widgetBackend) {
+ delete q_func()->layout();
+
+ delete widgetBackend;
+ widgetBackend = 0;
+ }
+
+ delete windowBackend;
+ windowBackend = 0;
+
+ delete rendererBackend;
+ rendererBackend = 0;
+
+ currentControl = 0;
+ currentBackend = 0;
+ outputControl = 0;
+ service = 0;
+}
+
+void QVideoWidgetPrivate::_q_mediaObjectDestroyed()
+{
+ mediaObject = 0;
+ clearService();
+}
+
+void QVideoWidgetPrivate::_q_brightnessChanged(int b)
+{
+ if (b != brightness)
+ emit q_func()->brightnessChanged(brightness = b);
+}
+
+void QVideoWidgetPrivate::_q_contrastChanged(int c)
+{
+ if (c != contrast)
+ emit q_func()->contrastChanged(contrast = c);
+}
+
+void QVideoWidgetPrivate::_q_hueChanged(int h)
+{
+ if (h != hue)
+ emit q_func()->hueChanged(hue = h);
+}
+
+void QVideoWidgetPrivate::_q_saturationChanged(int s)
+{
+ if (s != saturation)
+ emit q_func()->saturationChanged(saturation = s);
+}
+
+
+void QVideoWidgetPrivate::_q_fullScreenChanged(bool fullScreen)
+{
+ if (!fullScreen && q_func()->isFullScreen())
+ q_func()->showNormal();
+}
+
+void QVideoWidgetPrivate::_q_dimensionsChanged()
+{
+ q_func()->updateGeometry();
+ q_func()->update();
+}
+
+/*!
+ \class QVideoWidget
+ \preliminary
+ \since 4.7
+ \brief The QVideoWidget class provides a widget which presents video
+ produced by a media object.
+ \ingroup multimedia
+
+ Attaching a QVideoWidget to a QMediaObject allows it to display the
+ video or image output of that media object. A QVideoWidget is attached
+ to media object by passing a pointer to the QMediaObject in its
+ constructor, and detached by destroying the QVideoWidget.
+
+ \code
+ player = new QMediaPlayer;
+
+ widget = new QVideoWidget(player);
+ widget->show();
+
+ player->setMedia(QUrl("http://example.com/movie.mp4"));
+ player->play();
+ \endcode
+
+ \bold {Note}: Only a single display output can be attached to a media
+ object at one time.
+
+ \sa QMediaObject, QMediaPlayer, QGraphicsVideoItem
+*/
+
+/*!
+ Constructs a new video widget.
+
+ The \a parent is passed to QWidget.
+*/
+QVideoWidget::QVideoWidget(QWidget *parent)
+ : QWidget(parent, 0)
+ , d_ptr(new QVideoWidgetPrivate)
+{
+ d_ptr->q_ptr = this;
+}
+
+/*!
+ Destroys a video widget.
+*/
+QVideoWidget::~QVideoWidget()
+{
+ setMediaObject(0);
+ delete d_ptr;
+}
+
+/*!
+ \property QVideoWidget::mediaObject
+ \brief the media object which provides the video displayed by a widget.
+*/
+
+QMediaObject *QVideoWidget::mediaObject() const
+{
+ return d_func()->mediaObject;
+}
+
+void QVideoWidget::setMediaObject(QMediaObject *object)
+{
+ Q_D(QVideoWidget);
+
+ if (object == d->mediaObject)
+ return;
+
+ if (d->mediaObject) {
+ disconnect(d->mediaObject, SIGNAL(destroyed()), this, SLOT(_q_mediaObjectDestroyed()));
+ d->mediaObject->unbind(this);
+ }
+
+ d->clearService();
+
+ d->mediaObject = object;
+
+ if (d->mediaObject) {
+ d->service = d->mediaObject->service();
+
+ connect(d->mediaObject, SIGNAL(destroyed()), this, SLOT(_q_mediaObjectDestroyed()));
+ d->mediaObject->bind(this);
+ }
+
+ if (d->service) {
+ connect(d->service, SIGNAL(destroyed()), SLOT(_q_serviceDestroyed()));
+
+ d->outputControl = qobject_cast<QVideoOutputControl *>(
+ d->service->control(QVideoOutputControl_iid));
+
+ QVideoWidgetControl *widgetControl = qobject_cast<QVideoWidgetControl *>(
+ d->service->control(QVideoWidgetControl_iid));
+
+ if (widgetControl != 0) {
+ d->widgetBackend = new QVideoWidgetControlBackend(widgetControl, this);
+ } else {
+ QVideoWindowControl *windowControl = qobject_cast<QVideoWindowControl *>(
+ d->service->control(QVideoWindowControl_iid));
+
+ if (windowControl != 0)
+ d->windowBackend = new QWindowVideoWidgetBackend(windowControl, this);
+
+ QVideoRendererControl *rendererControl = qobject_cast<QVideoRendererControl *>(
+ d->service->control(QVideoRendererControl_iid));
+
+ if (rendererControl != 0)
+ d->rendererBackend = new QRendererVideoWidgetBackend(rendererControl, this);
+ }
+
+ if (isVisible())
+ d->show();
+ }
+}
+
+/*!
+ \property QVideoWidget::aspectRatioMode
+ \brief how video is scaled with respect to its aspect ratio.
+*/
+
+Qt::AspectRatioMode QVideoWidget::aspectRatioMode() const
+{
+ return d_func()->aspectRatioMode;
+}
+
+void QVideoWidget::setAspectRatioMode(Qt::AspectRatioMode mode)
+{
+ Q_D(QVideoWidget);
+
+ if (d->currentControl) {
+ d->currentControl->setAspectRatioMode(mode);
+ d->aspectRatioMode = d->currentControl->aspectRatioMode();
+ } else {
+ d->aspectRatioMode = mode;
+ }
+}
+
+/*!
+ \property QVideoWidget::fullScreen
+ \brief whether video display is confined to a window or is fullScreen.
+*/
+
+void QVideoWidget::setFullScreen(bool fullScreen)
+{
+ Q_D(QVideoWidget);
+
+ if (fullScreen) {
+ Qt::WindowFlags flags = windowFlags();
+
+ d->nonFullScreenFlags = flags & (Qt::Window | Qt::SubWindow);
+ flags |= Qt::Window;
+ flags &= ~Qt::SubWindow;
+ setWindowFlags(flags);
+
+ showFullScreen();
+ } else {
+ showNormal();
+ }
+}
+
+/*!
+ \fn QVideoWidget::fullScreenChanged(bool fullScreen)
+
+ Signals that the \a fullScreen mode of a video widget has changed.
+
+ \sa fullScreen
+*/
+
+/*!
+ \property QVideoWidget::brightness
+ \brief an adjustment to the brightness of displayed video.
+
+ Valid brightness values range between -100 and 100, the default is 0.
+*/
+
+int QVideoWidget::brightness() const
+{
+ return d_func()->brightness;
+}
+
+void QVideoWidget::setBrightness(int brightness)
+{
+ Q_D(QVideoWidget);
+
+ int boundedBrightness = qBound(-100, brightness, 100);
+
+ if (d->currentControl)
+ d->currentControl->setBrightness(boundedBrightness);
+ else if (d->brightness != boundedBrightness)
+ emit brightnessChanged(d->brightness = boundedBrightness);
+}
+
+/*!
+ \fn QVideoWidget::brightnessChanged(int brightness)
+
+ Signals that a video widgets's \a brightness adjustment has changed.
+
+ \sa brightness
+*/
+
+/*!
+ \property QVideoWidget::contrast
+ \brief an adjustment to the contrast of displayed video.
+
+ Valid contrast values range between -100 and 100, the default is 0.
+
+*/
+
+int QVideoWidget::contrast() const
+{
+ return d_func()->contrast;
+}
+
+void QVideoWidget::setContrast(int contrast)
+{
+ Q_D(QVideoWidget);
+
+ int boundedContrast = qBound(-100, contrast, 100);
+
+ if (d->currentControl)
+ d->currentControl->setContrast(boundedContrast);
+ else if (d->contrast != boundedContrast)
+ emit contrastChanged(d->contrast = boundedContrast);
+}
+
+/*!
+ \fn QVideoWidget::contrastChanged(int contrast)
+
+ Signals that a video widgets's \a contrast adjustment has changed.
+
+ \sa contrast
+*/
+
+/*!
+ \property QVideoWidget::hue
+ \brief an adjustment to the hue of displayed video.
+
+ Valid hue values range between -100 and 100, the default is 0.
+*/
+
+int QVideoWidget::hue() const
+{
+ return d_func()->hue;
+}
+
+void QVideoWidget::setHue(int hue)
+{
+ Q_D(QVideoWidget);
+
+ int boundedHue = qBound(-100, hue, 100);
+
+ if (d->currentControl)
+ d->currentControl->setHue(boundedHue);
+ else if (d->hue != boundedHue)
+ emit hueChanged(d->hue = boundedHue);
+}
+
+/*!
+ \fn QVideoWidget::hueChanged(int hue)
+
+ Signals that a video widgets's \a hue has changed.
+
+ \sa hue
+*/
+
+/*!
+ \property QVideoWidget::saturation
+ \brief an adjustment to the saturation of displayed video.
+
+ Valid saturation values range between -100 and 100, the default is 0.
+*/
+
+int QVideoWidget::saturation() const
+{
+ return d_func()->saturation;
+}
+
+void QVideoWidget::setSaturation(int saturation)
+{
+ Q_D(QVideoWidget);
+
+ int boundedSaturation = qBound(-100, saturation, 100);
+
+ if (d->currentControl)
+ d->currentControl->setSaturation(boundedSaturation);
+ else if (d->saturation != boundedSaturation)
+ emit saturationChanged(d->saturation = boundedSaturation);
+
+}
+
+/*!
+ \fn QVideoWidget::saturationChanged(int saturation)
+
+ Signals that a video widgets's \a saturation has changed.
+
+ \sa saturation
+*/
+
+/*!
+ Returns the size hint for the current back end,
+ if there is one, or else the size hint from QWidget.
+ */
+QSize QVideoWidget::sizeHint() const
+{
+ Q_D(const QVideoWidget);
+
+ if (d->currentBackend)
+ return d->currentBackend->sizeHint();
+ else
+ return QWidget::sizeHint();
+
+
+}
+
+/*!
+ \reimp
+ \internal
+ */
+bool QVideoWidget::event(QEvent *event)
+{
+ Q_D(QVideoWidget);
+
+ if (event->type() == QEvent::WindowStateChange) {
+ Qt::WindowFlags flags = windowFlags();
+
+ if (windowState() & Qt::WindowFullScreen) {
+ if (d->currentControl)
+ d->currentControl->setFullScreen(true);
+
+ if (!d->wasFullScreen)
+ emit fullScreenChanged(d->wasFullScreen = true);
+ } else {
+ if (d->currentControl)
+ d->currentControl->setFullScreen(false);
+
+ if (d->wasFullScreen) {
+ flags &= ~(Qt::Window | Qt::SubWindow); //clear the flags...
+ flags |= d->nonFullScreenFlags; //then we reset the flags (window and subwindow)
+ setWindowFlags(flags);
+
+ emit fullScreenChanged(d->wasFullScreen = false);
+ }
+ }
+ }
+ return QWidget::event(event);
+}
+
+/*!
+ Handles the show \a event.
+ */
+void QVideoWidget::showEvent(QShowEvent *event)
+{
+ Q_D(QVideoWidget);
+
+ QWidget::showEvent(event);
+
+ d->show();
+
+}
+
+/*!
+
+ Handles the hide \a event.
+*/
+void QVideoWidget::hideEvent(QHideEvent *event)
+{
+ Q_D(QVideoWidget);
+
+ if (d->currentBackend)
+ d->currentBackend->hideEvent(event);
+
+ QWidget::hideEvent(event);
+}
+
+/*!
+ Handles the resize \a event.
+ */
+void QVideoWidget::resizeEvent(QResizeEvent *event)
+{
+ Q_D(QVideoWidget);
+
+ QWidget::resizeEvent(event);
+
+ if (d->currentBackend)
+ d->currentBackend->resizeEvent(event);
+}
+
+/*!
+ Handles the move \a event.
+ */
+void QVideoWidget::moveEvent(QMoveEvent *event)
+{
+ Q_D(QVideoWidget);
+
+ if (d->currentBackend)
+ d->currentBackend->moveEvent(event);
+}
+
+/*!
+ Handles the paint \a event.
+ */
+void QVideoWidget::paintEvent(QPaintEvent *event)
+{
+ Q_D(QVideoWidget);
+
+ if (d->currentBackend) {
+ d->currentBackend->paintEvent(event);
+ } else if (testAttribute(Qt::WA_OpaquePaintEvent)) {
+ QPainter painter(this);
+
+ painter.fillRect(event->rect(), palette().window());
+ }
+}
+
+#include "moc_qvideowidget.cpp"
+#include "moc_qvideowidget_p.cpp"
+
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/mediaservices/base/qvideowidget.h b/src/multimedia/mediaservices/base/qvideowidget.h
new file mode 100644
index 0000000..a21739a
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qvideowidget.h
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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$
+**
+****************************************************************************/
+
+#ifndef QVIDEOWIDGET_H
+#define QVIDEOWIDGET_H
+
+#include <QtGui/qwidget.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QMediaObject;
+
+class QVideoWidgetPrivate;
+class Q_MEDIASERVICES_EXPORT QVideoWidget : public QWidget
+{
+ Q_OBJECT
+ Q_PROPERTY(QMediaObject* mediaObject READ mediaObject WRITE setMediaObject)
+ Q_PROPERTY(bool fullScreen READ isFullScreen WRITE setFullScreen NOTIFY fullScreenChanged)
+ Q_PROPERTY(Qt::AspectRatioMode aspectRatioMode READ aspectRatioMode WRITE setAspectRatioMode NOTIFY aspectRatioModeChanged)
+ Q_PROPERTY(int brightness READ brightness WRITE setBrightness NOTIFY brightnessChanged)
+ Q_PROPERTY(int contrast READ contrast WRITE setContrast NOTIFY contrastChanged)
+ Q_PROPERTY(int hue READ hue WRITE setHue NOTIFY hueChanged)
+ Q_PROPERTY(int saturation READ saturation WRITE setSaturation NOTIFY saturationChanged)
+
+public:
+ QVideoWidget(QWidget *parent = 0);
+ ~QVideoWidget();
+
+ QMediaObject *mediaObject() const;
+ void setMediaObject(QMediaObject *object);
+
+#ifdef Q_QDOC
+ bool isFullScreen() const;
+#endif
+
+ Qt::AspectRatioMode aspectRatioMode() const;
+
+ int brightness() const;
+ int contrast() const;
+ int hue() const;
+ int saturation() const;
+
+ QSize sizeHint() const;
+
+public Q_SLOTS:
+ void setFullScreen(bool fullScreen);
+ void setAspectRatioMode(Qt::AspectRatioMode mode);
+ void setBrightness(int brightness);
+ void setContrast(int contrast);
+ void setHue(int hue);
+ void setSaturation(int saturation);
+
+Q_SIGNALS:
+ void fullScreenChanged(bool fullScreen);
+ void brightnessChanged(int brightness);
+ void contrastChanged(int contrast);
+ void hueChanged(int hue);
+ void saturationChanged(int saturation);
+
+protected:
+ bool event(QEvent *event);
+ void showEvent(QShowEvent *event);
+ void hideEvent(QHideEvent *event);
+ void resizeEvent(QResizeEvent *event);
+ void moveEvent(QMoveEvent *event);
+ void paintEvent(QPaintEvent *event);
+
+protected:
+ QVideoWidgetPrivate *d_ptr;
+
+private:
+ Q_DECLARE_PRIVATE(QVideoWidget)
+ Q_PRIVATE_SLOT(d_func(), void _q_serviceDestroyed())
+ Q_PRIVATE_SLOT(d_func(), void _q_mediaObjectDestroyed())
+ Q_PRIVATE_SLOT(d_func(), void _q_brightnessChanged(int))
+ Q_PRIVATE_SLOT(d_func(), void _q_contrastChanged(int))
+ Q_PRIVATE_SLOT(d_func(), void _q_hueChanged(int))
+ Q_PRIVATE_SLOT(d_func(), void _q_saturationChanged(int))
+ Q_PRIVATE_SLOT(d_func(), void _q_fullScreenChanged(bool))
+ Q_PRIVATE_SLOT(d_func(), void _q_dimensionsChanged())
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/multimedia/mediaservices/base/qvideowidget_p.h b/src/multimedia/mediaservices/base/qvideowidget_p.h
new file mode 100644
index 0000000..bb44dfa
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qvideowidget_p.h
@@ -0,0 +1,271 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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$
+**
+****************************************************************************/
+
+#ifndef QVIDEOWIDGET_P_H
+#define QVIDEOWIDGET_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtMediaServices/qvideowidget.h>
+
+#ifndef QT_NO_OPENGL
+#include <QGLWidget>
+#endif
+
+#include "qpaintervideosurface_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+
+class QVideoWidgetControlInterface
+{
+public:
+ virtual ~QVideoWidgetControlInterface() {}
+
+ virtual void setBrightness(int brightness) = 0;
+ virtual void setContrast(int contrast) = 0;
+ virtual void setHue(int hue) = 0;
+ virtual void setSaturation(int saturation) = 0;
+
+ virtual void setFullScreen(bool fullScreen) = 0;
+
+ virtual Qt::AspectRatioMode aspectRatioMode() const = 0;
+ virtual void setAspectRatioMode(Qt::AspectRatioMode mode) = 0;
+};
+
+class QVideoWidgetBackend : public QObject, public QVideoWidgetControlInterface
+{
+ Q_OBJECT
+
+public:
+ virtual QSize sizeHint() const = 0;
+
+ virtual void showEvent() = 0;
+ virtual void hideEvent(QHideEvent *event) = 0;
+ virtual void resizeEvent(QResizeEvent *event) = 0;
+ virtual void moveEvent(QMoveEvent *event) = 0;
+ virtual void paintEvent(QPaintEvent *event) = 0;
+};
+
+class QVideoWidgetControl;
+
+class QVideoWidgetControlBackend : public QObject, public QVideoWidgetControlInterface
+{
+ Q_OBJECT
+public:
+ QVideoWidgetControlBackend(QVideoWidgetControl *control, QWidget *widget);
+
+ void setBrightness(int brightness);
+ void setContrast(int contrast);
+ void setHue(int hue);
+ void setSaturation(int saturation);
+
+ void setFullScreen(bool fullScreen);
+
+ Qt::AspectRatioMode aspectRatioMode() const;
+ void setAspectRatioMode(Qt::AspectRatioMode mode);
+
+private:
+ QVideoWidgetControl *m_widgetControl;
+};
+
+
+class QVideoRendererControl;
+
+class QRendererVideoWidgetBackend : public QVideoWidgetBackend
+{
+ Q_OBJECT
+public:
+ QRendererVideoWidgetBackend(QVideoRendererControl *control, QWidget *widget);
+ ~QRendererVideoWidgetBackend();
+
+ void clearSurface();
+
+ void setBrightness(int brightness);
+ void setContrast(int contrast);
+ void setHue(int hue);
+ void setSaturation(int saturation);
+
+ void setFullScreen(bool fullScreen);
+
+ Qt::AspectRatioMode aspectRatioMode() const;
+ void setAspectRatioMode(Qt::AspectRatioMode mode);
+
+ QSize sizeHint() const;
+
+ void showEvent();
+ void hideEvent(QHideEvent *event);
+ void resizeEvent(QResizeEvent *event);
+ void moveEvent(QMoveEvent *event);
+ void paintEvent(QPaintEvent *event);
+
+Q_SIGNALS:
+ void fullScreenChanged(bool fullScreen);
+ void brightnessChanged(int brightness);
+ void contrastChanged(int contrast);
+ void hueChanged(int hue);
+ void saturationChanged(int saturation);
+
+private Q_SLOTS:
+ void formatChanged(const QVideoSurfaceFormat &format);
+ void frameChanged();
+
+private:
+ void updateRects();
+
+ QVideoRendererControl *m_rendererControl;
+ QWidget *m_widget;
+ QPainterVideoSurface *m_surface;
+ Qt::AspectRatioMode m_aspectRatioMode;
+ QRect m_boundingRect;
+ QRectF m_sourceRect;
+ QSize m_nativeSize;
+ bool m_updatePaintDevice;
+};
+
+class QVideoWindowControl;
+
+class QWindowVideoWidgetBackend : public QVideoWidgetBackend
+{
+ Q_OBJECT
+public:
+ QWindowVideoWidgetBackend(QVideoWindowControl *control, QWidget *widget);
+ ~QWindowVideoWidgetBackend();
+
+ void setBrightness(int brightness);
+ void setContrast(int contrast);
+ void setHue(int hue);
+ void setSaturation(int saturation);
+
+ void setFullScreen(bool fullScreen);
+
+ Qt::AspectRatioMode aspectRatioMode() const;
+ void setAspectRatioMode(Qt::AspectRatioMode mode);
+
+ QSize sizeHint() const;
+
+ void showEvent();
+ void hideEvent(QHideEvent *event);
+ void resizeEvent(QResizeEvent *event);
+ void moveEvent(QMoveEvent *event);
+ void paintEvent(QPaintEvent *event);
+
+private:
+ QVideoWindowControl *m_windowControl;
+ QWidget *m_widget;
+ Qt::AspectRatioMode m_aspectRatioMode;
+ QSize m_pixelAspectRatio;
+};
+
+class QMediaService;
+class QVideoOutputControl;
+
+class QVideoWidgetPrivate
+{
+ Q_DECLARE_PUBLIC(QVideoWidget)
+public:
+ QVideoWidgetPrivate()
+ : q_ptr(0)
+ , mediaObject(0)
+ , service(0)
+ , outputControl(0)
+ , widgetBackend(0)
+ , windowBackend(0)
+ , rendererBackend(0)
+ , currentControl(0)
+ , currentBackend(0)
+ , brightness(0)
+ , contrast(0)
+ , hue(0)
+ , saturation(0)
+ , aspectRatioMode(Qt::KeepAspectRatio)
+ , nonFullScreenFlags(0)
+ , wasFullScreen(false)
+ {
+ }
+
+ QVideoWidget *q_ptr;
+ QMediaObject *mediaObject;
+ QMediaService *service;
+ QVideoOutputControl *outputControl;
+ QVideoWidgetControlBackend *widgetBackend;
+ QWindowVideoWidgetBackend *windowBackend;
+ QRendererVideoWidgetBackend *rendererBackend;
+ QVideoWidgetControlInterface *currentControl;
+ QVideoWidgetBackend *currentBackend;
+ int brightness;
+ int contrast;
+ int hue;
+ int saturation;
+ Qt::AspectRatioMode aspectRatioMode;
+ Qt::WindowFlags nonFullScreenFlags;
+ bool wasFullScreen;
+
+ void setCurrentControl(QVideoWidgetControlInterface *control);
+ void show();
+ void clearService();
+
+ void _q_serviceDestroyed();
+ void _q_mediaObjectDestroyed();
+ void _q_brightnessChanged(int brightness);
+ void _q_contrastChanged(int contrast);
+ void _q_hueChanged(int hue);
+ void _q_saturationChanged(int saturation);
+ void _q_fullScreenChanged(bool fullScreen);
+ void _q_dimensionsChanged();
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/multimedia/mediaservices/base/qvideowidgetcontrol.cpp b/src/multimedia/mediaservices/base/qvideowidgetcontrol.cpp
new file mode 100644
index 0000000..538f158
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qvideowidgetcontrol.cpp
@@ -0,0 +1,235 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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 <QtMediaServices/qvideowidgetcontrol.h>
+#include "qmediacontrol_p.h"
+
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QVideoWidgetControl
+ \preliminary
+ \since 4.7
+ \brief The QVideoWidgetControl class provides a media control which
+ implements a video widget.
+
+ \ingroup multimedia-serv
+
+ The videoWidget() property of QVideoWidgetControl provides a pointer to
+ a video widget implemented by the control's media service. This widget
+ is owned by the media service and so care should be taken not to delete it.
+
+ \code
+ QVideoWidgetControl *widgetControl = mediaService->control<QVideoWidgetControl *>();
+
+ layout->addWidget(widgetControl->widget());
+ \endcode
+
+ QVideoWidgetControl is one of number of possible video output controls,
+ in order to receive video it must be made the active video output
+ control by setting the output property of QVideoOutputControl to \l {QVideoOutputControl::WidgetOutput}{WidgetOutput}. Consequently any
+ QMediaService that implements QVideoWidgetControl must also implement
+ QVideoOutputControl.
+
+ The interface name of QVideoWidgetControl is \c com.nokia.Qt.QVideoWidgetControl/1.0 as
+ defined in QVideoWidgetControl_iid.
+
+ \sa QMediaService::control(), QVideoOutputControl, QVideoWidget
+*/
+
+/*!
+ \macro QVideoWidgetControl_iid
+
+ \c com.nokia.Qt.QVideoWidgetControl/1.0
+
+ Defines the interface name of the QVideoWidgetControl class.
+
+ \relates QVideoWidgetControl
+*/
+
+/*!
+ Constructs a new video widget control with the given \a parent.
+*/
+QVideoWidgetControl::QVideoWidgetControl(QObject *parent)
+ :QMediaControl(parent)
+{
+}
+
+/*!
+ Destroys a video widget control.
+*/
+QVideoWidgetControl::~QVideoWidgetControl()
+{
+}
+
+/*!
+ \fn QVideoWidgetControl::isFullScreen() const
+
+ Returns true if the video is shown using the complete screen.
+*/
+
+/*!
+ \fn QVideoWidgetControl::setFullScreen(bool fullScreen)
+
+ Sets whether a video widget is in \a fullScreen mode.
+*/
+
+/*!
+ \fn QVideoWidgetControl::fullScreenChanged(bool fullScreen)
+
+ Signals that the \a fullScreen state of a video widget has changed.
+*/
+
+/*!
+ \fn QVideoWidgetControl::aspectRatioMode() const
+
+ Returns how video is scaled to fit the widget with respect to its aspect ratio.
+*/
+
+/*!
+ \fn QVideoWidgetControl::setAspectRatioMode(Qt::AspectRatioMode mode)
+
+ Sets the aspect ratio \a mode which determines how video is scaled to the fit the widget with
+ respect to its aspect ratio.
+*/
+
+/*!
+ \fn QVideoWidgetControl::brightness() const
+
+ Returns the brightness adjustment applied to a video.
+
+ Valid brightness values range between -100 and 100, the default is 0.
+*/
+
+/*!
+ \fn QVideoWidgetControl::setBrightness(int brightness)
+
+ Sets a \a brightness adjustment for a video.
+
+ Valid brightness values range between -100 and 100, the default is 0.
+*/
+
+/*!
+ \fn QVideoWidgetControl::brightnessChanged(int brightness)
+
+ Signals that a video widget's \a brightness adjustment has changed.
+*/
+
+/*!
+ \fn QVideoWidgetControl::contrast() const
+
+ Returns the contrast adjustment applied to a video.
+
+ Valid contrast values range between -100 and 100, the default is 0.
+*/
+
+/*!
+ \fn QVideoWidgetControl::setContrast(int contrast)
+
+ Sets the contrast adjustment for a video widget to \a contrast.
+
+ Valid contrast values range between -100 and 100, the default is 0.
+*/
+
+
+/*!
+ \fn QVideoWidgetControl::contrastChanged(int contrast)
+
+ Signals that a video widget's \a contrast adjustment has changed.
+*/
+
+/*!
+ \fn QVideoWidgetControl::hue() const
+
+ Returns the hue adjustment applied to a video widget.
+
+ Value hue values range between -100 and 100, the default is 0.
+*/
+
+/*!
+ \fn QVideoWidgetControl::setHue(int hue)
+
+ Sets a \a hue adjustment for a video widget.
+
+ Valid hue values range between -100 and 100, the default is 0.
+*/
+
+
+/*!
+ \fn QVideoWidgetControl::hueChanged(int hue)
+
+ Signals that a video widget's \a hue adjustment has changed.
+*/
+
+/*!
+ \fn QVideoWidgetControl::saturation() const
+
+ Returns the saturation adjustment applied to a video widget.
+
+ Value saturation values range between -100 and 100, the default is 0.
+*/
+
+
+/*!
+ \fn QVideoWidgetControl::setSaturation(int saturation)
+
+ Sets a \a saturation adjustment for a video widget.
+
+ Valid saturation values range between -100 and 100, the default is 0.
+*/
+
+/*!
+ \fn QVideoWidgetControl::saturationChanged(int saturation)
+
+ Signals that a video widget's \a saturation adjustment has changed.
+*/
+
+/*!
+ \fn QVideoWidgetControl::videoWidget()
+
+ Returns the QWidget.
+*/
+
+#include "moc_qvideowidgetcontrol.cpp"
+
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/mediaservices/base/qvideowidgetcontrol.h b/src/multimedia/mediaservices/base/qvideowidgetcontrol.h
new file mode 100644
index 0000000..1013beb
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qvideowidgetcontrol.h
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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$
+**
+****************************************************************************/
+
+#ifndef QVIDEOWIDGETCONTROL_H
+#define QVIDEOWIDGETCONTROL_H
+
+#include <QtGui/qwidget.h>
+
+#include <QtMediaServices/qvideowidget.h>
+#include <QtMediaServices/qmediacontrol.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QVideoWidgetControlPrivate;
+
+class Q_MEDIASERVICES_EXPORT QVideoWidgetControl : public QMediaControl
+{
+ Q_OBJECT
+
+public:
+ virtual ~QVideoWidgetControl();
+
+ virtual QWidget *videoWidget() = 0;
+
+ virtual Qt::AspectRatioMode aspectRatioMode() const = 0;
+ virtual void setAspectRatioMode(Qt::AspectRatioMode mode) = 0;
+
+ virtual bool isFullScreen() const = 0;
+ virtual void setFullScreen(bool fullScreen) = 0;
+
+ virtual int brightness() const = 0;
+ virtual void setBrightness(int brightness) = 0;
+
+ virtual int contrast() const = 0;
+ virtual void setContrast(int contrast) = 0;
+
+ virtual int hue() const = 0;
+ virtual void setHue(int hue) = 0;
+
+ virtual int saturation() const = 0;
+ virtual void setSaturation(int saturation) = 0;
+
+Q_SIGNALS:
+ void fullScreenChanged(bool fullScreen);
+ void brightnessChanged(int brightness);
+ void contrastChanged(int contrast);
+ void hueChanged(int hue);
+ void saturationChanged(int saturation);
+
+protected:
+ QVideoWidgetControl(QObject *parent = 0);
+};
+
+#define QVideoWidgetControl_iid "com.nokia.Qt.QVideoWidgetControl/1.0"
+Q_MEDIA_DECLARE_CONTROL(QVideoWidgetControl, QVideoWidgetControl_iid)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/multimedia/mediaservices/base/qvideowindowcontrol.cpp b/src/multimedia/mediaservices/base/qvideowindowcontrol.cpp
new file mode 100644
index 0000000..967a2d6
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qvideowindowcontrol.cpp
@@ -0,0 +1,275 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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 <QtMediaServices/qvideowindowcontrol.h>
+
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QVideoWindowControl
+ \preliminary
+ \since 4.7
+ \ingroup multimedia-serv
+ \brief The QVideoWindowControl class provides a media control for rendering video to a window.
+
+
+ The winId() property QVideoWindowControl allows a platform specific
+ window ID to be set as the video render target of a QMediaService. The
+ displayRect() property is used to set the region of the window the
+ video should be rendered to, and the aspectRatioMode() property
+ indicates how the video should be scaled to fit the displayRect().
+
+ \code
+ QVideoWindowControl *windowControl = mediaService->control<QVideoWindowControl *>();
+ windowControl->setWinId(widget->winId());
+ windowControl->setDisplayRect(widget->rect());
+ windowControl->setAspectRatioMode(Qt::KeepAspectRatio);
+ \endcode
+
+ QVideoWindowControl is one of number of possible video output controls,
+ in order to receive video it must be made the active video output
+ control by setting the output property of QVideoOutputControl to \l {QVideoOutputControl::WindowOutput}{WindowOutput}.
+ Consequently any QMediaService that implements QVideoWindowControl must
+ also implement QVideoOutputControl.
+
+ \code
+ QVideoOutputControl *outputControl = mediaService->control<QVideoOutputControl *>();
+ outputControl->setOutput(QVideoOutputControl::WindowOutput);
+ \endcode
+
+ The interface name of QVideoWindowControl is \c com.nokia.Qt.QVideoWindowControl/1.0 as
+ defined in QVideoWindowControl_iid.
+
+ \sa QMediaService::control(), QVideoOutputControl, QVideoWidget
+*/
+
+/*!
+ \macro QVideoWindowControl_iid
+
+ \c com.nokia.Qt.QVideoWindowControl/1.0
+
+ Defines the interface name of the QVideoWindowControl class.
+
+ \relates QVideoWindowControl
+*/
+
+/*!
+ Constructs a new video window control with the given \a parent.
+*/
+QVideoWindowControl::QVideoWindowControl(QObject *parent)
+ : QMediaControl(parent)
+{
+}
+
+/*!
+ Destroys a video window control.
+*/
+QVideoWindowControl::~QVideoWindowControl()
+{
+}
+
+/*!
+ \fn QVideoWindowControl::winId() const
+
+ Returns the ID of the window a video overlay end point renders to.
+*/
+
+/*!
+ \fn QVideoWindowControl::setWinId(WId id)
+
+ Sets the \a id of the window a video overlay end point renders to.
+*/
+
+/*!
+ \fn QVideoWindowControl::displayRect() const
+ Returns the sub-rect of a window where video is displayed.
+*/
+
+/*!
+ \fn QVideoWindowControl::setDisplayRect(const QRect &rect)
+ Sets the sub-\a rect of a window where video is displayed.
+*/
+
+/*!
+ \fn QVideoWindowControl::isFullScreen() const
+
+ Identifies if a video overlay is a fullScreen overlay.
+
+ Returns true if the video overlay is fullScreen, and false otherwise.
+*/
+
+/*!
+ \fn QVideoWindowControl::setFullScreen(bool fullScreen)
+
+ Sets whether a video overlay is a \a fullScreen overlay.
+*/
+
+/*!
+ \fn QVideoWindowControl::fullScreenChanged(bool fullScreen)
+
+ Signals that the \a fullScreen state of a video overlay has changed.
+*/
+
+/*!
+ \fn QVideoWindowControl::repaint()
+
+ Repaints the last frame.
+*/
+
+/*!
+ \fn QVideoWindowControl::nativeSize() const
+
+ Returns a suggested size for the video display based on the resolution and aspect ratio of the
+ video.
+*/
+
+/*!
+ \fn QVideoWindowControl::nativeSizeChanged()
+
+ Signals that the native dimensions of the video have changed.
+*/
+
+
+/*!
+ \fn QVideoWindowControl::aspectRatioMode() const
+
+ Returns how video is scaled to fit the display region with respect to its aspect ratio.
+*/
+
+/*!
+ \fn QVideoWindowControl::setAspectRatioMode(Qt::AspectRatioMode mode)
+
+ Sets the aspect ratio \a mode which determines how video is scaled to the fit the display region
+ with respect to its aspect ratio.
+*/
+
+/*!
+ \fn QVideoWindowControl::brightness() const
+
+ Returns the brightness adjustment applied to a video overlay.
+
+ Valid brightness values range between -100 and 100, the default is 0.
+*/
+
+/*!
+ \fn QVideoWindowControl::setBrightness(int brightness)
+
+ Sets a \a brightness adjustment for a video overlay.
+
+ Valid brightness values range between -100 and 100, the default is 0.
+*/
+
+/*!
+ \fn QVideoWindowControl::brightnessChanged(int brightness)
+
+ Signals that a video overlay's \a brightness adjustment has changed.
+*/
+
+/*!
+ \fn QVideoWindowControl::contrast() const
+
+ Returns the contrast adjustment applied to a video overlay.
+
+ Valid contrast values range between -100 and 100, the default is 0.
+*/
+
+/*!
+ \fn QVideoWindowControl::setContrast(int contrast)
+
+ Sets the \a contrast adjustment for a video overlay.
+
+ Valid contrast values range between -100 and 100, the default is 0.
+*/
+
+/*!
+ \fn QVideoWindowControl::contrastChanged(int contrast)
+
+ Signals that a video overlay's \a contrast adjustment has changed.
+*/
+
+/*!
+ \fn QVideoWindowControl::hue() const
+
+ Returns the hue adjustment applied to a video overlay.
+
+ Value hue values range between -100 and 100, the default is 0.
+*/
+
+/*!
+ \fn QVideoWindowControl::setHue(int hue)
+
+ Sets a \a hue adjustment for a video overlay.
+
+ Valid hue values range between -100 and 100, the default is 0.
+*/
+
+/*!
+ \fn QVideoWindowControl::hueChanged(int hue)
+
+ Signals that a video overlay's \a hue adjustment has changed.
+*/
+
+/*!
+ \fn QVideoWindowControl::saturation() const
+
+ Returns the saturation adjustment applied to a video overlay.
+
+ Value saturation values range between -100 and 100, the default is 0.
+*/
+
+/*!
+ \fn QVideoWindowControl::setSaturation(int saturation)
+ Sets a \a saturation adjustment for a video overlay.
+
+ Valid saturation values range between -100 and 100, the default is 0.
+*/
+
+/*!
+ \fn QVideoWindowControl::saturationChanged(int saturation)
+
+ Signals that a video overlay's \a saturation adjustment has changed.
+*/
+
+#include "moc_qvideowindowcontrol.cpp"
+
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/mediaservices/base/qvideowindowcontrol.h b/src/multimedia/mediaservices/base/qvideowindowcontrol.h
new file mode 100644
index 0000000..47ba520
--- /dev/null
+++ b/src/multimedia/mediaservices/base/qvideowindowcontrol.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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$
+**
+****************************************************************************/
+
+#ifndef QVIDEOWINDOWCONTROL_H
+#define QVIDEOWINDOWCONTROL_H
+
+#include <QtGui/qwidget.h>
+
+#include <QtMediaServices/qmediacontrol.h>
+#include <QtMediaServices/qvideowidget.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class Q_MEDIASERVICES_EXPORT QVideoWindowControl : public QMediaControl
+{
+ Q_OBJECT
+
+public:
+ ~QVideoWindowControl();
+
+ virtual WId winId() const = 0;
+ virtual void setWinId(WId id) = 0;
+
+ virtual QRect displayRect() const = 0;
+ virtual void setDisplayRect(const QRect &rect) = 0;
+
+ virtual bool isFullScreen() const = 0;
+ virtual void setFullScreen(bool fullScreen) = 0;
+
+ virtual void repaint() = 0;
+
+ virtual QSize nativeSize() const = 0;
+
+ virtual Qt::AspectRatioMode aspectRatioMode() const = 0;
+ virtual void setAspectRatioMode(Qt::AspectRatioMode mode) = 0;
+
+ virtual int brightness() const = 0;
+ virtual void setBrightness(int brightness) = 0;
+
+ virtual int contrast() const = 0;
+ virtual void setContrast(int contrast) = 0;
+
+ virtual int hue() const = 0;
+ virtual void setHue(int hue) = 0;
+
+ virtual int saturation() const = 0;
+ virtual void setSaturation(int saturation) = 0;
+
+Q_SIGNALS:
+ void fullScreenChanged(bool fullScreen);
+ void brightnessChanged(int brightness);
+ void contrastChanged(int contrast);
+ void hueChanged(int hue);
+ void saturationChanged(int saturation);
+ void nativeSizeChanged();
+
+protected:
+ QVideoWindowControl(QObject *parent = 0);
+};
+
+#define QVideoWindowControl_iid "com.nokia.Qt.QVideoWindowControl/1.0"
+Q_MEDIA_DECLARE_CONTROL(QVideoWindowControl, QVideoWindowControl_iid)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/multimedia/mediaservices/effects/effects.pri b/src/multimedia/mediaservices/effects/effects.pri
new file mode 100644
index 0000000..6307255
--- /dev/null
+++ b/src/multimedia/mediaservices/effects/effects.pri
@@ -0,0 +1,26 @@
+
+
+unix:!mac {
+ contains(QT_CONFIG, pulseaudio) {
+ DEFINES += QT_MULTIMEDIA_PULSEAUDIO
+ HEADERS += $$PWD/qsoundeffect_pulse_p.h
+ SOURCES += $$PWD/qsoundeffect_pulse_p.cpp
+ QMAKE_CXXFLAGS += $$QT_CFLAGS_PULSEAUDIO
+ LIBS += $$QT_LIBS_PULSEAUDIO
+ } else {
+ DEFINES += QT_MULTIMEDIA_QMEDIAPLAYER
+ HEADERS += $$PWD/qsoundeffect_qmedia_p.h
+ SOURCES += $$PWD/qsoundeffect_qmedia_p.cpp
+ }
+} else {
+ HEADERS += $$PWD/qsoundeffect_qsound_p.h
+ SOURCES += $$PWD/qsoundeffect_qsound_p.cpp
+}
+
+HEADERS += \
+ $$PWD/qsoundeffect_p.h \
+ $$PWD/wavedecoder_p.h
+
+SOURCES += \
+ $$PWD/qsoundeffect.cpp \
+ $$PWD/wavedecoder_p.cpp
diff --git a/src/multimedia/mediaservices/effects/qsoundeffect.cpp b/src/multimedia/mediaservices/effects/qsoundeffect.cpp
new file mode 100644
index 0000000..1992ee5
--- /dev/null
+++ b/src/multimedia/mediaservices/effects/qsoundeffect.cpp
@@ -0,0 +1,207 @@
+/****************************************************************************
+**
+** 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 QtMultimedia module 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 "qsoundeffect_p.h"
+
+#if defined(QT_MULTIMEDIA_PULSEAUDIO)
+#include "qsoundeffect_pulse_p.h"
+#elif(QT_MULTIMEDIA_QMEDIAPLAYER)
+#include "qsoundeffect_qmedia_p.h"
+#else
+#include "qsoundeffect_qsound_p.h"
+#endif
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmlclass SoundEffect QSoundEffect
+ \since 4.7
+ \brief The SoundEffect element provides a way to play sound effects in QML.
+
+ This element is part of the \bold{Qt.multimedia 4.7} module.
+
+ The following example plays a wav file on mouse click.
+
+ \qml
+ import Qt 4.7
+ import Qt.multimedia 4.7
+
+ Item {
+ SoundEffect {
+ id: playSound
+ source: "test.wav"
+ }
+ MouseArea {
+ id: playArea
+ anchors.fill: parent
+ onPressed: {
+ playSound.play()
+ }
+ }
+ }
+ \endqml
+*/
+
+/*!
+ \qmlproperty url SoundEffect::source
+
+ This property provides a way to control the sound to play.
+*/
+
+/*!
+ \qmlproperty int SoundEffect::loops
+
+ This property provides a way to control the number of times to repeat the sound on each play().
+*/
+
+/*!
+ \qmlproperty int SoundEffect::volume
+
+ This property provides a way to control the volume for playback.
+*/
+
+/*!
+ \qmlproperty bool SoundEffect::muted
+
+ This property provides a way to control muting.
+*/
+
+/*!
+ \qmlsignal SoundEffect::sourceChanged()
+
+ This handler is called when the source has changed.
+*/
+
+/*!
+ \qmlsignal SoundEffect::loopsChanged()
+
+ This handler is called when the number of loops has changes.
+*/
+
+/*!
+ \qmlsignal SoundEffect::volumeChanged()
+
+ This handler is called when the volume has changed.
+*/
+
+/*!
+ \qmlsignal SoundEffect::mutedChanged()
+
+ This handler is called when the mute state has changed.
+*/
+
+
+QSoundEffect::QSoundEffect(QObject *parent) :
+ QObject(parent)
+{
+ d = new QSoundEffectPrivate(this);
+ connect(d, SIGNAL(volumeChanged()), SIGNAL(volumeChanged()));
+ connect(d, SIGNAL(mutedChanged()), SIGNAL(mutedChanged()));
+}
+
+QSoundEffect::~QSoundEffect()
+{
+ d->deleteLater();
+}
+
+QUrl QSoundEffect::source() const
+{
+ return d->source();
+}
+
+void QSoundEffect::setSource(const QUrl &url)
+{
+ if (d->source() == url)
+ return;
+
+ d->setSource(url);
+
+ emit sourceChanged();
+}
+
+int QSoundEffect::loops() const
+{
+ return d->loopCount();
+}
+
+void QSoundEffect::setLoops(int loopCount)
+{
+ if (d->loopCount() == loopCount)
+ return;
+
+ d->setLoopCount(loopCount);
+ emit loopsChanged();
+}
+
+int QSoundEffect::volume() const
+{
+ return d->volume();
+}
+
+void QSoundEffect::setVolume(int volume)
+{
+ if (d->volume() == volume)
+ return;
+
+ d->setVolume(volume);
+ emit volumeChanged();
+}
+
+bool QSoundEffect::isMuted() const
+{
+ return d->isMuted();
+}
+
+void QSoundEffect::setMuted(bool muted)
+{
+ if (d->isMuted() == muted)
+ return;
+
+ d->setMuted(muted);
+ emit mutedChanged();
+}
+
+void QSoundEffect::play()
+{
+ d->play();
+}
+
+QT_END_NAMESPACE
diff --git a/src/multimedia/mediaservices/effects/qsoundeffect_p.h b/src/multimedia/mediaservices/effects/qsoundeffect_p.h
new file mode 100644
index 0000000..64ddb77
--- /dev/null
+++ b/src/multimedia/mediaservices/effects/qsoundeffect_p.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** 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 QtMediaServices module 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$
+**
+****************************************************************************/
+
+#ifndef QSOUNDEFFECT_H
+#define QSOUNDEFFECT_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+
+#include <QtCore/qobject.h>
+#include <QtCore/qurl.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QSoundEffectPrivate;
+class Q_MEDIASERVICES_EXPORT QSoundEffect : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
+ Q_PROPERTY(int loops READ loops WRITE setLoops NOTIFY loopsChanged)
+ Q_PROPERTY(int volume READ volume WRITE setVolume NOTIFY volumeChanged)
+ Q_PROPERTY(bool muted READ isMuted WRITE setMuted NOTIFY mutedChanged)
+
+public:
+ explicit QSoundEffect(QObject *parent = 0);
+ ~QSoundEffect();
+
+ QUrl source() const;
+ void setSource(const QUrl &url);
+
+ int loops() const;
+ void setLoops(int loopCount);
+
+ int volume() const;
+ void setVolume(int volume);
+
+ bool isMuted() const;
+ void setMuted(bool muted);
+
+Q_SIGNALS:
+ void sourceChanged();
+ void loopsChanged();
+ void volumeChanged();
+ void mutedChanged();
+
+public Q_SLOTS:
+ void play();
+
+private:
+ Q_DISABLE_COPY(QSoundEffect)
+ QSoundEffectPrivate* d;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif // QSOUNDEFFECT_H
diff --git a/src/multimedia/mediaservices/effects/qsoundeffect_pulse_p.cpp b/src/multimedia/mediaservices/effects/qsoundeffect_pulse_p.cpp
new file mode 100644
index 0000000..c856157
--- /dev/null
+++ b/src/multimedia/mediaservices/effects/qsoundeffect_pulse_p.cpp
@@ -0,0 +1,499 @@
+/****************************************************************************
+**
+** 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 QtMediaServices module 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$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qcoreapplication.h>
+#include <QtMultimedia/qaudioformat.h>
+#include <QtNetwork>
+#include <QTime>
+
+#include "wavedecoder_p.h"
+
+#include "qsoundeffect_pulse_p.h"
+
+#if defined(Q_WS_MAEMO_5)
+#include <pulse/ext-stream-restore.h>
+#endif
+
+#include <unistd.h>
+
+// Less than ideal
+#define PA_SCACHE_ENTRY_SIZE_MAX (1024*1024*16)
+
+QT_BEGIN_NAMESPACE
+
+namespace
+{
+inline pa_sample_spec audioFormatToSampleSpec(const QAudioFormat &format)
+{
+ pa_sample_spec spec;
+
+ spec.rate = format.frequency();
+ spec.channels = format.channels();
+
+ if (format.sampleSize() == 8)
+ spec.format = PA_SAMPLE_U8;
+ else if (format.sampleSize() == 16) {
+ switch (format.byteOrder()) {
+ case QAudioFormat::BigEndian: spec.format = PA_SAMPLE_S16BE; break;
+ case QAudioFormat::LittleEndian: spec.format = PA_SAMPLE_S16LE; break;
+ }
+ }
+ else if (format.sampleSize() == 32) {
+ switch (format.byteOrder()) {
+ case QAudioFormat::BigEndian: spec.format = PA_SAMPLE_S32BE; break;
+ case QAudioFormat::LittleEndian: spec.format = PA_SAMPLE_S32LE; break;
+ }
+ }
+
+ return spec;
+}
+
+class PulseDaemon
+{
+public:
+ PulseDaemon():m_prepared(false)
+ {
+ prepare();
+ }
+
+ ~PulseDaemon()
+ {
+ if (m_prepared)
+ release();
+ }
+
+ inline void lock()
+ {
+ pa_threaded_mainloop_lock(m_mainLoop);
+ }
+
+ inline void unlock()
+ {
+ pa_threaded_mainloop_unlock(m_mainLoop);
+ }
+
+ inline pa_context *context() const
+ {
+ return m_context;
+ }
+
+ int volume()
+ {
+ return m_vol;
+ }
+
+private:
+ void prepare()
+ {
+ m_vol = 100;
+
+ m_mainLoop = pa_threaded_mainloop_new();
+ if (m_mainLoop == 0) {
+ qWarning("PulseAudioService: unable to create pulseaudio mainloop");
+ return;
+ }
+
+ if (pa_threaded_mainloop_start(m_mainLoop) != 0) {
+ qWarning("PulseAudioService: unable to start pulseaudio mainloop");
+ pa_threaded_mainloop_free(m_mainLoop);
+ return;
+ }
+
+ m_mainLoopApi = pa_threaded_mainloop_get_api(m_mainLoop);
+
+ lock();
+ m_context = pa_context_new(m_mainLoopApi, QString(QLatin1String("QtPulseAudio:%1")).arg(::getpid()).toAscii().constData());
+
+#if defined(Q_WS_MAEMO_5)
+ pa_context_set_state_callback(m_context, context_state_callback, this);
+#endif
+ if (m_context == 0) {
+ qWarning("PulseAudioService: Unable to create new pulseaudio context");
+ pa_threaded_mainloop_free(m_mainLoop);
+ return;
+ }
+
+ if (pa_context_connect(m_context, NULL, (pa_context_flags_t)0, NULL) < 0) {
+ qWarning("PulseAudioService: pa_context_connect() failed");
+ pa_context_unref(m_context);
+ pa_threaded_mainloop_free(m_mainLoop);
+ return;
+ }
+ unlock();
+
+ m_prepared = true;
+ }
+
+ void release()
+ {
+ if (!m_prepared) return;
+ pa_threaded_mainloop_stop(m_mainLoop);
+ pa_threaded_mainloop_free(m_mainLoop);
+ m_prepared = false;
+ }
+
+#if defined(Q_WS_MAEMO_5)
+ static void context_state_callback(pa_context *c, void *userdata)
+ {
+ PulseDaemon *self = reinterpret_cast<PulseDaemon*>(userdata);
+ switch (pa_context_get_state(c)) {
+ case PA_CONTEXT_CONNECTING:
+ case PA_CONTEXT_AUTHORIZING:
+ case PA_CONTEXT_SETTING_NAME:
+ break;
+ case PA_CONTEXT_READY:
+ pa_ext_stream_restore_set_subscribe_cb(c, &stream_restore_monitor_callback, self);
+ pa_ext_stream_restore_subscribe(c, 1, NULL, self);
+ break;
+ default:
+ break;
+ }
+ }
+ static void stream_restore_monitor_callback(pa_context *c, void *userdata)
+ {
+ PulseDaemon *self = reinterpret_cast<PulseDaemon*>(userdata);
+ pa_ext_stream_restore2_read(c, &stream_restore_info_callback, self);
+ }
+ static void stream_restore_info_callback(pa_context *c, const pa_ext_stream_restore2_info *info,
+ int eol, void *userdata)
+ {
+ Q_UNUSED(c)
+
+ PulseDaemon *self = reinterpret_cast<PulseDaemon*>(userdata);
+
+ if (!eol) {
+ if (QString(info->name).startsWith(QLatin1String("sink-input-by-media-role:x-maemo"))) {
+ const unsigned str_length = 256;
+ char str[str_length];
+ pa_cvolume_snprint(str, str_length, &info->volume);
+ self->m_vol = QString(str).replace(" ","").replace("%","").mid(2).toInt();
+ }
+ }
+ }
+#endif
+
+ int m_vol;
+ bool m_prepared;
+ pa_context *m_context;
+ pa_threaded_mainloop *m_mainLoop;
+ pa_mainloop_api *m_mainLoopApi;
+};
+}
+
+Q_GLOBAL_STATIC(PulseDaemon, daemon)
+
+
+QSoundEffectPrivate::QSoundEffectPrivate(QObject* parent):
+ QObject(parent),
+ m_retry(false),
+ m_muted(false),
+ m_playQueued(false),
+ m_sampleLoaded(false),
+ m_volume(100),
+ m_duration(0),
+ m_dataUploaded(0),
+ m_loopCount(1),
+ m_runningCount(0),
+ m_reply(0),
+ m_stream(0),
+ m_networkAccessManager(0)
+{
+}
+
+QSoundEffectPrivate::~QSoundEffectPrivate()
+{
+ m_reply->deleteLater();
+ unloadSample();
+}
+
+QUrl QSoundEffectPrivate::source() const
+{
+ return m_source;
+}
+
+void QSoundEffectPrivate::setSource(const QUrl &url)
+{
+ if (url.isEmpty()) {
+ m_source = QUrl();
+ unloadSample();
+ return;
+ }
+
+ m_source = url;
+
+ if (m_networkAccessManager == 0)
+ m_networkAccessManager = new QNetworkAccessManager(this);
+
+ m_stream = m_networkAccessManager->get(QNetworkRequest(m_source));
+
+ unloadSample();
+ loadSample();
+}
+
+int QSoundEffectPrivate::loopCount() const
+{
+ return m_loopCount;
+}
+
+void QSoundEffectPrivate::setLoopCount(int loopCount)
+{
+ m_loopCount = loopCount;
+}
+
+int QSoundEffectPrivate::volume() const
+{
+ return m_volume;
+}
+
+void QSoundEffectPrivate::setVolume(int volume)
+{
+ m_volume = volume;
+}
+
+bool QSoundEffectPrivate::isMuted() const
+{
+ return m_muted;
+}
+
+void QSoundEffectPrivate::setMuted(bool muted)
+{
+ m_muted = muted;
+}
+
+void QSoundEffectPrivate::play()
+{
+ if (m_retry) {
+ m_retry = false;
+ setSource(m_source);
+ return;
+ }
+
+ if (!m_sampleLoaded) {
+ m_playQueued = true;
+ return;
+ }
+
+ m_runningCount += m_loopCount;
+
+ playSample();
+}
+
+void QSoundEffectPrivate::decoderReady()
+{
+ if (m_waveDecoder->size() >= PA_SCACHE_ENTRY_SIZE_MAX) {
+ m_waveDecoder->deleteLater();
+ qWarning("QSoundEffect(pulseaudio): Attempting to load to large a sample");
+ return;
+ }
+
+ if (m_name.isNull())
+ m_name = QString(QLatin1String("QtPulseSample-%1-%2")).arg(::getpid()).arg(quintptr(this)).toUtf8();
+
+ pa_sample_spec spec = audioFormatToSampleSpec(m_waveDecoder->audioFormat());
+
+ daemon()->lock();
+ pa_stream *stream = pa_stream_new(daemon()->context(), m_name.constData(), &spec, 0);
+ pa_stream_set_state_callback(stream, stream_state_callback, this);
+ pa_stream_set_write_callback(stream, stream_write_callback, this);
+ pa_stream_connect_upload(stream, (size_t)m_waveDecoder->size());
+ m_pulseStream = stream;
+ daemon()->unlock();
+}
+
+void QSoundEffectPrivate::decoderError()
+{
+ qWarning("QSoundEffect(pulseaudio): Error decoding source");
+}
+
+void QSoundEffectPrivate::checkPlayTime()
+{
+ int elapsed = m_playbackTime.elapsed();
+
+ if (elapsed < m_duration)
+ startTimer(m_duration - elapsed);
+}
+
+void QSoundEffectPrivate::loadSample()
+{
+ m_sampleLoaded = false;
+ m_dataUploaded = 0;
+ m_waveDecoder = new WaveDecoder(m_stream);
+ connect(m_waveDecoder, SIGNAL(formatKnown()), SLOT(decoderReady()));
+ connect(m_waveDecoder, SIGNAL(invalidFormat()), SLOT(decoderError()));
+}
+
+void QSoundEffectPrivate::unloadSample()
+{
+ if (!m_sampleLoaded)
+ return;
+
+ daemon()->lock();
+ pa_context_remove_sample(daemon()->context(), m_name.constData(), NULL, NULL);
+ daemon()->unlock();
+
+ m_duration = 0;
+ m_dataUploaded = 0;
+ m_sampleLoaded = false;
+}
+
+void QSoundEffectPrivate::uploadSample()
+{
+ daemon()->lock();
+
+ size_t bufferSize = qMin(pa_stream_writable_size(m_pulseStream),
+ size_t(m_waveDecoder->bytesAvailable()));
+ char buffer[bufferSize];
+
+ size_t len = 0;
+ while (len < (m_waveDecoder->size())) {
+ qint64 read = m_waveDecoder->read(buffer, qMin((int)bufferSize,
+ (int)(m_waveDecoder->size()-len)));
+ if (read > 0) {
+ if (pa_stream_write(m_pulseStream, buffer, size_t(read), 0, 0, PA_SEEK_RELATIVE) == 0)
+ len += size_t(read);
+ else
+ break;
+ }
+ }
+
+ m_dataUploaded += len;
+ pa_stream_set_write_callback(m_pulseStream, NULL, NULL);
+
+ if (m_waveDecoder->size() == m_dataUploaded) {
+ int err = pa_stream_finish_upload(m_pulseStream);
+ if(err != 0) {
+ qWarning("pa_stream_finish_upload() err=%d",err);
+ pa_stream_disconnect(m_pulseStream);
+ m_retry = true;
+ m_playQueued = false;
+ QMetaObject::invokeMethod(this, "play");
+ daemon()->unlock();
+ return;
+ }
+ m_duration = m_waveDecoder->duration();
+ m_waveDecoder->deleteLater();
+ m_stream->deleteLater();
+ m_sampleLoaded = true;
+ if (m_playQueued) {
+ m_playQueued = false;
+ QMetaObject::invokeMethod(this, "play");
+ }
+ }
+ daemon()->unlock();
+}
+
+void QSoundEffectPrivate::playSample()
+{
+ pa_volume_t volume = PA_VOLUME_NORM;
+
+ daemon()->lock();
+#ifdef Q_WS_MAEMO_5
+ volume = PA_VOLUME_NORM / 100 * ((daemon()->volume() + m_volume) / 2);
+#endif
+ pa_operation_unref(
+ pa_context_play_sample(daemon()->context(),
+ m_name.constData(),
+ 0,
+ volume,
+ play_callback,
+ this)
+ );
+ daemon()->unlock();
+
+ m_playbackTime.start();
+}
+
+void QSoundEffectPrivate::timerEvent(QTimerEvent *event)
+{
+ if (m_runningCount > 0)
+ playSample();
+
+ killTimer(event->timerId());
+}
+
+void QSoundEffectPrivate::stream_write_callback(pa_stream *s, size_t length, void *userdata)
+{
+ Q_UNUSED(length);
+
+ QSoundEffectPrivate *self = reinterpret_cast<QSoundEffectPrivate*>(userdata);
+
+ QMetaObject::invokeMethod(self, "uploadSample", Qt::QueuedConnection);
+}
+
+void QSoundEffectPrivate::stream_state_callback(pa_stream *s, void *userdata)
+{
+ switch (pa_stream_get_state(s)) {
+ case PA_STREAM_CREATING:
+ case PA_STREAM_READY:
+ case PA_STREAM_TERMINATED:
+ break;
+
+ case PA_STREAM_FAILED:
+ default:
+ qWarning("QSoundEffect(pulseaudio): Error in pulse audio stream");
+ break;
+ }
+}
+
+void QSoundEffectPrivate::play_callback(pa_context *c, int success, void *userdata)
+{
+ Q_UNUSED(c);
+
+ QSoundEffectPrivate *self = reinterpret_cast<QSoundEffectPrivate*>(userdata);
+
+ if (success == 1) {
+ self->m_runningCount--;
+ QMetaObject::invokeMethod(self, "checkPlayTime", Qt::QueuedConnection);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/multimedia/mediaservices/effects/qsoundeffect_pulse_p.h b/src/multimedia/mediaservices/effects/qsoundeffect_pulse_p.h
new file mode 100644
index 0000000..1327bf5
--- /dev/null
+++ b/src/multimedia/mediaservices/effects/qsoundeffect_pulse_p.h
@@ -0,0 +1,137 @@
+/****************************************************************************
+**
+** 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 QtMediaServices module 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$
+**
+****************************************************************************/
+
+#ifndef QSOUNDEFFECT_PULSE_H
+#define QSOUNDEFFECT_PULSE_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+
+#include "qsoundeffect_p.h"
+
+#include <QtCore/qobject.h>
+#include <QtCore/qdatetime.h>
+#include <QtMediaServices/qmediaplayer.h>
+#include <pulse/pulseaudio.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QNetworkReply;
+class QNetworkAccessManager;
+class WaveDecoder;
+
+class QSoundEffectPrivate : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QSoundEffectPrivate(QObject* parent);
+ ~QSoundEffectPrivate();
+
+ QUrl source() const;
+ void setSource(const QUrl &url);
+ int loopCount() const;
+ void setLoopCount(int loopCount);
+ int volume() const;
+ void setVolume(int volume);
+ bool isMuted() const;
+ void setMuted(bool muted);
+
+public Q_SLOTS:
+ void play();
+
+Q_SIGNALS:
+ void volumeChanged();
+ void mutedChanged();
+
+private Q_SLOTS:
+ void decoderReady();
+ void decoderError();
+ void checkPlayTime();
+ void uploadSample();
+
+private:
+ void loadSample();
+ void unloadSample();
+ void playSample();
+
+ void timerEvent(QTimerEvent *event);
+
+ static void stream_write_callback(pa_stream *s, size_t length, void *userdata);
+ static void stream_state_callback(pa_stream *s, void *userdata);
+ static void play_callback(pa_context *c, int success, void *userdata);
+
+ pa_stream *m_pulseStream;
+
+ bool m_retry;
+ bool m_muted;
+ bool m_playQueued;
+ bool m_sampleLoaded;
+ int m_volume;
+ int m_duration;
+ int m_dataUploaded;
+ int m_loopCount;
+ int m_runningCount;
+ QUrl m_source;
+ QTime m_playbackTime;
+ QByteArray m_name;
+ QNetworkReply *m_reply;
+ WaveDecoder *m_waveDecoder;
+ QIODevice *m_stream;
+ QNetworkAccessManager *m_networkAccessManager;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSOUNDEFFECT_PULSE_H
diff --git a/src/multimedia/mediaservices/effects/qsoundeffect_qmedia_p.cpp b/src/multimedia/mediaservices/effects/qsoundeffect_qmedia_p.cpp
new file mode 100644
index 0000000..5e40bed
--- /dev/null
+++ b/src/multimedia/mediaservices/effects/qsoundeffect_qmedia_p.cpp
@@ -0,0 +1,132 @@
+/****************************************************************************
+**
+** 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 QtMediaServices module 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$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qsoundeffect_qmedia_p.h"
+
+#include <QtCore/qcoreapplication.h>
+
+#include <QtMediaServices/qmediacontent.h>
+#include <QtMediaServices/qmediaplayer.h>
+
+
+QT_BEGIN_NAMESPACE
+
+QSoundEffectPrivate::QSoundEffectPrivate(QObject* parent):
+ QObject(parent),
+ m_loopCount(1),
+ m_runningCount(0),
+ m_player(0)
+{
+ m_player = new QMediaPlayer(this, QMediaPlayer::LowLatency);
+ connect(m_player, SIGNAL(stateChanged(QMediaPlayer::State)), SLOT(stateChanged(QMediaPlayer::State)));
+}
+
+QSoundEffectPrivate::~QSoundEffectPrivate()
+{
+}
+
+QUrl QSoundEffectPrivate::source() const
+{
+ return m_player->media().canonicalUrl();
+}
+
+void QSoundEffectPrivate::setSource(const QUrl &url)
+{
+ m_player->setMedia(url);
+}
+
+int QSoundEffectPrivate::loopCount() const
+{
+ return m_loopCount;
+}
+
+void QSoundEffectPrivate::setLoopCount(int loopCount)
+{
+ m_loopCount = loopCount;
+}
+
+int QSoundEffectPrivate::volume() const
+{
+ return m_player->volume();
+}
+
+void QSoundEffectPrivate::setVolume(int volume)
+{
+ m_player->setVolume(volume);
+}
+
+bool QSoundEffectPrivate::isMuted() const
+{
+ return m_player->isMuted();
+}
+
+void QSoundEffectPrivate::setMuted(bool muted)
+{
+ m_player->setMuted(muted);
+}
+
+void QSoundEffectPrivate::play()
+{
+ m_runningCount += m_loopCount;
+ m_player->play();
+}
+
+void QSoundEffectPrivate::stateChanged(QMediaPlayer::State state)
+{
+ if (state == QMediaPlayer::StoppedState) {
+ if (--m_runningCount > 0)
+ m_player->play();
+ }
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/mediaservices/effects/qsoundeffect_qmedia_p.h b/src/multimedia/mediaservices/effects/qsoundeffect_qmedia_p.h
new file mode 100644
index 0000000..82ea000
--- /dev/null
+++ b/src/multimedia/mediaservices/effects/qsoundeffect_qmedia_p.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** 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 QtMediaServices module 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$
+**
+****************************************************************************/
+
+#ifndef QSOUNDEFFECT_QMEDIA_H
+#define QSOUNDEFFECT_QMEDIA_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+
+#include <QtCore/qobject.h>
+#include <QtCore/qurl.h>
+#include <QtMediaServices/qmediaplayer.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+
+class QSoundEffectPrivate : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QSoundEffectPrivate(QObject* parent);
+ ~QSoundEffectPrivate();
+
+ QUrl source() const;
+ void setSource(const QUrl &url);
+ int loopCount() const;
+ void setLoopCount(int loopCount);
+ int volume() const;
+ void setVolume(int volume);
+ bool isMuted() const;
+ void setMuted(bool muted);
+
+public Q_SLOTS:
+ void play();
+
+Q_SIGNALS:
+ void volumeChanged();
+ void mutedChanged();
+
+private Q_SLOTS:
+ void stateChanged(QMediaPlayer::State);
+
+private:
+ int m_loopCount;
+ int m_runningCount;
+ QMediaPlayer *m_player;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSOUNDEFFECT_QMEDIA_H
diff --git a/src/multimedia/mediaservices/effects/qsoundeffect_qsound_p.cpp b/src/multimedia/mediaservices/effects/qsoundeffect_qsound_p.cpp
new file mode 100644
index 0000000..9247aba
--- /dev/null
+++ b/src/multimedia/mediaservices/effects/qsoundeffect_qsound_p.cpp
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** 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 QtMediaServices module 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$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qsoundeffect_qsound_p.h"
+
+#include <QtCore/qcoreapplication.h>
+#include <QtGui/qsound.h>
+
+
+QT_BEGIN_NAMESPACE
+
+QSoundEffectPrivate::QSoundEffectPrivate(QObject* parent):
+ QObject(parent),
+ m_muted(false),
+ m_loopCount(1),
+ m_volume(100),
+ m_sound(0)
+{
+}
+
+QSoundEffectPrivate::~QSoundEffectPrivate()
+{
+}
+
+QUrl QSoundEffectPrivate::source() const
+{
+ return m_source;
+}
+
+void QSoundEffectPrivate::setSource(const QUrl &url)
+{
+ if (url.isEmpty() || url.scheme() != QLatin1String("file")) {
+ m_source = QUrl();
+ return;
+ }
+
+ if (m_sound != 0)
+ delete m_sound;
+
+ m_source = url;
+ m_sound = new QSound(m_source.toLocalFile(), this);
+ m_sound->setLoops(m_loopCount);
+}
+
+int QSoundEffectPrivate::loopCount() const
+{
+ return m_loopCount;
+}
+
+void QSoundEffectPrivate::setLoopCount(int lc)
+{
+ m_loopCount = lc;
+ if (m_sound)
+ m_sound->setLoops(lc);
+}
+
+int QSoundEffectPrivate::volume() const
+{
+ return m_volume;
+}
+
+void QSoundEffectPrivate::setVolume(int v)
+{
+ m_volume = v;
+}
+
+bool QSoundEffectPrivate::isMuted() const
+{
+ return m_muted;
+}
+
+void QSoundEffectPrivate::setMuted(bool muted)
+{
+ m_muted = muted;
+}
+
+void QSoundEffectPrivate::play()
+{
+ m_sound->play();
+}
+
+QT_END_NAMESPACE
diff --git a/src/multimedia/mediaservices/effects/qsoundeffect_qsound_p.h b/src/multimedia/mediaservices/effects/qsoundeffect_qsound_p.h
new file mode 100644
index 0000000..dad7b6f
--- /dev/null
+++ b/src/multimedia/mediaservices/effects/qsoundeffect_qsound_p.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** 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 QtMediaServices module 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$
+**
+****************************************************************************/
+
+#ifndef QSOUNDEFFECT_QSOUND_H
+#define QSOUNDEFFECT_QSOUND_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+
+#include <QtCore/qobject.h>
+#include <QtCore/qurl.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QSound;
+
+class QSoundEffectPrivate : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QSoundEffectPrivate(QObject* parent);
+ ~QSoundEffectPrivate();
+
+ QUrl source() const;
+ void setSource(const QUrl &url);
+ int loopCount() const;
+ void setLoopCount(int loopCount);
+ int volume() const;
+ void setVolume(int volume);
+ bool isMuted() const;
+ void setMuted(bool muted);
+
+public Q_SLOTS:
+ void play();
+
+Q_SIGNALS:
+ void volumeChanged();
+ void mutedChanged();
+
+private:
+ bool m_muted;
+ int m_loopCount;
+ int m_volume;
+ QSound *m_sound;
+ QUrl m_source;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSOUNDEFFECT_QSOUND_H
diff --git a/src/multimedia/mediaservices/effects/wavedecoder_p.cpp b/src/multimedia/mediaservices/effects/wavedecoder_p.cpp
new file mode 100644
index 0000000..1c26c8f
--- /dev/null
+++ b/src/multimedia/mediaservices/effects/wavedecoder_p.cpp
@@ -0,0 +1,151 @@
+/****************************************************************************
+**
+** 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 QtMediaServices module 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 "wavedecoder_p.h"
+
+#include <QtCore/qtimer.h>
+#include <QtCore/qendian.h>
+
+QT_BEGIN_NAMESPACE
+
+WaveDecoder::WaveDecoder(QIODevice *s, QObject *parent):
+ QIODevice(parent),
+ haveFormat(false),
+ dataSize(0),
+ remaining(0),
+ source(s)
+{
+ open(QIODevice::ReadOnly | QIODevice::Unbuffered);
+
+ if (source->bytesAvailable() >= qint64(sizeof(CombinedHeader) + sizeof(DATAHeader) + sizeof(quint16)))
+ QTimer::singleShot(0, this, SLOT(handleData()));
+ else
+ connect(source, SIGNAL(readyRead()), SLOT(handleData()));
+}
+
+WaveDecoder::~WaveDecoder()
+{
+}
+
+QAudioFormat WaveDecoder::audioFormat() const
+{
+ return format;
+}
+
+int WaveDecoder::duration() const
+{
+ return size() * 1000 / (format.sampleSize() / 8) / format.channels() / format.frequency();
+}
+
+qint64 WaveDecoder::size() const
+{
+ return haveFormat ? dataSize : 0;
+}
+
+bool WaveDecoder::isSequential() const
+{
+ return source->isSequential();
+}
+
+qint64 WaveDecoder::bytesAvailable() const
+{
+ return haveFormat ? source->bytesAvailable() : 0;
+}
+
+qint64 WaveDecoder::readData(char *data, qint64 maxlen)
+{
+ return haveFormat ? source->read(data, maxlen) : 0;
+}
+
+qint64 WaveDecoder::writeData(const char *data, qint64 len)
+{
+ Q_UNUSED(data);
+ Q_UNUSED(len);
+
+ return -1;
+}
+
+void WaveDecoder::handleData()
+{
+ if (source->bytesAvailable() < qint64(sizeof(CombinedHeader) + sizeof(DATAHeader) + sizeof(quint16)))
+ return;
+
+ source->disconnect(SIGNAL(readyRead()), this, SLOT(handleData()));
+ source->read((char*)&header, sizeof(CombinedHeader));
+
+ if (qstrncmp(header.riff.descriptor.id, "RIFF", 4) != 0 ||
+ qstrncmp(header.riff.type, "WAVE", 4) != 0 ||
+ qstrncmp(header.wave.descriptor.id, "fmt ", 4) != 0 ||
+ (header.wave.audioFormat != 0 && header.wave.audioFormat != 1)) {
+
+ emit invalidFormat();
+ }
+ else {
+ DATAHeader dataHeader;
+
+ if (qFromLittleEndian<quint32>(header.wave.descriptor.size) > sizeof(WAVEHeader)) {
+ // Extended data available
+ quint16 extraFormatBytes;
+ source->peek((char*)&extraFormatBytes, sizeof(quint16));
+ extraFormatBytes = qFromLittleEndian<quint16>(extraFormatBytes);
+ source->read(sizeof(quint16) + extraFormatBytes); // dump it all
+ }
+
+ source->read((char*)&dataHeader, sizeof(DATAHeader));
+
+ int bps = qFromLittleEndian<quint16>(header.wave.bitsPerSample);
+
+ format.setCodec(QLatin1String("audio/pcm"));
+ format.setSampleType(bps == 8 ? QAudioFormat::UnSignedInt : QAudioFormat::SignedInt);
+ format.setByteOrder(QAudioFormat::LittleEndian);
+ format.setFrequency(qFromLittleEndian<quint32>(header.wave.sampleRate));
+ format.setSampleSize(bps);
+ format.setChannels(qFromLittleEndian<quint16>(header.wave.numChannels));
+
+ dataSize = qFromLittleEndian<quint32>(dataHeader.descriptor.size);
+
+ haveFormat = true;
+ connect(source, SIGNAL(readyRead()), SIGNAL(readyRead()));
+ emit formatKnown();
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/multimedia/mediaservices/effects/wavedecoder_p.h b/src/multimedia/mediaservices/effects/wavedecoder_p.h
new file mode 100644
index 0000000..dcc5453
--- /dev/null
+++ b/src/multimedia/mediaservices/effects/wavedecoder_p.h
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** 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 QtMediaServices module 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$
+**
+****************************************************************************/
+
+#ifndef WAVEDECODER_H
+#define WAVEDECODER_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qiodevice.h>
+#include <QtMultimedia/qaudioformat.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+
+class WaveDecoder : public QIODevice
+{
+ Q_OBJECT
+
+public:
+ explicit WaveDecoder(QIODevice *source, QObject *parent = 0);
+ ~WaveDecoder();
+
+ QAudioFormat audioFormat() const;
+ int duration() const;
+
+ qint64 size() const;
+ bool isSequential() const;
+ qint64 bytesAvailable() const;
+
+Q_SIGNALS:
+ void formatKnown();
+ void invalidFormat();
+
+private Q_SLOTS:
+ void handleData();
+
+private:
+ qint64 readData(char *data, qint64 maxlen);
+ qint64 writeData(const char *data, qint64 len);
+
+ struct chunk
+ {
+ char id[4];
+ quint32 size;
+ };
+ struct RIFFHeader
+ {
+ chunk descriptor;
+ char type[4];
+ };
+ struct WAVEHeader
+ {
+ chunk descriptor;
+ quint16 audioFormat;
+ quint16 numChannels;
+ quint32 sampleRate;
+ quint32 byteRate;
+ quint16 blockAlign;
+ quint16 bitsPerSample;
+ };
+ struct DATAHeader
+ {
+ chunk descriptor;
+ };
+ struct CombinedHeader
+ {
+ RIFFHeader riff;
+ WAVEHeader wave;
+ };
+
+ bool haveFormat;
+ qint64 dataSize;
+ qint64 remaining;
+ QAudioFormat format;
+ QIODevice *source;
+ CombinedHeader header;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // WAVEDECODER_H
diff --git a/src/multimedia/mediaservices/mediaservices.pro b/src/multimedia/mediaservices/mediaservices.pro
new file mode 100644
index 0000000..d5b0e4c
--- /dev/null
+++ b/src/multimedia/mediaservices/mediaservices.pro
@@ -0,0 +1,21 @@
+TARGET = QtMediaServices
+QPRO_PWD = $$PWD
+QT = core gui multimedia
+
+DEFINES += QT_BUILD_MEDIASERVICES_LIB QT_NO_USING_NAMESPACE
+
+unix:QMAKE_PKGCONFIG_REQUIRES = QtCore QtGui QtMultimedia
+
+include(../../qbase.pri)
+
+include(base/base.pri)
+include(playback/playback.pri)
+include(effects/effects.pri)
+
+symbian: {
+ TARGET.UID3 = 0x2001E631
+ contains(CONFIG, def_files) {
+ DEF_FILE=../../s60installs
+ }
+}
+
diff --git a/src/multimedia/mediaservices/playback/playback.pri b/src/multimedia/mediaservices/playback/playback.pri
new file mode 100644
index 0000000..09a81c9
--- /dev/null
+++ b/src/multimedia/mediaservices/playback/playback.pri
@@ -0,0 +1,11 @@
+
+HEADERS += \
+ $$PWD/qmediaplayer.h \
+ $$PWD/qmediaplayercontrol.h
+
+SOURCES += \
+ $$PWD/qmediaplayer.cpp \
+ $$PWD/qmediaplayercontrol.cpp
+
+
+
diff --git a/src/multimedia/mediaservices/playback/qmediaplayer.cpp b/src/multimedia/mediaservices/playback/qmediaplayer.cpp
new file mode 100644
index 0000000..ca1f250
--- /dev/null
+++ b/src/multimedia/mediaservices/playback/qmediaplayer.cpp
@@ -0,0 +1,996 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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 <QtCore/qcoreevent.h>
+#include <QtCore/qmetaobject.h>
+#include <QtCore/qtimer.h>
+#include <QtCore/qpointer.h>
+#include <QtCore/qdebug.h>
+
+#include <QtMediaServices/qmediaplayer.h>
+
+#include <QtMediaServices/private/qmediaobject_p.h>
+#include <QtMediaServices/qmediaservice.h>
+#include <QtMediaServices/qmediaplayercontrol.h>
+#include <QtMediaServices/qmediaserviceprovider.h>
+#include <QtMediaServices/qmediaplaylist.h>
+#include <QtMediaServices/qmediaplaylistcontrol.h>
+#include <QtMediaServices/qvideowidget.h>
+#include <QtMediaServices/qgraphicsvideoitem.h>
+
+//#define DEBUG_PLAYER_STATE
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+/*!
+ \class QMediaPlayer
+ \brief The QMediaPlayer class allows the playing of a media source.
+ \ingroup multimedia
+ \since 4.7
+ \preliminary
+
+ The QMediaPlayer class is a high level media playback class. It can be used
+ to playback such content as songs, movies and internet radio. The content
+ to playback is specified as a QMediaContent, which can be thought of as a
+ main or canonical URL with addition information attached. When provided
+ with a QMediaContent playback may be able to commence.
+
+ \code
+ player = new QMediaPlayer;
+ connect(player, SIGNAL(positionChanged(qint64)), this, SLOT(positionChanged(qint64)));
+ player->setMedia(QUrl::fromLocalFile("/Users/me/Music/coolsong.mp3"));
+ player->setVolume(50);
+ player->play();
+ \endcode
+
+ QVideoWidget can be used with QMediaPlayer for video rendering and QMediaPlaylist
+ for accessing playlist functionality.
+
+ \code
+ player = new QMediaPlayer;
+
+ playlist = new QMediaPlaylist;
+ playlist->setMediaObject(player);
+ playlist->append(QUrl("http://example.com/movie1.mp4"));
+ playlist->append(QUrl("http://example.com/movie2.mp4"));
+
+ widget = new QVideoWidget;
+ widget->setMediaObject(player);
+ widget->show();
+
+ player->play();
+ \endcode
+
+ \sa QMediaObject, QMediaService, QVideoWidget, QMediaPlaylist
+*/
+
+namespace
+{
+class MediaPlayerRegisterMetaTypes
+{
+public:
+ MediaPlayerRegisterMetaTypes()
+ {
+ qRegisterMetaType<QMediaPlayer::State>();
+ qRegisterMetaType<QMediaPlayer::MediaStatus>();
+ qRegisterMetaType<QMediaPlayer::Error>();
+ }
+} _registerPlayerMetaTypes;
+}
+
+class QMediaPlayerPrivate : public QMediaObjectPrivate
+{
+ Q_DECLARE_NON_CONST_PUBLIC(QMediaPlayer)
+
+public:
+ QMediaPlayerPrivate()
+ : provider(0)
+ , control(0)
+ , playlistControl(0)
+ , state(QMediaPlayer::StoppedState)
+ , error(QMediaPlayer::NoError)
+ , filterStates(false)
+ , playlist(0)
+ {}
+
+ QMediaServiceProvider *provider;
+ QMediaPlayerControl* control;
+ QMediaPlaylistControl* playlistControl;
+ QMediaPlayer::State state;
+ QMediaPlayer::Error error;
+ QString errorString;
+ bool filterStates;
+
+ QMediaPlaylist *playlist;
+ QPointer<QVideoWidget> videoWidget;
+#ifndef QT_NO_GRAPHICSVIEW
+ QPointer<QGraphicsVideoItem> videoItem;
+#endif
+
+ void _q_stateChanged(QMediaPlayer::State state);
+ void _q_mediaStatusChanged(QMediaPlayer::MediaStatus status);
+ void _q_error(int error, const QString &errorString);
+ void _q_updateMedia(const QMediaContent&);
+ void _q_playlistDestroyed();
+};
+
+#define ENUM_NAME(c,e,v) (c::staticMetaObject.enumerator(c::staticMetaObject.indexOfEnumerator(e)).valueToKey((v)))
+
+void QMediaPlayerPrivate::_q_stateChanged(QMediaPlayer::State ps)
+{
+ Q_Q(QMediaPlayer);
+
+#ifdef DEBUG_PLAYER_STATE
+ qDebug() << "State changed:" << ENUM_NAME(QMediaPlayer, "State", ps) << (filterStates ? "(filtered)" : "");
+#endif
+
+ if (filterStates)
+ return;
+
+ if (playlist
+ && !playlistControl //service should do this itself
+ && ps != state && ps == QMediaPlayer::StoppedState
+ && control->mediaStatus() == QMediaPlayer::EndOfMedia) {
+ playlist->next();
+ ps = control->state();
+ }
+
+ if (ps != state) {
+ state = ps;
+
+ if (ps == QMediaPlayer::PlayingState)
+ q->addPropertyWatch("position");
+ else
+ q->removePropertyWatch("position");
+
+ emit q->stateChanged(ps);
+ }
+}
+
+void QMediaPlayerPrivate::_q_mediaStatusChanged(QMediaPlayer::MediaStatus status)
+{
+ Q_Q(QMediaPlayer);
+
+#ifdef DEBUG_PLAYER_STATE
+ qDebug() << "MediaStatus changed:" << ENUM_NAME(QMediaPlayer, "MediaStatus", status);
+#endif
+
+ switch (status) {
+ case QMediaPlayer::StalledMedia:
+ case QMediaPlayer::BufferingMedia:
+ q->addPropertyWatch("bufferStatus");
+ emit q->mediaStatusChanged(status);
+ break;
+ default:
+ q->removePropertyWatch("bufferStatus");
+ emit q->mediaStatusChanged(status);
+ break;
+ }
+
+}
+
+void QMediaPlayerPrivate::_q_error(int error, const QString &errorString)
+{
+ Q_Q(QMediaPlayer);
+
+ this->error = QMediaPlayer::Error(error);
+ this->errorString = errorString;
+
+ emit q->error(this->error);
+}
+
+void QMediaPlayerPrivate::_q_updateMedia(const QMediaContent &media)
+{
+ const QMediaPlayer::State currentState = state;
+
+ filterStates = true;
+ control->setMedia(media, 0);
+
+ if (!media.isNull()) {
+ switch (currentState) {
+ case QMediaPlayer::PlayingState:
+ control->play();
+ break;
+ case QMediaPlayer::PausedState:
+ control->pause();
+ break;
+ default:
+ break;
+ }
+ }
+ filterStates = false;
+
+ state = control->state();
+
+ if (state != currentState) {
+#ifdef DEBUG_PLAYER_STATE
+ qDebug() << "State changed:" << ENUM_NAME(QMediaPlayer, "State", state);
+#endif
+ emit q_func()->stateChanged(state);
+ }
+}
+
+void QMediaPlayerPrivate::_q_playlistDestroyed()
+{
+ playlist = 0;
+
+ control->setMedia(QMediaContent(), 0);
+}
+
+static QMediaService *playerService(QMediaPlayer::Flags flags, QMediaServiceProvider *provider)
+{
+ if (flags) {
+ QMediaServiceProviderHint::Features features = 0;
+ if (flags & QMediaPlayer::LowLatency)
+ features |= QMediaServiceProviderHint::LowLatencyPlayback;
+
+ if (flags & QMediaPlayer::StreamPlayback)
+ features |= QMediaServiceProviderHint::StreamPlayback;
+
+ return provider->requestService(Q_MEDIASERVICE_MEDIAPLAYER,
+ QMediaServiceProviderHint(features));
+ } else
+ return provider->requestService(Q_MEDIASERVICE_MEDIAPLAYER);
+}
+
+
+/*!
+ Construct a QMediaPlayer that uses the playback service from \a provider,
+ parented to \a parent and with \a flags.
+
+ If a playback service is not specified the system default will be used.
+*/
+
+QMediaPlayer::QMediaPlayer(QObject *parent, QMediaPlayer::Flags flags, QMediaServiceProvider *provider):
+ QMediaObject(*new QMediaPlayerPrivate,
+ parent,
+ playerService(flags,provider))
+{
+ Q_D(QMediaPlayer);
+
+ d->provider = provider;
+
+ if (d->service == 0) {
+ d->error = ServiceMissingError;
+ } else {
+ d->control = qobject_cast<QMediaPlayerControl*>(d->service->control(QMediaPlayerControl_iid));
+ d->playlistControl = qobject_cast<QMediaPlaylistControl*>(d->service->control(QMediaPlaylistControl_iid));
+ if (d->control != 0) {
+ connect(d->control, SIGNAL(mediaChanged(QMediaContent)), SIGNAL(mediaChanged(QMediaContent)));
+ connect(d->control, SIGNAL(stateChanged(QMediaPlayer::State)), SLOT(_q_stateChanged(QMediaPlayer::State)));
+ connect(d->control, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)),
+ SLOT(_q_mediaStatusChanged(QMediaPlayer::MediaStatus)));
+ connect(d->control, SIGNAL(error(int,QString)), SLOT(_q_error(int,QString)));
+
+ connect(d->control, SIGNAL(durationChanged(qint64)), SIGNAL(durationChanged(qint64)));
+ connect(d->control, SIGNAL(positionChanged(qint64)), SIGNAL(positionChanged(qint64)));
+ connect(d->control, SIGNAL(audioAvailableChanged(bool)), SIGNAL(audioAvailableChanged(bool)));
+ connect(d->control, SIGNAL(videoAvailableChanged(bool)), SIGNAL(videoAvailableChanged(bool)));
+ connect(d->control, SIGNAL(volumeChanged(int)), SIGNAL(volumeChanged(int)));
+ connect(d->control, SIGNAL(mutedChanged(bool)), SIGNAL(mutedChanged(bool)));
+ connect(d->control, SIGNAL(seekableChanged(bool)), SIGNAL(seekableChanged(bool)));
+ connect(d->control, SIGNAL(playbackRateChanged(qreal)), SIGNAL(playbackRateChanged(qreal)));
+
+ if (d->control->state() == PlayingState)
+ addPropertyWatch("position");
+
+ if (d->control->mediaStatus() == StalledMedia || d->control->mediaStatus() == BufferingMedia)
+ addPropertyWatch("bufferStatus");
+ }
+ }
+}
+
+
+/*!
+ Destroys the player object.
+*/
+
+QMediaPlayer::~QMediaPlayer()
+{
+ Q_D(QMediaPlayer);
+
+ d->provider->releaseService(d->service);
+}
+
+QMediaContent QMediaPlayer::media() const
+{
+ Q_D(const QMediaPlayer);
+
+ if (d->control != 0)
+ return d->control->media();
+
+ return QMediaContent();
+}
+
+/*!
+ Returns the stream source of media data.
+
+ This is only valid if a stream was passed to setMedia().
+
+ \sa setMedia()
+*/
+
+const QIODevice *QMediaPlayer::mediaStream() const
+{
+ Q_D(const QMediaPlayer);
+
+ if (d->control != 0)
+ return d->control->mediaStream();
+
+ return 0;
+}
+
+QMediaPlayer::State QMediaPlayer::state() const
+{
+ return d_func()->state;
+}
+
+QMediaPlayer::MediaStatus QMediaPlayer::mediaStatus() const
+{
+ Q_D(const QMediaPlayer);
+
+ if (d->control != 0)
+ return d->control->mediaStatus();
+
+ return QMediaPlayer::UnknownMediaStatus;
+}
+
+qint64 QMediaPlayer::duration() const
+{
+ Q_D(const QMediaPlayer);
+
+ if (d->control != 0)
+ return d->control->duration();
+
+ return -1;
+}
+
+qint64 QMediaPlayer::position() const
+{
+ Q_D(const QMediaPlayer);
+
+ if (d->control != 0)
+ return d->control->position();
+
+ return 0;
+}
+
+int QMediaPlayer::volume() const
+{
+ Q_D(const QMediaPlayer);
+
+ if (d->control != 0)
+ return d->control->volume();
+
+ return 0;
+}
+
+bool QMediaPlayer::isMuted() const
+{
+ Q_D(const QMediaPlayer);
+
+ if (d->control != 0)
+ return d->control->isMuted();
+
+ return false;
+}
+
+int QMediaPlayer::bufferStatus() const
+{
+ Q_D(const QMediaPlayer);
+
+ if (d->control != 0)
+ return d->control->bufferStatus();
+
+ return 0;
+}
+
+bool QMediaPlayer::isAudioAvailable() const
+{
+ Q_D(const QMediaPlayer);
+
+ if (d->control != 0)
+ return d->control->isAudioAvailable();
+
+ return false;
+}
+
+bool QMediaPlayer::isVideoAvailable() const
+{
+ Q_D(const QMediaPlayer);
+
+ if (d->control != 0)
+ return d->control->isVideoAvailable();
+
+ return false;
+}
+
+bool QMediaPlayer::isSeekable() const
+{
+ Q_D(const QMediaPlayer);
+
+ if (d->control != 0)
+ return d->control->isSeekable();
+
+ return false;
+}
+
+qreal QMediaPlayer::playbackRate() const
+{
+ Q_D(const QMediaPlayer);
+
+ if (d->control != 0)
+ return d->control->playbackRate();
+
+ return 0.0;
+}
+
+/*!
+ Returns the current error state.
+*/
+
+QMediaPlayer::Error QMediaPlayer::error() const
+{
+ return d_func()->error;
+}
+
+QString QMediaPlayer::errorString() const
+{
+ return d_func()->errorString;
+}
+
+//public Q_SLOTS:
+/*!
+ Start or resume playing the current source.
+*/
+
+void QMediaPlayer::play()
+{
+ Q_D(QMediaPlayer);
+
+ if (d->control == 0) {
+ QMetaObject::invokeMethod(this, "_q_error", Qt::QueuedConnection,
+ Q_ARG(int, QMediaPlayer::ServiceMissingError),
+ Q_ARG(QString, tr("The QMediaPlayer object does not have a valid service")));
+ return;
+ }
+
+ //if playlist control is available, the service should advance itself
+ if (d->playlist && !d->playlistControl && d->playlist->currentIndex() == -1 && !d->playlist->isEmpty())
+ d->playlist->setCurrentIndex(0);
+
+ // Reset error conditions
+ d->error = NoError;
+ d->errorString = QString();
+
+ d->control->play();
+}
+
+/*!
+ Pause playing the current source.
+*/
+
+void QMediaPlayer::pause()
+{
+ Q_D(QMediaPlayer);
+
+ if (d->control != 0)
+ d->control->pause();
+}
+
+/*!
+ Stop playing, and reset the play position to the beginning.
+*/
+
+void QMediaPlayer::stop()
+{
+ Q_D(QMediaPlayer);
+
+ if (d->control != 0)
+ d->control->stop();
+}
+
+void QMediaPlayer::setPosition(qint64 position)
+{
+ Q_D(QMediaPlayer);
+
+ if (d->control == 0 || !isSeekable())
+ return;
+
+ d->control->setPosition(qBound(qint64(0), duration(), position));
+}
+
+void QMediaPlayer::setVolume(int v)
+{
+ Q_D(QMediaPlayer);
+
+ if (d->control == 0)
+ return;
+
+ int clamped = qBound(0, v, 100);
+ if (clamped == volume())
+ return;
+
+ d->control->setVolume(clamped);
+}
+
+void QMediaPlayer::setMuted(bool muted)
+{
+ Q_D(QMediaPlayer);
+
+ if (d->control == 0 || muted == isMuted())
+ return;
+
+ d->control->setMuted(muted);
+}
+
+void QMediaPlayer::setPlaybackRate(qreal rate)
+{
+ Q_D(QMediaPlayer);
+
+ if (d->control != 0)
+ d->control->setPlaybackRate(rate);
+}
+
+/*!
+ Sets the current \a media source.
+
+ If a \a stream is supplied; media data will be read from it instead of resolving the media
+ source. In this case the media source may still be used to resolve additional information
+ about the media such as mime type.
+
+ Setting the media to a null QMediaContent will cause the player to discard all
+ information relating to the current media source and to cease all I/O operations related
+ to that media.
+*/
+
+void QMediaPlayer::setMedia(const QMediaContent &media, QIODevice *stream)
+{
+ Q_D(QMediaPlayer);
+
+ if (d->control != 0)
+ d_func()->control->setMedia(media, stream);
+}
+
+/*!
+ \internal
+*/
+
+void QMediaPlayer::bind(QObject *obj)
+{
+ Q_D(QMediaPlayer);
+
+ if (d->control != 0) {
+ QMediaPlaylist *playlist = qobject_cast<QMediaPlaylist*>(obj);
+
+ if (playlist) {
+ if (d->playlist)
+ d->playlist->setMediaObject(0);
+
+ d->playlist = playlist;
+ connect(d->playlist, SIGNAL(currentMediaChanged(QMediaContent)),
+ this, SLOT(_q_updateMedia(QMediaContent)));
+ connect(d->playlist, SIGNAL(destroyed()), this, SLOT(_q_playlistDestroyed()));
+
+ setMedia(playlist->currentMedia());
+
+ return;
+ }
+
+ QVideoWidget *videoWidget = qobject_cast<QVideoWidget*>(obj);
+#ifndef QT_NO_GRAPHICSVIEW
+ QGraphicsVideoItem *videoItem = qobject_cast<QGraphicsVideoItem*>(obj);
+#endif
+
+ if (videoWidget
+#ifndef QT_NO_GRAPHICSVIEW
+ || videoItem
+#endif
+ ) {
+ //detach the current video output
+ if (d->videoWidget) {
+ d->videoWidget->setMediaObject(0);
+ d->videoWidget = 0;
+ }
+
+#ifndef QT_NO_GRAPHICSVIEW
+ if (d->videoItem) {
+ d->videoItem->setMediaObject(0);
+ d->videoItem = 0;
+ }
+#endif
+ }
+
+ if (videoWidget)
+ d->videoWidget = videoWidget;
+
+#ifndef QT_NO_GRAPHICSVIEW
+ if (videoItem)
+ d->videoItem = videoItem;
+#endif
+ }
+}
+
+/*!
+ \internal
+*/
+
+void QMediaPlayer::unbind(QObject *obj)
+{
+ Q_D(QMediaPlayer);
+
+ if (obj == d->videoWidget) {
+ d->videoWidget = 0;
+#ifndef QT_NO_GRAPHICSVIEW
+ } else if (obj == d->videoItem) {
+ d->videoItem = 0;
+#endif
+ } else if (obj == d->playlist) {
+ disconnect(d->playlist, SIGNAL(currentMediaChanged(QMediaContent)),
+ this, SLOT(_q_updateMedia(QMediaContent)));
+ disconnect(d->playlist, SIGNAL(destroyed()), this, SLOT(_q_playlistDestroyed()));
+ d->playlist = 0;
+ setMedia(QMediaContent());
+ }
+}
+
+/*!
+ Returns the level of support a media player has for a \a mimeType and a set of \a codecs.
+
+ The \a flags argument allows additional requirements such as performance indicators to be
+ specified.
+*/
+QtMediaServices::SupportEstimate QMediaPlayer::hasSupport(const QString &mimeType,
+ const QStringList& codecs,
+ Flags flags)
+{
+ return QMediaServiceProvider::defaultServiceProvider()->hasSupport(QByteArray(Q_MEDIASERVICE_MEDIAPLAYER),
+ mimeType,
+ codecs,
+ flags);
+}
+
+/*!
+ Returns a list of MIME types supported by the media player.
+
+ The \a flags argument causes the resultant list to be restricted to MIME types which can be supported
+ given additional requirements, such as performance indicators.
+*/
+QStringList QMediaPlayer::supportedMimeTypes(Flags flags)
+{
+ return QMediaServiceProvider::defaultServiceProvider()->supportedMimeTypes(QByteArray(Q_MEDIASERVICE_MEDIAPLAYER),
+ flags);
+}
+
+
+// Enums
+/*!
+ \enum QMediaPlayer::State
+
+ Defines the current state of a media player.
+
+ \value PlayingState The media player is currently playing content.
+ \value PausedState The media player has paused playback, playback of the current track will
+ resume from the position the player was paused at.
+ \value StoppedState The media player is not playing content, playback will begin from the start
+ of the current track.
+*/
+
+/*!
+ \enum QMediaPlayer::MediaStatus
+
+ Defines the status of a media player's current media.
+
+ \value UnknownMediaStatus The status of the media cannot be determined.
+ \value NoMedia The is no current media. The player is in the StoppedState.
+ \value LoadingMedia The current media is being loaded. The player may be in any state.
+ \value LoadedMedia The current media has been loaded. The player is in the StoppedState.
+ \value StalledMedia Playback of the current media has stalled due to insufficient buffering or
+ some other temporary interruption. The player is in the PlayingState or PausedState.
+ \value BufferingMedia The player is buffering data but has enough data buffered for playback to
+ continue for the immediate future. The player is in the PlayingState or PausedState.
+ \value BufferedMedia The player has fully buffered the current media. The player is in the
+ PlayingState or PausedState.
+ \value EndOfMedia Playback has reached the end of the current media. The player is in the
+ StoppedState.
+ \value InvalidMedia The current media cannot be played. The player is in the StoppedState.
+*/
+
+/*!
+ \enum QMediaPlayer::Error
+
+ Defines a media player error condition.
+
+ \value NoError No error has occurred.
+ \value ResourceError A media resource couldn't be resolved.
+ \value FormatError The format of a media resource isn't (fully) supported. Playback may still
+ be possible, but without an audio or video component.
+ \value NetworkError A network error occurred.
+ \value AccessDeniedError There are not the appropriate permissions to play a media resource.
+ \value ServiceMissingError A valid playback service was not found, playback cannot proceed.
+*/
+
+// Signals
+/*!
+ \fn QMediaPlayer::error(QMediaPlayer::Error error)
+
+ Signals that an \a error condition has occurred.
+
+ \sa errorString()
+*/
+
+/*!
+ \fn void QMediaPlayer::stateChanged(State state)
+
+ Signal the \a state of the Player object has changed.
+*/
+
+/*!
+ \fn QMediaPlayer::mediaStatusChanged(QMediaPlayer::MediaStatus status)
+
+ Signals that the \a status of the current media has changed.
+
+ \sa mediaStatus()
+*/
+
+/*!
+ \fn void QMediaPlayer::mediaChanged(const QMediaContent &media);
+
+ Signals that the current playing content will be obtained from \a media.
+
+ \sa media()
+*/
+
+/*!
+ \fn void QMediaPlayer::playbackRateChanged(qreal rate);
+
+ Signals the playbackRate has changed to \a rate.
+*/
+
+/*!
+ \fn void QMediaPlayer::seekableChanged(bool seekable);
+
+ Signals the \a seekable status of the player object has changed.
+*/
+
+// Properties
+/*!
+ \property QMediaPlayer::state
+ \brief the media player's playback state.
+
+ By default this property is QMediaPlayer::Stopped
+
+ \sa mediaStatus(), play(), pause(), stop()
+*/
+
+/*!
+ \property QMediaPlayer::error
+ \brief a string describing the last error condition.
+
+ \sa error()
+*/
+
+/*!
+ \property QMediaPlayer::media
+ \brief the active media source being used by the player object.
+
+ The player object will use the QMediaContent for selection of the content to
+ be played.
+
+ By default this property has a null QMediaContent.
+
+ Setting this property to a null QMediaContent will cause the player to discard all
+ information relating to the current media source and to cease all I/O operations related
+ to that media.
+
+ \sa QMediaContent
+*/
+
+/*!
+ \property QMediaPlayer::mediaStatus
+ \brief the status of the current media stream.
+
+ The stream status describes how the playback of the current stream is
+ progressing.
+
+ By default this property is QMediaPlayer::NoMedia
+
+ \sa state
+*/
+
+/*!
+ \property QMediaPlayer::duration
+ \brief the duration of the current media.
+
+ The value is the total playback time in milliseconds of the current media.
+ The value may change across the life time of the QMediaPlayer object and
+ may not be available when initial playback begins, connect to the
+ durationChanged() signal to receive status notifications.
+*/
+
+/*!
+ \property QMediaPlayer::position
+ \brief the playback position of the current media.
+
+ The value is the current playback position, expressed in milliseconds since
+ the beginning of the media. Periodically changes in the position will be
+ indicated with the signal positionChanged(), the interval between updates
+ can be set with QMediaObject's method setNotifyInterval().
+*/
+
+/*!
+ \property QMediaPlayer::volume
+ \brief the current playback volume.
+
+ The playback volume is a linear in effect and the value can range from 0 -
+ 100, values outside this range will be clamped.
+*/
+
+/*!
+ \property QMediaPlayer::muted
+ \brief the muted state of the current media.
+
+ The value will be true if the playback volume is muted; otherwise false.
+*/
+
+/*!
+ \property QMediaPlayer::bufferStatus
+ \brief the percentage of the temporary buffer filled before playback begins.
+
+ When the player object is buffering; this property holds the percentage of
+ the temporary buffer that is filled. The buffer will need to reach 100%
+ filled before playback can resume, at which time the MediaStatus will be
+ BufferedMedia.
+
+ \sa mediaStatus()
+*/
+
+/*!
+ \property QMediaPlayer::audioAvailable
+ \brief the audio availabilty status for the current media.
+
+ As the life time of QMediaPlayer can be longer than the playback of one
+ QMediaContent, this property may change over time, the
+ audioAvailableChanged signal can be used to monitor it's status.
+*/
+
+/*!
+ \property QMediaPlayer::videoAvailable
+ \brief the video availability status for the current media.
+
+ If available, the QVideoWidget class can be used to view the video. As the
+ life time of QMediaPlayer can be longer than the playback of one
+ QMediaContent, this property may change over time, the
+ videoAvailableChanged signal can be used to monitor it's status.
+
+ \sa QVideoWidget, QMediaContent
+*/
+
+/*!
+ \property QMediaPlayer::seekable
+ \brief the seek-able status of the current media
+
+ If seeking is supported this property will be true; false otherwise. The
+ status of this property may change across the life time of the QMediaPlayer
+ object, use the seekableChanged signal to monitor changes.
+*/
+
+/*!
+ \property QMediaPlayer::playbackRate
+ \brief the playback rate of the current media.
+
+ This value is a multiplier applied to the media's standard play rate. By
+ default this value is 1.0, indicating that the media is playing at the
+ standard pace. Values higher than 1.0 will increase the rate of play.
+ Values less than zero can be set and indicate the media will rewind at the
+ multiplier of the standard pace.
+
+ Not all playback services support change of the playback rate. It is
+ framework defined as to the status and quality of audio and video
+ while fast forwarding or rewinding.
+*/
+
+/*!
+ \fn void QMediaPlayer::durationChanged(qint64 duration)
+
+ Signal the duration of the content has changed to \a duration, expressed in milliseconds.
+*/
+
+/*!
+ \fn void QMediaPlayer::positionChanged(qint64 position)
+
+ Signal the position of the content has changed to \a position, expressed in
+ milliseconds.
+*/
+
+/*!
+ \fn void QMediaPlayer::volumeChanged(int volume)
+
+ Signal the playback volume has changed to \a volume.
+*/
+
+/*!
+ \fn void QMediaPlayer::mutedChanged(bool muted)
+
+ Signal the mute state has changed to \a muted.
+*/
+
+/*!
+ \fn void QMediaPlayer::audioAvailableChanged(bool available)
+
+ Signals the availability of audio content has changed to \a available.
+*/
+
+/*!
+ \fn void QMediaPlayer::videoAvailableChanged(bool videoAvailable)
+
+ Signal the availability of visual content has changed to \a videoAvailable.
+*/
+
+/*!
+ \fn void QMediaPlayer::bufferStatusChanged(int percentFilled)
+
+ Signal the amount of the local buffer filled as a percentage by \a percentFilled.
+*/
+
+/*!
+ \enum QMediaPlayer::Flag
+
+ \value LowLatency
+ The player is expected to be used with simple audio formats,
+ but playback should start without significant delay.
+ Such playback service can be used for beeps, ringtones, etc.
+
+ \value StreamPlayback
+ The player is expected to play QIODevice based streams.
+ If passed to QMediaPlayer constructor, the service supporting
+ streams playback will be choosen.
+*/
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#include "moc_qmediaplayer.cpp"
diff --git a/src/multimedia/mediaservices/playback/qmediaplayer.h b/src/multimedia/mediaservices/playback/qmediaplayer.h
new file mode 100644
index 0000000..d75c58a
--- /dev/null
+++ b/src/multimedia/mediaservices/playback/qmediaplayer.h
@@ -0,0 +1,203 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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$
+**
+****************************************************************************/
+
+#ifndef QMEDIAPLAYER_H
+#define QMEDIAPLAYER_H
+
+#include <QtMediaServices/qmediaserviceprovider.h>
+#include <QtMediaServices/qmediaobject.h>
+#include <QtMediaServices/qmediacontent.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QMediaPlaylist;
+
+class QMediaPlayerPrivate;
+class Q_MEDIASERVICES_EXPORT QMediaPlayer : public QMediaObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QMediaContent media READ media WRITE setMedia NOTIFY mediaChanged)
+ Q_PROPERTY(qint64 duration READ duration NOTIFY durationChanged)
+ Q_PROPERTY(qint64 position READ position WRITE setPosition NOTIFY positionChanged)
+ Q_PROPERTY(int volume READ volume WRITE setVolume NOTIFY volumeChanged)
+ Q_PROPERTY(bool muted READ isMuted WRITE setMuted NOTIFY mutedChanged)
+ Q_PROPERTY(int bufferStatus READ bufferStatus NOTIFY bufferStatusChanged)
+ Q_PROPERTY(bool audioAvailable READ isAudioAvailable NOTIFY audioAvailableChanged)
+ Q_PROPERTY(bool videoAvailable READ isVideoAvailable NOTIFY videoAvailableChanged)
+ Q_PROPERTY(bool seekable READ isSeekable NOTIFY seekableChanged)
+ Q_PROPERTY(qreal playbackRate READ playbackRate WRITE setPlaybackRate NOTIFY playbackRateChanged)
+ Q_PROPERTY(State state READ state NOTIFY stateChanged)
+ Q_PROPERTY(MediaStatus mediaStatus READ mediaStatus NOTIFY mediaStatusChanged)
+ Q_PROPERTY(QString error READ errorString)
+ Q_ENUMS(State)
+ Q_ENUMS(MediaStatus)
+
+public:
+ enum State
+ {
+ StoppedState,
+ PlayingState,
+ PausedState
+ };
+
+ enum MediaStatus
+ {
+ UnknownMediaStatus,
+ NoMedia,
+ LoadingMedia,
+ LoadedMedia,
+ StalledMedia,
+ BufferingMedia,
+ BufferedMedia,
+ EndOfMedia,
+ InvalidMedia
+ };
+
+ enum Flag
+ {
+ LowLatency = 0x01,
+ StreamPlayback = 0x02
+ };
+ Q_DECLARE_FLAGS(Flags, Flag)
+
+ enum Error
+ {
+ NoError,
+ ResourceError,
+ FormatError,
+ NetworkError,
+ AccessDeniedError,
+ ServiceMissingError
+ };
+
+ QMediaPlayer(QObject *parent = 0, Flags flags = 0, QMediaServiceProvider *provider = QMediaServiceProvider::defaultServiceProvider());
+ ~QMediaPlayer();
+
+ static QtMediaServices::SupportEstimate hasSupport(const QString &mimeType,
+ const QStringList& codecs = QStringList(),
+ Flags flags = 0);
+ static QStringList supportedMimeTypes(Flags flags = 0);
+
+ QMediaContent media() const;
+ const QIODevice *mediaStream() const;
+
+ State state() const;
+ MediaStatus mediaStatus() const;
+
+ qint64 duration() const;
+ qint64 position() const;
+
+ int volume() const;
+ bool isMuted() const;
+ bool isAudioAvailable() const;
+ bool isVideoAvailable() const;
+
+ int bufferStatus() const;
+
+ bool isSeekable() const;
+ qreal playbackRate() const;
+
+ Error error() const;
+ QString errorString() const;
+
+public Q_SLOTS:
+ void play();
+ void pause();
+ void stop();
+
+ void setPosition(qint64 position);
+ void setVolume(int volume);
+ void setMuted(bool muted);
+
+ void setPlaybackRate(qreal rate);
+
+ void setMedia(const QMediaContent &media, QIODevice *stream = 0);
+
+Q_SIGNALS:
+ void mediaChanged(const QMediaContent &media);
+
+ void stateChanged(QMediaPlayer::State newState);
+ void mediaStatusChanged(QMediaPlayer::MediaStatus status);
+
+ void durationChanged(qint64 duration);
+ void positionChanged(qint64 position);
+
+ void volumeChanged(int volume);
+ void mutedChanged(bool muted);
+ void audioAvailableChanged(bool audioAvailable);
+ void videoAvailableChanged(bool videoAvailable);
+
+ void bufferStatusChanged(int percentFilled);
+
+ void seekableChanged(bool seekable);
+ void playbackRateChanged(qreal rate);
+
+ void error(QMediaPlayer::Error error);
+
+public:
+ virtual void bind(QObject*);
+ virtual void unbind(QObject*);
+
+private:
+ Q_DISABLE_COPY(QMediaPlayer)
+ Q_DECLARE_PRIVATE(QMediaPlayer)
+ Q_PRIVATE_SLOT(d_func(), void _q_stateChanged(QMediaPlayer::State))
+ Q_PRIVATE_SLOT(d_func(), void _q_mediaStatusChanged(QMediaPlayer::MediaStatus))
+ Q_PRIVATE_SLOT(d_func(), void _q_error(int, const QString &))
+ Q_PRIVATE_SLOT(d_func(), void _q_updateMedia(const QMediaContent&))
+ Q_PRIVATE_SLOT(d_func(), void _q_playlistDestroyed())
+};
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QMediaPlayer::State)
+Q_DECLARE_METATYPE(QMediaPlayer::MediaStatus)
+Q_DECLARE_METATYPE(QMediaPlayer::Error)
+
+QT_END_HEADER
+
+#endif // QMEDIAPLAYER_H
diff --git a/src/multimedia/mediaservices/playback/qmediaplayercontrol.cpp b/src/multimedia/mediaservices/playback/qmediaplayercontrol.cpp
new file mode 100644
index 0000000..ca58ce4
--- /dev/null
+++ b/src/multimedia/mediaservices/playback/qmediaplayercontrol.cpp
@@ -0,0 +1,378 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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 <QtMediaServices/qmediaplayercontrol.h>
+#include <QtMediaServices/private/qmediacontrol_p.h>
+#include <QtMediaServices/qmediaplayer.h>
+
+
+QT_BEGIN_NAMESPACE
+
+
+/*!
+ \class QMediaPlayerControl
+ \ingroup multimedia-serv
+ \since 4.7
+ \preliminary
+ \brief The QMediaPlayerControl class provides access to the media playing
+ functionality of a QMediaService.
+
+ If a QMediaService can play media is will implement QMediaPlayerControl.
+ This control provides a means to set the \l {setMedia()}{media} to play,
+ \l {play()}{start}, \l {pause()} {pause} and \l {stop()}{stop} playback,
+ \l {setPosition()}{seek}, and control the \l {setVolume()}{volume}.
+ It also provides feedback on the \l {duration()}{duration} of the media,
+ the current \l {position()}{position}, and \l {bufferStatus()}{buffering}
+ progress.
+
+ The functionality provided by this control is exposed to application
+ code through the QMediaPlayer class.
+
+ The interface name of QMediaPlayerControl is \c com.nokia.Qt.QMediaPlayerControl/1.0 as
+ defined in QMediaPlayerControl_iid.
+
+ \sa QMediaService::control(), QMediaPlayer
+*/
+
+/*!
+ \macro QMediaPlayerControl_iid
+
+ \c com.nokia.Qt.QMediaPlayerControl/1.0
+
+ Defines the interface name of the QMediaPlayerControl class.
+
+ \relates QMediaPlayerControl
+*/
+
+/*!
+ Destroys a media player control.
+*/
+QMediaPlayerControl::~QMediaPlayerControl()
+{
+}
+
+/*!
+ Constructs a new media player control with the given \a parent.
+*/
+QMediaPlayerControl::QMediaPlayerControl(QObject *parent):
+ QMediaControl(*new QMediaControlPrivate, parent)
+{
+}
+
+/*!
+ \fn QMediaPlayerControl::state() const
+
+ Returns the state of a player control.
+*/
+
+/*!
+ \fn QMediaPlayerControl::stateChanged(QMediaPlayer::State state)
+
+ Signals that the \a state of a player control has changed.
+
+ \sa state()
+*/
+
+/*!
+ \fn QMediaPlayerControl::mediaStatus() const
+
+ Returns the status of the current media.
+*/
+
+/*!
+ \fn QMediaPlayerControl::mediaStatusChanged(QMediaPlayer::MediaStatus status)
+
+ Signals that the \a status of the current media has changed.
+
+ \sa mediaStatus()
+*/
+
+
+/*!
+ \fn QMediaPlayerControl::duration() const
+
+ Returns the duration of the current media in milliseconds.
+*/
+
+/*!
+ \fn QMediaPlayerControl::durationChanged(qint64 duration)
+
+ Signals that the \a duration of the current media has changed.
+
+ \sa duration()
+*/
+
+/*!
+ \fn QMediaPlayerControl::position() const
+
+ Returns the current playback position in milliseconds.
+*/
+
+/*!
+ \fn QMediaPlayerControl::setPosition(qint64 position)
+
+ Sets the playback \a position of the current media. This will initiate a seek and it may take
+ some time for playback to reach the position set.
+*/
+
+/*!
+ \fn QMediaPlayerControl::positionChanged(qint64 position)
+
+ Signals the playback \a position has changed.
+
+ This is only emitted in when there has been a discontinous change in the playback postion, such
+ as a seek or the position being reset.
+
+ \sa position()
+*/
+
+/*!
+ \fn QMediaPlayerControl::volume() const
+
+ Returns the audio volume of a player control.
+*/
+
+/*!
+ \fn QMediaPlayerControl::setVolume(int volume)
+
+ Sets the audio \a volume of a player control.
+*/
+
+/*!
+ \fn QMediaPlayerControl::volumeChanged(int volume)
+
+ Signals the audio \a volume of a player control has changed.
+
+ \sa volume()
+*/
+
+/*!
+ \fn QMediaPlayerControl::isMuted() const
+
+ Returns the mute state of a player control.
+*/
+
+/*!
+ \fn QMediaPlayerControl::setMuted(bool mute)
+
+ Sets the \a mute state of a player control.
+*/
+
+/*!
+ \fn QMediaPlayerControl::mutedChanged(bool mute)
+
+ Signals a change in the \a mute status of a player control.
+
+ \sa isMuted()
+*/
+
+/*!
+ \fn QMediaPlayerControl::bufferStatus() const
+
+ Returns the buffering progress of the current media. Progress is measured in the percentage
+ of the buffer filled.
+*/
+
+/*!
+ \fn QMediaPlayerControl::bufferStatusChanged(int progress)
+
+ Signals that buffering \a progress has changed.
+
+ \sa bufferStatus()
+*/
+
+/*!
+ \fn QMediaPlayerControl::isAudioAvailable() const
+
+ Identifies if there is audio output available for the current media.
+
+ Returns true if audio output is available and false otherwise.
+*/
+
+/*!
+ \fn QMediaPlayerControl::audioAvailableChanged(bool audio)
+
+ Signals that there has been a change in the availability of \a audio output.
+
+ \sa isAudioAvailable()
+*/
+
+/*!
+ \fn QMediaPlayerControl::isVideoAvailable() const
+
+ Identifies if there is video output available for the current media.
+
+ Returns true if video output is available and false otherwise.
+*/
+
+/*!
+ \fn QMediaPlayerControl::videoAvailableChanged(bool video)
+
+ Signals that there has been a change in the availability of \a video output.
+
+ \sa isVideoAvailable()
+*/
+
+/*!
+ \fn QMediaPlayerControl::isSeekable() const
+
+ Identifies if the current media is seekable.
+
+ Returns true if it possible to seek within the current media, and false otherwise.
+*/
+
+/*!
+ \fn QMediaPlayerControl::seekableChanged(bool seekable)
+
+ Signals that the \a seekable state of a player control has changed.
+
+ \sa isSeekable()
+*/
+
+/*!
+ \fn QMediaPlayerControl::availablePlaybackRanges() const
+
+ Returns a range of times in milliseconds that can be played back.
+
+ Usually for local files this is a continuous interval equal to [0..duration()]
+ or an empty time range if seeking is not supported, but for network sources
+ it refers to the buffered parts of the media.
+*/
+
+/*!
+ \fn QMediaPlayerControl::availablePlaybackRangesChanged(const QMediaTimeRange &ranges)
+
+ Signals that the available media playback \a ranges have changed.
+
+ \sa QMediaPlayerControl::availablePlaybackRanges()
+*/
+
+/*!
+ \fn qreal QMediaPlayerControl::playbackRate() const
+
+ Returns the rate of playback.
+*/
+
+/*!
+ \fn QMediaPlayerControl::setPlaybackRate(qreal rate)
+
+ Sets the \a rate of playback.
+*/
+
+/*!
+ \fn QMediaPlayerControl::media() const
+
+ Returns the current media source.
+*/
+
+/*!
+ \fn QMediaPlayerControl::mediaStream() const
+
+ Returns the current media stream. This is only a valid if a stream was passed to setMedia().
+
+ \sa setMedia()
+*/
+
+/*!
+ \fn QMediaPlayerControl::setMedia(const QMediaContent &media, QIODevice *stream)
+
+ Sets the current \a media source. If a \a stream is supplied; data will be read from that
+ instead of attempting to resolve the media source. The media source may still be used to
+ supply media information such as mime type.
+
+ Setting the media to a null QMediaContent will cause the control to discard all
+ information relating to the current media source and to cease all I/O operations related
+ to that media.
+*/
+
+/*!
+ \fn QMediaPlayerControl::mediaChanged(const QMediaContent& content)
+
+ Signals that the current media \a content has changed.
+*/
+
+/*!
+ \fn QMediaPlayerControl::play()
+
+ Starts playback of the current media.
+
+ If successful the player control will immediately enter the \l {QMediaPlayer::PlayingState}
+ {playing} state.
+
+ \sa state()
+*/
+
+/*!
+ \fn QMediaPlayerControl::pause()
+
+ Pauses playback of the current media.
+
+ If sucessful the player control will immediately enter the \l {QMediaPlayer::PausedState}
+ {paused} state.
+
+ \sa state(), play(), stop()
+*/
+
+/*!
+ \fn QMediaPlayerControl::stop()
+
+ Stops playback of the current media.
+
+ If succesful the player control will immediately enter the \l {QMediaPlayer::StoppedState}
+ {stopped} state.
+*/
+
+/*!
+ \fn QMediaPlayerControl::error(int error, const QString &errorString)
+
+ Signals that an \a error has occurred. The \a errorString provides a more detailed explanation.
+*/
+
+/*!
+ \fn QMediaPlayerControl::playbackRateChanged(qreal rate)
+
+ Signal emitted when playback rate changes to \a rate.
+*/
+
+QT_END_NAMESPACE
+
+#include "moc_qmediaplayercontrol.cpp"
+
diff --git a/src/multimedia/mediaservices/playback/qmediaplayercontrol.h b/src/multimedia/mediaservices/playback/qmediaplayercontrol.h
new file mode 100644
index 0000000..7a3c24e
--- /dev/null
+++ b/src/multimedia/mediaservices/playback/qmediaplayercontrol.h
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtMediaServices module 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$
+**
+****************************************************************************/
+
+#ifndef QMEDIAPLAYERCONTROL_H
+#define QMEDIAPLAYERCONTROL_H
+
+#include <QtCore/qpair.h>
+
+#include <QtMediaServices/qmediacontrol.h>
+#include <QtMediaServices/qmediaplayer.h>
+#include <QtMediaServices/qmediatimerange.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QMediaPlaylist;
+
+class Q_MEDIASERVICES_EXPORT QMediaPlayerControl : public QMediaControl
+{
+ Q_OBJECT
+
+public:
+ ~QMediaPlayerControl();
+
+ virtual QMediaPlayer::State state() const = 0;
+
+ virtual QMediaPlayer::MediaStatus mediaStatus() const = 0;
+
+ virtual qint64 duration() const = 0;
+
+ virtual qint64 position() const = 0;
+ virtual void setPosition(qint64 position) = 0;
+
+ virtual int volume() const = 0;
+ virtual void setVolume(int volume) = 0;
+
+ virtual bool isMuted() const = 0;
+ virtual void setMuted(bool muted) = 0;
+
+ virtual int bufferStatus() const = 0;
+
+ virtual bool isAudioAvailable() const = 0;
+ virtual bool isVideoAvailable() const = 0;
+
+ virtual bool isSeekable() const = 0;
+
+ virtual QMediaTimeRange availablePlaybackRanges() const = 0;
+
+ virtual qreal playbackRate() const = 0;
+ virtual void setPlaybackRate(qreal rate) = 0;
+
+ virtual QMediaContent media() const = 0;
+ virtual const QIODevice *mediaStream() const = 0;
+ virtual void setMedia(const QMediaContent &media, QIODevice *stream) = 0;
+
+ virtual void play() = 0;
+ virtual void pause() = 0;
+ virtual void stop() = 0;
+
+Q_SIGNALS:
+ void mediaChanged(const QMediaContent& content);
+ void durationChanged(qint64 duration);
+ void positionChanged(qint64 position);
+ void stateChanged(QMediaPlayer::State newState);
+ void mediaStatusChanged(QMediaPlayer::MediaStatus status);
+ void volumeChanged(int volume);
+ void mutedChanged(bool muted);
+ void audioAvailableChanged(bool audioAvailable);
+ void videoAvailableChanged(bool videoAvailable);
+ void bufferStatusChanged(int percentFilled);
+ void seekableChanged(bool);
+ void availablePlaybackRangesChanged(const QMediaTimeRange&);
+ void playbackRateChanged(qreal rate);
+ void error(int error, const QString &errorString);
+
+protected:
+ QMediaPlayerControl(QObject* parent = 0);
+};
+
+#define QMediaPlayerControl_iid "com.nokia.Qt.QMediaPlayerControl/1.0"
+Q_MEDIA_DECLARE_CONTROL(QMediaPlayerControl, QMediaPlayerControl_iid)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QMEDIAPLAYERCONTROL_H
+