rtp seq 校验

本文解析了RTP源结构体中的关键信息,包括序列号处理、基准seq确定、丢失和乱序检测。介绍了初始化和更新seq函数的作用,展示了如何通过update_seq判断seq的有效性。核心在于理解seq的管理和RTP协议的可靠性保障。
摘要由CSDN通过智能技术生成

rtp rfc 文档链接

1. rtp 源 结构体信息

/*
 * Per-source state information
 */
 typedef struct {
 u_int16 max_seq; /* highest seq. number seen */
 u_int32 cycles; /* shifted count of seq. number cycles */
 u_int32 base_seq; /* base seq number */
 u_int32 bad_seq; /* last ’bad’ seq number + 1 */
 u_int32 probation; /* sequ. packets till source is valid */
 u_int32 received; /* packets received */
 u_int32 expected_prior; /* packet expected at last interval */
 u_int32 received_prior; /* packet received at last interval */
 u_int32 transit; /* relative trans time for prev pkt */
 u_int32 jitter; /* estimated jitter */
 /* ... */
 } source;

2. 初始化源

init_seq(s, seq);
s->max_seq = seq - 1;
s->probation = MIN_SEQUENTIAL;

3. 初始化 seq 函数

void init_seq(source *s, u_int16 seq)
 {
	 s->base_seq = seq;
	 s->max_seq = seq;
	 s->bad_seq = RTP_SEQ_MOD + 1; /* so seq == bad_seq is false */
	 s->cycles = 0;
	 s->received = 0;
	 s->received_prior = 0;
	 s->expected_prior = 0;
	 /* other initialization */
 }

4. seq 更新函数

int update_seq(source *s, u_int16 seq)
{
    u_int16 udelta = seq - s->max_seq;
    const int MAX_DROPOUT = 3000;
    const int MAX_MISORDER = 100;
    const int MIN_SEQUENTIAL = 2;
    /*
    * Source is not valid until MIN_SEQUENTIAL packets with
    * sequential sequence numbers have been received.
    */
    /* 通过连续probation个变量,确定base_seq */
    if (s->probation) {
        /* packet is in sequence */
        if (seq == s->max_seq + 1) {
            s->probation--;
            s->max_seq = seq;
            if (s->probation == 0) {
                init_seq(s, seq);
                s->received++;
                return 1;
            }
        }
        else {
            s->probation = MIN_SEQUENTIAL - 1;
            s->max_seq = seq;
        }
        return 0;
    } else if (udelta < MAX_DROPOUT) {	// 当前max_seq 向后MAX_DROPOUT内个seq
        /* in order, with permissible gap */
        if (seq < s->max_seq) {		// 如果seq < s->max_seq 表示又一次循环
            /*
            * Sequence number wrapped - count another 64K cycle.
            */
            s->cycles += RTP_SEQ_MOD;
        }
        s->max_seq = seq;
    } else if (udelta <= RTP_SEQ_MOD - MAX_MISORDER) {	// 向前超过MAX_MISORDER个seq
        /* the sequence number made a very large jump */
        if (seq == s->bad_seq) {
            /*
            * Two sequential packets -- assume that the other side
            * restarted without telling us so just re-sync
            * (i.e., pretend this was the first packet).
            */
            init_seq(s, seq);
        } else {
        	// 设置seq + 1为bad_seq,如果下一个seq == s->bad_seq, 则重新初始化seq
            s->bad_seq = (seq + 1) & (RTP_SEQ_MOD - 1);		
            return 0;
        }
    }
    else {
        /* duplicate or reordered packet */
    }
    s->received++;
    return 1;
}

update_seq 主要包括三部分:

  • 因为rtp 中的初始seq 不确定,通过接收连续prodation个seq,来确定基准seq
  • udelta < MAX_DROPOUT 表示向后跳变,不能超过MAX_DROPOUT
  • udelta <= RTP_SEQ_MOD - MAX_MISORDER 向前跳变,超过MAX_MISORDER

通过update_seq 函数即可校验当前的seq是否有效

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值