mirror of
https://github.com/go-gst/go-gst.git
synced 2025-10-09 09:50:18 +08:00
major cleanup
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -21,3 +21,4 @@ _bin/
|
||||
.devcontainer/
|
||||
_rust/
|
||||
*.DS_Store*
|
||||
*.supp
|
@@ -8,7 +8,7 @@
|
||||
// functionality to implement these plugins. The example in this code produces an element
|
||||
// that can read from a file on the local system.
|
||||
//
|
||||
// In order to build the plugin for use by GStreamer, you may do the following:
|
||||
// In order to build the plugin for use by GStreamer, you can do the following:
|
||||
//
|
||||
// $ go build -o libgstgofilesrc.so -buildmode c-shared .
|
||||
//
|
||||
@@ -21,14 +21,15 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
"github.com/tinyzimmer/go-gst/gst"
|
||||
"github.com/tinyzimmer/go-gst/gst/base"
|
||||
)
|
||||
|
||||
// CAT is the log category for the gofilesrc
|
||||
// CAT is the log category for the gofilesrc. It is safe to define GStreamer objects as globals
|
||||
// without calling gst.Init, since in the context of a loaded plugin all initialization has
|
||||
// already been taken care of by the loading application.
|
||||
var CAT = gst.NewDebugCategory(
|
||||
"gofilesrc",
|
||||
gst.DebugColorNone,
|
||||
@@ -77,6 +78,11 @@ type fileSrc struct {
|
||||
state *state
|
||||
}
|
||||
|
||||
func (f *fileSrc) PostMessage(self *gst.Element, msg *gst.Message) bool {
|
||||
fmt.Println("Received message on the pipeline", msg)
|
||||
return self.ParentPostMessage(msg)
|
||||
}
|
||||
|
||||
// Private methods only used internally by the plugin
|
||||
|
||||
// setLocation is a simple method to check the validity of a provided file path and set the
|
||||
@@ -97,7 +103,7 @@ func (f *fileSrc) setLocation(path string) error {
|
||||
// gst.GoElement implementation. Here we simply create a new fileSrc with zeroed settings
|
||||
// and state objects.
|
||||
func (f *fileSrc) New() gst.GoElement {
|
||||
CAT.Log(gst.LevelDebug, "Initializing new fileSrc object")
|
||||
CAT.Log(gst.LevelLog, "Initializing new fileSrc object")
|
||||
return &fileSrc{
|
||||
settings: &settings{},
|
||||
state: &state{},
|
||||
@@ -107,29 +113,27 @@ func (f *fileSrc) New() gst.GoElement {
|
||||
// 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 *gst.TypeInstance) {
|
||||
CAT.Log(gst.LevelDebug, "Adding URIHandler interface to type")
|
||||
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
|
||||
// and properties.
|
||||
func (f *fileSrc) ClassInit(klass *gst.ElementClass) {
|
||||
CAT.Log(gst.LevelDebug, "Initializing gofilesrc class")
|
||||
CAT.Log(gst.LevelLog, "Initializing gofilesrc class")
|
||||
klass.SetMetadata(
|
||||
"File Source",
|
||||
"Source/File",
|
||||
"Read stream from a file",
|
||||
"Avi Zimmerman <avi.zimmerman@gmail.com>",
|
||||
)
|
||||
caps := gst.NewAnyCaps()
|
||||
srcPadTemplate := gst.NewPadTemplate(
|
||||
CAT.Log(gst.LevelLog, "Adding src pad template and properties to class")
|
||||
klass.AddPadTemplate(gst.NewPadTemplate(
|
||||
"src",
|
||||
gst.PadDirectionSource,
|
||||
gst.PadPresenceAlways,
|
||||
caps,
|
||||
)
|
||||
CAT.Log(gst.LevelDebug, "Adding src pad template and properties to class")
|
||||
klass.AddPadTemplate(srcPadTemplate)
|
||||
gst.NewAnyCaps(),
|
||||
))
|
||||
klass.InstallProperties(properties)
|
||||
}
|
||||
|
||||
@@ -189,7 +193,7 @@ func (f *fileSrc) GetProperty(self *gst.Object, id uint) *glib.Value {
|
||||
// during the initialization process can be performed here. In this example, we set the format on our
|
||||
// underlying GstBaseSrc to bytes.
|
||||
func (f *fileSrc) Constructed(self *gst.Object) {
|
||||
self.Log(CAT, gst.LevelDebug, "Setting format of GstBaseSrc to bytes")
|
||||
self.Log(CAT, gst.LevelLog, "Setting format of GstBaseSrc to bytes")
|
||||
base.ToGstBaseSrc(self).SetFormat(gst.FormatBytes)
|
||||
}
|
||||
|
||||
@@ -211,7 +215,7 @@ func (f *fileSrc) GetSize(self *base.GstBaseSrc) (bool, int64) {
|
||||
// and any error encountered in the process is posted to the pipeline.
|
||||
func (f *fileSrc) Start(self *base.GstBaseSrc) bool {
|
||||
if f.state.started {
|
||||
self.ErrorMessage(gst.DomainResource, gst.ResourceErrorSettings, "FileSrc is already started", "")
|
||||
self.ErrorMessage(gst.DomainResource, gst.ResourceErrorSettings, "GoFileSrc is already started", "")
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -240,7 +244,7 @@ func (f *fileSrc) Start(self *base.GstBaseSrc) bool {
|
||||
self.Log(CAT, gst.LevelDebug, fmt.Sprintf("file stat - name: %s size: %d mode: %v modtime: %v", stat.Name(), stat.Size(), stat.Mode(), stat.ModTime()))
|
||||
|
||||
self.Log(CAT, gst.LevelDebug, fmt.Sprintf("Opening file %s for reading", f.settings.location))
|
||||
f.state.file, err = os.OpenFile(f.settings.location, syscall.O_RDONLY, 0444)
|
||||
f.state.file, err = os.Open(f.settings.location)
|
||||
if err != nil {
|
||||
self.ErrorMessage(gst.DomainResource, gst.ResourceErrorOpenRead,
|
||||
fmt.Sprintf("Could not open file %s for reading", f.settings.location), err.Error())
|
||||
@@ -285,7 +289,7 @@ func (f *fileSrc) Fill(self *base.GstBaseSrc, offset uint64, size uint, buffer *
|
||||
return gst.FlowError
|
||||
}
|
||||
|
||||
self.Log(CAT, gst.LevelDebug, fmt.Sprintf("Request to fill buffer from offset %v with size %v", offset, size))
|
||||
self.Log(CAT, gst.LevelLog, fmt.Sprintf("Request to fill buffer from offset %v with size %v", offset, size))
|
||||
|
||||
if f.state.position != offset {
|
||||
self.Log(CAT, gst.LevelDebug, fmt.Sprintf("Seeking to new position at offset %v from previous position at offset %v", offset, f.state.position))
|
||||
@@ -297,18 +301,6 @@ func (f *fileSrc) Fill(self *base.GstBaseSrc, offset uint64, size uint, buffer *
|
||||
f.state.position = offset
|
||||
}
|
||||
|
||||
self.Log(CAT, gst.LevelDebug, fmt.Sprintf("Reading %v bytes from file at offset %v", size, f.state.position))
|
||||
out := make([]byte, int(size))
|
||||
if _, err := f.state.file.Read(out); err != nil && err != io.EOF {
|
||||
self.ErrorMessage(gst.DomainResource, gst.ResourceErrorRead,
|
||||
fmt.Sprintf("Failed to read %d bytes from file at %d", size, offset), err.Error())
|
||||
return gst.FlowError
|
||||
}
|
||||
|
||||
f.state.position = f.state.position + uint64(size)
|
||||
self.Log(CAT, gst.LevelDebug, fmt.Sprintf("Incremented current position to %v", f.state.position))
|
||||
|
||||
self.Log(CAT, gst.LevelDebug, fmt.Sprintf("Writing data from file to buffer"))
|
||||
bufmap := buffer.Map(gst.MapWrite)
|
||||
if bufmap == nil {
|
||||
self.ErrorMessage(gst.DomainLibrary, gst.LibraryErrorFailed, "Failed to map buffer", "")
|
||||
@@ -316,9 +308,17 @@ func (f *fileSrc) Fill(self *base.GstBaseSrc, offset uint64, size uint, buffer *
|
||||
}
|
||||
defer buffer.Unmap()
|
||||
|
||||
bufmap.WriteData(out)
|
||||
self.Log(CAT, gst.LevelLog, fmt.Sprintf("Reading %v bytes from offset %v in file into buffer at %v", size, f.state.position, bufmap.Data()))
|
||||
if _, err := io.CopyN(bufmap.Writer(), f.state.file, int64(size)); err != nil {
|
||||
self.ErrorMessage(gst.DomainResource, gst.ResourceErrorRead,
|
||||
fmt.Sprintf("Failed to read %d bytes from file at %d into buffer", size, offset), err.Error())
|
||||
return gst.FlowError
|
||||
}
|
||||
buffer.SetSize(int64(size))
|
||||
|
||||
f.state.position = f.state.position + uint64(size)
|
||||
self.Log(CAT, gst.LevelLog, fmt.Sprintf("Incremented current position to %v", f.state.position))
|
||||
|
||||
return gst.FlowOK
|
||||
}
|
||||
|
||||
|
2
go.mod
2
go.mod
@@ -3,6 +3,6 @@ module github.com/tinyzimmer/go-gst
|
||||
go 1.15
|
||||
|
||||
require (
|
||||
github.com/gotk3/gotk3 v0.4.0
|
||||
github.com/mattn/go-pointer v0.0.1
|
||||
github.com/tinyzimmer/go-glib v0.0.2
|
||||
)
|
||||
|
7
go.sum
7
go.sum
@@ -1,5 +1,6 @@
|
||||
github.com/gotk3/gotk3 v0.4.0 h1:TIuhyQitGeRTxOQIV3AJlYtEWWJpC74JHwAIsxlH8MU=
|
||||
github.com/gotk3/gotk3 v0.4.0/go.mod h1:Eew3QBwAOBTrfFFDmsDE5wZWbcagBL1NUslj1GhRveo=
|
||||
github.com/gotk3/gotk3 v0.5.2 h1:jbSFvUNMfo3ImM6BWBAkNUxY5piqP3eTc1YFbYy9ecU=
|
||||
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.1 h1:pfsr7EbP23/cZPGlEpsmwtQXjdzYj0S+WhUgOALdsQI=
|
||||
github.com/tinyzimmer/go-glib v0.0.1/go.mod h1:D5rd0CvYn1p7TBhwlwnBXHSr4d8lwEY9JImPQ66S+Bs=
|
||||
github.com/tinyzimmer/go-glib v0.0.2 h1:hdvjwrhcS6WrMMeqfxsf3e7/lOhV8gbVyJ9/sN3LfyY=
|
||||
github.com/tinyzimmer/go-glib v0.0.2/go.mod h1:D5rd0CvYn1p7TBhwlwnBXHSr4d8lwEY9JImPQ66S+Bs=
|
||||
|
@@ -87,11 +87,13 @@ func (a *Source) GetCurrentLevelBytes() uint64 {
|
||||
return uint64(C.gst_app_src_get_current_level_bytes(a.Instance()))
|
||||
}
|
||||
|
||||
var gstClockTimeNone C.GstClockTime = 0xffffffffffffffff
|
||||
|
||||
// GetDuration gets the duration of the stream in nanoseconds. A negative value means that the duration is not known.
|
||||
func (a *Source) GetDuration() time.Duration {
|
||||
dur := C.gst_app_src_get_duration(a.Instance())
|
||||
if gst.ClockTime(dur) == gst.ClockTimeNone {
|
||||
return time.Duration(-1)
|
||||
if dur == gstClockTimeNone {
|
||||
return gst.ClockTimeNone
|
||||
}
|
||||
return time.Duration(uint64(dur)) * time.Nanosecond
|
||||
}
|
||||
|
@@ -50,7 +50,7 @@ import (
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
"github.com/tinyzimmer/go-gst/gst"
|
||||
)
|
||||
|
||||
|
@@ -8,7 +8,7 @@ import (
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
)
|
||||
|
||||
func toGObject(data unsafe.Pointer) *glib.Object {
|
||||
@@ -99,7 +99,7 @@ func streamSliceToGlist(streams []*Stream) *C.GList {
|
||||
for _, stream := range streams {
|
||||
wrapped = wrapped.Append(uintptr(stream.Unsafe()))
|
||||
}
|
||||
return (*C.GList)(unsafe.Pointer(wrapped.Native()))
|
||||
return &glist
|
||||
}
|
||||
|
||||
func glistToStreamSlice(glist *C.GList) []*Stream {
|
||||
|
@@ -10,10 +10,11 @@ import "C"
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
gopointer "github.com/mattn/go-pointer"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
)
|
||||
|
||||
//export goElementCallAsync
|
||||
@@ -223,7 +224,7 @@ func goClockCb(gclock *C.GstClock, clockTime C.GstClockTime, clockID C.GstClockI
|
||||
}
|
||||
|
||||
clock := wrapClock(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(gclock))})
|
||||
return gboolean(cb(clock, ClockTime(clockTime)))
|
||||
return gboolean(cb(clock, time.Duration(clockTime)))
|
||||
}
|
||||
|
||||
//export goPluginInit
|
||||
|
@@ -3,7 +3,10 @@ package gst
|
||||
// #include "gst.go.h"
|
||||
import "C"
|
||||
|
||||
import "unsafe"
|
||||
import (
|
||||
"time"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Version represents information about the current GST version.
|
||||
type Version int
|
||||
@@ -47,20 +50,20 @@ func (g GFraction) Num() int { return g.num }
|
||||
// Denom returns the fraction's denominator.
|
||||
func (g GFraction) Denom() int { return g.denom }
|
||||
|
||||
// ClockTime is a go representation of a GstClockTime. Most of the time these are casted
|
||||
// to time.Duration objects. It represents a time value in nanoseconds.
|
||||
type ClockTime uint64
|
||||
|
||||
// ClockTimeDiff is a datatype to hold a time difference, measured in nanoseconds.
|
||||
type ClockTimeDiff int64
|
||||
|
||||
const (
|
||||
// ClockFormat is the string used when formatting clock strings
|
||||
ClockFormat string = "u:%02u:%02u.%09u"
|
||||
// ClockTimeNone means infinite timeout or an empty value
|
||||
var ClockTimeNone time.Duration = time.Duration(-1)
|
||||
|
||||
// BufferOffsetNone is a var for no-offset return results.
|
||||
var BufferOffsetNone time.Duration = time.Duration(-1)
|
||||
|
||||
var (
|
||||
// ClockTimeNone means infinite timeout (unsigned representation of -1) or an otherwise unknown value.
|
||||
ClockTimeNone ClockTime = 0xffffffffffffffff
|
||||
// BufferOffsetNone is a constant for no-offset return results.
|
||||
BufferOffsetNone ClockTime = 0xffffffffffffffff
|
||||
gstClockTimeNone C.GstClockTime = 0xffffffffffffffff
|
||||
// // BufferOffsetNone is a constant for no-offset return results.
|
||||
// gstBufferOffsetNone C.GstClockTime = 0xffffffffffffffff
|
||||
)
|
||||
|
||||
// ClockEntryType wraps GstClockEntryType
|
||||
@@ -562,6 +565,32 @@ const (
|
||||
SeekTypeEnd SeekType = C.GST_SEEK_TYPE_END
|
||||
)
|
||||
|
||||
// StateChange is the different state changes an element goes through. StateNull ⇒ StatePlaying is called
|
||||
// an upwards state change and StatePlaying ⇒ StateNull a downwards state change.
|
||||
//
|
||||
// See https://gstreamer.freedesktop.org/documentation/gstreamer/gstelement.html?gi-language=c#GstStateChange
|
||||
// for more information on the responsibiltiies of elements during each transition.
|
||||
type StateChange int
|
||||
|
||||
// StateChange castings
|
||||
const (
|
||||
StateChangeNullToReady StateChange = C.GST_STATE_CHANGE_NULL_TO_READY
|
||||
StateChangeReadyToPaused StateChange = C.GST_STATE_CHANGE_READY_TO_PAUSED
|
||||
StateChangePausedToPlaying StateChange = C.GST_STATE_CHANGE_PAUSED_TO_PLAYING
|
||||
StateChangePlayingToPaused StateChange = C.GST_STATE_CHANGE_PLAYING_TO_PAUSED
|
||||
StateChangePausedToReady StateChange = C.GST_STATE_CHANGE_PAUSED_TO_READY
|
||||
StateChangeReadyToNull StateChange = C.GST_STATE_CHANGE_READY_TO_NULL
|
||||
StateChangeNullToNull StateChange = C.GST_STATE_CHANGE_NULL_TO_NULL
|
||||
StateChangeReadyToReady StateChange = C.GST_STATE_CHANGE_READY_TO_READY
|
||||
StateChangePausedToPaused StateChange = C.GST_STATE_CHANGE_PAUSED_TO_PAUSED
|
||||
StateChangePlayingToPlaying StateChange = C.GST_STATE_CHANGE_PLAYING_TO_PLAYING
|
||||
)
|
||||
|
||||
// String returns the string representation of a StateChange
|
||||
func (s StateChange) String() string {
|
||||
return C.GoString(C.gst_state_change_get_name(C.GstStateChange(s)))
|
||||
}
|
||||
|
||||
// StateChangeReturn is a representation of GstStateChangeReturn.
|
||||
type StateChangeReturn int
|
||||
|
||||
@@ -573,6 +602,10 @@ const (
|
||||
StateChangeNoPreroll StateChangeReturn = C.GST_STATE_CHANGE_NO_PREROLL
|
||||
)
|
||||
|
||||
func (s StateChangeReturn) String() string {
|
||||
return C.GoString(C.gst_element_state_change_return_get_name(C.GstStateChangeReturn(s)))
|
||||
}
|
||||
|
||||
// ElementFlags casts C GstElementFlags to a go type
|
||||
type ElementFlags int
|
||||
|
||||
|
@@ -32,10 +32,10 @@ import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
)
|
||||
|
||||
// GoObject is an interface that abstracts on the GObject. In most cases at least SetProperty and GetProperty
|
||||
// GoObject is an interface that abstracts on the GObject. In almost all cases at least SetProperty and GetProperty
|
||||
// should be implemented by elements built from the go bindings.
|
||||
type GoObject interface {
|
||||
// SetProperty should set the value of the property with the given id. ID is the index+1 of the parameter
|
||||
@@ -48,7 +48,8 @@ type GoObject interface {
|
||||
Constructed(*Object)
|
||||
}
|
||||
|
||||
// ExtendsObject signifies a GoElement that extends a GObject.
|
||||
// ExtendsObject signifies a GoElement that extends a GObject. It is the base Extendable
|
||||
// that all other implementations derive from.
|
||||
var ExtendsObject Extendable = &extendObject{}
|
||||
|
||||
type extendObject struct{}
|
||||
|
@@ -22,7 +22,7 @@ import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
)
|
||||
|
||||
// ObjectClass is a loose binding around the glib GObjectClass.
|
||||
|
@@ -7,7 +7,7 @@ import (
|
||||
"strings"
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
)
|
||||
|
||||
// ParameterSpec is a go representation of a C GParamSpec
|
||||
|
@@ -6,7 +6,7 @@ import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
)
|
||||
|
||||
// AllocationParams wraps the GstAllocationParams.
|
||||
|
@@ -8,7 +8,7 @@ import (
|
||||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
)
|
||||
|
||||
// Bin is a go wrapper arounds a GstBin.
|
||||
|
@@ -26,8 +26,8 @@ import (
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
gopointer "github.com/mattn/go-pointer"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
)
|
||||
|
||||
// GetMaxBufferMemory returns the maximum amount of memory a buffer can hold.
|
||||
@@ -161,42 +161,42 @@ func (b *Buffer) Bytes() []byte {
|
||||
// presented to the user.
|
||||
func (b *Buffer) PresentationTimestamp() time.Duration {
|
||||
pts := b.Instance().pts
|
||||
if ClockTime(pts) == ClockTimeNone {
|
||||
return time.Duration(-1)
|
||||
if pts == gstClockTimeNone {
|
||||
return ClockTimeNone
|
||||
}
|
||||
return guint64ToDuration(pts)
|
||||
return time.Duration(pts)
|
||||
}
|
||||
|
||||
// SetPresentationTimestamp sets the presentation timestamp on the buffer.
|
||||
func (b *Buffer) SetPresentationTimestamp(dur time.Duration) {
|
||||
ins := b.Instance()
|
||||
ins.pts = C.GstClockTime(durationToClockTime(dur))
|
||||
ins.pts = C.GstClockTime(dur.Nanoseconds())
|
||||
}
|
||||
|
||||
// DecodingTimestamp returns the decoding timestamp of the buffer, or a negative duration if not known
|
||||
// or relevant. This value contains the timestamp when the media should be processed.
|
||||
func (b *Buffer) DecodingTimestamp() time.Duration {
|
||||
dts := b.Instance().dts
|
||||
if ClockTime(dts) == ClockTimeNone {
|
||||
return time.Duration(-1)
|
||||
if dts == gstClockTimeNone {
|
||||
return ClockTimeNone
|
||||
}
|
||||
return guint64ToDuration(dts)
|
||||
return time.Duration(dts)
|
||||
}
|
||||
|
||||
// Duration returns the length of the data inside this buffer, or a negative duration if not known
|
||||
// or relevant.
|
||||
func (b *Buffer) Duration() time.Duration {
|
||||
dur := b.Instance().duration
|
||||
if ClockTime(dur) == ClockTimeNone {
|
||||
return time.Duration(-1)
|
||||
if dur == gstClockTimeNone {
|
||||
return ClockTimeNone
|
||||
}
|
||||
return guint64ToDuration(dur)
|
||||
return time.Duration(dur)
|
||||
}
|
||||
|
||||
// SetDuration sets the duration on the buffer.
|
||||
func (b *Buffer) SetDuration(dur time.Duration) {
|
||||
ins := b.Instance()
|
||||
ins.duration = C.GstClockTime(durationToClockTime(dur))
|
||||
ins.duration = C.GstClockTime(dur.Nanoseconds())
|
||||
}
|
||||
|
||||
// Offset returns a media specific offset for the buffer data. For video frames, this is the frame
|
||||
@@ -292,8 +292,8 @@ func (b *Buffer) AddReferenceTimestampMeta(ref *Caps, timestamp, duration time.D
|
||||
return &ReferenceTimestampMeta{
|
||||
Parent: wrapMeta(&meta.parent),
|
||||
Reference: wrapCaps(meta.reference),
|
||||
Timestamp: clockTimeToDuration(ClockTime(meta.timestamp)),
|
||||
Duration: clockTimeToDuration(ClockTime(meta.duration)),
|
||||
Timestamp: time.Duration(meta.timestamp),
|
||||
Duration: time.Duration(meta.duration),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -472,8 +472,8 @@ func (b *Buffer) GetReferenceTimestampMeta(caps *Caps) *ReferenceTimestampMeta {
|
||||
return &ReferenceTimestampMeta{
|
||||
Parent: wrapMeta(&meta.parent),
|
||||
Reference: wrapCaps(meta.reference),
|
||||
Timestamp: clockTimeToDuration(ClockTime(meta.timestamp)),
|
||||
Duration: clockTimeToDuration(ClockTime(meta.duration)),
|
||||
Timestamp: time.Duration(meta.timestamp),
|
||||
Duration: time.Duration(meta.duration),
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -7,7 +7,7 @@ import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
)
|
||||
|
||||
// BufferPool is a go wrapper around a GstBufferPool.
|
||||
|
@@ -28,8 +28,8 @@ import (
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
gopointer "github.com/mattn/go-pointer"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
)
|
||||
|
||||
// Bus is a Go wrapper around a GstBus. It provides convenience methods for
|
||||
@@ -283,7 +283,7 @@ func (b *Bus) Peek() *Message {
|
||||
// For 0 timeouts use gst_bus_pop_filtered instead of this function; for other short timeouts use TimedPopFiltered;
|
||||
// everything else is better handled by setting up an asynchronous bus watch and doing things from there.
|
||||
func (b *Bus) Poll(msgTypes MessageType, timeout time.Duration) *Message {
|
||||
cTime := C.GstClockTime(durationToClockTime(timeout))
|
||||
cTime := C.GstClockTime(timeout.Nanoseconds())
|
||||
mType := C.GstMessageType(msgTypes)
|
||||
msg := C.gst_bus_poll(b.Instance(), mType, cTime)
|
||||
if msg == nil {
|
||||
@@ -364,10 +364,10 @@ func (b *Bus) SetSyncHandler(f BusSyncHandler) {
|
||||
// If timeout is 0, this function behaves like Pop. If timeout is < 0, this function will block forever until a message was posted on the bus.
|
||||
func (b *Bus) TimedPop(dur time.Duration) *Message {
|
||||
var cTime C.GstClockTime
|
||||
if dur.Nanoseconds() < 0 {
|
||||
cTime = C.GstClockTime(ClockTimeNone)
|
||||
if dur == ClockTimeNone {
|
||||
cTime = C.GstClockTime(gstClockTimeNone)
|
||||
} else {
|
||||
cTime = C.GstClockTime(durationToClockTime(dur))
|
||||
cTime = C.GstClockTime(dur.Nanoseconds())
|
||||
}
|
||||
msg := C.gst_bus_timed_pop(b.Instance(), cTime)
|
||||
if msg == nil {
|
||||
@@ -383,10 +383,10 @@ func (b *Bus) TimedPop(dur time.Duration) *Message {
|
||||
// was posted on the bus.
|
||||
func (b *Bus) TimedPopFiltered(dur time.Duration, msgTypes MessageType) *Message {
|
||||
var cTime C.GstClockTime
|
||||
if dur.Nanoseconds() < 0 {
|
||||
cTime = C.GstClockTime(ClockTimeNone)
|
||||
if dur == ClockTimeNone {
|
||||
cTime = C.GstClockTime(gstClockTimeNone)
|
||||
} else {
|
||||
cTime = C.GstClockTime(durationToClockTime(dur))
|
||||
cTime = C.GstClockTime(dur.Nanoseconds())
|
||||
}
|
||||
msg := C.gst_bus_timed_pop_filtered(b.Instance(), cTime, C.GstMessageType(msgTypes))
|
||||
if msg == nil {
|
||||
|
@@ -17,8 +17,8 @@ import (
|
||||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
gopointer "github.com/mattn/go-pointer"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
)
|
||||
|
||||
// Caps is a go wrapper around GstCaps.
|
||||
@@ -406,7 +406,7 @@ func (c *Caps) SetValue(field string, val interface{}) {
|
||||
C.gst_caps_set_value(
|
||||
c.Instance(),
|
||||
(*C.gchar)(unsafe.Pointer(C.CString(field))),
|
||||
(*C.GValue)(gVal.Native()),
|
||||
(*C.GValue)(unsafe.Pointer(gVal.GValue)),
|
||||
)
|
||||
}
|
||||
|
||||
|
100
gst/gst_clock.go
100
gst/gst_clock.go
@@ -23,12 +23,12 @@ import (
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
gopointer "github.com/mattn/go-pointer"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
)
|
||||
|
||||
// ClockCallback is the prototype of a clock callback function.
|
||||
type ClockCallback func(clock *Clock, clockTime ClockTime) bool
|
||||
type ClockCallback func(clock *Clock, clockTime time.Duration) bool
|
||||
|
||||
// ClockID is a go wrapper around a GstClockID.
|
||||
type ClockID struct {
|
||||
@@ -45,8 +45,8 @@ func (c *ClockID) GetClock() *Clock {
|
||||
}
|
||||
|
||||
// GetTime returns the time for this ClockID
|
||||
func (c *ClockID) GetTime() ClockTime {
|
||||
return ClockTime(C.gst_clock_id_get_time(c.Instance()))
|
||||
func (c *ClockID) GetTime() time.Duration {
|
||||
return time.Duration(C.gst_clock_id_get_time(c.Instance()))
|
||||
}
|
||||
|
||||
// Unschedule cancels an outstanding request with id. This can either be an outstanding async notification or a pending sync notification.
|
||||
@@ -88,8 +88,8 @@ func (c *ClockID) Wait() (ret ClockReturn, jitter ClockTimeDiff) {
|
||||
//
|
||||
// id := clock.NewSingleShotID(gst.ClockTime(1000000000)) // 1 second
|
||||
//
|
||||
// id.WaitAsync(func(clock *gst.Clock, clockTime gst.ClockTime) bool {
|
||||
// fmt.Println("Single shot triggered at", clockTime)
|
||||
// id.WaitAsync(func(clock *gst.Clock, clockTime time.Duration) bool {
|
||||
// fmt.Println("Single shot triggered at", clockTime.Nanoseconds())
|
||||
// pipeline.SetState(gst.StateNull)
|
||||
// return true
|
||||
// })
|
||||
@@ -130,7 +130,7 @@ func (c *Clock) Instance() *C.GstClock { return C.toGstClock(c.Unsafe()) }
|
||||
//
|
||||
// If this functions returns TRUE, the float will contain the correlation coefficient of the interpolation. A value of 1.0 means
|
||||
// a perfect regression was performed. This value can be used to control the sampling frequency of the master and slave clocks.
|
||||
func (c *Clock) AddObservation(slaveTime, masterTime ClockTime) (bool, float64) {
|
||||
func (c *Clock) AddObservation(slaveTime, masterTime time.Duration) (bool, float64) {
|
||||
var out C.gdouble
|
||||
ok := gobool(C.gst_clock_add_observation(
|
||||
c.Instance(),
|
||||
@@ -145,7 +145,7 @@ func (c *Clock) AddObservation(slaveTime, masterTime ClockTime) (bool, float64)
|
||||
// result of the master clock estimation, without updating the internal calibration.
|
||||
//
|
||||
// The caller can then take the results and call SetCalibration with the values, or some modified version of them.
|
||||
func (c *Clock) AddObservationUnapplied(slaveTime, masterTime ClockTime) (ok bool, rSquared float64, internalTime, externalTime, rateNum, rateDenom ClockTime) {
|
||||
func (c *Clock) AddObservationUnapplied(slaveTime, masterTime time.Duration) (ok bool, rSquared float64, internalTime, externalTime, rateNum, rateDenom time.Duration) {
|
||||
var ginternal, gexternal, grateNum, grateDenom C.GstClockTime
|
||||
var grSquared C.gdouble
|
||||
ok = gobool(C.gst_clock_add_observation_unapplied(
|
||||
@@ -154,7 +154,7 @@ func (c *Clock) AddObservationUnapplied(slaveTime, masterTime ClockTime) (ok boo
|
||||
C.GstClockTime(masterTime),
|
||||
&grSquared, &ginternal, &gexternal, &grateNum, &grateDenom,
|
||||
))
|
||||
return ok, float64(grSquared), ClockTime(ginternal), ClockTime(gexternal), ClockTime(grateNum), ClockTime(grateDenom)
|
||||
return ok, float64(grSquared), time.Duration(ginternal), time.Duration(gexternal), time.Duration(grateNum), time.Duration(grateDenom)
|
||||
}
|
||||
|
||||
// AdjustUnlocked converts the given internal clock time to the external time, adjusting for the rate and reference time set with
|
||||
@@ -162,8 +162,8 @@ func (c *Clock) AddObservationUnapplied(slaveTime, masterTime ClockTime) (ok boo
|
||||
// held and is mainly used by clock subclasses.
|
||||
//
|
||||
// This function is the reverse of UnadjustUnlocked.
|
||||
func (c *Clock) AdjustUnlocked(internal ClockTime) ClockTime {
|
||||
return ClockTime(C.gst_clock_adjust_unlocked(c.Instance(), C.GstClockTime(internal)))
|
||||
func (c *Clock) AdjustUnlocked(internal time.Duration) time.Duration {
|
||||
return time.Duration(C.gst_clock_adjust_unlocked(c.Instance(), C.GstClockTime(internal)))
|
||||
}
|
||||
|
||||
// AdjustWithCalibration converts the given internal_target clock time to the external time, using the passed calibration parameters.
|
||||
@@ -171,8 +171,8 @@ func (c *Clock) AdjustUnlocked(internal ClockTime) ClockTime {
|
||||
// doesn't ensure a monotonically increasing result as AdjustUnlocked does.
|
||||
//
|
||||
// See: https://gstreamer.freedesktop.org/documentation/gstreamer/gstclock.html#gst_clock_adjust_with_calibration
|
||||
func (c *Clock) AdjustWithCalibration(internalTarget, cinternal, cexternal, cnum, cdenom ClockTime) ClockTime {
|
||||
return ClockTime(C.gst_clock_adjust_with_calibration(
|
||||
func (c *Clock) AdjustWithCalibration(internalTarget, cinternal, cexternal, cnum, cdenom time.Duration) time.Duration {
|
||||
return time.Duration(C.gst_clock_adjust_with_calibration(
|
||||
c.Instance(),
|
||||
C.GstClockTime(internalTarget),
|
||||
C.GstClockTime(cinternal),
|
||||
@@ -183,48 +183,30 @@ func (c *Clock) AdjustWithCalibration(internalTarget, cinternal, cexternal, cnum
|
||||
}
|
||||
|
||||
// GetCalibration gets the internal rate and reference time of clock. See gst_clock_set_calibration for more information.
|
||||
func (c *Clock) GetCalibration() (internal, external, rateNum, rateDenom ClockTime) {
|
||||
func (c *Clock) GetCalibration() (internal, external, rateNum, rateDenom time.Duration) {
|
||||
var ginternal, gexternal, grateNum, grateDenom C.GstClockTime
|
||||
C.gst_clock_get_calibration(c.Instance(), &ginternal, &gexternal, &grateNum, &grateDenom)
|
||||
return ClockTime(ginternal), ClockTime(gexternal), ClockTime(grateNum), ClockTime(grateDenom)
|
||||
return time.Duration(ginternal), time.Duration(gexternal), time.Duration(grateNum), time.Duration(grateDenom)
|
||||
}
|
||||
|
||||
// GetTime gets the current time of the given clock in nanoseconds or ClockTimeNone if invalid.
|
||||
// GetTime gets the current time of the given clock in nanoseconds or -1 if invalid.
|
||||
// The time is always monotonically increasing and adjusted according to the current offset and rate.
|
||||
func (c *Clock) GetTime() ClockTime {
|
||||
func (c *Clock) GetTime() time.Duration {
|
||||
res := C.gst_clock_get_time(c.Instance())
|
||||
if ClockTime(res) == ClockTimeNone {
|
||||
if res == C.GST_CLOCK_TIME_NONE {
|
||||
return ClockTimeNone
|
||||
}
|
||||
return ClockTime(res)
|
||||
return time.Duration(res)
|
||||
}
|
||||
|
||||
// GetInternalTime gets the current internal time of the given clock in nanoseconds
|
||||
// or ClockTimeNone if invalid. The time is returned unadjusted for the offset and the rate.
|
||||
func (c *Clock) GetInternalTime() ClockTime {
|
||||
func (c *Clock) GetInternalTime() time.Duration {
|
||||
res := C.gst_clock_get_internal_time(c.Instance())
|
||||
if ClockTime(res) == ClockTimeNone {
|
||||
if res == C.GST_CLOCK_TIME_NONE {
|
||||
return ClockTimeNone
|
||||
}
|
||||
return ClockTime(res)
|
||||
}
|
||||
|
||||
// GetDuration returns the time.Duration equivalent of this clock time.
|
||||
func (c *Clock) GetDuration() time.Duration {
|
||||
tm := c.GetTime()
|
||||
if tm == ClockTimeNone {
|
||||
return time.Duration(-1)
|
||||
}
|
||||
return clockTimeToDuration(tm)
|
||||
}
|
||||
|
||||
// GetInternalDuration returns the time.Duration equivalent of this clock's internal time.
|
||||
func (c *Clock) GetInternalDuration() time.Duration {
|
||||
tm := c.GetInternalTime()
|
||||
if tm == ClockTimeNone {
|
||||
return time.Duration(-1)
|
||||
}
|
||||
return clockTimeToDuration(tm)
|
||||
return time.Duration(res)
|
||||
}
|
||||
|
||||
// GetMaster returns the master clock that this clock is slaved to or nil when the clock
|
||||
@@ -239,17 +221,21 @@ func (c *Clock) GetMaster() *Clock {
|
||||
|
||||
// GetResolution gets the accuracy of the clock. The accuracy of the clock is the granularity
|
||||
// of the values returned by GetTime.
|
||||
func (c *Clock) GetResolution() ClockTime { return ClockTime(C.gst_clock_get_resolution(c.Instance())) }
|
||||
func (c *Clock) GetResolution() time.Duration {
|
||||
return time.Duration(C.gst_clock_get_resolution(c.Instance()))
|
||||
}
|
||||
|
||||
// GetTimeout gets the amount of time that master and slave clocks are sampled.
|
||||
func (c *Clock) GetTimeout() ClockTime { return ClockTime(C.gst_clock_get_timeout(c.Instance())) }
|
||||
func (c *Clock) GetTimeout() time.Duration {
|
||||
return time.Duration(C.gst_clock_get_timeout(c.Instance()))
|
||||
}
|
||||
|
||||
// IsSynced returns true if the clock is synced.
|
||||
func (c *Clock) IsSynced() bool { return gobool(C.gst_clock_is_synced(c.Instance())) }
|
||||
|
||||
// NewPeriodicID gets an ID from clock to trigger a periodic notification. The periodic notifications
|
||||
// will start at time start_time and will then be fired with the given interval. ID should be unreffed after usage.
|
||||
func (c *Clock) NewPeriodicID(startTime, interval ClockTime) *ClockID {
|
||||
func (c *Clock) NewPeriodicID(startTime, interval time.Duration) *ClockID {
|
||||
id := C.gst_clock_new_periodic_id(
|
||||
c.Instance(),
|
||||
C.GstClockTime(startTime),
|
||||
@@ -260,7 +246,7 @@ func (c *Clock) NewPeriodicID(startTime, interval ClockTime) *ClockID {
|
||||
|
||||
// NewSingleShotID gets a ClockID from the clock to trigger a single shot notification at the requested time.
|
||||
// The single shot id should be unreffed after usage.
|
||||
func (c *Clock) NewSingleShotID(at ClockTime) *ClockID {
|
||||
func (c *Clock) NewSingleShotID(at time.Duration) *ClockID {
|
||||
id := C.gst_clock_new_single_shot_id(
|
||||
c.Instance(),
|
||||
C.GstClockTime(at),
|
||||
@@ -270,7 +256,7 @@ func (c *Clock) NewSingleShotID(at ClockTime) *ClockID {
|
||||
|
||||
// PeriodicIDReinit reinitializes the provided periodic id to the provided start time and interval. Does not
|
||||
/// modify the reference count.
|
||||
func (c *Clock) PeriodicIDReinit(clockID *ClockID, startTime, interval ClockTime) bool {
|
||||
func (c *Clock) PeriodicIDReinit(clockID *ClockID, startTime, interval time.Duration) bool {
|
||||
return gobool(C.gst_clock_periodic_id_reinit(
|
||||
c.Instance(),
|
||||
clockID.Instance(),
|
||||
@@ -281,7 +267,7 @@ func (c *Clock) PeriodicIDReinit(clockID *ClockID, startTime, interval ClockTime
|
||||
|
||||
// SetCalibration adjusts the rate and time of clock.
|
||||
// See: https://gstreamer.freedesktop.org/documentation/gstreamer/gstclock.html#gst_clock_set_calibration.
|
||||
func (c *Clock) SetCalibration(internal, external, rateNum, rateDenom ClockTime) {
|
||||
func (c *Clock) SetCalibration(internal, external, rateNum, rateDenom time.Duration) {
|
||||
C.gst_clock_set_calibration(
|
||||
c.Instance(),
|
||||
C.GstClockTime(internal),
|
||||
@@ -305,8 +291,8 @@ func (c *Clock) SetMaster(master *Clock) bool {
|
||||
// SetResolution sets the accuracy of the clock. Some clocks have the possibility to operate with different accuracy
|
||||
// at the expense of more resource usage. There is normally no need to change the default resolution of a clock.
|
||||
// The resolution of a clock can only be changed if the clock has the ClockFlagCanSetResolution flag set.
|
||||
func (c *Clock) SetResolution(resolution ClockTime) ClockTime {
|
||||
return ClockTime(C.gst_clock_set_resolution(c.Instance(), C.GstClockTime(resolution)))
|
||||
func (c *Clock) SetResolution(resolution time.Duration) time.Duration {
|
||||
return time.Duration(C.gst_clock_set_resolution(c.Instance(), C.GstClockTime(resolution)))
|
||||
}
|
||||
|
||||
// SetSynced sets clock to synced and emits the GstClock::synced signal, and wakes up any thread waiting in WaitForSync.
|
||||
@@ -316,12 +302,12 @@ func (c *Clock) SetResolution(resolution ClockTime) ClockTime {
|
||||
func (c *Clock) SetSynced(synced bool) { C.gst_clock_set_synced(c.Instance(), gboolean(synced)) }
|
||||
|
||||
// SetTimeout sets the amount of time, in nanoseconds, to sample master and slave clocks
|
||||
func (c *Clock) SetTimeout(timeout ClockTime) {
|
||||
func (c *Clock) SetTimeout(timeout time.Duration) {
|
||||
C.gst_clock_set_timeout(c.Instance(), C.GstClockTime(timeout))
|
||||
}
|
||||
|
||||
// SingleShotIDReinit reinitializes the provided single shot id to the provided time. Does not modify the reference count.
|
||||
func (c *Clock) SingleShotIDReinit(clockID *ClockID, at ClockTime) bool {
|
||||
func (c *Clock) SingleShotIDReinit(clockID *ClockID, at time.Duration) bool {
|
||||
return gobool(C.gst_clock_single_shot_id_reinit(c.Instance(), clockID.Instance(), C.GstClockTime(at)))
|
||||
}
|
||||
|
||||
@@ -329,14 +315,14 @@ func (c *Clock) SingleShotIDReinit(clockID *ClockID, at ClockTime) bool {
|
||||
// set with SetCalibration. This function should be called with the clock's OBJECT_LOCK held and is mainly used by clock subclasses.
|
||||
//
|
||||
// This function is the reverse of AdjustUnlocked.
|
||||
func (c *Clock) UnadjustUnlocked(external ClockTime) ClockTime {
|
||||
return ClockTime(C.gst_clock_unadjust_unlocked(c.Instance(), C.GstClockTime(external)))
|
||||
func (c *Clock) UnadjustUnlocked(external time.Duration) time.Duration {
|
||||
return time.Duration(C.gst_clock_unadjust_unlocked(c.Instance(), C.GstClockTime(external)))
|
||||
}
|
||||
|
||||
// UnadjustWithCalibration converts the given external_target clock time to the internal time, using the passed calibration parameters.
|
||||
// This function performs the same calculation as UnadjustUnlocked when called using the current calibration parameters.
|
||||
func (c *Clock) UnadjustWithCalibration(externalTarget, cinternal, cexternal, cnum, cdenom ClockTime) ClockTime {
|
||||
return ClockTime(C.gst_clock_unadjust_with_calibration(
|
||||
func (c *Clock) UnadjustWithCalibration(externalTarget, cinternal, cexternal, cnum, cdenom time.Duration) time.Duration {
|
||||
return time.Duration(C.gst_clock_unadjust_with_calibration(
|
||||
c.Instance(),
|
||||
C.GstClockTime(externalTarget),
|
||||
C.GstClockTime(cinternal),
|
||||
@@ -352,12 +338,12 @@ func (c *Clock) UnadjustWithCalibration(externalTarget, cinternal, cexternal, cn
|
||||
// For asynchronous waiting, the GstClock::synced signal can be used.
|
||||
//
|
||||
// This returns immediately with TRUE if ClockFlagNeedsStartupSync is not set on the clock, or if the clock is already synced.
|
||||
func (c *Clock) WaitForSync(timeout ClockTime) bool {
|
||||
func (c *Clock) WaitForSync(timeout time.Duration) bool {
|
||||
return gobool(C.gst_clock_wait_for_sync(c.Instance(), C.GstClockTime(timeout)))
|
||||
}
|
||||
|
||||
// String returns the string representation of this clock value.
|
||||
func (c *Clock) String() string { return c.GetDuration().String() }
|
||||
func (c *Clock) String() string { return c.GetTime().String() }
|
||||
|
||||
// InternalString returns the string representation of this clock's internal value.
|
||||
func (c *Clock) InternalString() string { return c.GetInternalDuration().String() }
|
||||
func (c *Clock) InternalString() string { return c.GetInternalTime().String() }
|
||||
|
@@ -8,7 +8,7 @@ import (
|
||||
"strings"
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
)
|
||||
|
||||
// Device is a Go representation of a GstDevice.
|
||||
|
@@ -16,6 +16,46 @@ void cgoElementCallAsync (GstElement * element, gpointer user_data)
|
||||
goElementCallAsync(element, user_data);
|
||||
}
|
||||
|
||||
gboolean elementParentPostMessage (GstElement * element, GstMessage * message) {
|
||||
GObjectClass * this_class = G_OBJECT_GET_CLASS(G_OBJECT(element));
|
||||
GstElementClass * parent = toGstElementClass(g_type_class_peek_parent(this_class));
|
||||
return parent->post_message(element, message);
|
||||
}
|
||||
|
||||
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"
|
||||
|
||||
@@ -23,9 +63,10 @@ import (
|
||||
"fmt"
|
||||
"path"
|
||||
"runtime"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
gopointer "github.com/mattn/go-pointer"
|
||||
)
|
||||
|
||||
@@ -119,6 +160,11 @@ func (e *Element) CallAsync(f func()) {
|
||||
)
|
||||
}
|
||||
|
||||
// ChangeState performs the given transition on this element.
|
||||
func (e *Element) ChangeState(transition StateChange) StateChangeReturn {
|
||||
return StateChangeReturn(C.gst_element_change_state(e.Instance(), C.GstStateChange(transition)))
|
||||
}
|
||||
|
||||
// Connect connects to the given signal on this element, and applies f as the callback. The callback must
|
||||
// match the signature of the expected callback from the documentation. However, instead of specifying C types
|
||||
// for arguments specify the go-gst equivalent (e.g. *gst.Element for almost all GstElement derivitives).
|
||||
@@ -291,6 +337,12 @@ func (e *Element) LinkFiltered(elem *Element, caps *Caps) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ParentPostMessage can be used when extending an element. During a PostMessage, use this method
|
||||
// to have the message posted on the bus after processing.
|
||||
func (e *Element) ParentPostMessage(msg *Message) bool {
|
||||
return gobool(C.elementParentPostMessage(e.Instance(), msg.Instance()))
|
||||
}
|
||||
|
||||
// Query performs a query on the given element.
|
||||
//
|
||||
// For elements that don't implement a query handler, this function forwards the query to a random srcpad or
|
||||
@@ -388,6 +440,44 @@ func (e *Element) URIHandler() URIHandler {
|
||||
// ExtendsElement signifies a GoElement that extends a GstElement.
|
||||
var ExtendsElement Extendable = &extendElement{parent: 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 Extendable }
|
||||
|
||||
func (e *extendElement) Type() glib.Type { return glib.Type(C.gst_element_get_type()) }
|
||||
@@ -396,4 +486,102 @@ func (e *extendElement) InstanceSize() int64 { return int64(C.sizeof_GstElement)
|
||||
|
||||
func (e *extendElement) InitClass(klass unsafe.Pointer, elem GoElement) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
160
gst/gst_element_exports.go
Normal file
160
gst/gst_element_exports.go
Normal file
@@ -0,0 +1,160 @@
|
||||
package gst
|
||||
|
||||
/*
|
||||
#include "gst.go.h"
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"time"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
//export goGstElementClassChangeState
|
||||
func goGstElementClassChangeState(elem *C.GstElement, change C.GstStateChange) C.GstStateChangeReturn {
|
||||
iface := FromObjectUnsafePrivate(unsafe.Pointer(elem)).(interface {
|
||||
ChangeState(*Element, StateChange) StateChangeReturn
|
||||
})
|
||||
return C.GstStateChangeReturn(iface.ChangeState(wrapCbElem(elem), StateChange(change)))
|
||||
}
|
||||
|
||||
//export goGstElementClassGetState
|
||||
func goGstElementClassGetState(elem *C.GstElement, state, pending *C.GstState, timeout C.GstClockTime) C.GstStateChangeReturn {
|
||||
iface := FromObjectUnsafePrivate(unsafe.Pointer(elem)).(interface {
|
||||
GetState(*Element, time.Duration) (ret StateChangeReturn, current, pending State)
|
||||
})
|
||||
ret, cur, pend := iface.GetState(wrapCbElem(elem), time.Duration(timeout)*time.Nanosecond)
|
||||
if ret == StateChangeFailure {
|
||||
return C.GstStateChangeReturn(ret)
|
||||
}
|
||||
*state = C.GstState(cur)
|
||||
*pending = C.GstState(pend)
|
||||
return C.GstStateChangeReturn(ret)
|
||||
}
|
||||
|
||||
//export goGstElementClassNoMorePads
|
||||
func goGstElementClassNoMorePads(elem *C.GstElement) {
|
||||
iface := FromObjectUnsafePrivate(unsafe.Pointer(elem)).(interface {
|
||||
NoMorePads(*Element)
|
||||
})
|
||||
iface.NoMorePads(wrapCbElem(elem))
|
||||
}
|
||||
|
||||
//export goGstElementClassPadAdded
|
||||
func goGstElementClassPadAdded(elem *C.GstElement, pad *C.GstPad) {
|
||||
iface := FromObjectUnsafePrivate(unsafe.Pointer(elem)).(interface {
|
||||
PadAdded(*Element, *Pad)
|
||||
})
|
||||
iface.PadAdded(wrapCbElem(elem), wrapPad(toGObject(unsafe.Pointer(pad))))
|
||||
}
|
||||
|
||||
//export goGstElementClassPadRemoved
|
||||
func goGstElementClassPadRemoved(elem *C.GstElement, pad *C.GstPad) {
|
||||
iface := FromObjectUnsafePrivate(unsafe.Pointer(elem)).(interface {
|
||||
PadRemoved(*Element, *Pad)
|
||||
})
|
||||
iface.PadRemoved(wrapCbElem(elem), wrapPad(toGObject(unsafe.Pointer(pad))))
|
||||
}
|
||||
|
||||
//export goGstElementClassPostMessage
|
||||
func goGstElementClassPostMessage(elem *C.GstElement, msg *C.GstMessage) C.gboolean {
|
||||
iface := FromObjectUnsafePrivate(unsafe.Pointer(elem)).(interface {
|
||||
PostMessage(*Element, *Message) bool
|
||||
})
|
||||
return gboolean(iface.PostMessage(wrapCbElem(elem), wrapMessage(msg)))
|
||||
}
|
||||
|
||||
//export goGstElementClassProvideClock
|
||||
func goGstElementClassProvideClock(elem *C.GstElement) *C.GstClock {
|
||||
iface := FromObjectUnsafePrivate(unsafe.Pointer(elem)).(interface {
|
||||
ProvideClock(*Element) *Clock
|
||||
})
|
||||
clock := iface.ProvideClock(wrapCbElem(elem))
|
||||
if clock == nil {
|
||||
return nil
|
||||
}
|
||||
return clock.Instance()
|
||||
}
|
||||
|
||||
//export goGstElementClassQuery
|
||||
func goGstElementClassQuery(elem *C.GstElement, query *C.GstQuery) C.gboolean {
|
||||
iface := FromObjectUnsafePrivate(unsafe.Pointer(elem)).(interface {
|
||||
Query(*Element, *Query) bool
|
||||
})
|
||||
return gboolean(iface.Query(wrapCbElem(elem), wrapQuery(query)))
|
||||
}
|
||||
|
||||
//export goGstElementClassReleasePad
|
||||
func goGstElementClassReleasePad(elem *C.GstElement, pad *C.GstPad) {
|
||||
iface := FromObjectUnsafePrivate(unsafe.Pointer(elem)).(interface {
|
||||
ReleasePad(*Element, *Pad)
|
||||
})
|
||||
iface.ReleasePad(wrapCbElem(elem), wrapPad(toGObject(unsafe.Pointer(pad))))
|
||||
}
|
||||
|
||||
//export goGstElementClassRequestNewPad
|
||||
func goGstElementClassRequestNewPad(elem *C.GstElement, templ *C.GstPadTemplate, name *C.gchar, caps *C.GstCaps) *C.GstPad {
|
||||
iface := FromObjectUnsafePrivate(unsafe.Pointer(elem)).(interface {
|
||||
RequestNewPad(self *Element, templ *PadTemplate, name string, caps *Caps) *Pad
|
||||
})
|
||||
pad := iface.RequestNewPad(
|
||||
wrapCbElem(elem),
|
||||
wrapPadTemplate(toGObject(unsafe.Pointer(templ))),
|
||||
C.GoString(name),
|
||||
wrapCaps(caps),
|
||||
)
|
||||
if pad == nil {
|
||||
return nil
|
||||
}
|
||||
return pad.Instance()
|
||||
}
|
||||
|
||||
//export goGstElementClassSendEvent
|
||||
func goGstElementClassSendEvent(elem *C.GstElement, event *C.GstEvent) C.gboolean {
|
||||
iface := FromObjectUnsafePrivate(unsafe.Pointer(elem)).(interface {
|
||||
SendEvent(*Element, *Event) bool
|
||||
})
|
||||
return gboolean(iface.SendEvent(wrapCbElem(elem), wrapEvent(event)))
|
||||
}
|
||||
|
||||
//export goGstElementClassSetBus
|
||||
func goGstElementClassSetBus(elem *C.GstElement, bus *C.GstBus) {
|
||||
iface := FromObjectUnsafePrivate(unsafe.Pointer(elem)).(interface {
|
||||
SetBus(*Element, *Bus)
|
||||
})
|
||||
iface.SetBus(wrapCbElem(elem), wrapBus(toGObject(unsafe.Pointer(bus))))
|
||||
}
|
||||
|
||||
//export goGstElementClassSetClock
|
||||
func goGstElementClassSetClock(elem *C.GstElement, clock *C.GstClock) C.gboolean {
|
||||
iface := FromObjectUnsafePrivate(unsafe.Pointer(elem)).(interface {
|
||||
SetClock(*Element, *Clock) bool
|
||||
})
|
||||
return gboolean(iface.SetClock(wrapCbElem(elem), wrapClock(toGObject(unsafe.Pointer(clock)))))
|
||||
}
|
||||
|
||||
//export goGstElementClassSetContext
|
||||
func goGstElementClassSetContext(elem *C.GstElement, ctx *C.GstContext) {
|
||||
iface := FromObjectUnsafePrivate(unsafe.Pointer(elem)).(interface {
|
||||
SetContext(*Element, *Context)
|
||||
})
|
||||
iface.SetContext(wrapCbElem(elem), wrapContext(ctx))
|
||||
}
|
||||
|
||||
//export goGstElementClassSetState
|
||||
func goGstElementClassSetState(elem *C.GstElement, state C.GstState) C.GstStateChangeReturn {
|
||||
iface := FromObjectUnsafePrivate(unsafe.Pointer(elem)).(interface {
|
||||
SetState(*Element, State) StateChangeReturn
|
||||
})
|
||||
return C.GstStateChangeReturn(iface.SetState(wrapCbElem(elem), State(state)))
|
||||
}
|
||||
|
||||
//export goGstElementClassStateChanged
|
||||
func goGstElementClassStateChanged(elem *C.GstElement, old, new, pending C.GstState) {
|
||||
iface := FromObjectUnsafePrivate(unsafe.Pointer(elem)).(interface {
|
||||
StateChanged(self *Element, old, new, pending State)
|
||||
})
|
||||
iface.StateChanged(wrapCbElem(elem), State(old), State(new), State(pending))
|
||||
}
|
||||
|
||||
func wrapCbElem(elem *C.GstElement) *Element { return wrapElement(toGObject(unsafe.Pointer(elem))) }
|
@@ -7,7 +7,7 @@ import (
|
||||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
)
|
||||
|
||||
// FromGstElementUnsafe wraps the pointer to the given C GstElement with the go type.
|
||||
|
@@ -7,7 +7,7 @@ import (
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
)
|
||||
|
||||
// Event is a go wrapper around a GstEvent.
|
||||
@@ -108,7 +108,7 @@ func (e *Event) ParseFlushStop() (resetTime bool) {
|
||||
func (e *Event) ParseGap() (timestamp, duration time.Duration) {
|
||||
var ts, dur C.GstClockTime
|
||||
C.gst_event_parse_gap(e.Instance(), &ts, &dur)
|
||||
return clockTimeToDuration(ClockTime(ts)), clockTimeToDuration(ClockTime(dur))
|
||||
return time.Duration(ts), time.Duration(dur)
|
||||
}
|
||||
|
||||
// ParseGapFlags retrieves the gap flags that may have been set on a gap event with SetGapFlags.
|
||||
@@ -135,7 +135,7 @@ func (e *Event) ParseGroupID() (ok bool, gid uint) {
|
||||
func (e *Event) ParseLatency() time.Duration {
|
||||
var out C.GstClockTime
|
||||
C.gst_event_parse_latency(e.Instance(), &out)
|
||||
return clockTimeToDuration(ClockTime(out))
|
||||
return time.Duration(out)
|
||||
}
|
||||
|
||||
// ParseProtection parses an event containing protection system specific information and stores the results in
|
||||
@@ -168,7 +168,7 @@ func (e *Event) ParseQOS() (qTtype QOSType, proportion float64, diff ClockTimeDi
|
||||
e.Instance(),
|
||||
>ype, &gprop, &gdiff, >s,
|
||||
)
|
||||
return QOSType(gtype), float64(gprop), ClockTimeDiff(gdiff), clockTimeToDuration(ClockTime(gts))
|
||||
return QOSType(gtype), float64(gprop), ClockTimeDiff(gdiff), time.Duration(gts)
|
||||
}
|
||||
|
||||
// ParseSeek parses a seek event.
|
||||
@@ -187,7 +187,7 @@ func (e *Event) ParseSeek() (rate float64, format Format, flags SeekFlags, start
|
||||
func (e *Event) ParseSeekTrickModeInterval() (interval time.Duration) {
|
||||
var out C.GstClockTime
|
||||
C.gst_event_parse_seek_trickmode_interval(e.Instance(), &out)
|
||||
return clockTimeToDuration(ClockTime(out))
|
||||
return time.Duration(out)
|
||||
}
|
||||
|
||||
// ParseSegment parses a segment event and stores the result in the given segment location. segment remains valid
|
||||
@@ -324,7 +324,7 @@ func (e *Event) SetRunningTimeOffset(offset int64) {
|
||||
// SetSeekTrickModeInterval sets a trickmode interval on a (writable) seek event. Elements that support TRICKMODE_KEY_UNITS
|
||||
// seeks SHOULD use this as the minimal interval between each frame they may output.
|
||||
func (e *Event) SetSeekTrickModeInterval(interval time.Duration) {
|
||||
C.gst_event_set_seek_trickmode_interval(e.Instance(), C.GstClockTime(durationToClockTime(interval)))
|
||||
C.gst_event_set_seek_trickmode_interval(e.Instance(), C.GstClockTime(interval.Nanoseconds()))
|
||||
}
|
||||
|
||||
// SetSeqnum sets the sequence number of a event.
|
||||
|
@@ -67,8 +67,8 @@ func NewFlushStopEvent(resetTime bool) *Event {
|
||||
// especially for sparse streams such as subtitle streams.
|
||||
func NewGapEvent(timestamp, duration time.Duration) *Event {
|
||||
return wrapEvent(C.gst_event_new_gap(
|
||||
C.GstClockTime(durationToClockTime(timestamp)),
|
||||
C.GstClockTime(durationToClockTime(duration)),
|
||||
C.GstClockTime(timestamp.Nanoseconds()),
|
||||
C.GstClockTime(duration.Nanoseconds()),
|
||||
))
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ func NewGapEvent(timestamp, duration time.Duration) *Event {
|
||||
// The latency is mostly used in live sinks and is always expressed in the time format.
|
||||
func NewLatencyEvent(latency time.Duration) *Event {
|
||||
return wrapEvent(C.gst_event_new_latency(
|
||||
C.GstClockTime(durationToClockTime(latency)),
|
||||
C.GstClockTime(latency.Nanoseconds()),
|
||||
))
|
||||
}
|
||||
|
||||
@@ -168,7 +168,7 @@ func NewQOSEvent(qType QOSType, proportion float64, diff ClockTimeDiff, timestam
|
||||
C.GstQOSType(qType),
|
||||
C.gdouble(proportion),
|
||||
C.GstClockTimeDiff(diff),
|
||||
C.GstClockTime(durationToClockTime(timestamp)),
|
||||
C.GstClockTime(timestamp.Nanoseconds()),
|
||||
))
|
||||
}
|
||||
|
||||
|
@@ -4,6 +4,10 @@ package gst
|
||||
import "C"
|
||||
import "unsafe"
|
||||
|
||||
// CAT is the global DebugCategory used for logging from the bindings. It is okay to use
|
||||
// it from applications, but plugins should use their own.
|
||||
var CAT *DebugCategory
|
||||
|
||||
// Init is a wrapper around gst_init() and must be called before any
|
||||
// other gstreamer calls and is used to initialize everything necessary.
|
||||
// In addition to setting up gstreamer for usage, a pointer to a slice of
|
||||
@@ -11,6 +15,10 @@ import "unsafe"
|
||||
// args will be modified to remove any flags that were handled.
|
||||
// Alternatively, nil may be passed in to not perform any command line
|
||||
// parsing.
|
||||
//
|
||||
// The bindings will also set up their own internal DebugCategory for logging
|
||||
// than can be invoked from applications or plugins as well. However, for
|
||||
// plugins it is generally better to initialize your own DebugCategory.
|
||||
func Init(args *[]string) {
|
||||
if args != nil {
|
||||
argc := C.int(len(*args))
|
||||
@@ -29,4 +37,5 @@ func Init(args *[]string) {
|
||||
} else {
|
||||
C.gst_init(nil, nil)
|
||||
}
|
||||
CAT = NewDebugCategory("GST_GO", DebugColorNone, "GStreamer Go Bindings")
|
||||
}
|
||||
|
@@ -2,11 +2,17 @@ package gst
|
||||
|
||||
/*
|
||||
#include "gst.go.h"
|
||||
|
||||
void memcpy_offset (void * dest, guint offset, const void * src, size_t n) { memcpy(dest + offset, src, n); }
|
||||
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"io"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
@@ -20,11 +26,45 @@ func (m *MapInfo) Instance() *C.GstMapInfo {
|
||||
return m.ptr
|
||||
}
|
||||
|
||||
// Reader returns a Reader for the contents of this map's memory.
|
||||
func (m *MapInfo) Reader() io.Reader {
|
||||
return bytes.NewReader(m.Bytes())
|
||||
}
|
||||
|
||||
type mapInfoWriter struct {
|
||||
mapInfo *MapInfo
|
||||
wsize int
|
||||
}
|
||||
|
||||
func (m *mapInfoWriter) Write(p []byte) (int, error) {
|
||||
if m.wsize+len(p) > int(m.mapInfo.Size()) {
|
||||
return 0, errors.New("Attempt to write more data than allocated to MapInfo")
|
||||
}
|
||||
m.mapInfo.WriteAt(m.wsize, p)
|
||||
m.wsize += len(p)
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
// Writer returns a writer that will copy the contents passed to Write directly to the
|
||||
// map's memory sequentially. An error will be returned if an attempt is made to write
|
||||
// more data than the map can hold.
|
||||
func (m *MapInfo) Writer() io.Writer {
|
||||
return &mapInfoWriter{
|
||||
mapInfo: m,
|
||||
wsize: 0,
|
||||
}
|
||||
}
|
||||
|
||||
// WriteData writes the given sequence directly to the map's memory.
|
||||
func (m *MapInfo) WriteData(data []byte) {
|
||||
C.memcpy(unsafe.Pointer(m.ptr.data), unsafe.Pointer(&data[0]), C.gsize(len(data)))
|
||||
}
|
||||
|
||||
// WriteAt writes the given data sequence directly to the map's memory at the given offset.
|
||||
func (m *MapInfo) WriteAt(offset int, data []byte) {
|
||||
C.memcpy_offset(unsafe.Pointer(m.ptr.data), C.guint(offset), unsafe.Pointer(&data[0]), C.gsize(len(data)))
|
||||
}
|
||||
|
||||
// Memory returns the underlying memory object.
|
||||
func (m *MapInfo) Memory() *Memory {
|
||||
return wrapMemory(m.ptr.memory)
|
||||
|
@@ -8,7 +8,7 @@ import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
)
|
||||
|
||||
// Memory is a go representation of GstMemory. This object is implemented in a read-only fashion
|
||||
|
@@ -8,7 +8,7 @@ import (
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
)
|
||||
|
||||
// Message is a Go wrapper around a GstMessage. It provides convenience methods for
|
||||
@@ -170,7 +170,7 @@ func (m *Message) ParseStreamStatus() (StreamStatusType, *Element) {
|
||||
func (m *Message) ParseAsyncDone() time.Duration {
|
||||
var clockTime C.GstClockTime
|
||||
C.gst_message_parse_async_done((*C.GstMessage)(m.Instance()), &clockTime)
|
||||
return clockTimeToDuration(ClockTime(clockTime))
|
||||
return time.Duration(clockTime)
|
||||
}
|
||||
|
||||
// BufferingStats represents the buffering stats as retrieved from a GST_MESSAGE_TYPE_BUFFERING.
|
||||
@@ -339,7 +339,7 @@ type QoSValues struct {
|
||||
// The stream time of the buffer that generated the message
|
||||
StreamTime time.Duration
|
||||
// The timestamps of the buffer that generated the message
|
||||
Timestamp ClockTime
|
||||
Timestamp time.Duration
|
||||
// The duration of the buffer that generated the message
|
||||
Duration time.Duration
|
||||
}
|
||||
@@ -356,10 +356,10 @@ func (m *Message) ParseQoS() *QoSValues {
|
||||
)
|
||||
return &QoSValues{
|
||||
Live: gobool(live),
|
||||
RunningTime: guint64ToDuration(runningTime),
|
||||
StreamTime: guint64ToDuration(streamTime),
|
||||
Timestamp: ClockTime(timestamp),
|
||||
Duration: guint64ToDuration(duration),
|
||||
RunningTime: time.Duration(runningTime),
|
||||
StreamTime: time.Duration(streamTime),
|
||||
Timestamp: time.Duration(timestamp),
|
||||
Duration: time.Duration(duration),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -385,7 +385,7 @@ func (m *Message) ParseProgress() (progressType ProgressType, code, text string)
|
||||
func (m *Message) ParseResetTime() time.Duration {
|
||||
var clockTime C.GstClockTime
|
||||
C.gst_message_parse_reset_time((*C.GstMessage)(m.Instance()), &clockTime)
|
||||
return clockTimeToDuration(ClockTime(clockTime))
|
||||
return time.Duration(clockTime)
|
||||
}
|
||||
|
||||
// ParseDeviceAdded parses a device-added message. The device-added message is
|
||||
|
@@ -6,7 +6,7 @@ import (
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
)
|
||||
|
||||
func getMessageSourceObj(src interface{}) *C.GstObject {
|
||||
@@ -41,9 +41,9 @@ func NewAsyncDoneMessage(src interface{}, runningTime time.Duration) *Message {
|
||||
}
|
||||
var cTime C.GstClockTime
|
||||
if runningTime.Nanoseconds() < 0 {
|
||||
cTime = C.GstClockTime(ClockTimeNone)
|
||||
cTime = C.GstClockTime(gstClockTimeNone)
|
||||
} else {
|
||||
cTime = C.GstClockTime(durationToClockTime(runningTime))
|
||||
cTime = C.GstClockTime(runningTime.Nanoseconds())
|
||||
}
|
||||
return wrapMessage(C.gst_message_new_async_done(
|
||||
srcObj,
|
||||
@@ -312,7 +312,7 @@ func NewPropertyNotifyMessage(src interface{}, propName string, val interface{})
|
||||
return wrapMessage(C.gst_message_new_property_notify(
|
||||
srcObj,
|
||||
cName,
|
||||
(*C.GValue)(gVal.Native()),
|
||||
(*C.GValue)(unsafe.Pointer(gVal.GValue)),
|
||||
))
|
||||
}
|
||||
|
||||
@@ -332,10 +332,10 @@ func NewQoSMessage(src interface{}, live bool, runningTime, streamTime, timestam
|
||||
return wrapMessage(C.gst_message_new_qos(
|
||||
srcObj,
|
||||
gboolean(live),
|
||||
C.guint64(durationToClockTime(runningTime)),
|
||||
C.guint64(durationToClockTime(streamTime)),
|
||||
C.guint64(durationToClockTime(timestamp)),
|
||||
C.guint64(durationToClockTime(duration)),
|
||||
C.guint64((runningTime.Nanoseconds())),
|
||||
C.guint64((streamTime.Nanoseconds())),
|
||||
C.guint64((timestamp.Nanoseconds())),
|
||||
C.guint64((duration.Nanoseconds())),
|
||||
))
|
||||
}
|
||||
|
||||
@@ -410,7 +410,7 @@ func NewResetTimeMessage(src interface{}, runningTime time.Duration) *Message {
|
||||
if srcObj == nil {
|
||||
return nil
|
||||
}
|
||||
return wrapMessage(C.gst_message_new_reset_time(srcObj, C.GstClockTime(durationToClockTime(runningTime))))
|
||||
return wrapMessage(C.gst_message_new_reset_time(srcObj, C.GstClockTime(runningTime.Nanoseconds())))
|
||||
}
|
||||
|
||||
// NewSegmentDoneMessage creates a new segment done message. This message is posted by elements that finish playback of a segment as a result of a
|
||||
@@ -479,7 +479,7 @@ func NewStepDoneMessage(src interface{}, format Format, amount uint64, rate floa
|
||||
C.gdouble(rate),
|
||||
gboolean(flush),
|
||||
gboolean(intermediate),
|
||||
C.guint64(durationToClockTime(duration)),
|
||||
C.guint64(duration.Nanoseconds()),
|
||||
gboolean(eos),
|
||||
))
|
||||
}
|
||||
|
@@ -27,7 +27,7 @@ import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
)
|
||||
|
||||
// Meta is a go representation of GstMeta.
|
||||
|
@@ -6,7 +6,7 @@ import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
)
|
||||
|
||||
// MiniObject is an opaque struct meant to form the base of gstreamer
|
||||
|
@@ -6,7 +6,7 @@ import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
)
|
||||
|
||||
// Object is a go representation of a GstObject.
|
||||
|
@@ -35,7 +35,7 @@ import (
|
||||
"errors"
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
gopointer "github.com/mattn/go-pointer"
|
||||
)
|
||||
|
||||
|
@@ -5,7 +5,7 @@ import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
)
|
||||
|
||||
// PadTemplate is a go representation of a GstPadTemplate
|
||||
|
@@ -9,7 +9,7 @@ import (
|
||||
"strings"
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
)
|
||||
|
||||
// Pipeline is a go implementation of a GstPipeline.
|
||||
|
@@ -16,8 +16,19 @@ gboolean cgoGlobalPluginInit(GstPlugin * plugin)
|
||||
return goGlobalPluginInit(plugin);
|
||||
}
|
||||
|
||||
GstPluginDesc * exportPluginMeta (gint major, gint minor, gchar * name, gchar * description, GstPluginInitFunc init, gchar * version, gchar * license, gchar * source, gchar * package, gchar * origin, gchar * release_datetime)
|
||||
GstPluginDesc * getPluginMeta (gint major,
|
||||
gint minor,
|
||||
gchar * name,
|
||||
gchar * description,
|
||||
GstPluginInitFunc init,
|
||||
gchar * version,
|
||||
gchar * license,
|
||||
gchar * source,
|
||||
gchar * package,
|
||||
gchar * origin,
|
||||
gchar * release_datetime)
|
||||
{
|
||||
|
||||
GstPluginDesc * desc = malloc ( sizeof (GstPluginDesc) );
|
||||
|
||||
desc->major_version = major;
|
||||
@@ -42,7 +53,7 @@ import (
|
||||
"errors"
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
gopointer "github.com/mattn/go-pointer"
|
||||
)
|
||||
|
||||
@@ -80,10 +91,10 @@ var globalPluginInit PluginInitFunc
|
||||
// Export will export the PluginMetadata to an unsafe pointer to a GstPluginDesc.
|
||||
func (p *PluginMetadata) Export() unsafe.Pointer {
|
||||
globalPluginInit = p.Init
|
||||
desc := C.exportPluginMeta(
|
||||
desc := C.getPluginMeta(
|
||||
C.gint(p.MajorVersion),
|
||||
C.gint(p.MinorVersion),
|
||||
(*C.gchar)(C.CString(p.Name)),
|
||||
(*C.gchar)(unsafe.Pointer(&[]byte(p.Name)[0])),
|
||||
(*C.gchar)(C.CString(p.Description)),
|
||||
(C.GstPluginInitFunc(C.cgoGlobalPluginInit)),
|
||||
(*C.gchar)(C.CString(p.Version)),
|
||||
|
@@ -6,7 +6,7 @@ import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
)
|
||||
|
||||
// PluginFeature wraps the C GstPluginFeature.
|
||||
|
@@ -6,7 +6,7 @@ import (
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
)
|
||||
|
||||
// Query is a go wrapper around a GstQuery.
|
||||
@@ -332,7 +332,7 @@ func (q *Query) ParseLatency() (live bool, minLatency, maxLatency time.Duration)
|
||||
var min, max C.GstClockTime
|
||||
var gl C.gboolean
|
||||
C.gst_query_parse_latency(q.Instance(), &gl, &min, &max)
|
||||
return gobool(gl), clockTimeToDuration(ClockTime(min)), clockTimeToDuration(ClockTime(max))
|
||||
return gobool(gl), time.Duration(min), time.Duration(max)
|
||||
}
|
||||
|
||||
// ParseNumFormats parses the number of formats in the formats query.
|
||||
@@ -517,7 +517,7 @@ func (q *Query) SetFormats(formats ...Format) {
|
||||
|
||||
// SetLatency answers a latency query by setting the requested values in the given format.
|
||||
func (q *Query) SetLatency(live bool, minLatency, maxLatency time.Duration) {
|
||||
C.gst_query_set_latency(q.Instance(), gboolean(live), C.GstClockTime(durationToClockTime(minLatency)), C.GstClockTime(durationToClockTime(maxLatency)))
|
||||
C.gst_query_set_latency(q.Instance(), gboolean(live), C.guint64(minLatency.Nanoseconds()), C.guint64(maxLatency.Nanoseconds()))
|
||||
}
|
||||
|
||||
// SetAllocationParamAt sets allocation params in query.
|
||||
|
@@ -7,7 +7,7 @@ import (
|
||||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
)
|
||||
|
||||
// Registry is a go representation of a GstRegistry.
|
||||
|
@@ -6,7 +6,7 @@ import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
)
|
||||
|
||||
// Stream is a Go representation of a GstStream.
|
||||
|
@@ -7,7 +7,7 @@ import (
|
||||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
)
|
||||
|
||||
// StreamCollection is a Go representation of a GstStreamCollection.
|
||||
|
@@ -20,8 +20,8 @@ import (
|
||||
"sync"
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
gopointer "github.com/mattn/go-pointer"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
)
|
||||
|
||||
// Structure is a go implementation of a C GstStructure.
|
||||
@@ -52,7 +52,7 @@ func NewStructureFromString(stStr string) *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()))
|
||||
st := C.gst_value_get_structure((*C.GValue)(unsafe.Pointer(gval.GValue)))
|
||||
if st == nil {
|
||||
return nil
|
||||
}
|
||||
|
@@ -5,7 +5,7 @@ import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
)
|
||||
|
||||
// SystemClock wraps GstSystemClock
|
||||
|
@@ -17,8 +17,8 @@ import (
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
gopointer "github.com/mattn/go-pointer"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
)
|
||||
|
||||
// TagList is a go wrapper around a GstTagList. For now, until the rest of the methods are
|
||||
@@ -86,7 +86,7 @@ func (t *TagList) AddValue(mergeMode TagMergeMode, tag Tag, value interface{}) {
|
||||
t.Instance(),
|
||||
C.GstTagMergeMode(mergeMode),
|
||||
(*C.gchar)(ctag),
|
||||
(*C.GValue)(gVal.Native()),
|
||||
(*C.GValue)(unsafe.Pointer(gVal.GValue)),
|
||||
)
|
||||
}
|
||||
|
||||
|
@@ -5,7 +5,7 @@ import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
)
|
||||
|
||||
// InterfaceTagSetter represents the GstTagsetter interface GType. Use this when querying bins
|
||||
@@ -57,7 +57,7 @@ func (t *gstTagSetter) AddTagValue(mergeMode TagMergeMode, tagKey Tag, tagValue
|
||||
t.Instance(),
|
||||
C.GstTagMergeMode(mergeMode),
|
||||
(*C.gchar)(unsafe.Pointer(ckey)),
|
||||
(*C.GValue)(gVal.Native()),
|
||||
(*C.GValue)(unsafe.Pointer(gVal.GValue)),
|
||||
)
|
||||
}
|
||||
|
||||
|
@@ -2,7 +2,7 @@ package gst
|
||||
|
||||
// #include "gst.go.h"
|
||||
import "C"
|
||||
import "github.com/gotk3/gotk3/glib"
|
||||
import "github.com/tinyzimmer/go-glib/glib"
|
||||
|
||||
// InterfaceTOCSetter represents the GstTocSetter interface GType. Use this when querying bins
|
||||
// for elements that implement a TOCSetter.
|
||||
|
@@ -8,7 +8,7 @@ import (
|
||||
"errors"
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
)
|
||||
|
||||
// InterfaceURIHandler represents the GstURIHandler interface GType. Use this when querying bins
|
||||
|
@@ -2,17 +2,85 @@ package gst
|
||||
|
||||
/*
|
||||
#include "gst.go.h"
|
||||
|
||||
GValue * toGValue (guintptr p) { return (GValue*)(p); }
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
)
|
||||
|
||||
func init() {
|
||||
func init() { registerMarshalers() }
|
||||
|
||||
// Object wrappers
|
||||
|
||||
func wrapAllocator(obj *glib.Object) *Allocator { return &Allocator{wrapObject(obj)} }
|
||||
func wrapBin(obj *glib.Object) *Bin { return &Bin{wrapElement(obj)} }
|
||||
func wrapBuffer(buf *C.GstBuffer) *Buffer { return &Buffer{ptr: buf} }
|
||||
func wrapBufferList(bufList *C.GstBufferList) *BufferList { return &BufferList{ptr: bufList} }
|
||||
func wrapBufferPool(obj *glib.Object) *BufferPool { return &BufferPool{wrapObject(obj)} }
|
||||
func wrapBus(obj *glib.Object) *Bus { return &Bus{Object: wrapObject(obj)} }
|
||||
func wrapCaps(caps *C.GstCaps) *Caps { return &Caps{native: caps} }
|
||||
func wrapClock(obj *glib.Object) *Clock { return &Clock{wrapObject(obj)} }
|
||||
func wrapContext(ctx *C.GstContext) *Context { return &Context{ptr: ctx} }
|
||||
func wrapDevice(obj *glib.Object) *Device { return &Device{wrapObject(obj)} }
|
||||
func wrapElement(obj *glib.Object) *Element { return &Element{wrapObject(obj)} }
|
||||
func wrapEvent(ev *C.GstEvent) *Event { return &Event{ptr: ev} }
|
||||
func wrapGhostPad(obj *glib.Object) *GhostPad { return &GhostPad{wrapProxyPad(obj)} }
|
||||
func wrapMainContext(ctx *C.GMainContext) *MainContext { return &MainContext{ptr: ctx} }
|
||||
func wrapMainLoop(loop *C.GMainLoop) *MainLoop { return &MainLoop{ptr: loop} }
|
||||
func wrapMapInfo(mapInfo *C.GstMapInfo) *MapInfo { return &MapInfo{ptr: mapInfo} }
|
||||
func wrapMemory(mem *C.GstMemory) *Memory { return &Memory{ptr: mem} }
|
||||
func wrapMessage(msg *C.GstMessage) *Message { return &Message{msg: msg} }
|
||||
func wrapMeta(meta *C.GstMeta) *Meta { return &Meta{ptr: meta} }
|
||||
func wrapMetaInfo(info *C.GstMetaInfo) *MetaInfo { return &MetaInfo{ptr: info} }
|
||||
func wrapPad(obj *glib.Object) *Pad { return &Pad{wrapObject(obj)} }
|
||||
func wrapPadTemplate(obj *glib.Object) *PadTemplate { return &PadTemplate{wrapObject(obj)} }
|
||||
func wrapPipeline(obj *glib.Object) *Pipeline { return &Pipeline{Bin: wrapBin(obj)} }
|
||||
func wrapPluginFeature(obj *glib.Object) *PluginFeature { return &PluginFeature{wrapObject(obj)} }
|
||||
func wrapPlugin(obj *glib.Object) *Plugin { return &Plugin{wrapObject(obj)} }
|
||||
func wrapProxyPad(obj *glib.Object) *ProxyPad { return &ProxyPad{wrapPad(obj)} }
|
||||
func wrapQuery(query *C.GstQuery) *Query { return &Query{ptr: query} }
|
||||
func wrapRegistry(obj *glib.Object) *Registry { return &Registry{wrapObject(obj)} }
|
||||
func wrapSample(sample *C.GstSample) *Sample { return &Sample{sample: sample} }
|
||||
func wrapSegment(segment *C.GstSegment) *Segment { return &Segment{ptr: segment} }
|
||||
func wrapStream(obj *glib.Object) *Stream { return &Stream{wrapObject(obj)} }
|
||||
func wrapTagList(tagList *C.GstTagList) *TagList { return &TagList{ptr: tagList} }
|
||||
func wrapTOC(toc *C.GstToc) *TOC { return &TOC{ptr: toc} }
|
||||
func wrapTOCEntry(toc *C.GstTocEntry) *TOCEntry { return &TOCEntry{ptr: toc} }
|
||||
|
||||
func wrapCapsFeatures(features *C.GstCapsFeatures) *CapsFeatures {
|
||||
return &CapsFeatures{native: features}
|
||||
}
|
||||
|
||||
func wrapObject(obj *glib.Object) *Object {
|
||||
return &Object{InitiallyUnowned: &glib.InitiallyUnowned{Object: obj}}
|
||||
}
|
||||
|
||||
func wrapElementFactory(obj *glib.Object) *ElementFactory {
|
||||
return &ElementFactory{wrapPluginFeature(obj)}
|
||||
}
|
||||
|
||||
func wrapStreamCollection(obj *glib.Object) *StreamCollection {
|
||||
return &StreamCollection{wrapObject(obj)}
|
||||
}
|
||||
|
||||
func wrapAllocationParams(obj *C.GstAllocationParams) *AllocationParams {
|
||||
return &AllocationParams{ptr: obj}
|
||||
}
|
||||
|
||||
func wrapElementClass(klass C.gpointer) *ElementClass {
|
||||
return &ElementClass{&ObjectClass{ptr: C.toGObjectClass(unsafe.Pointer(klass))}}
|
||||
}
|
||||
|
||||
// Marshallers
|
||||
|
||||
func uintptrToGVal(p uintptr) *C.GValue { return (*C.GValue)(C.toGValue(C.guintptr(p))) }
|
||||
|
||||
func registerMarshalers() {
|
||||
tm := []glib.TypeMarshaler{
|
||||
{
|
||||
T: glib.Type(C.gst_buffering_mode_get_type()),
|
||||
@@ -147,92 +215,6 @@ func init() {
|
||||
glib.RegisterGValueMarshalers(tm)
|
||||
}
|
||||
|
||||
func uintptrToGVal(p uintptr) *C.GValue {
|
||||
return (*C.GValue)(unsafe.Pointer(p)) // vet thinks this is unsafe and there is no way around it for now.
|
||||
// but the given ptr is an address to a C object so go's concerns are misplaced.
|
||||
}
|
||||
|
||||
// Object wrappers
|
||||
|
||||
func wrapAllocator(obj *glib.Object) *Allocator { return &Allocator{wrapObject(obj)} }
|
||||
func wrapBin(obj *glib.Object) *Bin { return &Bin{wrapElement(obj)} }
|
||||
func wrapBuffer(buf *C.GstBuffer) *Buffer { return &Buffer{ptr: buf} }
|
||||
func wrapBufferList(bufList *C.GstBufferList) *BufferList { return &BufferList{ptr: bufList} }
|
||||
func wrapBufferPool(obj *glib.Object) *BufferPool { return &BufferPool{wrapObject(obj)} }
|
||||
func wrapBus(obj *glib.Object) *Bus { return &Bus{Object: wrapObject(obj)} }
|
||||
func wrapCaps(caps *C.GstCaps) *Caps { return &Caps{native: caps} }
|
||||
func wrapClock(obj *glib.Object) *Clock { return &Clock{wrapObject(obj)} }
|
||||
func wrapContext(ctx *C.GstContext) *Context { return &Context{ptr: ctx} }
|
||||
func wrapDevice(obj *glib.Object) *Device { return &Device{wrapObject(obj)} }
|
||||
func wrapElement(obj *glib.Object) *Element { return &Element{wrapObject(obj)} }
|
||||
func wrapEvent(ev *C.GstEvent) *Event { return &Event{ptr: ev} }
|
||||
func wrapGhostPad(obj *glib.Object) *GhostPad { return &GhostPad{wrapProxyPad(obj)} }
|
||||
func wrapMainContext(ctx *C.GMainContext) *MainContext { return &MainContext{ptr: ctx} }
|
||||
func wrapMainLoop(loop *C.GMainLoop) *MainLoop { return &MainLoop{ptr: loop} }
|
||||
func wrapMapInfo(mapInfo *C.GstMapInfo) *MapInfo { return &MapInfo{ptr: mapInfo} }
|
||||
func wrapMemory(mem *C.GstMemory) *Memory { return &Memory{ptr: mem} }
|
||||
func wrapMessage(msg *C.GstMessage) *Message { return &Message{msg: msg} }
|
||||
func wrapMeta(meta *C.GstMeta) *Meta { return &Meta{ptr: meta} }
|
||||
func wrapMetaInfo(info *C.GstMetaInfo) *MetaInfo { return &MetaInfo{ptr: info} }
|
||||
func wrapPad(obj *glib.Object) *Pad { return &Pad{wrapObject(obj)} }
|
||||
func wrapPadTemplate(obj *glib.Object) *PadTemplate { return &PadTemplate{wrapObject(obj)} }
|
||||
func wrapPipeline(obj *glib.Object) *Pipeline { return &Pipeline{Bin: wrapBin(obj)} }
|
||||
func wrapPluginFeature(obj *glib.Object) *PluginFeature { return &PluginFeature{wrapObject(obj)} }
|
||||
func wrapPlugin(obj *glib.Object) *Plugin { return &Plugin{wrapObject(obj)} }
|
||||
func wrapProxyPad(obj *glib.Object) *ProxyPad { return &ProxyPad{wrapPad(obj)} }
|
||||
func wrapQuery(query *C.GstQuery) *Query { return &Query{ptr: query} }
|
||||
func wrapRegistry(obj *glib.Object) *Registry { return &Registry{wrapObject(obj)} }
|
||||
func wrapSample(sample *C.GstSample) *Sample { return &Sample{sample: sample} }
|
||||
func wrapSegment(segment *C.GstSegment) *Segment { return &Segment{ptr: segment} }
|
||||
func wrapStream(obj *glib.Object) *Stream { return &Stream{wrapObject(obj)} }
|
||||
func wrapTagList(tagList *C.GstTagList) *TagList { return &TagList{ptr: tagList} }
|
||||
func wrapTOC(toc *C.GstToc) *TOC { return &TOC{ptr: toc} }
|
||||
func wrapTOCEntry(toc *C.GstTocEntry) *TOCEntry { return &TOCEntry{ptr: toc} }
|
||||
|
||||
func wrapCapsFeatures(features *C.GstCapsFeatures) *CapsFeatures {
|
||||
return &CapsFeatures{native: features}
|
||||
}
|
||||
|
||||
func wrapObject(obj *glib.Object) *Object {
|
||||
return &Object{InitiallyUnowned: &glib.InitiallyUnowned{Object: obj}}
|
||||
}
|
||||
|
||||
func wrapElementFactory(obj *glib.Object) *ElementFactory {
|
||||
return &ElementFactory{wrapPluginFeature(obj)}
|
||||
}
|
||||
|
||||
func wrapStreamCollection(obj *glib.Object) *StreamCollection {
|
||||
return &StreamCollection{wrapObject(obj)}
|
||||
}
|
||||
|
||||
func wrapAllocationParams(obj *C.GstAllocationParams) *AllocationParams {
|
||||
return &AllocationParams{ptr: obj}
|
||||
}
|
||||
|
||||
func wrapElementClass(klass C.gpointer) *ElementClass {
|
||||
return &ElementClass{&ObjectClass{ptr: C.toGObjectClass(unsafe.Pointer(klass))}}
|
||||
}
|
||||
|
||||
// Clock wrappers
|
||||
|
||||
func clockTimeToDuration(n ClockTime) time.Duration {
|
||||
if n == ClockTimeNone {
|
||||
return time.Duration(-1)
|
||||
}
|
||||
return time.Duration(uint64(n)) * time.Nanosecond
|
||||
}
|
||||
|
||||
func guint64ToDuration(n C.guint64) time.Duration { return clockTimeToDuration(ClockTime(n)) }
|
||||
|
||||
func durationToClockTime(dur time.Duration) ClockTime {
|
||||
if dur.Nanoseconds() < 0 {
|
||||
return ClockTimeNone
|
||||
}
|
||||
return ClockTime(dur.Nanoseconds())
|
||||
}
|
||||
|
||||
// Marshallers
|
||||
|
||||
func marshalBufferingMode(p uintptr) (interface{}, error) {
|
||||
c := C.g_value_get_enum(uintptrToGVal(p))
|
||||
return BufferingMode(c), nil
|
||||
|
@@ -15,13 +15,13 @@ import (
|
||||
"reflect"
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
gopointer "github.com/mattn/go-pointer"
|
||||
)
|
||||
|
||||
// GoElement is an interface to be implemented by GStreamer elements built using the
|
||||
// go bindings. Select methods from other interfaces can be overridden and declared via
|
||||
// the Extendable properties.
|
||||
// the Extendable property provided at plugin registration.
|
||||
//
|
||||
// Typically, at the very least, an element will want to implement methods from the Element
|
||||
// Extendable (and by extension the GoObject).
|
||||
@@ -68,7 +68,6 @@ type classData struct {
|
||||
func gtypeForGoElement(name string, elem GoElement, extendable Extendable) C.GType {
|
||||
registerMutex.Lock()
|
||||
defer registerMutex.Unlock()
|
||||
// fmt.Printf("Checking registration of %v\n", reflect.TypeOf(elem).String())
|
||||
if registered, ok := registeredTypes[reflect.TypeOf(elem).String()]; ok {
|
||||
return registered
|
||||
}
|
||||
@@ -96,7 +95,6 @@ func gtypeForGoElement(name string, elem GoElement, extendable Extendable) C.GTy
|
||||
C.GTypeFlags(0),
|
||||
)
|
||||
elem.TypeInit(&TypeInstance{gtype: gtype, gotype: elem})
|
||||
// fmt.Printf("Registering %v to type %v\n", reflect.TypeOf(elem).String(), gtype)
|
||||
registeredTypes[reflect.TypeOf(elem).String()] = gtype
|
||||
return gtype
|
||||
}
|
||||
|
@@ -8,7 +8,7 @@ import (
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
"github.com/tinyzimmer/go-gst/gst"
|
||||
)
|
||||
|
||||
|
@@ -2,7 +2,7 @@ package gst
|
||||
|
||||
/*
|
||||
#cgo pkg-config: gstreamer-1.0
|
||||
#cgo CFLAGS: -Wno-deprecated-declarations -g -Wall
|
||||
#cgo CFLAGS: -Wno-deprecated-declarations -Wno-format-security -g -Wall
|
||||
#cgo LDFLAGS: -lm
|
||||
*/
|
||||
import "C"
|
||||
|
@@ -13,7 +13,7 @@ import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
"github.com/tinyzimmer/go-gst/gst"
|
||||
)
|
||||
|
||||
|
@@ -35,7 +35,6 @@ gint infoWidth (GstVideoInfo * info)
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"runtime"
|
||||
"unsafe"
|
||||
|
||||
"github.com/tinyzimmer/go-gst/gst"
|
||||
@@ -164,10 +163,13 @@ type Info struct {
|
||||
|
||||
func wrapInfo(vinfo *C.GstVideoInfo) *Info {
|
||||
info := &Info{vinfo}
|
||||
runtime.SetFinalizer(info, func(i *Info) { C.gst_video_info_free(vinfo) })
|
||||
return info
|
||||
}
|
||||
|
||||
func (i *Info) Free() {
|
||||
C.gst_video_info_free(i.instance())
|
||||
}
|
||||
|
||||
// instance returns the underlying GstVideoInfo instance.
|
||||
func (i *Info) instance() *C.GstVideoInfo { return i.ptr }
|
||||
|
||||
|
Reference in New Issue
Block a user