gstreamer之G_DEFINE_TYPE

G_DEFINE_TYPE分解

G_DEFINE_TYPE是一个用于类型实现的宏,它声明了一个类的初始化函数,一个实例的初始化函数(关于这些的信息请参考gtype.h)和一个名为type_name##_parent_class的静态变量,指向父类。此外,它还定义了一个type_name##_get_type()函数。

G_DEFINE_TYPE是由_G_DEFINE_TYPE_EXTENDED_BEGIN,_G_DEFINE_TYPE_EXTENDED_BEGIN_PRE,_G_DEFINE_TYPE_EXTENDED_BEGIN_REGISTER三个组成,这三个又可以展开为好多个宏,到最后会产生好多代码,其中就有type_name##_get_type(),比如curlhttpsink插件,就是gst_curl_http_sink_get_type(),下面就以curlhttpsink带入分析:

G_DEFINE_TYPE (GstCurlHttpSink, gst_curl_http_sink, GST_TYPE_CURL_TLS_SINK);
// TN:  GstCurlHttpSink                 // The name of the new type,展开后是作为函数的参数TypeName
// t_n: gst_curl_http_sink              // The name of the new type, in lowercase, with words,展开后是函数名的一部分type_name
// T_P: GST_TYPE_CURL_TLS_SINK          // The #GType of the parent type. 展开后指向get_type函数

G_DEFINE_TYPE的宏展开次序:

G_DEFINE_TYPE
	G_DEFINE_TYPE_EXTENDED
		_G_DEFINE_TYPE_EXTENDED_BEGIN
			_G_DEFINE_TYPE_EXTENDED_BEGIN_PRE
			_G_DEFINE_TYPE_EXTENDED_BEGIN_REGISTER
		_G_DEFINE_TYPE_EXTENDED_END

下面是每一个的定义:

G_DEFINE_TYPE:

// G_DEFINE_TYPE
#define G_DEFINE_TYPE(TN, t_n, T_P)			    G_DEFINE_TYPE_EXTENDED (TN, t_n, T_P, 0, {})

G_DEFINE_TYPE_EXTENDED:

#define G_DEFINE_TYPE_EXTENDED(TN, t_n, T_P, _f_, _C_)	 _G_DEFINE_TYPE_EXTENDED_BEGIN (TN, t_n, T_P, _f_) {_C_;} _G_DEFINE_TYPE_EXTENDED_END()

_G_DEFINE_TYPE_EXTENDED_BEGIN & _G_DEFINE_TYPE_EXTENDED_END:

//_G_DEFINE_TYPE_EXTENDED_BEGIN
#define _G_DEFINE_TYPE_EXTENDED_BEGIN(TypeName, type_name, TYPE_PARENT, flags) \
  _G_DEFINE_TYPE_EXTENDED_BEGIN_PRE(TypeName, type_name, TYPE_PARENT) \
  _G_DEFINE_TYPE_EXTENDED_BEGIN_REGISTER(TypeName, type_name, TYPE_PARENT, flags) \

//_G_DEFINE_TYPE_EXTENDED_END
#define _G_DEFINE_TYPE_EXTENDED_END()	\
        /* following custom code */	\
      }					\
      g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); \
    }					\
  return g_define_type_id__volatile;	\
} /* closes type_name##_get_type() */

_G_DEFINE_TYPE_EXTENDED_BEGIN_PRE:

