diff --git a/.gitignore b/.gitignore index 3a14734a..b24787dd 100644 --- a/.gitignore +++ b/.gitignore @@ -22,4 +22,5 @@ _bin/ _rust/ *.DS_Store* *.supp -zzgenerated* \ No newline at end of file +zzgenerated* +.idea/ diff --git a/README.md b/README.md index 0a0d58f5..47683243 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +Deprecated. Use the official [go-gst](https://github.com/go-gst/go-gst) instead. + # go-gst Go bindings for the GStreamer C libraries diff --git a/go.sum b/go.sum index ad14e8f9..c7c7c2d2 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.24 h1:ktZZC22/9t88kGRgNEFV/SESgIWhGHE+q7Z7Qj++luw= -github.com/tinyzimmer/go-glib v0.0.24/go.mod h1:ltV0gO6xNFzZhsIRbFXv8RTq9NGoNT2dmAER4YmZfaM= +github.com/tinyzimmer/go-glib v0.0.25 h1:2GpumtkxA0wpXhCXP6D3ksb5pGMfo9WbhgLvEw8njK4= +github.com/tinyzimmer/go-glib v0.0.25/go.mod h1:ltV0gO6xNFzZhsIRbFXv8RTq9NGoNT2dmAER4YmZfaM= diff --git a/gst/cgo_exports.go b/gst/cgo_exports.go index 0c735eed..235c3173 100644 --- a/gst/cgo_exports.go +++ b/gst/cgo_exports.go @@ -243,3 +243,34 @@ func goPluginInit(plugin *C.GstPlugin, userData C.gpointer) C.gboolean { func goGlobalPluginInit(plugin *C.GstPlugin) C.gboolean { return gboolean(globalPluginInit(wrapPlugin(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(plugin))}))) } + +//export goLogFunction +func goLogFunction( + category *C.GstDebugCategory, + level C.GstDebugLevel, + file *C.gchar, + function *C.gchar, + line C.gint, + object *C.GObject, + message *C.GstDebugMessage, + userData C.gpointer, +) { + logFnMu.RLock() + f := customLogFunction + logFnMu.RUnlock() + + if f != nil { + var obj *glib.Object + if object != nil { + obj = glib.TransferNone(unsafe.Pointer(object)) + } + f( + DebugLevel(level), + C.GoString(file), + C.GoString(function), + int(line), + obj, + C.GoString(C.gst_debug_message_get(message)), + ) + } +} diff --git a/gst/gst.go.c b/gst/gst.go.c index adc00798..5d139413 100644 --- a/gst/gst.go.c +++ b/gst/gst.go.c @@ -153,6 +153,13 @@ gboolean gstObjectFlagIsSet (GstObject * obj, GstElementFlags flags) GstTocSetter * toTocSetter (GstElement * elem) { return GST_TOC_SETTER(elem); } GstTagSetter * toTagSetter (GstElement *elem) { return GST_TAG_SETTER(elem); } +/* Sample Utilities */ + +GstSample * getSampleValue (GValue * val) +{ + return gst_value_get_sample(val); +} + /* Misc */ diff --git a/gst/gst.go.h b/gst/gst.go.h index 62e4692c..7ae676c5 100644 --- a/gst/gst.go.h +++ b/gst/gst.go.h @@ -132,4 +132,8 @@ extern gpointer glistNext (GList * list); extern int sizeOfGCharArray (gchar ** arr); +/* Sample Utilities */ + +extern GstSample * getSampleValue (GValue * val); + #endif diff --git a/gst/gst_buffer.go b/gst/gst_buffer.go index 15ea9e85..40852920 100644 --- a/gst/gst_buffer.go +++ b/gst/gst_buffer.go @@ -43,6 +43,10 @@ type Buffer struct { // FromGstBufferUnsafeNone wraps the given buffer, sinking any floating references, and places // a finalizer on the wrapped Buffer. func FromGstBufferUnsafeNone(buf unsafe.Pointer) *Buffer { + if buf == nil { + return nil + } + wrapped := ToGstBuffer(buf) wrapped.Ref() runtime.SetFinalizer(wrapped, (*Buffer).Unref) @@ -51,6 +55,10 @@ func FromGstBufferUnsafeNone(buf unsafe.Pointer) *Buffer { // FromGstBufferUnsafeFull wraps the given buffer without taking an additional reference. func FromGstBufferUnsafeFull(buf unsafe.Pointer) *Buffer { + if buf == nil { + return nil + } + wrapped := ToGstBuffer(buf) runtime.SetFinalizer(wrapped, (*Buffer).Unref) return wrapped @@ -120,16 +128,16 @@ func NewBufferFromReader(rdr io.Reader) (*Buffer, error) { // // The prefix/padding must be filled with 0 if flags contains MemoryFlagZeroPrefixed and MemoryFlagZeroPadded respectively. // -// // Example +// // Example // -// buf := gst.NewBufferFull(0, []byte("hello-world"), 1024, 0, 1024, func() { -// fmt.Println("buffer was destroyed") -// }) -// if buf != nil { -// buf.Unref() -// } +// buf := gst.NewBufferFull(0, []byte("hello-world"), 1024, 0, 1024, func() { +// fmt.Println("buffer was destroyed") +// }) +// if buf != nil { +// buf.Unref() +// } // -// // > buffer was destroyed +// // > buffer was destroyed func NewBufferFull(flags MemoryFlags, data []byte, maxSize, offset, size int64, notifyFunc func()) *Buffer { var notifyData unsafe.Pointer var gnotifyFunc C.GDestroyNotify @@ -228,27 +236,26 @@ func (b *Buffer) OffsetEnd() int64 { return int64(b.Instance().offset_end) } // parameters are passed to the MetaInfo's init function, and as such will only work // for MetaInfo objects created from the go runtime. // -// // Example -// -// metaInfo := gst.RegisterMeta(glib.TypeFromName("MyObjectType"), "my-meta", 1024, &gst.MetaInfoCallbackFuncs{ -// InitFunc: func(params interface{}, buffer *gst.Buffer) bool { -// paramStr := params.(string) -// fmt.Println("Buffer initialized with params:", paramStr) -// return true -// }, -// FreeFunc: func(buffer *gst.Buffer) { -// fmt.Println("Buffer was destroyed") -// }, -// }) +// // Example // -// buf := gst.NewEmptyBuffer() -// buf.AddMeta(metaInfo, "hello world") +// metaInfo := gst.RegisterMeta(glib.TypeFromName("MyObjectType"), "my-meta", 1024, &gst.MetaInfoCallbackFuncs{ +// InitFunc: func(params interface{}, buffer *gst.Buffer) bool { +// paramStr := params.(string) +// fmt.Println("Buffer initialized with params:", paramStr) +// return true +// }, +// FreeFunc: func(buffer *gst.Buffer) { +// fmt.Println("Buffer was destroyed") +// }, +// }) // -// buf.Unref() +// buf := gst.NewEmptyBuffer() +// buf.AddMeta(metaInfo, "hello world") // -// // > Buffer initialized with params: hello world -// // > Buffer was destroyed +// buf.Unref() // +// // > Buffer initialized with params: hello world +// // > Buffer was destroyed func (b *Buffer) AddMeta(info *MetaInfo, params interface{}) *Meta { meta := C.gst_buffer_add_meta(b.Instance(), info.Instance(), (C.gpointer)(gopointer.Save(params))) if meta == nil { diff --git a/gst/gst_debug.go b/gst/gst_debug.go index 8c27aae6..e4a5d4ec 100644 --- a/gst/gst_debug.go +++ b/gst/gst_debug.go @@ -3,6 +3,15 @@ package gst /* #include "gst.go.h" +extern void goLogFunction(GstDebugCategory * category, + GstDebugLevel level, + const gchar * file, + const gchar * function, + gint line, + GObject * object, + GstDebugMessage * message, + gpointer user_data) G_GNUC_NO_INSTRUMENT; + void cgoDebugLog (GstDebugCategory * category, GstDebugLevel level, const gchar * file, @@ -14,12 +23,27 @@ void cgoDebugLog (GstDebugCategory * category, gst_debug_log(category, level, file, function, line, object, msg); } +void cgoSetLogFunction() +{ + gst_debug_remove_log_function(gst_debug_log_default); + gst_debug_add_log_function(goLogFunction, NULL, NULL); +} + +void cgoResetLogFunction() +{ + gst_debug_remove_log_function(goLogFunction); + gst_debug_add_log_function(gst_debug_log_default, NULL, NULL); +} + */ import "C" import ( "path" "runtime" + "sync" "unsafe" + + "github.com/tinyzimmer/go-glib/glib" ) // DebugColorFlags are terminal style flags you can use when creating your debugging @@ -164,3 +188,29 @@ func (d *DebugCategory) LogTrace(message string, obj ...*Object) { func (d *DebugCategory) LogMemDump(message string, obj ...*Object) { d.logDepth(LevelMemDump, message, 2, getLogObj(obj...)) } + +type LogFunction func( + level DebugLevel, + file string, + function string, + line int, + object *glib.Object, + message string, +) + +var ( + logFnMu sync.RWMutex + customLogFunction LogFunction +) + +func SetLogFunction(f LogFunction) { + logFnMu.Lock() + defer logFnMu.Unlock() + + if f == nil { + C.cgoResetLogFunction() + } else if customLogFunction == nil { + C.cgoSetLogFunction() + } + customLogFunction = f +} diff --git a/gst/gst_message.go b/gst/gst_message.go index 4d1c4864..0ca127b3 100644 --- a/gst/gst_message.go +++ b/gst/gst_message.go @@ -84,6 +84,8 @@ func (m *Message) GetStructure() *Structure { C.gst_message_parse_info_details((*C.GstMessage)(m.Instance()), (**C.GstStructure)(unsafe.Pointer(&st))) case MessageWarning: C.gst_message_parse_warning_details((*C.GstMessage)(m.Instance()), (**C.GstStructure)(unsafe.Pointer(&st))) + case MessageElement: + st = C.gst_message_get_structure((*C.GstMessage)(m.Instance())) } // if no structure was returned, immediately return nil diff --git a/gst/gst_wrappers.go b/gst/gst_wrappers.go index 316a7dff..f982bb4f 100644 --- a/gst/gst_wrappers.go +++ b/gst/gst_wrappers.go @@ -234,6 +234,10 @@ func registerMarshalers() { T: TypeValueList, F: marshalValueList, }, + { + T: glib.Type(C.gst_sample_get_type()), + F: marshalSample, + }, } glib.RegisterGValueMarshalers(tm) @@ -500,3 +504,8 @@ func marshalQuery(p uintptr) (interface{}, error) { obj := (*C.GstQuery)(unsafe.Pointer(c)) return wrapQuery(obj), nil } + +func marshalSample(p uintptr) (interface{}, error) { + c := C.getSampleValue(toGValue(p)) + return wrapSample(c), nil +}