implement streams and streamcollections and finish message parsers

This commit is contained in:
tinyzimmer
2020-09-28 20:16:51 +03:00
parent 10b088998b
commit 2927ae7b1d
8 changed files with 241 additions and 23 deletions

View File

@@ -274,4 +274,16 @@ GstDevice *
toGstDevice(void *p)
{
return (GST_DEVICE_CAST(p));
}
GstStreamCollection *
toGstStreamCollection(void *p)
{
return (GST_STREAM_COLLECTION_CAST(p));
}
GstStream *
toGstStream(void *p)
{
return (GST_STREAM_CAST(p));
}

View File

@@ -40,26 +40,28 @@ GParamSpecDouble * getParamDouble (GParamSpec * param);
Type Castings
*/
GstUri * toGstURI (void *p);
GstURIHandler * toGstURIHandler (void *p);
GstRegistry * toGstRegistry (void *p);
GstPlugin * toGstPlugin (void *p);
GstPluginFeature * toGstPluginFeature (void *p);
GstObject * toGstObject (void *p);
GstElementFactory * toGstElementFactory (void *p);
GstElement * toGstElement (void *p);
GstBin * toGstBin (void *p);
GstBus * toGstBus (void *p);
GstMessage * toGstMessage (void *p);
GstPipeline * toGstPipeline (void *p);
GstPad * toGstPad (void *p);
GstPadTemplate * toGstPadTemplate (void *p);
GstStructure * toGstStructure (void *p);
GstClock * toGstClock (void *p);
GstMiniObject * toGstMiniObject (void *p);
GstCaps * toGstCaps (void *p);
GstCapsFeatures * toGstCapsFeatures (void *p);
GstBuffer * toGstBuffer (void *p);
GstBufferPool * toGstBufferPool (void *p);
GstSample * toGstSample (void *p);
GstDevice * toGstDevice (void *p);
GstUri * toGstURI (void *p);
GstURIHandler * toGstURIHandler (void *p);
GstRegistry * toGstRegistry (void *p);
GstPlugin * toGstPlugin (void *p);
GstPluginFeature * toGstPluginFeature (void *p);
GstObject * toGstObject (void *p);
GstElementFactory * toGstElementFactory (void *p);
GstElement * toGstElement (void *p);
GstBin * toGstBin (void *p);
GstBus * toGstBus (void *p);
GstMessage * toGstMessage (void *p);
GstPipeline * toGstPipeline (void *p);
GstPad * toGstPad (void *p);
GstPadTemplate * toGstPadTemplate (void *p);
GstStructure * toGstStructure (void *p);
GstClock * toGstClock (void *p);
GstMiniObject * toGstMiniObject (void *p);
GstCaps * toGstCaps (void *p);
GstCapsFeatures * toGstCapsFeatures (void *p);
GstBuffer * toGstBuffer (void *p);
GstBufferPool * toGstBufferPool (void *p);
GstSample * toGstSample (void *p);
GstDevice * toGstDevice (void *p);
GstStreamCollection * toGstStreamCollection (void *p);
GstStream * toGstStream (void *p);

View File

@@ -2,6 +2,7 @@ package gst
// #include "gst.go.h"
import "C"
import "unsafe"
// 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.
@@ -368,3 +369,33 @@ func (p ProgressType) String() string {
}
return ""
}
// StreamType is a go representation of a GstStreamType
type StreamType int
// Type castings of stream types
const (
StreamTypeUnknown StreamType = C.GST_STREAM_TYPE_UNKNOWN // (1) The stream is of unknown (unclassified) type.
StreamTypeAudio StreamType = C.GST_STREAM_TYPE_AUDIO // (2) The stream is of audio data
StreamTypeVideo StreamType = C.GST_STREAM_TYPE_VIDEO // (4) The stream carries video data
StreamTypeContainer StreamType = C.GST_STREAM_TYPE_CONTAINER // (8) The stream is a muxed container type
StreamTypeText StreamType = C.GST_STREAM_TYPE_TEXT // (16) The stream contains subtitle / subpicture data.
)
// String implements a stringer on StreamTypes.
func (s StreamType) String() string {
name := C.gst_stream_type_get_name((C.GstStreamType)(s))
defer C.free(unsafe.Pointer(name))
return C.GoString(name)
}
// StreamFlags represent configuration options for a new stream.
type StreamFlags int
// Type castings of StreamFlags
const (
StreamFlagNone StreamFlags = C.GST_STREAM_FLAG_NONE // (0) This stream has no special attributes
StreamFlagSparse StreamFlags = C.GST_STREAM_FLAG_SPARSE // (1) This stream is a sparse stream (e.g. a subtitle stream), data may flow only in irregular intervals with large gaps in between.
StreamFlagSelect StreamFlags = C.GST_STREAM_FLAG_SELECT // (2) This stream should be selected by default. This flag may be used by demuxers to signal that a stream should be selected by default in a playback scenario.
StreamFlagUnselect StreamFlags = C.GST_STREAM_FLAG_UNSELECT // (4) This stream should not be selected by default. This flag may be used by demuxers to signal that a stream should not be selected by default in a playback scenario, but only if explicitly selected by the user (e.g. an audio track for the hard of hearing or a director's commentary track).
)

