【问题标题】:Gstreamer example sinkGstreamer 示例接收器
【发布时间】:2022-04-14 06:59:02
【问题描述】:

gstreamer 中是否有用于视频接收器的模板,就像插件元素一样?

我有一个非常简单的想法:一个初始化函数、渲染(显示)函数和 deinit 函数。而已。

【问题讨论】:

    标签: templates gstreamer sink


    【解决方案1】:

    最好的“模板”是可用的源代码。从 -base 或 -good 获取一个简单的接收器,并将其用作起点。这也是了解 GStreamer 的好方法,了解编写良好的元素的行为方式。您想要的基类可能是 gstbasesink,因为 有 gstbaseaudiosink 这样的东西,但(还没有)gstbasevideosink。

    【讨论】:

      【解决方案2】:

      我还寻找了一个基于 gstbasesink 的接收器“模板”,但没有找到。我按照上面的建议从我称之为 vpphlsvideosink 的 fakesink 元素创建了一个,尽管它不是专门的视频接收器(还)。它除了发送一个用于渲染的 'r' 字符和一个用于事件的 'e' 字符到 std cout 之外什么都不做。这些是文件:

      1. gstvpphlsvideosink.cpp
      #ifdef HAVE_CONFIG_H
      #include "config.h"
      #endif
      
      #include "vpphlsvideosink.h"
      
      static gboolean plugin_init (GstPlugin * plugin)
      {
        return gst_element_register(plugin, "vpphlsvideosink", GST_RANK_NONE, GST_TYPE_VPPHLSVIDEOSINK);
      }//end plugin_init.
      
      // GST_PLUGIN_DEFINE needs PACKAGE to be defined.
      
      #ifndef PACKAGE
      #define PACKAGE "vpphlsvideosink"
      #endif
      
      #ifndef VERSION
      #define VERSION "1.0.0.0"
      #endif
      
      #ifndef GST_PACKAGE_NAME
      #define GST_PACKAGE_NAME "GStreamer"
      #endif
      
      #ifndef GST_PACKAGE_ORIGIN
      #define GST_PACKAGE_ORIGIN "http://somewhere.net/"
      #endif
      
      GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
                         GST_VERSION_MINOR,
                         vpphlsvideosink,
                         "HLS Video Sink Plugin",
                         plugin_init, 
                           VERSION, 
                           "LGPL", 
                           GST_PACKAGE_NAME, 
                           GST_PACKAGE_ORIGIN);
      
      
      1. vpphlsvideosink.h
      #pragma once
      
      #include <gst/gst.h>
      #include <gst/base/gstbasesink.h>
      
      G_BEGIN_DECLS
      
      // Definition of structure storing data for this element.
      typedef struct _Gstvpphlsvideosink
      {
        GstBaseSink element;
        gboolean    silent;
      } Gstvpphlsvideosink;
      
      // Standard definition defining a class for this element.
      typedef struct _GstvpphlsvideosinkClass
      {
        GstBaseSinkClass parent_class;
      } GstvpphlsvideosinkClass;
      
      // Standard macros for defining types for this element.
      #define GST_TYPE_VPPHLSVIDEOSINK (gst_vpphlsvideosink_get_type())
      #define GST_VPPHLSVIDEOSINK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VPPHLSVIDEOSINK,Gstvpphlsvideosink))
      #define GST_VPPHLSVIDEOSINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VPPHLSVIDEOSINK,GstvpphlsvideosinkClass))
      #define GST_IS_VPPHLSVIDEOSINK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VPPHLSVIDEOSINK))
      #define GST_IS_VPPHLSVIDEOSINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VPPHLSVIDEOSINK))
      
      GType gst_vpphlsvideosink_get_type(void);
      
      G_END_DECLS
      
      
      1. vpphlsvideosink.cpp
      #ifdef HAVE_CONFIG_H
      #  include <config.h>
      #endif
      
      #include "vpphlsvideosink.h"
      #include <iostream>
      
      using namespace std;
      
      GST_DEBUG_CATEGORY_STATIC (gst_vpphlsvideosink_debug);
      #define GST_CAT_DEFAULT gst_vpphlsvideosink_debug
      
      #define DEFAULT_SYNC              true
      
      #define DEFAULT_SILENT            false
      
      // Filter signals and args
      enum
      {
        /* FILL ME */
        LAST_SIGNAL
      };
      
      enum
      {
        PROP_0,
        PROP_SILENT
      };
      
      // The capabilities of the inputs and outputs.
      static GstStaticPadTemplate sinkpadtemplate = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_CAPS ("ANY"));
      
      #define gst_vpphlsvideosink_parent_class parent_class
      
      G_DEFINE_TYPE(Gstvpphlsvideosink, gst_vpphlsvideosink, GST_TYPE_BASE_SINK);
      
      static void gst_vpphlsvideosink_set_property (GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec);
      static void gst_vpphlsvideosink_get_property (GObject* object, guint prop_id, GValue* value, GParamSpec* pspec);
      static void gst_vpphlsvideosink_finalize(GObject* obj);
      
      static GstStateChangeReturn gst_vpphlsvideosink_change_state(GstElement* element,  GstStateChange transition);
      
      static GstFlowReturn  gst_vpphlsvideosink_render(GstBaseSink* parent, GstBuffer* buffer);
      static GstFlowReturn  gst_vpphlsvideosink_preroll(GstBaseSink* parent, GstBuffer* buffer);
      static gboolean       gst_vpphlsvideosink_event(GstBaseSink* parent, GstEvent* event);
      static gboolean       gst_vpphlsvideosink_query(GstBaseSink* parent, GstQuery* query);
      
      // Use this when there is at least one signal enum defined
      //static guint          gst_vpphlsvideosink_signals[LAST_SIGNAL] = { 0 };
      
      // ------------- GObject virtual methods ------------------------------------------------------------------------------
      
      // Initialize the vpphlsvideosink class
      static void gst_vpphlsvideosink_class_init(GstvpphlsvideosinkClass* klass)
      {
        GObjectClass*     gobject_class     = G_OBJECT_CLASS(klass);
        GstElementClass*  gstelement_class  = GST_ELEMENT_CLASS(klass);
        GstBaseSinkClass* gstbasesink_class = GST_BASE_SINK_CLASS(klass);
      
        gobject_class->set_property = gst_vpphlsvideosink_set_property;
        gobject_class->get_property = gst_vpphlsvideosink_get_property;
        gobject_class->finalize     = gst_vpphlsvideosink_finalize;
      
        g_object_class_install_property (gobject_class, PROP_SILENT,
                                         g_param_spec_boolean ("silent", "Silent", "Produce verbose output?",
                                         DEFAULT_SILENT, 
                                         (GParamFlags)(G_PARAM_READWRITE | GST_PARAM_MUTABLE_PLAYING | G_PARAM_STATIC_STRINGS)));
      
        gst_element_class_set_static_metadata(gstelement_class,
          "A VPP HLS Video Sink",
          "Sink/VPPHLSVIDEOSINK",
          "Writes video buffers to an externally defined queue",
          "Keith L Ferguson <<user@hostname.org>>");
      
        // The one sink pad template
        gst_element_class_add_static_pad_template(gstelement_class, &sinkpadtemplate);
      
        // Set override methods
        gstbasesink_class->render   = GST_DEBUG_FUNCPTR(gst_vpphlsvideosink_render);
        gstbasesink_class->preroll  = GST_DEBUG_FUNCPTR(gst_vpphlsvideosink_preroll);
        gstbasesink_class->event    = GST_DEBUG_FUNCPTR(gst_vpphlsvideosink_event);
        gstbasesink_class->query    = GST_DEBUG_FUNCPTR(gst_vpphlsvideosink_query);
      
      }//end gst_vpphlsvideosink_class_init.
      
      // Initialise the new element.
      static void gst_vpphlsvideosink_init (Gstvpphlsvideosink* vsink)
      {
        // On this sink class
        vsink->silent = DEFAULT_SILENT;
      
        // On the base class
        gst_base_sink_set_sync(GST_BASE_SINK(vsink), DEFAULT_SYNC);
      
      }//end gst_vpphlsvideosink_init.
      
      static void gst_vpphlsvideosink_finalize(GObject* obj)
      {
        G_OBJECT_CLASS(parent_class)->finalize(obj);
      }//end gst_vpphlsvideosink_finalize.
      
      static void gst_vpphlsvideosink_set_property (GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec)
      {
        Gstvpphlsvideosink* vsink = GST_VPPHLSVIDEOSINK (object);
      
        switch (prop_id) 
        {
          case PROP_SILENT:
            vsink->silent = g_value_get_boolean (value);
            break;
          default:
            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
            break;
        }//end switch prop_id...
      }//end gst_vpphlsvideosink_set_property.
      
      static void gst_vpphlsvideosink_get_property (GObject* object, guint prop_id, GValue* value, GParamSpec* pspec)
      {
        Gstvpphlsvideosink* vsink = GST_VPPHLSVIDEOSINK (object);
      
        switch (prop_id) 
        {
          case PROP_SILENT:
            g_value_set_boolean (value, vsink->silent);
            break;
          default:
            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
            break;
        }//end switch prop_id...
      }//end gst_vpphlsvideosink_get_property.
      
      // -------------- GstBaseSink virtual methods ---------------------------------------------------------------
      
      static GstFlowReturn gst_vpphlsvideosink_render(GstBaseSink* parent, GstBuffer* buffer)
      {
        Gstvpphlsvideosink* vsink = GST_VPPHLSVIDEOSINK(parent);
      
        if (!vsink->silent)
          cout << "r";
      
        return GST_FLOW_OK;
      }//end gst_vpphlsvideosink_render.
      
      static GstFlowReturn gst_vpphlsvideosink_preroll(GstBaseSink* parent, GstBuffer* buffer)
      {
        Gstvpphlsvideosink* vsink = GST_VPPHLSVIDEOSINK(parent);
      
        if (!vsink->silent)
          cout << "p";
      
        return GST_FLOW_OK;
      }//end gst_vpphlsvideosink_preroll.
      
      static gboolean gst_vpphlsvideosink_event(GstBaseSink* parent, GstEvent* event)
      {
        Gstvpphlsvideosink* vsink = GST_VPPHLSVIDEOSINK(parent);
      
        if (!vsink->silent)
          cout << "e";
      
        return GST_BASE_SINK_CLASS(parent_class)->event(parent, event);
      }//end gst_vpphlsvideosink_event.
      
      static gboolean gst_vpphlsvideosink_query(GstBaseSink* parent, GstQuery* query)
      {
        gboolean ret;
      
        switch (GST_QUERY_TYPE(query)) 
        {
          case GST_QUERY_SEEKING: 
          {
            // Seeking is not supported
            GstFormat fmt;
            gst_query_parse_seeking(query, &fmt, NULL, NULL, NULL);
            gst_query_set_seeking(query, fmt, FALSE, 0, -1);
            ret = TRUE;
            break;
          }
          default:
            ret = GST_BASE_SINK_CLASS(parent_class)->query(parent, query);
            break;
        }//end switch query...
      
        return ret;
      }//end gst_vpphlsvideosink_query.
      
      static GstStateChangeReturn gst_vpphlsvideosink_change_state(GstElement* element, GstStateChange transition)
      {
        GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
        Gstvpphlsvideosink* vsink = GST_VPPHLSVIDEOSINK(element);
      
        ret = GST_ELEMENT_CLASS(parent_class)->change_state(element, transition);
      }//end gst_vpphlsvideosink_change_state.
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-03-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-11
        相关资源
        最近更新 更多