GstPad setcaps,getcaps,set_setcaps_function...caps协商解说

这里需要描述一下gst_pad_get_caps/gst_pad_set_getcaps_function, gst_pad_set_caps/gst_pad_set_setcaps_function这四个函数。 

gst_pad_get_caps函数用来返回该pad能接受的caps。这个函数的逻辑是:首先检查getcaps函数指针是否为NULL,如果不是则调用getcaps函数,这是一个函数指针,我们可以通过gst_pad_set_getcaps_function来给这个函数指针赋值,从而实现自定义的get_caps函数的逻辑。完成后函数返回;如果getcaps函数指针为NULL,则gst_pad_get_caps函数从该pad的pad template中列出所有的caps,返回;如果该pad没有pad template,则gst_pad_get_caps函数检查该GstPad的caps成员是否为NULL,如果不为NULL,则返回这个member;最后,如果前面的都不成立,则gst_pad_get_caps创建一个empty的GstCaps并返回,表示该pad目前没有caps。 

get_pad_set_caps函数用来设置指定pad的caps。该函数首先检查参数中给出的caps是否已经和目前该pad中的caps相同,如果是,则直接返回。如果不相同,则检查setcaps函数指针是否为NULL,如果不为NULL则调用setcaps函数。我们可以通过gst_pad_set_setcaps_function函数来给setcaps这个函数指针赋值,这样就在gst_pad_set_caps函数中实现了自定义的逻辑。注意,gst_pad_set_caps函数会判断setcaps函数的返回值,如果是FALSE,则会直接报错return FALSE,这样的结果就是gst_pad_set_caps函数执行失败,caps negotiation失败。OK,当setcaps函数执行完毕后,gst_pad_set_caps函数执行gst_caps_replace,将保存在该pad中的caps member替换成参数中指定的caps,然后函数结束。 

请参考gst_pad_get_caps, gst_pad_set_caps的源码,如果还有不清楚的地方的话。 

OK,说清楚了这四个函数的逻辑很有必要,因为这四个函数长相差不多,容易混淆,而且互相之间的连系也需要搞清楚。现在进一步,我们需要知道,什么时候gst_pad_get_caps/get_pad_set_caps会需要用到。这部分内容可以参考Part-negotiation.txt中的描述,说的很清楚,因为这两个函数就是用于caps negotiation的。简单概括一下: 

caps negotiation在PUSH MODE和PULL MODE下逻辑不相同。PUSH MODE下,总是由src pad发起negotiation,为了整出一个src pad和peer sink pad都能接受的caps来,src pad会将自己的caps和peer sink pad的caps做intersect,这时就会调用函数gst_pad_get_caps,参数就是peer sink pad(一般直接使用gst_pad_peer_get_caps函数一步完成)。回顾一下上面gst_pad_get_caps函数的逻辑,如果peer sink pad没有设置getcaps函数指针的话,那就会直接返回peer sink pad template中的所有caps。接下去就是src pad调用gst_pad_set_caps,把自己的caps确定下来,再然后就是申请并分配buffer...... 

在PULL MODE下,由于是sink element的sink pad来drive pipeline,所以,caps negotiation要在pull thread启动之前就完成。首先,sink pad将自己的caps和peer src pad的caps做intersect(当然需要调用src pad上的gst_pad_get_caps),然后调用gst_pad_set_caps将caps确定下来。然后我们需要设置setcaps函数指针,然后在setcaps函数中,调用gst_pad_set_caps,参数是peer src pad,如果成功,那么表示src pad和自己一样,都具备了相同的caps,这样negotiation就OK了。最后,我们就可以使用gst_pad_pull_range来获取数据了,这个函数会为我们检查buffer中的caps和当前sink pad中的caps是否一致,如果不一致,就会return GST_FLOW_NOT_NEGOTIATED。 

最后再说一下gst_pad_set_caps函数被调用的时机。当在_chain函数中收到一个buffer之后,一般需要检查该buffer中的caps是否和当前pad中的caps相同,以防止数据在运行过程中改变caps。如果这两个caps不相同,那么,_chain函数应该返回GST_FLOW_NOT_NEGOTIATED,这样,gstreamer core就会用buffer中这个新的caps,去调用gst_pad_set_caps,这样做的目的是gstreamer要知道pad能否接受这个caps,如果函数返回TRUE,表示接受该caps,而且pad已经更新了自己的caps为目前这个,如果函数返回FALSE,表示caps negotiation failed,pipeline就无法正常运行了。 

到这里,可以看到,在PUSH模式下,_chain函数返回GST_FLOW_NOT_NEGOTIATED,gstreamer core就会自动为我们调用gst_pad_set_caps;但是在PULL模式下,虽然gst_pad_pull_range也会返回GST_FLOW_NOT_NEGOTIATED,但是gst_pad_set_caps并不会自动被调用,这是因为出于latency的考虑,gstramer不支持在pull thread中做set caps的动作。所以,在PULL模式下,我们需要自己handle这种GST_FLOW_NOT_NEGOTIATED的情况。回想pull thread没有启动之前,为什么我们需要设置setcaps函数呢?这是因为我们需要在这个函数中,使用gst_pad_set_caps来给peer src pad设置caps来完成caps negotiation,而这个动作在PUSH模式下,只要peer element的_chain函数返回GST_FLOW_NOT_NEGOTIATED,gstreamer core就会自动为我们调用peer src pad上的gst_pad_set_caps,所以,PUSH模式下,我们不需要去设置setcaps函数指针。 

有不明白的,参考Part-negotiation.txt,有详细的说明。

转载于:https://www.cnblogs.com/super119/archive/2011/01/03/1924445.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值