From 0488976dd6e107d1d04e68c5610f6a4f7400a483 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?= Date: Sat, 10 Sep 2022 23:18:16 +0200 Subject: [PATCH] gstreamer add API. --- pkg/gst/gst.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- pkg/gst/gst.go | 48 +++++++++++++++++++++++++++++++++++++++++++++++- pkg/gst/gst.h | 4 ++++ 3 files changed, 99 insertions(+), 2 deletions(-) diff --git a/pkg/gst/gst.c b/pkg/gst/gst.c index 1bc9cab8..edcc4a29 100644 --- a/pkg/gst/gst.c +++ b/pkg/gst/gst.c @@ -47,7 +47,7 @@ static gboolean gstreamer_bus_call(GstBus *bus, GstMessage *msg, gpointer user_d gstreamer_pipeline_log(ctx, "debug", "got tags from element %s", GST_OBJECT_NAME(msg->src)); - + gst_tag_list_unref(tags); break; } @@ -163,3 +163,50 @@ void gstreamer_pipeline_push(GstPipelineCtx *ctx, void *buffer, int bufferLen) { gst_app_src_push_buffer(GST_APP_SRC(ctx->appsrc), buffer); } } + +gboolean gstreamer_pipeline_set_prop_int(GstPipelineCtx *ctx, char *binName, char *prop, gint value) { + GstElement *el = gst_bin_get_by_name(GST_BIN(ctx->pipeline), binName); + if (el == NULL) return FALSE; + + g_object_set(G_OBJECT(el), + prop, value, + NULL); + + gst_object_unref(el); + return TRUE; +} + +gboolean gstreamer_pipeline_set_caps_framerate(GstPipelineCtx *ctx, const gchar* binName, gint numerator, gint denominator) { + GstElement *el = gst_bin_get_by_name(GST_BIN(ctx->pipeline), binName); + if (el == NULL) return FALSE; + + GstCaps *caps = gst_caps_new_simple("video/x-raw", + "framerate", GST_TYPE_FRACTION, numerator, denominator, + NULL); + + g_object_set(G_OBJECT(el), + "caps", caps, + NULL); + + gst_caps_unref(caps); + gst_object_unref(el); + return TRUE; +} + +gboolean gstreamer_pipeline_set_caps_resolution(GstPipelineCtx *ctx, const gchar* binName, gint width, gint height) { + GstElement *el = gst_bin_get_by_name(GST_BIN(ctx->pipeline), binName); + if (el == NULL) return FALSE; + + GstCaps *caps = gst_caps_new_simple("video/x-raw", + "width", G_TYPE_INT, width, + "height", G_TYPE_INT, height, + NULL); + + g_object_set(G_OBJECT(el), + "caps", caps, + NULL); + + gst_caps_unref(caps); + gst_object_unref(el); + return TRUE; +} diff --git a/pkg/gst/gst.go b/pkg/gst/gst.go index 80498dcb..e98d80fd 100644 --- a/pkg/gst/gst.go +++ b/pkg/gst/gst.go @@ -21,6 +21,7 @@ import ( type Pipeline struct { id int + logger zerolog.Logger Src string Ctx *C.GstPipelineCtx Sample chan types.Sample @@ -56,7 +57,11 @@ func CreatePipeline(pipelineStr string) (*Pipeline, error) { } p := &Pipeline{ - id: int(id), + id: int(id), + logger: log.With(). + Str("module", "capture"). + Str("submodule", "gstreamer"). + Int("pipeline_id", int(id)).Logger(), Src: pipelineStr, Ctx: ctx, Sample: make(chan types.Sample), @@ -107,6 +112,47 @@ func (p *Pipeline) Push(buffer []byte) { C.gstreamer_pipeline_push(p.Ctx, bytes, C.int(len(buffer))) } +func (p *Pipeline) SetPropInt(binName string, prop string, value int) bool { + cBinName := C.CString(binName) + defer C.free(unsafe.Pointer(cBinName)) + + cProp := C.CString(prop) + defer C.free(unsafe.Pointer(cProp)) + + cValue := C.int(value) + + p.logger.Debug().Msgf("setting prop %s of %s to %d", prop, binName, value) + + ok := C.gstreamer_pipeline_set_prop_int(p.Ctx, cBinName, cProp, cValue) + return ok == C.TRUE +} + +func (p *Pipeline) SetCapsFramerate(binName string, numerator, denominator int) bool { + cBinName := C.CString(binName) + cNumerator := C.int(numerator) + cDenominator := C.int(denominator) + + defer C.free(unsafe.Pointer(cBinName)) + + p.logger.Debug().Msgf("setting caps framerate of %s to %d/%d", binName, numerator, denominator) + + ok := C.gstreamer_pipeline_set_caps_framerate(p.Ctx, cBinName, cNumerator, cDenominator) + return ok == C.TRUE +} + +func (p *Pipeline) SetCapsResolution(binName string, width, height int) bool { + cBinName := C.CString(binName) + cWidth := C.int(width) + cHeight := C.int(height) + + defer C.free(unsafe.Pointer(cBinName)) + + p.logger.Debug().Msgf("setting caps resolution of %s to %dx%d", binName, width, height) + + ok := C.gstreamer_pipeline_set_caps_resolution(p.Ctx, cBinName, cWidth, cHeight) + return ok == C.TRUE +} + // gst-inspect-1.0 func CheckPlugins(plugins []string) error { var plugin *C.GstPlugin diff --git a/pkg/gst/gst.h b/pkg/gst/gst.h index f2af6a2e..64598569 100644 --- a/pkg/gst/gst.h +++ b/pkg/gst/gst.h @@ -22,5 +22,9 @@ void gstreamer_pipeline_pause(GstPipelineCtx *ctx); void gstreamer_pipeline_destory(GstPipelineCtx *ctx); void gstreamer_pipeline_push(GstPipelineCtx *ctx, void *buffer, int bufferLen); +gboolean gstreamer_pipeline_set_prop_int(GstPipelineCtx *ctx, char *binName, char *prop, gint value); +gboolean gstreamer_pipeline_set_caps_framerate(GstPipelineCtx *ctx, const gchar* binName, gint numerator, gint denominator); +gboolean gstreamer_pipeline_set_caps_resolution(GstPipelineCtx *ctx, const gchar* binName, gint width, gint height); + void gstreamer_init(void); void gstreamer_loop(void);