Killing Zombies - Unref-ing pipelines waiting for async change
Wes Miller
wmiller at sdr.com
Fri Aug 12 10:56:19 PDT 2011
I also see at
http://lists.freedesktop.org/archives/gstreamer-devel/2011-August/032658.html
that my code in this note got deleted. My apologies to anyone reading this
thread in the forum.
FWIW, the RAW tag in naabble seems to be the OMIT-THIS tag.
Re-posting for posterity:
----------------------------------------------------------------------------------------------
This has turned into an interesting problem. Michael and Nicola were
correct. The use of:
gst_element_set_locked_state( m_audioDecoder, TRUE ); //
m_audioDecode is Decodebin
gst_element_abort_state( m_audioDecoder );
gst_element_set_locked_state( m_audioDecoder, FALSE );
created problems and isn't needed.
The part I left out of my explanation, apologies to all, the pipeline was
running in a separate thread from the class destructor that was trying to
kill off the "stuck", async, pipeline. It was coded more or less as in all
the examples:
g_signal_connect( m_recvDecoder, "new-decoded-pad", G_CALLBACK(
on_recv_pad_decoded ), (gpointer)m_recvIdentity );
/*--- Set the pipelines to "playing" state---*/
g_print( "\nReceive pipeline - change pipeline state to
GST_STATE_PLAYING. \n\n" );
m_stateChgRc_recv = gst_element_set_state( m_recvPipeline,
GST_STATE_PLAYING );
g_print( "\nReceive pipeline - state change rc = %d \n\n",
m_stateChgRc_recv );
gst_element_get_state( m_recvPipeline, NULL, NULL, -1 ) ;
g_print( "Recv pipeline - Async state change completed. rc = %d \n",
m_stateChgRc_recv );
/*--- Let the pipelines iterate until an EOS is received ---*/
g_print( "\nReceive pipelines - Running...\n\n" );
g_main_loop_run( m_loop );
/*--- Beyond the main loop, clean up nicely ---*/
g_print( "Receive pipeline - Returned, stopping playback\n" );
gst_element_set_state( m_recvPipeline, GST_STATE_NULL );
g_print( "Receive pipeline - Deleting receive pipeline\n" );
g_main_loop_quit( m_loop );
gst_object_unref( GST_OBJECT ( m_recvPipeline ));
m_recvPipeline = 0;
gst_object_unref( GST_OBJECT ( m_loop ));
m_loop = 0;
Here is what was happening:
The destructor, in its separate thread, set the recvPipeline state to NULL
and unrefed the pipeline and loop.
In the pipeline's thread, the gst_element_get_state() was no longer ASYNC so
the gst_element_get_state() returned and the code above resumed trying to
run the (unref-ed)pipeline and enter the (unref-ed)main loop. This spit out
all sorts of CRITICAL messages and warnings about invalid objects and
refcounts > 0.
The fix was to,
1. remove the unrefs from the destructor, letting the other thread handle
those operations. Then
2.fix the pipeline code thus:
GstState now, pending;
gst_element_get_state( m_recvPipeline, &now, &pending, -1 ) ;
g_print( "Recv pipeline - Async state change completed. rc = %d \n",
m_stateChgRc_recv );
g_print( "Recv pipeline - now = %d \n pendiong = %d\n",
(int)now, (int)pending );
/*--- Let the pipelines iterate until an EOS is received or state !=
PLAYING---*/
if ( GST_STATE_PLAYING == now )
{
g_print( "\nReceive pipelines - Running...\n\n" );
g_main_loop_run( m_loop );
}
/*--- Beyond the main loop, clean up nicely ---*/
g_print( "Receive pipeline - Returned, stopping playback\n" );
gst_element_set_state( m_recvPipeline, GST_STATE_NULL );
g_print( "Receive pipeline - Deleting receive pipeline\n" );
g_main_loop_quit( m_loop );
gst_object_unref( GST_OBJECT ( m_recvPipeline ));
m_recvPipeline = 0;
gst_object_unref( GST_OBJECT ( m_loop ));
m_loop = 0;
Hope this helps the next guy and many thanks to Nicola and Michael.
Wes
--
View this message in context: http://gstreamer-devel.966125.n4.nabble.com/Killing-Zombies-Unref-ing-pipelines-waiting-for-async-change-tp3732732p3740050.html
Sent from the GStreamer-devel mailing list archive at Nabble.com.
More information about the gstreamer-devel
mailing list