gstreamer教程(6)——构建应用之Bin的使用
Bin:
bin 是一个容器元素。您可以将 element 元素添加到 bin 中。由于 bin 本身就是一个元素,因此 bin 可以像任何其他元素一样处理。因此,上一章 (element)的操作也适用于 bin。
什么是bin:
bin 允许您将一组链接起来的元素合并为一个逻辑元素。您不再处理每一个元素,而只处理一个 bin 元素。我们会发现这非常强大,当你想要构建一个复杂的 pipeline 管道时,你可以将 pipeline 管道分解成一个个小一点的块。
bin 还将管理其中包含的元素。它将对其内部的所有元素执行状态变更,以及收集和转发总线消息。
GStreamer 程序员可以使用一种特殊类型的 bin:
- pipeline:管理所包含元素的同步和总线消息的通用容器。顶层 bin 必须是一个 pipeline,因此每个应用程序至少需要一个 pipeline。
创建 bin:
bin 的创建方式与其他元素的创建方式相同,即使用 element factory 元素工厂。还有一些方便的函数可用(gst_bin_new()
和 gst_pipeline_new()
)。可以使用 gst_bin_add()
和 gst_bin_remove()
将元素添加到 bin 或从 bin 中删除元素 。请注意,您添加元素的 bin 将获得该元素的所有权。如果销毁 bin,则元素将随之取消引用。如果从 bin 中删除元素,它也将自动取消引用。
basic-example-8.c
#include <stdio.h> #include <gst/gst.h> int main (int argc, char *argv[]) { GstElement *bin, *pipeline, *source, *sink; /* init */ gst_init (&argc, &argv); /* create */ pipeline = gst_pipeline_new ("my_pipeline"); bin = gst_bin_new ("my_bin"); source = gst_element_factory_make ("fakesrc", "source"); sink = gst_element_factory_make ("fakesink", "sink"); /* First add the elements to the bin */ gst_bin_add_many (GST_BIN (bin), source, sink, NULL); /* add the bin to the pipeline */ gst_bin_add (GST_BIN (pipeline), bin); /* link the elements */ gst_element_link (source, sink); [..] }
该示例并不是完整代码,不能运行,主要用于理解pipeline和bin的创建,和向bin中添加element元素。
有多种函数可用于在 bin 中查找元素。最常用的是 gst_bin_get_by_name()
和 gst_bin_get_by_interface()
。您还可以使用函数 gst_bin_iterate_elements()
迭代查找 bin 包含的所有元素。有关详细信息,请参阅 GstBin
的 API 参考。
自定义 bin:
应用程序程序员可以创建包含元素的自定义 bin 来执行特定任务。例如,这允许您仅使用以下代码行编写 Ogg/Vorbis 解码器:
basic-example-9.c
#include <stdio.h> #include <gst/gst.h> int main (int argc, char *argv[]) { GstElement *player; /* init */ gst_init (&argc, &argv); /* create player */ player = gst_element_factory_make ("oggvorbisplayer", "player"); /* set the source audio file */ g_object_set (player, "location", "helloworld.ogg", NULL); /* start playback */ gst_element_set_state (GST_ELEMENT (player), GST_STATE_PLAYING); [..] }
(当然,这是一个愚蠢的例子,已经存在一个更强大、更通用的自定义 bin,例如:playbin 元素。)
可以使用插件或从应用程序创建自定义 bin。您可以在 Plugin Writer's Guide 中找到有关创建自定义 bin 的更多信息
此类自定义 bin 的示例是 gst-plugins-base 中的 playbin 和 uridecodebin 元素。
bin管理其子项的状态:
bin 管理其中包含的所有元素的状态。如果使用 gst_element_set_state()
将 bin(或管道,这是一种特殊的顶级 bin)设置为某个目标状态,它将确保其中包含的所有元素都将设置为此状态。这意味着通常只需要设置顶级 pipeline 管道的状态即可启动或关闭 pipeline 管道。
bin 将对其从 sink 元素到 source 元素的所有子元素执行状态更改,顺序也是先设置 sink,再设置 source。这可确保下游 element 元素在上游 element 元素被置于 PAUSED
或 PLAYING
状态时准备好接收数据。同样在关闭时,sink 元素将首先设置为 READY
或 NULL
,这会使上游 element 元素收到 FLUSHING
错误,会让 element 元素被设置为 READY
或 NULL
状态之前就停止流式处理线程了。
但请注意,如果将元素添加到已经在运行的 bin 或 pipeline 中,例如从 “pad-added” 信号回调中,element 元素状态不会自动与添加到的 bin 或 pipeline 的当前状态或目标状态保持一致。相反,当你向已经运行的pipeline中添加元素时,你需要使用 gst_element_set_state() 或
自行将其设置为所需的目标状态。gst_element_sync_state_with_parent()