Search code examples
c++gstreamerglibgobject

How do I create a GstValueArray in C++?


I am trying to create a GstValueArray in C++ to update a pad property in some GStreamer code, but am unable to figure out from the documentation how to do so. My problem is that I have a GStreamer element that has sink pads with a property "dimensions", which is a "GstValueArray of GValues of type gint". See output from gst-inspect-1.0, some parts omitted for brevity:

...

Pad Templates:
  SINK template: 'sink_%u'
    Availability: On request
    Capabilities:
      ...
    Type: GstVideoComposerSinkPad
    Pad Properties:
      dimensions          : The destination rectangle width and height, if left as '0' they will be the same as input dimensions ('<WIDTH, HEIGHT>')
                            flags: readable, writable, changeable in NULL, READY, PAUSED or PLAYING state, 0x4000
0000
                            GstValueArray of GValues of type "gint"

I'd like to be able to update the dimensions property from my code. Currently, I am trying this:

const auto pad = gst_element_get_static_pad(videomixer, sink_name.c_str());
...
// Create a GValue for width
GValue width = G_VALUE_INIT;
g_value_init(&width, G_TYPE_INT);
g_value_set_int(&width, cameraUpdate["width"]);

// Create a GValue for height
GValue height = G_VALUE_INIT;
g_value_init(&height, G_TYPE_INT);
g_value_set_int(&height, cameraUpdate["height"]);

// Create the GstValueArray
GValue new_dimensions = G_VALUE_INIT;
g_value_init(&new_dimensions, GST_TYPE_ARRAY);
gst_value_array_append_value(&new_dimensions, &width);
gst_value_array_append_value(&new_dimensions, &height);

// Update the pad property "dimensions" with this array
g_object_set(pad, "dimensions", new_dimensions, nullptr);

But this has a runtime error of: GLib-ERROR **: 17:21:07.582: ../../../../glib/gmem.c:135: failed to allocate 62846110096 bytes. I am unsure also where I accidentally requested 62 GB of memory.

Thank you!


Solution

  • g_object_set is a convenience function that, among other things, parses internally the GType of the property and automatically creates the underlying GValue for you. If you are creating the GValue yourself you need to use g_object_set_property instead.

    Replace your g_object_set with:

    g_object_set_property (G_OBJECT(pad), “dimensions”, &new_dimensions)
    

    By the way, remember to call g_value_unset on every GValue to clean up everything.