Simple GValue and GstStructure Question

Tim-Philipp Müller t.i.m at zen.co.uk
Tue Feb 19 15:17:44 PST 2013


On Tue, 2013-02-19 at 15:00 -0800, johnwesting wrote:

Hi,

> I apologize for trying to make my post easier for others to read by adding
> the  tag to the 2 functions. I have read those documents, I still don't
> understand. Here are the 2 functions I posted earlier:

The lifecycle of a GValue is as follows:

 GValue val = { 0, }; /* or = G_VALUE_INIT */

 g_value_init (&val, G_TYPE_FOO or GST_TYPE_FOO or XYZ_TYPE_FOO);
 ... do something with the value ..
 g_value_unset (&val);

This is when the value is allocated on the stack, as it is often the
case. You can of course also allocate a GValue dynamically, then you
have to add alloc/free to the above.


> void add_int_value_on_stack(GstStructure *struct, gint int_value)
> {
>    GValue gvalue = G_VALUE_INIT;
> 
>    g_value_init(&gvalue, G_TYPE_INT);
> 
>    g_value_set_int(&gvalue, int_value);
> 
>    // does gst_structure_set_value() create its own gvalue?
>    gst_structure_set_value(struct, "field", &gvalue);

According to
http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/gstreamer-GstStructure.html#gst-structure-set-value
the function signature has a const GValue * as last argument. The
'const' implies that the structure will make a copy of the value you
pass. This means you are still responsible for unsetting it, and - if it
was allocated dynamically on the heap - freeing it. _unset() will clear
any "deep" allocations the value made (e.g. object references or string
copies), but not the GValue struct itself.

>    // safe to unset?
>    g_value_unset(&gvalue);

Yes, safe and correct.
> }
> 
> void add_int_value_on_heap(GstStructure *struct, gint int_value)
> {
>    GValue *gvalue;
> 
>    galue = malloc(sizeof(GValue));
>    bzero(gvalue, sizeof(gvalue));
> 
>    // need to init if I malloced and zeroed??
>    g_value_init(gvalue, G_TYPE_INT);

Yes, you need to init it to set the type and initialise the fields
(depending on the type fields may be initialised to something else than
just 0/NULL).


>    g_value_set_int(gvalue, int_value);
> 
>    gst_structure_take_value(struct, "field", gvalue);

_take_value() will take ownership of the GValue *contents*, but not the
structure itself (remember that the API was designed mostly for GValues
allocated on the stack). This means you must not call g_value_unset(),
but if you allocated the GValue structure on the heap you will still
have to free it.

> }

There are multiple different ways of doing things. _take_value() is
slightly more efficient here, since it avoids doing a copy with an
unnecessary init/unset cycle (which goes through the type system), but
you can us _set_value() or _take_value() both with heap allocated values
and with stack allocated values.

Cheers
 -Tim



More information about the gstreamer-devel mailing list