qtmobility/src/multimedia/qmediaplayer.cpp
changeset 14 6fbed849b4f4
parent 11 06b8e2af4411
child 15 1f895d8a5b2b
--- a/qtmobility/src/multimedia/qmediaplayer.cpp	Fri Jun 11 14:26:25 2010 +0300
+++ b/qtmobility/src/multimedia/qmediaplayer.cpp	Wed Jun 23 19:08:38 2010 +0300
@@ -48,14 +48,15 @@
 
 #include "qmediaplayer.h"
 
-#include "qmediaobject_p.h"
-#include "qmediaservice.h"
-#include "qmediaplayercontrol.h"
-#include "qmediaserviceprovider.h"
-#include "qmediaplaylist.h"
-#include "qmediaplaylistcontrol.h"
-#include "qvideowidget.h"
-#include "qgraphicsvideoitem.h"
+#include <qmediaobject_p.h>
+#include <qmediaservice.h>
+#include <qmediaplayercontrol.h>
+#include <qmediaserviceprovider.h>
+#include <qmediaplaylist.h>
+#include <qmediaplaylistcontrol.h>
+#include <qmediaplaylistsourcecontrol.h>
+#include <qvideowidget.h>
+#include <qgraphicsvideoitem.h>
 
 QT_BEGIN_NAMESPACE
 
@@ -84,15 +85,15 @@
     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"));
 
+        player = new QMediaPlayer;
+        player->setPlaylist(playlist);
+
         widget = new QVideoWidget;
-        widget->setMediaObject(player);
+        player->addVideoOutput(widget);
         widget->show();
 
         player->play();
@@ -123,7 +124,7 @@
     QMediaPlayerPrivate()
         : provider(0)
         , control(0)
-        , playlistControl(0)
+        , playlistSourceControl(0)
         , state(QMediaPlayer::StoppedState)
         , error(QMediaPlayer::NoError)
         , filterStates(false)
@@ -132,15 +133,14 @@
 
     QMediaServiceProvider *provider;
     QMediaPlayerControl* control;
-    QMediaPlaylistControl* playlistControl;
+    QMediaPlaylistSourceControl* playlistSourceControl;
     QMediaPlayer::State state;
     QMediaPlayer::Error error;
     QString errorString;
     bool filterStates;
 
+    QPointer<QObject> videoOutput;
     QMediaPlaylist *playlist;
-    QPointer<QVideoWidget> videoWidget;
-    QPointer<QGraphicsVideoItem> videoItem;
 
     void _q_stateChanged(QMediaPlayer::State state);
     void _q_mediaStatusChanged(QMediaPlayer::MediaStatus status);
@@ -157,7 +157,6 @@
         return;
 
     if (playlist
-            && !playlistControl //service should do this itself
             && ps != state && ps == QMediaPlayer::StoppedState
             && control->mediaStatus() == QMediaPlayer::EndOfMedia) {
         playlist->next();
@@ -206,6 +205,9 @@
 
 void QMediaPlayerPrivate::_q_updateMedia(const QMediaContent &media)
 {
+    if (!control)
+        return;
+
     const QMediaPlayer::State currentState = state;
 
     filterStates = true;
@@ -235,6 +237,12 @@
 {
     playlist = 0;
 
+    if (!control)
+        return;
+
+    if (playlistSourceControl)
+        playlistSourceControl->setPlaylist(0);
+
     control->setMedia(QMediaContent(), 0);
 }
 
@@ -274,8 +282,9 @@
     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));
+        d->control = qobject_cast<QMediaPlayerControl*>(d->service->requestControl(QMediaPlayerControl_iid));
+        d->playlistSourceControl = qobject_cast<QMediaPlaylistSourceControl*>(d->service->requestControl(QMediaPlaylistSourceControl_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)));
@@ -310,6 +319,11 @@
 {
     Q_D(QMediaPlayer);
 
+    if (d->service) {
+        if (d->control)
+            d->service->releaseControl(d->control);
+    }
+
     d->provider->releaseService(d->service);
 }
 
@@ -341,6 +355,48 @@
     return 0;
 }
 