View File

@@ -424,3 +424,46 @@ func (m *Message) ParsePropertyNotify() (obj *Object, propertName string, proper
string(C.GoBytes(namePtr, C.sizeOfGCharArray((**C.gchar)(namePtr)))),
glib.ValueFromNative(unsafe.Pointer(gval))
}
// ParseStreamCollection parses a stream-collection message.
func (m *Message) ParseStreamCollection() *StreamCollection {
var collection *C.GstStreamCollection
C.gst_message_parse_stream_collection(
(*C.GstMessage)(m.Instance()),
&collection,
)
return wrapStreamCollection(glib.Take(unsafe.Pointer(collection)))
}
// ParseStreamsSelected parses a streams-selected message.
func (m *Message) ParseStreamsSelected() *StreamCollection {
var collection *C.GstStreamCollection
C.gst_message_parse_streams_selected(
(*C.GstMessage)(m.Instance()),
&collection,
)
return wrapStreamCollection(glib.Take(unsafe.Pointer(collection)))
}
// NumRedirectEntries returns the number of redirect entries in a MessageRedirect.
func (m *Message) NumRedirectEntries() int64 {
return int64(C.gst_message_get_num_redirect_entries((*C.GstMessage)(m.Instance())))
}
// ParseRedirectEntryAt parses the redirect entry at the given index. Total indices can be retrieved
// with NumRedirectEntries().
func (m *Message) ParseRedirectEntryAt(idx int64) (location string, tags *TagList, structure *Structure) {
locPtr := C.malloc(C.sizeof_char * 1024)
defer C.free(unsafe.Pointer(locPtr))
var tagList *C.GstTagList
var entryStruct *C.GstStructure
C.gst_message_parse_redirect_entry(
(*C.GstMessage)(m.Instance()),
C.gsize(idx),
(**C.char)(locPtr),
&tagList,
&entryStruct,
)
return string(C.GoBytes(locPtr, C.sizeOfGCharArray((**C.gchar)(locPtr)))),
wrapTagList(tagList), wrapStructure(entryStruct)
}

View File

@@ -169,10 +169,15 @@ func (m *Message) String() string {
}
case MessageStreamCollection:
collection := m.ParseStreamCollection()
msg += fmt.Sprintf("New stream collection with upstream id: %s", collection.GetUpstreamID())
case MessageStreamsSelected:
collection := m.ParseStreamsSelected()
msg += fmt.Sprintf("Stream with upstream id '%s' has selected new streams", collection.GetUpstreamID())
case MessageRedirect:
msg += fmt.Sprintf("Received redirect message with %d entries", m.NumRedirectEntries())
case MessageUnknown:
msg += "Unknown message type"

70
gst/gst_stream.go Normal file
View File

