多线程图形接口调用
单线程的GUI和多线程的GStreamer
问题:GUI
工具包通常只允许通过主线程(或应用程序线程)操作图形“小部件”,而GStreamer通常会生成多个线程来处理不同的任务。从回调中调用GTK+
函数通常会失败,因为回调执行在调用线程中,该线程不一定是主线程。
解决方案:通过在回调中向GStreamer总线发布消息(为每种消息类型注册一个回调函数)可以解决这个问题:这些消息将由主线程接收,然后相应地进行操作。
函数与知识点
gst_bus_add_signal_watch()
功能:将一个总线信号监视器(bus signal watch
)添加到默认的主上下文(main context
)中,并使用默认的优先级(G_PRIORITY_DEFAULT
)。也可以使用非默认的主上下文,通过使用g_main_context_push_thread_default
进行设置(在之前必须手动创建总线监视器源,并将其附加到所需的主上下文上)。调用此语句后,总线将针对总线上发布的每条消息发出"message
"信号。注意:可以多次调用该函数。清理时,调用者负责调用gst_bus_remove_signal_watch()
的次数与调用此函数的次数相同。gst_bus_remove_signal_watch()
功能:用于消除gst_bus_add_signal_watch()
对总线的引用。message::details
介绍:通过调用gst_bus_add_signal_watch(),我们指示总线在接收到消息时发出一个信号。该信号的名称为message::detail,其中detail是触发信号发出的消息。例如,当总线接收到EOS消息时,它会发出一个名称为message::eos的信号。guint g_timeout_add_seconds (guint interval, GSourceFunc function, gpointer data)
功能:用于注册回调函数,每次调用时,执行function
函数(循环调用)。参数:Interval
函数之间的时间间隔,以秒为单位;function
调用的函数;data
要传递给函数的数据,该参数可以为NULL
,数据由函数的调用者拥有。提示:Basic tutorial 5
使用此函数刷新GUI
界面。GdkWindow* gtk_widget_get_window(GtkWidget* widget)
功能:如果小部件已经实例化,返回小部件的窗口;否则返回NULL
。gboolean gdk_window_ensure_native (GdkWindow* window)
功能:如果窗口具有原生窗口,返回TRUE
;否则返回FALSE
。gst_video_overlay_set_window_handle (GstVideoOverlay * overlay, guintptr handle)
功能:这将调用视频覆盖层的set_window_handle
方法。您应该使用此方法告诉覆盖层将视频输出显示到特定窗口(例如X11上的XWindow)。将0作为句柄传递给覆盖层,将告诉覆盖层停止使用该窗口并创建一个内部窗口。void gtk_main_quit(void )
功能:让最内层的主循环返回,当它重新获得控制时。提示:最终将在main
函数中调用gtk_main_run()
来终止程序。在这里,当主窗口关闭时调用它,在停止管道之后(只是出于整洁的考虑)。void gtk_widget_get_allocation (GtkWidget* widget, GtkAllocation* allocation)
功能:返回实际分配给小部件的调整后的分配。但是,请注意,调整后的分配肯定完全包含在gtk_widget_size_allocate()
的分配内。参数:allocation
指向要复制的GtkAllocation
的指针。void g_signal_handler_block (GObject* instance, gulong handler_id)
功能:阻塞一个实例(GObject
)的处理器,这样在信号发出期间它就不会被调用,除非再次解除阻塞。说明:“阻塞”一个信号处理器意味着暂时停用它,一个信号处理器必须被解除阻塞的次数与之前被阻塞的次数相同,才能重新激活。void g_signal_handler_unblock (GObject* instance, gulong handler_id)
功能:撤销先前的g_signal_handler_block()
调用的效果(解除阻塞)。说明:1. 被阻塞的处理器在信号发送期间被跳过并不会被调用,解除阻塞(与之前被阻塞的次数相同)会恢复其“阻塞”状态,这样信号系统会识别该处理器,并在未来或当前正在进行的信号发射中调用它(由于信号发射期间处理器被调用的顺序是确定的,因此是否调用被解除阻塞的处理器取决于该信号发射已经进行到何种程度)。2.handler_id
必须是一个有效的、目前被阻塞的信号处理器ID
,连接到实例的一个信号上。gst_element_post_message()
功能:在元素的GstBus
上发布消息。说明:此函数接管消息的所有权;想在调用后访问消息,应该在调用之前添加一个额外的引用。GstMessage *gst_message_new_application(GstObject * src, GstStructure * structure)
功能:创建一个新的应用程序类型的消息(GStreamer永远不会创建这些消息;彩蛋)GstStructure *gst_structure_new_empty (const gchar * name)
功能:使用给定的名称创建一个新的空GstStructure
。提示:请参阅gst_structure_set_name
中关于名称参数的限制。 c l e a n u p cleanup cleanup:gst_structure_free()