diff --git a/cmd/gst-plugin-gen/main.go b/cmd/gst-plugin-gen/main.go index 9edbf57..891ca1e 100644 --- a/cmd/gst-plugin-gen/main.go +++ b/cmd/gst-plugin-gen/main.go @@ -119,6 +119,12 @@ var pluginTmpl = template.Must(template.New("").Funcs(template.FuncMap{ "adjustedName": func(name string) string { return strings.ToLower(strings.Replace(name, "-", "_", -1)) }, + "extendsFromBase": func(subclass string) bool { + if strings.HasPrefix(subclass, "base.") { + return true + } + return false + }, }).Parse(`// !WARNING! THIS FILE WAS GENERATED BY GST-PLUGIN-GEN !WARNING! // package main @@ -128,7 +134,9 @@ import ( "unsafe" "github.com/tinyzimmer/go-gst/gst" + {{- if (.Config.Element.Subclass | extendsFromBase) }} "github.com/tinyzimmer/go-gst/gst/base" + {{- end }} ) // The metadata for this plugin diff --git a/examples/plugins/Makefile b/examples/plugins/Makefile index 6954605..bbeafe0 100644 --- a/examples/plugins/Makefile +++ b/examples/plugins/Makefile @@ -6,8 +6,8 @@ all: $(PLUGINS) $(PLUGINS): cd $@ && \ go generate && \ - go build -o ../libgstgo$@.so -buildmode c-shared . - rm libgstgo$@.h + go build -o ../libgst$@.so -buildmode c-shared . + rm libgst$@.h clean: rm -f *.so *.h \ No newline at end of file diff --git a/examples/plugins/filesink/filesink.go b/examples/plugins/gofilesink/filesink.go similarity index 99% rename from examples/plugins/filesink/filesink.go rename to examples/plugins/gofilesink/filesink.go index 2c68fd6..9820973 100644 --- a/examples/plugins/filesink/filesink.go +++ b/examples/plugins/gofilesink/filesink.go @@ -59,8 +59,8 @@ var CAT = gst.NewDebugCategory( // This element only has a single property, the location of the file to write to. // When getting and setting properties later on, you will reference them by their index in // this list. -var properties = []*gst.ParameterSpec{ - gst.NewStringParameter( +var properties = []*gst.ParamSpec{ + gst.NewStringParam( "location", // The name of the parameter "File Location", // The long name for the parameter "Location to write the file to", // A blurb about the parameter diff --git a/examples/plugins/filesrc/filesrc.go b/examples/plugins/gofilesrc/filesrc.go similarity index 99% rename from examples/plugins/filesrc/filesrc.go rename to examples/plugins/gofilesrc/filesrc.go index 0dbe629..df3883b 100644 --- a/examples/plugins/filesrc/filesrc.go +++ b/examples/plugins/gofilesrc/filesrc.go @@ -59,8 +59,8 @@ var CAT = gst.NewDebugCategory( // This element only has a single property, the location of the file to read from. // When getting and setting properties later on, you will reference them by their index in // this list. -var properties = []*gst.ParameterSpec{ - gst.NewStringParameter( +var properties = []*gst.ParamSpec{ + gst.NewStringParam( "location", // The name of the parameter "File Location", // The long name for the parameter "Location of the file to read from", // A blurb about the parameter diff --git a/examples/plugins/websocketsrc/websocketsrc.go b/examples/plugins/websocketsrc/websocketsrc.go new file mode 100644 index 0000000..cf4ffee --- /dev/null +++ b/examples/plugins/websocketsrc/websocketsrc.go @@ -0,0 +1,191 @@ +// This is a GStreamer element implemented in Go that uses inbound data on a websocket +// connection as the source for the stream. +// +// In order to build the plugin for use by GStreamer, you can do the following: +// +// $ go generate +// $ go build -o libgstgofilesrc.so -buildmode c-shared . +// +// +//go:generate gst-plugin-gen +// +// +plugin:Name=websocketsrc +// +plugin:Description=GStreamer Websocket Source +// +plugin:Version=v0.0.1 +// +plugin:License=gst.LicenseLGPL +// +plugin:Source=go-gst +// +plugin:Package=examples +// +plugin:Origin=https://github.com/tinyzimmer/go-gst +// +plugin:ReleaseDate=2021-01-10 +// +// +element:Name=websocketsrc +// +element:Rank=gst.RankNone +// +element:Impl=websocketSrc +// +element:Subclass=gst.ExtendsElement +package main + +import ( + "fmt" + "net/http" + + "github.com/tinyzimmer/go-glib/glib" + "github.com/tinyzimmer/go-gst/gst" +) + +// Defaults // +var ( + DefaultAddress string = "0.0.0.0" + DefaultPort int = 5000 + DefaultRetrieveRemoteAddr bool = true +) + +func main() {} + +// CAT is the log category for the websocketsrc. +var CAT = gst.NewDebugCategory( + "websocketsrc", + gst.DebugColorNone, + "WebsocketSrc Element", +) + +var properties = []*gst.ParamSpec{ + gst.NewStringParam( + "address", + "Server Address", + "The address to bind the server to", + &DefaultAddress, + gst.ParameterReadWrite, + ), + gst.NewIntParam( + "port", + "Server Port", + "The port to bind the server to", + 1024, 65535, + DefaultPort, + gst.ParameterReadWrite, + ), + gst.NewBoolParam( + "retrieve-remote-addr", + "Retrieve Remote Address", + "Include the remote client's address in the buffer metadata", + DefaultRetrieveRemoteAddr, + gst.ParameterReadWrite, + ), +} + +// Internals // + +type state struct { + started bool + server *http.Server + needInitialEvents bool + needSegment bool +} + +type settings struct { + address string + port int + retrieveRemoteAddr bool +} + +func defaultSettings() *settings { + return &settings{ + address: DefaultAddress, + port: DefaultPort, + retrieveRemoteAddr: DefaultRetrieveRemoteAddr, + } +} + +// Element implementation // + +type websocketSrc struct { + settings *settings + state *state + srcpad *gst.Pad +} + +// // ObjectSubclass // // + +func (w *websocketSrc) New() gst.GoElement { + return &websocketSrc{ + settings: defaultSettings(), + state: &state{}, + } +} + +func (w *websocketSrc) TypeInit(instance *gst.TypeInstance) {} + +func (w *websocketSrc) ClassInit(klass *gst.ElementClass) { + klass.SetMetadata( + "Websocket Src", + "Src/Websocket", + "Write stream from a connection over a websocket server", + "Avi Zimmerman ", + ) + klass.AddPadTemplate(gst.NewPadTemplate( + "src", + gst.PadDirectionSource, + gst.PadPresenceAlways, + gst.NewAnyCaps(), + )) + klass.InstallProperties(properties) +} + +// // Object // // +func (w *websocketSrc) SetProperty(self *gst.Object, id uint, value *glib.Value) {} + +func (w *websocketSrc) GetProperty(self *gst.Object, id uint) *glib.Value { return nil } + +func (w *websocketSrc) Constructed(self *gst.Object) { + w.srcpad = gst.ToElement(self).GetStaticPad("src") + + w.srcpad.SetEventFunction(func(pad *gst.Pad, parent *gst.Object, event *gst.Event) bool { + var ret bool + + self.Log(CAT, gst.LevelLog, fmt.Sprintf("Handling event: %s", event.Type())) + + switch event.Type() { + case gst.EventTypeFlushStart: + // TODO + case gst.EventTypeFlushStop: + // TODO + case gst.EventTypeReconfigure: + ret = true + case gst.EventTypeLatency: + ret = true + default: + ret = false + } + + if ret { + self.Log(CAT, gst.LevelLog, fmt.Sprintf("Handled event: %s", event.Type())) + } else { + self.Log(CAT, gst.LevelLog, fmt.Sprintf("Didn't handle event: %s", event.Type())) + } + + return ret + }) + + w.srcpad.SetQueryFunction(func(pad *gst.Pad, parent *gst.Object, query *gst.Query) bool { + var ret bool + + self.Log(CAT, gst.LevelLog, fmt.Sprintf("Handling query: %s", query.Type())) + + switch query.Type() { + case gst.QueryLatency: + query.SetLatency(true, 0, gst.ClockTimeNone) + ret = true + case gst.QueryScheduling: + query.SetScheduling(gst.SchedulingFlagSequential, 1, -1, 0) + query.AddSchedulingMode(gst.PadModePush) + ret = true + case gst.QueryCaps: + query.SetCapsResult(query.ParseCaps()) + ret = true + default: + ret = false + } + + return ret + }) +} diff --git a/go.mod b/go.mod index ca91355..0389c28 100644 --- a/go.mod +++ b/go.mod @@ -4,5 +4,5 @@ go 1.15 require ( github.com/mattn/go-pointer v0.0.1 - github.com/tinyzimmer/go-glib v0.0.2 + github.com/tinyzimmer/go-glib v0.0.3 ) diff --git a/go.sum b/go.sum index 81c9865..e891af5 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,4 @@ github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= -github.com/tinyzimmer/go-glib v0.0.2 h1:hdvjwrhcS6WrMMeqfxsf3e7/lOhV8gbVyJ9/sN3LfyY= -github.com/tinyzimmer/go-glib v0.0.2/go.mod h1:D5rd0CvYn1p7TBhwlwnBXHSr4d8lwEY9JImPQ66S+Bs= +github.com/tinyzimmer/go-glib v0.0.3 h1:yPax+QpAcmm16Ye3RZOsBVR0UpMZ9JnglJCgrlBN+C8= +github.com/tinyzimmer/go-glib v0.0.3/go.mod h1:D5rd0CvYn1p7TBhwlwnBXHSr4d8lwEY9JImPQ66S+Bs= diff --git a/gst/cgo_exports.go b/gst/cgo_exports.go index a790009..51a85fa 100644 --- a/gst/cgo_exports.go +++ b/gst/cgo_exports.go @@ -4,6 +4,7 @@ package gst // there will be double linkage issues. /* +#include #include */ import "C" @@ -273,7 +274,7 @@ func goInstanceInit(obj *C.GTypeInstance, klass C.gpointer) { ptr := gopointer.Save(elem) private := C.g_type_instance_get_private(obj, registeredTypes[reflect.TypeOf(registeredClasses[klass]).String()]) - C.memcpy(unsafe.Pointer(private), unsafe.Pointer(&ptr), C.gulong(unsafe.Sizeof(uintptr(0)))) + C.memcpy(unsafe.Pointer(private), unsafe.Pointer(&ptr), C.gsize(unsafe.Sizeof(uintptr(0)))) } //export goURIHdlrGetURIType diff --git a/gst/constants.go b/gst/constants.go index bd6fbc2..917086e 100644 --- a/gst/constants.go +++ b/gst/constants.go @@ -848,6 +848,8 @@ const ( QueryBitrate QueryType = C.GST_QUERY_BITRATE // (51202) – the bitrate query (since 1.16) ) +func (q QueryType) String() string { return C.GoString(C.gst_query_type_get_name(C.GstQueryType(q))) } + // QueryTypeFlags casts GstQueryTypeFlags type QueryTypeFlags int diff --git a/gst/g_object_class.go b/gst/g_object_class.go index b497c9d..f65e6cd 100644 --- a/gst/g_object_class.go +++ b/gst/g_object_class.go @@ -39,7 +39,7 @@ func (o *ObjectClass) Instance() *C.GObjectClass { return o.ptr } // InstallProperties will install the given ParameterSpecs to the object class. // They will be IDed in the order they are provided. -func (o *ObjectClass) InstallProperties(params []*ParameterSpec) { +func (o *ObjectClass) InstallProperties(params []*ParamSpec) { for idx, prop := range params { C.g_object_class_install_property( o.Instance(), diff --git a/gst/g_parameter_spec.go b/gst/g_param_spec.go similarity index 78% rename from gst/g_parameter_spec.go rename to gst/g_param_spec.go index 2c67ea4..88496c6 100644 --- a/gst/g_parameter_spec.go +++ b/gst/g_param_spec.go @@ -10,112 +10,96 @@ import ( "github.com/tinyzimmer/go-glib/glib" ) -// ParameterSpec is a go representation of a C GParamSpec -type ParameterSpec struct{ paramSpec *C.GParamSpec } - -// NewStringParameter returns a new ParameterSpec that will hold a string value. -func NewStringParameter(name, nick, blurb string, defaultValue *string, flags ParameterFlags) *ParameterSpec { - var cdefault *C.gchar - if defaultValue != nil { - cdefault = C.CString(*defaultValue) - } - paramSpec := C.g_param_spec_string( - (*C.gchar)(C.CString(name)), - (*C.gchar)(C.CString(nick)), - (*C.gchar)(C.CString(blurb)), - (*C.gchar)(cdefault), - C.GParamFlags(flags), - ) - return &ParameterSpec{paramSpec: paramSpec} -} +// ParamSpec is a go representation of a C GParamSpec +type ParamSpec struct{ paramSpec *C.GParamSpec } // Name returns the name of this parameter. -func (p *ParameterSpec) Name() string { +func (p *ParamSpec) Name() string { return C.GoString(C.g_param_spec_get_name(p.paramSpec)) } // Blurb returns the blurb for this parameter. -func (p *ParameterSpec) Blurb() string { +func (p *ParamSpec) Blurb() string { return C.GoString(C.g_param_spec_get_blurb(p.paramSpec)) } // Flags returns the flags for this parameter. -func (p *ParameterSpec) Flags() ParameterFlags { +func (p *ParamSpec) Flags() ParameterFlags { return ParameterFlags(p.paramSpec.flags) } // ValueType returns the GType for the value inside this parameter. -func (p *ParameterSpec) ValueType() glib.Type { +func (p *ParamSpec) ValueType() glib.Type { return glib.Type(p.paramSpec.value_type) } // OwnerType returns the Gtype for the owner of this parameter. -func (p *ParameterSpec) OwnerType() glib.Type { +func (p *ParamSpec) OwnerType() glib.Type { return glib.Type(p.paramSpec.owner_type) } // Unref the underlying paramater spec. -func (p *ParameterSpec) Unref() { C.g_param_spec_unref(p.paramSpec) } +func (p *ParamSpec) Unref() { C.g_param_spec_unref(p.paramSpec) } // UIntRange returns the range of the Uint stored in this parameter spec. -func (p *ParameterSpec) UIntRange() (uint, uint) { +func (p *ParamSpec) UIntRange() (uint, uint) { paramUint := C.getParamUInt(p.paramSpec) return uint(paramUint.minimum), uint(paramUint.maximum) } // IntRange returns the range of the Int stored in this parameter spec. -func (p *ParameterSpec) IntRange() (int, int) { +func (p *ParamSpec) IntRange() (int, int) { paramUint := C.getParamInt(p.paramSpec) return int(paramUint.minimum), int(paramUint.maximum) } // UInt64Range returns the range of the Uint64 stored in this parameter spec. -func (p *ParameterSpec) UInt64Range() (uint64, uint64) { +func (p *ParamSpec) UInt64Range() (uint64, uint64) { paramUint := C.getParamUInt64(p.paramSpec) return uint64(paramUint.minimum), uint64(paramUint.maximum) } // Int64Range returns the range of the Int64 stored in this parameter spec. -func (p *ParameterSpec) Int64Range() (int64, int64) { +func (p *ParamSpec) Int64Range() (int64, int64) { paramUint := C.getParamInt64(p.paramSpec) return int64(paramUint.minimum), int64(paramUint.maximum) } // FloatRange returns the range of the Float stored in this parameter spec. -func (p *ParameterSpec) FloatRange() (float64, float64) { +func (p *ParamSpec) FloatRange() (float64, float64) { paramUint := C.getParamFloat(p.paramSpec) return float64(paramUint.minimum), float64(paramUint.maximum) } // DoubleRange returns the range of the Double stored in this parameter spec. -func (p *ParameterSpec) DoubleRange() (float64, float64) { +func (p *ParamSpec) DoubleRange() (float64, float64) { paramUint := C.getParamDouble(p.paramSpec) return float64(paramUint.minimum), float64(paramUint.maximum) } // IsCaps returns true if this parameter contains a caps object. -func (p *ParameterSpec) IsCaps() bool { return gobool(C.isParamSpecTypeCaps(p.paramSpec)) } +func (p *ParamSpec) IsCaps() bool { return gobool(C.isParamSpecTypeCaps(p.paramSpec)) } // IsEnum returns true if this parameter contains an enum. -func (p *ParameterSpec) IsEnum() bool { return gobool(C.isParamSpecEnum(p.paramSpec)) } +func (p *ParamSpec) IsEnum() bool { return gobool(C.isParamSpecEnum(p.paramSpec)) } // IsFlags returns true if this paramater contains flags. -func (p *ParameterSpec) IsFlags() bool { return gobool(C.isParamSpecFlags(p.paramSpec)) } +func (p *ParamSpec) IsFlags() bool { return gobool(C.isParamSpecFlags(p.paramSpec)) } // IsObject returns true if this parameter contains an object. -func (p *ParameterSpec) IsObject() bool { return gobool(C.isParamSpecObject(p.paramSpec)) } +func (p *ParamSpec) IsObject() bool { return gobool(C.isParamSpecObject(p.paramSpec)) } // IsBoxed returns true if this parameter contains a boxed object. -func (p *ParameterSpec) IsBoxed() bool { return gobool(C.isParamSpecBoxed(p.paramSpec)) } +func (p *ParamSpec) IsBoxed() bool { return gobool(C.isParamSpecBoxed(p.paramSpec)) } // IsPointer returns true if this paramater contains a pointer. -func (p *ParameterSpec) IsPointer() bool { return gobool(C.isParamSpecPointer(p.paramSpec)) } +func (p *ParamSpec) IsPointer() bool { return gobool(C.isParamSpecPointer(p.paramSpec)) } // IsFraction returns true if this parameter contains a fraction. -func (p *ParameterSpec) IsFraction() bool { return gobool(C.isParamSpecFraction(p.paramSpec)) } +func (p *ParamSpec) IsFraction() bool { return gobool(C.isParamSpecFraction(p.paramSpec)) } // IsGstArray returns true if this parameter contains a Gst array. -func (p *ParameterSpec) IsGstArray() bool { return gobool(C.isParamSpecGstArray(p.paramSpec)) } +func (p *ParamSpec) IsGstArray() bool { return gobool(C.isParamSpecGstArray(p.paramSpec)) } // EnumValue is a go representation of a GEnumValue type EnumValue struct { @@ -124,7 +108,7 @@ type EnumValue struct { } // GetEnumValues returns the possible enum values for this parameter. -func (p *ParameterSpec) GetEnumValues() []*EnumValue { +func (p *ParamSpec) GetEnumValues() []*EnumValue { var gsize C.guint gEnumValues := C.getEnumValues(p.paramSpec, &gsize) size := int(gsize) @@ -146,7 +130,7 @@ type FlagsValue struct { } // GetFlagValues returns the possible flags for this parameter. -func (p *ParameterSpec) GetFlagValues() []*FlagsValue { +func (p *ParamSpec) GetFlagValues() []*FlagsValue { var gSize C.guint gFlags := C.getParamSpecFlags(p.paramSpec, &gSize) size := int(gSize) diff --git a/gst/g_param_spec_constructors.go b/gst/g_param_spec_constructors.go new file mode 100644 index 0000000..0c05645 --- /dev/null +++ b/gst/g_param_spec_constructors.go @@ -0,0 +1,134 @@ +package gst + +// #include "gst.go.h" +import "C" + +import "github.com/tinyzimmer/go-glib/glib" + +// NewStringParam returns a new ParamSpec that will hold a string value. +func NewStringParam(name, nick, blurb string, defaultValue *string, flags ParameterFlags) *ParamSpec { + var cdefault *C.gchar + if defaultValue != nil { + cdefault = C.CString(*defaultValue) + } + paramSpec := C.g_param_spec_string( + (*C.gchar)(C.CString(name)), + (*C.gchar)(C.CString(nick)), + (*C.gchar)(C.CString(blurb)), + (*C.gchar)(cdefault), + C.GParamFlags(flags), + ) + return &ParamSpec{paramSpec: paramSpec} +} + +// NewBoolParam creates a new ParamSpec that will hold a boolean value. +func NewBoolParam(name, nick, blurb string, defaultValue bool, flags ParameterFlags) *ParamSpec { + paramSpec := C.g_param_spec_boolean( + (*C.gchar)(C.CString(name)), + (*C.gchar)(C.CString(nick)), + (*C.gchar)(C.CString(blurb)), + gboolean(defaultValue), + C.GParamFlags(flags), + ) + return &ParamSpec{paramSpec: paramSpec} +} + +// NewIntParam creates a new ParamSpec that will hold a signed integer value. +func NewIntParam(name, nick, blurb string, min, max, defaultValue int, flags ParameterFlags) *ParamSpec { + paramSpec := C.g_param_spec_int( + (*C.gchar)(C.CString(name)), + (*C.gchar)(C.CString(nick)), + (*C.gchar)(C.CString(blurb)), + C.gint(min), + C.gint(max), + C.gint(defaultValue), + C.GParamFlags(flags), + ) + return &ParamSpec{paramSpec: paramSpec} +} + +// NewUintParam creates a new ParamSpec that will hold an unsigned integer value. +func NewUintParam(name, nick, blurb string, min, max, defaultValue uint, flags ParameterFlags) *ParamSpec { + paramSpec := C.g_param_spec_uint( + (*C.gchar)(C.CString(name)), + (*C.gchar)(C.CString(nick)), + (*C.gchar)(C.CString(blurb)), + C.guint(min), + C.guint(max), + C.guint(defaultValue), + C.GParamFlags(flags), + ) + return &ParamSpec{paramSpec: paramSpec} +} + +// NewInt64Param creates a new ParamSpec that will hold a signed 64-bit integer value. +func NewInt64Param(name, nick, blurb string, min, max, defaultValue int64, flags ParameterFlags) *ParamSpec { + paramSpec := C.g_param_spec_int64( + (*C.gchar)(C.CString(name)), + (*C.gchar)(C.CString(nick)), + (*C.gchar)(C.CString(blurb)), + C.gint64(min), + C.gint64(max), + C.gint64(defaultValue), + C.GParamFlags(flags), + ) + return &ParamSpec{paramSpec: paramSpec} +} + +// NewUint64Param creates a new ParamSpec that will hold an unsigned 64-bit integer value. +func NewUint64Param(name, nick, blurb string, min, max, defaultValue uint64, flags ParameterFlags) *ParamSpec { + paramSpec := C.g_param_spec_uint64( + (*C.gchar)(C.CString(name)), + (*C.gchar)(C.CString(nick)), + (*C.gchar)(C.CString(blurb)), + C.guint64(min), + C.guint64(max), + C.guint64(defaultValue), + C.GParamFlags(flags), + ) + return &ParamSpec{paramSpec: paramSpec} +} + +// NewFloat32Param creates a new ParamSpec that will hold a 32-bit float value. +func NewFloat32Param(name, nick, blurb string, min, max, defaultValue float32, flags ParameterFlags) *ParamSpec { + paramSpec := C.g_param_spec_float( + (*C.gchar)(C.CString(name)), + (*C.gchar)(C.CString(nick)), + (*C.gchar)(C.CString(blurb)), + C.gfloat(min), + C.gfloat(max), + C.gfloat(defaultValue), + C.GParamFlags(flags), + ) + return &ParamSpec{paramSpec: paramSpec} +} + +// NewFloat64Param creates a new ParamSpec that will hold a 64-bit float value. +func NewFloat64Param(name, nick, blurb string, min, max, defaultValue float64, flags ParameterFlags) *ParamSpec { + paramSpec := C.g_param_spec_double( + (*C.gchar)(C.CString(name)), + (*C.gchar)(C.CString(nick)), + (*C.gchar)(C.CString(blurb)), + C.gdouble(min), + C.gdouble(max), + C.gdouble(defaultValue), + C.GParamFlags(flags), + ) + return &ParamSpec{paramSpec: paramSpec} +} + +// TypeCaps is the static Glib Type for a GstCaps. +var TypeCaps = glib.Type(C.gst_caps_get_type()) + +// NewBoxedParam creates a new ParamSpec containing a boxed type. Some helper type castings are included +// in these bindings. +func NewBoxedParam(name, nick, blurb string, boxedType glib.Type, flags ParameterFlags) *ParamSpec { + paramSpec := C.g_param_spec_boxed( + (*C.gchar)(C.CString(name)), + (*C.gchar)(C.CString(nick)), + (*C.gchar)(C.CString(blurb)), + C.GType(boxedType), + C.GParamFlags(flags), + ) + return &ParamSpec{paramSpec: paramSpec} +} diff --git a/gst/gst_object.go b/gst/gst_object.go index 565ba23..8f9f833 100644 --- a/gst/gst_object.go +++ b/gst/gst_object.go @@ -66,17 +66,17 @@ func (o *Object) Interfaces() []string { // set in this object, or their defaults. // // Unref after usage. -func (o *Object) ListProperties() []*ParameterSpec { +func (o *Object) ListProperties() []*ParamSpec { var size C.guint props := C.g_object_class_list_properties((*C.GObjectClass)(o.Class()), &size) if props == nil { return nil } defer C.g_free((C.gpointer)(props)) - out := make([]*ParameterSpec, 0) + out := make([]*ParamSpec, 0) for _, prop := range (*[1 << 30]*C.GParamSpec)(unsafe.Pointer(props))[:size:size] { C.g_param_spec_sink(prop) // steal the ref on the property - out = append(out, &ParameterSpec{ + out = append(out, &ParamSpec{ paramSpec: prop, }) } diff --git a/gst/gst_pad.go b/gst/gst_pad.go index 5053517..0d9f710 100644 --- a/gst/gst_pad.go +++ b/gst/gst_pad.go @@ -752,7 +752,7 @@ func (p *Pad) QueryPosition(format Format) (bool, int64) { // RemoveProbe removes the probe with id from pad. func (p *Pad) RemoveProbe(id uint64) { - C.gst_pad_remove_probe(p.Instance(), C.gulong(id)) + C.gst_pad_remove_probe(p.Instance(), C.guint64(id)) } // SendEvent sends the event to the pad. This function can be used by applications to send events in the pipeline. diff --git a/gst/gst_query.go b/gst/gst_query.go index e12123c..d2c784e 100644 --- a/gst/gst_query.go +++ b/gst/gst_query.go @@ -14,6 +14,9 @@ type Query struct { ptr *C.GstQuery } +// Type returns the type of the Query. +func (q *Query) Type() QueryType { return QueryType(q.ptr._type) } + // FromGstQueryUnsafe wraps the pointer to the given C GstQuery with the go type. // This is meant for internal usage and is exported for visibility to other packages. func FromGstQueryUnsafe(query unsafe.Pointer) *Query { return wrapQuery((*C.GstQuery)(query)) } diff --git a/gst/interfaces.go b/gst/interfaces.go index 5ab5315..ea2d2f5 100644 --- a/gst/interfaces.go +++ b/gst/interfaces.go @@ -15,8 +15,8 @@ import ( "reflect" "unsafe" - "github.com/tinyzimmer/go-glib/glib" gopointer "github.com/mattn/go-pointer" + "github.com/tinyzimmer/go-glib/glib" ) // GoElement is an interface to be implemented by GStreamer elements built using the @@ -76,22 +76,25 @@ func gtypeForGoElement(name string, elem GoElement, extendable Extendable) C.GTy ext: extendable, } ptr := gopointer.Save(classData) - typeInfo := C.GTypeInfo{ - class_size: C.gushort(extendable.ClassSize()), - base_init: nil, - base_finalize: nil, - class_init: C.GClassInitFunc(C.cgoClassInit), - class_finalize: nil, - class_data: (C.gconstpointer)(ptr), - instance_size: C.gushort(extendable.InstanceSize()), - n_preallocs: 0, - instance_init: C.GInstanceInitFunc(C.cgoInstanceInit), - value_table: nil, - } + + typeInfo := (*C.GTypeInfo)(C.malloc(C.sizeof_GTypeInfo)) + defer C.free(unsafe.Pointer(typeInfo)) + + typeInfo.base_init = nil + typeInfo.base_finalize = nil + typeInfo.class_size = C.gushort(extendable.ClassSize()) + typeInfo.class_finalize = nil + typeInfo.class_init = C.GClassInitFunc(C.cgoClassInit) + typeInfo.class_data = (C.gconstpointer)(ptr) + typeInfo.instance_size = C.gushort(extendable.InstanceSize()) + typeInfo.n_preallocs = 0 + typeInfo.instance_init = C.GInstanceInitFunc(C.cgoInstanceInit) + typeInfo.value_table = nil + gtype := C.g_type_register_static( C.GType(extendable.Type()), (*C.gchar)(C.CString(name)), - &typeInfo, + typeInfo, C.GTypeFlags(0), ) elem.TypeInit(&TypeInstance{gtype: gtype, gotype: elem})