After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 753754 - Add GstValueList and GstValueArray support to gst-python
Add GstValueList and GstValueArray support to gst-python
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gst-python
1.11.2
Other All
: Normal enhancement
: git master
Assigned To: GStreamer Maintainers
GStreamer Maintainers
: 693168 (view as bug list)
Depends on:
Blocks: 780053
 
 
Reported: 2015-08-18 10:55 UTC by Christian Leichsenring
Modified: 2017-08-05 14:24 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
gstvalue: Add transformation to/from GValueArray (5.92 KB, patch)
2017-03-20 20:49 UTC, Nicolas Dufresne (ndufresne)
committed Details | Review
structure: Add get/set_array/list using GValueArray (9.35 KB, patch)
2017-03-20 20:49 UTC, Nicolas Dufresne (ndufresne)
committed Details | Review
gstutils: Add helpers to get/set array properties (4.63 KB, patch)
2017-03-20 20:49 UTC, Nicolas Dufresne (ndufresne)
committed Details | Review
overrides: Add more GstValue overrides (13.31 KB, patch)
2017-03-23 17:58 UTC, Nicolas Dufresne (ndufresne)
committed Details | Review

Description Christian Leichsenring 2015-08-18 10:55:52 UTC
As detailed in bug #669982, the GStreamer Python bindings currently lack support for GstValueList. As Sebastian pointed out in https://bugzilla.gnome.org/show_bug.cgi?id=669982#c5 some "override magic" would be nedded to overcome the lack of support in pygi.

