mirror of
https://github.com/go-gst/go-gst.git
synced 2025-10-05 07:56:51 +08:00
pull in upstream interface improvements and add a few more gstreamer interfaces
This commit is contained in:
@@ -36,6 +36,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/tinyzimmer/go-glib/glib"
|
||||||
"github.com/tinyzimmer/go-gst/gst"
|
"github.com/tinyzimmer/go-gst/gst"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -51,7 +52,7 @@ func main() {
|
|||||||
|
|
||||||
// Create a main loop. This is only required when utilizing signals via the bindings.
|
// Create a main loop. This is only required when utilizing signals via the bindings.
|
||||||
// In this example, the AddWatch on the pipeline bus requires iterating on the main loop.
|
// In this example, the AddWatch on the pipeline bus requires iterating on the main loop.
|
||||||
mainLoop := gst.NewMainLoop(gst.DefaultMainContext(), false)
|
mainLoop := glib.NewMainLoop(glib.MainContextDefault(), false)
|
||||||
defer mainLoop.Unref()
|
defer mainLoop.Unref()
|
||||||
|
|
||||||
// Build a pipeline string from the cli arguments
|
// Build a pipeline string from the cli arguments
|
||||||
|
@@ -47,7 +47,7 @@ type pluginConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type elementConfig struct {
|
type elementConfig struct {
|
||||||
Name, Rank, Impl, Subclass string
|
Name, Rank, Impl, Subclass, Interfaces string
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildCfgFromDir(dir string) *libraryConfig {
|
func buildCfgFromDir(dir string) *libraryConfig {
|
||||||
@@ -119,6 +119,9 @@ var pluginTmpl = template.Must(template.New("").Funcs(template.FuncMap{
|
|||||||
"adjustedName": func(name string) string {
|
"adjustedName": func(name string) string {
|
||||||
return strings.ToLower(strings.Replace(name, "-", "_", -1))
|
return strings.ToLower(strings.Replace(name, "-", "_", -1))
|
||||||
},
|
},
|
||||||
|
"splitInterfaces": func(ifacesString string) []string {
|
||||||
|
return strings.Split(ifacesString, ",")
|
||||||
|
},
|
||||||
"extendsFromBase": func(subclass string) bool {
|
"extendsFromBase": func(subclass string) bool {
|
||||||
if strings.HasPrefix(subclass, "base.") {
|
if strings.HasPrefix(subclass, "base.") {
|
||||||
return true
|
return true
|
||||||
@@ -163,6 +166,12 @@ var pluginMeta = &gst.PluginMetadata{
|
|||||||
&{{ .Config.Element.Impl }}{},
|
&{{ .Config.Element.Impl }}{},
|
||||||
// The base subclass this element extends
|
// The base subclass this element extends
|
||||||
{{ .Config.Element.Subclass }},
|
{{ .Config.Element.Subclass }},
|
||||||
|
{{- if .Config.Element.Interfaces }}
|
||||||
|
// The interfaces this element implements
|
||||||
|
{{- range $index, $interface := .Config.Element.Interfaces | splitInterfaces }}
|
||||||
|
{{ $interface }},
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@@ -60,7 +60,7 @@ func playbin(mainLoop *glib.MainLoop) error {
|
|||||||
// Watch state change events
|
// Watch state change events
|
||||||
case gst.MessageStateChanged:
|
case gst.MessageStateChanged:
|
||||||
if _, newState := msg.ParseStateChanged(); newState == gst.StatePlaying {
|
if _, newState := msg.ParseStateChanged(); newState == gst.StatePlaying {
|
||||||
bin := gst.BinFromElement(playbin)
|
bin := gst.ToGstBin(playbin)
|
||||||
// Generate a dot graph of the pipeline to GST_DEBUG_DUMP_DOT_DIR if defined
|
// Generate a dot graph of the pipeline to GST_DEBUG_DUMP_DOT_DIR if defined
|
||||||
bin.DebugBinToDotFile(gst.DebugGraphShowAll, "PLAYING")
|
bin.DebugBinToDotFile(gst.DebugGraphShowAll, "PLAYING")
|
||||||
}
|
}
|
||||||
|
27
examples/plugins/boilerplate/boilerplate.go
Normal file
27
examples/plugins/boilerplate/boilerplate.go
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
//go:generate gst-plugin-gen
|
||||||
|
//
|
||||||
|
// +plugin:Name=boilerplate
|
||||||
|
// +plugin:Description=My plugin written in go
|
||||||
|
// +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-18
|
||||||
|
//
|
||||||
|
// +element:Name=myelement
|
||||||
|
// +element:Rank=gst.RankNone
|
||||||
|
// +element:Impl=myelement
|
||||||
|
// +element:Subclass=gst.ExtendsElement
|
||||||
|
//
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "github.com/tinyzimmer/go-glib/glib"
|
||||||
|
|
||||||
|
func main() {}
|
||||||
|
|
||||||
|
type myelement struct{}
|
||||||
|
|
||||||
|
func (g *myelement) New() glib.GoObjectSubclass { return &myelement{} }
|
||||||
|
|
||||||
|
func (g *myelement) ClassInit(klass *glib.ObjectClass) {}
|
27
examples/plugins/gobin/gobin.go
Normal file
27
examples/plugins/gobin/gobin.go
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
//go:generate gst-plugin-gen
|
||||||
|
//
|
||||||
|
// +plugin:Name=gobin
|
||||||
|
// +plugin:Description=A bin element written in go
|
||||||
|
// +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-18
|
||||||
|
//
|
||||||
|
// +element:Name=gobin
|
||||||
|
// +element:Rank=gst.RankNone
|
||||||
|
// +element:Impl=gobin
|
||||||
|
// +element:Subclass=gst.ExtendsBin
|
||||||
|
//
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "github.com/tinyzimmer/go-glib/glib"
|
||||||
|
|
||||||
|
func main() {}
|
||||||
|
|
||||||
|
type gobin struct{}
|
||||||
|
|
||||||
|
func (g *gobin) New() glib.GoObjectSubclass { return &gobin{} }
|
||||||
|
|
||||||
|
func (g *gobin) ClassInit(klass *glib.ObjectClass) {}
|
@@ -29,6 +29,8 @@
|
|||||||
// +element:Rank=gst.RankNone
|
// +element:Rank=gst.RankNone
|
||||||
// +element:Impl=fileSink
|
// +element:Impl=fileSink
|
||||||
// +element:Subclass=base.ExtendsBaseSink
|
// +element:Subclass=base.ExtendsBaseSink
|
||||||
|
// +element:Interfaces=gst.InterfaceURIHandler
|
||||||
|
//
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -119,13 +121,6 @@ func (f *fileSink) New() glib.GoObjectSubclass {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The TypeInit method should register any additional interfaces provided by the element.
|
|
||||||
// In this example we signal to the type system that we also implement the GstURIHandler interface.
|
|
||||||
func (f *fileSink) TypeInit(instance *glib.TypeInstance) {
|
|
||||||
CAT.Log(gst.LevelLog, "Adding URIHandler interface to type")
|
|
||||||
instance.AddInterface(gst.InterfaceURIHandler)
|
|
||||||
}
|
|
||||||
|
|
||||||
// The ClassInit method should specify the metadata for this element and add any pad templates
|
// The ClassInit method should specify the metadata for this element and add any pad templates
|
||||||
// and properties.
|
// and properties.
|
||||||
func (f *fileSink) ClassInit(klass *glib.ObjectClass) {
|
func (f *fileSink) ClassInit(klass *glib.ObjectClass) {
|
||||||
|
@@ -29,6 +29,8 @@
|
|||||||
// +element:Rank=gst.RankNone
|
// +element:Rank=gst.RankNone
|
||||||
// +element:Impl=fileSrc
|
// +element:Impl=fileSrc
|
||||||
// +element:Subclass=base.ExtendsBaseSrc
|
// +element:Subclass=base.ExtendsBaseSrc
|
||||||
|
// +element:Interfaces=gst.InterfaceURIHandler
|
||||||
|
//
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -123,13 +125,6 @@ func (f *fileSrc) New() glib.GoObjectSubclass {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The TypeInit method should register any additional interfaces provided by the element.
|
|
||||||
// In this example we signal to the type system that we also implement the GstURIHandler interface.
|
|
||||||
func (f *fileSrc) TypeInit(instance *glib.TypeInstance) {
|
|
||||||
CAT.Log(gst.LevelLog, "Adding URIHandler interface to type")
|
|
||||||
instance.AddInterface(gst.InterfaceURIHandler)
|
|
||||||
}
|
|
||||||
|
|
||||||
// The ClassInit method should specify the metadata for this element and add any pad templates
|
// The ClassInit method should specify the metadata for this element and add any pad templates
|
||||||
// and properties.
|
// and properties.
|
||||||
func (f *fileSrc) ClassInit(klass *glib.ObjectClass) {
|
func (f *fileSrc) ClassInit(klass *glib.ObjectClass) {
|
||||||
|
2
go.mod
2
go.mod
@@ -4,5 +4,5 @@ go 1.15
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/mattn/go-pointer v0.0.1
|
github.com/mattn/go-pointer v0.0.1
|
||||||
github.com/tinyzimmer/go-glib v0.0.7
|
github.com/tinyzimmer/go-glib v0.0.11
|
||||||
)
|
)
|
||||||
|
4
go.sum
4
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 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0=
|
||||||
github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc=
|
github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc=
|
||||||
github.com/tinyzimmer/go-glib v0.0.7 h1:09SIbhaL+E+5U/4qbZXiM7f6HEDvcxOBuEiSCkT9FNw=
|
github.com/tinyzimmer/go-glib v0.0.11 h1:+X15JtyglmBhiLu5KXHWxcxhypyc/CEqW+SIFmjZ110=
|
||||||
github.com/tinyzimmer/go-glib v0.0.7/go.mod h1:zy2cs6eXSTtqqYrv9/UgYMDfr4pWKuYPSzwX87cBGX4=
|
github.com/tinyzimmer/go-glib v0.0.11/go.mod h1:zy2cs6eXSTtqqYrv9/UgYMDfr4pWKuYPSzwX87cBGX4=
|
||||||
|
@@ -19,12 +19,14 @@ inline GObjectClass * toGObjectClass (void *p) { return (G_
|
|||||||
|
|
||||||
inline GstAllocator * toGstAllocator (void *p) { return (GST_ALLOCATOR_CAST(p)); }
|
inline GstAllocator * toGstAllocator (void *p) { return (GST_ALLOCATOR_CAST(p)); }
|
||||||
inline GstBin * toGstBin (void *p) { return (GST_BIN(p)); }
|
inline GstBin * toGstBin (void *p) { return (GST_BIN(p)); }
|
||||||
|
inline GstBinClass * toGstBinClass (void *p) { return (GST_BIN_CLASS(p)); }
|
||||||
inline GstBufferList * toGstBufferList (void *p) { return (GST_BUFFER_LIST(p)); }
|
inline GstBufferList * toGstBufferList (void *p) { return (GST_BUFFER_LIST(p)); }
|
||||||
inline GstBufferPool * toGstBufferPool (void *p) { return (GST_BUFFER_POOL(p)); }
|
inline GstBufferPool * toGstBufferPool (void *p) { return (GST_BUFFER_POOL(p)); }
|
||||||
inline GstBuffer * toGstBuffer (void *p) { return (GST_BUFFER(p)); }
|
inline GstBuffer * toGstBuffer (void *p) { return (GST_BUFFER(p)); }
|
||||||
inline GstBus * toGstBus (void *p) { return (GST_BUS(p)); }
|
inline GstBus * toGstBus (void *p) { return (GST_BUS(p)); }
|
||||||
inline GstCapsFeatures * toGstCapsFeatures (void *p) { return (GST_CAPS_FEATURES(p)); }
|
inline GstCapsFeatures * toGstCapsFeatures (void *p) { return (GST_CAPS_FEATURES(p)); }
|
||||||
inline GstCaps * toGstCaps (void *p) { return (GST_CAPS(p)); }
|
inline GstCaps * toGstCaps (void *p) { return (GST_CAPS(p)); }
|
||||||
|
inline GstChildProxy * toGstChildProxy (void *p) { return (GST_CHILD_PROXY(p)); }
|
||||||
inline GstClock * toGstClock (void *p) { return (GST_CLOCK(p)); }
|
inline GstClock * toGstClock (void *p) { return (GST_CLOCK(p)); }
|
||||||
inline GstContext * toGstContext (void *p) { return (GST_CONTEXT_CAST(p)); }
|
inline GstContext * toGstContext (void *p) { return (GST_CONTEXT_CAST(p)); }
|
||||||
inline GstDevice * toGstDevice (void *p) { return (GST_DEVICE_CAST(p)); }
|
inline GstDevice * toGstDevice (void *p) { return (GST_DEVICE_CAST(p)); }
|
||||||
|
141
gst/gst_bin.go
141
gst/gst_bin.go
@@ -1,6 +1,73 @@
|
|||||||
package gst
|
package gst
|
||||||
|
|
||||||
// #include "gst.go.h"
|
/*
|
||||||
|
#include "gst.go.h"
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
binParentAddElement (GstBin * bin, GstElement * element)
|
||||||
|
{
|
||||||
|
GObjectClass * this_class = G_OBJECT_GET_CLASS(G_OBJECT(bin));
|
||||||
|
GstBinClass * parent = toGstBinClass(g_type_class_peek_parent(this_class));
|
||||||
|
return parent->add_element(bin, element);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
binParentDeepElementAdded (GstBin * bin, GstBin * subbin, GstElement * element)
|
||||||
|
{
|
||||||
|
GObjectClass * this_class = G_OBJECT_GET_CLASS(G_OBJECT(bin));
|
||||||
|
GstBinClass * parent = toGstBinClass(g_type_class_peek_parent(this_class));
|
||||||
|
parent->deep_element_added(bin, subbin, element);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
binParentDeepElementRemoved (GstBin * bin, GstBin * subbin, GstElement * element)
|
||||||
|
{
|
||||||
|
GObjectClass * this_class = G_OBJECT_GET_CLASS(G_OBJECT(element));
|
||||||
|
GstBinClass * parent = toGstBinClass(g_type_class_peek_parent(this_class));
|
||||||
|
parent->deep_element_removed(bin, subbin, element);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
binParentDoLatency (GstBin * bin)
|
||||||
|
{
|
||||||
|
GObjectClass * this_class = G_OBJECT_GET_CLASS(G_OBJECT(bin));
|
||||||
|
GstBinClass * parent = toGstBinClass(g_type_class_peek_parent(this_class));
|
||||||
|
return parent->do_latency(bin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
binParentElementAdded (GstBin * bin, GstElement * element)
|
||||||
|
{
|
||||||
|
GObjectClass * this_class = G_OBJECT_GET_CLASS(G_OBJECT(bin));
|
||||||
|
GstBinClass * parent = toGstBinClass(g_type_class_peek_parent(this_class));
|
||||||
|
parent->element_added(bin, element);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
binParentElementRemoved (GstBin * bin, GstElement * element)
|
||||||
|
{
|
||||||
|
GObjectClass * this_class = G_OBJECT_GET_CLASS(G_OBJECT(bin));
|
||||||
|
GstBinClass * parent = toGstBinClass(g_type_class_peek_parent(this_class));
|
||||||
|
parent->element_removed(bin, element);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
binParentHandleMessage (GstBin * bin, GstMessage * message)
|
||||||
|
{
|
||||||
|
GObjectClass * this_class = G_OBJECT_GET_CLASS(G_OBJECT(bin));
|
||||||
|
GstBinClass * parent = toGstBinClass(g_type_class_peek_parent(this_class));
|
||||||
|
parent->handle_message(bin, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
binParentRemoveElement (GstBin * bin, GstElement * element)
|
||||||
|
{
|
||||||
|
GObjectClass * this_class = G_OBJECT_GET_CLASS(G_OBJECT(bin));
|
||||||
|
GstBinClass * parent = toGstBinClass(g_type_class_peek_parent(this_class));
|
||||||
|
return parent->remove_element(bin, element);
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -22,14 +89,18 @@ func NewBin(name string) *Bin {
|
|||||||
return wrapBin(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(bin))})
|
return wrapBin(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(bin))})
|
||||||
}
|
}
|
||||||
|
|
||||||
// BinFromElement wraps the given Element in a Bin reference. This only works for elements
|
// ToGstBin wraps the given glib.Object, gst.Object, or gst.Element in a Bin instance. Only
|
||||||
// that implement their own Bin, such as playbin. If the provided element does not implement
|
// works for objects that implement their own Bin.
|
||||||
// a Bin then nil is returned.
|
func ToGstBin(obj interface{}) *Bin {
|
||||||
func BinFromElement(elem *Element) *Bin {
|
switch obj := obj.(type) {
|
||||||
if C.toGstBin(elem.Unsafe()) == nil {
|
case *Object:
|
||||||
return nil
|
return &Bin{&Element{Object: obj}}
|
||||||
|
case *Element:
|
||||||
|
return &Bin{obj}
|
||||||
|
case *glib.Object:
|
||||||
|
return &Bin{&Element{Object: &Object{InitiallyUnowned: &glib.InitiallyUnowned{Object: obj}}}}
|
||||||
}
|
}
|
||||||
return &Bin{elem}
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Instance returns the underlying GstBin instance.
|
// Instance returns the underlying GstBin instance.
|
||||||
@@ -95,10 +166,10 @@ func (b *Bin) GetElementsSorted() ([]*Element, error) {
|
|||||||
// element is found, it returns the element. You can cast this element to the given interface afterwards.
|
// element is found, it returns the element. You can cast this element to the given interface afterwards.
|
||||||
// If you want all elements that implement the interface, use GetAllByInterface. This function recurses
|
// If you want all elements that implement the interface, use GetAllByInterface. This function recurses
|
||||||
// into child bins.
|
// into child bins.
|
||||||
func (b *Bin) GetByInterface(iface glib.Type) (*Element, error) {
|
func (b *Bin) GetByInterface(iface glib.Interface) (*Element, error) {
|
||||||
elem := C.gst_bin_get_by_interface(b.Instance(), C.GType(iface))
|
elem := C.gst_bin_get_by_interface(b.Instance(), C.GType(iface.Type()))
|
||||||
if elem == nil {
|
if elem == nil {
|
||||||
return nil, fmt.Errorf("Could not find any elements implementing %s", iface.Name())
|
return nil, fmt.Errorf("Could not find any elements implementing %s", iface.Type().Name())
|
||||||
}
|
}
|
||||||
return wrapElement(toGObject(unsafe.Pointer(elem))), nil
|
return wrapElement(toGObject(unsafe.Pointer(elem))), nil
|
||||||
}
|
}
|
||||||
@@ -106,8 +177,8 @@ func (b *Bin) GetByInterface(iface glib.Type) (*Element, error) {
|
|||||||
// GetAllByInterface looks for all elements inside the bin that implements the given interface. You can
|
// GetAllByInterface looks for all elements inside the bin that implements the given interface. You can
|
||||||
// safely cast all returned elements to the given interface. The function recurses inside child bins.
|
// safely cast all returned elements to the given interface. The function recurses inside child bins.
|
||||||
// The function will return a series of Elements that should be unreffed after use.
|
// The function will return a series of Elements that should be unreffed after use.
|
||||||
func (b *Bin) GetAllByInterface(iface glib.Type) ([]*Element, error) {
|
func (b *Bin) GetAllByInterface(iface glib.Interface) ([]*Element, error) {
|
||||||
iterator := C.gst_bin_iterate_all_by_interface(b.Instance(), C.GType(iface))
|
iterator := C.gst_bin_iterate_all_by_interface(b.Instance(), C.GType(iface.Type()))
|
||||||
return iteratorToElementSlice(iterator)
|
return iteratorToElementSlice(iterator)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,7 +194,7 @@ func (b *Bin) GetAllByInterface(iface glib.Type) ([]*Element, error) {
|
|||||||
// Add adds an element to the bin.
|
// Add adds an element to the bin.
|
||||||
func (b *Bin) Add(elem *Element) error {
|
func (b *Bin) Add(elem *Element) error {
|
||||||
if ok := C.gst_bin_add((*C.GstBin)(b.Instance()), (*C.GstElement)(elem.Instance())); !gobool(ok) {
|
if ok := C.gst_bin_add((*C.GstBin)(b.Instance()), (*C.GstElement)(elem.Instance())); !gobool(ok) {
|
||||||
return fmt.Errorf("Failed to add element to pipeline: %s", elem.Name())
|
return fmt.Errorf("Failed to add element to pipeline: %s", elem.GetName())
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -141,7 +212,7 @@ func (b *Bin) AddMany(elems ...*Element) error {
|
|||||||
// Remove removes an element from the Bin.
|
// Remove removes an element from the Bin.
|
||||||
func (b *Bin) Remove(elem *Element) error {
|
func (b *Bin) Remove(elem *Element) error {
|
||||||
if ok := C.gst_bin_remove((*C.GstBin)(b.Instance()), (*C.GstElement)(elem.Instance())); !gobool(ok) {
|
if ok := C.gst_bin_remove((*C.GstBin)(b.Instance()), (*C.GstElement)(elem.Instance())); !gobool(ok) {
|
||||||
return fmt.Errorf("Failed to add element to pipeline: %s", elem.Name())
|
return fmt.Errorf("Failed to add element to pipeline: %s", elem.GetName())
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -257,3 +328,43 @@ func iteratorToElementSlice(iterator *C.GstIterator) ([]*Element, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ParentAddElement chains up to the parent AddElement handler.
|
||||||
|
func (b *Bin) ParentAddElement(element *Element) bool {
|
||||||
|
return gobool(C.binParentAddElement(b.Instance(), element.Instance()))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParentDeepElementAdded chains up to the parent DeepElementAdded handler.
|
||||||
|
func (b *Bin) ParentDeepElementAdded(subbin *Bin, element *Element) {
|
||||||
|
C.binParentDeepElementAdded(b.Instance(), subbin.Instance(), element.Instance())
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParentDeepElementRemoved chains up to the parent DeepElementRemoved handler.
|
||||||
|
func (b *Bin) ParentDeepElementRemoved(subbin *Bin, element *Element) {
|
||||||
|
C.binParentDeepElementRemoved(b.Instance(), subbin.Instance(), element.Instance())
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParentDoLatency chains up to the parent DoLatency handler.
|
||||||
|
func (b *Bin) ParentDoLatency() bool {
|
||||||
|
return gobool(C.binParentDoLatency(b.Instance()))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParentElementAdded chains up to the parent ElementAdded handler.
|
||||||
|
func (b *Bin) ParentElementAdded(element *Element) {
|
||||||
|
C.binParentElementAdded(b.Instance(), element.Instance())
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParentElementRemoved chains up to the parent ElementRemoved handler.
|
||||||
|
func (b *Bin) ParentElementRemoved(element *Element) {
|
||||||
|
C.binParentElementRemoved(b.Instance(), element.Instance())
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParentHandleMessage chains up to the parent HandleMessage handler.
|
||||||
|
func (b *Bin) ParentHandleMessage(message *Message) {
|
||||||
|
C.binParentHandleMessage(b.Instance(), message.Instance())
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParentRemoveElement chains up to the parent RemoveElement handler.
|
||||||
|
func (b *Bin) ParentRemoveElement(element *Element) bool {
|
||||||
|
return gobool(C.binParentRemoveElement(b.Instance(), element.Instance()))
|
||||||
|
}
|
||||||
|
91
gst/gst_bin_exports.go
Normal file
91
gst/gst_bin_exports.go
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
package gst
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include "gst.go.h"
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/tinyzimmer/go-glib/glib"
|
||||||
|
)
|
||||||
|
|
||||||
|
func cbWrapBin(bin *C.GstBin) *Bin {
|
||||||
|
return wrapBin(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(bin))})
|
||||||
|
}
|
||||||
|
|
||||||
|
func cbWrapElement(elem *C.GstElement) *Element {
|
||||||
|
return wrapElement(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(elem))})
|
||||||
|
}
|
||||||
|
|
||||||
|
//export goGstBinAddElement
|
||||||
|
func goGstBinAddElement(bin *C.GstBin, element *C.GstElement) C.gboolean {
|
||||||
|
elem := glib.FromObjectUnsafePrivate(unsafe.Pointer(bin))
|
||||||
|
caller := elem.(interface {
|
||||||
|
AddElement(self *Bin, element *Element) bool
|
||||||
|
})
|
||||||
|
return gboolean(caller.AddElement(cbWrapBin(bin), cbWrapElement(element)))
|
||||||
|
}
|
||||||
|
|
||||||
|
//export goGstBinDeepElementAdded
|
||||||
|
func goGstBinDeepElementAdded(bin *C.GstBin, subbin *C.GstBin, child *C.GstElement) {
|
||||||
|
elem := glib.FromObjectUnsafePrivate(unsafe.Pointer(bin))
|
||||||
|
caller := elem.(interface {
|
||||||
|
DeepElementAdded(self *Bin, subbin *Bin, child *Element)
|
||||||
|
})
|
||||||
|
caller.DeepElementAdded(cbWrapBin(bin), cbWrapBin(subbin), cbWrapElement(child))
|
||||||
|
}
|
||||||
|
|
||||||
|
//export goGstBinDeepElementRemoved
|
||||||
|
func goGstBinDeepElementRemoved(bin *C.GstBin, subbin *C.GstBin, child *C.GstElement) {
|
||||||
|
elem := glib.FromObjectUnsafePrivate(unsafe.Pointer(bin))
|
||||||
|
caller := elem.(interface {
|
||||||
|
DeepElementRemoved(self *Bin, subbin *Bin, child *Element)
|
||||||
|
})
|
||||||
|
caller.DeepElementRemoved(cbWrapBin(bin), cbWrapBin(subbin), cbWrapElement(child))
|
||||||
|
}
|
||||||
|
|
||||||
|
//export goGstBinDoLatency
|
||||||
|
func goGstBinDoLatency(bin *C.GstBin) C.gboolean {
|
||||||
|
elem := glib.FromObjectUnsafePrivate(unsafe.Pointer(bin))
|
||||||
|
caller := elem.(interface {
|
||||||
|
DoLatency(self *Bin) bool
|
||||||
|
})
|
||||||
|
return gboolean(caller.DoLatency(cbWrapBin(bin)))
|
||||||
|
}
|
||||||
|
|
||||||
|
//export goGstBinElementAdded
|
||||||
|
func goGstBinElementAdded(bin *C.GstBin, child *C.GstElement) {
|
||||||
|
elem := glib.FromObjectUnsafePrivate(unsafe.Pointer(bin))
|
||||||
|
caller := elem.(interface {
|
||||||
|
ElementAdded(self *Bin, child *Element)
|
||||||
|
})
|
||||||
|
caller.ElementAdded(cbWrapBin(bin), cbWrapElement(child))
|
||||||
|
}
|
||||||
|
|
||||||
|
//export goGstBinElementRemoved
|
||||||
|
func goGstBinElementRemoved(bin *C.GstBin, child *C.GstElement) {
|
||||||
|
elem := glib.FromObjectUnsafePrivate(unsafe.Pointer(bin))
|
||||||
|
caller := elem.(interface {
|
||||||
|
ElementRemoved(self *Bin, child *Element)
|
||||||
|
})
|
||||||
|
caller.ElementRemoved(cbWrapBin(bin), cbWrapElement(child))
|
||||||
|
}
|
||||||
|
|
||||||
|
//export goGstBinHandleMessage
|
||||||
|
func goGstBinHandleMessage(bin *C.GstBin, message *C.GstMessage) {
|
||||||
|
elem := glib.FromObjectUnsafePrivate(unsafe.Pointer(bin))
|
||||||
|
caller := elem.(interface {
|
||||||
|
HandleMessage(self *Bin, msg *Message)
|
||||||
|
})
|
||||||
|
caller.HandleMessage(cbWrapBin(bin), wrapMessage(message))
|
||||||
|
}
|
||||||
|
|
||||||
|
//export goGstBinRemoveElement
|
||||||
|
func goGstBinRemoveElement(bin *C.GstBin, element *C.GstElement) C.gboolean {
|
||||||
|
elem := glib.FromObjectUnsafePrivate(unsafe.Pointer(bin))
|
||||||
|
caller := elem.(interface {
|
||||||
|
RemoveElement(self *Bin, element *Element) bool
|
||||||
|
})
|
||||||
|
return gboolean(caller.RemoveElement(cbWrapBin(bin), cbWrapElement(element)))
|
||||||
|
}
|
106
gst/gst_bin_impl.go
Normal file
106
gst/gst_bin_impl.go
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
package gst
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include "gst.go.h"
|
||||||
|
|
||||||
|
extern gboolean goGstBinAddElement (GstBin * bin, GstElement * element);
|
||||||
|
extern void goGstBinDeepElementAdded (GstBin * bin, GstBin * subbin, GstElement * child);
|
||||||
|
extern void goGstBinDeepElementRemoved (GstBin * bin, GstBin * subbin, GstElement * child);
|
||||||
|
extern gboolean goGstBinDoLatency (GstBin * bin);
|
||||||
|
extern void goGstBinElementAdded (GstBin * bin, GstElement * child);
|
||||||
|
extern void goGstBinElementRemoved (GstBin * bin, GstElement * child);
|
||||||
|
extern void goGstBinHandleMessage (GstBin * bin, GstMessage * message);
|
||||||
|
extern gboolean goGstBinRemoveElement (GstBin * bin, GstElement * element);
|
||||||
|
|
||||||
|
void setGstBinAddElement (GstBinClass * klass) { klass->add_element = goGstBinAddElement; };
|
||||||
|
void setGstBinDeepElementAdded (GstBinClass * klass) { klass->deep_element_added = goGstBinDeepElementAdded; };
|
||||||
|
void setGstBinDeepElementRemoved (GstBinClass * klass) { klass->deep_element_removed = goGstBinDeepElementRemoved; };
|
||||||
|
void setGstBinDoLatency (GstBinClass * klass) { klass->do_latency = goGstBinDoLatency; };
|
||||||
|
void setGstBinElementAdded (GstBinClass * klass) { klass->element_added = goGstBinElementAdded; };
|
||||||
|
void setGstBinElementRemoved (GstBinClass * klass) { klass->element_removed = goGstBinElementRemoved; };
|
||||||
|
void setGstBinHandleMessage (GstBinClass * klass) { klass->handle_message = goGstBinHandleMessage; };
|
||||||
|
void setGstBinRemoveElement (GstBinClass * klass) { klass->remove_element = goGstBinRemoveElement; };
|
||||||
|
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/tinyzimmer/go-glib/glib"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ExtendsBin implements an Extendable object based on a GstBin.
|
||||||
|
var ExtendsBin glib.Extendable = &extendsBin{parent: ExtendsElement}
|
||||||
|
|
||||||
|
// BinImpl is the reference interface for Go elements extending a Bin. You only need to
|
||||||
|
// implement the methods that interest you.
|
||||||
|
type BinImpl interface {
|
||||||
|
AddElement(self *Bin, element *Element) bool
|
||||||
|
DeepElementAdded(self *Bin, subbin *Bin, child *Element)
|
||||||
|
DeepElementRemoved(self *Bin, subbin *Bin, child *Element)
|
||||||
|
DoLatency(self *Bin) bool
|
||||||
|
ElementAdded(self *Bin, child *Element)
|
||||||
|
ElementRemoved(self *Bin, child *Element)
|
||||||
|
HandleMessage(self *Bin, msg *Message)
|
||||||
|
RemoveElement(self *Bin, element *Element) bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type extendsBin struct{ parent glib.Extendable }
|
||||||
|
|
||||||
|
func (e *extendsBin) Type() glib.Type { return glib.Type(C.gst_bin_get_type()) }
|
||||||
|
func (e *extendsBin) ClassSize() int64 { return int64(C.sizeof_GstBinClass) }
|
||||||
|
func (e *extendsBin) InstanceSize() int64 { return int64(C.sizeof_GstBin) }
|
||||||
|
|
||||||
|
func (e *extendsBin) InitClass(klass unsafe.Pointer, elem glib.GoObjectSubclass) {
|
||||||
|
e.parent.InitClass(klass, elem)
|
||||||
|
|
||||||
|
class := C.toGstBinClass(klass)
|
||||||
|
|
||||||
|
if _, ok := elem.(interface {
|
||||||
|
AddElement(self *Bin, element *Element) bool
|
||||||
|
}); ok {
|
||||||
|
C.setGstBinAddElement(class)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := elem.(interface {
|
||||||
|
DeepElementAdded(self *Bin, subbin *Bin, child *Element)
|
||||||
|
}); ok {
|
||||||
|
C.setGstBinDeepElementAdded(class)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := elem.(interface {
|
||||||
|
DeepElementRemoved(self *Bin, subbin *Bin, child *Element)
|
||||||
|
}); ok {
|
||||||
|
C.setGstBinDeepElementRemoved(class)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := elem.(interface {
|
||||||
|
DoLatency(self *Bin) bool
|
||||||
|
}); ok {
|
||||||
|
C.setGstBinDoLatency(class)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := elem.(interface {
|
||||||
|
ElementAdded(self *Bin, child *Element)
|
||||||
|
}); ok {
|
||||||
|
C.setGstBinElementAdded(class)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := elem.(interface {
|
||||||
|
ElementRemoved(self *Bin, child *Element)
|
||||||
|
}); ok {
|
||||||
|
C.setGstBinElementRemoved(class)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := elem.(interface {
|
||||||
|
HandleMessage(self *Bin, msg *Message)
|
||||||
|
}); ok {
|
||||||
|
C.setGstBinHandleMessage(class)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := elem.(interface {
|
||||||
|
RemoveElement(self *Bin, element *Element) bool
|
||||||
|
}); ok {
|
||||||
|
C.setGstBinRemoveElement(class)
|
||||||
|
}
|
||||||
|
}
|
222
gst/gst_child_proxy.go
Normal file
222
gst/gst_child_proxy.go
Normal file
@@ -0,0 +1,222 @@
|
|||||||
|
package gst
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include "gst.go.h"
|
||||||
|
|
||||||
|
extern void goGstChildProxyChildAdded (GstChildProxy * parent, GObject * child, const gchar * name);
|
||||||
|
extern void goGstChildProxyChildRemoved (GstChildProxy * parent, GObject * child, const gchar * name);
|
||||||
|
extern GObject * goGstChildProxyGetChildByIndex (GstChildProxy * parent, guint idx);
|
||||||
|
extern GObject * goGstChildProxyGetChildByName (GstChildProxy * parent, const gchar * name);
|
||||||
|
extern guint goGstChildProxyGetChildrenCount (GstChildProxy * parent);
|
||||||
|
|
||||||
|
void setGstChildProxyChildAdded (gpointer iface) { ((GstChildProxyInterface*)iface)->child_added = goGstChildProxyChildAdded; }
|
||||||
|
void setGstChildProxyChildRemoved (gpointer iface) { ((GstChildProxyInterface*)iface)->child_removed = goGstChildProxyChildRemoved; }
|
||||||
|
void setGstChildProxyGetChildByIndex (gpointer iface) { ((GstChildProxyInterface*)iface)->get_child_by_index = goGstChildProxyGetChildByIndex; }
|
||||||
|
void setGstChildProxyGetChildByName (gpointer iface) { ((GstChildProxyInterface*)iface)->get_child_by_name = goGstChildProxyGetChildByName; }
|
||||||
|
void setGstChildProxyGetChildrenCount (gpointer iface) { ((GstChildProxyInterface*)iface)->get_children_count = goGstChildProxyGetChildrenCount; }
|
||||||
|
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/tinyzimmer/go-glib/glib"
|
||||||
|
)
|
||||||
|
|
||||||
|
// InterfaceChildProxy represents the GstChildProxy interface. Use this when querying bins
|
||||||
|
// for elements that implement GstChildProxy, or when signaling that a GoObjectSubclass
|
||||||
|
// provides this interface.
|
||||||
|
var InterfaceChildProxy glib.Interface = &interfaceChildProxy{}
|
||||||
|
|
||||||
|
type interfaceChildProxy struct{ glib.Interface }
|
||||||
|
|
||||||
|
func (i *interfaceChildProxy) Type() glib.Type { return glib.Type(C.GST_TYPE_CHILD_PROXY) }
|
||||||
|
func (i *interfaceChildProxy) InitFunc() glib.InterfaceInitFunc {
|
||||||
|
return func(instance *glib.TypeInstance) {
|
||||||
|
goobj := instance.GoType
|
||||||
|
|
||||||
|
if _, ok := goobj.(interface {
|
||||||
|
ChildAdded(self *ChildProxy, child *glib.Object, name string)
|
||||||
|
}); ok {
|
||||||
|
C.setGstChildProxyChildAdded((C.gpointer)(instance.GTypeInstance))
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := goobj.(interface {
|
||||||
|
ChildRemoved(self *ChildProxy, child *glib.Object, name string)
|
||||||
|
}); ok {
|
||||||
|
C.setGstChildProxyChildRemoved((C.gpointer)(instance.GTypeInstance))
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := goobj.(interface {
|
||||||
|
GetChildByIndex(self *ChildProxy, idx uint) *glib.Object
|
||||||
|
}); ok {
|
||||||
|
C.setGstChildProxyGetChildByIndex((C.gpointer)(instance.GTypeInstance))
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := goobj.(interface {
|
||||||
|
GetChildByName(self *ChildProxy, name string) *glib.Object
|
||||||
|
}); ok {
|
||||||
|
C.setGstChildProxyGetChildByName((C.gpointer)(instance.GTypeInstance))
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := goobj.(interface {
|
||||||
|
GetChildrenCount(self *ChildProxy) uint
|
||||||
|
}); ok {
|
||||||
|
C.setGstChildProxyGetChildrenCount((C.gpointer)(instance.GTypeInstance))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChildProxyImpl is the reference implementation for a ChildProxy implemented by a Go object.
|
||||||
|
type ChildProxyImpl interface {
|
||||||
|
ChildAdded(self *ChildProxy, child *glib.Object, name string)
|
||||||
|
ChildRemoved(self *ChildProxy, child *glib.Object, name string)
|
||||||
|
GetChildByIndex(self *ChildProxy, idx uint) *glib.Object
|
||||||
|
GetChildByName(self *ChildProxy, name string) *glib.Object
|
||||||
|
GetChildrenCount(self *ChildProxy) uint
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChildProxy is an interface that abstracts handling of property sets for
|
||||||
|
// elements with children. They all have multiple GstPad or some kind of voice
|
||||||
|
// objects. Another use case are container elements like GstBin. The element
|
||||||
|
// implementing the interface acts as a parent for those child objects.
|
||||||
|
//
|
||||||
|
// Property names are written as "child-name::property-name". The whole naming
|
||||||
|
// scheme is recursive. Thus "child1::child2::property" is valid too, if "child1"
|
||||||
|
// and "child2" implement the GstChildProxy interface.
|
||||||
|
type ChildProxy struct{ ptr *C.GstChildProxy }
|
||||||
|
|
||||||
|
// ToChildProxy returns a ChildProxy for the given element. If the element does not implement
|
||||||
|
// a ChildProxy it returns nil.
|
||||||
|
func ToChildProxy(elem *Element) *ChildProxy {
|
||||||
|
if proxy := C.toGstChildProxy(elem.Unsafe()); proxy != nil {
|
||||||
|
return &ChildProxy{proxy}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Instance returns the underlying GstChildProxy instance.
|
||||||
|
func (c *ChildProxy) Instance() *C.GstChildProxy {
|
||||||
|
return C.toGstChildProxy(unsafe.Pointer(c.ptr))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChildAdded emits the "child-added" signal.
|
||||||
|
func (c *ChildProxy) ChildAdded(child *glib.Object, name string) {
|
||||||
|
cname := C.CString(name)
|
||||||
|
defer C.free(unsafe.Pointer(cname))
|
||||||
|
C.gst_child_proxy_child_added(
|
||||||
|
c.Instance(),
|
||||||
|
(*C.GObject)(child.Unsafe()),
|
||||||
|
(*C.gchar)(unsafe.Pointer(cname)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChildRemoved emits the "child-removed" signal.
|
||||||
|
func (c *ChildProxy) ChildRemoved(child *glib.Object, name string) {
|
||||||
|
cname := C.CString(name)
|
||||||
|
defer C.free(unsafe.Pointer(cname))
|
||||||
|
C.gst_child_proxy_child_removed(
|
||||||
|
c.Instance(),
|
||||||
|
(*C.GObject)(child.Unsafe()),
|
||||||
|
(*C.gchar)(unsafe.Pointer(cname)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get gets properties of the parent object and its children. This is a direct alias to looping
|
||||||
|
// over GetProperty and returning the results in the order of the arguments. If any of the results
|
||||||
|
// returns nil from an allocation error, nil is returned for the entire slice.
|
||||||
|
func (c *ChildProxy) Get(names ...string) []*glib.Value {
|
||||||
|
out := make([]*glib.Value, len(names))
|
||||||
|
for i, name := range names {
|
||||||
|
val := c.GetProperty(name)
|
||||||
|
if val == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out[i] = val
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetChildByIndex fetches a child by its number. This function can return nil if the object is not
|
||||||
|
// found. Unref after usage.
|
||||||
|
func (c *ChildProxy) GetChildByIndex(idx uint) *glib.Object {
|
||||||
|
gobj := C.gst_child_proxy_get_child_by_index(c.Instance(), C.guint(idx))
|
||||||
|
if gobj == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return &glib.Object{GObject: glib.ToGObject(unsafe.Pointer(gobj))}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetChildByName fetches a child by name. The virtual method's default implementation uses Object
|
||||||
|
// together with Object.GetName. If the interface is to be used with GObjects, this method needs
|
||||||
|
// to be overridden.
|
||||||
|
//
|
||||||
|
// This function can return nil if the object is not found. Unref after usage.
|
||||||
|
func (c *ChildProxy) GetChildByName(name string) *glib.Object {
|
||||||
|
cname := C.CString(name)
|
||||||
|
defer C.free(unsafe.Pointer(cname))
|
||||||
|
gobj := C.gst_child_proxy_get_child_by_name(c.Instance(), (*C.gchar)(unsafe.Pointer(cname)))
|
||||||
|
if gobj == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return &glib.Object{GObject: glib.ToGObject(unsafe.Pointer(gobj))}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetChildrenCount returns the number of child objects the parent contains.
|
||||||
|
func (c *ChildProxy) GetChildrenCount() uint {
|
||||||
|
return uint(C.gst_child_proxy_get_children_count(c.Instance()))
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetProperty gets a single property using the ChildProxy mechanism. The bindings
|
||||||
|
// take care of freeing the value when it leaves the user's scope. This function
|
||||||
|
// can return nil if a failure happens trying to allocate GValues.
|
||||||
|
func (c *ChildProxy) GetProperty(name string) *glib.Value {
|
||||||
|
value, err := glib.ValueAlloc()
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
cname := C.CString(name)
|
||||||
|
defer C.free(unsafe.Pointer(cname))
|
||||||
|
C.gst_child_proxy_get_property(c.Instance(), (*C.gchar)(unsafe.Pointer(cname)), (*C.GValue)(unsafe.Pointer(value.GValue)))
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lookup looks up which object and and parameter would be affected by the given name.
|
||||||
|
// If ok is false, the targets could not be found and this function returned nil.
|
||||||
|
// Unref target after usage.
|
||||||
|
func (c *ChildProxy) Lookup(name string) (ok bool, target *glib.Object, param *glib.ParamSpec) {
|
||||||
|
var gtarget *C.GObject
|
||||||
|
var gspec *C.GParamSpec
|
||||||
|
cname := C.CString(name)
|
||||||
|
defer C.free(unsafe.Pointer(cname))
|
||||||
|
ok = gobool(C.gst_child_proxy_lookup(
|
||||||
|
c.Instance(),
|
||||||
|
(*C.gchar)(unsafe.Pointer(cname)),
|
||||||
|
>arget, &gspec,
|
||||||
|
))
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
target = &glib.Object{GObject: glib.ToGObject(unsafe.Pointer(gtarget))}
|
||||||
|
param = glib.ToParamSpec(unsafe.Pointer(gspec))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set takes a map of names to values and applies them using the ChildProxy mechanism.
|
||||||
|
func (c *ChildProxy) Set(values map[string]*glib.Value) {
|
||||||
|
for name, value := range values {
|
||||||
|
c.SetProperty(name, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetProperty sets a single property using the ChildProxy mechanism.
|
||||||
|
func (c *ChildProxy) SetProperty(name string, value *glib.Value) {
|
||||||
|
cname := C.CString(name)
|
||||||
|
defer C.free(unsafe.Pointer(cname))
|
||||||
|
C.gst_child_proxy_set_property(
|
||||||
|
c.Instance(),
|
||||||
|
(*C.gchar)(unsafe.Pointer(cname)),
|
||||||
|
(*C.GValue)(unsafe.Pointer(value.GValue)),
|
||||||
|
)
|
||||||
|
}
|
74
gst/gst_child_proxy_exports.go
Normal file
74
gst/gst_child_proxy_exports.go
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
package gst
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include "gst.go.h"
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/tinyzimmer/go-glib/glib"
|
||||||
|
)
|
||||||
|
|
||||||
|
func wrapParent(parent *C.GstChildProxy) *ChildProxy { return &ChildProxy{ptr: parent} }
|
||||||
|
|
||||||
|
//export goGstChildProxyChildAdded
|
||||||
|
func goGstChildProxyChildAdded(parent *C.GstChildProxy, child *C.GObject, name *C.gchar) {
|
||||||
|
iface := glib.FromObjectUnsafePrivate(unsafe.Pointer(parent))
|
||||||
|
caller := iface.(interface {
|
||||||
|
ChildAdded(self *ChildProxy, child *glib.Object, name string)
|
||||||
|
})
|
||||||
|
caller.ChildAdded(
|
||||||
|
wrapParent(parent),
|
||||||
|
&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(child))},
|
||||||
|
C.GoString(name),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
//export goGstChildProxyChildRemoved
|
||||||
|
func goGstChildProxyChildRemoved(parent *C.GstChildProxy, child *C.GObject, name *C.gchar) {
|
||||||
|
iface := glib.FromObjectUnsafePrivate(unsafe.Pointer(parent))
|
||||||
|
caller := iface.(interface {
|
||||||
|
ChildRemoved(self *ChildProxy, child *glib.Object, name string)
|
||||||
|
})
|
||||||
|
caller.ChildRemoved(
|
||||||
|
wrapParent(parent),
|
||||||
|
&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(child))},
|
||||||
|
C.GoString(name),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
//export goGstChildProxyGetChildByIndex
|
||||||
|
func goGstChildProxyGetChildByIndex(parent *C.GstChildProxy, idx C.guint) *C.GObject {
|
||||||
|
iface := glib.FromObjectUnsafePrivate(unsafe.Pointer(parent))
|
||||||
|
caller := iface.(interface {
|
||||||
|
GetChildByIndex(self *ChildProxy, idx uint) *glib.Object
|
||||||
|
})
|
||||||
|
obj := caller.GetChildByIndex(wrapParent(parent), uint(idx))
|
||||||
|
if obj == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return (*C.GObject)(unsafe.Pointer(obj.GObject))
|
||||||
|
}
|
||||||
|
|
||||||
|
//export goGstChildProxyGetChildByName
|
||||||
|
func goGstChildProxyGetChildByName(parent *C.GstChildProxy, name *C.gchar) *C.GObject {
|
||||||
|
iface := glib.FromObjectUnsafePrivate(unsafe.Pointer(parent))
|
||||||
|
caller := iface.(interface {
|
||||||
|
GetChildByName(self *ChildProxy, name string) *glib.Object
|
||||||
|
})
|
||||||
|
obj := caller.GetChildByName(wrapParent(parent), C.GoString(name))
|
||||||
|
if obj == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return (*C.GObject)(unsafe.Pointer(obj.GObject))
|
||||||
|
}
|
||||||
|
|
||||||
|
//export goGstChildProxyGetChildrenCount
|
||||||
|
func goGstChildProxyGetChildrenCount(parent *C.GstChildProxy) C.guint {
|
||||||
|
iface := glib.FromObjectUnsafePrivate(unsafe.Pointer(parent))
|
||||||
|
caller := iface.(interface {
|
||||||
|
GetChildrenCount(self *ChildProxy) uint
|
||||||
|
})
|
||||||
|
return C.guint(caller.GetChildrenCount(wrapParent(parent)))
|
||||||
|
}
|
@@ -70,7 +70,7 @@ func (d *Device) HasClasses(classes []string) bool {
|
|||||||
// while in the PLAYING state.
|
// while in the PLAYING state.
|
||||||
func (d *Device) ReconfigureElement(elem *Element) error {
|
func (d *Device) ReconfigureElement(elem *Element) error {
|
||||||
if ok := gobool(C.gst_device_reconfigure_element(d.Instance(), elem.Instance())); !ok {
|
if ok := gobool(C.gst_device_reconfigure_element(d.Instance(), elem.Instance())); !ok {
|
||||||
return fmt.Errorf("Failed to reconfigure element %s", elem.Name())
|
return fmt.Errorf("Failed to reconfigure element %s", elem.GetName())
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@@ -29,40 +29,6 @@ GstStateChangeReturn elementParentChangeState (GstElement * element, GstStateCha
|
|||||||
return parent->change_state(element, transition);
|
return parent->change_state(element, transition);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern GstStateChangeReturn goGstElementClassChangeState (GstElement * element, GstStateChange change);
|
|
||||||
extern GstStateChangeReturn goGstElementClassGetState (GstElement * element, GstState * state, GstState * pending, GstClockTime timeout);
|
|
||||||
extern void goGstElementClassNoMorePads (GstElement * element);
|
|
||||||
extern void goGstElementClassPadAdded (GstElement * element, GstPad * pad);
|
|
||||||
extern void goGstElementClassPadRemoved (GstElement * element, GstPad * pad);
|
|
||||||
extern gboolean goGstElementClassPostMessage (GstElement * element, GstMessage * msg);
|
|
||||||
extern GstClock * goGstElementClassProvideClock (GstElement * element);
|
|
||||||
extern gboolean goGstElementClassQuery (GstElement * element, GstQuery * query);
|
|
||||||
extern void goGstElementClassReleasePad (GstElement * element, GstPad * pad);
|
|
||||||
extern GstPad * goGstElementClassRequestNewPad (GstElement * element, GstPadTemplate * templ, const gchar * name, const GstCaps * caps);
|
|
||||||
extern gboolean goGstElementClassSendEvent (GstElement * element, GstEvent * event);
|
|
||||||
extern void goGstElementClassSetBus (GstElement * element, GstBus * bus);
|
|
||||||
extern gboolean goGstElementClassSetClock (GstElement * element, GstClock * clock);
|
|
||||||
extern void goGstElementClassSetContext (GstElement * element, GstContext * ctx);
|
|
||||||
extern GstStateChangeReturn goGstElementClassSetState (GstElement * element, GstState state);
|
|
||||||
extern void goGstElementClassStateChanged (GstElement * element, GstState old, GstState new, GstState pending);
|
|
||||||
|
|
||||||
void setGstElementClassChangeState (GstElementClass * klass) { klass->change_state = goGstElementClassChangeState; }
|
|
||||||
void setGstElementClassGetState (GstElementClass * klass) { klass->get_state = goGstElementClassGetState; }
|
|
||||||
void setGstElementClassNoMorePads (GstElementClass * klass) { klass->no_more_pads = goGstElementClassNoMorePads; }
|
|
||||||
void setGstElementClassPadAdded (GstElementClass * klass) { klass->pad_added = goGstElementClassPadAdded; }
|
|
||||||
void setGstElementClassPadRemoved (GstElementClass * klass) { klass->pad_removed = goGstElementClassPadRemoved; }
|
|
||||||
void setGstElementClassPostMessage (GstElementClass * klass) { klass->post_message = goGstElementClassPostMessage; }
|
|
||||||
void setGstElementClassProvideClock (GstElementClass * klass) { klass->provide_clock = goGstElementClassProvideClock; }
|
|
||||||
void setGstElementClassQuery (GstElementClass * klass) { klass->query = goGstElementClassQuery; }
|
|
||||||
void setGstElementClassReleasePad (GstElementClass * klass) { klass->release_pad = goGstElementClassReleasePad; }
|
|
||||||
void setGstElementClassRequestNewPad (GstElementClass * klass) { klass->request_new_pad = goGstElementClassRequestNewPad; }
|
|
||||||
void setGstElementClassSendEvent (GstElementClass * klass) { klass->send_event = goGstElementClassSendEvent; }
|
|
||||||
void setGstElementClassSetBus (GstElementClass * klass) { klass->set_bus = goGstElementClassSetBus; }
|
|
||||||
void setGstElementClassSetClock (GstElementClass * klass) { klass->set_clock = goGstElementClassSetClock; }
|
|
||||||
void setGstElementClassSetContext (GstElementClass * klass) { klass->set_context = goGstElementClassSetContext; }
|
|
||||||
void setGstElementClassSetState (GstElementClass * klass) { klass->set_state = goGstElementClassSetState; }
|
|
||||||
void setGstElementClassStateChanged (GstElementClass * klass) { klass->state_changed = goGstElementClassStateChanged; }
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
@@ -70,7 +36,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"path"
|
"path"
|
||||||
"runtime"
|
"runtime"
|
||||||
"time"
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
gopointer "github.com/mattn/go-pointer"
|
gopointer "github.com/mattn/go-pointer"
|
||||||
@@ -117,12 +82,12 @@ const (
|
|||||||
|
|
||||||
// RegisterElement creates a new elementfactory capable of instantiating objects of the given GoElement
|
// RegisterElement creates a new elementfactory capable of instantiating objects of the given GoElement
|
||||||
// and adds the factory to the plugin. A higher rank means more importance when autoplugging.
|
// and adds the factory to the plugin. A higher rank means more importance when autoplugging.
|
||||||
func RegisterElement(plugin *Plugin, name string, rank Rank, elem glib.GoObjectSubclass, extends glib.Extendable) bool {
|
func RegisterElement(plugin *Plugin, name string, rank Rank, elem glib.GoObjectSubclass, extends glib.Extendable, interfaces ...glib.Interface) bool {
|
||||||
return gobool(C.gst_element_register(
|
return gobool(C.gst_element_register(
|
||||||
plugin.Instance(),
|
plugin.Instance(),
|
||||||
C.CString(name),
|
C.CString(name),
|
||||||
C.guint(rank),
|
C.guint(rank),
|
||||||
C.GType(glib.RegisterGoType(name, elem, extends)),
|
C.GType(glib.RegisterGoType(name, elem, extends, interfaces...)),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -340,7 +305,7 @@ func (e *Element) IsURIHandler() bool {
|
|||||||
// Link wraps gst_element_link and links this element to the given one.
|
// Link wraps gst_element_link and links this element to the given one.
|
||||||
func (e *Element) Link(elem *Element) error {
|
func (e *Element) Link(elem *Element) error {
|
||||||
if ok := C.gst_element_link((*C.GstElement)(e.Instance()), (*C.GstElement)(elem.Instance())); !gobool(ok) {
|
if ok := C.gst_element_link((*C.GstElement)(e.Instance()), (*C.GstElement)(elem.Instance())); !gobool(ok) {
|
||||||
return fmt.Errorf("Failed to link %s to %s", e.Name(), elem.Name())
|
return fmt.Errorf("Failed to link %s to %s", e.GetName(), elem.GetName())
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -349,7 +314,7 @@ func (e *Element) Link(elem *Element) error {
|
|||||||
// using the provided sink caps.
|
// using the provided sink caps.
|
||||||
func (e *Element) LinkFiltered(elem *Element, caps *Caps) error {
|
func (e *Element) LinkFiltered(elem *Element, caps *Caps) error {
|
||||||
if ok := C.gst_element_link_filtered((*C.GstElement)(e.Instance()), (*C.GstElement)(elem.Instance()), (*C.GstCaps)(caps.Instance())); !gobool(ok) {
|
if ok := C.gst_element_link_filtered((*C.GstElement)(e.Instance()), (*C.GstElement)(elem.Instance()), (*C.GstCaps)(caps.Instance())); !gobool(ok) {
|
||||||
return fmt.Errorf("Failed to link %s to %s with provider caps", e.Name(), elem.Name())
|
return fmt.Errorf("Failed to link %s to %s with provided caps", e.GetName(), elem.GetName())
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -459,152 +424,3 @@ func (e *Element) URIHandler() URIHandler {
|
|||||||
}
|
}
|
||||||
return &gstURIHandler{ptr: e.Instance()}
|
return &gstURIHandler{ptr: e.Instance()}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExtendsElement signifies a GoElement that extends a GstElement.
|
|
||||||
var ExtendsElement glib.Extendable = &extendElement{parent: glib.ExtendsObject}
|
|
||||||
|
|
||||||
// ElementImpl is an interface containing go quivalents of the virtual methods that can be
|
|
||||||
// overridden by a plugin extending an Element.
|
|
||||||
type ElementImpl interface {
|
|
||||||
// ChangeState is called by SetState to perform an incremental state change.
|
|
||||||
ChangeState(*Element, StateChange) StateChangeReturn
|
|
||||||
// GetState should return the states of the element
|
|
||||||
GetState(self *Element, timeout time.Duration) (ret StateChangeReturn, current, pending State)
|
|
||||||
// NoMorePads is called when there are no more pads on the element.
|
|
||||||
NoMorePads(*Element)
|
|
||||||
// PadAdded is called to add a pad to the element.
|
|
||||||
PadAdded(*Element, *Pad)
|
|
||||||
// PadRemoved is called to remove a pad from the element.
|
|
||||||
PadRemoved(*Element, *Pad)
|
|
||||||
// PostMessage is called when a message is posted to the element. Call Element.ParentPostMessage
|
|
||||||
// to have it posted on the bus after processing.
|
|
||||||
PostMessage(*Element, *Message) bool
|
|
||||||
// ProvideClock is called to retrieve the clock provided by the element.
|
|
||||||
ProvideClock(*Element) *Clock
|
|
||||||
// Query is called to perform a query on the element.
|
|
||||||
Query(*Element, *Query) bool
|
|
||||||
// ReleasePad is called when a request pad is to be released.
|
|
||||||
ReleasePad(*Element, *Pad)
|
|
||||||
// RequestNewPad is called when a new pad is requested from the element.
|
|
||||||
RequestNewPad(self *Element, templ *PadTemplate, name string, caps *Caps) *Pad
|
|
||||||
// SendEvent is called to send an event to the element.
|
|
||||||
SendEvent(*Element, *Event) bool
|
|
||||||
// SetBus is called to set the Bus on the element.
|
|
||||||
SetBus(*Element, *Bus)
|
|
||||||
// SetClock is called to set the clock on the element.
|
|
||||||
SetClock(*Element, *Clock) bool
|
|
||||||
// SetContext is called to set the Context on the element.
|
|
||||||
SetContext(*Element, *Context)
|
|
||||||
// SetState is called to set a new state on the element.
|
|
||||||
SetState(*Element, State) StateChangeReturn
|
|
||||||
// StateChanged is called immediately after a new state was set.
|
|
||||||
StateChanged(self *Element, old, new, pending State)
|
|
||||||
}
|
|
||||||
|
|
||||||
type extendElement struct{ parent glib.Extendable }
|
|
||||||
|
|
||||||
func (e *extendElement) Type() glib.Type { return glib.Type(C.gst_element_get_type()) }
|
|
||||||
func (e *extendElement) ClassSize() int64 { return int64(C.sizeof_GstElementClass) }
|
|
||||||
func (e *extendElement) InstanceSize() int64 { return int64(C.sizeof_GstElement) }
|
|
||||||
|
|
||||||
func (e *extendElement) InitClass(klass unsafe.Pointer, elem glib.GoObjectSubclass) {
|
|
||||||
e.parent.InitClass(klass, elem)
|
|
||||||
|
|
||||||
elemClass := C.toGstElementClass(klass)
|
|
||||||
|
|
||||||
if _, ok := elem.(interface {
|
|
||||||
ChangeState(*Element, StateChange) StateChangeReturn
|
|
||||||
}); ok {
|
|
||||||
C.setGstElementClassChangeState(elemClass)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := elem.(interface {
|
|
||||||
GetState(self *Element, timeout time.Duration) (ret StateChangeReturn, current, pending State)
|
|
||||||
}); ok {
|
|
||||||
C.setGstElementClassGetState(elemClass)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := elem.(interface {
|
|
||||||
NoMorePads(*Element)
|
|
||||||
}); ok {
|
|
||||||
C.setGstElementClassNoMorePads(elemClass)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := elem.(interface {
|
|
||||||
PadAdded(*Element, *Pad)
|
|
||||||
}); ok {
|
|
||||||
C.setGstElementClassPadAdded(elemClass)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := elem.(interface {
|
|
||||||
PadRemoved(*Element, *Pad)
|
|
||||||
}); ok {
|
|
||||||
C.setGstElementClassPadRemoved(elemClass)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := elem.(interface {
|
|
||||||
PostMessage(*Element, *Message) bool
|
|
||||||
}); ok {
|
|
||||||
C.setGstElementClassPostMessage(elemClass)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := elem.(interface {
|
|
||||||
ProvideClock(*Element) *Clock
|
|
||||||
}); ok {
|
|
||||||
C.setGstElementClassProvideClock(elemClass)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := elem.(interface {
|
|
||||||
Query(*Element, *Query) bool
|
|
||||||
}); ok {
|
|
||||||
C.setGstElementClassQuery(elemClass)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := elem.(interface {
|
|
||||||
ReleasePad(*Element, *Pad)
|
|
||||||
}); ok {
|
|
||||||
C.setGstElementClassReleasePad(elemClass)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := elem.(interface {
|
|
||||||
RequestNewPad(self *Element, templ *PadTemplate, name string, caps *Caps) *Pad
|
|
||||||
}); ok {
|
|
||||||
C.setGstElementClassRequestNewPad(elemClass)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := elem.(interface {
|
|
||||||
SendEvent(*Element, *Event) bool
|
|
||||||
}); ok {
|
|
||||||
C.setGstElementClassSendEvent(elemClass)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := elem.(interface {
|
|
||||||
SetBus(*Element, *Bus)
|
|
||||||
}); ok {
|
|
||||||
C.setGstElementClassSetBus(elemClass)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := elem.(interface {
|
|
||||||
SetClock(*Element, *Clock) bool
|
|
||||||
}); ok {
|
|
||||||
C.setGstElementClassSetClock(elemClass)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := elem.(interface {
|
|
||||||
SetContext(*Element, *Context)
|
|
||||||
}); ok {
|
|
||||||
C.setGstElementClassSetContext(elemClass)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := elem.(interface {
|
|
||||||
SetState(*Element, State) StateChangeReturn
|
|
||||||
}); ok {
|
|
||||||
C.setGstElementClassSetState(elemClass)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := elem.(interface {
|
|
||||||
StateChanged(self *Element, old, new, pending State)
|
|
||||||
}); ok {
|
|
||||||
C.setGstElementClassStateChanged(elemClass)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@@ -14,11 +14,23 @@ import (
|
|||||||
// This is meant for internal usage and is exported for visibility to other packages.
|
// This is meant for internal usage and is exported for visibility to other packages.
|
||||||
func FromGstElementUnsafe(elem unsafe.Pointer) *Element { return wrapElement(toGObject(elem)) }
|
func FromGstElementUnsafe(elem unsafe.Pointer) *Element { return wrapElement(toGObject(elem)) }
|
||||||
|
|
||||||
// NewElement is a generic wrapper around `gst_element_factory_make`.
|
// NewElement creates a new element using the factory of the given name.
|
||||||
func NewElement(name string) (*Element, error) {
|
func NewElement(factory string) (*Element, error) {
|
||||||
elemName := C.CString(name)
|
return NewElementWithName(factory, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewElementWithName creates a new element and sets it's name to the given value.
|
||||||
|
func NewElementWithName(factory string, name string) (*Element, error) {
|
||||||
|
elemName := C.CString(factory)
|
||||||
defer C.free(unsafe.Pointer(elemName))
|
defer C.free(unsafe.Pointer(elemName))
|
||||||
elem := C.gst_element_factory_make((*C.gchar)(elemName), nil)
|
var elem *C.GstElement
|
||||||
|
if name == "" {
|
||||||
|
elem = C.gst_element_factory_make((*C.gchar)(elemName), nil)
|
||||||
|
} else {
|
||||||
|
cname := C.CString(name)
|
||||||
|
defer C.free(unsafe.Pointer(cname))
|
||||||
|
elem = C.gst_element_factory_make((*C.gchar)(elemName), (*C.gchar)(cname))
|
||||||
|
}
|
||||||
if elem == nil {
|
if elem == nil {
|
||||||
return nil, fmt.Errorf("Could not create element: %s", name)
|
return nil, fmt.Errorf("Could not create element: %s", name)
|
||||||
}
|
}
|
||||||
|
196
gst/gst_element_impl.go
Normal file
196
gst/gst_element_impl.go
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
package gst
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include "gst.go.h"
|
||||||
|
|
||||||
|
extern GstStateChangeReturn goGstElementClassChangeState (GstElement * element, GstStateChange change);
|
||||||
|
extern GstStateChangeReturn goGstElementClassGetState (GstElement * element, GstState * state, GstState * pending, GstClockTime timeout);
|
||||||
|
extern void goGstElementClassNoMorePads (GstElement * element);
|
||||||
|
extern void goGstElementClassPadAdded (GstElement * element, GstPad * pad);
|
||||||
|
extern void goGstElementClassPadRemoved (GstElement * element, GstPad * pad);
|
||||||
|
extern gboolean goGstElementClassPostMessage (GstElement * element, GstMessage * msg);
|
||||||
|
extern GstClock * goGstElementClassProvideClock (GstElement * element);
|
||||||
|
extern gboolean goGstElementClassQuery (GstElement * element, GstQuery * query);
|
||||||
|
extern void goGstElementClassReleasePad (GstElement * element, GstPad * pad);
|
||||||
|
extern GstPad * goGstElementClassRequestNewPad (GstElement * element, GstPadTemplate * templ, const gchar * name, const GstCaps * caps);
|
||||||
|
extern gboolean goGstElementClassSendEvent (GstElement * element, GstEvent * event);
|
||||||
|
extern void goGstElementClassSetBus (GstElement * element, GstBus * bus);
|
||||||
|
extern gboolean goGstElementClassSetClock (GstElement * element, GstClock * clock);
|
||||||
|
extern void goGstElementClassSetContext (GstElement * element, GstContext * ctx);
|
||||||
|
extern GstStateChangeReturn goGstElementClassSetState (GstElement * element, GstState state);
|
||||||
|
extern void goGstElementClassStateChanged (GstElement * element, GstState old, GstState new, GstState pending);
|
||||||
|
|
||||||
|
void setGstElementClassChangeState (GstElementClass * klass) { klass->change_state = goGstElementClassChangeState; }
|
||||||
|
void setGstElementClassGetState (GstElementClass * klass) { klass->get_state = goGstElementClassGetState; }
|
||||||
|
void setGstElementClassNoMorePads (GstElementClass * klass) { klass->no_more_pads = goGstElementClassNoMorePads; }
|
||||||
|
void setGstElementClassPadAdded (GstElementClass * klass) { klass->pad_added = goGstElementClassPadAdded; }
|
||||||
|
void setGstElementClassPadRemoved (GstElementClass * klass) { klass->pad_removed = goGstElementClassPadRemoved; }
|
||||||
|
void setGstElementClassPostMessage (GstElementClass * klass) { klass->post_message = goGstElementClassPostMessage; }
|
||||||
|
void setGstElementClassProvideClock (GstElementClass * klass) { klass->provide_clock = goGstElementClassProvideClock; }
|
||||||
|
void setGstElementClassQuery (GstElementClass * klass) { klass->query = goGstElementClassQuery; }
|
||||||
|
void setGstElementClassReleasePad (GstElementClass * klass) { klass->release_pad = goGstElementClassReleasePad; }
|
||||||
|
void setGstElementClassRequestNewPad (GstElementClass * klass) { klass->request_new_pad = goGstElementClassRequestNewPad; }
|
||||||
|
void setGstElementClassSendEvent (GstElementClass * klass) { klass->send_event = goGstElementClassSendEvent; }
|
||||||
|
void setGstElementClassSetBus (GstElementClass * klass) { klass->set_bus = goGstElementClassSetBus; }
|
||||||
|
void setGstElementClassSetClock (GstElementClass * klass) { klass->set_clock = goGstElementClassSetClock; }
|
||||||
|
void setGstElementClassSetContext (GstElementClass * klass) { klass->set_context = goGstElementClassSetContext; }
|
||||||
|
void setGstElementClassSetState (GstElementClass * klass) { klass->set_state = goGstElementClassSetState; }
|
||||||
|
void setGstElementClassStateChanged (GstElementClass * klass) { klass->state_changed = goGstElementClassStateChanged; }
|
||||||
|
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/tinyzimmer/go-glib/glib"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ExtendsElement implements an Extendable object based on a GstElement.
|
||||||
|
var ExtendsElement glib.Extendable = &extendElement{parent: glib.ExtendsObject}
|
||||||
|
|
||||||
|
// ElementImpl is an interface containing go equivalents of the virtual methods that can be
|
||||||
|
// overridden by a plugin extending an Element.
|
||||||
|
type ElementImpl interface {
|
||||||
|
// ChangeState is called by SetState to perform an incremental state change.
|
||||||
|
ChangeState(*Element, StateChange) StateChangeReturn
|
||||||
|
// GetState should return the states of the element
|
||||||
|
GetState(self *Element, timeout time.Duration) (ret StateChangeReturn, current, pending State)
|
||||||
|
// NoMorePads is called when there are no more pads on the element.
|
||||||
|
NoMorePads(*Element)
|
||||||
|
// PadAdded is called to add a pad to the element.
|
||||||
|
PadAdded(*Element, *Pad)
|
||||||
|
// PadRemoved is called to remove a pad from the element.
|
||||||
|
PadRemoved(*Element, *Pad)
|
||||||
|
// PostMessage is called when a message is posted to the element. Call Element.ParentPostMessage
|
||||||
|
// to have it posted on the bus after processing.
|
||||||
|
PostMessage(*Element, *Message) bool
|
||||||
|
// ProvideClock is called to retrieve the clock provided by the element.
|
||||||
|
ProvideClock(*Element) *Clock
|
||||||
|
// Query is called to perform a query on the element.
|
||||||
|
Query(*Element, *Query) bool
|
||||||
|
// ReleasePad is called when a request pad is to be released.
|
||||||
|
ReleasePad(*Element, *Pad)
|
||||||
|
// RequestNewPad is called when a new pad is requested from the element.
|
||||||
|
RequestNewPad(self *Element, templ *PadTemplate, name string, caps *Caps) *Pad
|
||||||
|
// SendEvent is called to send an event to the element.
|
||||||
|
SendEvent(*Element, *Event) bool
|
||||||
|
// SetBus is called to set the Bus on the element.
|
||||||
|
SetBus(*Element, *Bus)
|
||||||
|
// SetClock is called to set the clock on the element.
|
||||||
|
SetClock(*Element, *Clock) bool
|
||||||
|
// SetContext is called to set the Context on the element.
|
||||||
|
SetContext(*Element, *Context)
|
||||||
|
// SetState is called to set a new state on the element.
|
||||||
|
SetState(*Element, State) StateChangeReturn
|
||||||
|
// StateChanged is called immediately after a new state was set.
|
||||||
|
StateChanged(self *Element, old, new, pending State)
|
||||||
|
}
|
||||||
|
|
||||||
|
type extendElement struct{ parent glib.Extendable }
|
||||||
|
|
||||||
|
func (e *extendElement) Type() glib.Type { return glib.Type(C.gst_element_get_type()) }
|
||||||
|
func (e *extendElement) ClassSize() int64 { return int64(C.sizeof_GstElementClass) }
|
||||||
|
func (e *extendElement) InstanceSize() int64 { return int64(C.sizeof_GstElement) }
|
||||||
|
|
||||||
|
func (e *extendElement) InitClass(klass unsafe.Pointer, elem glib.GoObjectSubclass) {
|
||||||
|
e.parent.InitClass(klass, elem)
|
||||||
|
|
||||||
|
elemClass := C.toGstElementClass(klass)
|
||||||
|
|
||||||
|
if _, ok := elem.(interface {
|
||||||
|
ChangeState(*Element, StateChange) StateChangeReturn
|
||||||
|
}); ok {
|
||||||
|
C.setGstElementClassChangeState(elemClass)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := elem.(interface {
|
||||||
|
GetState(self *Element, timeout time.Duration) (ret StateChangeReturn, current, pending State)
|
||||||
|
}); ok {
|
||||||
|
C.setGstElementClassGetState(elemClass)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := elem.(interface {
|
||||||
|
NoMorePads(*Element)
|
||||||
|
}); ok {
|
||||||
|
C.setGstElementClassNoMorePads(elemClass)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := elem.(interface {
|
||||||
|
PadAdded(*Element, *Pad)
|
||||||
|
}); ok {
|
||||||
|
C.setGstElementClassPadAdded(elemClass)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := elem.(interface {
|
||||||
|
PadRemoved(*Element, *Pad)
|
||||||
|
}); ok {
|
||||||
|
C.setGstElementClassPadRemoved(elemClass)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := elem.(interface {
|
||||||
|
PostMessage(*Element, *Message) bool
|
||||||
|
}); ok {
|
||||||
|
C.setGstElementClassPostMessage(elemClass)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := elem.(interface {
|
||||||
|
ProvideClock(*Element) *Clock
|
||||||
|
}); ok {
|
||||||
|
C.setGstElementClassProvideClock(elemClass)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := elem.(interface {
|
||||||
|
Query(*Element, *Query) bool
|
||||||
|
}); ok {
|
||||||
|
C.setGstElementClassQuery(elemClass)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := elem.(interface {
|
||||||
|
ReleasePad(*Element, *Pad)
|
||||||
|
}); ok {
|
||||||
|
C.setGstElementClassReleasePad(elemClass)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := elem.(interface {
|
||||||
|
RequestNewPad(self *Element, templ *PadTemplate, name string, caps *Caps) *Pad
|
||||||
|
}); ok {
|
||||||
|
C.setGstElementClassRequestNewPad(elemClass)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := elem.(interface {
|
||||||
|
SendEvent(*Element, *Event) bool
|
||||||
|
}); ok {
|
||||||
|
C.setGstElementClassSendEvent(elemClass)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := elem.(interface {
|
||||||
|
SetBus(*Element, *Bus)
|
||||||
|
}); ok {
|
||||||
|
C.setGstElementClassSetBus(elemClass)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := elem.(interface {
|
||||||
|
SetClock(*Element, *Clock) bool
|
||||||
|
}); ok {
|
||||||
|
C.setGstElementClassSetClock(elemClass)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := elem.(interface {
|
||||||
|
SetContext(*Element, *Context)
|
||||||
|
}); ok {
|
||||||
|
C.setGstElementClassSetContext(elemClass)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := elem.(interface {
|
||||||
|
SetState(*Element, State) StateChangeReturn
|
||||||
|
}); ok {
|
||||||
|
C.setGstElementClassSetState(elemClass)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := elem.(interface {
|
||||||
|
StateChanged(self *Element, old, new, pending State)
|
||||||
|
}); ok {
|
||||||
|
C.setGstElementClassStateChanged(elemClass)
|
||||||
|
}
|
||||||
|
}
|
@@ -72,11 +72,11 @@ func (m *Message) String() string {
|
|||||||
|
|
||||||
case MessageStructureChange:
|
case MessageStructureChange:
|
||||||
chgType, elem, busy := m.ParseStructureChange()
|
chgType, elem, busy := m.ParseStructureChange()
|
||||||
msg += fmt.Sprintf("Structure change of type %s from %s. (in progress: %v)", chgType.String(), elem.Name(), busy)
|
msg += fmt.Sprintf("Structure change of type %s from %s. (in progress: %v)", chgType.String(), elem.GetName(), busy)
|
||||||
|
|
||||||
case MessageStreamStatus:
|
case MessageStreamStatus:
|
||||||
statusType, elem := m.ParseStreamStatus()
|
statusType, elem := m.ParseStreamStatus()
|
||||||
msg += fmt.Sprintf("Stream status from %s: %s", elem.Name(), statusType.String())
|
msg += fmt.Sprintf("Stream status from %s: %s", elem.GetName(), statusType.String())
|
||||||
|
|
||||||
case MessageApplication:
|
case MessageApplication:
|
||||||
msg += "Message posted by the application, possibly via an application-specific element."
|
msg += "Message posted by the application, possibly via an application-specific element."
|
||||||
@@ -165,7 +165,7 @@ func (m *Message) String() string {
|
|||||||
if obj != nil && propVal != nil {
|
if obj != nil && propVal != nil {
|
||||||
goval, err := propVal.GoValue()
|
goval, err := propVal.GoValue()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
msg += fmt.Sprintf("Object %s had property '%s' changed to %+v", obj.Name(), propName, goval)
|
msg += fmt.Sprintf("Object %s had property '%s' changed to %+v", obj.GetName(), propName, goval)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -4,6 +4,7 @@ package gst
|
|||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"time"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/tinyzimmer/go-glib/glib"
|
"github.com/tinyzimmer/go-glib/glib"
|
||||||
@@ -14,70 +15,36 @@ type Object struct{ *glib.InitiallyUnowned }
|
|||||||
|
|
||||||
// FromGstObjectUnsafe returns an Object wrapping the given pointer. It meant for internal
|
// FromGstObjectUnsafe returns an Object wrapping the given pointer. It meant for internal
|
||||||
// usage and exported for visibility to other packages.
|
// usage and exported for visibility to other packages.
|
||||||
func FromGstObjectUnsafe(ptr unsafe.Pointer) *Object {
|
func FromGstObjectUnsafe(ptr unsafe.Pointer) *Object { return wrapObject(toGObject(ptr)) }
|
||||||
return wrapObject(toGObject(ptr))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unsafe returns the unsafe pointer to the underlying object. This method is primarily
|
|
||||||
// for internal usage and is exposed for visibility in other packages.
|
|
||||||
func (o *Object) Unsafe() unsafe.Pointer {
|
|
||||||
if o == nil || o.GObject == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return unsafe.Pointer(o.GObject)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Instance returns the native C GstObject.
|
// Instance returns the native C GstObject.
|
||||||
func (o *Object) Instance() *C.GstObject { return C.toGstObject(o.Unsafe()) }
|
func (o *Object) Instance() *C.GstObject { return C.toGstObject(o.Unsafe()) }
|
||||||
|
|
||||||
// BaseObject returns this object for embedding structs.
|
// BaseObject is a convenience method for retrieving this object from embedded structs.
|
||||||
func (o *Object) BaseObject() *Object { return o }
|
func (o *Object) BaseObject() *Object { return o }
|
||||||
|
|
||||||
// GstObject is an alias to Instance on the underlying GstObject of any extending struct.
|
// GstObject is an alias to Instance on the underlying GstObject of any extending struct.
|
||||||
func (o *Object) GstObject() *C.GstObject { return C.toGstObject(o.Unsafe()) }
|
func (o *Object) GstObject() *C.GstObject { return C.toGstObject(o.Unsafe()) }
|
||||||
|
|
||||||
// Class returns the GObjectClass of this instance.
|
// GObject returns the underlying GObject instance.
|
||||||
func (o *Object) Class() *C.GObjectClass { return C.getGObjectClass(o.Unsafe()) }
|
func (o *Object) GObject() *glib.Object { return o.InitiallyUnowned.Object }
|
||||||
|
|
||||||
// Name returns the name of this object.
|
// GetName returns the name of this object.
|
||||||
func (o *Object) Name() string {
|
func (o *Object) GetName() string {
|
||||||
cName := C.gst_object_get_name((*C.GstObject)(o.Instance()))
|
cName := C.gst_object_get_name((*C.GstObject)(o.Instance()))
|
||||||
defer C.free(unsafe.Pointer(cName))
|
defer C.free(unsafe.Pointer(cName))
|
||||||
return C.GoString(cName)
|
return C.GoString(cName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interfaces returns the interfaces associated with this object.
|
// GetValue retrieves the value for the given controlled property at the given timestamp.
|
||||||
func (o *Object) Interfaces() []string {
|
func (o *Object) GetValue(property string, timestamp time.Duration) *glib.Value {
|
||||||
var size C.guint
|
cprop := C.CString(property)
|
||||||
ifaces := C.g_type_interfaces(C.gsize(o.TypeFromInstance()), &size)
|
defer C.free(unsafe.Pointer(cprop))
|
||||||
if int(size) == 0 {
|
gval := C.gst_object_get_value(o.Instance(), (*C.gchar)(cprop), C.GstClockTime(timestamp.Nanoseconds()))
|
||||||
|
if gval == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
defer C.g_free((C.gpointer)(ifaces))
|
return glib.ValueFromNative(unsafe.Pointer(gval))
|
||||||
out := make([]string, int(size))
|
|
||||||
for _, t := range (*[1 << 30]int)(unsafe.Pointer(ifaces))[:size:size] {
|
|
||||||
out = append(out, glib.Type(t).Name())
|
|
||||||
}
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListProperties returns a list of the properties associated with this object.
|
|
||||||
// The default values assumed in the parameter spec reflect the values currently
|
|
||||||
// set in this object, or their defaults.
|
|
||||||
//
|
|
||||||
// Unref after usage.
|
|
||||||
func (o *Object) ListProperties() []*glib.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([]*glib.ParamSpec, 0)
|
|
||||||
for _, prop := range (*[1 << 30]*C.GParamSpec)(unsafe.Pointer(props))[:size:size] {
|
|
||||||
out = append(out, glib.ToParamSpec(unsafe.Pointer(prop)))
|
|
||||||
}
|
|
||||||
return out
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log logs a message to the given category from this object using the currently registered
|
// Log logs a message to the given category from this object using the currently registered
|
||||||
@@ -85,3 +52,25 @@ func (o *Object) ListProperties() []*glib.ParamSpec {
|
|||||||
func (o *Object) Log(cat *DebugCategory, level DebugLevel, message string) {
|
func (o *Object) Log(cat *DebugCategory, level DebugLevel, message string) {
|
||||||
cat.logDepth(level, message, 2, (*C.GObject)(o.Unsafe()))
|
cat.logDepth(level, message, 2, (*C.GObject)(o.Unsafe()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clear will will clear all references to this object. If the reference is already null
|
||||||
|
// the the function does nothing. Otherwise the reference count is decreased and the pointer
|
||||||
|
// set to null.
|
||||||
|
func (o *Object) Clear() {
|
||||||
|
if ptr := o.Unsafe(); ptr != nil {
|
||||||
|
C.gst_clear_object((**C.GstObject)(unsafe.Pointer(&ptr)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ref increments the reference count on object. This function does not take the lock on object
|
||||||
|
// because it relies on atomic refcounting. For convenience the same object is returned.
|
||||||
|
func (o *Object) Ref() *Object {
|
||||||
|
C.gst_object_ref((C.gpointer)(o.Unsafe()))
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unref decrements the reference count on object. If reference count hits zero, destroy object.
|
||||||
|
// This function does not take the lock on object as it relies on atomic refcounting.
|
||||||
|
func (o *Object) Unref() {
|
||||||
|
C.gst_object_unref((C.gpointer)(o.Unsafe()))
|
||||||
|
}
|
||||||
|
@@ -9,8 +9,15 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// InterfaceTagSetter represents the GstTagsetter interface GType. Use this when querying bins
|
// InterfaceTagSetter represents the GstTagsetter interface GType. Use this when querying bins
|
||||||
// for elements that implement a TagSetter.
|
// for elements that implement a TagSetter. Extending this interface is not yet implemented.
|
||||||
var InterfaceTagSetter = glib.Type(C.GST_TYPE_TAG_SETTER)
|
var InterfaceTagSetter glib.Interface = &interfaceTagSetter{}
|
||||||
|
|
||||||
|
type interfaceTagSetter struct{}
|
||||||
|
|
||||||
|
func (i *interfaceTagSetter) Type() glib.Type { return glib.Type(C.GST_TYPE_TAG_SETTER) }
|
||||||
|
func (i *interfaceTagSetter) InitFunc() glib.InterfaceInitFunc {
|
||||||
|
return func(instance *glib.TypeInstance) {}
|
||||||
|
}
|
||||||
|
|
||||||
// TagSetter is an interface that elements can implement to provide Tag writing capabilities.
|
// TagSetter is an interface that elements can implement to provide Tag writing capabilities.
|
||||||
type TagSetter interface {
|
type TagSetter interface {
|
||||||
|
@@ -27,21 +27,18 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// InterfaceURIHandler represents the GstURIHandler interface GType. Use this when querying bins
|
// InterfaceURIHandler represents the GstURIHandler interface GType. Use this when querying bins
|
||||||
// for elements that implement a URIHandler, or when signaling that a GoElement provides this
|
// for elements that implement a URIHandler, or when signaling that a GoObjectSubclass provides this
|
||||||
// interface.
|
// interface. Note that the way this interface is implemented, it can only be used once per plugin.
|
||||||
var InterfaceURIHandler glib.Interface = &interfaceURIHandler{}
|
var InterfaceURIHandler glib.Interface = &interfaceURIHandler{}
|
||||||
|
|
||||||
type interfaceURIHandler struct {
|
type interfaceURIHandler struct{ glib.Interface }
|
||||||
glib.Interface
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i *interfaceURIHandler) Type() glib.Type {
|
func (i *interfaceURIHandler) Type() glib.Type { return glib.Type(C.GST_TYPE_URI_HANDLER) }
|
||||||
return glib.Type(C.GST_TYPE_URI_HANDLER)
|
func (i *interfaceURIHandler) InitFunc() glib.InterfaceInitFunc {
|
||||||
}
|
return func(instance *glib.TypeInstance) {
|
||||||
|
globalURIHdlr = instance.GoType.(URIHandler)
|
||||||
func (i *interfaceURIHandler) InitFunc(t *glib.TypeInstance) unsafe.Pointer {
|
C.uriHandlerInit((C.gpointer)(instance.GTypeInstance), nil)
|
||||||
globalURIHdlr = t.GoType.(URIHandler)
|
}
|
||||||
return unsafe.Pointer(C.uriHandlerInit)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// URIHandler represents an interface that elements can implement to provide URI handling
|
// URIHandler represents an interface that elements can implement to provide URI handling
|
||||||
|
Reference in New Issue
Block a user