// _G_DEFINE_TYPE_EXTENDED_BEGIN_PRE
#define _G_DEFINE_TYPE_EXTENDED_BEGIN_PRE(TypeName, type_name, TYPE_PARENT) \
\
static void     type_name##_init              (TypeName        *self); \
static void     type_name##_class_init        (TypeName##Class *klass); \
static gpointer type_name##_parent_class = NULL; \
static gint     TypeName##_private_offset; \
\
_G_DEFINE_TYPE_EXTENDED_CLASS_INIT(TypeName, type_name) \
\
G_GNUC_UNUSED \
static inline gpointer \
type_name##_get_instance_private (TypeName *self) \
{ \
  return (G_STRUCT_MEMBER_P (self, TypeName##_private_offset)); \
} \
\
GType \
type_name##_get_type (void) \
{ \
  static volatile gsize g_define_type_id__volatile = 0;
  /* Prelude goes here */

_G_DEFINE_TYPE_EXTENDED_BEGIN_REGISTER:

// _G_DEFINE_TYPE_EXTENDED_BEGIN_REGISTER
#define _G_DEFINE_TYPE_EXTENDED_BEGIN_REGISTER(TypeName, type_name, TYPE_PARENT, flags) \
  if (g_once_init_enter (&g_define_type_id__volatile))  \
    { \
      GType g_define_type_id = \
        g_type_register_static_simple (TYPE_PARENT, \
                                       g_intern_static_string (#TypeName), \
                                       sizeof (TypeName##Class), \
                                       (GClassInitFunc)(void (*)(void)) type_name##_class_intern_init, \
                                       sizeof (TypeName), \
                                       (GInstanceInitFunc)(void (*)(void)) type_name##_init, \
                                       (GTypeFlags) flags); \
      { /* custom code follows */

再把前面这些放在一块展开就是下面的代码段,可以用下面这curlhttpsink的字符串带入阅读:

  • TypeName:GstCurlHttpSink
  • type_name:gst_curl_http_sink
  • TYPE_PARENT:GST_TYPE_CURL_TLS_SINK
/ _G_DEFINE_TYPE_EXTENDED_BEGIN_PRE
static void     type_name##_init              (TypeName        *self); \
static void     type_name##_class_init        (TypeName##Class *klass); \
static gpointer type_name##_parent_class = NULL; \
static gint     TypeName##_private_offset; \
\
_G_DEFINE_TYPE_EXTENDED_CLASS_INIT(TypeName, type_name) \
\
G_GNUC_UNUSED \
static inline gpointer \
type_name##_get_instance_private (TypeName *self) \
{ \
  return (G_STRUCT_MEMBER_P (self, TypeName##_private_offset)); \
} \
\
GType \
type_name##_get_type (void) \
{ \
  static volatile gsize g_define_type_id__volatile = 0;
  /* Prelude goes here */

 / _G_DEFINE_TYPE_EXTENDED_BEGIN_REGISTER
  if (g_once_init_enter (&g_define_type_id__volatile))  \
    { \
      GType g_define_type_id = \
        g_type_register_static_simple (TYPE_PARENT, \
                                       g_intern_static_string (#TypeName), \
                                       sizeof (TypeName##Class), \
                                       (GClassInitFunc)(void (*)(void)) type_name##_class_intern_init, \
                                       sizeof (TypeName), \
                                       (GInstanceInitFunc)(void (*)(void)) type_name##_init, \
                                       (GTypeFlags) flags); \
      { /* custom code follows */
        // _C_; G_DEFINE_TYPE_EXTENDED的_C_参数展开
 
 / _G_DEFINE_TYPE_EXTENDED_END
        /* following custom code */	\
      }					\
      g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); \
    }					\
  return g_define_type_id__volatile;	\
} /* closes type_name##_get_type() */

G_DEFINE_TYPE_WITH_CODE分解

G_DEFINE_TYPE一样,G_DEFINE_TYPE_WITH_CODE实际上和G_DEFINE_TYPE基本上是一样的,G_DEFINE_TYPE_WITH_CODE比起G_DEFINE_TYPE多了参数_C__C_是其他的初始化代码,G_DEFINE_TYPE只有3个参数,不能有这部分。

从xvimagesink中可以看到实例:

/// G_DEFINE_TYPE_WITH_CODE
G_DEFINE_TYPE_WITH_CODE (GstXvImageSink, gst_xv_image_sink, GST_TYPE_VIDEO_SINK,
    G_IMPLEMENT_INTERFACE (GST_TYPE_NAVIGATION,
        gst_xv_image_sink_navigation_init);
    G_IMPLEMENT_INTERFACE (GST_TYPE_VIDEO_OVERLAY,
        gst_xv_image_sink_video_overlay_init);
    G_IMPLEMENT_INTERFACE (GST_TYPE_COLOR_BALANCE,
        gst_xv_image_sink_colorbalance_init));

G_DEFINE_TYPE_WITH_CODE vs G_DEFINE_TYPE

/// G_DEFINE_TYPE_WITH_CODE
#define G_DEFINE_TYPE_WITH_CODE(TN, t_n, T_P, _C_)	    _G_DEFINE_TYPE_EXTENDED_BEGIN (TN, t_n, T_P, 0) {_C_;} _G_DEFINE_TYPE_EXTENDED_END()

/// G_DEFINE_TYPE & G_DEFINE_TYPE_EXTENDED
#define G_DEFINE_TYPE(TN, t_n, T_P)			    G_DEFINE_TYPE_EXTENDED (TN, t_n, T_P, 0, {})
#define G_DEFINE_TYPE_EXTENDED(TN, t_n, T_P, _f_, _C_)	_G_DEFINE_TYPE_EXTENDED_BEGIN (TN, t_n, T_P, _f_) {_C_;} _G_DEFINE_TYPE_EXTENDED_END()

除了这个_C_参数之外,其他都是完全一样的,这里就不展开了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值