mirror of
https://github.com/go-gst/go-gst.git
synced 2025-09-27 04:15:56 +08:00
change clockTime type, add more bindings
This commit is contained in:
@@ -6,7 +6,6 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/go-gst/go-gst/examples"
|
"github.com/go-gst/go-gst/examples"
|
||||||
"github.com/go-gst/go-gst/gst"
|
"github.com/go-gst/go-gst/gst"
|
||||||
@@ -116,7 +115,7 @@ func mainLoop(pipeline *gst.Pipeline) error {
|
|||||||
|
|
||||||
// Loop over messsages from the pipeline
|
// Loop over messsages from the pipeline
|
||||||
for {
|
for {
|
||||||
msg := bus.TimedPop(time.Duration(-1))
|
msg := bus.TimedPop(gst.ClockTimeNone)
|
||||||
if msg == nil {
|
if msg == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@@ -13,7 +13,6 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/go-gst/go-glib/glib"
|
"github.com/go-gst/go-glib/glib"
|
||||||
"github.com/go-gst/go-gst/examples"
|
"github.com/go-gst/go-gst/examples"
|
||||||
@@ -87,7 +86,7 @@ func padProbes(mainLoop *glib.MainLoop) error {
|
|||||||
|
|
||||||
// Block on messages coming in from the bus instead of using the main loop
|
// Block on messages coming in from the bus instead of using the main loop
|
||||||
for {
|
for {
|
||||||
msg := pipeline.GetPipelineBus().TimedPop(time.Duration(-1))
|
msg := pipeline.GetPipelineBus().TimedPop(gst.ClockTimeNone)
|
||||||
if msg == nil {
|
if msg == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@@ -23,7 +23,6 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/go-gst/go-gst/examples"
|
"github.com/go-gst/go-gst/examples"
|
||||||
"github.com/go-gst/go-gst/gst"
|
"github.com/go-gst/go-gst/gst"
|
||||||
@@ -65,7 +64,7 @@ func tagsetter() error {
|
|||||||
var cont bool
|
var cont bool
|
||||||
var pipelineErr error
|
var pipelineErr error
|
||||||
for {
|
for {
|
||||||
msg := pipeline.GetPipelineBus().TimedPop(time.Duration(-1))
|
msg := pipeline.GetPipelineBus().TimedPop(gst.ClockTimeNone)
|
||||||
if msg == nil {
|
if msg == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@@ -87,7 +87,7 @@ func tagsetter(mainLoop *glib.MainLoop) error {
|
|||||||
// timed_pop on the bus with the desired timeout for when to stop waiting for new messages.
|
// timed_pop on the bus with the desired timeout for when to stop waiting for new messages.
|
||||||
// (-1 = Wait forever)
|
// (-1 = Wait forever)
|
||||||
for {
|
for {
|
||||||
msg := pipeline.GetPipelineBus().TimedPop(time.Duration(-1))
|
msg := pipeline.GetPipelineBus().TimedPop(gst.ClockTimeNone)
|
||||||
switch msg.Type() {
|
switch msg.Type() {
|
||||||
|
|
||||||
// When we use this method of popping from the bus (instead of a Watch), we own a
|
// When we use this method of popping from the bus (instead of a Watch), we own a
|
||||||
|
@@ -18,7 +18,6 @@ gboolean cgoSeekDataCb (GstAppSrc *src, guint64 offset, gpointer user_data) {
|
|||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
import (
|
import (
|
||||||
"time"
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/go-gst/go-gst/gst"
|
"github.com/go-gst/go-gst/gst"
|
||||||
@@ -91,12 +90,10 @@ func (a *Source) GetCurrentLevelBytes() uint64 {
|
|||||||
var gstClockTimeNone C.GstClockTime = 0xffffffffffffffff
|
var gstClockTimeNone C.GstClockTime = 0xffffffffffffffff
|
||||||
|
|
||||||
// GetDuration gets the duration of the stream in nanoseconds. A negative value means that the duration is not known.
|
// 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 {
|
func (a *Source) GetDuration() gst.ClockTime {
|
||||||
dur := C.gst_app_src_get_duration(a.Instance())
|
dur := C.gst_app_src_get_duration(a.Instance())
|
||||||
if dur == gstClockTimeNone {
|
|
||||||
return gst.ClockTimeNone
|
return gst.ClockTime(dur)
|
||||||
}
|
|
||||||
return time.Duration(uint64(dur)) * time.Nanosecond
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetEmitSignals checks if appsrc will emit the "new-preroll" and "new-buffer" signals.
|
// GetEmitSignals checks if appsrc will emit the "new-preroll" and "new-buffer" signals.
|
||||||
@@ -189,8 +186,8 @@ func (a *Source) SetCaps(caps *gst.Caps) {
|
|||||||
|
|
||||||
// SetDuration sets the duration of the source stream. You should call
|
// SetDuration sets the duration of the source stream. You should call
|
||||||
// this if the value is known.
|
// this if the value is known.
|
||||||
func (a *Source) SetDuration(dur time.Duration) {
|
func (a *Source) SetDuration(dur gst.ClockTime) {
|
||||||
C.gst_app_src_set_duration((*C.GstAppSrc)(a.Instance()), C.GstClockTime(dur.Nanoseconds()))
|
C.gst_app_src_set_duration((*C.GstAppSrc)(a.Instance()), C.GstClockTime(dur))
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetEmitSignals makes appsrc emit the "new-preroll" and "new-buffer" signals. This option is by default disabled because signal emission
|
// SetEmitSignals makes appsrc emit the "new-preroll" and "new-buffer" signals. This option is by default disabled because signal emission
|
||||||
|
@@ -10,7 +10,6 @@ package gst
|
|||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/go-gst/go-glib/glib"
|
"github.com/go-gst/go-glib/glib"
|
||||||
@@ -224,7 +223,7 @@ func goClockCb(gclock *C.GstClock, clockTime C.GstClockTime, clockID C.GstClockI
|
|||||||
}
|
}
|
||||||
|
|
||||||
clock := wrapClock(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(gclock))})
|
clock := wrapClock(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(gclock))})
|
||||||
return gboolean(cb(clock, time.Duration(clockTime)))
|
return gboolean(cb(clock, ClockTime(clockTime)))
|
||||||
}
|
}
|
||||||
|
|
||||||
//export goPluginInit
|
//export goPluginInit
|
||||||
|
@@ -38,18 +38,11 @@ const (
|
|||||||
type ClockTimeDiff int64
|
type ClockTimeDiff int64
|
||||||
|
|
||||||
// ClockTimeNone means infinite timeout or an empty value
|
// ClockTimeNone means infinite timeout or an empty value
|
||||||
var ClockTimeNone time.Duration = time.Duration(-1)
|
var ClockTimeNone ClockTime = C.GST_CLOCK_TIME_NONE
|
||||||
|
|
||||||
// BufferOffsetNone is a var for no-offset return results.
|
// BufferOffsetNone is a var for no-offset return results.
|
||||||
var BufferOffsetNone time.Duration = time.Duration(-1)
|
var BufferOffsetNone time.Duration = time.Duration(-1)
|
||||||
|
|
||||||
var (
|
|
||||||
// ClockTimeNone means infinite timeout (unsigned representation of -1) or an otherwise unknown value.
|
|
||||||
gstClockTimeNone C.GstClockTime = 0xffffffffffffffff
|
|
||||||
// // BufferOffsetNone is a constant for no-offset return results.
|
|
||||||
// gstBufferOffsetNone C.GstClockTime = 0xffffffffffffffff
|
|
||||||
)
|
|
||||||
|
|
||||||
// ClockEntryType wraps GstClockEntryType
|
// ClockEntryType wraps GstClockEntryType
|
||||||
type ClockEntryType int
|
type ClockEntryType int
|
||||||
|
|
||||||
|
30
gst/control_binding.go
Normal file
30
gst/control_binding.go
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
package gst
|
||||||
|
|
||||||
|
// #include "gst.go.h"
|
||||||
|
import "C"
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/go-gst/go-glib/glib"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ControlBinding struct{ *Object }
|
||||||
|
|
||||||
|
func (cb *ControlBinding) Instance() *C.GstControlBinding {
|
||||||
|
return C.toGstControlBinding(cb.Unsafe())
|
||||||
|
}
|
||||||
|
|
||||||
|
type DirectControlBinding struct{ ControlBinding }
|
||||||
|
|
||||||
|
func NewDirectControlBinding(obj *Object, prop string, csource *InterpolationControlSource) *DirectControlBinding {
|
||||||
|
cprop := C.CString(prop)
|
||||||
|
defer C.free(unsafe.Pointer(cprop))
|
||||||
|
|
||||||
|
cbinding := C.gst_direct_control_binding_new(obj.Instance(), cprop, csource.Instance())
|
||||||
|
|
||||||
|
return &DirectControlBinding{
|
||||||
|
ControlBinding: ControlBinding{
|
||||||
|
Object: wrapObject(glib.TransferNone(unsafe.Pointer(cbinding))),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
27
gst/control_source.go
Normal file
27
gst/control_source.go
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
package gst
|
||||||
|
|
||||||
|
// #include "gst.go.h"
|
||||||
|
import "C"
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/go-gst/go-glib/glib"
|
||||||
|
)
|
||||||
|
|
||||||
|
type InterpolationControlSource struct{ *Object }
|
||||||
|
|
||||||
|
func (cs *InterpolationControlSource) Instance() *C.GstControlSource {
|
||||||
|
return C.toGstControlSource(cs.Unsafe())
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewInterpolationControlSource() *InterpolationControlSource {
|
||||||
|
cCs := C.gst_interpolation_control_source_new()
|
||||||
|
|
||||||
|
return &InterpolationControlSource{
|
||||||
|
Object: wrapObject(glib.TransferNone(unsafe.Pointer(cCs))),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cs *InterpolationControlSource) SetTimedValue(time ClockTime, value float64) {
|
||||||
|
C.gst_timed_value_control_source_set(C.toGstTimedValueControlSource(cs.Unsafe()), C.ulong(time), C.double(value))
|
||||||
|
}
|
85
gst/gst.go.c
85
gst/gst.go.c
@@ -1,47 +1,50 @@
|
|||||||
#include "gst.go.h"
|
#include "gst.go.h"
|
||||||
|
|
||||||
GType objectGType (GObject *obj) { return G_OBJECT_TYPE(obj); };
|
GType objectGType (GObject *obj) { return G_OBJECT_TYPE(obj); };
|
||||||
|
|
||||||
GstAllocator * toGstAllocator (void *p) { return (GST_ALLOCATOR_CAST(p)); }
|
GstAllocator * toGstAllocator (void *p) { return (GST_ALLOCATOR_CAST(p)); }
|
||||||
GstBin * toGstBin (void *p) { return (GST_BIN(p)); }
|
GstBin * toGstBin (void *p) { return (GST_BIN(p)); }
|
||||||
GstBinClass * toGstBinClass (void *p) { return (GST_BIN_CLASS(p)); }
|
GstBinClass * toGstBinClass (void *p) { return (GST_BIN_CLASS(p)); }
|
||||||
GstBufferList * toGstBufferList (void *p) { return (GST_BUFFER_LIST(p)); }
|
GstBufferList * toGstBufferList (void *p) { return (GST_BUFFER_LIST(p)); }
|
||||||
GstBufferPool * toGstBufferPool (void *p) { return (GST_BUFFER_POOL(p)); }
|
GstBufferPool * toGstBufferPool (void *p) { return (GST_BUFFER_POOL(p)); }
|
||||||
GstBuffer * toGstBuffer (void *p) { return (GST_BUFFER(p)); }
|
GstBuffer * toGstBuffer (void *p) { return (GST_BUFFER(p)); }
|
||||||
GstBus * toGstBus (void *p) { return (GST_BUS(p)); }
|
GstBus * toGstBus (void *p) { return (GST_BUS(p)); }
|
||||||
GstCapsFeatures * toGstCapsFeatures (void *p) { return (GST_CAPS_FEATURES(p)); }
|
GstCapsFeatures * toGstCapsFeatures (void *p) { return (GST_CAPS_FEATURES(p)); }
|
||||||
GstCaps * toGstCaps (void *p) { return (GST_CAPS(p)); }
|
GstCaps * toGstCaps (void *p) { return (GST_CAPS(p)); }
|
||||||
GstChildProxy * toGstChildProxy (void *p) { return (GST_CHILD_PROXY(p)); }
|
GstChildProxy * toGstChildProxy (void *p) { return (GST_CHILD_PROXY(p)); }
|
||||||
GstClock * toGstClock (void *p) { return (GST_CLOCK(p)); }
|
GstClock * toGstClock (void *p) { return (GST_CLOCK(p)); }
|
||||||
GstContext * toGstContext (void *p) { return (GST_CONTEXT_CAST(p)); }
|
GstContext * toGstContext (void *p) { return (GST_CONTEXT_CAST(p)); }
|
||||||
GstDevice * toGstDevice (void *p) { return (GST_DEVICE_CAST(p)); }
|
GstDevice * toGstDevice (void *p) { return (GST_DEVICE_CAST(p)); }
|
||||||
GstElementFactory * toGstElementFactory (void *p) { return (GST_ELEMENT_FACTORY(p)); }
|
GstElementFactory * toGstElementFactory (void *p) { return (GST_ELEMENT_FACTORY(p)); }
|
||||||
GstElementClass * toGstElementClass (void *p) { return (GST_ELEMENT_CLASS(p)); }
|
GstElementClass * toGstElementClass (void *p) { return (GST_ELEMENT_CLASS(p)); }
|
||||||
GstElement * toGstElement (void *p) { return (GST_ELEMENT(p)); }
|
GstElement * toGstElement (void *p) { return (GST_ELEMENT(p)); }
|
||||||
GstEvent * toGstEvent (void *p) { return (GST_EVENT(p)); }
|
GstEvent * toGstEvent (void *p) { return (GST_EVENT(p)); }
|
||||||
GstGhostPad * toGstGhostPad (void *p) { return (GST_GHOST_PAD(p)); }
|
GstGhostPad * toGstGhostPad (void *p) { return (GST_GHOST_PAD(p)); }
|
||||||
GstMemory * toGstMemory (void *p) { return (GST_MEMORY_CAST(p)); }
|
GstMemory * toGstMemory (void *p) { return (GST_MEMORY_CAST(p)); }
|
||||||
GstMessage * toGstMessage (void *p) { return (GST_MESSAGE(p)); }
|
GstMessage * toGstMessage (void *p) { return (GST_MESSAGE(p)); }
|
||||||
GstMeta * toGstMeta (void *p) { return (GST_META_CAST(p)); }
|
GstMeta * toGstMeta (void *p) { return (GST_META_CAST(p)); }
|
||||||
GstMiniObject * toGstMiniObject (void *p) { return (GST_MINI_OBJECT(p)); }
|
GstMiniObject * toGstMiniObject (void *p) { return (GST_MINI_OBJECT(p)); }
|
||||||
GstObject * toGstObject (void *p) { return (GST_OBJECT(p)); }
|
GstObject * toGstObject (void *p) { return (GST_OBJECT(p)); }
|
||||||
GstPad * toGstPad (void *p) { return (GST_PAD(p)); }
|
GstPad * toGstPad (void *p) { return (GST_PAD(p)); }
|
||||||
GstPadTemplate * toGstPadTemplate (void *p) { return (GST_PAD_TEMPLATE(p)); }
|
GstPadTemplate * toGstPadTemplate (void *p) { return (GST_PAD_TEMPLATE(p)); }
|
||||||
GstPipeline * toGstPipeline (void *p) { return (GST_PIPELINE(p)); }
|
GstPipeline * toGstPipeline (void *p) { return (GST_PIPELINE(p)); }
|
||||||
GstPluginFeature * toGstPluginFeature (void *p) { return (GST_PLUGIN_FEATURE(p)); }
|
GstPluginFeature * toGstPluginFeature (void *p) { return (GST_PLUGIN_FEATURE(p)); }
|
||||||
GstPlugin * toGstPlugin (void *p) { return (GST_PLUGIN(p)); }
|
GstPlugin * toGstPlugin (void *p) { return (GST_PLUGIN(p)); }
|
||||||
GstProxyPad * toGstProxyPad (void *p) { return (GST_PROXY_PAD(p)); }
|
GstProxyPad * toGstProxyPad (void *p) { return (GST_PROXY_PAD(p)); }
|
||||||
GstQuery * toGstQuery (void *p) { return (GST_QUERY(p)); }
|
GstQuery * toGstQuery (void *p) { return (GST_QUERY(p)); }
|
||||||
GstRegistry * toGstRegistry (void *p) { return (GST_REGISTRY(p)); }
|
GstRegistry * toGstRegistry (void *p) { return (GST_REGISTRY(p)); }
|
||||||
GstSample * toGstSample (void *p) { return (GST_SAMPLE(p)); }
|
GstSample * toGstSample (void *p) { return (GST_SAMPLE(p)); }
|
||||||
GstStreamCollection * toGstStreamCollection (void *p) { return (GST_STREAM_COLLECTION_CAST(p)); }
|
GstStreamCollection * toGstStreamCollection (void *p) { return (GST_STREAM_COLLECTION_CAST(p)); }
|
||||||
GstStream * toGstStream (void *p) { return (GST_STREAM_CAST(p)); }
|
GstStream * toGstStream (void *p) { return (GST_STREAM_CAST(p)); }
|
||||||
GstStructure * toGstStructure (void *p) { return (GST_STRUCTURE(p)); }
|
GstStructure * toGstStructure (void *p) { return (GST_STRUCTURE(p)); }
|
||||||
GstTagList * toGstTagList (void *p) { return (GST_TAG_LIST(p)); }
|
GstTagList * toGstTagList (void *p) { return (GST_TAG_LIST(p)); }
|
||||||
GstTask * toGstTask (void *p) { return (GST_TASK_CAST(p)); }
|
GstTask * toGstTask (void *p) { return (GST_TASK_CAST(p)); }
|
||||||
GstTaskPool * toGstTaskPool (void *p) { return (GST_TASK_POOL_CAST(p)); }
|
GstTaskPool * toGstTaskPool (void *p) { return (GST_TASK_POOL_CAST(p)); }
|
||||||
GstURIHandler * toGstURIHandler (void *p) { return (GST_URI_HANDLER(p)); }
|
GstURIHandler * toGstURIHandler (void *p) { return (GST_URI_HANDLER(p)); }
|
||||||
GstUri * toGstURI (void *p) { return (GST_URI(p)); }
|
GstUri * toGstURI (void *p) { return (GST_URI(p)); }
|
||||||
|
GstControlBinding * toGstControlBinding (void *p) { return (GST_CONTROL_BINDING(p)); }
|
||||||
|
GstControlSource * toGstControlSource (void *p) { return (GST_CONTROL_SOURCE(p)); }
|
||||||
|
GstTimedValueControlSource * toGstTimedValueControlSource (void *p) { return (GST_TIMED_VALUE_CONTROL_SOURCE(p)); }
|
||||||
|
|
||||||
/* Buffer Utilities */
|
/* Buffer Utilities */
|
||||||
|
|
||||||
|
87
gst/gst.go.h
87
gst/gst.go.h
@@ -4,6 +4,8 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include <gst/base/base.h>
|
#include <gst/base/base.h>
|
||||||
|
#include <gst/controller/gstinterpolationcontrolsource.h>
|
||||||
|
#include <gst/controller/gstdirectcontrolbinding.h>
|
||||||
|
|
||||||
typedef struct _PadDestroyNotifyInfo {
|
typedef struct _PadDestroyNotifyInfo {
|
||||||
gpointer pad_ptr;
|
gpointer pad_ptr;
|
||||||
@@ -14,48 +16,51 @@ typedef struct _PadDestroyNotifyInfo {
|
|||||||
Type Castings
|
Type Castings
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern GType objectGType (GObject *obj);
|
extern GType objectGType (GObject *obj);
|
||||||
|
|
||||||
extern GstAllocator * toGstAllocator (void *p);
|
extern GstAllocator * toGstAllocator (void *p);
|
||||||
extern GstBin * toGstBin (void *p);
|
extern GstBin * toGstBin (void *p);
|
||||||
extern GstBinClass * toGstBinClass (void *p);
|
extern GstBinClass * toGstBinClass (void *p);
|
||||||
extern GstBufferList * toGstBufferList (void *p);
|
extern GstBufferList * toGstBufferList (void *p);
|
||||||
extern GstBufferPool * toGstBufferPool (void *p);
|
extern GstBufferPool * toGstBufferPool (void *p);
|
||||||
extern GstBuffer * toGstBuffer (void *p);
|
extern GstBuffer * toGstBuffer (void *p);
|
||||||
extern GstBus * toGstBus (void *p);
|
extern GstBus * toGstBus (void *p);
|
||||||
extern GstCapsFeatures * toGstCapsFeatures (void *p);
|
extern GstCapsFeatures * toGstCapsFeatures (void *p);
|
||||||
extern GstCaps * toGstCaps (void *p);
|
extern GstCaps * toGstCaps (void *p);
|
||||||
extern GstChildProxy * toGstChildProxy (void *p);
|
extern GstChildProxy * toGstChildProxy (void *p);
|
||||||
extern GstClock * toGstClock (void *p);
|
extern GstClock * toGstClock (void *p);
|
||||||
extern GstContext * toGstContext (void *p);
|
extern GstContext * toGstContext (void *p);
|
||||||
extern GstDevice * toGstDevice (void *p);
|
extern GstDevice * toGstDevice (void *p);
|
||||||
extern GstElementFactory * toGstElementFactory (void *p);
|
extern GstElementFactory * toGstElementFactory (void *p);
|
||||||
extern GstElementClass * toGstElementClass (void *p);
|
extern GstElementClass * toGstElementClass (void *p);
|
||||||
extern GstElement * toGstElement (void *p);
|
extern GstElement * toGstElement (void *p);
|
||||||
extern GstEvent * toGstEvent (void *p);
|
extern GstEvent * toGstEvent (void *p);
|
||||||
extern GstGhostPad * toGstGhostPad (void *p);
|
extern GstGhostPad * toGstGhostPad (void *p);
|
||||||
extern GstMemory * toGstMemory (void *p);
|
extern GstMemory * toGstMemory (void *p);
|
||||||
extern GstMessage * toGstMessage (void *p);
|
extern GstMessage * toGstMessage (void *p);
|
||||||
extern GstMeta * toGstMeta (void *p);
|
extern GstMeta * toGstMeta (void *p);
|
||||||
extern GstMiniObject * toGstMiniObject (void *p);
|
extern GstMiniObject * toGstMiniObject (void *p);
|
||||||
extern GstObject * toGstObject (void *p);
|
extern GstObject * toGstObject (void *p);
|
||||||
extern GstPad * toGstPad (void *p);
|
extern GstPad * toGstPad (void *p);
|
||||||
extern GstPadTemplate * toGstPadTemplate (void *p);
|
extern GstPadTemplate * toGstPadTemplate (void *p);
|
||||||
extern GstPipeline * toGstPipeline (void *p);
|
extern GstPipeline * toGstPipeline (void *p);
|
||||||
extern GstPluginFeature * toGstPluginFeature (void *p);
|
extern GstPluginFeature * toGstPluginFeature (void *p);
|
||||||
extern GstPlugin * toGstPlugin (void *p);
|
extern GstPlugin * toGstPlugin (void *p);
|
||||||
extern GstProxyPad * toGstProxyPad (void *p);
|
extern GstProxyPad * toGstProxyPad (void *p);
|
||||||
extern GstQuery * toGstQuery (void *p);
|
extern GstQuery * toGstQuery (void *p);
|
||||||
extern GstRegistry * toGstRegistry (void *p);
|
extern GstRegistry * toGstRegistry (void *p);
|
||||||
extern GstSample * toGstSample (void *p);
|
extern GstSample * toGstSample (void *p);
|
||||||
extern GstStreamCollection * toGstStreamCollection (void *p);
|
extern GstStreamCollection * toGstStreamCollection (void *p);
|
||||||
extern GstStream * toGstStream (void *p);
|
extern GstStream * toGstStream (void *p);
|
||||||
extern GstStructure * toGstStructure (void *p);
|
extern GstStructure * toGstStructure (void *p);
|
||||||
extern GstTagList * toGstTagList (void *p);
|
extern GstTagList * toGstTagList (void *p);
|
||||||
extern GstTask * toGstTask (void *p);
|
extern GstTask * toGstTask (void *p);
|
||||||
extern GstTaskPool * toGstTaskPool (void *p);
|
extern GstTaskPool * toGstTaskPool (void *p);
|
||||||
extern GstURIHandler * toGstURIHandler (void *p);
|
extern GstURIHandler * toGstURIHandler (void *p);
|
||||||
extern GstUri * toGstURI (void *p);
|
extern GstUri * toGstURI (void *p);
|
||||||
|
extern GstControlBinding * toGstControlBinding (void *p);
|
||||||
|
extern GstControlSource * toGstControlSource (void *p);
|
||||||
|
extern GstTimedValueControlSource * toGstTimedValueControlSource (void *p);
|
||||||
|
|
||||||
/* Buffer Utilities */
|
/* Buffer Utilities */
|
||||||
|
|
||||||
|
@@ -176,12 +176,10 @@ func (b *Buffer) Bytes() []byte {
|
|||||||
// PresentationTimestamp returns the presentation timestamp of the buffer, or a negative duration
|
// PresentationTimestamp returns the presentation timestamp of the buffer, or a negative duration
|
||||||
// if not known or relevant. This value contains the timestamp when the media should be
|
// if not known or relevant. This value contains the timestamp when the media should be
|
||||||
// presented to the user.
|
// presented to the user.
|
||||||
func (b *Buffer) PresentationTimestamp() time.Duration {
|
func (b *Buffer) PresentationTimestamp() ClockTime {
|
||||||
pts := b.Instance().pts
|
pts := b.Instance().pts
|
||||||
if pts == gstClockTimeNone {
|
|
||||||
return ClockTimeNone
|
return ClockTime(pts)
|
||||||
}
|
|
||||||
return time.Duration(pts)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetPresentationTimestamp sets the presentation timestamp on the buffer.
|
// SetPresentationTimestamp sets the presentation timestamp on the buffer.
|
||||||
@@ -192,22 +190,18 @@ func (b *Buffer) SetPresentationTimestamp(dur time.Duration) {
|
|||||||
|
|
||||||
// DecodingTimestamp returns the decoding timestamp of the buffer, or a negative duration if not known
|
// 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.
|
// or relevant. This value contains the timestamp when the media should be processed.
|
||||||
func (b *Buffer) DecodingTimestamp() time.Duration {
|
func (b *Buffer) DecodingTimestamp() ClockTime {
|
||||||
dts := b.Instance().dts
|
dts := b.Instance().dts
|
||||||
if dts == gstClockTimeNone {
|
|
||||||
return ClockTimeNone
|
return ClockTime(dts)
|
||||||
}
|
|
||||||
return time.Duration(dts)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Duration returns the length of the data inside this buffer, or a negative duration if not known
|
// Duration returns the length of the data inside this buffer, or a negative duration if not known
|
||||||
// or relevant.
|
// or relevant.
|
||||||
func (b *Buffer) Duration() time.Duration {
|
func (b *Buffer) Duration() ClockTime {
|
||||||
dur := b.Instance().duration
|
dur := b.Instance().duration
|
||||||
if dur == gstClockTimeNone {
|
|
||||||
return ClockTimeNone
|
return ClockTime(dur)
|
||||||
}
|
|
||||||
return time.Duration(dur)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetDuration sets the duration on the buffer.
|
// SetDuration sets the duration on the buffer.
|
||||||
@@ -287,7 +281,7 @@ func (b *Buffer) AddProtectionMeta(info *Structure) *ProtectionMeta {
|
|||||||
type ReferenceTimestampMeta struct {
|
type ReferenceTimestampMeta struct {
|
||||||
Parent *Meta
|
Parent *Meta
|
||||||
Reference *Caps
|
Reference *Caps
|
||||||
Timestamp, Duration time.Duration
|
Timestamp, Duration ClockTime
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddReferenceTimestampMeta adds a ReferenceTimestampMeta to this buffer that holds a
|
// AddReferenceTimestampMeta adds a ReferenceTimestampMeta to this buffer that holds a
|
||||||
@@ -295,21 +289,16 @@ type ReferenceTimestampMeta struct {
|
|||||||
//
|
//
|
||||||
// See the documentation of GstReferenceTimestampMeta for details.
|
// See the documentation of GstReferenceTimestampMeta for details.
|
||||||
// https://gstreamer.freedesktop.org/documentation/gstreamer/gstbuffer.html?gi-language=c#GstReferenceTimestampMeta
|
// https://gstreamer.freedesktop.org/documentation/gstreamer/gstbuffer.html?gi-language=c#GstReferenceTimestampMeta
|
||||||
func (b *Buffer) AddReferenceTimestampMeta(ref *Caps, timestamp, duration time.Duration) *ReferenceTimestampMeta {
|
func (b *Buffer) AddReferenceTimestampMeta(ref *Caps, timestamp, duration ClockTime) *ReferenceTimestampMeta {
|
||||||
durClockTime := C.GstClockTime(ClockTimeNone)
|
meta := C.gst_buffer_add_reference_timestamp_meta(b.Instance(), ref.Instance(), C.GstClockTime(timestamp), C.GstClockTime(duration))
|
||||||
if duration > time.Duration(0) {
|
|
||||||
durClockTime = C.GstClockTime(duration.Nanoseconds())
|
|
||||||
}
|
|
||||||
tsClockTime := C.GstClockTime(timestamp.Nanoseconds())
|
|
||||||
meta := C.gst_buffer_add_reference_timestamp_meta(b.Instance(), ref.Instance(), tsClockTime, durClockTime)
|
|
||||||
if meta == nil {
|
if meta == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return &ReferenceTimestampMeta{
|
return &ReferenceTimestampMeta{
|
||||||
Parent: wrapMeta(&meta.parent),
|
Parent: wrapMeta(&meta.parent),
|
||||||
Reference: wrapCaps(meta.reference),
|
Reference: wrapCaps(meta.reference),
|
||||||
Timestamp: time.Duration(meta.timestamp),
|
Timestamp: ClockTime(meta.timestamp),
|
||||||
Duration: time.Duration(meta.duration),
|
Duration: ClockTime(meta.duration),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -502,8 +491,8 @@ func (b *Buffer) GetReferenceTimestampMeta(caps *Caps) *ReferenceTimestampMeta {
|
|||||||
}
|
}
|
||||||
refMeta := &ReferenceTimestampMeta{
|
refMeta := &ReferenceTimestampMeta{
|
||||||
Parent: wrapMeta(&meta.parent),
|
Parent: wrapMeta(&meta.parent),
|
||||||
Timestamp: time.Duration(meta.timestamp),
|
Timestamp: ClockTime(meta.timestamp),
|
||||||
Duration: time.Duration(meta.duration),
|
Duration: ClockTime(meta.duration),
|
||||||
}
|
}
|
||||||
if meta.reference != nil {
|
if meta.reference != nil {
|
||||||
refMeta.Reference = wrapCaps(meta.reference)
|
refMeta.Reference = wrapCaps(meta.reference)
|
||||||
|
@@ -97,8 +97,8 @@ func (b *Bus) AddSignalWatch() { C.gst_bus_add_signal_watch(b.Instance()) }
|
|||||||
//
|
//
|
||||||
// It is much safer and easier to use the AddWatch or other polling functions. Only use this method if you
|
// It is much safer and easier to use the AddWatch or other polling functions. Only use this method if you
|
||||||
// are unable to also run a MainLoop, or for convenience sake.
|
// are unable to also run a MainLoop, or for convenience sake.
|
||||||
func (b *Bus) PopMessage(timeout int) *Message {
|
func (b *Bus) PopMessage(timeout ClockTime) *Message {
|
||||||
return b.TimedPop(time.Duration(timeout) * time.Second)
|
return b.TimedPop(timeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
// BlockPopMessage blocks until a message is available on the bus and then returns it.
|
// BlockPopMessage blocks until a message is available on the bus and then returns it.
|
||||||
@@ -315,15 +315,9 @@ func (b *Bus) SetSyncHandler(f BusSyncHandler) {
|
|||||||
|
|
||||||
// TimedPop gets a message from the bus, waiting up to the specified timeout. Unref returned messages after usage.
|
// TimedPop gets a message from the bus, waiting up to the specified timeout. Unref returned messages after usage.
|
||||||
//
|
//
|
||||||
// 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.
|
// If timeout is 0, this function behaves like Pop. If timeout is ClockTimeNone, this function will block forever until a message was posted on the bus.
|
||||||
func (b *Bus) TimedPop(dur time.Duration) *Message {
|
func (b *Bus) TimedPop(dur ClockTime) *Message {
|
||||||
var cTime C.GstClockTime
|
msg := C.gst_bus_timed_pop(b.Instance(), C.GstClockTime(dur))
|
||||||
if dur == ClockTimeNone {
|
|
||||||
cTime = C.GstClockTime(gstClockTimeNone)
|
|
||||||
} else {
|
|
||||||
cTime = C.GstClockTime(dur.Nanoseconds())
|
|
||||||
}
|
|
||||||
msg := C.gst_bus_timed_pop(b.Instance(), cTime)
|
|
||||||
if msg == nil {
|
if msg == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -333,16 +327,10 @@ func (b *Bus) TimedPop(dur time.Duration) *Message {
|
|||||||
// TimedPopFiltered gets a message from the bus whose type matches the message type mask types, waiting up to the specified timeout
|
// TimedPopFiltered gets a message from the bus whose type matches the message type mask types, waiting up to the specified timeout
|
||||||
// (and discarding any messages that do not match the mask provided).
|
// (and discarding any messages that do not match the mask provided).
|
||||||
//
|
//
|
||||||
// If timeout is 0, this function behaves like PopFiltered. If timeout is < 0, this function will block forever until a matching message
|
// If timeout is 0, this function behaves like PopFiltered. If timeout is ClockTimeNone, this function will block forever until a matching message
|
||||||
// was posted on the bus.
|
// was posted on the bus.
|
||||||
func (b *Bus) TimedPopFiltered(dur time.Duration, msgTypes MessageType) *Message {
|
func (b *Bus) TimedPopFiltered(dur ClockTime, msgTypes MessageType) *Message {
|
||||||
var cTime C.GstClockTime
|
msg := C.gst_bus_timed_pop_filtered(b.Instance(), C.GstClockTime(dur), C.GstMessageType(msgTypes))
|
||||||
if dur == ClockTimeNone {
|
|
||||||
cTime = C.GstClockTime(gstClockTimeNone)
|
|
||||||
} else {
|
|
||||||
cTime = C.GstClockTime(dur.Nanoseconds())
|
|
||||||
}
|
|
||||||
msg := C.gst_bus_timed_pop_filtered(b.Instance(), cTime, C.GstMessageType(msgTypes))
|
|
||||||
if msg == nil {
|
if msg == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
101
gst/gst_clock.go
101
gst/gst_clock.go
@@ -20,6 +20,7 @@ void clockDestroyNotify (gpointer user_data)
|
|||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"runtime"
|
"runtime"
|
||||||
"time"
|
"time"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
@@ -28,8 +29,28 @@ import (
|
|||||||
gopointer "github.com/mattn/go-pointer"
|
gopointer "github.com/mattn/go-pointer"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type ClockTime C.GstClockTime
|
||||||
|
|
||||||
|
func (ct ClockTime) String() string {
|
||||||
|
if ct == ClockTimeNone {
|
||||||
|
return "ClockTimeNone"
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprint(uint64(ct))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ct ClockTime) AsDuration() *time.Duration {
|
||||||
|
if ct == ClockTimeNone {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
dur := time.Duration(uint64(ct))
|
||||||
|
|
||||||
|
return &dur
|
||||||
|
}
|
||||||
|
|
||||||
// ClockCallback is the prototype of a clock callback function.
|
// ClockCallback is the prototype of a clock callback function.
|
||||||
type ClockCallback func(clock *Clock, clockTime time.Duration) bool
|
type ClockCallback func(clock *Clock, clockTime ClockTime) bool
|
||||||
|
|
||||||
// ClockID is a go wrapper around a GstClockID.
|
// ClockID is a go wrapper around a GstClockID.
|
||||||
type ClockID struct {
|
type ClockID struct {
|
||||||
@@ -46,8 +67,8 @@ func (c *ClockID) GetClock() *Clock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetTime returns the time for this ClockID
|
// GetTime returns the time for this ClockID
|
||||||
func (c *ClockID) GetTime() time.Duration {
|
func (c *ClockID) GetTime() ClockTime {
|
||||||
return time.Duration(C.gst_clock_id_get_time(c.Instance()))
|
return ClockTime(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.
|
// Unschedule cancels an outstanding request with id. This can either be an outstanding async notification or a pending sync notification.
|
||||||
@@ -89,7 +110,7 @@ func (c *ClockID) Wait() (ret ClockReturn, jitter ClockTimeDiff) {
|
|||||||
//
|
//
|
||||||
// id := clock.NewSingleShotID(gst.ClockTime(1000000000)) // 1 second
|
// id := clock.NewSingleShotID(gst.ClockTime(1000000000)) // 1 second
|
||||||
//
|
//
|
||||||
// id.WaitAsync(func(clock *gst.Clock, clockTime time.Duration) bool {
|
// id.WaitAsync(func(clock *gst.Clock, clockTime ClockTime) bool {
|
||||||
// fmt.Println("Single shot triggered at", clockTime.Nanoseconds())
|
// fmt.Println("Single shot triggered at", clockTime.Nanoseconds())
|
||||||
// pipeline.SetState(gst.StateNull)
|
// pipeline.SetState(gst.StateNull)
|
||||||
// return true
|
// return true
|
||||||
@@ -143,7 +164,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
|
// 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.
|
// 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 time.Duration) (bool, float64) {
|
func (c *Clock) AddObservation(slaveTime, masterTime ClockTime) (bool, float64) {
|
||||||
var out C.gdouble
|
var out C.gdouble
|
||||||
ok := gobool(C.gst_clock_add_observation(
|
ok := gobool(C.gst_clock_add_observation(
|
||||||
c.Instance(),
|
c.Instance(),
|
||||||
@@ -158,7 +179,7 @@ func (c *Clock) AddObservation(slaveTime, masterTime time.Duration) (bool, float
|
|||||||
// result of the master clock estimation, without updating the internal calibration.
|
// 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.
|
// 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 time.Duration) (ok bool, rSquared float64, internalTime, externalTime, rateNum, rateDenom time.Duration) {
|
func (c *Clock) AddObservationUnapplied(slaveTime, masterTime ClockTime) (ok bool, rSquared float64, internalTime, externalTime, rateNum, rateDenom ClockTime) {
|
||||||
var ginternal, gexternal, grateNum, grateDenom C.GstClockTime
|
var ginternal, gexternal, grateNum, grateDenom C.GstClockTime
|
||||||
var grSquared C.gdouble
|
var grSquared C.gdouble
|
||||||
ok = gobool(C.gst_clock_add_observation_unapplied(
|
ok = gobool(C.gst_clock_add_observation_unapplied(
|
||||||
@@ -167,7 +188,7 @@ func (c *Clock) AddObservationUnapplied(slaveTime, masterTime time.Duration) (ok
|
|||||||
C.GstClockTime(masterTime),
|
C.GstClockTime(masterTime),
|
||||||
&grSquared, &ginternal, &gexternal, &grateNum, &grateDenom,
|
&grSquared, &ginternal, &gexternal, &grateNum, &grateDenom,
|
||||||
))
|
))
|
||||||
return ok, float64(grSquared), time.Duration(ginternal), time.Duration(gexternal), time.Duration(grateNum), time.Duration(grateDenom)
|
return ok, float64(grSquared), ClockTime(ginternal), ClockTime(gexternal), ClockTime(grateNum), ClockTime(grateDenom)
|
||||||
}
|
}
|
||||||
|
|
||||||
// AdjustUnlocked converts the given internal clock time to the external time, adjusting for the rate and reference time set with
|
// AdjustUnlocked converts the given internal clock time to the external time, adjusting for the rate and reference time set with
|
||||||
@@ -175,8 +196,8 @@ func (c *Clock) AddObservationUnapplied(slaveTime, masterTime time.Duration) (ok
|
|||||||
// held and is mainly used by clock subclasses.
|
// held and is mainly used by clock subclasses.
|
||||||
//
|
//
|
||||||
// This function is the reverse of UnadjustUnlocked.
|
// This function is the reverse of UnadjustUnlocked.
|
||||||
func (c *Clock) AdjustUnlocked(internal time.Duration) time.Duration {
|
func (c *Clock) AdjustUnlocked(internal ClockTime) ClockTime {
|
||||||
return time.Duration(C.gst_clock_adjust_unlocked(c.Instance(), C.GstClockTime(internal)))
|
return ClockTime(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.
|
// AdjustWithCalibration converts the given internal_target clock time to the external time, using the passed calibration parameters.
|
||||||
@@ -184,8 +205,8 @@ func (c *Clock) AdjustUnlocked(internal time.Duration) time.Duration {
|
|||||||
// doesn't ensure a monotonically increasing result as AdjustUnlocked does.
|
// doesn't ensure a monotonically increasing result as AdjustUnlocked does.
|
||||||
//
|
//
|
||||||
// See: https://gstreamer.freedesktop.org/documentation/gstreamer/gstclock.html#gst_clock_adjust_with_calibration
|
// See: https://gstreamer.freedesktop.org/documentation/gstreamer/gstclock.html#gst_clock_adjust_with_calibration
|
||||||
func (c *Clock) AdjustWithCalibration(internalTarget, cinternal, cexternal, cnum, cdenom time.Duration) time.Duration {
|
func (c *Clock) AdjustWithCalibration(internalTarget, cinternal, cexternal, cnum, cdenom ClockTime) ClockTime {
|
||||||
return time.Duration(C.gst_clock_adjust_with_calibration(
|
return ClockTime(C.gst_clock_adjust_with_calibration(
|
||||||
c.Instance(),
|
c.Instance(),
|
||||||
C.GstClockTime(internalTarget),
|
C.GstClockTime(internalTarget),
|
||||||
C.GstClockTime(cinternal),
|
C.GstClockTime(cinternal),
|
||||||
@@ -196,30 +217,26 @@ 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.
|
// 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 time.Duration) {
|
func (c *Clock) GetCalibration() (internal, external, rateNum, rateDenom ClockTime) {
|
||||||
var ginternal, gexternal, grateNum, grateDenom C.GstClockTime
|
var ginternal, gexternal, grateNum, grateDenom C.GstClockTime
|
||||||
C.gst_clock_get_calibration(c.Instance(), &ginternal, &gexternal, &grateNum, &grateDenom)
|
C.gst_clock_get_calibration(c.Instance(), &ginternal, &gexternal, &grateNum, &grateDenom)
|
||||||
return time.Duration(ginternal), time.Duration(gexternal), time.Duration(grateNum), time.Duration(grateDenom)
|
return ClockTime(ginternal), ClockTime(gexternal), ClockTime(grateNum), ClockTime(grateDenom)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTime gets the current time of the given clock in nanoseconds or -1 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.
|
// The time is always monotonically increasing and adjusted according to the current offset and rate.
|
||||||
func (c *Clock) GetTime() time.Duration {
|
func (c *Clock) GetTime() ClockTime {
|
||||||
res := C.gst_clock_get_time(c.Instance())
|
res := C.gst_clock_get_time(c.Instance())
|
||||||
if res == gstClockTimeNone {
|
|
||||||
return ClockTimeNone
|
return ClockTime(res)
|
||||||
}
|
|
||||||
return time.Duration(res)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetInternalTime gets the current internal time of the given clock in nanoseconds
|
// 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.
|
// or ClockTimeNone if invalid. The time is returned unadjusted for the offset and the rate.
|
||||||
func (c *Clock) GetInternalTime() time.Duration {
|
func (c *Clock) GetInternalTime() ClockTime {
|
||||||
res := C.gst_clock_get_internal_time(c.Instance())
|
res := C.gst_clock_get_internal_time(c.Instance())
|
||||||
if res == gstClockTimeNone {
|
|
||||||
return ClockTimeNone
|
return ClockTime(res)
|
||||||
}
|
|
||||||
return time.Duration(res)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMaster returns the master clock that this clock is slaved to or nil when the clock
|
// GetMaster returns the master clock that this clock is slaved to or nil when the clock
|
||||||
@@ -234,13 +251,13 @@ func (c *Clock) GetMaster() *Clock {
|
|||||||
|
|
||||||
// GetResolution gets the accuracy of the clock. The accuracy of the clock is the granularity
|
// GetResolution gets the accuracy of the clock. The accuracy of the clock is the granularity
|
||||||
// of the values returned by GetTime.
|
// of the values returned by GetTime.
|
||||||
func (c *Clock) GetResolution() time.Duration {
|
func (c *Clock) GetResolution() ClockTime {
|
||||||
return time.Duration(C.gst_clock_get_resolution(c.Instance()))
|
return ClockTime(C.gst_clock_get_resolution(c.Instance()))
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTimeout gets the amount of time that master and slave clocks are sampled.
|
// GetTimeout gets the amount of time that master and slave clocks are sampled.
|
||||||
func (c *Clock) GetTimeout() time.Duration {
|
func (c *Clock) GetTimeout() ClockTime {
|
||||||
return time.Duration(C.gst_clock_get_timeout(c.Instance()))
|
return ClockTime(C.gst_clock_get_timeout(c.Instance()))
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsSynced returns true if the clock is synced.
|
// IsSynced returns true if the clock is synced.
|
||||||
@@ -248,7 +265,7 @@ 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
|
// 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.
|
// 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 time.Duration) *ClockID {
|
func (c *Clock) NewPeriodicID(startTime, interval ClockTime) *ClockID {
|
||||||
id := C.gst_clock_new_periodic_id(
|
id := C.gst_clock_new_periodic_id(
|
||||||
c.Instance(),
|
c.Instance(),
|
||||||
C.GstClockTime(startTime),
|
C.GstClockTime(startTime),
|
||||||
@@ -261,7 +278,7 @@ func (c *Clock) NewPeriodicID(startTime, interval time.Duration) *ClockID {
|
|||||||
|
|
||||||
// NewSingleShotID gets a ClockID from the clock to trigger a single shot notification at the requested time.
|
// 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.
|
// The single shot id should be unreffed after usage.
|
||||||
func (c *Clock) NewSingleShotID(at time.Duration) *ClockID {
|
func (c *Clock) NewSingleShotID(at ClockTime) *ClockID {
|
||||||
id := C.gst_clock_new_single_shot_id(
|
id := C.gst_clock_new_single_shot_id(
|
||||||
c.Instance(),
|
c.Instance(),
|
||||||
C.GstClockTime(at),
|
C.GstClockTime(at),
|
||||||
@@ -273,7 +290,7 @@ func (c *Clock) NewSingleShotID(at time.Duration) *ClockID {
|
|||||||
|
|
||||||
// PeriodicIDReinit reinitializes the provided periodic id to the provided start time and interval. Does not
|
// PeriodicIDReinit reinitializes the provided periodic id to the provided start time and interval. Does not
|
||||||
// / modify the reference count.
|
// / modify the reference count.
|
||||||
func (c *Clock) PeriodicIDReinit(clockID *ClockID, startTime, interval time.Duration) bool {
|
func (c *Clock) PeriodicIDReinit(clockID *ClockID, startTime, interval ClockTime) bool {
|
||||||
return gobool(C.gst_clock_periodic_id_reinit(
|
return gobool(C.gst_clock_periodic_id_reinit(
|
||||||
c.Instance(),
|
c.Instance(),
|
||||||
clockID.Instance(),
|
clockID.Instance(),
|
||||||
@@ -284,7 +301,7 @@ func (c *Clock) PeriodicIDReinit(clockID *ClockID, startTime, interval time.Dura
|
|||||||
|
|
||||||
// SetCalibration adjusts the rate and time of clock.
|
// SetCalibration adjusts the rate and time of clock.
|
||||||
// See: https://gstreamer.freedesktop.org/documentation/gstreamer/gstclock.html#gst_clock_set_calibration.
|
// See: https://gstreamer.freedesktop.org/documentation/gstreamer/gstclock.html#gst_clock_set_calibration.
|
||||||
func (c *Clock) SetCalibration(internal, external, rateNum, rateDenom time.Duration) {
|
func (c *Clock) SetCalibration(internal, external, rateNum, rateDenom ClockTime) {
|
||||||
C.gst_clock_set_calibration(
|
C.gst_clock_set_calibration(
|
||||||
c.Instance(),
|
c.Instance(),
|
||||||
C.GstClockTime(internal),
|
C.GstClockTime(internal),
|
||||||
@@ -311,8 +328,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
|
// 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.
|
// 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.
|
// The resolution of a clock can only be changed if the clock has the ClockFlagCanSetResolution flag set.
|
||||||
func (c *Clock) SetResolution(resolution time.Duration) time.Duration {
|
func (c *Clock) SetResolution(resolution ClockTime) ClockTime {
|
||||||
return time.Duration(C.gst_clock_set_resolution(c.Instance(), C.GstClockTime(resolution)))
|
return ClockTime(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.
|
// SetSynced sets clock to synced and emits the GstClock::synced signal, and wakes up any thread waiting in WaitForSync.
|
||||||
@@ -322,12 +339,12 @@ func (c *Clock) SetResolution(resolution time.Duration) time.Duration {
|
|||||||
func (c *Clock) SetSynced(synced bool) { C.gst_clock_set_synced(c.Instance(), gboolean(synced)) }
|
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
|
// SetTimeout sets the amount of time, in nanoseconds, to sample master and slave clocks
|
||||||
func (c *Clock) SetTimeout(timeout time.Duration) {
|
func (c *Clock) SetTimeout(timeout ClockTime) {
|
||||||
C.gst_clock_set_timeout(c.Instance(), C.GstClockTime(timeout))
|
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.
|
// SingleShotIDReinit reinitializes the provided single shot id to the provided time. Does not modify the reference count.
|
||||||
func (c *Clock) SingleShotIDReinit(clockID *ClockID, at time.Duration) bool {
|
func (c *Clock) SingleShotIDReinit(clockID *ClockID, at ClockTime) bool {
|
||||||
return gobool(C.gst_clock_single_shot_id_reinit(c.Instance(), clockID.Instance(), C.GstClockTime(at)))
|
return gobool(C.gst_clock_single_shot_id_reinit(c.Instance(), clockID.Instance(), C.GstClockTime(at)))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,14 +352,14 @@ func (c *Clock) SingleShotIDReinit(clockID *ClockID, at time.Duration) bool {
|
|||||||
// set with SetCalibration. This function should be called with the clock's OBJECT_LOCK held and is mainly used by clock subclasses.
|
// 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.
|
// This function is the reverse of AdjustUnlocked.
|
||||||
func (c *Clock) UnadjustUnlocked(external time.Duration) time.Duration {
|
func (c *Clock) UnadjustUnlocked(external ClockTime) ClockTime {
|
||||||
return time.Duration(C.gst_clock_unadjust_unlocked(c.Instance(), C.GstClockTime(external)))
|
return ClockTime(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.
|
// 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.
|
// This function performs the same calculation as UnadjustUnlocked when called using the current calibration parameters.
|
||||||
func (c *Clock) UnadjustWithCalibration(externalTarget, cinternal, cexternal, cnum, cdenom time.Duration) time.Duration {
|
func (c *Clock) UnadjustWithCalibration(externalTarget, cinternal, cexternal, cnum, cdenom ClockTime) ClockTime {
|
||||||
return time.Duration(C.gst_clock_unadjust_with_calibration(
|
return ClockTime(C.gst_clock_unadjust_with_calibration(
|
||||||
c.Instance(),
|
c.Instance(),
|
||||||
C.GstClockTime(externalTarget),
|
C.GstClockTime(externalTarget),
|
||||||
C.GstClockTime(cinternal),
|
C.GstClockTime(cinternal),
|
||||||
@@ -358,12 +375,12 @@ func (c *Clock) UnadjustWithCalibration(externalTarget, cinternal, cexternal, cn
|
|||||||
// For asynchronous waiting, the GstClock::synced signal can be used.
|
// 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.
|
// 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 time.Duration) bool {
|
func (c *Clock) WaitForSync(timeout ClockTime) bool {
|
||||||
return gobool(C.gst_clock_wait_for_sync(c.Instance(), C.GstClockTime(timeout)))
|
return gobool(C.gst_clock_wait_for_sync(c.Instance(), C.GstClockTime(timeout)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns the string representation of this clock value.
|
// String returns the string representation of this clock value.
|
||||||
func (c *Clock) String() string { return c.GetTime().String() }
|
func (c *Clock) String() string { return fmt.Sprintf("%d", c.GetTime()) }
|
||||||
|
|
||||||
// InternalString returns the string representation of this clock's internal value.
|
// InternalString returns the string representation of this clock's internal value.
|
||||||
func (c *Clock) InternalString() string { return c.GetInternalTime().String() }
|
func (c *Clock) InternalString() string { return fmt.Sprintf("%d", c.GetInternalTime()) }
|
||||||
|
@@ -520,3 +520,39 @@ func (e *Element) GetRequestPad(name string) *Pad {
|
|||||||
func (e *Element) ReleaseRequestPad(pad *Pad) {
|
func (e *Element) ReleaseRequestPad(pad *Pad) {
|
||||||
C.gst_element_release_request_pad(e.Instance(), pad.Instance())
|
C.gst_element_release_request_pad(e.Instance(), pad.Instance())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the start time of an element. The start time of the element is the running time of the element
|
||||||
|
// when it last went to the PAUSED state. In READY or after a flushing seek, it is set to 0.
|
||||||
|
//
|
||||||
|
// Toplevel elements like GstPipeline will manage the start_time and base_time on its children.
|
||||||
|
// Setting the start_time to GST_CLOCK_TIME_NONE on such a toplevel element will disable the distribution of the base_time
|
||||||
|
// to the children and can be useful if the application manages the base_time itself, for example if you want to synchronize
|
||||||
|
// capture from multiple pipelines, and you can also ensure that the pipelines have the same clock.
|
||||||
|
//
|
||||||
|
// MT safe.
|
||||||
|
func (e *Element) SetStartTime(startTime ClockTime) {
|
||||||
|
C.gst_element_set_start_time(e.Instance(), C.GstClockTime(startTime))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the start time of the element. The start time is the running time of the clock when this element was last put to PAUSED.
|
||||||
|
// Usually the start_time is managed by a toplevel element such as GstPipeline.
|
||||||
|
// MT safe.
|
||||||
|
func (e *Element) GetStartTime() ClockTime {
|
||||||
|
ctime := C.gst_element_get_start_time(e.Instance())
|
||||||
|
|
||||||
|
return ClockTime(ctime)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the base time of an element. The base time is the absolute time of the clock
|
||||||
|
// when this element was last put to PLAYING. Subtracting the base time from the clock time gives the running time of the element.
|
||||||
|
func (e *Element) SetBaseTime(startTime ClockTime) {
|
||||||
|
C.gst_element_set_base_time(e.Instance(), C.GstClockTime(startTime))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the base time of the element. The base time is the absolute time of the clock
|
||||||
|
// when this element was last put to PLAYING. Subtracting the base time from the clock time gives the running time of the element.
|
||||||
|
func (e *Element) GetBaseTime() ClockTime {
|
||||||
|
ctime := C.gst_element_get_base_time(e.Instance())
|
||||||
|
|
||||||
|
return ClockTime(ctime)
|
||||||
|
}
|
||||||
|
@@ -28,11 +28,52 @@ func NewElementWithName(factory string, name string) (*Element, error) {
|
|||||||
elem = C.gst_element_factory_make((*C.gchar)(elemName), (*C.gchar)(cname))
|
elem = C.gst_element_factory_make((*C.gchar)(elemName), (*C.gchar)(cname))
|
||||||
}
|
}
|
||||||
if elem == nil {
|
if elem == nil {
|
||||||
return nil, fmt.Errorf("Could not create element: %s", factory)
|
return nil, fmt.Errorf("could not create element: %s", factory)
|
||||||
}
|
}
|
||||||
return wrapElement(glib.TransferNone(unsafe.Pointer(elem))), nil
|
return wrapElement(glib.TransferNone(unsafe.Pointer(elem))), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create a new element of the type defined by the given elementfactory. The supplied list of properties, will be passed at object construction.
|
||||||
|
//
|
||||||
|
// using this results in a free() panic :( DO NOT USE
|
||||||
|
func NewElementWithProperties(factory string, properties map[string]interface{}) (*Element, error) {
|
||||||
|
props := make([]*C.char, 0)
|
||||||
|
values := make([]C.GValue, 0)
|
||||||
|
|
||||||
|
for p, v := range properties {
|
||||||
|
cpropName := C.CString(p)
|
||||||
|
defer C.free(unsafe.Pointer(cpropName))
|
||||||
|
|
||||||
|
props = append(props, cpropName)
|
||||||
|
|
||||||
|
cValue, err := glib.GValue(v)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
values = append(values, *(*C.GValue)(cValue.Unsafe()))
|
||||||
|
}
|
||||||
|
|
||||||
|
cfactory := C.CString(factory)
|
||||||
|
defer C.free(unsafe.Pointer(cfactory))
|
||||||
|
|
||||||
|
n := C.uint(len(properties))
|
||||||
|
|
||||||
|
var elem *C.GstElement
|
||||||
|
|
||||||
|
if n > 0 {
|
||||||
|
elem = C.gst_element_factory_make_with_properties(cfactory, n, &props[0], &values[0])
|
||||||
|
} else {
|
||||||
|
elem = C.gst_element_factory_make_with_properties(cfactory, n, nil, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
if elem == nil {
|
||||||
|
return nil, fmt.Errorf("could not create element: %s", factory)
|
||||||
|
}
|
||||||
|
return wrapElement(glib.TransferFull(unsafe.Pointer(elem))), nil
|
||||||
|
}
|
||||||
|
|
||||||
// NewElementMany is a convenience wrapper around building many GstElements in a
|
// NewElementMany is a convenience wrapper around building many GstElements in a
|
||||||
// single function call. It returns an error if the creation of any element fails. A
|
// single function call. It returns an error if the creation of any element fails. A
|
||||||
// slice in the order the names were given is returned.
|
// slice in the order the names were given is returned.
|
||||||
|
@@ -34,20 +34,15 @@ func NewApplicationMessage(src interface{}, structure *Structure) *Message {
|
|||||||
// RunningTime contains the time of the desired running time when this elements goes to PLAYING.
|
// RunningTime contains the time of the desired running time when this elements goes to PLAYING.
|
||||||
// A value less than 0 for runningTime means that the element has no clock interaction and thus doesn't
|
// A value less than 0 for runningTime means that the element has no clock interaction and thus doesn't
|
||||||
// care about the running time of the pipeline.
|
// care about the running time of the pipeline.
|
||||||
func NewAsyncDoneMessage(src interface{}, runningTime time.Duration) *Message {
|
func NewAsyncDoneMessage(src interface{}, runningTime ClockTime) *Message {
|
||||||
srcObj := getMessageSourceObj(src)
|
srcObj := getMessageSourceObj(src)
|
||||||
if srcObj == nil {
|
if srcObj == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var cTime C.GstClockTime
|
|
||||||
if runningTime.Nanoseconds() < 0 {
|
|
||||||
cTime = C.GstClockTime(gstClockTimeNone)
|
|
||||||
} else {
|
|
||||||
cTime = C.GstClockTime(runningTime.Nanoseconds())
|
|
||||||
}
|
|
||||||
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_async_done(
|
return FromGstMessageUnsafeFull(unsafe.Pointer(C.gst_message_new_async_done(
|
||||||
srcObj,
|
srcObj,
|
||||||
cTime,
|
C.GstClockTime(runningTime),
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -93,3 +93,7 @@ func (o *Object) Ref() *Object {
|
|||||||
func (o *Object) Unref() {
|
func (o *Object) Unref() {
|
||||||
C.gst_object_unref((C.gpointer)(o.Unsafe()))
|
C.gst_object_unref((C.gpointer)(o.Unsafe()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o *Object) AddControlBinding(binding *ControlBinding) {
|
||||||
|
C.gst_object_add_control_binding(o.Instance(), binding.Instance())
|
||||||
|
}
|
||||||
|
@@ -78,6 +78,15 @@ func (p *Pipeline) GetPipelineClock() *Clock {
|
|||||||
return FromGstClockUnsafeFull(unsafe.Pointer(cClock))
|
return FromGstClockUnsafeFull(unsafe.Pointer(cClock))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Force pipeline to use the given clock. The pipeline will always use the given clock even if new clock providers are added to this pipeline.
|
||||||
|
//
|
||||||
|
// If clock is NULL all clocking will be disabled which will make the pipeline run as fast as possible.
|
||||||
|
//
|
||||||
|
// MT safe.
|
||||||
|
func (p *Pipeline) ForceClock(clock *Clock) {
|
||||||
|
C.gst_pipeline_use_clock(p.Instance(), clock.Instance())
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
SetAutoFlushBus can be used to disable automatically flushing the message bus
|
SetAutoFlushBus can be used to disable automatically flushing the message bus
|
||||||
when a pipeline goes to StateNull.
|
when a pipeline goes to StateNull.
|
||||||
|
64
gst/gstnet/gst_ntp_clock.go
Normal file
64
gst/gstnet/gst_ntp_clock.go
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
package gstnet
|
||||||
|
|
||||||
|
// #include "gst.go.h"
|
||||||
|
import "C"
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"time"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/go-gst/go-gst/gst"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NTP timestamps are realtive to 1. Jan 1900, so we need an offset for 70 Years to be Unix TS compatible
|
||||||
|
const NTPTimeToUnixEpoch = gst.ClockTime(2208988800 * time.Second)
|
||||||
|
|
||||||
|
// NTPClock wraps GstClock
|
||||||
|
type NTPClock struct{ *gst.Clock }
|
||||||
|
|
||||||
|
// ObtainNTPClock returns the default NTPClock. The refcount of the clock will be
|
||||||
|
// increased so you need to unref the clock after usage.
|
||||||
|
func ObtainNTPClock(ctx context.Context, name, address string, port int) (*NTPClock, error) {
|
||||||
|
cname := C.CString(name)
|
||||||
|
defer C.free(unsafe.Pointer(cname))
|
||||||
|
|
||||||
|
caddr := C.CString(address)
|
||||||
|
defer C.free(unsafe.Pointer(caddr))
|
||||||
|
|
||||||
|
currentSystemTime := time.Now().UnixNano() + int64(NTPTimeToUnixEpoch)
|
||||||
|
|
||||||
|
ntpC := &NTPClock{gst.FromGstClockUnsafeFull(unsafe.Pointer(C.gst_ntp_clock_new(cname, caddr, C.gint(port), C.GstClockTime(currentSystemTime))))}
|
||||||
|
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return nil, errors.New("timeout reached while trying to sync")
|
||||||
|
default:
|
||||||
|
if ntpC.IsSynced() {
|
||||||
|
return ntpC, nil
|
||||||
|
}
|
||||||
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the current time of the clock
|
||||||
|
//
|
||||||
|
// if you want to access the clocks actual time value, use the underlying NTPClock.Clock.GetTime() instead
|
||||||
|
func (ntp *NTPClock) GetTime() time.Time {
|
||||||
|
// nanos since 1. Jan 1900
|
||||||
|
ntpNanos := NTPClockTime(ntp.Clock.GetTime())
|
||||||
|
|
||||||
|
return ntpNanos.ToDate()
|
||||||
|
}
|
||||||
|
|
||||||
|
type NTPClockTime gst.ClockTime
|
||||||
|
|
||||||
|
func (ct NTPClockTime) ToDate() time.Time {
|
||||||
|
return time.Unix(0, int64(ct)-int64(NTPTimeToUnixEpoch))
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewNTPClockTime(t time.Time) NTPClockTime {
|
||||||
|
return NTPClockTime(t.UnixNano() + int64(NTPTimeToUnixEpoch))
|
||||||
|
}
|
@@ -1,7 +1,7 @@
|
|||||||
package gst
|
package gst
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#cgo pkg-config: gstreamer-1.0
|
#cgo pkg-config: gstreamer-1.0 gstreamer-controller-1.0
|
||||||
#cgo CFLAGS: -Wno-deprecated-declarations -Wno-format-security -g -Wall -Wno-unused-variable
|
#cgo CFLAGS: -Wno-deprecated-declarations -Wno-format-security -g -Wall -Wno-unused-variable
|
||||||
#cgo LDFLAGS: -lm
|
#cgo LDFLAGS: -lm
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user