mirror of
https://github.com/go-gst/go-gst.git
synced 2025-10-04 23:52:55 +08:00
145 lines
3.8 KiB
Go
145 lines
3.8 KiB
Go
package gst
|
|
|
|
/*
|
|
#include "gst.go.h"
|
|
|
|
extern gboolean structForEachCb (GQuark field_id, GValue * value, gpointer user_data);
|
|
|
|
gboolean structureForEach (GQuark field_id, GValue * value, gpointer user_data)
|
|
{
|
|
return structForEachCb(field_id, value, user_data);
|
|
}
|
|
*/
|
|
import "C"
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
"unsafe"
|
|
|
|
"github.com/gotk3/gotk3/glib"
|
|
gopointer "github.com/mattn/go-pointer"
|
|
)
|
|
|
|
// Structure is a go implementation of a C GstStructure.
|
|
type Structure struct {
|
|
ptr unsafe.Pointer
|
|
gType glib.Type
|
|
}
|
|
|
|
// NewStructure returns a new empty structure with the given name.
|
|
func NewStructure(name string) *Structure {
|
|
cName := C.CString(name)
|
|
defer C.free(unsafe.Pointer(cName))
|
|
structure := C.gst_structure_new_empty(cName)
|
|
return wrapStructure(structure)
|
|
}
|
|
|
|
// NewStructureFromString builds a new GstStructure from the given string.
|
|
func NewStructureFromString(stStr string) *Structure {
|
|
cStr := C.CString(stStr)
|
|
defer C.free(unsafe.Pointer(cStr))
|
|
structure := C.gst_structure_from_string(cStr, nil)
|
|
if structure == nil {
|
|
return nil
|
|
}
|
|
return wrapStructure(structure)
|
|
}
|
|
|
|
// StructureFromGValue extracts the GstStructure from a glib.Value, or nil
|
|
// if one does not exist.
|
|
func StructureFromGValue(gval *glib.Value) *Structure {
|
|
st := C.gst_value_get_structure((*C.GValue)(gval.Native()))
|
|
if st == nil {
|
|
return nil
|
|
}
|
|
return wrapStructure(st)
|
|
}
|
|
|
|
// Instance returns the native GstStructure instance.
|
|
func (s *Structure) Instance() *C.GstStructure { return C.toGstStructure(s.ptr) }
|
|
|
|
// Free frees the memory for the underlying GstStructure.
|
|
func (s *Structure) Free() { C.gst_structure_free(s.Instance()) }
|
|
|
|
// String implement a stringer on a GstStructure.
|
|
func (s *Structure) String() string {
|
|
str := C.gst_structure_to_string(s.Instance())
|
|
defer C.g_free((C.gpointer)(str))
|
|
return C.GoString(str)
|
|
}
|
|
|
|
// Name returns the name of this structure.
|
|
func (s *Structure) Name() string {
|
|
return C.GoString(C.gst_structure_get_name(s.Instance()))
|
|
}
|
|
|
|
// Size returns the number of fields inside this structure.
|
|
func (s *Structure) Size() int {
|
|
return int(C.gst_structure_n_fields(s.Instance()))
|
|
}
|
|
|
|
// SetValue sets the data at key to the given value.
|
|
func (s *Structure) SetValue(key string, value interface{}) error {
|
|
gVal, err := glib.GValue(value)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
cKey := C.CString(key)
|
|
defer C.free(unsafe.Pointer(cKey))
|
|
C.gst_structure_set_value(s.Instance(), cKey, (*C.GValue)(gVal.GetPointer()))
|
|
return nil
|
|
}
|
|
|
|
// GetValue retrieves the value at key.
|
|
func (s *Structure) GetValue(key string) (interface{}, error) {
|
|
cKey := C.CString(key)
|
|
defer C.free(unsafe.Pointer(cKey))
|
|
gVal := C.gst_structure_get_value(s.Instance(), cKey)
|
|
if gVal == nil {
|
|
return nil, fmt.Errorf("No value exists at %s", key)
|
|
}
|
|
return glib.ValueFromNative(unsafe.Pointer(gVal)).GoValue()
|
|
}
|
|
|
|
// RemoveValue removes the value at the given key. If the key does not exist,
|
|
// the structure is unchanged.
|
|
func (s *Structure) RemoveValue(key string) {
|
|
cKey := C.CString(key)
|
|
defer C.free(unsafe.Pointer(cKey))
|
|
C.gst_structure_remove_field(s.Instance(), cKey)
|
|
}
|
|
|
|
// Values returns a map of all the values inside this structure. If values cannot be
|
|
// converted to an equivalent go type, they are serialized to a string.
|
|
func (s *Structure) Values() map[string]interface{} {
|
|
out := make(map[string]interface{})
|
|
resCh := make(chan interface{})
|
|
chPtr := gopointer.Save(resCh)
|
|
defer gopointer.Unref(chPtr)
|
|
|
|
var wg sync.WaitGroup
|
|
wg.Add(1)
|
|
go func() {
|
|
defer wg.Done()
|
|
for i := 0; i < s.Size(); i++ {
|
|
nameIface := <-resCh
|
|
valIface := <-resCh
|
|
fieldName := nameIface.(string)
|
|
out[fieldName] = valIface
|
|
}
|
|
}()
|
|
|
|
C.gst_structure_foreach(s.Instance(), C.GstStructureForeachFunc(C.structureForEach), (C.gpointer)(unsafe.Pointer(chPtr)))
|
|
wg.Wait()
|
|
|
|
return out
|
|
}
|
|
|
|
func wrapStructure(st *C.GstStructure) *Structure {
|
|
return &Structure{
|
|
ptr: unsafe.Pointer(st),
|
|
gType: glib.Type(st._type),
|
|
}
|
|
}
|