As it currently stands, elements using GstValueList to communicate (namely spectrum) are virtually unsupported in Python.
Comment 1 Arne Caspari 2015-11-13 14:32:12 UTC
This issue not only affects the spectrum element but the much more widely used v4l2src element too. It certainly needs fixing.
Comment 2 Sebastian Dröge (slomo) 2015-11-13 15:20:35 UTC
There's also GstValueArray which works basically the same and would be good to have
Comment 3 Thibault Saunier 2015-11-13 15:26:08 UTC
We need to do something similare to http://cgit.freedesktop.org/gstreamer/gst-python/tree/gi/overrides/gstmodule.c#n131 for those GTypes
Comment 4 Florent Thiéry 2016-06-08 14:29:38 UTC
Am i correct in assuming that it is still not possible to get volume magnitude from python ?
Comment 5 Nicolas Dufresne (ndufresne) 2017-03-17 01:41:01 UTC
(In reply to Arne Caspari from comment #1)
> This issue not only affects the spectrum element but the much more widely
> used v4l2src element too. It certainly needs fixing.

How does this affect v4l2src ?
Comment 6 Arne Caspari 2017-03-17 07:35:40 UTC
(In reply to Nicolas Dufresne (stormer) from comment #5)
> How does this affect v4l2src ?

It affects any caps that may contain a value list, for example:


>>> from gi.repository import Gst
>>> Gst.init(())
[]
>>> src = Gst.ElementFactory.make("v4l2src")
>>> src.set_property("device", "/dev/video1")
>>> src.set_state(Gst.State.READY)
<enum GST_STATE_CHANGE_SUCCESS of type Gst.StateChangeReturn>
>>> caps = src.pads[0].query_caps()
>>> s = caps.get_structure(0)
>>> s.to_string()
'video/x-bayer, format=(string)gbrg, width=(int)744, height=(int)480, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 20000/263, 60/1, 30/1, 25/1, 15/1, 15/2, 5/1 };'
>>> s.get_value("framerate")
Traceback (most recent call last):
  • File "<stdin>", line 1 in <module>
TypeError: unknown type GstValueList
>>>
Comment 7 Nicolas Dufresne (ndufresne) 2017-03-18 01:37:08 UTC
While it would be interesting to have python specific bindings (even though not that trivial), I made a experiment today of a new API that would address this issue.

What I did, and it was conclusive, is to implement GValueArray to/from GST_TYPE_ARRAY/LIST conversion (though g_value_transform). Then I implement those new function in GstStructure:

  gboolean gst_structure_get_array (s, fieldname, GValueArray ** array)
  gboolean gst_structure_get_list (s, fieldname, GValueArray **array)
  void gst_structure_set_array (s, fieldname, GValueArray * array)
  void gst_structure_set_list (s, fieldname, GValueArray * array)

Then in Python, you can use it as follow:

  s = Gst.Structure.new_empty("test")
  arr = GObject.ValueArray()
  arr.append(1)
  arr.append(2)
  s.set_array("array", arr)
  ret, arr = s.get_array("array")

I'll add similar helpers to get/set GST_TYPE_ARRAY/LIST object properties. The reason I went this way is that it's language agnostic, and representing those in an override seems more complex then just a Fraction.
Comment 8 Nicolas Dufresne (ndufresne) 2017-03-20 20:49:07 UTC
Created attachment 348360 [details] [review]
gstvalue: Add transformation to/from GValueArray

This allow transforming a GValue of type G_TYPE_VALUE_ARRAY to
and from GST_TYPE_ARRAY/LIST.
Comment 9 Nicolas Dufresne (ndufresne) 2017-03-20 20:49:12 UTC
Created attachment 348361 [details] [review]
structure: Add get/set_array/list using GValueArray

This adds a binding friendly interface to get and set arrays
and list into GstStructure.

New API:
 - gst_structure_set_array
 - gst_structure_set_list
 - gst_structure_get_array
 - gst_structure_get_list
Comment 10 Nicolas Dufresne (ndufresne) 2017-03-20 20:49:17 UTC
Created attachment 348362 [details] [review]
gstutils: Add helpers to get/set array properties

This is to help bindings access properties of type GST_TYPE_ARRAY.
This function will get/set the property and convert form/to
GValueArray.

New API:
  gst_util_set_object_array
  gst_util_get_object_array
Comment 11 Nicolas Dufresne (ndufresne) 2017-03-20 21:14:07 UTC
There is an interesting side effect that should be mentionned, you can now g_object_set() any GST_TYPE_LIST/GST_TYPE_ARRAY using a GValueArray (and vis-versa). GObject kindly call g_value_transform() internally. This is not usable from Python though, since the bindings will try and convert by itself. So if you pass a GValueArray, it won't wrap it into a GValue before setting it.
Comment 12 Nicolas Dufresne (ndufresne) 2017-03-20 21:21:28 UTC
And same applies if you use g_object_get/get_property(). Meaning you don't even need to port code using those properties, at least in C.
Comment 13 Nicolas Dufresne (ndufresne) 2017-03-21 18:04:38 UTC
*** Bug 693168 has been marked as a duplicate of this bug. ***
Comment 14 Nicolas Dufresne (ndufresne) 2017-03-21 18:07:25 UTC
Ok, this is just not elegant, though the transform stuff is kind of nice to have, so maybe we could keep this one. I'll start adding stuff in the python overrides. That means at some point we should create gst-javascript if we want the same to be usable.
Comment 15 Nicolas Dufresne (ndufresne) 2017-03-23 17:58:26 UTC
Created attachment 348593 [details] [review]
overrides: Add more GstValue overrides

This patch adds overrides to support IntRange, Int64Range, DoubleRange,
FractionRange, Array and List. For integer ranges, it maps this
to python 'range'. Gst.IntRange() and Gst.Int64Range() are simple cast
to let the underlying code know which GType to use. To set such range in
python you will do:

  structure.set_value("range", Gst.IntRange(range(0,10,2)))

Same for the 64 bit variant. And when you do:

  r = structure.get_value("range")

A range will be returned directly, without the wrapper. For DoubleRange
and FractionRange, there is no native support in python. So the usage
will be:

  structure.set_value("range", Gst.DoubleRange(0,10.0))
  structure.set_value("range",
      Gst.FractionRange(Gst.Fraction(1/30), Gst.Fraction(1/5))

When getting this value, Gst.DoubleRange and Gst.FractionRange class are
returned. They both have start/stop members. The naming was taken from
range type.

For Array and List, both uses the native list type, though they can be
constructed from any python sequence. So again, the class is just like
a cast, to let it pick the right GType and python list are being
returned.

  structure.set_value("list", Gst.ValueList([1,2,3,4]))
  structure.set_value("array", Gst.ValueArray([1,2,3,4))

Using string and tuple could also work. Since Gst.ValueList/Array are
sequence, you can convert one to the other with:

  list = Gst.ValueList([1,2,3,4])
  array = Gst.ValueArray (list)
Comment 16 Thibault Saunier 2017-03-23 18:34:58 UTC
Review of attachment 348593 [details] [review]:

Looks about right, but adding some unit tests would be very welcome :)

::: gi/overrides/gstmodule.c
@@ -130,0 +130,40 @@
+static PyObject *
+gi_gst_int_range_from_value (const GValue * value)
+{
... 37 more ...

Please raise an exception here.

@@ -130,0 +130,83 @@
+static PyObject *
+gi_gst_int_range_from_value (const GValue * value)
+{
... 80 more ...

Sounds like you should raise an exception here.

@@ +271,3 @@
+  return 0;
+
+    goto fail;

Same.

@@ +348,3 @@
+  return 0;
+
+    PyErr_SetString (PyExc_KeyError,

Same.
Comment 17 Nicolas Dufresne (ndufresne) 2017-03-24 17:30:31 UTC
Comment on attachment 348593 [details] [review]
overrides: Add more GstValue overrides

Attachment 348593 [details] pushed as a4566ff - overrides: Add more GstValue overrides
Comment 18 Nicolas Dufresne (ndufresne) 2017-03-24 17:32:46 UTC
Attachment 348360 [details] pushed as 84f826a - gstvalue: Add transformation to/from GValueArray
Attachment 348361 [details] pushed as c21e219 - structure: Add get/set_array/list using GValueArray
Attachment 348362 [details] pushed as 2c05656 - gstutils: Add helpers to get/set array properties
Comment 19 Nicolas Dufresne (ndufresne) 2017-03-24 17:34:43 UTC
Voilà, so now we have both the workaround, and proper overrides in Python. Btw, I have added all exception code, added type check on the python side and finally added unit tests for everything (which has been very useful to find small bugs).
Comment 20 wavlew 2017-08-05 11:41:21 UTC
Dear Gstreamers, thank you for your work.

I tried to run an application with the gstspectrum element in a python environment.
When I read the elements message with the array of frequency magnitudes:

def on_message(self, bus, message):
    s = message.get_structure()
        gva = s.get_value('magnitude')

I still get:

TypeError: unknown type GstValueArray. 

What is the difference between GstValueArray and Gst.ValueArray?
What am I doing wrong?

Gstreamer 1.12.2 
Python 2.7.12
Linux pi-VirtualBox 4.4.0-53-generic #74-Ubuntu SMP ... x86_64 GNU/Linux
Comment 21 Nicolas Dufresne (ndufresne) 2017-08-05 14:24:57 UTC
This ticket was closed and you don't seem to be reporting a regression, but instead requesting for support. The GStreamer mailing list is likely a better place for your question.

P.s. Make sure you have gst-python 1.12 package properly installed.