从activatepush_function来看gstreamer中的激活机制

从gstrtpjitterbuffer.c中使用activatepush_function来看gstreamer中的激活机制 

有关函数gst_pad_set_activatepush_function。这个可以看gstreamer包中doc/design目录下的part-activation.txt这篇文档,这篇文档将pad active的逻辑说的还是比较清楚的。首先gstreamer core会调用pad的activate方法(如果我们调用gst_pad_set_activate_function重载了的话),在这个方法中,必须最后要调用gst_pad_activate_push和gst_pad_activate_pull,来告诉gstreamer core,这个pad是使用push还是pull模式进行调度。如果我们没有重载activate函数,那么,默认的activate函数使用的是gst_pad_activate_push,也就是PUSH模式。 

OK,现在来看gst_pad_set_activatepush_function和gst_pad_set_activatepull_function就比较好理解了。如果这个pad是PUSH模式,那么,当gstreamer core激活这个pad的时候,就会调用该pad的activatepush_function(如果我们设定了的话);如果这个pad是PULL模式,那么,当gstreamer core激活这个pad的时候,就会调用这个pad的activatepull_function。 

举例来说,在gstrtpjitterbuffer.c中,给sink pad设定了chain函数,同时给src pad设定了activatepush_function,这就表示sink pad和src pad都使用PUSH模式(因为没有对任何一个pad设定activate函数,使用默认设置,也就是PUSH模式),这种情况则表示使用_chain函数来进行数据流转(参见plugin writer’s guide调度模式一章。事实上,我觉得只要sink pad是PUSH模式,则_chain函数就肯定会被调用,因为在src pad上设定PULL模式,一般是为downstream element服务,也就是downstream element的sink pad可以使用PULL模式了)。 

OK,现在pipeline开始运转。首先,GStreamer core在初始化并激活pipeline中elements的时候,是从sink element开始,一直到源头的src element。如果反过来,那么,src先被激活产生了数据,sink element还没准备好,这显然不合适;在单个element激活的过程中,也是先从src pad开始,再到sink pad,也是同样的道理,让sink pad产生数据时,src pad已经ready。所以,再回到gstrtpjitterbuffer中来看,src pad先被激活,此时activatepush_function被调用,在这个函数中,代码启动了一个gthread,这个thread会等待某个condition,condition被signal了之后就会开始工作,最后是调用gst_pad_push将buffer push到downstream;然后,sink pad被激活,由于我们没有给sink pad设定activatepush_function,所以使用默认的逻辑,也就是gstreamer core中的默认实现。 

Sink和Src pad都激活后,_chain函数被调用。这里注意不要混淆activatepush_function/activatepull_function和_chain函数,前面两个函数都只会在pad被激活的时候被调用一次,而_chain函数是会一直被调用的,因为不断的有buffer从上游传递过来。如果我们的sink pad不是PUSH模式,而是PULL模式的话,我们一般会启动一个GstTask,这个Task会循环从上游读取数据,所以这种情况下_chain函数就不需要了。OK,gstrtpjitterbuffer.c中的_chain函数会检查buffer中的RTP数据是否有效,如果有效再经过一系列处理之后就会去signal condition。之前我们说过,这个condition正是src pad的activatepush_function中启动的那个gthread等待的condition,这个condition被signal了之后,这个gthread就开始工作了,主要做的工作是将收到的数据按照timestamp排好序,去掉重复的RTP packet等。最后调用gst_pad_push将buffer传递了下去。 

整个流程就是这样,所以,在gstrtpjitterbuffer.c的_chain函数中,我们是看不到gst_pad_push这句代码的,因为我们对src pad的PUSH逻辑有了自己的定义。

你可能感兴趣的:(function)