From 14963830849df4e73d82657a9d14fca04f66c42c Mon Sep 17 00:00:00 2001 From: tinyzimmer <38474291+tinyzimmer@users.noreply.github.com> Date: Thu, 1 Oct 2020 18:53:43 +0300 Subject: [PATCH] add tagsetter and tocsetter interfaces --- .github/workflows/tests.yml | 11 +++--- Makefile | 2 +- gst/gst_element.go | 20 +++++++++++ gst/gst_tag_setter.go | 70 +++++++++++++++++++++++++++++++++++++ gst/gst_toc_setter.go | 34 ++++++++++++++++++ gst/gst_wrappers.go | 10 +++--- 6 files changed, 135 insertions(+), 12 deletions(-) create mode 100644 gst/gst_tag_setter.go create mode 100644 gst/gst_toc_setter.go diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8e6f59a..b57c2b9 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -10,7 +10,7 @@ jobs: setup: name: Tests - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - name: Set up Go 1.15 @@ -35,12 +35,11 @@ jobs: - name: Install gstreamer dependencies run: | - sudo apt-get update && sudo DEBIAN_FRONTEND=noninteractive apt-get install -y libgstreamer1.0-0 libgstreamer1.0-dev libgstreamer-plugins-base1.0-0 libgstreamer-plugins-base1.0-dev pkg-config build-essential + sudo apt-get update && sudo DEBIAN_FRONTEND=noninteractive apt-get install -y \ + libgstreamer1.0-0 libgstreamer1.0-dev \ + libgstreamer-plugins-base1.0-0 libgstreamer-plugins-base1.0-dev \ + pkg-config build-essential - name: Lint all packages run: | CGO_ENABLED=1 make lint - - # - name: Run all unit tests - # run: | - # CGO_ENABLED=1 make test diff --git a/Makefile b/Makefile index 608dfbf..49fefe5 100644 --- a/Makefile +++ b/Makefile @@ -17,4 +17,4 @@ $(GOLANGCI_LINT): ln -s golangci-lint-$(GOLANGCI_VERSION)-$(shell uname | tr A-Z a-z)-amd64/golangci-lint $(GOLANGCI_LINT) lint: $(GOLANGCI_LINT) - $(GOLANGCI_LINT) run -v \ No newline at end of file + $(GOLANGCI_LINT) run -v diff --git a/gst/gst_element.go b/gst/gst_element.go index 03a325d..ad319d6 100644 --- a/gst/gst_element.go +++ b/gst/gst_element.go @@ -168,3 +168,23 @@ func (e *Element) GetURIProtocols() []string { size := C.sizeOfGCharArray(protocols) return goStrings(size, protocols) } + +// TOCSetter returns a TOCSetter interface if implemented by this element. Otherwise it +// returns nil. Currently this only supports elements built through this package, however, +// inner application elements could still use the interface as a reference implementation. +func (e *Element) TOCSetter() TOCSetter { + if C.toTocSetter(e.Instance()) == nil { + return nil + } + return &gstTOCSetter{ptr: e.Instance()} +} + +// TagSetter returns a TagSetter interface if implemented by this element. Otherwise it returns nil. +// This currently only supports elements built through this package's bindings, however, inner application +// elements can still implement the interface themselves if they want. +func (e *Element) TagSetter() TagSetter { + if C.toTagSetter(e.Instance()) == nil { + return nil + } + return &gstTagSetter{ptr: e.Instance()} +} diff --git a/gst/gst_tag_setter.go b/gst/gst_tag_setter.go new file mode 100644 index 0000000..31e20a6 --- /dev/null +++ b/gst/gst_tag_setter.go @@ -0,0 +1,70 @@ +package gst + +// #include "gst.go.h" +import "C" +import ( + "unsafe" + + "github.com/gotk3/gotk3/glib" +) + +// TagSetter is an interface that elements can implement to provide Tag writing capabilities. +type TagSetter interface { + // Returns the current list of tags the setter uses. The list should not be modified or freed. + GetTagList() *TagList + // Adds the given tag/value pair using the given merge mode. + // TODO: Either an additional function or this one should be modified to accept go types. + AddTagValue(mergeMode TagMergeMode, tagKey string, tagValue *glib.Value) + // Merges a tag list with the given merge mode + MergeTags(*TagList, TagMergeMode) + // Resets the internal tag list. Elements should call this from within the state-change handler. + ResetTags() + // Queries the mode by which tags inside the setter are overwritten by tags from events + GetTagMergeMode() TagMergeMode + // Sets the given merge mode that is used for adding tags from events to tags specified by this interface. + // The default is TagMergeKeep, which keeps the tags set with this interface and discards tags from events. + SetTagMergeMode(TagMergeMode) +} + +// gstTocSetter implements a TagSetter that is backed by an Element from the C runtime. +type gstTagSetter struct { + ptr *C.GstElement +} + +// Instance returns the underlying TagSetter instance. +func (t *gstTagSetter) Instance() *C.GstTagSetter { return C.toTagSetter(t.ptr) } + +func (t *gstTagSetter) GetTagList() *TagList { + tagList := C.gst_tag_setter_get_tag_list(t.Instance()) + if tagList == nil { + return nil + } + return wrapTagList(tagList) +} + +func (t *gstTagSetter) AddTagValue(mergeMode TagMergeMode, tagKey string, tagValue *glib.Value) { + ckey := C.CString(tagKey) + defer C.free(unsafe.Pointer(ckey)) + C.gst_tag_setter_add_tag_value( + t.Instance(), + C.GstTagMergeMode(mergeMode), + (*C.gchar)(unsafe.Pointer(ckey)), + (*C.GValue)(tagValue.GetPointer()), + ) +} + +func (t *gstTagSetter) MergeTags(tagList *TagList, mergeMode TagMergeMode) { + C.gst_tag_setter_merge_tags(t.Instance(), tagList.Instance(), C.GstTagMergeMode(mergeMode)) +} + +func (t *gstTagSetter) ResetTags() { + C.gst_tag_setter_reset_tags(t.Instance()) +} + +func (t *gstTagSetter) GetTagMergeMode() TagMergeMode { + return TagMergeMode(C.gst_tag_setter_get_tag_merge_mode(t.Instance())) +} + +func (t *gstTagSetter) SetTagMergeMode(mergeMode TagMergeMode) { + C.gst_tag_setter_set_tag_merge_mode(t.Instance(), C.GstTagMergeMode(mergeMode)) +} diff --git a/gst/gst_toc_setter.go b/gst/gst_toc_setter.go new file mode 100644 index 0000000..7233f41 --- /dev/null +++ b/gst/gst_toc_setter.go @@ -0,0 +1,34 @@ +package gst + +// #include "gst.go.h" +import "C" + +// TOCSetter is an interface that elements can implement to provide TOC writing capabilities. +type TOCSetter interface { + // Return current TOC the setter uses. The TOC should not be modified without making it writable first. + GetTOC() *TOC + // Set the given TOC on the setter. Previously set TOC will be unreffed before setting a new one. + SetTOC(*TOC) + // Reset the internal TOC. Elements should call this from within the state-change handler. + Reset() +} + +// gstTocSetter implements a TOCSetter that is backed by an Element from the C runtime. +type gstTOCSetter struct { + ptr *C.GstElement +} + +func (g *gstTOCSetter) Instance() *C.GstTocSetter { + return C.toTocSetter(g.ptr) +} + +func (g *gstTOCSetter) GetTOC() *TOC { + toc := C.gst_toc_setter_get_toc(g.Instance()) + if toc == nil { + return nil + } + return wrapTOC(toc) +} + +func (g *gstTOCSetter) SetTOC(toc *TOC) { C.gst_toc_setter_set_toc(g.Instance(), toc.Instance()) } +func (g *gstTOCSetter) Reset() { C.gst_toc_setter_reset(g.Instance()) } diff --git a/gst/gst_wrappers.go b/gst/gst_wrappers.go index 45244f5..c6d14d4 100644 --- a/gst/gst_wrappers.go +++ b/gst/gst_wrappers.go @@ -3,7 +3,7 @@ package gst /* #include "gst.go.h" -GValue * gvalPtrToGval (uintptr_t p) +GValue * gvalPtrToGval (gpointer p) { return (GValue*)(p); } @@ -141,6 +141,10 @@ func init() { glib.RegisterGValueMarshalers(tm) } +func uintptrToGVal(p uintptr) *C.GValue { + return (*C.GValue)(unsafe.Pointer(p)) +} + // Object wrappers func wrapAllocator(obj *glib.Object) *Allocator { return &Allocator{wrapObject(obj)} } @@ -205,10 +209,6 @@ func durationToClockTime(dur time.Duration) ClockTime { return ClockTime(dur.Nan // Marshallers -func uintptrToGVal(p uintptr) *C.GValue { - return C.gvalPtrToGval(C.ulong(p)) -} - func marshalBufferingMode(p uintptr) (interface{}, error) { c := C.g_value_get_enum(uintptrToGVal(p)) return BufferingMode(c), nil