mirror of
https://github.com/go-gst/go-gst.git
synced 2025-09-27 04:15:56 +08:00
380 lines
14 KiB
Go
380 lines
14 KiB
Go
package gst
|
|
|
|
// #include "gst.go.h"
|
|
import "C"
|
|
|
|
import (
|
|
"runtime"
|
|
"time"
|
|
"unsafe"
|
|
)
|
|
|
|
// Event is a go wrapper around a GstEvent.
|
|
type Event struct {
|
|
ptr *C.GstEvent
|
|
}
|
|
|
|
// // FromGstEventUnsafe is an alias to FromGstEventUnsafeNone.
|
|
// func FromGstEventUnsafe(ev unsafe.Pointer) *Event { return FromGstEventUnsafeNone(ev) }
|
|
|
|
// FromGstEventUnsafeNone wraps the pointer to the given C GstEvent with the go type.
|
|
// A ref is taken and finalizer applied.
|
|
func FromGstEventUnsafeNone(ev unsafe.Pointer) *Event {
|
|
event := ToGstEvent(ev)
|
|
event.Ref()
|
|
runtime.SetFinalizer(event, (*Event).Unref)
|
|
return event
|
|
}
|
|
|
|
// FromGstEventUnsafeFull wraps the pointer to the given C GstEvent without taking a ref.
|
|
// A finalizer is applied.
|
|
func FromGstEventUnsafeFull(ev unsafe.Pointer) *Event {
|
|
event := ToGstEvent(ev)
|
|
runtime.SetFinalizer(event, (*Event).Unref)
|
|
return event
|
|
}
|
|
|
|
// ToGstEvent converts the given pointer into an Event without affecting the ref count or
|
|
// placing finalizers.
|
|
func ToGstEvent(ev unsafe.Pointer) *Event {
|
|
return wrapEvent((*C.GstEvent)(ev))
|
|
}
|
|
|
|
// Instance returns the underlying GstEvent instance.
|
|
func (e *Event) Instance() *C.GstEvent { return C.toGstEvent(unsafe.Pointer(e.ptr)) }
|
|
|
|
// Type returns the type of the event
|
|
func (e *Event) Type() EventType { return EventType(e.Instance()._type) }
|
|
|
|
// Timestamp returns the timestamp of the event.
|
|
func (e *Event) Timestamp() time.Duration {
|
|
ts := e.Instance().timestamp
|
|
return time.Duration(uint64(ts)) * time.Nanosecond
|
|
}
|
|
|
|
// Seqnum returns the sequence number of the event.
|
|
func (e *Event) Seqnum() uint32 {
|
|
return uint32(e.Instance().seqnum)
|
|
}
|
|
|
|
// Copy copies the event using the event specific copy function.
|
|
func (e *Event) Copy() *Event {
|
|
return FromGstEventUnsafeFull(unsafe.Pointer(C.gst_event_copy(e.Instance())))
|
|
}
|
|
|
|
// CopySegment parses a segment event and copies the Segment into the location given by segment.
|
|
func (e *Event) CopySegment(segment *Segment) {
|
|
C.gst_event_copy_segment(e.Instance(), segment.Instance())
|
|
}
|
|
|
|
// GetRunningTimeOffset retrieves the accumulated running time offset of the event.
|
|
//
|
|
// Events passing through GstPad that have a running time offset set via gst_pad_set_offset will get their
|
|
// offset adjusted according to the pad's offset.
|
|
//
|
|
// If the event contains any information that related to the running time, this information will need to be
|
|
// updated before usage with this offset.
|
|
func (e *Event) GetRunningTimeOffset() int64 {
|
|
return int64(C.gst_event_get_running_time_offset(e.Instance()))
|
|
}
|
|
|
|
// GetSeqnum retrieves the sequence number of a event.
|
|
//
|
|
// Events have ever-incrementing sequence numbers, which may also be set explicitly via SetSeqnum. Sequence
|
|
// numbers are typically used to indicate that a event corresponds to some other set of events or messages,
|
|
// for example an EOS event corresponding to a SEEK event. It is considered good practice to make this
|
|
// correspondence when possible, though it is not required.
|
|
//
|
|
// Note that events and messages share the same sequence number incrementor; two events or messages will never
|
|
// have the same sequence number unless that correspondence was made explicitly.
|
|
func (e *Event) GetSeqnum() uint32 {
|
|
return uint32(C.gst_event_get_seqnum(e.Instance()))
|
|
}
|
|
|
|
// GetStructure accesses the structure of the event.
|
|
func (e *Event) GetStructure() *Structure {
|
|
return wrapStructure(C.gst_event_get_structure(e.Instance()))
|
|
}
|
|
|
|
// HasName checks if event has the given name. This function is usually used to check the name of a custom event.
|
|
func (e *Event) HasName(name string) bool {
|
|
cName := C.CString(name)
|
|
defer C.free(unsafe.Pointer(cName))
|
|
return gobool(C.gst_event_has_name(e.Instance(), (*C.gchar)(unsafe.Pointer(cName))))
|
|
}
|
|
|
|
// ParseBufferSize gets the format, minsize, maxsize and async-flag in the buffersize event.
|
|
func (e *Event) ParseBufferSize() (format Format, minSize, maxSize int64, async bool) {
|
|
var gformat C.GstFormat
|
|
var gmin, gmax C.gint64
|
|
var gasync C.gboolean
|
|
C.gst_event_parse_buffer_size(e.Instance(), &gformat, &gmin, &gmax, &gasync)
|
|
return Format(gformat), int64(gmin), int64(gmax), gobool(gasync)
|
|
}
|
|
|
|
// ParseCaps gets the caps from event. The caps remains valid as long as event remains valid.
|
|
func (e *Event) ParseCaps() *Caps {
|
|
var caps *C.GstCaps
|
|
C.gst_event_parse_caps(e.Instance(), &caps)
|
|
return FromGstCapsUnsafeNone(unsafe.Pointer(caps))
|
|
}
|
|
|
|
// ParseFlushStop parses the FLUSH_STOP event and retrieve the reset_time member. Value reflects whether
|
|
// time should be reset.
|
|
func (e *Event) ParseFlushStop() (resetTime bool) {
|
|
var gbool C.gboolean
|
|
C.gst_event_parse_flush_stop(e.Instance(), &gbool)
|
|
return gobool(gbool)
|
|
}
|
|
|
|
// ParseGap extracts timestamp and duration from a new GAP event.
|
|
func (e *Event) ParseGap() (timestamp, duration time.Duration) {
|
|
var ts, dur C.GstClockTime
|
|
C.gst_event_parse_gap(e.Instance(), &ts, &dur)
|
|
return time.Duration(ts), time.Duration(dur)
|
|
}
|
|
|
|
// ParseGapFlags retrieves the gap flags that may have been set on a gap event with SetGapFlags.
|
|
// func (e *Event) ParseGapFlags() GapFlags {
|
|
// var out C.GstGapFlags
|
|
// C.gst_event_parse_gap_flags(e.Instance(), &out)
|
|
// return GapFlags(out)
|
|
// }
|
|
|
|
// ParseGroupID returns a group ID if set on the event.
|
|
func (e *Event) ParseGroupID() (ok bool, gid uint) {
|
|
var out C.guint
|
|
gok := C.gst_event_parse_group_id(e.Instance(), &out)
|
|
return gobool(gok), uint(out)
|
|
}
|
|
|
|
// ParseInstantRateChange extracts rate and flags from an instant-rate-change event.
|
|
// func (e *Event) ParseInstantRateChange() {}
|
|
|
|
// ParseInstantRateSyncTime extracts the rate multiplier and running times from an instant-rate-sync-time event.
|
|
// func (e *Event) ParseInstantRateChange() {}
|
|
|
|
// ParseLatency gets the latency in the latency event.
|
|
func (e *Event) ParseLatency() ClockTime {
|
|
var out C.GstClockTime
|
|
C.gst_event_parse_latency(e.Instance(), &out)
|
|
return ClockTime(out)
|
|
}
|
|
|
|
// ParseProtection parses an event containing protection system specific information and stores the results in
|
|
// system_id, data and origin. The data stored in system_id, origin and data are valid until event is released.
|
|
func (e *Event) ParseProtection() (systemID string, data *Buffer, origin string) {
|
|
idPtr := C.malloc(C.sizeof_char * 1024)
|
|
originPtr := C.malloc(C.sizeof_char * 1024)
|
|
defer C.free(unsafe.Pointer(idPtr))
|
|
defer C.free(unsafe.Pointer(originPtr))
|
|
var buf *C.GstBuffer
|
|
C.gst_event_parse_protection(
|
|
e.Instance(),
|
|
(**C.gchar)(unsafe.Pointer(&idPtr)),
|
|
&buf,
|
|
(**C.gchar)(unsafe.Pointer(&originPtr)),
|
|
)
|
|
return C.GoString((*C.char)(unsafe.Pointer(idPtr))), wrapBuffer(buf), C.GoString((*C.char)(unsafe.Pointer(originPtr)))
|
|
}
|
|
|
|
// ParseQOS gets the type, proportion, diff and timestamp in the qos event. See NewQOSEvent for more information about
|
|
// the different QoS values.
|
|
//
|
|
// timestamp will be adjusted for any pad offsets of pads it was passing through.
|
|
func (e *Event) ParseQOS() (qTtype QOSType, proportion float64, diff ClockTimeDiff, timestamp ClockTime) {
|
|
var gtype C.GstQOSType
|
|
var gprop C.gdouble
|
|
var gdiff C.GstClockTimeDiff
|
|
var gts C.GstClockTime
|
|
C.gst_event_parse_qos(
|
|
e.Instance(),
|
|
>ype, &gprop, &gdiff, >s,
|
|
)
|
|
return QOSType(gtype), float64(gprop), ClockTimeDiff(gdiff), ClockTime(gts)
|
|
}
|
|
|
|
// ParseSeek parses a seek event.
|
|
func (e *Event) ParseSeek() (rate float64, format Format, flags SeekFlags, startType SeekType, start int64, stopType SeekType, stop int64) {
|
|
var grate C.gdouble
|
|
var gformat C.GstFormat
|
|
var gflags C.GstSeekFlags
|
|
var gstartType, gstopType C.GstSeekType
|
|
var gstart, gstop C.gint64
|
|
C.gst_event_parse_seek(e.Instance(), &grate, &gformat, &gflags, &gstartType, &gstart, &gstopType, &gstop)
|
|
return float64(grate), Format(gformat), SeekFlags(gflags), SeekType(gstartType), int64(gstart), SeekType(gstopType), int64(gstop)
|
|
}
|
|
|
|
// ParseSeekTrickModeInterval retrieves the trickmode interval that may have been set on a seek event with
|
|
// SetSeekTrickModeInterval.
|
|
func (e *Event) ParseSeekTrickModeInterval() (interval ClockTime) {
|
|
var out C.GstClockTime
|
|
C.gst_event_parse_seek_trickmode_interval(e.Instance(), &out)
|
|
return ClockTime(out)
|
|
}
|
|
|
|
// ParseSegment parses a segment event and stores the result in the given segment location. segment remains valid
|
|
// only until the event is freed. Don't modify the segment and make a copy if you want to modify it or store it for
|
|
// later use.
|
|
func (e *Event) ParseSegment() *Segment {
|
|
var out *C.GstSegment
|
|
C.gst_event_parse_segment(e.Instance(), &out)
|
|
return wrapSegment(out)
|
|
}
|
|
|
|
// ParseSegmentDone extracts the position and format from the segment done message.
|
|
func (e *Event) ParseSegmentDone() (Format, int64) {
|
|
var format C.GstFormat
|
|
var pos C.gint64
|
|
C.gst_event_parse_segment_done(e.Instance(), &format, &pos)
|
|
return Format(format), int64(pos)
|
|
}
|
|
|
|
// ParseSelectStreams parses the SELECT_STREAMS event and retrieve the contained streams.
|
|
func (e *Event) ParseSelectStreams() []*Stream {
|
|
var outList *C.GList
|
|
C.gst_event_parse_select_streams(e.Instance(), &outList)
|
|
return glistToStreamSlice(outList)
|
|
}
|
|
|
|
// ParseSinkMessage parses the sink-message event. Unref msg after usage.
|
|
func (e *Event) ParseSinkMessage() *Message {
|
|
var msg *C.GstMessage
|
|
C.gst_event_parse_sink_message(e.Instance(), &msg)
|
|
return wrapMessage(msg)
|
|
}
|
|
|
|
// ParseStep parses a step message
|
|
func (e *Event) ParseStep() (format Format, amount uint64, rate float64, flush, intermediate bool) {
|
|
var gformat C.GstFormat
|
|
var gamount C.guint64
|
|
var grate C.gdouble
|
|
var gflush, gintermediate C.gboolean
|
|
C.gst_event_parse_step(e.Instance(), &gformat, &gamount, &grate, &gflush, &gintermediate)
|
|
return Format(gformat), uint64(gamount), float64(grate), gobool(gflush), gobool(gintermediate)
|
|
}
|
|
|
|
// ParseStream parses a stream-start event and extract the GstStream from it.
|
|
func (e *Event) ParseStream() *Stream {
|
|
var stream *C.GstStream
|
|
C.gst_event_parse_stream(e.Instance(), &stream)
|
|
return FromGstStreamUnsafeFull(unsafe.Pointer(stream))
|
|
}
|
|
|
|
// ParseStreamCollection parses a stream collection from the event.
|
|
func (e *Event) ParseStreamCollection() *StreamCollection {
|
|
stream := &C.GstStreamCollection{}
|
|
C.gst_event_parse_stream_collection(e.Instance(), &stream)
|
|
return FromGstStreamCollectionUnsafeFull(unsafe.Pointer(stream))
|
|
}
|
|
|
|
// ParseStreamFlags parses the stream flags from an event.
|
|
func (e *Event) ParseStreamFlags() StreamFlags {
|
|
var out C.GstStreamFlags
|
|
C.gst_event_parse_stream_flags(e.Instance(), &out)
|
|
return StreamFlags(out)
|
|
}
|
|
|
|
// ParseStreamGroupDone parses a stream-group-done event and store the result in the given group_id location.
|
|
func (e *Event) ParseStreamGroupDone() uint {
|
|
var out C.guint
|
|
C.gst_event_parse_stream_group_done(e.Instance(), &out)
|
|
return uint(out)
|
|
}
|
|
|
|
// ParseStreamStart parses a stream-id event and store the result in the given stream_id location.
|
|
func (e *Event) ParseStreamStart() string {
|
|
idPtr := C.malloc(C.sizeof_char * 1024)
|
|
defer C.free(idPtr)
|
|
|
|
C.gst_event_parse_stream_start(e.Instance(), (**C.gchar)(unsafe.Pointer(&idPtr)))
|
|
return C.GoString((*C.char)(unsafe.Pointer(idPtr)))
|
|
}
|
|
|
|
// ParseTag parses a tag event and stores the results in the given taglist location. Do not modify or free the returned
|
|
// tag list.
|
|
func (e *Event) ParseTag() *TagList {
|
|
var out *C.GstTagList
|
|
C.gst_event_parse_tag(e.Instance(), &out)
|
|
return FromGstTagListUnsafeNone(unsafe.Pointer(out))
|
|
}
|
|
|
|
// ParseTOC parses a TOC event and store the results in the given toc and updated locations.
|
|
func (e *Event) ParseTOC() (toc *TOC, updated bool) {
|
|
var out *C.GstToc
|
|
var gupdated C.gboolean
|
|
C.gst_event_parse_toc(e.Instance(), &out, &gupdated)
|
|
return FromGstTOCUnsafeFull(unsafe.Pointer(out)), gobool(gupdated)
|
|
}
|
|
|
|
// ParseTOCSelect parses a TOC select event and store the results in the given uid location.
|
|
func (e *Event) ParseTOCSelect() string {
|
|
idPtr := C.malloc(C.sizeof_char * 1024)
|
|
defer C.free(unsafe.Pointer(idPtr))
|
|
C.gst_event_parse_toc_select(e.Instance(), (**C.gchar)(unsafe.Pointer(&idPtr)))
|
|
return C.GoString((*C.char)(unsafe.Pointer(idPtr)))
|
|
}
|
|
|
|
// Ref increases the ref count on the event by one.
|
|
func (e *Event) Ref() *Event {
|
|
C.gst_event_ref(e.Instance())
|
|
return e
|
|
}
|
|
|
|
// SetGapFlags sets flags on event to give additional information about the reason for the GST_EVENT_GAP.
|
|
// func (e *Event) SetGapFlags(flags GapFlags) {
|
|
// C.gst_event_set_gap_flags(e.Instance(), C.GstGapFlags(flags))
|
|
// }
|
|
|
|
// NextGroupID returns a new group id that can be used for an event.
|
|
func NextGroupID() uint {
|
|
return uint(C.gst_util_group_id_next())
|
|
}
|
|
|
|
// SetGroupID sets the group id for the stream. All streams that have the same group id are supposed to be played
|
|
// together, i.e. all streams inside a container file should have the same group id but different stream ids. The
|
|
// group id should change each time the stream is started, resulting in different group ids each time a file is
|
|
// played for example.
|
|
//
|
|
// Use NextGroupID to get a new group id.
|
|
func (e *Event) SetGroupID(id uint) {
|
|
C.gst_event_set_group_id(e.Instance(), C.guint(id))
|
|
}
|
|
|
|
// SetRunningTimeOffset sets the running time offset of a event. See GetRunningTimeOffset for more information.
|
|
func (e *Event) SetRunningTimeOffset(offset int64) {
|
|
C.gst_event_set_running_time_offset(e.Instance(), C.gint64(offset))
|
|
}
|
|
|
|
// 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 ClockTime) {
|
|
C.gst_event_set_seek_trickmode_interval(e.Instance(), C.GstClockTime(interval))
|
|
}
|
|
|
|
// SetSeqnum sets the sequence number of a event.
|
|
//
|
|
// This function might be called by the creator of a event to indicate that the event relates to other events or messages.
|
|
// See GetSeqnum for more information.
|
|
func (e *Event) SetSeqnum(seqnum uint32) {
|
|
C.gst_event_set_seqnum(e.Instance(), C.guint32(seqnum))
|
|
}
|
|
|
|
// SetStream sets the stream on the stream-start event
|
|
func (e *Event) SetStream(stream *Stream) {
|
|
C.gst_event_set_stream(e.Instance(), stream.Instance())
|
|
}
|
|
|
|
// SetStreamFlags sets the stream flags on the event.
|
|
func (e *Event) SetStreamFlags(flags StreamFlags) {
|
|
C.gst_event_set_stream_flags(e.Instance(), C.GstStreamFlags(flags))
|
|
}
|
|
|
|
// Unref decreases the refcount of an event, freeing it if the refcount reaches 0.
|
|
func (e *Event) Unref() { C.gst_event_unref(e.Instance()) }
|
|
|
|
// WritableStructure returns a writable version of the structure.
|
|
func (e *Event) WritableStructure() *Structure {
|
|
return wrapStructure(C.gst_event_writable_structure(e.Instance()))
|
|
}
|