rtp协议丢包以及包重复判断

从事流媒体开发的朋友经常会用到rtp协议,今天我就udp荷载rtp包编码过程中经常遇到的重复包以及丢包如何判断说一下自己的经验。总体思路如下:

1、基于udp协议的rtp包接受包处理;
2、把收到的rtp包放入map容器中;map容器设置如下:std::map<int, RtpData> RtpDataMap;其中int值为rtp包的序列号,RtpData为自定义的结构体,用来存储每个rtp包内容(rtp包序列号、时间戳、marker值、rtp包数据有效长度以及rtp包数据等);
3、通过rtp包的marker值或者rtp包时间戳判断出完整的一帧数据之后,此时你的map容器中应该包括完整的一帧rtp包数据,可以通过map容器中的int值判断是否丢包以及包重复。

以上为总体思路概述。下面进行伪代码分析:

1、先简单介绍一下rtp包解析过程:
typedef struct RTP_FIXED_HEADER{
	/*byte 0*/
	unsigned char csrc_len : 4;
	unsigned char extension : 1;
	unsigned char padding : 1;
	unsigned char version : 2;
	/*byte 1*/
	unsigned char payload : 7; 
	unsigned char marker : 1;
	/*byte 2, 3*/
	uint16_t seq_no;
	/*byte 4-7*/
	uint32_t timestamp;
	/*byte 8-11*/
	uint32_t ssrc;
} RTP_FIXED_HEADER;

RTP_FIXED_HEADER rtp_header;
int rtp_header_size = sizeof(RTP_FIXED_HEADER);
//buffer为recv函数接收到的完整的rtp数据包内容
memcpy((void*)&rtp_header, buffer, rtp_header_size);
unsigned int  timestamp = ntohl(rtp_header.timestamp);
unsigned int  seq_no = ntohs(rtp_header.seq_no);
unsigned int marker = rtp_header.marker;

rtp_data = buffer + rtp_header_size;
//iDataNum为recv函数收到的rtp包大小
unsigned int rtp_data_size = iDataNum - rtp_header_size;

//此时rtp包接收、解析完成。


//定义RtpData结构体,开始重复包以及丢包判断
struct RtpData
{
    unsigned int seqNum;
    unsigned int isMark;
    unsigned int len;
    unsigned char data[1600];
    unsigned int  timestamp;

    CacheData()
    {
        seqNum = -1;
        isMark = false;
        len = 0;
	timestamp=-1;
    }
};
 RtpData dataTemp;
 dataTemp.seqNum=seq_no;
 dataTemp.len=rtp_data_size;
 dataTemp.timestamp=timestamp;
 dataTemp.isMark=marker;
 memcpy(dataTemp.data, RecvBuffer + rtpheadlen, dataTemp.len);
 //重复包的判断
 if (RtpDataMap.find(dataTemp.seqNum) != RtpDataMap.end())
 {
  //repeate data
  continue;
 }
 RtpDataMap[nSeqNum] = dataTemp;
 int SeqNum=dataTemp.seqNum;
 //判断为完整的一帧数据后操作
 if (dataTemp.isMark)
 {
  isComFrame = true;
  for (int i = beginSeq; i <= SeqNum; i++)
  {   
    //判断rtp是否丢包
    if (RtpDataMap.find(i) == cacheMap.end())
    {
      isComFrame = false;
      break;
    }
  }

  //完整的一帧数据操作
  if (isComFrame){
  //do something
  //根据你自己的业务需求处理
  }
  //beginSeq的维护
  beginSeq = SeqNum + 1;
  //无论是否为完整的一帧数据都会清空
  RtpDataMap.clear();
  

以上即为基于rtp协议的rtp包重复以及丢包检测的判断方法。该方法是基于一帧rtp数据包来进行判断的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值