ServiceMP3: Optimize GStreamer start sequence
authorAthanasios Oikonomou <athoik@gmail.com>
Sun, 22 Nov 2015 10:12:30 +0000 (12:12 +0200)
committerErik Slagter <erik@openpli.org>
Sat, 28 Nov 2015 16:50:06 +0000 (17:50 +0100)
On start set PLAYING state and check return value of the change state.
On stop make sure that last change state was sucessfull, it prevents deadlock on fast channel zap.
When unpause is called make sure that we are in paused state before change state.
Move evStart event in NULL to READY state and update EPG on READY to PAUSED state.

Note: The get state on stop might block forever, so use 5 seconds timeout.
Note:  The m_state change to running when pipeline is prerolled, on ready to paused state.
(cherry picked from commit 7b64e9f1695786baf658f3e55fbcdc4084ca6120)
Signed-off-by: Erik Slagter <erik@openpli.org>

lib/service/servicemp3.cpp
lib/service/servicemp3.h

index 43c5598..27b075c 100644 (file)
@@ -418,7 +418,6 @@ eServiceMP3::eServiceMP3(eServiceReference ref):
        m_cuesheet_loaded = false; /* cuesheet CVR */
 #if GST_VERSION_MAJOR >= 1
        m_use_chapter_entries = false; /* TOC chapter support CVR */
-       m_user_paused = false; /* CVR */
        m_last_seek_pos = 0; /* CVR last seek position */
 #endif
        m_extra_headers = "";
@@ -666,8 +665,7 @@ eServiceMP3::~eServiceMP3()
                gst_object_unref(bus);
        }
 
-       if (m_state == stRunning)
-               stop();
+       stop();
 
        if (m_stream_tags)
                gst_tag_list_free(m_stream_tags);
@@ -748,19 +746,28 @@ RESULT eServiceMP3::start()
 {
        ASSERT(m_state == stIdle);
 
-       m_state = stRunning;
        if (m_gst_playbin)
        {
                eDebug("[eServiceMP3] starting pipeline");
-#if GST_VERSION_MAJOR < 1
-               gst_element_set_state (m_gst_playbin, GST_STATE_PLAYING);
-#else
-               gst_element_set_state (m_gst_playbin, GST_STATE_PAUSED);
-#endif
-               updateEpgCacheNowNext();
-       }
+               GstStateChangeReturn ret;
+               ret = gst_element_set_state (m_gst_playbin, GST_STATE_PLAYING);
 
-       m_event(this, evStart);
+               switch(ret)
+               {
+               case GST_STATE_CHANGE_FAILURE:
+                       eDebug("[eServiceMP3] failed to start pipeline");
+                       stop();
+                       break;
+               case GST_STATE_CHANGE_SUCCESS:
+                       m_is_live = false;
+                       break;
+               case GST_STATE_CHANGE_NO_PREROLL:
+                       m_is_live = true;
+                       break;
+               default:
+                       break;
+               }
+       }
 
        return 0;
 }
@@ -774,14 +781,25 @@ void eServiceMP3::sourceTimeout()
 
 RESULT eServiceMP3::stop()
 {
-       ASSERT(m_state != stIdle);
-
-       if (m_state == stStopped)
+       if (!m_gst_playbin || m_state == stStopped)
                return -1;
 
        eDebug("[eServiceMP3] stop %s", m_ref.path.c_str());
-       gst_element_set_state(m_gst_playbin, GST_STATE_NULL);
        m_state = stStopped;
+
+       GstStateChangeReturn ret;
+       GstState state, pending;
+       /* make sure that last state change was successfull */
+       ret = gst_element_get_state(m_gst_playbin, &state, &pending, 5 * GST_SECOND);
+       eDebug("[eServiceMP3] stop state:%s pending:%s ret:%s",
+               gst_element_state_get_name(state),
+               gst_element_state_get_name(pending),
+               gst_element_state_change_return_get_name(ret));
+
+       ret = gst_element_set_state(m_gst_playbin, GST_STATE_NULL);
+       if (ret != GST_STATE_CHANGE_SUCCESS)
+               eDebug("[eServiceMP3] stop GST_STATE_NULL failure");
+
        saveCuesheet();
        m_nownext_timer->stop();
        if (m_streamingsrc_timeout)
@@ -821,6 +839,7 @@ RESULT eServiceMP3::pause()
        if (!m_gst_playbin || m_state != stRunning)
                return -1;
 
+       eDebug("[eServiceMP3] pause");
        trickSeek(0.0);
 
        return 0;
@@ -831,6 +850,14 @@ RESULT eServiceMP3::unpause()
        if (!m_gst_playbin || m_state != stRunning)
                return -1;
 
+       /* no need to unpase if we are not paused already */
+       if (m_currentTrickRatio == 1.0 && !m_paused)
+       {
+               eDebug("[eServiceMP3] trickSeek no need to unpause!");
+               return 0;
+       }
+
+       eDebug("[eServiceMP3] unpause");
        trickSeek(1.0);
 
        return 0;
@@ -845,10 +872,7 @@ RESULT eServiceMP3::seek(ePtr<iSeekableService> &ptr)
 
 RESULT eServiceMP3::getLength(pts_t &pts)
 {
-       if (!m_gst_playbin)
-               return -1;
-
-       if (m_state != stRunning)
+       if (!m_gst_playbin || m_state != stRunning)
                return -1;
 
        GstFormat fmt = GST_FORMAT_TIME;
@@ -884,19 +908,11 @@ RESULT eServiceMP3::seekToImpl(pts_t to)
                return -1;
        }
 
-#if GST_VERSION_MAJOR < 1
        if (m_paused)
        {
                m_seek_paused = true;
                gst_element_set_state(m_gst_playbin, GST_STATE_PLAYING);
        }
-#else
-       if (m_user_paused)
-       {
-               m_seek_paused = true;
-               gst_element_set_state(m_gst_playbin, GST_STATE_PLAYING);
-       }
-#endif
 
        return 0;
 }
