rtp协议丢包以及包重复判断
从事流媒体开发的朋友经常会用到rtp协议,今天我就udp荷载rtp包编码过程中经常遇到的重复包以及丢包如何判断说一下自己的经验。总体思路如下:1、基于udp协议的rtp包接受包处理;2、把收到的rtp包放入map容器中;map容器设置如下:std::map<int, RtpData> RtpDataMap;其中int值为rtp包的序列号,RtpData为自定义的结构体,用来存储每个rt
·
从事流媒体开发的朋友经常会用到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条内容
所有评论(0)