mirror of
https://github.com/go-gst/go-gst.git
synced 2025-10-24 08:13:53 +08:00
add push src and flow combiner
This commit is contained in:
@@ -68,8 +68,8 @@ func createPipeline() (*gst.Pipeline, error) {
|
||||
// mode of access (read, read/write).
|
||||
//
|
||||
// We also know what format to expect because we set it with the caps. So we convert
|
||||
// the map directly to signed 16-bit integers.
|
||||
samples := buffer.Map(gst.MapRead).AsInt16Slice()
|
||||
// the map directly to signed 16-bit little-endian integers.
|
||||
samples := buffer.Map(gst.MapRead).AsInt16LESlice()
|
||||
defer buffer.Unmap()
|
||||
|
||||
// Calculate the root mean square for the buffer
|
||||
|
||||
@@ -65,7 +65,7 @@ func padProbes(mainLoop *gst.MainLoop) error {
|
||||
// We know what format the data in the memory region has, since we requested
|
||||
// it by setting the fakesink's caps. So what we do here is interpret the
|
||||
// memory region we mapped as an array of signed 16 bit integers.
|
||||
samples := mapInfo.AsInt16Slice()
|
||||
samples := mapInfo.AsInt16LESlice()
|
||||
if len(samples) == 0 {
|
||||
return gst.PadProbeOK
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
// $ go build -o libgstgofilesrc.so -buildmode c-shared .
|
||||
//
|
||||
//
|
||||
//go:generate go run github.com/tinyzimmer/go-gst/gen/plugin-gen.go
|
||||
package main
|
||||
|
||||
import (
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
#ifndef __GST_BASE_GO_H__
|
||||
#define __GST_BASE_GO_H__
|
||||
|
||||
#include <gst/base/gstbasesrc.h>
|
||||
#include <gst/base/gstbasesink.h>
|
||||
#include <gst/base/base.h>
|
||||
|
||||
inline GstBaseSink * toGstBaseSink (void *p) { return GST_BASE_SINK_CAST(p); }
|
||||
inline GstBaseSrc * toGstBaseSrc (void *p) { return GST_BASE_SRC_CAST(p); }
|
||||
inline GstPushSrc * toGstPushSrc (void *p) { return GST_PUSH_SRC(p); }
|
||||
|
||||
inline GstBaseSinkClass * toGstBaseSinkClass (void *p) { return (GstBaseSinkClass *)p; }
|
||||
inline GstBaseSrcClass * toGstBaseSrcClass (void *p) { return (GstBaseSrcClass *)p; }
|
||||
inline GstPushSrcClass * toGstPushSrcClass (void *p) { return (GstPushSrcClass *)p; }
|
||||
|
||||
#endif
|
||||
78
gst/base/gst_flow_combiner.go
Normal file
78
gst/base/gst_flow_combiner.go
Normal file
@@ -0,0 +1,78 @@
|
||||
package base
|
||||
|
||||
/*
|
||||
#include "gst.go.h"
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/tinyzimmer/go-gst/gst"
|
||||
)
|
||||
|
||||
// FlowCombiner is a helper structure for aggregating flow returns. This struct
|
||||
// is not thread safe.
|
||||
// For more information see https://gstreamer.freedesktop.org/documentation/base/gstflowcombiner.html?gi-language=c#GstFlowCombiner
|
||||
type FlowCombiner struct{ ptr *C.GstFlowCombiner }
|
||||
|
||||
func wrapFlowCombiner(ptr *C.GstFlowCombiner) *FlowCombiner {
|
||||
return &FlowCombiner{ptr}
|
||||
}
|
||||
|
||||
// NewFlowCombiner creates a new flow combiner. Use Free() to free it.
|
||||
func NewFlowCombiner() *FlowCombiner {
|
||||
return wrapFlowCombiner(C.gst_flow_combiner_new())
|
||||
}
|
||||
|
||||
// Instance returns the underlying GstFlowCombiner instance.
|
||||
func (f *FlowCombiner) Instance() *C.GstFlowCombiner { return f.ptr }
|
||||
|
||||
// AddPad adds a new pad to the FlowCombiner. A reference is taken on the pad.
|
||||
func (f *FlowCombiner) AddPad(pad *gst.Pad) {
|
||||
C.gst_flow_combiner_add_pad(f.Instance(), (*C.GstPad)(unsafe.Pointer(pad.Instance())))
|
||||
}
|
||||
|
||||
// Clear will remove all pads and reset the combiner to its initial state.
|
||||
func (f *FlowCombiner) Clear() { C.gst_flow_combiner_clear(f.Instance()) }
|
||||
|
||||
// Free will free a FlowCombiner and all its internal data.
|
||||
func (f *FlowCombiner) Free() { C.gst_flow_combiner_free(f.Instance()) }
|
||||
|
||||
// Ref will increment the reference count on the FlowCombiner.
|
||||
func (f *FlowCombiner) Ref() *FlowCombiner {
|
||||
return wrapFlowCombiner(C.gst_flow_combiner_ref(f.Instance()))
|
||||
}
|
||||
|
||||
// RemovePad will remove a pad from the FlowCombiner.
|
||||
func (f *FlowCombiner) RemovePad(pad *gst.Pad) {
|
||||
C.gst_flow_combiner_remove_pad(f.Instance(), (*C.GstPad)(unsafe.Pointer(pad.Instance())))
|
||||
}
|
||||
|
||||
// Reset flow combiner and all pads to their initial state without removing pads.
|
||||
func (f *FlowCombiner) Reset() { C.gst_flow_combiner_reset(f.Instance()) }
|
||||
|
||||
// Unref decrements the reference count on the Flow Combiner.
|
||||
func (f *FlowCombiner) Unref() { C.gst_flow_combiner_unref(f.Instance()) }
|
||||
|
||||
// UpdateFlow computes the combined flow return for the pads in it.
|
||||
//
|
||||
// The GstFlowReturn parameter should be the last flow return update for a pad in this GstFlowCombiner.
|
||||
// It will use this value to be able to shortcut some combinations and avoid looking over all pads again.
|
||||
// e.g. The last combined return is the same as the latest obtained GstFlowReturn.
|
||||
func (f *FlowCombiner) UpdateFlow(fret gst.FlowReturn) gst.FlowReturn {
|
||||
return gst.FlowReturn(C.gst_flow_combiner_update_flow(f.Instance(), C.GstFlowReturn(fret)))
|
||||
}
|
||||
|
||||
// UpdatePadFlow sets the provided pad's last flow return to provided value and computes the combined flow
|
||||
// return for the pads in it.
|
||||
//
|
||||
// The GstFlowReturn parameter should be the last flow return update for a pad in this GstFlowCombiner. It
|
||||
// will use this value to be able to shortcut some combinations and avoid looking over all pads again. e.g.
|
||||
// The last combined return is the same as the latest obtained GstFlowReturn.
|
||||
func (f *FlowCombiner) UpdatePadFlow(pad *gst.Pad, fret gst.FlowReturn) gst.FlowReturn {
|
||||
return gst.FlowReturn(C.gst_flow_combiner_update_pad_flow(
|
||||
f.Instance(),
|
||||
(*C.GstPad)(unsafe.Pointer(pad.Instance())),
|
||||
C.GstFlowReturn(fret),
|
||||
))
|
||||
}
|
||||
30
gst/base/gst_push_src.go
Normal file
30
gst/base/gst_push_src.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package base
|
||||
|
||||
/*
|
||||
#include "gst.go.h"
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/tinyzimmer/go-gst/gst"
|
||||
)
|
||||
|
||||
// GstPushSrc represents a GstBaseSrc.
|
||||
type GstPushSrc struct{ *GstBaseSrc }
|
||||
|
||||
// ToGstPushSrc returns a GstPushSrc object for the given object.
|
||||
func ToGstPushSrc(obj *gst.Object) *GstPushSrc {
|
||||
return &GstPushSrc{&GstBaseSrc{&gst.Element{Object: obj}}}
|
||||
}
|
||||
|
||||
// wrapGstPushSrc wraps the given unsafe.Pointer in a GstPushSrc instance.
|
||||
func wrapGstPushSrc(obj *C.GstPushSrc) *GstPushSrc {
|
||||
return &GstPushSrc{&GstBaseSrc{gst.FromGstElementUnsafe(unsafe.Pointer(obj))}}
|
||||
}
|
||||
|
||||
// Instance returns the underlying C GstBaseSrc instance
|
||||
func (g *GstPushSrc) Instance() *C.GstPushSrc {
|
||||
return C.toGstPushSrc(g.Unsafe())
|
||||
}
|
||||
46
gst/base/gst_push_src_exports.go
Normal file
46
gst/base/gst_push_src_exports.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package base
|
||||
|
||||
/*
|
||||
#include "gst.go.h"
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/tinyzimmer/go-gst/gst"
|
||||
)
|
||||
|
||||
//export goGstPushSrcAlloc
|
||||
func goGstPushSrcAlloc(src *C.GstPushSrc, buf **C.GstBuffer) C.GstFlowReturn {
|
||||
caller := gst.FromObjectUnsafePrivate(unsafe.Pointer(src)).(interface {
|
||||
Alloc(*GstPushSrc) (gst.FlowReturn, *gst.Buffer)
|
||||
})
|
||||
ret, buffer := caller.Alloc(wrapGstPushSrc(src))
|
||||
if ret != gst.FlowOK {
|
||||
return C.GstFlowReturn(ret)
|
||||
}
|
||||
C.memcpy(unsafe.Pointer(*buf), unsafe.Pointer(buffer.Instance()), C.sizeof_GstBuffer)
|
||||
return C.GstFlowReturn(ret)
|
||||
}
|
||||
|
||||
//export goGstPushSrcCreate
|
||||
func goGstPushSrcCreate(src *C.GstPushSrc, buf **C.GstBuffer) C.GstFlowReturn {
|
||||
caller := gst.FromObjectUnsafePrivate(unsafe.Pointer(src)).(interface {
|
||||
Create(*GstPushSrc) (gst.FlowReturn, *gst.Buffer)
|
||||
})
|
||||
ret, buffer := caller.Create(wrapGstPushSrc(src))
|
||||
if ret != gst.FlowOK {
|
||||
return C.GstFlowReturn(ret)
|
||||
}
|
||||
C.memcpy(unsafe.Pointer(*buf), unsafe.Pointer(buffer.Instance()), C.sizeof_GstBuffer)
|
||||
return C.GstFlowReturn(ret)
|
||||
}
|
||||
|
||||
//export goGstPushSrcFill
|
||||
func goGstPushSrcFill(src *C.GstPushSrc, buf *C.GstBuffer) C.GstFlowReturn {
|
||||
caller := gst.FromObjectUnsafePrivate(unsafe.Pointer(src)).(interface {
|
||||
Fill(*GstPushSrc, *gst.Buffer) gst.FlowReturn
|
||||
})
|
||||
return C.GstFlowReturn(caller.Fill(wrapGstPushSrc(src), gst.FromGstBufferUnsafe(unsafe.Pointer(buf))))
|
||||
}
|
||||
72
gst/base/gst_push_src_impl.go
Normal file
72
gst/base/gst_push_src_impl.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package base
|
||||
|
||||
/*
|
||||
#include "gst.go.h"
|
||||
|
||||
extern GstFlowReturn goGstPushSrcAlloc (GstPushSrc * src, GstBuffer ** buf);
|
||||
extern GstFlowReturn goGstPushSrcCreate (GstPushSrc * src, GstBuffer ** buf);
|
||||
extern GstFlowReturn goGstPushSrcFill (GstPushSrc * src, GstBuffer * buf);
|
||||
|
||||
void setGstPushSrcAlloc (GstPushSrcClass * klass) { klass->alloc = goGstPushSrcAlloc; }
|
||||
void setGstPushSrcCreate (GstPushSrcClass * klass) { klass->create = goGstPushSrcCreate; }
|
||||
void setGstPushSrcFill (GstPushSrcClass * klass) { klass->fill = goGstPushSrcFill; }
|
||||
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/tinyzimmer/go-glib/glib"
|
||||
"github.com/tinyzimmer/go-gst/gst"
|
||||
)
|
||||
|
||||
var (
|
||||
// ExtendsPushSrc is an Extendable for extending a GstPushSrc
|
||||
ExtendsPushSrc gst.Extendable = &extendsPushSrc{parent: ExtendsBaseSrc}
|
||||
)
|
||||
|
||||
// GstPushSrcImpl is the documented interface for an element extending a GstPushSrc. It does not have to
|
||||
// be implemented in it's entirety. Each of the methods it declares will be checked for their presence
|
||||
// in the initializing object, and if the object declares an override it will replace the default
|
||||
// implementation in the virtual methods.
|
||||
type GstPushSrcImpl interface {
|
||||
// Asks the subclass to allocate a buffer. The subclass decides which size this buffer should be.
|
||||
// The default implementation will create a new buffer from the negotiated allocator.
|
||||
Alloc(*GstPushSrc) (gst.FlowReturn, *gst.Buffer)
|
||||
// Asks the subclass to create a buffer. The subclass decides which size this buffer should be. Other
|
||||
// then that, refer to GstBaseSrc.create for more details. If this method is not implemented, alloc
|
||||
// followed by fill will be called.
|
||||
Create(*GstPushSrc) (gst.FlowReturn, *gst.Buffer)
|
||||
// Asks the subclass to fill the buffer with data.
|
||||
Fill(*GstPushSrc, *gst.Buffer) gst.FlowReturn
|
||||
}
|
||||
|
||||
type extendsPushSrc struct{ parent gst.Extendable }
|
||||
|
||||
func (e *extendsPushSrc) Type() glib.Type { return glib.Type(C.gst_push_src_get_type()) }
|
||||
func (e *extendsPushSrc) ClassSize() int64 { return int64(C.sizeof_GstPushSrcClass) }
|
||||
func (e *extendsPushSrc) InstanceSize() int64 { return int64(C.sizeof_GstPushSrc) }
|
||||
|
||||
func (e *extendsPushSrc) InitClass(klass unsafe.Pointer, elem gst.GoElement) {
|
||||
e.parent.InitClass(klass, elem)
|
||||
|
||||
srcClass := C.toGstPushSrcClass(klass)
|
||||
|
||||
if _, ok := elem.(interface {
|
||||
Alloc(*GstPushSrc) (gst.FlowReturn, *gst.Buffer)
|
||||
}); ok {
|
||||
C.setGstPushSrcAlloc(srcClass)
|
||||
}
|
||||
|
||||
if _, ok := elem.(interface {
|
||||
Create(*GstPushSrc) (gst.FlowReturn, *gst.Buffer)
|
||||
}); ok {
|
||||
C.setGstPushSrcCreate(srcClass)
|
||||
}
|
||||
|
||||
if _, ok := elem.(interface {
|
||||
Fill(*GstPushSrc, *gst.Buffer) gst.FlowReturn
|
||||
}); ok {
|
||||
C.setGstPushSrcFill(srcClass)
|
||||
}
|
||||
}
|
||||
152
gst/base/gst_type_find.go
Normal file
152
gst/base/gst_type_find.go
Normal file
@@ -0,0 +1,152 @@
|
||||
package base
|
||||
|
||||
/*
|
||||
#include "gst.go.h"
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/tinyzimmer/go-gst/gst"
|
||||
)
|
||||
|
||||
// TypeFindHelper tries to find what type of data is flowing from the given source GstPad.
|
||||
// Returns nil if no Caps matches the data stream. Unref after usage.
|
||||
func TypeFindHelper(pad *gst.Pad, size uint64) *gst.Caps {
|
||||
caps := C.gst_type_find_helper((*C.GstPad)(unsafe.Pointer(pad.Instance())), C.guint64(size))
|
||||
if caps == nil {
|
||||
return nil
|
||||
}
|
||||
return gst.FromGstCapsUnsafe(unsafe.Pointer(caps))
|
||||
}
|
||||
|
||||
// TypeFindHelperForBuffer tries to find what type of data is contained in the given GstBuffer,
|
||||
// the assumption being that the buffer represents the beginning of the stream or file.
|
||||
//
|
||||
// All available typefinders will be called on the data in order of rank. If a typefinding function
|
||||
// returns a probability of gst.TypeFindMaximum, typefinding is stopped immediately and the found
|
||||
// caps will be returned right away. Otherwise, all available typefind functions will the tried, and
|
||||
// the caps with the highest probability will be returned, or nil if the content of the buffer could
|
||||
// not be identified.
|
||||
//
|
||||
// Object can either be nil or the object doing the typefinding (used for logging). Caps should be unrefed
|
||||
// after usage.
|
||||
func TypeFindHelperForBuffer(obj *gst.Object, buffer *gst.Buffer) (*gst.Caps, gst.TypeFindProbability) {
|
||||
var prob C.GstTypeFindProbability
|
||||
var cobj *C.GstObject
|
||||
if obj != nil {
|
||||
cobj = (*C.GstObject)(obj.Unsafe())
|
||||
}
|
||||
caps := C.gst_type_find_helper_for_buffer(cobj, (*C.GstBuffer)(unsafe.Pointer(buffer.Instance())), &prob)
|
||||
if caps == nil {
|
||||
return nil, gst.TypeFindProbability(prob)
|
||||
}
|
||||
return gst.FromGstCapsUnsafe(unsafe.Pointer(caps)), gst.TypeFindProbability(prob)
|
||||
}
|
||||
|
||||
// TypeFindHelperForBufferWithExtension ries to find what type of data is contained in the given GstBuffer,
|
||||
// the assumption being that the buffer represents the beginning of the stream or file.
|
||||
//
|
||||
// All available typefinders will be called on the data in order of rank. If a typefinding function returns
|
||||
// a probability of gst.TypeFindMaximum, typefinding is stopped immediately and the found caps will be returned
|
||||
// right away. Otherwise, all available typefind functions will the tried, and the caps with the highest
|
||||
// probability will be returned, or nil if the content of the buffer could not be identified.
|
||||
//
|
||||
// When extension is not empty, this function will first try the typefind functions for the given extension,
|
||||
// which might speed up the typefinding in many cases.
|
||||
//
|
||||
// Unref caps after usage.
|
||||
func TypeFindHelperForBufferWithExtension(obj *gst.Object, buffer *gst.Buffer, extension string) (*gst.Caps, gst.TypeFindProbability) {
|
||||
var prob C.GstTypeFindProbability
|
||||
var cobj *C.GstObject
|
||||
var cext *C.gchar
|
||||
if obj != nil {
|
||||
cobj = (*C.GstObject)(obj.Unsafe())
|
||||
}
|
||||
if extension != "" {
|
||||
cstr := C.CString(extension)
|
||||
defer C.free(unsafe.Pointer(cstr))
|
||||
cext = (*C.gchar)(unsafe.Pointer(cstr))
|
||||
}
|
||||
caps := C.gst_type_find_helper_for_buffer_with_extension(cobj, (*C.GstBuffer)(unsafe.Pointer(buffer.Instance())), cext, &prob)
|
||||
if caps == nil {
|
||||
return nil, gst.TypeFindProbability(prob)
|
||||
}
|
||||
return gst.FromGstCapsUnsafe(unsafe.Pointer(caps)), gst.TypeFindProbability(prob)
|
||||
}
|
||||
|
||||
// TypeFindHelperForData tries to find what type of data is contained in the given data,
|
||||
// the assumption being that the buffer represents the beginning of the stream or file.
|
||||
//
|
||||
// All available typefinders will be called on the data in order of rank. If a typefinding function
|
||||
// returns a probability of gst.TypeFindMaximum, typefinding is stopped immediately and the found
|
||||
// caps will be returned right away. Otherwise, all available typefind functions will the tried, and
|
||||
// the caps with the highest probability will be returned, or nil if the content of the buffer could
|
||||
// not be identified.
|
||||
//
|
||||
// Object can either be nil or the object doing the typefinding (used for logging). Caps should be unrefed
|
||||
// after usage.
|
||||
func TypeFindHelperForData(obj *gst.Object, data []byte) (*gst.Caps, gst.TypeFindProbability) {
|
||||
var prob C.GstTypeFindProbability
|
||||
var cobj *C.GstObject
|
||||
if obj != nil {
|
||||
cobj = (*C.GstObject)(obj.Unsafe())
|
||||
}
|
||||
caps := C.gst_type_find_helper_for_data(cobj, (*C.guint8)(unsafe.Pointer(&data[0])), C.gsize(len(data)), &prob)
|
||||
if caps == nil {
|
||||
return nil, gst.TypeFindProbability(prob)
|
||||
}
|
||||
return gst.FromGstCapsUnsafe(unsafe.Pointer(caps)), gst.TypeFindProbability(prob)
|
||||
}
|
||||
|
||||
// TypeFindHelperForDataWithExtension ries to find what type of data is contained in the given data,
|
||||
// the assumption being that the buffer represents the beginning of the stream or file.
|
||||
//
|
||||
// All available typefinders will be called on the data in order of rank. If a typefinding function returns
|
||||
// a probability of gst.TypeFindMaximum, typefinding is stopped immediately and the found caps will be returned
|
||||
// right away. Otherwise, all available typefind functions will the tried, and the caps with the highest
|
||||
// probability will be returned, or nil if the content of the buffer could not be identified.
|
||||
//
|
||||
// When extension is not empty, this function will first try the typefind functions for the given extension,
|
||||
// which might speed up the typefinding in many cases.
|
||||
//
|
||||
// Object can either be nil or the object doing the typefinding (used for logging). Unref caps after usage.
|
||||
func TypeFindHelperForDataWithExtension(obj *gst.Object, data []byte, extension string) (*gst.Caps, gst.TypeFindProbability) {
|
||||
var prob C.GstTypeFindProbability
|
||||
var cobj *C.GstObject
|
||||
var cext *C.gchar
|
||||
if obj != nil {
|
||||
cobj = (*C.GstObject)(obj.Unsafe())
|
||||
}
|
||||
if extension != "" {
|
||||
cstr := C.CString(extension)
|
||||
defer C.free(unsafe.Pointer(cstr))
|
||||
cext = (*C.gchar)(unsafe.Pointer(cstr))
|
||||
}
|
||||
caps := C.gst_type_find_helper_for_data_with_extension(cobj, (*C.guint8)(unsafe.Pointer(&data[0])), C.gsize(len(data)), cext, &prob)
|
||||
if caps == nil {
|
||||
return nil, gst.TypeFindProbability(prob)
|
||||
}
|
||||
return gst.FromGstCapsUnsafe(unsafe.Pointer(caps)), gst.TypeFindProbability(prob)
|
||||
}
|
||||
|
||||
// TypeFindHelperForExtension tries to find the best GstCaps associated with extension.
|
||||
//
|
||||
// All available typefinders will be checked against the extension in order of rank. The caps of the first typefinder
|
||||
// that can handle extension will be returned.
|
||||
//
|
||||
// Object can either be nil or the object doing the typefinding (used for logging). Unref caps after usage.
|
||||
func TypeFindHelperForExtension(obj *gst.Object, extension string) *gst.Caps {
|
||||
var cobj *C.GstObject
|
||||
if obj != nil {
|
||||
cobj = (*C.GstObject)(obj.Unsafe())
|
||||
}
|
||||
cext := C.CString(extension)
|
||||
defer C.free(unsafe.Pointer(cext))
|
||||
caps := C.gst_type_find_helper_for_extension(cobj, (*C.gchar)(unsafe.Pointer(cext)))
|
||||
if caps == nil {
|
||||
return nil
|
||||
}
|
||||
return gst.FromGstCapsUnsafe(unsafe.Pointer(caps))
|
||||
}
|
||||
@@ -1046,3 +1046,17 @@ const (
|
||||
TagVersion Tag = C.GST_TAG_VERSION
|
||||
TagVideoCodec Tag = C.GST_TAG_VIDEO_CODEC
|
||||
)
|
||||
|
||||
// TypeFindProbability represents a probability for type find functions. Higher values
|
||||
// reflect higher certainty.
|
||||
type TypeFindProbability int
|
||||
|
||||
// Type castings
|
||||
const (
|
||||
TypeFindNone TypeFindProbability = C.GST_TYPE_FIND_NONE // (0) – type undetected.
|
||||
TypeFindMinimum TypeFindProbability = C.GST_TYPE_FIND_MINIMUM // (1) – unlikely typefind.
|
||||
TypeFindPossible TypeFindProbability = C.GST_TYPE_FIND_POSSIBLE // (50) – possible type detected.
|
||||
TypeFindLikely TypeFindProbability = C.GST_TYPE_FIND_LIKELY // (80) – likely a type was detected.
|
||||
TypeFindNearlyCertain TypeFindProbability = C.GST_TYPE_FIND_NEARLY_CERTAIN // (99) – nearly certain that a type was detected.
|
||||
TypeFindMaximum TypeFindProbability = C.GST_TYPE_FIND_MAXIMUM // (100) – very certain a type was detected.
|
||||
)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <gst/gst.h>
|
||||
#include <gst/base/gstbasesrc.h>
|
||||
#include <gst/base/base.h>
|
||||
|
||||
/*
|
||||
Type Castings
|
||||
|
||||
@@ -5,12 +5,29 @@ package gst
|
||||
|
||||
void memcpy_offset (void * dest, guint offset, const void * src, size_t n) { memcpy(dest + offset, src, n); }
|
||||
|
||||
|
||||
GstByteReader * newByteReader (const guint8 * data, guint size)
|
||||
{
|
||||
GstByteReader *ret = g_slice_new0 (GstByteReader);
|
||||
|
||||
ret->data = data;
|
||||
ret->size = size;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void freeByteReader (GstByteReader * reader)
|
||||
{
|
||||
g_return_if_fail (reader != NULL);
|
||||
g_slice_free (GstByteReader, reader);
|
||||
}
|
||||
|
||||
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"io"
|
||||
"unsafe"
|
||||
@@ -97,79 +114,234 @@ func (m *MapInfo) Bytes() []byte {
|
||||
|
||||
// AsInt8Slice returns the contents of this map as a slice of signed 8-bit integers.
|
||||
func (m *MapInfo) AsInt8Slice() []int8 {
|
||||
uint8sl := m.AsUint8Slice()
|
||||
out := make([]int8, m.Size())
|
||||
for i := range out {
|
||||
out[i] = int8(uint8sl[i])
|
||||
br := C.newByteReader(m.Instance().data, C.guint(m.Instance().size))
|
||||
defer C.freeByteReader(br)
|
||||
out := make([]int8, 0)
|
||||
for C.gst_byte_reader_get_remaining(br) != C.guint(0) {
|
||||
var gint C.gint8
|
||||
C.gst_byte_reader_get_int8(br, &gint)
|
||||
out = append(out, int8(gint))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// AsInt16Slice returns the contents of this map as a slice of signed 16-bit integers.
|
||||
func (m *MapInfo) AsInt16Slice() []int16 {
|
||||
uint8sl := m.AsUint8Slice()
|
||||
out := make([]int16, m.Size()/2)
|
||||
for i := range out {
|
||||
out[i] = int16(binary.LittleEndian.Uint16(uint8sl[i*2 : (i+1)*2]))
|
||||
// AsInt16BESlice returns the contents of this map as a slice of signed 16-bit big-endian integers.
|
||||
func (m *MapInfo) AsInt16BESlice() []int16 {
|
||||
br := C.newByteReader(m.Instance().data, C.guint(m.Instance().size))
|
||||
defer C.freeByteReader(br)
|
||||
out := make([]int16, 0)
|
||||
for C.gst_byte_reader_get_remaining(br) != C.guint(0) {
|
||||
var gint C.gint16
|
||||
C.gst_byte_reader_get_int16_be(br, &gint)
|
||||
out = append(out, int16(gint))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// AsInt32Slice returns the contents of this map as a slice of signed 32-bit integers.
|
||||
func (m *MapInfo) AsInt32Slice() []int32 {
|
||||
uint8sl := m.AsUint8Slice()
|
||||
out := make([]int32, m.Size()/4)
|
||||
for i := range out {
|
||||
out[i] = int32(binary.LittleEndian.Uint32(uint8sl[i*4 : (i+1)*4]))
|
||||
// AsInt16LESlice returns the contents of this map as a slice of signed 16-bit little-endian integers.
|
||||
func (m *MapInfo) AsInt16LESlice() []int16 {
|
||||
br := C.newByteReader(m.Instance().data, C.guint(m.Instance().size))
|
||||
defer C.freeByteReader(br)
|
||||
out := make([]int16, 0)
|
||||
for C.gst_byte_reader_get_remaining(br) != C.guint(0) {
|
||||
var gint C.gint16
|
||||
C.gst_byte_reader_get_int16_le(br, &gint)
|
||||
out = append(out, int16(gint))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// AsInt64Slice returns the contents of this map as a slice of signed 64-bit integers.
|
||||
func (m *MapInfo) AsInt64Slice() []int64 {
|
||||
uint8sl := m.AsUint8Slice()
|
||||
out := make([]int64, m.Size()/8)
|
||||
for i := range out {
|
||||
out[i] = int64(binary.LittleEndian.Uint64(uint8sl[i*8 : (i+1)*8]))
|
||||
// AsInt32BESlice returns the contents of this map as a slice of signed 32-bit big-endian integers.
|
||||
func (m *MapInfo) AsInt32BESlice() []int32 {
|
||||
br := C.newByteReader(m.Instance().data, C.guint(m.Instance().size))
|
||||
defer C.freeByteReader(br)
|
||||
out := make([]int32, 0)
|
||||
for C.gst_byte_reader_get_remaining(br) != C.guint(0) {
|
||||
var gint C.gint32
|
||||
C.gst_byte_reader_get_int32_be(br, &gint)
|
||||
out = append(out, int32(gint))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// AsInt32LESlice returns the contents of this map as a slice of signed 32-bit little-endian integers.
|
||||
func (m *MapInfo) AsInt32LESlice() []int32 {
|
||||
br := C.newByteReader(m.Instance().data, C.guint(m.Instance().size))
|
||||
defer C.freeByteReader(br)
|
||||
out := make([]int32, 0)
|
||||
for C.gst_byte_reader_get_remaining(br) != C.guint(0) {
|
||||
var gint C.gint32
|
||||
C.gst_byte_reader_get_int32_le(br, &gint)
|
||||
out = append(out, int32(gint))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// AsInt64BESlice returns the contents of this map as a slice of signed 64-bit big-endian integers.
|
||||
func (m *MapInfo) AsInt64BESlice() []int64 {
|
||||
br := C.newByteReader(m.Instance().data, C.guint(m.Instance().size))
|
||||
defer C.freeByteReader(br)
|
||||
out := make([]int64, 0)
|
||||
for C.gst_byte_reader_get_remaining(br) != C.guint(0) {
|
||||
var gint C.gint64
|
||||
C.gst_byte_reader_get_int64_be(br, &gint)
|
||||
out = append(out, int64(gint))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// AsInt64LESlice returns the contents of this map as a slice of signed 64-bit little-endian integers.
|
||||
func (m *MapInfo) AsInt64LESlice() []int64 {
|
||||
br := C.newByteReader(m.Instance().data, C.guint(m.Instance().size))
|
||||
defer C.freeByteReader(br)
|
||||
out := make([]int64, 0)
|
||||
for C.gst_byte_reader_get_remaining(br) != C.guint(0) {
|
||||
var gint C.gint64
|
||||
C.gst_byte_reader_get_int64_le(br, &gint)
|
||||
out = append(out, int64(gint))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// AsUint8Slice returns the contents of this map as a slice of unsigned 8-bit integers.
|
||||
func (m *MapInfo) AsUint8Slice() []uint8 {
|
||||
out := make([]uint8, m.Size())
|
||||
for i, t := range (*[1 << 30]uint8)(m.Data())[:m.Size():m.Size()] {
|
||||
out[i] = t
|
||||
br := C.newByteReader(m.Instance().data, C.guint(m.Instance().size))
|
||||
defer C.freeByteReader(br)
|
||||
out := make([]uint8, 0)
|
||||
for C.gst_byte_reader_get_remaining(br) != C.guint(0) {
|
||||
var gint C.guint8
|
||||
C.gst_byte_reader_get_uint8(br, &gint)
|
||||
out = append(out, uint8(gint))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// AsUint16Slice returns the contents of this map as a slice of unsigned 16-bit integers.
|
||||
func (m *MapInfo) AsUint16Slice() []uint16 {
|
||||
uint8sl := m.AsUint8Slice()
|
||||
out := make([]uint16, m.Size()/2)
|
||||
for i := range out {
|
||||
out[i] = uint16(binary.LittleEndian.Uint16(uint8sl[i*2 : (i+1)*2]))
|
||||
// AsUint16BESlice returns the contents of this map as a slice of unsigned 16-bit big-endian integers.
|
||||
func (m *MapInfo) AsUint16BESlice() []uint16 {
|
||||
br := C.newByteReader(m.Instance().data, C.guint(m.Instance().size))
|
||||
defer C.freeByteReader(br)
|
||||
out := make([]uint16, 0)
|
||||
for C.gst_byte_reader_get_remaining(br) != C.guint(0) {
|
||||
var gint C.guint16
|
||||
C.gst_byte_reader_get_uint16_be(br, &gint)
|
||||
out = append(out, uint16(gint))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// AsUint32Slice returns the contents of this map as a slice of unsigned 32-bit integers.
|
||||
func (m *MapInfo) AsUint32Slice() []uint32 {
|
||||
uint8sl := m.AsUint8Slice()
|
||||
out := make([]uint32, m.Size()/4)
|
||||
for i := range out {
|
||||
out[i] = uint32(binary.LittleEndian.Uint32(uint8sl[i*4 : (i+1)*4]))
|
||||
// AsUint16LESlice returns the contents of this map as a slice of unsigned 16-bit little-endian integers.
|
||||
func (m *MapInfo) AsUint16LESlice() []uint16 {
|
||||
br := C.newByteReader(m.Instance().data, C.guint(m.Instance().size))
|
||||
defer C.freeByteReader(br)
|
||||
out := make([]uint16, 0)
|
||||
for C.gst_byte_reader_get_remaining(br) != C.guint(0) {
|
||||
var gint C.guint16
|
||||
C.gst_byte_reader_get_uint16_le(br, &gint)
|
||||
out = append(out, uint16(gint))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// AsUint64Slice returns the contents of this map as a slice of unsigned 64-bit integers.
|
||||
func (m *MapInfo) AsUint64Slice() []uint64 {
|
||||
uint8sl := m.AsUint8Slice()
|
||||
out := make([]uint64, m.Size()/8)
|
||||
for i := range out {
|
||||
out[i] = uint64(binary.LittleEndian.Uint64(uint8sl[i*8 : (i+1)*8]))
|
||||
// AsUint32BESlice returns the contents of this map as a slice of unsigned 32-bit big-endian integers.
|
||||
func (m *MapInfo) AsUint32BESlice() []uint32 {
|
||||
br := C.newByteReader(m.Instance().data, C.guint(m.Instance().size))
|
||||
defer C.freeByteReader(br)
|
||||
out := make([]uint32, 0)
|
||||
for C.gst_byte_reader_get_remaining(br) != C.guint(0) {
|
||||
var gint C.guint32
|
||||
C.gst_byte_reader_get_uint32_be(br, &gint)
|
||||
out = append(out, uint32(gint))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// AsUint32LESlice returns the contents of this map as a slice of unsigned 32-bit little-endian integers.
|
||||
func (m *MapInfo) AsUint32LESlice() []uint32 {
|
||||
br := C.newByteReader(m.Instance().data, C.guint(m.Instance().size))
|
||||
defer C.freeByteReader(br)
|
||||
out := make([]uint32, 0)
|
||||
for C.gst_byte_reader_get_remaining(br) != C.guint(0) {
|
||||
var gint C.guint32
|
||||
C.gst_byte_reader_get_uint32_le(br, &gint)
|
||||
out = append(out, uint32(gint))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// AsUint64BESlice returns the contents of this map as a slice of unsigned 64-bit big-endian integers.
|
||||
func (m *MapInfo) AsUint64BESlice() []uint64 {
|
||||
br := C.newByteReader(m.Instance().data, C.guint(m.Instance().size))
|
||||
defer C.freeByteReader(br)
|
||||
out := make([]uint64, 0)
|
||||
for C.gst_byte_reader_get_remaining(br) != C.guint(0) {
|
||||
var gint C.guint64
|
||||
C.gst_byte_reader_get_uint64_be(br, &gint)
|
||||
out = append(out, uint64(gint))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// AsUint64LESlice returns the contents of this map as a slice of unsigned 64-bit little-endian integers.
|
||||
func (m *MapInfo) AsUint64LESlice() []uint64 {
|
||||
br := C.newByteReader(m.Instance().data, C.guint(m.Instance().size))
|
||||
defer C.freeByteReader(br)
|
||||
out := make([]uint64, 0)
|
||||
for C.gst_byte_reader_get_remaining(br) != C.guint(0) {
|
||||
var gint C.guint64
|
||||
C.gst_byte_reader_get_uint64_le(br, &gint)
|
||||
out = append(out, uint64(gint))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// AsFloat32BESlice returns the contents of this map as a slice of 32-bit big-endian floats.
|
||||
func (m *MapInfo) AsFloat32BESlice() []float32 {
|
||||
br := C.newByteReader(m.Instance().data, C.guint(m.Instance().size))
|
||||
defer C.freeByteReader(br)
|
||||
out := make([]float32, 0)
|
||||
for C.gst_byte_reader_get_remaining(br) != C.guint(0) {
|
||||
var gint C.gfloat
|
||||
C.gst_byte_reader_get_float32_be(br, &gint)
|
||||
out = append(out, float32(gint))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// AsFloat32LESlice returns the contents of this map as a slice of 32-bit little-endian floats.
|
||||
func (m *MapInfo) AsFloat32LESlice() []float32 {
|
||||
br := C.newByteReader(m.Instance().data, C.guint(m.Instance().size))
|
||||
defer C.freeByteReader(br)
|
||||
out := make([]float32, 0)
|
||||
for C.gst_byte_reader_get_remaining(br) != C.guint(0) {
|
||||
var gint C.gfloat
|
||||
C.gst_byte_reader_get_float32_le(br, &gint)
|
||||
out = append(out, float32(gint))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// AsFloat64BESlice returns the contents of this map as a slice of 64-bit big-endian floats.
|
||||
func (m *MapInfo) AsFloat64BESlice() []float64 {
|
||||
br := C.newByteReader(m.Instance().data, C.guint(m.Instance().size))
|
||||
defer C.freeByteReader(br)
|
||||
out := make([]float64, 0)
|
||||
for C.gst_byte_reader_get_remaining(br) != C.guint(0) {
|
||||
var gint C.gdouble
|
||||
C.gst_byte_reader_get_float64_be(br, &gint)
|
||||
out = append(out, float64(gint))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// AsFloat64LESlice returns the contents of this map as a slice of 64-bit little-endian floats.
|
||||
func (m *MapInfo) AsFloat64LESlice() []float64 {
|
||||
br := C.newByteReader(m.Instance().data, C.guint(m.Instance().size))
|
||||
defer C.freeByteReader(br)
|
||||
out := make([]float64, 0)
|
||||
for C.gst_byte_reader_get_remaining(br) != C.guint(0) {
|
||||
var gint C.gdouble
|
||||
C.gst_byte_reader_get_float64_le(br, &gint)
|
||||
out = append(out, float64(gint))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user