gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] gnash ChangeLog server/asobj/NetStreamGst.cpp s...


From: Sandro Santilli
Subject: [Gnash-commit] gnash ChangeLog server/asobj/NetStreamGst.cpp s...
Date: Wed, 16 May 2007 12:50:27 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Sandro Santilli <strk>  07/05/16 12:50:27

Modified files:
        .              : ChangeLog 
        server/asobj   : NetStreamGst.cpp NetStreamGst.h 

Log message:
                * server/asobj/NetStreamGst.{cpp,h}: define and use
                  mutex-protected pipeline control methods.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.3237&r2=1.3238
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/NetStreamGst.cpp?cvsroot=gnash&r1=1.39&r2=1.40
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/NetStreamGst.h?cvsroot=gnash&r1=1.18&r2=1.19

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.3237
retrieving revision 1.3238
diff -u -b -r1.3237 -r1.3238
--- ChangeLog   16 May 2007 09:09:39 -0000      1.3237
+++ ChangeLog   16 May 2007 12:50:26 -0000      1.3238
@@ -1,5 +1,10 @@
 2007-05-16 Sandro Santilli <address@hidden>
 
+       * server/asobj/NetStreamGst.{cpp,h}: define and use 
+         mutex-protected pipeline control methods.
+
+2007-05-16 Sandro Santilli <address@hidden>
+
        * server/asobj/NetStreamGst.cpp: always check return code
          from gst_element_factory_make. Handling in case of failure
          is not verified to be correct. Tgc, could you check it out ?

Index: server/asobj/NetStreamGst.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/NetStreamGst.cpp,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -b -r1.39 -r1.40
--- server/asobj/NetStreamGst.cpp       16 May 2007 09:09:39 -0000      1.39
+++ server/asobj/NetStreamGst.cpp       16 May 2007 12:50:26 -0000      1.40
@@ -17,7 +17,7 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 //
 
-/* $Id: NetStreamGst.cpp,v 1.39 2007/05/16 09:09:39 strk Exp $ */
+/* $Id: NetStreamGst.cpp,v 1.40 2007/05/16 12:50:26 strk Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -81,6 +81,8 @@
        audiodecoder(NULL),
        videoinputcaps(NULL),
        audioinputcaps(NULL),
+       _handoffVideoSigHandler(0),
+       _handoffAudioSigHandler(0),
 
 #ifndef DISABLE_START_THREAD
        startThread(NULL),
@@ -108,15 +110,23 @@
        {
                m_pause = (mode == 0) ? true : false;
        }
-       if (pipeline) {
-               if (m_pause) { 
-                       gst_element_set_state (GST_ELEMENT (pipeline), 
GST_STATE_PAUSED);
-               } else {
-                       if (!m_go) { 
-                               setStatus(playStart);
-                               m_go = true;
+
+       if (pipeline)
+       {
+               if (m_pause)
+               { 
+                       log_msg("Pausing pipeline on user request");
+                       if ( ! pausePipeline(false) )
+                       {
+                               log_error("Could not pause pipeline");
+                       }
+               }
+               else
+               {
+                       if ( ! playPipeline() )
+                       {
+                               log_error("Could not play pipeline");
                        }
-                       gst_element_set_state (GST_ELEMENT (pipeline), 
GST_STATE_PLAYING);
                }
        }
 }
@@ -132,7 +142,7 @@
 #endif
        }
 
-       if ( ! resetPipeline() )
+       if ( ! disablePipeline() )
        {
                log_error("Can't reset pipeline on close");
        }
@@ -149,16 +159,6 @@
 NetStreamGst::play(const std::string& c_url)
 {
 
-       // Is it already playing ?
-       if (m_go)
-       {
-               if (m_pause) {
-                       m_pause = false;
-                       gst_element_set_state (GST_ELEMENT (pipeline), 
GST_STATE_PLAYING);
-               }
-               return 0;
-       }
-
        // Does it have an associated NetConnection?
        if ( ! _netCon )
        {
@@ -168,6 +168,17 @@
                return 0;
        }
 
+       // Is it already playing ?
+       if (m_go)
+       {
+               if (m_pause)
+               {
+                       playPipeline();
+               }
+               return 0;
+       }
+
+
        url += c_url;
        // Remove any "mp3:" prefix. Maybe should use this to mark as audio-only
        if (url.compare(0, 4, std::string("mp3:")) == 0) {
@@ -177,7 +188,7 @@
 
        // To avoid blocking while connecting, we use a thread.
 #ifndef DISABLE_START_THREAD
-       startThread = new 
boost::thread(boost::bind(NetStreamGst::startPlayback, this));
+       startThread = new 
boost::thread(boost::bind(NetStreamGst::playbackStarter, this));
 #else
        startPlayback(this);
 #endif
@@ -227,7 +238,6 @@
 void 
 NetStreamGst::callback_output (GstElement* /*c*/, GstBuffer *buffer, GstPad* 
