go-gst / go-gst

Gstreamer bindings and utilities for golang
GNU Lesser General Public License v2.1
158 stars 62 forks source link

GValueArray of doubles marshaler #121

Open Xeue opened 2 months ago

Xeue commented 2 months ago

Hey, we are trying to use the level element which produces messages as described here: https://gstreamer.freedesktop.org/documentation/level/index.html?gi-language=c

There is no parser for this built in and we are struggling to work out how to access the GValueArrays. The [GstClockTime] types are converted but the GetValues and Values functions. But the [GValueArray of doubles] is serialised.

We have tried messing around with go glib and havn't really got anywhere other than a few SIGSEGV violations and other such nasty things...

Is there a way to parse these values and if not how can we go about writing a parser?

Thanks!

RSWilli commented 2 months ago

The "parsers" are actually called marshalers and are defined here: https://github.com/go-gst/go-glib/blob/main/glib/gvalue.go#L326 in go-glib. Additional marshalers can be registered by other libraries like this: https://github.com/go-gst/go-gst/blob/main/gst/gstwebrtc/session_description.go#L13-L20

The two functions ToGValue and marshalXXX work as follows:


Since the GValueArray is located in glib, the bindings should be added to go-glib.

Oftentimes the gtk rust bindings are also a good place for reference, since they do similar things.

RSWilli commented 1 month ago

@Xeue did you solve your problem?

Xeue commented 1 month ago

Yes, eventually, was a bit long winded, but got what I needed working!

grf1 commented 1 month ago

hi @Xeue I'm having a similar issue, would you mind sharing what you did to get it working?

Xeue commented 1 month ago

Hi grf1, so in this case I was trying to process the a message from the event bus, that message was a message generated in the C code in gstreamer, so is stucted and has types in C. To be able to access that in go we need to "un-marshal" it from a C object and into a GO one. To do this we use some of the go and C integration methods. It helps reading up on cGo: https://dev.to/metal3d/understand-how-to-use-c-libraries-in-go-with-cgo-3dbn

But essentialy the steps here are the create a function that can unmarshal the C object. A simple versions looks like this: https://github.com/go-gst/go-gst/blob/main/gst/gstwebrtc/session_description.go#L111-L120

Notice at the top of the file C has been imported, this allows line 112 to use a C function C.g_value_get_boxed (see cGo refernece above)

Once you have a function that can un-marshal it from C you can then register that as an unmarshaler with glib: https://github.com/go-gst/go-gst/blob/main/gst/gstwebrtc/session_description.go#L15-L19

Once regsitered you can use the usual methods in this library to read the values in go (GValue.GoValue())

I know I havn't explained that particularly well... But hopefully that helps get you going in the direction you need?

RSWilli commented 1 month ago

@Xeue could you create a PR for this?

Xeue commented 1 month ago

Sure! I'll need to tidy stuff up and remove the stuff that's specific to me, so won't be for a little bit as I've got a lot on at the moment