[gst-devel] How to flush a bus when removing an element from a pipeline?

wl2776 wl2776 at gmail.com
Fri Apr 23 10:29:36 CEST 2010



Edward Hervey wrote:
> 
> On Thu, 2010-04-22 at 22:52 -0800, wl2776 wrote:
>> My application adds an uridecodebin instance to the pipeline, and then
>> removes it, if the element doesn't go to the paused state (this can
>> happen,
>> if a non-media file was supplied to the uridecodebin) and returns
>> GST_STATE_CHANGE_FAILURE.
> 
>   Have you set uridecodebin to NULL before removing it ? Have you made
> sure it didn't connect to anything ? Did you hold an extra reference to
> uridecodebin before adding it to the pipeline (if not, the pipeline
> *stole* your reference and you shouldn't have to unref it after removing
> it from the pipeline).
> 
The exact code.

while(<have a file in a directory and no video or audio stream>) {
  gboolean rb=FALSE;
  uridecodebin[1]=gst_element_factory_make("uridecodebin",
                                           
(m_video_present)?"audio_decodebin":"video_decodebin");
  if(uridecodebin[1])
     rb=gst_bin_add(GST_BIN(m_player),uridecodebin[1]);
  if(rb){
     g_object_set(G_OBJECT(uridecodebin[1]),"uri",file_uri,NULL);
  
     h_id2=g_signal_connect(G_OBJECT(uridecodebin[1]),"no-more-pads",
                                    G_CALLBACK(no_more_pads_cb),this);
     h_id3=g_signal_connect(G_OBJECT(uridecodebin[1]),"unknown-type",
                                    G_CALLBACK(unknown_type_cb),this);
     rs=gst_element_set_state(m_player,GST_STATE_PAUSED);

     while(m_player->current_state!=GST_STATE_PAUSED &&
          !(m_flags & FLAG_DORENDER_COMPLETE) && 
           rs!=GST_STATE_CHANGE_FAILURE){
 	 g_usleep(100000);
     } 
     g_signal_handler_disconnect(G_OBJECT(uridecodebin[1]),h_id2);
     g_signal_handler_disconnect(G_OBJECT(uridecodebin[1]),h_id3);

     if(rs==GST_STATE_CHANGE_FAILURE){
        gst_element_set_state(GST_ELEMENT(m_player),GST_STATE_NULL);
        gst_bin_remove(GST_BIN(m_player),uridecodebin[1]);
        gst_object_unref(uridecodebin[1]);
        uridecodebin[1]=NULL;
     }
  }
}


So, yes, I've put the uridecodebin to NULL.
No, I didn't hold the extra reference - will remove
gst_object_unref(uridecodebin[1]);


Edward Hervey wrote:
> 
>> And the problem is that my application sometimes crashes with the system
>> error message saying, it attempted writing to the location 0x0000010. Or,
>> the location 0xfeeefef6. 
>> I am using MS Visual Studio 2008, and the latter address is very close to
>> the 0xfeeefeee - the value, CRT fills the just released memory.
>> Call stack is useless, it contains only some addresses in the GLib DLL
>> and
>> in windows system libraries.
> 
>   Those addresses are really useful... *NOT* ! 
> 
What not?
How can I use these addresses?


Edward Hervey wrote:
> 
>> I suspect, this is because the bus contains some messages related to the
>> recently removed uridecodebin.
> 
>   Most likely due to the double-unreferencing I explained above.
> 

It shouldn't be a problem, gst_object_unref() contains the checks for
ref_count field and doesn't do anything if it's <=0

void
gst_object_unref (gpointer object)
{
  g_return_if_fail (object != NULL);
  g_return_if_fail (((GObject *) object)->ref_count > 0);
...

-- 
View this message in context: http://gstreamer-devel.966125.n4.nabble.com/How-to-flush-a-bus-when-removing-an-element-from-a-pipeline-tp2027847p2035308.html
Sent from the GStreamer-devel mailing list archive at Nabble.com.




More information about the gstreamer-devel mailing list