Gstreamer 1.0: Fix GValueArray usage in gstlal_segmentsrc
Done: We can create and use lal_segmentsrc
in spiir in a production environment.
Issue:
The segment_list property of gstlal_segmentsrc.c currently cannot be set from python. But our injection test scripts use veto segments, which we require a segmentsrc to be created. If you try, you see an error similar to the following (copied for convenience from the Gstlal example, so for us the types/values are different): TypeError: could not convert array([1.3, 2.6, 3.9]) to type 'GValueArray' when setting property 'GstAudioFIRFilter.kernel'
Background:
GSTLAL ran into an issue with GValueArray when updating to the version of PyGObject in the IGWN Conda environment.
They raised an issue with GSTLAL, GStreamer, then PyGObject. They've all stalled for a year, with no action. GSTLAL decided to use an older version of PyGObject.
GValueArray has been deprecated for some time, and GStreamer's pushed to keep support for it. This could be a functionality regression in PyGObject, it could be undefined/unintended behaviour that they're no longer supporting. Either way, GValueArrays are a sinking ship. The fact that this is a somewhat old issue in a released and in-use version of PyGObject means there's probably a solution or workaround.
Solution:
It seems like the intended solution is to switch to a GArray of GValues. There seems to be some special case support for it between Python and C too. For example, see https://gitlab.gnome.org/GNOME/pygobject/-/issues/162
I'm able to make 1D arrays by creating a Python list of GObject.Value
s, and using that to set segment_list
.
I can make 2D arrays by creating nested GLib.Array
s, with the inner one containing GObject.Value
s.
In C, the segment_list property needs to be changed to accept a GArray. However, on get_property, python receives a GArray, which does not expose its data property. This could still be a good intermediate solution for SPIIR, since we don't use get_property on segment_list.
Alternatives:
- We can make a 1D array without ever referring to GArray in python, and 'unroll' higher dimensional arrays :|
- GstValueArrays seem to be a GStreamer drop-in replacement for GValueArrays, except that the elements have so far only worked if they're a few fundamental types:
int, string, booleans, float
. - We could use the older version of PyGObject. @patrick.clearwater reports that this would be quite difficult to achieve, besides which it's exactly the problem we're trying to avoid.
- It may be possible to define our own 'boxed type', which there's some examples of in C, but I'm unsure how complex it is to set it through python.
- In the worst case, we could serialize/deserialize to string