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