+QMediaPlaylist *QMediaPlayer::playlist() const
+{
+    return d_func()->playlistSourceControl ?
+            d_func()->playlistSourceControl->playlist() :
+            d_func()->playlist;
+}
+
+void QMediaPlayer::setPlaylist(QMediaPlaylist *playlist)
+{
+    Q_D(QMediaPlayer);
+
+    if (d->playlistSourceControl) {
+        if (d->playlistSourceControl->playlist())
+            disconnect(d->playlist, SIGNAL(destroyed()), this, SLOT(_q_playlistDestroyed()));
+
+        d->playlistSourceControl->setPlaylist(playlist);
+
+        if (playlist)
+            connect(d->playlist, SIGNAL(destroyed()), this, SLOT(_q_playlistDestroyed()));
+    } else {
+        if (d->playlist) {
+            disconnect(d->playlist, SIGNAL(currentMediaChanged(QMediaContent)),
+                    this, SLOT(_q_updateMedia(QMediaContent)));
+            disconnect(d->playlist, SIGNAL(destroyed()), this, SLOT(_q_playlistDestroyed()));
+        }
+
+        d->playlist = playlist;
+
+        if (d->playlist) {
+            connect(d->playlist, SIGNAL(currentMediaChanged(QMediaContent)),
+                    this, SLOT(_q_updateMedia(QMediaContent)));
+            connect(d->playlist, SIGNAL(destroyed()), this, SLOT(_q_playlistDestroyed()));
+
+            if (d->control != 0)
+                d->control->setMedia(playlist->currentMedia(), 0);
+        } else {
+            setMedia(QMediaContent(), 0);
+        }
+
+    }
+}
+
 QMediaPlayer::State QMediaPlayer::state() const
 {
     return d_func()->state;
@@ -470,14 +526,14 @@
     Q_D(QMediaPlayer);
 
     if (d->control == 0) {
-        QMetaObject::invokeMethod(this, "_q_error", Qt::QueuedConnection);
+        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"));
+                                    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())
+    if (d->playlist && d->playlist->currentIndex() == -1 && !d->playlist->isEmpty())
         d->playlist->setCurrentIndex(0);
 
     // Reset error conditions
@@ -569,6 +625,9 @@
 {
     Q_D(QMediaPlayer);
 
+    if (playlist() && playlist()->currentMedia() != media)
+        setPlaylist(0);
+
     if (d->control != 0)
         d_func()->control->setMedia(media, stream);
 }
@@ -577,49 +636,9 @@
     \internal
 */
 
-void QMediaPlayer::bind(QObject *obj)
+bool 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);
-        QGraphicsVideoItem *videoItem = qobject_cast<QGraphicsVideoItem*>(obj);
-
-        if (videoWidget || videoItem) {
-            //detach the current video output
-            if (d->videoWidget) {
-                d->videoWidget->setMediaObject(0);
-                d->videoWidget = 0;
-            }
-
-            if (d->videoItem) {
-                d->videoItem->setMediaObject(0);
-                d->videoItem = 0;
-            }
-        }
-
-        if (videoWidget)
-            d->videoWidget = videoWidget;
-
-        if (videoItem)
-            d->videoItem = videoItem;
-    }
+    return QMediaObject::bind(obj);
 }
 
 /*!
@@ -628,19 +647,7 @@
 
 void QMediaPlayer::unbind(QObject *obj)
 {
-    Q_D(QMediaPlayer);
-
-    if (obj == d->videoWidget) {
-        d->videoWidget = 0;
-    } else if (obj == d->videoItem) {
-        d->videoItem = 0;
-    } 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());
-    }
+    QMediaObject::unbind(obj);
 }
 
 /*!
@@ -649,7 +656,7 @@
     The \a flags argument allows additional requirements such as performance indicators to be
     specified.
 */
-QtMediaServices::SupportEstimate QMediaPlayer::hasSupport(const QString &mimeType,
+QtMultimedia::SupportEstimate QMediaPlayer::hasSupport(const QString &mimeType,
                                                const QStringList& codecs,
                                                Flags flags)
 {
@@ -671,6 +678,47 @@
                                                                                flags);
 }
 
+/*!
+    Attach a QVideoWidget video \a output to the media player.
+
+    If the media player has already video output attached,
+    it will be replaced with a new one.
+
+    \sa setVideoOutput(QGraphicsVideoItem*)
+*/
+void QMediaPlayer::setVideoOutput(QVideoWidget *output)
+{
+    Q_D(QMediaPlayer);
+
+    if (d->videoOutput)
+        unbind(d->videoOutput);
+
+    d->videoOutput = output;
+
+    if (d->videoOutput)
+        bind(d->videoOutput);
+}
+
+/*!
+    Attach a QGraphicsVideoItem video \a output to the media player.
+
+    If the media player has already video output attached,
+    it will be replaced with a new one.
+
+    \sa setVideoOutput(QVideoWidget*)
+*/
+void QMediaPlayer::setVideoOutput(QGraphicsVideoItem *output)
+{
+    Q_D(QMediaPlayer);
+
+    if (d->videoOutput)
+        unbind(d->videoOutput);
+
+    d->videoOutput = output;
+
+    if (d->videoOutput)
+        bind(d->videoOutput);
+}
 
 // Enums
 /*!
@@ -796,6 +844,24 @@
 */
 
 /*!
+    \property QMediaPlayer::playlist
+    \brief the media playlist being used by the player object.
+
+    The player object will use the current playlist item for selection of the content to
+    be played.
+
+    By default this property is set to null.
+
+    If the media playlist is used as a source, QMediaPlayer::media is updated with
+    a current playlist item. The current source should be selected with
+    QMediaPlaylist::setCurrentIndex(int) instead of QMediaPlayer::setMedia(),
+    otherwise the current playlist will be discarded.
+
+    \sa QMediaContent
+*/
+
+
+/*!
     \property QMediaPlayer::mediaStatus
     \brief the status of the current media stream.