/*pad*/, gpointer user_data)
 {
-
        NetStreamGst* ns = static_cast<NetStreamGst*>(user_data);
 
        boost::mutex::scoped_lock lock(ns->image_mutex);
@@ -336,8 +346,16 @@
 }
 
 void
-NetStreamGst::startPlayback(NetStreamGst* ns)
+NetStreamGst::playbackStarter(NetStreamGst* ns)
+{
+       ns->startPlayback();
+}
+
+void
+NetStreamGst::startPlayback()
 {
+       NetStreamGst* ns = this; // quick hack
+
        boost::intrusive_ptr<NetConnection> nc = ns->_netCon;
        assert(nc);
 
@@ -455,7 +473,11 @@
                                                "sizetype", 2, 
"can-activate-pull", FALSE, "signal-handoffs", TRUE, NULL);
 
                        // Setup the callback
-                       g_signal_connect (ns->videosource, "handoff", 
G_CALLBACK (NetStreamGst::video_callback_handoff), ns);
+                       if ( ! connectVideoHandoffSignal() )
+                       {
+                               log_error("Unable to connect the video 
'handoff' signal handler");
+                               // TODO: what to do in this case ?
+                       }
 
                        // Setup the input capsfilter
                        ns->videoinputcaps = gst_element_factory_make 
("capsfilter", NULL);
@@ -546,7 +568,13 @@
                        g_object_set (G_OBJECT (ns->audiosource),
                                                "sizetype", 2, 
"can-activate-pull", FALSE, "signal-handoffs", TRUE, NULL);
 
-                       g_signal_connect (ns->audiosource, "handoff", 
G_CALLBACK (NetStreamGst::audio_callback_handoff), ns);           
+                       // Setup the callback
+                       if ( ! connectAudioHandoffSignal() )
+                       {
+                               log_error("Unable to connect the audio 
'handoff' signal handler");
+                               // TODO: what to do in this case ?
+                       }
+
 
                        if (audioInfo->codec == AUDIO_CODEC_MP3) { 
 
@@ -641,6 +669,7 @@
                }
 
                g_object_set (G_OBJECT (ns->videosink), "signal-handoffs", 
TRUE, "sync", TRUE, NULL);
+               // TODO: use connectVideoSincCallback()
                g_signal_connect (ns->videosink, "handoff", G_CALLBACK 
(NetStreamGst::callback_output), ns);
        }
 
@@ -686,12 +715,24 @@
        }
 
        // start playing        
