jrtplib 发送rtp包时时间戳的处理方法
前言
今天在处理前同事写的代码的时候发现通过rtp传输的视频播放的时候异常,检查发现是时间戳搞错了,因为这个地方
比较容易混淆,特此记录。
一、rtp时间戳说明
rtp时间戳单位:rtp时间戳的单位不是时间,是通过采样率转换成的,比如,视频的采样率为90000Hz的话,
是将1秒的时间分成90000份,所以一份的是1/90000,这个值就是时间戳的单位。
rtp时间戳单位和帧率的关系:比如,一个视频25帧/秒,因为一秒的采样率为90000,每帧对应的采样率增加为90000/25=3600,
可以理解为3600份个1/90000,所以下一帧视频的rtp相对上一帧应该增加3600,假如一帧视频分为10个rtp包发送,那么这10包的
时间戳应该相同,一直到下一帧视频再增加。
二、jrtplib的相关函数说明
SetDefaultTimestampIncrement(3600):设置默认的增量。
int SendPacket(const void *data,size_t len):设置参数后按设置值发送数据,每次调用,
下个rtp包相对本次发送的rtp包时间戳增加设置的时间戳增量。
int SendPacket(const void *data,size_t len,
uint8_t pt,bool mark,uint32_t timestampinc):自定义mark和时间戳增量发送数据,
每次调用,下个rtp包相对本次发送的rtp包时间戳增加自定义传入的时间戳增量。
为什么设置了默认的增量还要有自定义步长的接口,如前文所说,因为SendPacket每调用一次,jrtplib就会将时间戳增加一次增量值,当音视频要分包发送的时候,并不是每次发送都要增加,所以,在分包发送的时候应该调用自定义时间戳增量的接口,只有在一帧视频首包的时候增加时间戳的值,这一帧后续的分包和首包相同。
伪代码示例:
// 注意:根据实际测试,设置了时间戳增量后,不是本次发送使用,是下次发送使用!!!!,所以在尾包设置。
int timeStep = 0;
int mark = 0;
if (最后一个分包)
{
mark = 1;
timeStep = 90000/nFramRate;
}
else
{
mark = 0;
timeStep = 0;
}
m_pRtpSession->SendPacket((char*)m_pSendBuf, len, PS_PAYLOAD_TYPE, mark, timeStep);
如图:

总结
学海无涯,如有错误,欢迎交流指正,谢谢