Trying to undersand g_signal_connect()

Enrique Ocaña González eocanha at igalia.com
Thu Nov 3 12:44:05 UTC 2016


El jueves, 3 de noviembre de 2016 4:44:04 (CET) Rick Blacker escribió:

> g_signal_connect( demuxer, "pad-added", G_CALLBACK( on_pad_added ),
> decoder );
> 
> static void on_pad_added( GstElement *element, GstPad *pad, 
> 					gpointer data )
> {
> 	GstPad 		*sinkpad;
> 	GstElement 	*decoder = ( GstElement * ) data;
> 	sinkpad = gst_element_get_static_pad( decoder, "sink" );
> 	gst_pad_link( pad, sinkpad );
> 	gst_object_unref( sinkpad );
> }
> 
> I get the comment. But what is throwing me off is the actual code for
> the definition of the callback. It's taking a pointer to an element,
> but that element is not even being used. I might have thought that it
> was a pointer to the demuxer.  
> 
> Which leads me to... Why are we adding the demuxer to the g_signal_call
> ?  Also where is the connection from the demuxer to the decoder? Is the
> GstPad pad the pad on the demuxer???  
> 
> I guess what is throwing me off is the definition of calling 
> g_signal_connect with it's required parameters and the declaration of
> on_pad_added and it's function definition.  

The callback takes 3 arguments (even if they're not used) because the signal 
definition demands that particular callback signature. That's how the API is. 
The programmer (user) can't decide about that.

GstOggDemux[1] is a subclass of GstElement, and all GstElements offer the pad-
added signal[2]. Note that for some reason which has always striked me, 
signals are only documented in developer.gnome.org.

The 3 parameters of the signal callback, as shown in [2] are:

- GstElement: The object which received the signal. Who is creating a new pad? 
  The demuxer. So the demuxer will be this element. In the particular code of 
  the example this info isn't needed, but in other contexts it would be. For 
  instance, if you register a callback on several different elements to just 
  log the creation of pads, you would be interested in knowing which element 
  created the pad. In the specific case of the example we register the 
  callback to only one element, so we already know that it will always be the 
  decoder.
- GstPad: This is the pad being added (to the demuxer element).
- gpointer user_data: This is kind of a "context", or "whatever the programmer 
  thinks is needed for the callback to do its job". If the callback was a 
  logger, this parameter could have been null. In this case, what this 
  callback wants to do is to link the created pad (2nd parameter) with the 
  demuxer. How do we get a pointer to the demuxer from inside the callback? 
  Using a global variable? That's not very elegant nor scalable (in a scenario 
  with several demuxers). The best way is to pass a pointer to the demuxer as 
  "context" when registering the callback. We could also have passed a pointer 
  to the decoder sink pad, or a pointer to the whole pipeline and perform a 
  search for the decoder using gst_bin_get_by_name()[3]. There's always more 
  than one way to do it.

I hope to have shed some light on why the example code is like that.

Cheers.


[1] https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-plugins/html/gst-plugins-base-plugins-oggdemux.html
[2] https://developer.gnome.org/gstreamer/stable/GstElement.html#GstElement-pad-added
[3] https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/
GstBin.html#gst-bin-get-by-name






-- 
Enrique Ocaña González


More information about the gstreamer-devel mailing list