Reset playbin state to NULL on end of stream signal.
authorLev Zelenskiy <lev.zelenskiy@nokia.com>
Fri, 30 Mar 2012 05:20:46 +0000 (15:20 +1000)
committerQt by Nokia <qt-info@nokia.com>
Thu, 5 Apr 2012 00:40:17 +0000 (02:40 +0200)
According to GStreamer documentation "playbin should be set
back to READY or NULL state, then the "uri" property should be set
to the new location and then playbin be set to PLAYING state again."
We reset playbin to NULL state and then call setMedia() again
in case playback is restarted.

Change-Id: If7efbf8d88e0aad461c3d1d8b802c6621af221f7
Reviewed-by: Mithra Pattison <mithra.pattison@nokia.com>
Reviewed-by: Jonas Rabbe <jonas.rabbe@nokia.com>
Reviewed-by: Dmytro Poplavskiy <dmytro.poplavskiy@nokia.com>
src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.cpp
src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.h
src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp
src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h

index 0666ab4..aa77a51 100644 (file)
@@ -69,6 +69,7 @@ QGstreamerPlayerControl::QGstreamerPlayerControl(QGstreamerPlayerSession *sessio
     , m_bufferProgress(-1)
     , m_seekToStartPending(false)
     , m_pendingSeekPosition(-1)
+    , m_setMediaPending(false)
     , m_stream(0)
     , m_fifoNotifier(0)
     , m_fifoCanWrite(false)
@@ -238,6 +239,12 @@ void QGstreamerPlayerControl::playOrPause(QMediaPlayer::State newState)
         return;
 
     pushState();
+
+    if (m_setMediaPending) {
+        m_mediaStatus = QMediaPlayer::LoadingMedia;
+        setMedia(m_currentResource, m_stream);
+    }
+
 #ifdef Q_WS_MAEMO_6
     //this is a work around for the gstreamer bug,
     //should be remove once it get fixed
@@ -246,11 +253,6 @@ void QGstreamerPlayerControl::playOrPause(QMediaPlayer::State newState)
     }
 #endif
 
-    if (m_mediaStatus == QMediaPlayer::EndOfMedia) {
-        m_mediaStatus = QMediaPlayer::BufferedMedia;
-        m_seekToStartPending = true;
-    }
-
     if (!m_resources->isGranted())
         m_resources->acquire();
 
@@ -356,6 +358,7 @@ void QGstreamerPlayerControl::setMedia(const QMediaContent &content, QIODevice *
     QMediaContent oldMedia = m_currentResource;
     m_pendingSeekPosition = -1;
     m_session->showPrerollFrames(false); // do not show prerolled frames until pause() or play() explicitly called
+    m_setMediaPending = false;
 
     if (!content.isNull() || stream) {
         if (!m_resources->isGranted())
@@ -552,7 +555,14 @@ void QGstreamerPlayerControl::processEOS()
     pushState();
     m_mediaStatus = QMediaPlayer::EndOfMedia;
     emit positionChanged(position());
-    stop();
+    m_session->endOfMediaReset();
+    m_setMediaPending = true;
+
+    if (m_state != QMediaPlayer::StoppedState) {
+        m_state = QMediaPlayer::StoppedState;
+        m_session->showPrerollFrames(false); // stop showing prerolled frames in stop state
+    }
+
     popAndNotifyState();
 }
 
index a9b1c84..4511d7e 100644 (file)
@@ -144,6 +144,7 @@ private:
     int m_bufferProgress;
     bool m_seekToStartPending;
     qint64 m_pendingSeekPosition;
+    bool m_setMediaPending;
     QMediaContent m_currentResource;
     QIODevice *m_stream;
     QSocketNotifier *m_fifoNotifier;
index 3fa93f0..c7e38a7 100644 (file)
@@ -1772,6 +1772,26 @@ gboolean QGstreamerPlayerSession::padAudioBufferProbe(GstPad *pad, GstBuffer *bu
     return TRUE;
 }
 
+// This function is similar to stop(),
+// but does not set m_everPlayed, m_lastPosition,
+// and setSeekable() values.
+void QGstreamerPlayerSession::endOfMediaReset()
+{
+    if (m_renderer)
+        m_renderer->stopRenderer();
+
+    flushVideoProbes();
+    gst_element_set_state(m_playbin, GST_STATE_NULL);
+
+    QMediaPlayer::State oldState = m_state;
+    m_pendingState = m_state = QMediaPlayer::StoppedState;
+
+    finishVideoOutputChange();
+
+    if (oldState != m_state)
+        emit stateChanged(m_state);
+}
+
 void QGstreamerPlayerSession::removeVideoBufferProbe()
 {
     if (m_videoBufferProbeId == -1)
index 044053c..4bda52d 100644 (file)
@@ -131,6 +131,8 @@ public:
     void removeProbe(QGstreamerAudioProbeControl* probe);
     static gboolean padAudioBufferProbe(GstPad *pad, GstBuffer *buffer, gpointer user_data);
 
+    void endOfMediaReset();
+
 public slots:
     void loadFromUri(const QNetworkRequest &url);
     void loadFromStream(const QNetworkRequest &url, QIODevice *stream);