gstreamer的category,简单来说就是用于区分log信息的类别,这里先从工作中的问题引入这个主题。
问题背景:为什么GST_CAT_DEFAULT为null?
增加代码在gst_v4l2_video_dec_register中通过GST_DEBUG输出:
+GST_DEBUG_CATEGORY_EXTERN (v4l2_debug);
+#define GST_CAT_DEFAULT v4l2_debug
void
gst_v4l2_video_dec_register (GstPlugin * plugin, const gchar * basename,
const gchar * device_path, GstCaps * sink_caps, GstCaps * src_caps)
@@ -1210,6 +1214,7 @@ gst_v4l2_video_dec_register (GstPlugin * plugin, const gchar * basename,
GType type, subtype;
gchar *type_name;
s = gst_caps_get_structure (sink_caps, i);
cdata = g_new0 (GstV4l2VideoDecCData, 1);
//...
+ GST_DEBUG ("type_name: %s, caps size: %d", type_name, gst_caps_get_size (sink_caps));
编译运行后,用GST_DEBUG会报错:assertion 'category != NULL' failed
sh-5.0# gst-inspect | grep mpeg4
(gst-plugin-scanner:13418): GStreamer-CRITICAL **: 22:10:59.056: gst_debug_log_valist: assertion 'category != NULL' failed
(gst-plugin-scanner:13427): GStreamer-CRITICAL **: 22:10:59.461: gst_debug_log_valist: assertion 'category != NULL' failed
从log推断GST_CAT_DEFAULT为null,就是GST_CAT_DEFAULT没有定义。所以这就要对GST_DEBUG_CATEGORY相关的代码展开理解。
GST_DEBUG_CATEGORY
从v4l2的代码中可以看到,GST_DEBUG_CATEGORY有三个定义:
gstreamer-1.0/gst/gstinfo.h
#define GST_DEBUG_CATEGORY(cat) GstDebugCategory *cat = NULL
#define GST_DEBUG_CATEGORY_EXTERN(cat) extern GstDebugCategory *cat
#define GST_DEBUG_CATEGORY_STATIC(cat) static GstDebugCategory *cat = NULL
找到这三个定义后,CATEGORY就很好理解了,GST_DEBUG_CATEGORY_STATIC定义了static类型初值为NULL的cat,GST_DEBUG_CATEGORY定义了非static的cat变量,初值为NULL,这个可以在其他文件里面被使用,通过GST_DEBUG_CATEGORY_EXTERN获得。
从v4l2中可以找到这三个出处:
subprojects/gst-plugins-good/sys/v4l2/gstv4l2object.c
GST_DEBUG_CATEGORY_EXTERN (v4l2_debug);
#define GST_CAT_DEFAULT v4l2_debug
subprojects/gst-plugins-good/sys/v4l2/gstv4l2videodec.c
GST_DEBUG_CATEGORY_STATIC (gst_v4l2_video_dec_debug);
#define GST_CAT_DEFAULT gst_v4l2_video_dec_debug
subprojects/gst-plugins-good/sys/v4l2/gstv4l2.c
GST_DEBUG_CATEGORY (v4l2_debug);
#define GST_CAT_DEFAULT v4l2_debug
所以也对应了两个初始化:
subprojects/gst-plugins-good/sys/v4l2/gstv4l2videodec.c
GST_DEBUG_CATEGORY_INIT (gst_v4l2_video_dec_debug, "v4l2videodec", 0, "V4L2 Video Decoder");
subprojects/gst-plugins-good/sys/v4l2/gstv4l2.c
GST_DEBUG_CATEGORY_INIT (v4l2_debug, "v4l2", 0, "V4L2 API calls");
所以要在其他地方使用GST_DEBUG,可以通过GST_DEBUG_CATEGORY_EXTERN引用已有的CATEGORY定义,也可以自己定义一个新的,关键的一点就是要对新定义使用GST_DEBUG_CATEGORY_INIT进行初始化。
+GST_DEBUG_CATEGORY_EXTERN (v4l2_debug);
+#define GST_CAT_DEFAULT v4l2_debug
插件中的实例
这样的例子在任意一个插件的代码里面都可以看到,比如wavpars插件里面:
在G_DEFINE_TYPE_WITH_CODE
的代码里面直接使用DEBUG_INIT
初始化debug category wavparse_debug
:
GST_DEBUG_CATEGORY_STATIC (wavparse_debug);
#define GST_CAT_DEFAULT (wavparse_debug)
G_DEFINE_TYPE_WITH_CODE (GstWavParse, gst_wavparse, GST_TYPE_ELEMENT,
DEBUG_INIT);
// GST_DEBUG_CATEGORY_INIT
#define DEBUG_INIT \
GST_DEBUG_CATEGORY_INIT (wavparse_debug, "wavparse", 0, "WAV parser");
比如videodiff插件里面:
GST_DEBUG_CATEGORY_STATIC
先定义一个static类型的gst_video_diff_debug_category
,GST_DEBUG_CATEGORY_INIT
初始化。
static没有什么特别之处,就是指定这个category的定义是在当前的文件域内。
GST_DEBUG_CATEGORY_STATIC (gst_video_diff_debug_category);
#define GST_CAT_DEFAULT gst_video_diff_debug_category
// GST_DEBUG_CATEGORY_INIT
G_DEFINE_TYPE_WITH_CODE (GstVideoDiff, gst_video_diff, GST_TYPE_VIDEO_FILTER,
GST_DEBUG_CATEGORY_INIT (gst_video_diff_debug_category, "videodiff", 0,
"debug category for videodiff element"));