GStreamer引用计数查看方法
GStreamer提供了GST_OBJECT_REFCOUNT_VALUE宏用于查询引用计数,其要求输入一个GstElement*类型的变量,并返回gint类型的该变量引用计数值。
注意,当输入变量未被分配或已释放(输入变量的引用计数降为0)时,该宏的行为未定义。
Pipeline释放前未设置状态为NULL时可能导致的内存泄露
当Pipeline释放前未设置状态为NULL时,其具有许多外部的引用计数,此时即使将其unref,也不会使得管道被释放,这将可能导致内存泄露。
使用如下代码进行测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| #include <gst/gst.h>
gboolean stop(gpointer data);
int main(int argc, char* argv[]) { gst_init(&argc, &argv);
GstElement* pipeline = gst_parse_launch("playbin uri=https://gstreamer.freedesktop.org/data/media/sintel_trailer-480p.webm", NULL); GMainLoop* main_loop = g_main_loop_new(NULL, FALSE);
g_timeout_add(5000, stop, main_loop);
g_print("pipeline ref on a: %d\n", GST_OBJECT_REFCOUNT_VALUE(pipeline));
gst_element_set_state(pipeline, GST_STATE_PLAYING); g_print("pipeline ref on b: %d\n", GST_OBJECT_REFCOUNT_VALUE(pipeline)); g_main_loop_run(main_loop); g_print("pipeline ref on c: %d\n", GST_OBJECT_REFCOUNT_VALUE(pipeline));
g_print("pipeline ref on d: %d\n", GST_OBJECT_REFCOUNT_VALUE(pipeline));
gst_object_unref(pipeline); g_print("pipeline ref on e: %d\n", GST_OBJECT_REFCOUNT_VALUE(pipeline)); g_main_loop_unref(main_loop); return 0; }
gboolean stop(gpointer data) { GMainLoop* loop = (GMainLoop*)data; g_print("STOP\n"); g_main_loop_quit(loop);
return FALSE; }
|
运行后,控制台打印结果为:
1 2 3 4 5 6
| pipeline ref on a: 1 pipeline ref on b: 3 STOP pipeline ref on c: 7 pipeline ref on d: 7 pipeline ref on e: 6
|
当正确设置状态为NULL时可避免该问题:
1 2 3 4 5
| pipeline ref on a: 1 pipeline ref on b: 3 STOP pipeline ref on c: 7 pipeline ref on d: 1
|
运行后,控制台打印结果为:
1 2 3 4 5
| pipeline ref on a: 1 pipeline ref on b: 3 STOP pipeline ref on c: 7 pipeline ref on d: 1
|