-       if (!ns->m_isFLV) {
-               if (video || sound) gst_element_set_state (GST_ELEMENT 
(ns->pipeline), GST_STATE_PLAYING);
-       } else {
-               if (video || sound) gst_element_set_state (GST_ELEMENT 
(ns->pipeline), GST_STATE_PAUSED);
-               ns->m_pause = true;
-               ns->m_start_onbuffer = true;
+       if (!ns->m_isFLV)
+       {
+               if (video || sound)
+               {
+                       // TODO: should call playPipeline() ?
+                       gst_element_set_state (GST_ELEMENT (ns->pipeline), 
GST_STATE_PLAYING);
+               }
+       }
+       else
+       {
+               if (video || sound)
+               {
+                       log_msg("Pausing pipeline on startPlayback");
+                       if ( ! pausePipeline(true) )
+                       {
+                               log_error("Could not pause pipeline");
+                       }
+               }
        }
 
        ns->setStatus(playStart);
@@ -728,25 +769,29 @@
 NetStreamGst::advance()
 {
        // Check if we should start the playback when a certain amount is 
buffered
-       if (m_isFLV && m_pause && m_go && m_start_onbuffer && m_parser && 
m_parser->isTimeLoaded(m_bufferTime)) {
-               log_debug("Setting status to bufferFull and enabling pipeline");
-               setStatus(bufferFull);
-               m_start_onbuffer = false;
-               m_pause = false;
-               gst_element_set_state (GST_ELEMENT (pipeline), 
GST_STATE_PLAYING);
+       if (m_isFLV && m_pause && m_go && m_start_onbuffer && m_parser && 
m_parser->isTimeLoaded(m_bufferTime))
+       {
+               if ( ! playPipeline() )
+               {
+                       log_error("Could not enable pipeline");
+                       return;
+               }
        }
 
        // If we're out of data, but still not done loading, pause playback,
        // or stop if loading is complete
-       if (m_pausePlayback) {
-               log_debug("Playback paused");
+       if (m_pausePlayback)
+       {
+               log_debug("Playback paused (out of data?)");
+
                m_pausePlayback = false;
-               if (_netCon->loadCompleted()) {
+               if (_netCon->loadCompleted())
+               {
                        log_debug("Load completed, setting playStop status and 
shutting down pipeline");
                        setStatus(playStop);
 
                        // Drop gstreamer pipeline so callbacks are not called 
again
-                       if ( ! resetPipeline() )
+                       if ( ! disablePipeline() )
                        {
                                // the state change failed
                                log_error("Could not interrupt pipeline!");
@@ -756,17 +801,23 @@
 
                        m_go = false;
                        m_clock_offset = 0;
-               } else {
-                       gst_element_set_state (GST_ELEMENT (pipeline), 
GST_STATE_PAUSED);
-                       GstFormat fmt = GST_FORMAT_TIME;
+               }
+               else
+               {
+                       log_msg("Pausing pipeline on ::advance() [ 
loadCompleted returned false ]");
+                       if ( !pausePipeline(true) )
+                       {
+                               log_error("Could not pause pipeline");
+                       }
+
+                       /// TODO: shouldn't we check 'ret' value here !!??
+
                        int64_t pos;
-                       GstStateChangeReturn ret;
                        GstState current, pending;
+                       GstStateChangeReturn ret;
+                       GstFormat fmt = GST_FORMAT_TIME;
 
                        ret = gst_element_get_state (GST_ELEMENT (pipeline), 
&current, &pending, 0);
-
-                       /// TODO: shouldn't we check 'ret' value here !!??
-
                        if (current != GST_STATE_NULL && 
gst_element_query_position (pipeline, &fmt, &pos)) {
                                pos = pos / 1000000;
                        } else {
@@ -774,8 +825,6 @@
                        }
                        // Buffer a second before continuing
                        m_bufferTime = pos + 1000;
-                       m_start_onbuffer = true;
-                       m_pause = true;
                }
        }
 
@@ -853,8 +902,82 @@
 
 /*private*/
 bool
-NetStreamGst::resetPipeline()
+NetStreamGst::disconnectVideoHandoffSignal()
+{
+       if (videosource && _handoffVideoSigHandler )
+       {
+               log_debug("Disconnecting video handoff signal %lu", 
_handoffAudioSigHandler);
+               g_signal_handler_disconnect(videosource, 
_handoffVideoSigHandler);
+               _handoffVideoSigHandler = 0;
+       }
+
+       // TODO: check return code from previous call !
+       return true;
+}
+
+/*private*/
+bool
+NetStreamGst::disconnectAudioHandoffSignal()
+{
+       if ( audiosource && _handoffAudioSigHandler );
+       {
+               log_debug("Disconnecting audio handoff signal %lu", 
_handoffAudioSigHandler);
+               g_signal_handler_disconnect(audiosource, 
_handoffAudioSigHandler);
+               _handoffAudioSigHandler = 0;
+       }
+
+       // TODO: check return code from previous call !
+       return true;
+}
+
+/*private*/
+bool
+NetStreamGst::connectVideoHandoffSignal()
+{
+       log_debug("Connecting video handoff signal");
+
+       assert(_handoffVideoSigHandler == 0);
+
+       _handoffVideoSigHandler = g_signal_connect (videosource, "handoff",
+                       G_CALLBACK (NetStreamGst::video_callback_handoff), 
this);
+       log_debug("New _handoffVideoSigHandler id : %lu", 
_handoffVideoSigHandler);
+
+       assert(_handoffVideoSigHandler != 0);
+
+       // TODO: check return code from previous call !
+       return true;
+}
+
+/*private*/
+bool
+NetStreamGst::connectAudioHandoffSignal()
+{
+       log_debug("Connecting audio handoff signal");
+
+       assert(_handoffAudioSigHandler == 0);
+
+       _handoffAudioSigHandler = g_signal_connect (audiosource, "handoff",
+                       G_CALLBACK (NetStreamGst::audio_callback_handoff), 
this);
+
+       log_debug("New _handoffAudioSigHandler id : %lu", 
_handoffAudioSigHandler);
+
+       assert(_handoffAudioSigHandler != 0);
+
+       // TODO: check return code from previous call !
+       return true;
+}
+
+/*private*/
+bool
+NetStreamGst::disablePipeline()
 {
+       boost::mutex::scoped_lock lock(_pipelineMutex);
+
+       // Disconnect the handoff handler
+       // TODO: VERIFY THE SIGNAL WILL BE RESTORED WHEN NEEDED !!
+       if ( videosource ) disconnectVideoHandoffSignal();
+       if ( audiosource ) disconnectAudioHandoffSignal();
+
        // Drop gstreamer pipeline so callbacks are not called again
        GstStateChangeReturn ret =  gst_element_set_state (GST_ELEMENT 
(pipeline), GST_STATE_NULL);
        if ( ret == GST_STATE_CHANGE_FAILURE )
@@ -868,15 +991,244 @@
        else if ( ret == GST_STATE_CHANGE_SUCCESS )
        {
                // the state change succeeded
-               log_debug("State change successful");
+               log_debug("State change to NULL successful");
+
+               // just make sure
+               GstState current, pending;
+               ret = gst_element_get_state (GST_ELEMENT (pipeline), &current, 
&pending, 0);
+               if (current != GST_STATE_NULL )
+               {
+                       log_error("State change to NULL NOT confirmed !");
+                       return false;
+               }
        }
        else if ( ret == GST_STATE_CHANGE_ASYNC )
        {
-               // the state change will happen asynchronously
-               log_debug("State change will happen asynchronously!");
+               // The element will perform the remainder of the state change
+               // asynchronously in another thread
+               // We'll wait for it...
 
-               // @@ we should call gst_get_state() to wait for it instead..
+               log_debug("State change to NULL will be asynchronous.. waiting 
for it");
+
+               GstState current, pending;
+               do {
+                       ret = gst_element_get_state (GST_ELEMENT (pipeline), 
&current, &pending, GST_SECOND*1); 
+
+                       log_debug(" NULL state change still not completed after 
X seconds");
+
+               } while ( ret == GST_STATE_CHANGE_ASYNC && current != 
GST_STATE_NULL );
+
+               if ( ret == GST_STATE_CHANGE_SUCCESS )
+               {
+                       assert ( current == GST_STATE_NULL );
+                       log_debug(" Async NULL completed successfully");
+               }
+               else if ( ret == GST_STATE_CHANGE_FAILURE )
+               {
+                       assert ( current != GST_STATE_NULL );
+                       log_debug(" Async NULL completed failing.");
                return false; 
+               }
+               else abort();
+
+
+       }
+       else if ( ret == GST_STATE_CHANGE_NO_PREROLL )
+       {
+               // the state change succeeded but the element
+               // cannot produce data in PAUSED.
+               // This typically happens with live sources.
+               log_debug("State change succeeded but the element cannot 
produce data in PAUSED");
+
+               // @@ what to do in this case ?
+       }
+       else
+       {
+               log_error("Unknown return code from gst_element_set_state");
+               return false;
+       }
+
+       return true;
+
+}
+
+/*private*/
+bool
+NetStreamGst::playPipeline()
+{
+       boost::mutex::scoped_lock lock(_pipelineMutex);
+
+       log_debug("Setting status to bufferFull and enabling pipeline");
+
+       if ( videosource && ! _handoffVideoSigHandler )
+       {
+               connectVideoHandoffSignal();
+       }
+
+       if ( audiosource && ! _handoffAudioSigHandler )
+       {
+               connectAudioHandoffSignal();
+       }
+
+       if (!m_go) { 
+               setStatus(playStart);
+               m_go = true;
+       }
+       m_pause = false;
+       m_start_onbuffer = false;
+
+
+       // Set pipeline to PLAYING state
+       GstStateChangeReturn ret =  gst_element_set_state (GST_ELEMENT 
(pipeline), GST_STATE_PLAYING);
+       if ( ret == GST_STATE_CHANGE_FAILURE )
+       {
+               // the state change failed
+               log_error("Could not set pipeline state to PLAYING!");
+               return false;
+
+               // @@ eh.. what to do then ?
+       }
+       else if ( ret == GST_STATE_CHANGE_SUCCESS )
+       {
+               // the state change succeeded
+               log_debug("State change to PLAYING successful");
+
+               // just make sure
+               GstState current, pending;
+               ret = gst_element_get_state (GST_ELEMENT (pipeline), &current, 
&pending, 0);
+               if (current != GST_STATE_PLAYING )
+               {
+                       log_error("State change to PLAYING NOT confirmed !");
+                       return false;
+               }
+       }
+       else if ( ret == GST_STATE_CHANGE_ASYNC )
+       {
+               // The element will perform the remainder of the state change
+               // asynchronously in another thread
+               // We'll wait for it...
+
+               log_debug("State change to play will be asynchronous.. waiting 
for it");
+
+               GstState current, pending;
+               do {
+                       ret = gst_element_get_state (GST_ELEMENT (pipeline), 
&current, &pending, GST_SECOND*1); 
+
+                       log_debug(" Play still not completed after X seconds");
+
+               } while ( ret == GST_STATE_CHANGE_ASYNC && current != 
GST_STATE_PLAYING );
+
+               if ( ret == GST_STATE_CHANGE_SUCCESS )
+               {
+                       assert ( current == GST_STATE_PLAYING );
+                       log_debug(" Async play completed successfully");
+               }
+               else if ( ret == GST_STATE_CHANGE_FAILURE )
+               {
+                       assert ( current != GST_STATE_PLAYING );
+                       log_debug(" Async play completed failing.");
+                       return false;
+               }
+               else abort();
+
+       }
+       else if ( ret == GST_STATE_CHANGE_NO_PREROLL )
+       {
+               // the state change succeeded but the element
+               // cannot produce data in PAUSED.
+               // This typically happens with live sources.
+               log_debug("State change succeeded but the element cannot 
produce data in PAUSED");
+
+               // @@ what to do in this case ?
+       }
+       else
+       {
+               log_error("Unknown return code from gst_element_set_state");
+               return false;
+       }
+
+       return true;
+
+}
+
+/*private*/
+bool
+NetStreamGst::pausePipeline(bool startOnBuffer)
+{
+       boost::mutex::scoped_lock lock(_pipelineMutex);
+
+       log_debug("Setting pipeline state to PAUSE");
+
+       if ( ! m_go )
+       {
+               log_debug("Won't set the pipeline to PAUSE state if m_go is 
false");
+               return false;
+       }
+
+
+       if ( videosource && ! _handoffVideoSigHandler )
+       {
+               connectVideoHandoffSignal();
+       }
+
+       if ( audiosource && ! _handoffAudioSigHandler )
+       {
+               connectAudioHandoffSignal();
+       }
+
+       m_pause = true;
+       m_start_onbuffer = startOnBuffer;
+
+       // Set pipeline to PAUSE state
+       GstStateChangeReturn ret =  gst_element_set_state (GST_ELEMENT 
(pipeline), GST_STATE_PAUSED);
+       if ( ret == GST_STATE_CHANGE_FAILURE )
+       {
+               // the state change failed
+               log_error("Could not interrupt pipeline!");
+               return false;
+       }
+       else if ( ret == GST_STATE_CHANGE_SUCCESS )
+       {
+               // the state change succeeded
+               log_debug("State change to PAUSE successful");
+
+               // just make sure
+               GstState current, pending;
+               ret = gst_element_get_state (GST_ELEMENT (pipeline), &current, 
&pending, 0);
+               if (current != GST_STATE_PAUSED )
+               {
+                       log_error("State change to PLAYING NOT confirmed !");
+                       return false;
+               }
+       }
+       else if ( ret == GST_STATE_CHANGE_ASYNC )
+       {
+               // The element will perform the remainder of the state change
+               // asynchronously in another thread
+               // We'll wait for it...
+
+               log_debug("State change to paused will be asynchronous.. 
waiting for it");
+
+               GstState current, pending;
+               do {
+                       ret = gst_element_get_state (GST_ELEMENT (pipeline), 
&current, &pending, GST_SECOND*1); 
+
+                       log_debug(" Pause still not completed after X seconds");
+
+               } while ( ret == GST_STATE_CHANGE_ASYNC && current != 
GST_STATE_PAUSED );
+
+               if ( ret == GST_STATE_CHANGE_SUCCESS )
+               {
+                       assert ( current == GST_STATE_PAUSED );
+                       log_debug(" Async pause completed successfully");
+               }
+               else if ( ret == GST_STATE_CHANGE_FAILURE )
+               {
+                       assert ( current != GST_STATE_PAUSED );
+                       log_debug(" Async pause completed failing.");
+                       return false;
+               }
+               else abort();
 
        }
        else if ( ret == GST_STATE_CHANGE_NO_PREROLL )

Index: server/asobj/NetStreamGst.h
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/NetStreamGst.h,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -b -r1.18 -r1.19
--- server/asobj/NetStreamGst.h 15 May 2007 18:20:45 -0000      1.18
+++ server/asobj/NetStreamGst.h 16 May 2007 12:50:26 -0000      1.19
@@ -60,7 +60,9 @@
        static int readPacket(void* opaque, char* buf, int buf_size);
        static int seekMedia(void *opaque, int offset, int whence);
 
-       static void startPlayback(NetStreamGst* ns);
+       void startPlayback();
+
+       static void playbackStarter(NetStreamGst* ns);
        static void callback_output (GstElement* /*c*/, GstBuffer *buffer, 
GstPad* /*pad*/, gpointer user_data);
        static void callback_newpad (GstElement *decodebin, GstPad *pad, 
gboolean last, gpointer data);
        static void video_callback_handoff (GstElement* /*c*/, GstBuffer 
*buffer, GstPad* /*pad*/, gpointer user_data);
@@ -68,12 +70,57 @@
 
 private:
 
+       /// Connect the video "handoff" signal
+       //
+       /// @return true on success, false on failure
+       ///
+       bool connectVideoHandoffSignal();
+
+       /// Connect the audio "handoff" signal
+       //
+       /// @return true on success, false on failure
+       ///
+       bool connectAudioHandoffSignal();
+
+       /// Disconnect the video "handoff" signal
+       //
+       /// @return true on success, false on failure
+       ///
+       bool disconnectVideoHandoffSignal();
+
+       /// Disconnect the audio "handoff" signal
+       //
+       /// @return true on success, false on failure
+       ///
+       bool disconnectAudioHandoffSignal();
+
+       /// \brief
        /// Set pipeline state to GST_STATE_NULL 
-       /// (the NULL state or initial state of an elemen)
+       /// and disconnect handoff signals
+       //
+       /// If the call needs be asynchronous, we'll wait for it.
+       /// TODO: implement the above
+       ///
+       bool disablePipeline();
+
+       /// \brief
+       /// Set pipeline state to GST_STATE_PLAYING,
+       /// connect handoff signals, send appropriate
+       /// notifications.
+       //
+       /// If the call needs be asynchronous, we'll wait for it.
+       /// TOOD: implement the above
        ///
+       bool playPipeline();
+
+       /// \brief
+       /// Set pipeline state to GST_STATE_PAUSE,
+       /// connect handoff signals if not connected already
+       //
        /// If the call needs be asynchronous, we'll wait for it.
+       /// TOOD: implement the above
        ///
-       bool resetPipeline();
+       bool pausePipeline(bool startOnBuffer);
 
        // gstreamer pipeline objects
        GstElement *pipeline;
@@ -87,6 +134,9 @@
        GstElement *videoflip;
        GstElement *audioconv;
 
+       // Mutex protecting pipeline control
+       boost::mutex _pipelineMutex;
+
        // used only for FLV
        GstElement *audiosource;
        GstElement *videosource;
@@ -96,6 +146,10 @@
        GstElement *videoinputcaps;
        GstElement *audioinputcaps;
 
+       // Signal handlers id
+       gulong _handoffVideoSigHandler;
+       gulong _handoffAudioSigHandler;
+
 #ifndef DISABLE_START_THREAD
        boost::thread *startThread;
 #endif




reply via email to

[Prev in Thread] Current Thread [Next in Thread]