@@ -1045,9 +1061,7 @@ RESULT eServiceMP3::getPlayPosition(pts_t &pts)
        gint64 pos;
        pts = 0;
 
-       if (!m_gst_playbin)
-               return -1;
-       if (m_state != stRunning)
+       if (!m_gst_playbin || m_state != stRunning)
                return -1;
 
        if (audioSink || videoSink)
@@ -1084,9 +1098,7 @@ RESULT eServiceMP3::isCurrentlySeekable()
 {
        int ret = 3; /* just assume that seeking and fast/slow winding are possible */
 
-       if (!m_gst_playbin)
-               return 0;
-       if (m_state != stRunning)
+       if (!m_gst_playbin || m_state != stRunning)
                return 0;
 
        return ret;
@@ -1650,17 +1662,11 @@ void eServiceMP3::gstBusCall(GstMessage *msg)
                        {
                                case GST_STATE_CHANGE_NULL_TO_READY:
                                {
-#if GST_VERSION_MAJOR >= 1
-                                       /* CVR basic init done , now playbin must go to pause until mediasettings are done */
-                                       if(m_gst_playbin)
-                                       {
-                                               gst_element_set_state(m_gst_playbin, GST_STATE_PAUSED);
-                                               m_paused = true;
-                                       }
-#endif
+                                       m_event(this, evStart);
                                }       break;
                                case GST_STATE_CHANGE_READY_TO_PAUSED:
                                {
+                                       m_state = stRunning;
 #if GST_VERSION_MAJOR >= 1
                                        GValue result = { 0, };
 #endif
@@ -1725,20 +1731,22 @@ void eServiceMP3::gstBusCall(GstMessage *msg)
 #endif
                                        gst_iterator_free(children);
 
-                                       m_is_live = (gst_element_get_state(m_gst_playbin, NULL, NULL, 0LL) == GST_STATE_CHANGE_NO_PREROLL);
+                                       /* if we are in preroll already do not check again the state */
+                                       if (!m_is_live)
+                                       {
+                                               m_is_live = (gst_element_get_state(m_gst_playbin, NULL, NULL, 0LL) == GST_STATE_CHANGE_NO_PREROLL);
+                                       }
 
                                        setAC3Delay(ac3_delay);
                                        setPCMDelay(pcm_delay);
                                        if(!m_cuesheet_loaded) /* cuesheet CVR */
                                                loadCuesheet();
+                                       updateEpgCacheNowNext();
                                }       break;
                                case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
                                {
                                        if ( m_sourceinfo.is_streaming && m_streamingsrc_timeout )
                                                m_streamingsrc_timeout->stop();
-#if GST_VERSION_MAJOR >= 1
-                                       m_user_paused = false;
-#endif
                                        m_paused = false;
                                        if (m_seek_paused)
                                        {
@@ -1750,9 +1758,6 @@ void eServiceMP3::gstBusCall(GstMessage *msg)
                                }       break;
                                case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
                                {
-#if GST_VERSION_MAJOR >= 1
-                                       m_user_paused = true;
-#endif
                                        m_paused = true;
                                }       break;
                                case GST_STATE_CHANGE_PAUSED_TO_READY:
@@ -2025,14 +2030,6 @@ void eServiceMP3::gstBusCall(GstMessage *msg)
                                if (m_errorInfo.missing_codec.find("video/") == 0 || (m_errorInfo.missing_codec.find("audio/") == 0 && m_audioStreams.empty()))
                                        m_event((iPlayableService*)this, evUser+12);
                        }
-#if GST_VERSION_MAJOR >= 1
-                       /* CVR now all audio,video and subsettings are done playbin may go to playing */
-                       if(m_paused && !m_user_paused)
-                       {
-                               gst_element_set_state (m_gst_playbin, GST_STATE_PLAYING);
-                               m_paused = false;
-                       }
-#endif
                        break;
                }
                case GST_MESSAGE_ELEMENT:
@@ -2097,7 +2094,7 @@ void eServiceMP3::gstBusCall(GstMessage *msg)
                        break;
                }
                case GST_MESSAGE_BUFFERING:
-                       if (m_state == stRunning && m_sourceinfo.is_streaming)
+                       if (m_sourceinfo.is_streaming)
                        {
                                GstBufferingMode mode;
                                gst_message_parse_buffering(msg, &(m_bufferInfo.bufferPercent));
index 61943c8..1f21efd 100644 (file)
@@ -306,8 +306,6 @@ private:
        /* servicemMP3 chapter TOC support CVR */
 #if GST_VERSION_MAJOR >= 1
        bool m_use_chapter_entries;
-       /* CVR needed for user requested media pause */
-       bool m_user_paused;
        /* last used seek position gst-1 only */
        gint64 m_last_seek_pos;
 #endif