1. 简介:
本文主要分析gstreamer中的rtpjitterbuffer中推送数据线程的代码。
2. 流程:
推送线程主要功能就是根据jbuf上的数据,对排序的包(或者对应包序的异常事件)进行处理下发。
主要流程如下:
1) 当rtpjitterbuffer工作在PUSH模式下,会通过gst_pad_start_task创建一个子线程,执行推送数据主要操作gst_rtp_jitter_buffer_loop。
2) handle_next_buffer中会对jbuf中的item进行分析处理,如果是连续包,会依序推送至下游组件。
3) 当jbuf中没有item,或者当包不连续的时候,会从handle_next_buffer返回GST_FLOW_WAIT,在gst_rtp_jitter_buffer_loop中会进入等待状态。
4) 当主线程收到包,或者当一个包确认被丢弃的时候,会激活推送数据线程来进行处理。回到2) 执行。
如图:
3. 代码片段:
3.1 函数主要入口gst_rtp_jitter_buffer_loop
这个函数主要就是一个循环,如果可以处理包就一直处理,直到包序不连续或者jbuf空,这时候会等待包或者丢包事件的到来唤醒本线程。
do {
// 一个循环中处理jbuf,直到处理到jbuf空或者出现包缺失,需要等待
// 这时候会等待条件变量来唤醒该线程。
result = handle_next_buffer (jitterbuffer);
if (G_LIKELY (result == GST_FLOW_WAIT)) {
/* now wait for the next event */
JBUF_WAIT_EVENT (priv, flushing);
result = GST_FLOW_OK;
}
} while (result == GST_FLOW_OK);
3.2 单个buffer处理函数 handle_next_buffer
这个函数整体处理的流程比较清晰。
1) 窥视jbuf的头部的item,如果为空则等待其余包到来。
2) 根据item序号判断是否连续包(也可能是事件,在这个函数中不体现,请查看3.3),是连续包则推送至下层,重复包则直接删除,如果包序发生跳跃(即gap > 0),则说明可能出现丢包,需要等待主线程和定时器配合判断,此时也需要进行等待,等待对应包序的包(或者事件,如LOST事件)到来。
/* Peek a buffer and compare the seqnum to the expected seqnum.
* If all is fine, the buffer is pushed.
* If something is wrong, we wait for some event
*/
static GstFlowReturn
handle_next_buffer (GstRtpJitterBuffer * jitterbuffer)
{
GstRtpJitterBufferPrivate *priv = jitterbuffer->priv;