@@ -0,0 +1,70 @@
package gst
// #include "gst.go.h"
import "C"
import (
"unsafe"
"github.com/gotk3/gotk3/glib"
)
// Stream is a Go representation of a GstStream.
type Stream struct{ *Object }
// NewStream returns a new Stream with the given ID, caps, type, and flags.
func NewStream(id string, caps *Caps, sType StreamType, flags StreamFlags) *Stream {
cID := C.CString(id)
defer C.free(unsafe.Pointer(cID))
stream := C.gst_stream_new(cID, caps.Instance(), C.GstStreamType(sType), C.GstStreamFlags(flags))
return wrapStream(glib.Take(unsafe.Pointer(stream)))
}
// Instance returns the underlying GstStream.
func (s *Stream) Instance() *C.GstStream {
return C.toGstStream(s.Unsafe())
}
// Caps returns the caps for this stream.
func (s *Stream) Caps() *Caps {
return wrapCaps(C.gst_stream_get_caps(s.Instance()))
}
// StreamFlags returns the flags for this stream.
func (s *Stream) StreamFlags() StreamFlags {
return StreamFlags(C.gst_stream_get_stream_flags(s.Instance()))
}
// StreamID returns the id of this stream.
func (s *Stream) StreamID() string {
return C.GoString(C.gst_stream_get_stream_id(s.Instance()))
}
// StreamType returns the type of this stream.
func (s *Stream) StreamType() StreamType {
return StreamType(C.gst_stream_get_stream_type(s.Instance()))
}
// Tags returns the tag list for this stream.
func (s *Stream) Tags() *TagList {
return wrapTagList(C.gst_stream_get_tags(s.Instance()))
}
// SetCaps sets the caps for this stream.
func (s *Stream) SetCaps(caps *Caps) {
C.gst_stream_set_caps(s.Instance(), caps.Instance())
}
// SetStreamFlags sets the flags for this stream.
func (s *Stream) SetStreamFlags(flags StreamFlags) {
C.gst_stream_set_stream_flags(s.Instance(), C.GstStreamFlags(flags))
}
// SetStreamType sets the type of this stream.
func (s *Stream) SetStreamType(sType StreamType) {
C.gst_stream_set_stream_type(s.Instance(), C.GstStreamType(sType))
}
// SetTags sets the tags for this stream.
func (s *Stream) SetTags(tags *TagList) {
C.gst_stream_set_tags(s.Instance(), tags.Instance())
}

View File

@@ -0,0 +1,51 @@
package gst
// #include "gst.go.h"
import "C"
import (
"fmt"
"unsafe"
"github.com/gotk3/gotk3/glib"
)
// StreamCollection is a Go representation of a GstStreamCollection.
type StreamCollection struct{ *Object }
// NewStreamCollection returns a new StreamCollection with an upstream parent
// of the given stream ID.
func NewStreamCollection(upstreamID string) *StreamCollection {
cID := C.CString(upstreamID)
defer C.free(unsafe.Pointer(cID))
collection := C.gst_stream_collection_new(cID)
return wrapStreamCollection(glib.Take(unsafe.Pointer(collection)))
}
// Instance returns the underlying GstStreamCollection.
func (s *StreamCollection) Instance() *C.GstStreamCollection {
return C.toGstStreamCollection(s.Unsafe())
}
// AddStream adds the given stream to this collection.
func (s *StreamCollection) AddStream(stream *Stream) error {
if ok := gobool(C.gst_stream_collection_add_stream(s.Instance(), stream.Instance())); !ok {
return fmt.Errorf("Failed to add stream %s to collection", stream.StreamID())
}
return nil
}
// GetSize returns the size of this stream collection.
func (s *StreamCollection) GetSize() uint {
return uint(C.gst_stream_collection_get_size(s.Instance()))
}
// GetStreamAt returns the stream at the given index in this collection.
func (s *StreamCollection) GetStreamAt(idx uint) *Stream {
stream := C.gst_stream_collection_get_stream(s.Instance(), C.guint(idx))
return wrapStream(glib.Take(unsafe.Pointer(stream)))
}
// GetUpstreamID retrieves the upstream ID for this collection.
func (s *StreamCollection) GetUpstreamID() string {
return C.GoString(C.gst_stream_collection_get_upstream_id(s.Instance()))
}

View File

@@ -117,6 +117,10 @@ func wrapSample(sample *C.GstSample) *Sample { return &Sample{sample:
func wrapBuffer(buf *C.GstBuffer) *Buffer { return &Buffer{ptr: buf} }
func wrapMainLoop(loop *C.GMainLoop) *MainLoop { return &MainLoop{ptr: loop} }
func wrapMainContext(ctx *C.GMainContext) *MainContext { return &MainContext{ptr: ctx} }
func wrapStream(obj *glib.Object) *Stream { return &Stream{wrapObject(obj)} }
func wrapStreamCollection(obj *glib.Object) *StreamCollection {
return &StreamCollection{wrapObject(obj)}
}
// Clock wrappers