理解GStreamer源码基础

    gst是基于Gobject来开发的,Gobject提供 类,继承 对象注册 和gst信号机制的基础。GStreamer代码里面有充斥着Goject的代码,Gobject也是理解Gstreamer各个模块的基础。需要了解的是几个方面, 如何向GOject注册一个新类, 如何创建一个新类, 一个类如何继承另一类。

3.1了解如何向Goject注册类

以video_decoder类为例

#define GST_TYPE_VIDEO_DECODER \

  (gst_video_decoder_get_type())

其中gst_video_decoder_get_type:



GType

gst_video_decoder_get_type (void)

{

  static volatile gsize type = 0;



  if (g_once_init_enter (&type)) {

    GType _type;

    static const GTypeInfo info = {

      sizeof (GstVideoDecoderClass),

      NULL,

      NULL,

      (GClassInitFunc) gst_video_decoder_class_init,

      NULL,

      NULL,

      sizeof (GstVideoDecoder),

      0,

      (GInstanceInitFunc) gst_video_decoder_init,

    };



    _type = g_type_register_static (GST_TYPE_ELEMENT,

        "GstVideoDecoder", &info, G_TYPE_FLAG_ABSTRACT);

    g_once_init_leave (&type, _type);

  }

  return type;

}

可以看出向Gobject注册一个类 需要先定义GTypeInfo 类型,然后调用g_type_register_static 向GTYPE去注册。Goject也提供一个宏G_DEFINE_TYPE , 直接传入注册的名字,名字的小写 和 父类 就可以代替上面的代码完成注册如下:

G_DEFINE_TYPE (GstDecodebin3, gst_decodebin3, GST_TYPE_BIN);

注册了之后,在这个Goject系统里面就有了这个类,可以直接调用g_object_new来创建一个类。

3.2 理解类结构体和实例结构体

    在Goject中将类分成两个部分一个是实例结构体 一个类结构体。实例结构体就是每创建一个对象要给对象分配一个即成员变量,类结构就只有一个,类结构体一般定义的是能够被继承的函数即成员函数。

还是gstvideodecoder为例

 

typedef struct _GstVideoDecoder GstVideoDecoder;

typedef struct _GstVideoDecoderClass GstVideoDecoderClass;

定义了两个结构体

其中实例结构体_GstVideoDecoder 定义了一堆的变量

struct _GstVideoDecoder

{

  /*< private >*/

  GstElement     element;



  /*< protected >*/

  GstPad         *sinkpad;

  GstPad         *srcpad;



  /* protects all data processing, i.e. is locked

   * in the chain function, finish_frame and when

   * processing serialized events */

  GRecMutex stream_lock;



  /* MT-protected (with STREAM_LOCK) */

  GstSegment      input_segment;

  GstSegment      output_segment;



  GstVideoDecoderPrivate *priv;



  /*< private >*/

  void             *padding[GST_PADDING_LARGE];

};

 

而class里面就定义一堆的函数指针。

struct _GstVideoDecoderClass

{

  /*< private >*/

  GstElementClass element_class;



  /*< public >*/

  gboolean      (*open)           (GstVideoDecoder *decoder);



  gboolean      (*close)          (GstVideoDecoder *decoder);



  gboolean      (*start)          (GstVideoDecoder *decoder);



  gboolean      (*stop)           (GstVideoDecoder *decoder);



  GstFlowReturn (*parse)          (GstVideoDecoder *decoder,

                       GstVideoCodecFrame *frame,

                       GstAdapter *adapter,

                       gboolean at_eos);



  gboolean      (*set_format)     (GstVideoDecoder *decoder,

                       GstVideoCodecState * state);



  gboolean      (*reset)          (GstVideoDecoder *decoder,

                       gboolean hard);



  GstFlowReturn (*finish)         (GstVideoDecoder *decoder);



  GstFlowReturn (*handle_frame)   (GstVideoDecoder *decoder,

                       GstVideoCodecFrame *frame);



  gboolean      (*sink_event)     (GstVideoDecoder *decoder,

                       GstEvent *event);



  gboolean      (*src_event)      (GstVideoDecoder *decoder,

                       GstEvent *event);



  gboolean      (*negotiate)      (GstVideoDecoder *decoder);



  gboolean      (*decide_allocation)  (GstVideoDecoder *decoder, GstQuery *query);



  gboolean      (*propose_allocation) (GstVideoDecoder *decoder, GstQuery * query);



  gboolean      (*flush)              (GstVideoDecoder *decoder);



  gboolean      (*sink_query)     (GstVideoDecoder *decoder,

                       GstQuery *query);



  gboolean      (*src_query)      (GstVideoDecoder *decoder,

                       GstQuery *query);



  GstCaps*      (*getcaps)        (GstVideoDecoder *decoder,

                                   GstCaps *filter);



  GstFlowReturn (*drain)          (GstVideoDecoder *decoder);



  gboolean      (*transform_meta) (GstVideoDecoder *decoder,

                                   GstVideoCodecFrame *frame,

                                   GstMeta * meta);



  /*< private >*/

  void         *padding[GST_PADDING_LARGE-6];

}

    另外从上面的代码也可以看到子类继承父类的方式 就是在子类定义类和结构体中分别包含父类的类和结构体,从上面可以看到GstVideoDecoder继承自Gstelement。当新建一个类的对象时 会默认调用以下类结构体和实例结构体初始化函数,其中类结构只在第一次创建的时候调用,同样类结构体中做了一些初始化函数指针的操作,而实例结构体则是成员的赋值。

 

static void

gst_video_decoder_init (GstVideoDecoder * decoder, GstVideoDecoderClass * klass)

static void

gst_video_decoder_class_init (GstVideoDecoderClass * klass)

 

综上:

Goject 将类抽象成两个不同的结构体,并分别用不同的函数进行注册,另外还有调用GOject的宏向Gtype系统注册类

猜你喜欢

转载自blog.csdn.net/H2008066215019910120/article/details/112565218
今日推荐