Basic tutorial 2: GStreamer concepts
Basic concepts.
目标
上一篇教程展示了如何自动地都剑一条pipeline。现在我们将手动构建一条pipeline:初始化每一个element并将它们连接起来。在本教程中,将学习:
什么是GStreamer element以及如何创建它。
如何连击两个elements。
如何自定义一个element的行为(属性)。
如何舰艇bus的错误情形并且从GStreamer messages中提取信息。
Manual Hello World
basic-tutorial-2.c
注:编译和运行在上一篇教程已经展示过了,后续不在赘述。
工作流
element是GStreamer的基本构成单位,它们处理从source element(数据生产者)通过filter element流向sink element(数据消费者)的数据。
创建element
上述代码展示了如何使用gst_element_factory_make()
新建一个element,函数的第一个参数是要创建的element名,即插件名。第二个参数是给这个特殊实例起的名称,在同一条pipeline中,必须是唯一的名称。这个名称可以用于后续检索它,假如你传递NULL
作为实例名,GStreamer也会自动为它初始化一个唯一的名称。
创建pipeline
在这篇教程中,我们创建了两个元素:videotestsrc
和autovideosink
,中间没有filter element,所以整个pipeline看起来就如下图:
videotestsrc
是一个按照制定pattern
生成测试视频source element(它将生产数据),这个插件在测试和教程中很好用,但通常并不会出现在真实的应用中。
autovideosink
是一个在窗口中播放它接收到的图像的sink element(它将消费数据),GStreamer包含有很多视频sink element,具体取决于操作系统,它们能够处理不同的图像格式,autovideosink
将自动选择其中一个并实例话化,所以用户不需要担心平台兼容性问题。
gst_pipeline_new()
可以创建一个pipeline,GStreamer中的所有元素在使用之前通常必须包含在一条pipeline 中,pipeline将负责一些时钟和消息功能。
一条pipeline也是一个特殊的bin,被用来包含其他elements,因此GstBin的所有方法也能用于GstPipeline。在上述代码中,我们调用gst_bin_add_many()
来将elements添加到pipeline中(注意对pipeline的GST_BIN()
映射),这个函数接受一个要被添加到pipeline中的element列表,因为不确定列表长度所以需要以NULL
结尾。添加单个element可以使用get_bin_add()
。
虽然elements已经被加入到一条pipeline中,但这时候这些elements仍然处于一个无须的状态,在运行之前,我们需要使用gst_element_link()
将它们彼此之间按顺序连接起来。gst_element_link()
的第一个参数必须是source elemnt,第二个参数必须是sink element,并且由于只能连接同一条pipeline中的elements,必须在连接之前将所有的elements加入pipeline。
设置element properties
GStreamer的实现依赖于GObject,所有的GStreamer elements都是特殊的GObject,用于提供property
特性。
大多数GStreamer elements都具有被称作属性的定制性质,使用g_obeject_set()
修改writable propeties
的属性值可以改变element的行为,使用g_obejct_get()
请求readable properties
的属性值可以获得element的内部状态。
g_object_set()
可以接受一个以NULL
结束的属性名-属性值键值对列表,所以可以一次性设置多个属性。
在本教程中我们将videotestsrc
的pattern
属性设置为0
,pattern
属性控制者videotestsec
的输出视频类型,用户可以尝试设置为不同的值并查看效果。
属性名和可能的属性值可以查看element的说明文档或者使用gst-inspect-1.0
工具查看。
Error监听
向上篇教程一样,这时已经成功构建和设置完pipeline了,调用gst_element_set_state()
改变pipeline的状态,但是这次将检查状态改变的返回值,假如状态修改失败,将返回一个error值并进行相关退出处理。
在上一篇教程中,我们没有对gst_bus_timed_pop_filtered()
返回的GstMessage进行处理,在本篇教程中,我们监听pipeline的erroe和EOS信号,并在发生时进行了打印了相应的信息,便于debug。
GstMessage是一个非常通用的结构,它可以传递几乎任何类型的信息。同时,GStreamer为每种消息提供了一系列解析函数。
在本教程里面,我们一旦知道message里面包含一个错误(通过使用GST_MESSAGE_TYPE宏),我们可以使用gst_message_parse_error()
方法来解析message,这个方法会返回一个GLib的GError结构。
GStreamer bus
GStreamer bus它是负责将element生成的GstMessages按顺序交付给应用程序和应用程序线程(这点很重要,因此GStreamer实际是在其他的线程中处理媒体流)的对象。
messgaes可以使用get_bus_timed_pop_filtered()
同步提取或者使用信号回调的方式异步提取。应用程序应该始终关注总线,以得到错误和其他回放相关问题的通知。
剩余代码和第一篇教程中的资源回收一样,不再赘述。
练习
尝试在这条example pipeline的source和sink之间添加视频filter element,例如vertigotv
,你需要创建它,将它加入pipeline,并将它和pipeline中的其他元素连接起来。
取决于你的开发平台和使用的插件,你可能会遇到一个“negotiation”错误,这是因为sink element无法理解视频filter element生产的数据格式,有关 negotiation的更多信息请阅读Basic tutorial 6: Media formats and Pad Capabilities。在这种情况下你需要在filter element之后添加videoconvert
,有关videoconvert
的更多信息可以阅读Basic tutorial 14: Handy elements。
注:关于手动创建GStreamer Pipeline推荐阅读Build Pipeline以获得更详细的介绍。
总结
这篇教程展示了:
如何使用
gst_element_factory_make()
创建element。如何使用
gst_pipeline_new()
创建一个空的pipeline。如何使用
gst_bin_add_many()
向pipeline中添加element。如何使用
gst_element_link_many()
连接element。
总计有两篇教程介绍GStreamer的基本概念,这是第一篇,下一篇是第二篇。
原文地址:https://gstreamer.freedesktop.org/documentation/tutorials/basic/concepts.html?gi-language=c
Last updated