gstreamer学习笔记---element流程总结

版权声明:本文为博主原创文章,未经允许,不得转载。 https://blog.csdn.net/weixin_41944449/article/details/82804574

element总结

  前面几篇较详细的介绍了v4l2src、videodecoder编码、gst-omx以及videosink显示几个element,介绍它们与其他element交互的操作流程,这一次,我们对之前的文章做一个总结。

element创建

  由于一开始gstreamer在加载的时候,会扫描/usr/lib/gstreamer-1.0目录下的库并加载,识别其中的feature,并记录相关的信息。当使用到某一功能的时候,检查gstreamer core是否支持该功能,如果有,则加载相应的库,获取信息,创建相应的element实例,这样,element创建出来了。

element link

  创建之后,将会添加到bin并且link element,而在通过link的时候,将会通过gst_pad_query_caps (pad, NULL)调用到相应element的查询函数。这个查询函数将会调用到element的init()函数通过gst_pad_set_query_function()设置的pad查询函数,而该查询函数在element link阶段一般都是返回pad template caps。因为这个阶段还没有进行打开设备、设备初始化等操作,不知道element真正支持的caps,但element link阶段只要查询的caps有交集即可link成功,所以问题不大。

NULL->READY

  该状态下,将会进行相应的设备初始化,根据相应的class调用start()函数或者open()等函数初始化相应的硬件设备,初始化class的结构参数等。

READY->PAUSED

  这一步,将会进一步申请资源,确定相应的参数设置,重要的一步,将会激活pad,激活的过程,将会调用到element init中通过gst_pad_set_activate_function()设置的pad激活函数,而在激活的同时,也将会选择相应的push模式,所以又会调用到element init通过gst_pad_set_activatemode_function()设置的pad激活模式函数。
  在激活pad的时候,一般的将会设置了GST_PAD_FLAG_NEED_RECONFIGURE标志位,在element中将会有检查这个标志位,然后将会进行协商操作,在协商的过程中将会多次调用到element的pad查询函数,为什么说是多次调用呢,一开始link时调用,得到的是pad template caps,在进行设备初始化之后,将会可以查询实际的硬件,得到真正支持的caps,这样,上游将得知下游支持的caps。
  caps之后,就将是接收到stream-start事件,上游告知element,将会开始传输数据,谁将负责处理EVENT呢,一般的element init中通过gst_pad_set_event_function()设置了pad的EVENT处理函数,element接收到该事件,提取相应的信息初始化结构。
  虽然上面反馈了caps到上游,上游根据自身情况选择相应的caps之后,又将会发送accept-caps query,再次查询,element是否支持该caps。
  上游再次得到反馈之后,将会发送caps事件到element,element接收该事件并将会set_caps。同时,上游会发送GST_QUERY_ALLOCATION查询缓冲区的属性,确定buffer pool缓冲区属性,决定时候申请buffer pool,以及激活pool等操作。
  最后,就是GST_EVENT_SEGMENT和TAG EVENT。segment将描述接下来的数据时间戳范围,之后的数据都将需要在这个范围才可以正常使用。TAG则是描述数据的其他一些信息,这些,element的event处理函数将会有相应的操作。
  接下来就是数据的预滚(preroll)。数据到达的时候,将会调用element init中通过gst_pad_set_chain_function()设置的chain函数。检查数据的时间戳是否在segment内,数据同步,通过preroll函数进行预滚,最后就是commit状态,进入PAUSED。

PAUSED->PLAYING

  在这个过程,将会设置clock,时钟运行,chain函数接收到数据的时候,检查时间有效性,进行数据同步、处理,push到下游,发送QOS事件到上游,完成一个循环。

总结

  上述的操作流程,不可能每个element都会是一样的操作,但是大致流程是差不多的,在接触一个新的插件的时候,可以通过上述的流程阅读代码,了解插件是如何操作的。当然,最好的,是可以通过捕获运行log信息来分析具体的流程。




  以上是个人理解,有理解错误的地方,欢迎指出,感谢

猜你喜欢

转载自blog.csdn.net/weixin_41944449/article/details/82804574