mirror of
https://github.com/go-gst/go-gst.git
synced 2025-10-05 16:06:55 +08:00
implement GstMeta, organize C code, add github action for linting
This commit is contained in:
46
.github/workflows/tests.yml
vendored
Normal file
46
.github/workflows/tests.yml
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
name: Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
|
||||
setup:
|
||||
name: Tests
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
|
||||
- name: Set up Go 1.15
|
||||
uses: actions/setup-go@v1
|
||||
with:
|
||||
go-version: 1.15
|
||||
id: go
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- uses: actions/cache@v1
|
||||
with:
|
||||
path: ~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-go-
|
||||
|
||||
- name: Get dependencies
|
||||
run: |
|
||||
go mod download
|
||||
|
||||
- name: Install gstreamer/pulse dependencies
|
||||
run: |
|
||||
sudo apt-get update && sudo DEBIAN_FRONTEND=noninteractive apt-get install -y libgstreamer1.0-0 libgstreamer1.0-dev libgstreamer-plugins-base1.0-0 pkg-config build-essential
|
||||
|
||||
- name: Lint all packages
|
||||
run: |
|
||||
CGO_ENABLED=1 make lint
|
||||
|
||||
# - name: Run all unit tests
|
||||
# run: |
|
||||
# CGO_ENABLED=1 make test
|
@@ -4,10 +4,8 @@ Go bindings for the gstreamer C library
|
||||
|
||||
[](https://pkg.go.dev/github.com/tinyzimmer/go-gst)
|
||||
[](https://godoc.org/github.com/tinyzimmer/go-gst)
|
||||
[](https://goreportcard.com/report/github.com/tinyzimmer/go-gst)
|
||||
|
||||
This package was originally written to aid the audio support in [`kvdi`](https://github.com/tinyzimmer/kvdi).
|
||||
But it made sense to turn it into an independent, consumable package. The intention now is to progressively implement the entire API.
|
||||
[](https://goreportcard.com/report/github.com/tinyzimmer/go-gst)
|
||||

|
||||
|
||||
See the go.dev reference for documentation and examples.
|
||||
|
||||
|
@@ -1,14 +0,0 @@
|
||||
#include <gst/app/gstappsink.h>
|
||||
#include <gst/app/gstappsrc.h>
|
||||
|
||||
GstAppSink *
|
||||
toGstAppSink(void *p)
|
||||
{
|
||||
return (GST_APP_SINK(p));
|
||||
}
|
||||
|
||||
GstAppSrc *
|
||||
toGstAppSrc(void *p)
|
||||
{
|
||||
return (GST_APP_SRC(p));
|
||||
}
|
@@ -1,5 +1,5 @@
|
||||
#include <gst/app/gstappsink.h>
|
||||
#include <gst/app/gstappsrc.h>
|
||||
|
||||
GstAppSink * toGstAppSink (void *p);
|
||||
GstAppSrc * toGstAppSrc (void *p);
|
||||
inline GstAppSink * toGstAppSink (void *p) { return (GST_APP_SINK(p)); }
|
||||
inline GstAppSrc * toGstAppSrc (void *p) { return (GST_APP_SRC(p)); }
|
||||
|
@@ -1,7 +1,8 @@
|
||||
package gst
|
||||
|
||||
// #include <gst/gst.h>
|
||||
// #include "gst.go.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
58
gst/cgo_exports.go
Normal file
58
gst/cgo_exports.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package gst
|
||||
|
||||
// CGO exports have to be defined in a separate file from where they are used or else
|
||||
// there will be double linkage issues.
|
||||
|
||||
// #include <gst/gst.h>
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
gopointer "github.com/mattn/go-pointer"
|
||||
)
|
||||
|
||||
//export structForEachCb
|
||||
func structForEachCb(fieldID C.GQuark, val *C.GValue, chPtr C.gpointer) C.gboolean {
|
||||
ptr := gopointer.Restore(unsafe.Pointer(chPtr))
|
||||
resCh := ptr.(chan interface{})
|
||||
fieldName := C.GoString(C.g_quark_to_string(fieldID))
|
||||
|
||||
var resValue interface{}
|
||||
|
||||
gVal := glib.ValueFromNative(unsafe.Pointer(val))
|
||||
if resValue, _ = gVal.GoValue(); resValue == nil {
|
||||
// serialize the value if we can't do anything else with it
|
||||
serialized := C.gst_value_serialize(val)
|
||||
defer C.free(unsafe.Pointer(serialized))
|
||||
resValue = C.GoString(serialized)
|
||||
}
|
||||
|
||||
resCh <- fieldName
|
||||
resCh <- resValue
|
||||
return gboolean(true)
|
||||
}
|
||||
|
||||
//export goBusFunc
|
||||
func goBusFunc(bus *C.GstBus, cMsg *C.GstMessage, userData C.gpointer) C.gboolean {
|
||||
// wrap the message
|
||||
msg := wrapMessage(cMsg)
|
||||
|
||||
// retrieve the ptr to the function
|
||||
ptr := unsafe.Pointer(userData)
|
||||
funcIface := gopointer.Restore(ptr)
|
||||
busFunc, ok := funcIface.(BusWatchFunc)
|
||||
if !ok {
|
||||
gopointer.Unref(ptr)
|
||||
return gboolean(false)
|
||||
}
|
||||
|
||||
// run the call back
|
||||
if cont := busFunc(msg); !cont {
|
||||
gopointer.Unref(ptr)
|
||||
return gboolean(false)
|
||||
}
|
||||
|
||||
return gboolean(true)
|
||||
}
|
301
gst/gst.go.c
301
gst/gst.go.c
@@ -1,301 +0,0 @@
|
||||
#include <gst/gst.h>
|
||||
#include "gst.go.h"
|
||||
|
||||
/*
|
||||
Utilitits
|
||||
*/
|
||||
|
||||
gboolean isParamSpecTypeCaps (GParamSpec * p)
|
||||
{
|
||||
return p->value_type == GST_TYPE_CAPS;
|
||||
}
|
||||
|
||||
gboolean isParamSpecEnum (GParamSpec * p)
|
||||
{
|
||||
return G_IS_PARAM_SPEC_ENUM(p);
|
||||
}
|
||||
|
||||
gboolean isParamSpecFlags (GParamSpec * p)
|
||||
{
|
||||
return G_IS_PARAM_SPEC_FLAGS(p);
|
||||
}
|
||||
|
||||
gboolean isParamSpecObject (GParamSpec * p)
|
||||
{
|
||||
return G_IS_PARAM_SPEC_OBJECT(p);
|
||||
}
|
||||
|
||||
gboolean isParamSpecBoxed (GParamSpec * p)
|
||||
{
|
||||
return G_IS_PARAM_SPEC_BOXED(p);
|
||||
}
|
||||
|
||||
gboolean isParamSpecPointer (GParamSpec * p)
|
||||
{
|
||||
return G_IS_PARAM_SPEC_POINTER(p);
|
||||
}
|
||||
|
||||
gboolean isParamSpecFraction (GParamSpec * p)
|
||||
{
|
||||
return GST_IS_PARAM_SPEC_FRACTION(p);
|
||||
}
|
||||
|
||||
gboolean isParamSpecGstArray (GParamSpec * p)
|
||||
{
|
||||
return p->value_type == GST_TYPE_ARRAY;
|
||||
}
|
||||
|
||||
GEnumValue * getEnumValues (GParamSpec * p, guint * size)
|
||||
{
|
||||
GEnumValue * values;
|
||||
values = G_ENUM_CLASS (g_type_class_ref (p->value_type))->values;
|
||||
guint i = 0;
|
||||
while (values[i].value_name) {
|
||||
++i;
|
||||
}
|
||||
*size = i;
|
||||
return values;
|
||||
}
|
||||
|
||||
GFlagsValue * getParamSpecFlags (GParamSpec * p, guint * size)
|
||||
{
|
||||
GParamSpecFlags *pflags = G_PARAM_SPEC_FLAGS (p);
|
||||
GFlagsValue *vals = pflags->flags_class->values;
|
||||
guint i = 0;
|
||||
while (vals[i].value_name) {
|
||||
++i;
|
||||
}
|
||||
*size = i;
|
||||
return vals;
|
||||
}
|
||||
|
||||
gboolean cgoBusFunc (GstBus * bus, GstMessage * msg, gpointer user_data)
|
||||
{
|
||||
return goBusFunc(bus, msg, user_data);
|
||||
}
|
||||
|
||||
gboolean structureForEach (GQuark field_id, GValue * value, gpointer user_data)
|
||||
{
|
||||
return structForEachCb(field_id, value, user_data);
|
||||
}
|
||||
|
||||
GObjectClass * getGObjectClass (void * p) {
|
||||
return G_OBJECT_GET_CLASS (p);
|
||||
}
|
||||
|
||||
int sizeOfGCharArray (gchar ** arr) {
|
||||
int i;
|
||||
for (i = 0 ; 1 ; i = i + 1) {
|
||||
if (arr[i] == NULL) { return i; };
|
||||
}
|
||||
}
|
||||
|
||||
gboolean gstObjectFlagIsSet (GstObject * obj, GstElementFlags flags)
|
||||
{
|
||||
return GST_OBJECT_FLAG_IS_SET (obj, flags);
|
||||
}
|
||||
|
||||
gboolean gstElementIsURIHandler (GstElement * elem)
|
||||
{
|
||||
return GST_IS_URI_HANDLER (elem);
|
||||
}
|
||||
|
||||
/*
|
||||
Number functions
|
||||
*/
|
||||
|
||||
GParamSpecUInt * getParamUInt (GParamSpec * param)
|
||||
{
|
||||
return G_PARAM_SPEC_UINT (param);
|
||||
}
|
||||
|
||||
GParamSpecInt * getParamInt (GParamSpec * param)
|
||||
{
|
||||
return G_PARAM_SPEC_INT (param);
|
||||
}
|
||||
|
||||
GParamSpecUInt64 * getParamUInt64 (GParamSpec * param)
|
||||
{
|
||||
return G_PARAM_SPEC_UINT64 (param);
|
||||
}
|
||||
|
||||
GParamSpecInt64 * getParamInt64 (GParamSpec * param)
|
||||
{
|
||||
return G_PARAM_SPEC_INT64 (param);
|
||||
}
|
||||
|
||||
GParamSpecFloat * getParamFloat (GParamSpec * param)
|
||||
{
|
||||
return G_PARAM_SPEC_FLOAT (param);
|
||||
}
|
||||
|
||||
GParamSpecDouble * getParamDouble(GParamSpec * param)
|
||||
{
|
||||
return G_PARAM_SPEC_DOUBLE (param);
|
||||
}
|
||||
|
||||
/*
|
||||
Type Castings
|
||||
*/
|
||||
|
||||
GstAllocator *
|
||||
toGstAllocator(void *p)
|
||||
{
|
||||
return (GST_ALLOCATOR_CAST(p));
|
||||
}
|
||||
|
||||
GstUri *
|
||||
toGstURI(void *p)
|
||||
{
|
||||
return (GST_URI(p));
|
||||
}
|
||||
|
||||
GstURIHandler *
|
||||
toGstURIHandler(void *p)
|
||||
{
|
||||
return (GST_URI_HANDLER(p));
|
||||
}
|
||||
|
||||
GstRegistry *
|
||||
toGstRegistry(void *p)
|
||||
{
|
||||
return (GST_REGISTRY(p));
|
||||
}
|
||||
|
||||
GstPlugin *
|
||||
toGstPlugin(void *p)
|
||||
{
|
||||
return (GST_PLUGIN(p));
|
||||
}
|
||||
|
||||
GstPluginFeature *
|
||||
toGstPluginFeature(void *p)
|
||||
{
|
||||
return (GST_PLUGIN_FEATURE(p));
|
||||
}
|
||||
|
||||
GstObject *
|
||||
toGstObject(void *p)
|
||||
{
|
||||
return (GST_OBJECT(p));
|
||||
}
|
||||
|
||||
GstElementFactory *
|
||||
toGstElementFactory(void *p)
|
||||
{
|
||||
return (GST_ELEMENT_FACTORY(p));
|
||||
}
|
||||
|
||||
GstElement *
|
||||
toGstElement(void *p)
|
||||
{
|
||||
return (GST_ELEMENT(p));
|
||||
}
|
||||
|
||||
GstBin *
|
||||
toGstBin(void *p)
|
||||
{
|
||||
return (GST_BIN(p));
|
||||
}
|
||||
|
||||
GstBus *
|
||||
toGstBus(void *p)
|
||||
{
|
||||
return (GST_BUS(p));
|
||||
}
|
||||
|
||||
GstMessage *
|
||||
toGstMessage(void *p)
|
||||
{
|
||||
return (GST_MESSAGE(p));
|
||||
}
|
||||
|
||||
GstPipeline *
|
||||
toGstPipeline(void *p)
|
||||
{
|
||||
return (GST_PIPELINE(p));
|
||||
}
|
||||
|
||||
GstPad *
|
||||
toGstPad(void *p)
|
||||
{
|
||||
return (GST_PAD(p));
|
||||
}
|
||||
|
||||
GstPadTemplate *
|
||||
toGstPadTemplate(void *p)
|
||||
{
|
||||
return (GST_PAD_TEMPLATE(p));
|
||||
}
|
||||
|
||||
GstStructure *
|
||||
toGstStructure(void *p)
|
||||
{
|
||||
return (GST_STRUCTURE(p));
|
||||
}
|
||||
|
||||
GstClock *
|
||||
toGstClock(void *p)
|
||||
{
|
||||
return (GST_CLOCK(p));
|
||||
}
|
||||
|
||||
GstMiniObject *
|
||||
toGstMiniObject(void *p)
|
||||
{
|
||||
return (GST_MINI_OBJECT(p));
|
||||
}
|
||||
|
||||
GstCaps *
|
||||
toGstCaps(void *p)
|
||||
{
|
||||
return (GST_CAPS(p));
|
||||
}
|
||||
|
||||
GstCapsFeatures *
|
||||
toGstCapsFeatures(void *p)
|
||||
{
|
||||
return (GST_CAPS_FEATURES(p));
|
||||
}
|
||||
|
||||
GstBuffer *
|
||||
toGstBuffer(void *p)
|
||||
{
|
||||
return (GST_BUFFER(p));
|
||||
}
|
||||
|
||||
GstBufferPool *
|
||||
toGstBufferPool(void *p)
|
||||
{
|
||||
return (GST_BUFFER_POOL(p));
|
||||
}
|
||||
|
||||
GstSample *
|
||||
toGstSample(void *p)
|
||||
{
|
||||
return (GST_SAMPLE(p));
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
GstMemory *
|
||||
toGstMemory(void *p)
|
||||
{
|
||||
return (GST_MEMORY_CAST(p));
|
||||
}
|
155
gst/gst.go.h
155
gst/gst.go.h
@@ -1,69 +1,98 @@
|
||||
#ifndef __GST_GO_H__
|
||||
#define __GST_GO_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
extern gboolean structForEachCb (GQuark field_id, GValue * value, gpointer user_data);
|
||||
extern gboolean goBusFunc (GstBus * bus, GstMessage * msg, gpointer user_data);
|
||||
|
||||
gboolean structureForEach (GQuark field_id, GValue * value, gpointer user_data);
|
||||
gboolean cgoBusFunc (GstBus * bus, GstMessage * msg, gpointer user_data);
|
||||
|
||||
GEnumValue * getEnumValues (GParamSpec * p, guint * size);
|
||||
GFlagsValue * getParamSpecFlags (GParamSpec * p, guint * size);
|
||||
|
||||
int sizeOfGCharArray (gchar ** arr);
|
||||
|
||||
gboolean isParamSpecTypeCaps (GParamSpec * p);
|
||||
gboolean isParamSpecEnum (GParamSpec * p);
|
||||
gboolean isParamSpecFlags (GParamSpec * p);
|
||||
gboolean isParamSpecObject (GParamSpec * p);
|
||||
gboolean isParamSpecBoxed (GParamSpec * p);
|
||||
gboolean isParamSpecPointer (GParamSpec * p);
|
||||
gboolean isParamSpecFraction (GParamSpec * p);
|
||||
gboolean isParamSpecGstArray (GParamSpec * p);
|
||||
|
||||
GObjectClass * getGObjectClass (void * p);
|
||||
|
||||
gboolean gstObjectFlagIsSet (GstObject * obj, GstElementFlags flags);
|
||||
gboolean gstElementIsURIHandler (GstElement * elem);
|
||||
|
||||
/*
|
||||
Number functions
|
||||
*/
|
||||
|
||||
GParamSpecUInt * getParamUInt (GParamSpec * param);
|
||||
GParamSpecInt * getParamInt (GParamSpec * param);
|
||||
GParamSpecUInt64 * getParamUInt64 (GParamSpec * param);
|
||||
GParamSpecInt64 * getParamInt64 (GParamSpec * param);
|
||||
GParamSpecFloat * getParamFloat (GParamSpec * param);
|
||||
GParamSpecDouble * getParamDouble (GParamSpec * param);
|
||||
|
||||
/*
|
||||
Type Castings
|
||||
*/
|
||||
|
||||
GstAllocator * toGstAllocator (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);
|
||||
GstMemory * toGstMemory (void *p);
|
||||
inline GstAllocator * toGstAllocator (void *p) { return (GST_ALLOCATOR_CAST(p)); }
|
||||
inline GstBin * toGstBin (void *p) { return (GST_BIN(p)); }
|
||||
inline GstBufferPool * toGstBufferPool (void *p) { return (GST_BUFFER_POOL(p)); }
|
||||
inline GstBuffer * toGstBuffer (void *p) { return (GST_BUFFER(p)); }
|
||||
inline GstBus * toGstBus (void *p) { return (GST_BUS(p)); }
|
||||
inline GstCapsFeatures * toGstCapsFeatures (void *p) { return (GST_CAPS_FEATURES(p)); }
|
||||
inline GstCaps * toGstCaps (void *p) { return (GST_CAPS(p)); }
|
||||
inline GstClock * toGstClock (void *p) { return (GST_CLOCK(p)); }
|
||||
inline GstDevice * toGstDevice (void *p) { return (GST_DEVICE_CAST(p)); }
|
||||
inline GstElementFactory * toGstElementFactory (void *p) { return (GST_ELEMENT_FACTORY(p)); }
|
||||
inline GstElement * toGstElement (void *p) { return (GST_ELEMENT(p)); }
|
||||
inline GstMemory * toGstMemory (void *p) { return (GST_MEMORY_CAST(p)); }
|
||||
inline GstMessage * toGstMessage (void *p) { return (GST_MESSAGE(p)); }
|
||||
inline GstMeta * toGstMeta (void *p) { return (GST_META_CAST(p)); }
|
||||
inline GstMiniObject * toGstMiniObject (void *p) { return (GST_MINI_OBJECT(p)); }
|
||||
inline GstObject * toGstObject (void *p) { return (GST_OBJECT(p)); }
|
||||
inline GstPadTemplate * toGstPadTemplate (void *p) { return (GST_PAD_TEMPLATE(p)); }
|
||||
inline GstPad * toGstPad (void *p) { return (GST_PAD(p)); }
|
||||
inline GstPipeline * toGstPipeline (void *p) { return (GST_PIPELINE(p)); }
|
||||
inline GstPluginFeature * toGstPluginFeature (void *p) { return (GST_PLUGIN_FEATURE(p)); }
|
||||
inline GstPlugin * toGstPlugin (void *p) { return (GST_PLUGIN(p)); }
|
||||
inline GstRegistry * toGstRegistry (void *p) { return (GST_REGISTRY(p)); }
|
||||
inline GstSample * toGstSample (void *p) { return (GST_SAMPLE(p)); }
|
||||
inline GstStreamCollection * toGstStreamCollection (void *p) { return (GST_STREAM_COLLECTION_CAST(p)); }
|
||||
inline GstStream * toGstStream (void *p) { return (GST_STREAM_CAST(p)); }
|
||||
inline GstStructure * toGstStructure (void *p) { return (GST_STRUCTURE(p)); }
|
||||
inline GstURIHandler * toGstURIHandler (void *p) { return (GST_URI_HANDLER(p)); }
|
||||
inline GstUri * toGstURI (void *p) { return (GST_URI(p)); }
|
||||
|
||||
/* Object Utilities */
|
||||
|
||||
inline GObjectClass * getGObjectClass (void * p) { return (G_OBJECT_GET_CLASS(p)); }
|
||||
inline gboolean gstElementIsURIHandler (GstElement * elem) { return (GST_IS_URI_HANDLER(elem)); }
|
||||
inline gboolean gstObjectFlagIsSet (GstObject * obj, GstElementFlags flags) { return (GST_OBJECT_FLAG_IS_SET(obj, flags)); }
|
||||
|
||||
/*
|
||||
ParamSpec Utilities
|
||||
*/
|
||||
|
||||
inline gboolean isParamSpecTypeCaps (GParamSpec * p) { return p->value_type == GST_TYPE_CAPS; }
|
||||
inline gboolean isParamSpecEnum (GParamSpec * p) { return (G_IS_PARAM_SPEC_ENUM(p)); }
|
||||
inline gboolean isParamSpecFlags (GParamSpec * p) { return (G_IS_PARAM_SPEC_FLAGS(p)); }
|
||||
inline gboolean isParamSpecObject (GParamSpec * p) { return (G_IS_PARAM_SPEC_OBJECT(p)); }
|
||||
inline gboolean isParamSpecBoxed (GParamSpec * p) { return (G_IS_PARAM_SPEC_BOXED(p)); }
|
||||
inline gboolean isParamSpecPointer (GParamSpec * p) { return (G_IS_PARAM_SPEC_POINTER(p)); }
|
||||
inline gboolean isParamSpecFraction (GParamSpec * p) { return (GST_IS_PARAM_SPEC_FRACTION(p)); }
|
||||
inline gboolean isParamSpecGstArray (GParamSpec * p) { return p->value_type == GST_TYPE_ARRAY; }
|
||||
|
||||
inline GParamSpecUInt * getParamUInt (GParamSpec * param) { return (G_PARAM_SPEC_UINT(param)); }
|
||||
inline GParamSpecInt * getParamInt (GParamSpec * param) { return (G_PARAM_SPEC_INT(param)); }
|
||||
inline GParamSpecUInt64 * getParamUInt64 (GParamSpec * param) { return (G_PARAM_SPEC_UINT64(param)); }
|
||||
inline GParamSpecInt64 * getParamInt64 (GParamSpec * param) { return (G_PARAM_SPEC_INT64(param)); }
|
||||
inline GParamSpecFloat * getParamFloat (GParamSpec * param) { return (G_PARAM_SPEC_FLOAT(param)); }
|
||||
inline GParamSpecDouble * getParamDouble (GParamSpec * param) { return (G_PARAM_SPEC_DOUBLE(param)); }
|
||||
|
||||
inline GEnumValue * getEnumValues (GParamSpec * p, guint * size)
|
||||
{
|
||||
GEnumValue * values;
|
||||
values = G_ENUM_CLASS (g_type_class_ref (p->value_type))->values;
|
||||
guint i = 0;
|
||||
while (values[i].value_name) {
|
||||
++i;
|
||||
}
|
||||
*size = i;
|
||||
return values;
|
||||
}
|
||||
|
||||
inline GFlagsValue * getParamSpecFlags (GParamSpec * p, guint * size)
|
||||
{
|
||||
GParamSpecFlags * pflags = G_PARAM_SPEC_FLAGS (p);
|
||||
GFlagsValue * vals = pflags->flags_class->values;
|
||||
guint i = 0;
|
||||
while (vals[i].value_name) {
|
||||
++i;
|
||||
}
|
||||
*size = i;
|
||||
return vals;
|
||||
}
|
||||
|
||||
/* Misc */
|
||||
inline int sizeOfGCharArray (gchar ** arr)
|
||||
{
|
||||
int i;
|
||||
for (i = 0 ; 1 ; i = i + 1) {
|
||||
if (arr[i] == NULL) { return i; };
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -2,6 +2,7 @@ package gst
|
||||
|
||||
// #include "gst.go.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
|
@@ -2,6 +2,7 @@ package gst
|
||||
|
||||
// #include "gst.go.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
|
@@ -2,6 +2,7 @@ package gst
|
||||
|
||||
// #include "gst.go.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
@@ -2,12 +2,15 @@ package gst
|
||||
|
||||
// #include "gst.go.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
)
|
||||
|
||||
// Buffer is a go representation of a GstBuffer.
|
||||
@@ -100,3 +103,10 @@ func (b *Buffer) Map() *MapInfo {
|
||||
C.gst_buffer_unmap(b.Instance(), (*C.GstMapInfo)(unsafe.Pointer(&mapInfo)))
|
||||
})
|
||||
}
|
||||
|
||||
// GetMeta retrieves the metadata on the buffer for the given api. If none exists
|
||||
// then nil is returned.
|
||||
func (b *Buffer) GetMeta(api glib.Type) *Meta {
|
||||
meta := C.gst_buffer_get_meta(b.Instance(), C.GType(api))
|
||||
return wrapMeta(meta)
|
||||
}
|
||||
|
@@ -1,6 +1,15 @@
|
||||
package gst
|
||||
|
||||
// #include "gst.go.h"
|
||||
/*
|
||||
#include "gst.go.h"
|
||||
|
||||
extern gboolean goBusFunc (GstBus * bus, GstMessage * msg, gpointer user_data);
|
||||
|
||||
gboolean cgoBusFunc (GstBus * bus, GstMessage * msg, gpointer user_data)
|
||||
{
|
||||
return goBusFunc(bus, msg, user_data);
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
@@ -100,29 +109,6 @@ func (b *Bus) BlockPopMessage() *Message {
|
||||
// the message unless addtional references are placed on it during processing.
|
||||
type BusWatchFunc func(msg *Message) bool
|
||||
|
||||
//export goBusFunc
|
||||
func goBusFunc(bus *C.GstBus, cMsg *C.GstMessage, userData C.gpointer) C.gboolean {
|
||||
// wrap the message
|
||||
msg := wrapMessage(cMsg)
|
||||
|
||||
// retrieve the ptr to the function
|
||||
ptr := unsafe.Pointer(userData)
|
||||
funcIface := gopointer.Restore(ptr)
|
||||
busFunc, ok := funcIface.(BusWatchFunc)
|
||||
if !ok {
|
||||
gopointer.Unref(ptr)
|
||||
return gboolean(false)
|
||||
}
|
||||
|
||||
// run the call back
|
||||
if cont := busFunc(msg); !cont {
|
||||
gopointer.Unref(ptr)
|
||||
return gboolean(false)
|
||||
}
|
||||
|
||||
return gboolean(true)
|
||||
}
|
||||
|
||||
// AddWatch adds a watch to the default MainContext for messages emitted on this bus.
|
||||
// This function is used to receive asynchronous messages in the main loop. There can
|
||||
// only be a single bus watch per bus, you must remove it before you can set a new one.
|
||||
|
@@ -2,6 +2,7 @@ package gst
|
||||
|
||||
// #include "gst.go.h"
|
||||
import "C"
|
||||
|
||||
import "time"
|
||||
|
||||
// Clock is a go wrapper around a GstClock.
|
||||
|
@@ -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
|
||||
@@ -413,3 +414,37 @@ const (
|
||||
MemoryFlagNotMappable MemoryFlags = C.GST_MEMORY_FLAG_NOT_MAPPABLE // (256) – the memory can't be mapped via gst_memory_map without any preconditions. (Since: 1.2)
|
||||
MemoryFlagLast MemoryFlags = 1048576 // first flag that can be used for custom purposes
|
||||
)
|
||||
|
||||
// URIType casts C GstURIType to a go type
|
||||
type URIType int
|
||||
|
||||
// Type cast URI types
|
||||
const (
|
||||
URIUnknown URIType = C.GST_URI_UNKNOWN // (0) – The URI direction is unknown
|
||||
URISink URIType = C.GST_URI_SINK // (1) – The URI is a consumer.
|
||||
URISource URIType = C.GST_URI_SRC // (2) - The URI is a producer.
|
||||
)
|
||||
|
||||
func (u URIType) String() string {
|
||||
switch u {
|
||||
case URIUnknown:
|
||||
return "Unknown"
|
||||
case URISink:
|
||||
return "Sink"
|
||||
case URISource:
|
||||
return "Source"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// MetaFlags casts C GstMetaFlags to a go type.
|
||||
type MetaFlags int
|
||||
|
||||
// Type casts of GstMetaFlags
|
||||
const (
|
||||
MetaFlagNone MetaFlags = C.GST_META_FLAG_NONE // (0) – no flags
|
||||
MetaFlagReadOnly MetaFlags = C.GST_META_FLAG_READONLY // (1) – metadata should not be modified
|
||||
MetaFlagPooled MetaFlags = C.GST_META_FLAG_POOLED // (2) – metadata is managed by a bufferpool
|
||||
MetaFlagLocked MetaFlags = C.GST_META_FLAG_LOCKED // (4) – metadata should not be removed
|
||||
MetaFlagLast MetaFlags = C.GST_META_FLAG_LAST // (65536) – additional flags can be added starting from this flag.
|
||||
)
|
||||
|
@@ -2,6 +2,7 @@ package gst
|
||||
|
||||
// #include "gst.go.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
@@ -54,23 +54,23 @@ func Find(name string) *ElementFactory {
|
||||
func (e *ElementFactory) Instance() *C.GstElementFactory { return C.toGstElementFactory(e.Unsafe()) }
|
||||
|
||||
// CanSinkAllCaps checks if the factory can sink all possible capabilities.
|
||||
func (e *ElementFactory) CanSinkAllCaps(caps *C.GstCaps) bool {
|
||||
return gobool(C.gst_element_factory_can_sink_all_caps((*C.GstElementFactory)(e.Instance()), (*C.GstCaps)(caps)))
|
||||
func (e *ElementFactory) CanSinkAllCaps(caps *Caps) bool {
|
||||
return gobool(C.gst_element_factory_can_sink_all_caps((*C.GstElementFactory)(e.Instance()), (*C.GstCaps)(caps.Instance())))
|
||||
}
|
||||
|
||||
// CanSinkAnyCaps checks if the factory can sink any possible capability.
|
||||
func (e *ElementFactory) CanSinkAnyCaps(caps *C.GstCaps) bool {
|
||||
return gobool(C.gst_element_factory_can_sink_any_caps((*C.GstElementFactory)(e.Instance()), (*C.GstCaps)(caps)))
|
||||
func (e *ElementFactory) CanSinkAnyCaps(caps *Caps) bool {
|
||||
return gobool(C.gst_element_factory_can_sink_any_caps((*C.GstElementFactory)(e.Instance()), (*C.GstCaps)(caps.Instance())))
|
||||
}
|
||||
|
||||
// CanSourceAllCaps checks if the factory can src all possible capabilities.
|
||||
func (e *ElementFactory) CanSourceAllCaps(caps *C.GstCaps) bool {
|
||||
return gobool(C.gst_element_factory_can_src_all_caps((*C.GstElementFactory)(e.Instance()), (*C.GstCaps)(caps)))
|
||||
func (e *ElementFactory) CanSourceAllCaps(caps *Caps) bool {
|
||||
return gobool(C.gst_element_factory_can_src_all_caps((*C.GstElementFactory)(e.Instance()), (*C.GstCaps)(caps.Instance())))
|
||||
}
|
||||
|
||||
// CanSourceAnyCaps checks if the factory can src any possible capability.
|
||||
func (e *ElementFactory) CanSourceAnyCaps(caps *C.GstCaps) bool {
|
||||
return gobool(C.gst_element_factory_can_src_any_caps((*C.GstElementFactory)(e.Instance()), (*C.GstCaps)(caps)))
|
||||
func (e *ElementFactory) CanSourceAnyCaps(caps *Caps) bool {
|
||||
return gobool(C.gst_element_factory_can_src_any_caps((*C.GstElementFactory)(e.Instance()), (*C.GstCaps)(caps.Instance())))
|
||||
}
|
||||
|
||||
// GetMetadata gets the metadata on this factory with key.
|
||||
|
@@ -2,6 +2,7 @@ package gst
|
||||
|
||||
// #include "gst.go.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"unsafe"
|
||||
|
40
gst/gst_meta.go
Normal file
40
gst/gst_meta.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package gst
|
||||
|
||||
// #include "gst.go.h"
|
||||
import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
)
|
||||
|
||||
// Meta is a go representation of GstMeta.
|
||||
type Meta struct {
|
||||
ptr *C.GstMeta
|
||||
}
|
||||
|
||||
// Instance returns the underlying GstMeta instance.
|
||||
func (m *Meta) Instance() *C.GstMeta { return C.toGstMeta(unsafe.Pointer(m.ptr)) }
|
||||
|
||||
// Flags returns the flags on this Meta instance.
|
||||
func (m *Meta) Flags() MetaFlags { return MetaFlags(m.Instance().flags) }
|
||||
|
||||
// Info returns the extra info with this metadata.
|
||||
func (m *Meta) Info() *MetaInfo { return wrapMetaInfo(m.Instance().info) }
|
||||
|
||||
// MetaInfo is a go representation of GstMetaInfo
|
||||
type MetaInfo struct {
|
||||
ptr *C.GstMetaInfo
|
||||
}
|
||||
|
||||
// Instance returns the underlying GstMetaInfo instance.
|
||||
func (m *MetaInfo) Instance() *C.GstMetaInfo { return m.ptr }
|
||||
|
||||
// API returns the tag identifying the metadata structure and api.
|
||||
func (m *MetaInfo) API() glib.Type { return glib.Type(m.Instance().api) }
|
||||
|
||||
// Type returns the type identifying the implementor of the api.
|
||||
func (m *MetaInfo) Type() glib.Type { return glib.Type(m.Instance()._type) }
|
||||
|
||||
// Size returns the size of the metadata.
|
||||
func (m *MetaInfo) Size() int64 { return int64(m.Instance().size) }
|
@@ -2,6 +2,7 @@ package gst
|
||||
|
||||
// #include "gst.go.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
|
@@ -2,6 +2,7 @@ package gst
|
||||
|
||||
// #include "gst.go.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
|
@@ -2,6 +2,7 @@ package gst
|
||||
|
||||
// #include "gst.go.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"unsafe"
|
||||
|
@@ -2,6 +2,7 @@ package gst
|
||||
|
||||
// #include "gst.go.h"
|
||||
import "C"
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// Sample is a go wrapper around a GstSample object.
|
||||
|
@@ -2,6 +2,7 @@ package gst
|
||||
|
||||
// #include "gst.go.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
|
@@ -2,6 +2,7 @@ package gst
|
||||
|
||||
// #include "gst.go.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"unsafe"
|
||||
|
@@ -1,6 +1,15 @@
|
||||
package gst
|
||||
|
||||
// #include "gst.go.h"
|
||||
/*
|
||||
#include "gst.go.h"
|
||||
|
||||
extern gboolean structForEachCb (GQuark field_id, GValue * value, gpointer user_data);
|
||||
|
||||
gboolean structureForEach (GQuark field_id, GValue * value, gpointer user_data)
|
||||
{
|
||||
return structForEachCb(field_id, value, user_data);
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
@@ -101,27 +110,6 @@ func (s *Structure) RemoveValue(key string) {
|
||||
C.gst_structure_remove_field(s.Instance(), cKey)
|
||||
}
|
||||
|
||||
//export structForEachCb
|
||||
func structForEachCb(fieldID C.GQuark, val *C.GValue, chPtr C.gpointer) C.gboolean {
|
||||
ptr := gopointer.Restore(unsafe.Pointer(chPtr))
|
||||
resCh := ptr.(chan interface{})
|
||||
fieldName := C.GoString(C.g_quark_to_string(fieldID))
|
||||
|
||||
var resValue interface{}
|
||||
|
||||
gVal := glib.ValueFromNative(unsafe.Pointer(val))
|
||||
if resValue, _ = gVal.GoValue(); resValue == nil {
|
||||
// serialize the value if we can't do anything else with it
|
||||
serialized := C.gst_value_serialize(val)
|
||||
defer C.free(unsafe.Pointer(serialized))
|
||||
resValue = C.GoString(serialized)
|
||||
}
|
||||
|
||||
resCh <- fieldName
|
||||
resCh <- resValue
|
||||
return gboolean(true)
|
||||
}
|
||||
|
||||
// Values returns a map of all the values inside this structure. If values cannot be
|
||||
// converted to an equivalent go type, they are serialized to a string.
|
||||
func (s *Structure) Values() map[string]interface{} {
|
||||
|
@@ -2,6 +2,7 @@ package gst
|
||||
|
||||
// #include "gst.go.h"
|
||||
import "C"
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// TagList is a go wrapper around a GstTagList. For now, until the rest of the methods are
|
||||
|
@@ -1,26 +0,0 @@
|
||||
package gst
|
||||
|
||||
// #include "gst.go.h"
|
||||
import "C"
|
||||
|
||||
// URIType casts C GstURIType to a go type
|
||||
type URIType C.GstURIType
|
||||
|
||||
// Type cast URI types
|
||||
const (
|
||||
URIUnknown URIType = C.GST_URI_UNKNOWN // (0) – The URI direction is unknown
|
||||
URISink = C.GST_URI_SINK // (1) – The URI is a consumer.
|
||||
URISource = C.GST_URI_SRC // (2) - The URI is a producer.
|
||||
)
|
||||
|
||||
func (u URIType) String() string {
|
||||
switch u {
|
||||
case URIUnknown:
|
||||
return "Unknown"
|
||||
case URISink:
|
||||
return "Sink"
|
||||
case URISource:
|
||||
return "Source"
|
||||
}
|
||||
return ""
|
||||
}
|
@@ -2,6 +2,7 @@ package gst
|
||||
|
||||
// #include "gst.go.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"time"
|
||||
"unsafe"
|
||||
@@ -103,6 +104,31 @@ func init() {
|
||||
|
||||
// Object wrappers
|
||||
|
||||
func wrapAllocator(obj *glib.Object) *Allocator { return &Allocator{wrapObject(obj)} }
|
||||
func wrapAtomicQueue(queue *C.GstAtomicQueue) *AtomicQueue { return &AtomicQueue{ptr: queue} }
|
||||
func wrapBin(obj *glib.Object) *Bin { return &Bin{wrapElement(obj)} }
|
||||
func wrapBuffer(buf *C.GstBuffer) *Buffer { return &Buffer{ptr: buf} }
|
||||
func wrapBus(obj *glib.Object) *Bus { return &Bus{Object: wrapObject(obj)} }
|
||||
func wrapClock(obj *glib.Object) *Clock { return &Clock{wrapObject(obj)} }
|
||||
func wrapDevice(obj *glib.Object) *Device { return &Device{wrapObject(obj)} }
|
||||
func wrapElement(obj *glib.Object) *Element { return &Element{wrapObject(obj)} }
|
||||
func wrapGhostPad(obj *glib.Object) *GhostPad { return &GhostPad{wrapPad(obj)} }
|
||||
func wrapMainContext(ctx *C.GMainContext) *MainContext { return &MainContext{ptr: ctx} }
|
||||
func wrapMainLoop(loop *C.GMainLoop) *MainLoop { return &MainLoop{ptr: loop} }
|
||||
func wrapMemory(mem *C.GstMemory) *Memory { return &Memory{ptr: mem} }
|
||||
func wrapMessage(msg *C.GstMessage) *Message { return &Message{msg: msg} }
|
||||
func wrapMeta(meta *C.GstMeta) *Meta { return &Meta{ptr: meta} }
|
||||
func wrapMetaInfo(info *C.GstMetaInfo) *MetaInfo { return &MetaInfo{ptr: info} }
|
||||
func wrapPad(obj *glib.Object) *Pad { return &Pad{wrapObject(obj)} }
|
||||
func wrapPadTemplate(obj *glib.Object) *PadTemplate { return &PadTemplate{wrapObject(obj)} }
|
||||
func wrapPipeline(obj *glib.Object) *Pipeline { return &Pipeline{Bin: wrapBin(obj)} }
|
||||
func wrapPluginFeature(obj *glib.Object) *PluginFeature { return &PluginFeature{wrapObject(obj)} }
|
||||
func wrapPlugin(obj *glib.Object) *Plugin { return &Plugin{wrapObject(obj)} }
|
||||
func wrapRegistry(obj *glib.Object) *Registry { return &Registry{wrapObject(obj)} }
|
||||
func wrapSample(sample *C.GstSample) *Sample { return &Sample{sample: sample} }
|
||||
func wrapStream(obj *glib.Object) *Stream { return &Stream{wrapObject(obj)} }
|
||||
func wrapTagList(tagList *C.GstTagList) *TagList { return &TagList{ptr: tagList} }
|
||||
|
||||
func wrapObject(obj *glib.Object) *Object {
|
||||
return &Object{InitiallyUnowned: &glib.InitiallyUnowned{Object: obj}}
|
||||
}
|
||||
@@ -111,29 +137,6 @@ func wrapElementFactory(obj *glib.Object) *ElementFactory {
|
||||
return &ElementFactory{wrapPluginFeature(obj)}
|
||||
}
|
||||
|
||||
func wrapAtomicQueue(queue *C.GstAtomicQueue) *AtomicQueue { return &AtomicQueue{ptr: queue} }
|
||||
func wrapDevice(obj *glib.Object) *Device { return &Device{wrapObject(obj)} }
|
||||
func wrapPluginFeature(obj *glib.Object) *PluginFeature { return &PluginFeature{wrapObject(obj)} }
|
||||
func wrapPipeline(obj *glib.Object) *Pipeline { return &Pipeline{Bin: wrapBin(obj)} }
|
||||
func wrapElement(obj *glib.Object) *Element { return &Element{wrapObject(obj)} }
|
||||
func wrapBin(obj *glib.Object) *Bin { return &Bin{wrapElement(obj)} }
|
||||
func wrapClock(obj *glib.Object) *Clock { return &Clock{wrapObject(obj)} }
|
||||
func wrapBus(obj *glib.Object) *Bus { return &Bus{Object: wrapObject(obj)} }
|
||||
func wrapMessage(msg *C.GstMessage) *Message { return &Message{msg: msg} }
|
||||
func wrapTagList(tagList *C.GstTagList) *TagList { return &TagList{ptr: tagList} }
|
||||
func wrapPad(obj *glib.Object) *Pad { return &Pad{wrapObject(obj)} }
|
||||
func wrapPadTemplate(obj *glib.Object) *PadTemplate { return &PadTemplate{wrapObject(obj)} }
|
||||
func wrapGhostPad(obj *glib.Object) *GhostPad { return &GhostPad{wrapPad(obj)} }
|
||||
func wrapPlugin(obj *glib.Object) *Plugin { return &Plugin{wrapObject(obj)} }
|
||||
func wrapRegistry(obj *glib.Object) *Registry { return &Registry{wrapObject(obj)} }
|
||||
func wrapSample(sample *C.GstSample) *Sample { return &Sample{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 wrapAllocator(obj *glib.Object) *Allocator { return &Allocator{wrapObject(obj)} }
|
||||
func wrapMemory(mem *C.GstMemory) *Memory { return &Memory{ptr: mem} }
|
||||
|
||||
func wrapStreamCollection(obj *glib.Object) *StreamCollection {
|
||||
return &StreamCollection{wrapObject(obj)}
|
||||
}
|
||||
|
@@ -3,5 +3,6 @@ package gst
|
||||
/*
|
||||
#cgo pkg-config: gstreamer-1.0
|
||||
#cgo CFLAGS: -Wno-deprecated-declarations -g -Wall
|
||||
#cgo LDFLAGS: -lm
|
||||
*/
|
||||
import "C"
|
||||
|
Reference in New Issue
Block a user