diff --git a/bin.go b/bin.go index cd71797..21c51ce 100644 --- a/bin.go +++ b/bin.go @@ -19,8 +19,8 @@ type Bin struct { func ParseBinFromDescription(binStr string, ghostPads bool) (bin *Bin, err error) { var gError *C.GError - pDesc := (*C.gchar)(unsafe.Pointer(C.CString(binStr))) - defer C.g_free(C.gpointer(unsafe.Pointer(pDesc))) + pDesc := C.CString(binStr) + defer C.free(unsafe.Pointer(pDesc)) var ghost int if ghostPads { @@ -29,7 +29,7 @@ func ParseBinFromDescription(binStr string, ghostPads bool) (bin *Bin, err error ghost = 0 } - gstElt := C.gst_parse_bin_from_description(pDesc, C.int(ghost), &gError) + gstElt := C.gst_parse_bin_from_description((*C.gchar)(pDesc), C.int(ghost), &gError) if gError != nil { err = errors.New("create bin error") @@ -48,10 +48,10 @@ func ParseBinFromDescription(binStr string, ghostPads bool) (bin *Bin, err error func BinNew(name string) (bin *Bin) { - pName := (*C.gchar)(unsafe.Pointer(C.CString(name))) - defer C.g_free(C.gpointer(unsafe.Pointer(pName))) + pName := C.CString(name) + defer C.free(unsafe.Pointer(pName)) - Celement := C.gst_bin_new(pName) + Celement := C.gst_bin_new((*C.gchar)(pName)) bin = &Bin{} bin.GstElement = Celement @@ -87,9 +87,9 @@ func (b *Bin) AddMany(elements ...*Element) { func (b *Bin) GetByName(name string) (element *Element) { - n := (*C.gchar)(unsafe.Pointer(C.CString(name))) - defer C.g_free(C.gpointer(unsafe.Pointer(n))) - CElement := C.X_gst_bin_get_by_name(b.GstElement, n) + n := C.CString(name) + defer C.free(unsafe.Pointer(n)) + CElement := C.X_gst_bin_get_by_name(b.GstElement, (*C.gchar)(n)) if CElement == nil { return diff --git a/bus.go b/bus.go index 8448cf8..4a08900 100644 --- a/bus.go +++ b/bus.go @@ -30,7 +30,7 @@ func (b *Bus) Pop() (message *Message) { } func (b *Bus) PopTimed() (message *Message, err error) { - var timeNone int64 = C.GST_CLOCK_TIME_NONE + var timeNone uint64 = C.GST_CLOCK_TIME_NONE CGstMessage := C.gst_bus_timed_pop(b.C, C.ulonglong(timeNone)) if CGstMessage == nil { diff --git a/caps.go b/caps.go index 2fb980f..243c104 100644 --- a/caps.go +++ b/caps.go @@ -16,9 +16,9 @@ type Caps struct { } func CapsFromString(caps string) (gstCaps *Caps) { - c := (*C.gchar)(unsafe.Pointer(C.CString(caps))) - defer C.g_free(C.gpointer(unsafe.Pointer(c))) - CCaps := C.gst_caps_from_string(c) + c := C.CString(caps) + defer C.free(unsafe.Pointer(c)) + CCaps := C.gst_caps_from_string((*C.gchar)(c)) gstCaps = &Caps{ caps: CCaps, } diff --git a/element.go b/element.go index ce36498..1b5f781 100644 --- a/element.go +++ b/element.go @@ -78,9 +78,9 @@ func (e *Element) Name() (name string) { } func (e *Element) DumpDot(filePath string) { - n := (*C.gchar)(unsafe.Pointer(C.CString(filePath))) - defer C.g_free(C.gpointer(unsafe.Pointer(n))) - C.X_GST_DEBUG_BIN_TO_DOT_FILE(e.GstElement, n) + n := C.CString(filePath) + defer C.free(unsafe.Pointer(n)) + C.X_GST_DEBUG_BIN_TO_DOT_FILE(e.GstElement, (*C.gchar)(n)) } func (e *Element) Link(dst *Element) bool { @@ -94,9 +94,9 @@ func (e *Element) Link(dst *Element) bool { func (e *Element) GetPadTemplate(name string) (padTemplate *PadTemplate) { - n := (*C.gchar)(unsafe.Pointer(C.CString(name))) - defer C.g_free(C.gpointer(unsafe.Pointer(n))) - CPadTemplate := C.gst_element_class_get_pad_template(C.X_GST_ELEMENT_GET_CLASS(e.GstElement), n) + n := C.CString(name) + defer C.free(unsafe.Pointer(n)) + CPadTemplate := C.gst_element_class_get_pad_template(C.X_GST_ELEMENT_GET_CLASS(e.GstElement), (*C.gchar)(n)) padTemplate = &PadTemplate{ C: CPadTemplate, } @@ -112,15 +112,15 @@ func (e *Element) GetRequestPad(padTemplate *PadTemplate, name string, caps *Cap if name == "" { n = nil } else { - n = (*C.gchar)(unsafe.Pointer(C.CString(name))) - defer C.g_free(C.gpointer(unsafe.Pointer(n))) + n = C.CString(name) + defer C.free(unsafe.Pointer(n)) } if caps == nil { c = nil } else { c = caps.caps } - CPad := C.gst_element_request_pad(e.GstElement, padTemplate.C, n, c) + CPad := C.gst_element_request_pad(e.GstElement, padTemplate.C, (*C.gchar)(n), c) pad = &Pad{ pad: CPad, } @@ -130,9 +130,9 @@ func (e *Element) GetRequestPad(padTemplate *PadTemplate, name string, caps *Cap func (e *Element) GetStaticPad(name string) (pad *Pad) { - n := (*C.gchar)(unsafe.Pointer(C.CString(name))) - defer C.g_free(C.gpointer(unsafe.Pointer(n))) - CPad := C.gst_element_get_static_pad(e.GstElement, n) + n := C.CString(name) + defer C.free(unsafe.Pointer(n)) + CPad := C.gst_element_get_static_pad(e.GstElement, (*C.gchar)(n)) pad = &Pad{ pad: CPad, } @@ -285,17 +285,17 @@ func (e *Element) IsEOS() bool { func (e *Element) SetObject(name string, value interface{}) { - cname := (*C.gchar)(unsafe.Pointer(C.CString(name))) - defer C.g_free(C.gpointer(unsafe.Pointer(cname))) + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) switch value.(type) { case string: - str := (*C.gchar)(unsafe.Pointer(C.CString(value.(string)))) - defer C.g_free(C.gpointer(unsafe.Pointer(str))) - C.X_gst_g_object_set_string(e.GstElement, cname, str) + str := C.CString(value.(string)) + defer C.free(unsafe.Pointer(str)) + C.X_gst_g_object_set_string(e.GstElement, (*C.gchar)(unsafe.Pointer(cname)), (*C.gchar)(str)) case int: - C.X_gst_g_object_set_int(e.GstElement, cname, C.gint(value.(int))) + C.X_gst_g_object_set_int(e.GstElement, (*C.gchar)(unsafe.Pointer(cname)), C.gint(value.(int))) case uint32: - C.X_gst_g_object_set_uint(e.GstElement, cname, C.guint(value.(uint32))) + C.X_gst_g_object_set_uint(e.GstElement, (*C.gchar)(unsafe.Pointer(cname)), C.guint(value.(uint32))) case bool: var cvalue int if value.(bool) == true { @@ -303,18 +303,18 @@ func (e *Element) SetObject(name string, value interface{}) { } else { cvalue = 0 } - C.X_gst_g_object_set_bool(e.GstElement, cname, C.gboolean(cvalue)) + C.X_gst_g_object_set_bool(e.GstElement, (*C.gchar)(unsafe.Pointer(cname)), C.gboolean(cvalue)) case float64: - C.X_gst_g_object_set_gdouble(e.GstElement, cname, C.gdouble(value.(float64))) + C.X_gst_g_object_set_gdouble(e.GstElement, (*C.gchar)(unsafe.Pointer(cname)), C.gdouble(value.(float64))) case *Caps: caps := value.(*Caps) - C.X_gst_g_object_set_caps(e.GstElement, cname, caps.caps) + C.X_gst_g_object_set_caps(e.GstElement, (*C.gchar)(unsafe.Pointer(cname)), caps.caps) case *Structure: structure := value.(*Structure) - C.X_gst_g_object_set_structure(e.GstElement, cname, structure.C) + C.X_gst_g_object_set_structure(e.GstElement, (*C.gchar)(unsafe.Pointer(cname)), structure.C) case *Element: element := value.(*Element) - C.X_gst_g_object_set_element(e.GstElement, cname, element.GstElement) + C.X_gst_g_object_set_element(e.GstElement, (*C.gchar)(unsafe.Pointer(cname)), element.GstElement) default: panic(fmt.Errorf("SetObject: don't know how to set value for type %T", value)) @@ -420,15 +420,15 @@ func (e *Element) SetPadAddedCallback(callback PadAddedCallback) { func ElementFactoryMake(factoryName string, name string) (e *Element, err error) { var pName *C.gchar - pFactoryName := (*C.gchar)(unsafe.Pointer(C.CString(factoryName))) - defer C.g_free(C.gpointer(unsafe.Pointer(pFactoryName))) + pFactoryName := C.CString(factoryName) + defer C.free(unsafe.Pointer(pFactoryName)) if name == "" { pName = nil } else { - pName = (*C.gchar)(unsafe.Pointer(C.CString(name))) - defer C.g_free(C.gpointer(unsafe.Pointer(pName))) + pName = C.CString(name) + defer C.free(unsafe.Pointer(pName)) } - gstElt := C.gst_element_factory_make(pFactoryName, pName) + gstElt := C.gst_element_factory_make((*C.gchar)(pFactoryName), (*C.gchar)(pName)) if gstElt == nil { err = errors.New(fmt.Sprintf("could not create a GStreamer element factoryName %s, name %s", factoryName, name)) diff --git a/element_other.go b/element_other.go index d625b96..75e52eb 100644 --- a/element_other.go +++ b/element_other.go @@ -1,5 +1,5 @@ -//go:build !arm && !arm64 -// +build !arm,!arm64 +//go:build !arm && !arm64 && !windows +// +build !arm,!arm64,!windows package gst diff --git a/element_windows.go b/element_windows.go new file mode 100644 index 0000000..682b798 --- /dev/null +++ b/element_windows.go @@ -0,0 +1,13 @@ +package gst + +/* +#cgo pkg-config: gstreamer-1.0 gstreamer-app-1.0 +#include "gst.h" +*/ +import "C" +import "time" + +func (e *Element) Seek(duration time.Duration) bool { + result := C.gst_element_seek_simple(e.GstElement, C.GST_FORMAT_TIME, C.GST_SEEK_FLAG_FLUSH, C.gint64(duration.Nanoseconds())) + return result == C.TRUE +} diff --git a/example/main.go b/example/main.go new file mode 100644 index 0000000..813dcb9 --- /dev/null +++ b/example/main.go @@ -0,0 +1,55 @@ +package main + +import ( + "fmt" + "github.com/notedit/gst" + "time" +) + +func testGST() { + println(1) + pipeline, err := gst.ParseLaunch("appsrc name=mysource format=time is-live=true do-timestamp=true ! videoconvert ! autovideosink") + println(2) + if err != nil { + panic("pipeline error") + } + println(3) + videoCap := gst.CapsFromString("video/x-raw,format=RGB,width=320,height=240,bpp=24,depth=24") + println(4) + element := pipeline.GetByName("mysource") + println(5) + element.SetObject("caps", videoCap) + println(6) + pipeline.SetState(gst.StatePlaying) + println(7) + i := 0 + for { + + if i > 100 { + break + } + + data := make([]byte, 320*240*3) + + err := element.PushBuffer(data) + + if err != nil { + fmt.Println("push buffer error") + break + } + + fmt.Println("push one") + i++ + time.Sleep(50000000) + } + + pipeline.SetState(gst.StateNull) + + pipeline = nil + element = nil + videoCap = nil +} +func main() { + + testGST() +} diff --git a/go.sum b/go.sum index e69de29..a97148f 100644 --- a/go.sum +++ b/go.sum @@ -0,0 +1,2 @@ +github.com/notedit/gst v0.1.3 h1:Z5q274M3TJst3w+iAdZLIoIhzp7QiwYdH98Vik+f89g= +github.com/notedit/gst v0.1.3/go.mod h1:99yZ0oIrCg0xd2a1rn/1cjcUAHLAGTDxXLD1FQ5NpoM= diff --git a/gst.c b/gst.c index 67102dc..bcfeffa 100644 --- a/gst.c +++ b/gst.c @@ -4,10 +4,13 @@ #include "gst.h" void X_gst_shim_init() { + + gchar *nano_str; guint major, minor, micro, nano; fprintf(stderr, "[ GSTREAMER ] shim init\n"); + gst_init(0, NULL); gst_version (&major, &minor, µ, &nano); @@ -244,9 +247,8 @@ void X_gst_pipeline_set_latency(GstElement* element, GstClockTime clockTime) { GstFlowReturn X_gst_app_src_push_buffer(GstElement* element, void *buffer,int len) { - - gpointer p = g_memdup2(buffer, len); - GstBuffer *data = gst_buffer_new_wrapped(p, len); + GstBuffer *data = gst_buffer_new_memdup(buffer, len); + //GstBuffer *data = gst_buffer_new_wrapped(p, len); return gst_app_src_push_buffer(GST_APP_SRC(element), data); } diff --git a/pad.go b/pad.go index 2382295..bc65be5 100644 --- a/pad.go +++ b/pad.go @@ -96,17 +96,17 @@ func (p *Pad) IsLinked() bool { func (e *Pad) SetObject(name string, value interface{}) { - cname := (*C.gchar)(unsafe.Pointer(C.CString(name))) - defer C.g_free(C.gpointer(unsafe.Pointer(cname))) + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) switch value.(type) { case string: - str := (*C.gchar)(unsafe.Pointer(C.CString(value.(string)))) - defer C.g_free(C.gpointer(unsafe.Pointer(str))) - C.X_gst_g_pad_set_string(e.pad, cname, str) + str := C.CString(value.(string)) + defer C.free(unsafe.Pointer(str)) + C.X_gst_g_pad_set_string(e.pad, (*C.gchar)(cname), (*C.gchar)(str)) case int: - C.X_gst_g_pad_set_int(e.pad, cname, C.gint(value.(int))) + C.X_gst_g_pad_set_int(e.pad, (*C.gchar)(cname), C.gint(value.(int))) case uint32: - C.X_gst_g_pad_set_uint(e.pad, cname, C.guint(value.(uint32))) + C.X_gst_g_pad_set_uint(e.pad, (*C.gchar)(cname), C.guint(value.(uint32))) case bool: var cvalue int if value.(bool) == true { @@ -114,15 +114,15 @@ func (e *Pad) SetObject(name string, value interface{}) { } else { cvalue = 0 } - C.X_gst_g_pad_set_bool(e.pad, cname, C.gboolean(cvalue)) + C.X_gst_g_pad_set_bool(e.pad, (*C.gchar)(cname), C.gboolean(cvalue)) case float64: - C.X_gst_g_pad_set_gdouble(e.pad, cname, C.gdouble(value.(float64))) + C.X_gst_g_pad_set_gdouble(e.pad, (*C.gchar)(cname), C.gdouble(value.(float64))) case *Caps: caps := value.(*Caps) - C.X_gst_g_pad_set_caps(e.pad, cname, caps.caps) + C.X_gst_g_pad_set_caps(e.pad, (*C.gchar)(cname), caps.caps) case *Structure: structure := value.(*Structure) - C.X_gst_g_pad_set_structure(e.pad, cname, structure.C) + C.X_gst_g_pad_set_structure(e.pad, (*C.gchar)(cname), structure.C) default: panic(fmt.Errorf("SetObject: don't know how to set value for type %T", value)) } diff --git a/pipeline.go b/pipeline.go index 8532317..8e9ce0d 100644 --- a/pipeline.go +++ b/pipeline.go @@ -25,25 +25,20 @@ type Pipeline struct { func ParseLaunch(pipelineStr string) (p *Pipeline, err error) { var gError *C.GError - pDesc := (*C.gchar)(unsafe.Pointer(C.CString(pipelineStr))) - defer C.g_free(C.gpointer(unsafe.Pointer(pDesc))) - - gstElt := C.gst_parse_launch(pDesc, &gError) + pDesc := C.CString(pipelineStr) + defer C.free(unsafe.Pointer(pDesc)) + gstElt := C.gst_parse_launch((*C.gchar)(pDesc), &gError) if gError != nil { err = errors.New(C.GoString(C.ErrorMessage(gError))) return } - p = &Pipeline{} p.GstElement = gstElt - C.X_gst_pipeline_use_clock_real(p.GstElement) - runtime.SetFinalizer(p, func(p *Pipeline) { C.gst_object_unref(C.gpointer(unsafe.Pointer(p.GstElement))) }) - return } @@ -53,11 +48,11 @@ func PipelineNew(name string) (e *Pipeline, err error) { if name == "" { pName = nil } else { - pName := (*C.gchar)(unsafe.Pointer(C.CString(name))) - defer C.g_free(C.gpointer(unsafe.Pointer(pName))) + pName := C.CString(name) + defer C.free(unsafe.Pointer(pName)) } - gstElt := C.gst_pipeline_new(pName) + gstElt := C.gst_pipeline_new((*C.gchar)(pName)) if gstElt == nil { err = errors.New(fmt.Sprintf("could not create a Gstreamer pipeline name %s", name)) return diff --git a/structure.go b/structure.go index f95ad0b..79c580f 100644 --- a/structure.go +++ b/structure.go @@ -94,17 +94,17 @@ func (s *Structure) GetString(name string) (string, error) { func (s *Structure) SetValue(name string, value interface{}) { - CName := (*C.gchar)(unsafe.Pointer(C.CString(name))) - defer C.g_free(C.gpointer(unsafe.Pointer(CName))) + CName := C.CString(name) + defer C.free(unsafe.Pointer(CName)) switch value.(type) { case string: - str := (*C.gchar)(unsafe.Pointer(C.CString(value.(string)))) - defer C.g_free(C.gpointer(unsafe.Pointer(str))) - C.X_gst_structure_set_string(s.C, CName, str) + str := C.CString(value.(string)) + defer C.free(unsafe.Pointer(str)) + C.X_gst_structure_set_string(s.C, (*C.gchar)(CName), (*C.gchar)(str)) case int: - C.X_gst_structure_set_int(s.C, CName, C.gint(value.(int))) + C.X_gst_structure_set_int(s.C, (*C.gchar)(CName), C.gint(value.(int))) case uint32: - C.X_gst_structure_set_uint(s.C, CName, C.guint(value.(uint32))) + C.X_gst_structure_set_uint(s.C, (*C.gchar)(CName), C.guint(value.(uint32))) case bool: var v int if value.(bool) == true { @@ -112,7 +112,7 @@ func (s *Structure) SetValue(name string, value interface{}) { } else { v = 0 } - C.X_gst_structure_set_bool(s.C, CName, C.gboolean(v)) + C.X_gst_structure_set_bool(s.C, (*C.gchar)(CName), C.gboolean(v)) } return