解决网络摄像机(IPC)长时间直播,时间发生跳变引起的无法播放的问题!

前言:

    上一篇文章,我们利用live555建立RTSP客户端,能够拉取IPC输出的RTSP协议,并能够打印出每一帧音视频数据包。《编译live555》

问题:

    我们在实际拉取IPC的音视频数据过程中,发现:大概超过2小时之后,就会不定期发生,播放器无法播放或卡顿的现象,感觉像是网络出现堵塞的情况,仔细经过网络排查,没有网络堵塞,怀疑可能是时间戳有问题,因此,在IPC数据流获取位置,一直打印音视频时间戳,连续打印5小时以上,由于vs2010开发工具内部不能保留过长的调试信息,需要将音视频时间戳保存到日志文件当中,进行分析。

    后来,终于发现:在获取数据2小时之后的某个时间点,时间戳从一直增长,突然变成了0,自然会造成播放器发生卡顿现象。

    进一步排查,将问题定位到 void DummySink::afterGettingFrame() 函数。将每一帧的时间戳计算方式进行了思路调整。

解决:

    错误的思路代码(使用IPC封装的每帧时间戳,会发生跳变)   

// 使用RTSP协议传递过来的时间戳进行时间戳计算...
if((fSTimeVal.tv_sec <= 0) && (fSTimeVal.tv_usec <= 0)) {
    fSTimeVal = presentationTime;
}
// 计算时间戳(毫秒),tv_sec是秒,tv_usec是微秒...
dwTimeStamp = uint32_t((presentationTime.tv_sec - fSTimeVal.tv_sec)*1000.0f + (presentationTime.tv_usec - fSTimeVal.tv_usec)/1000.0f);

正确的思路代码(使用本地自己计算的时间戳,不会跳变)

// 把第一帧时间戳作为起点时间...
uint32_t	dwTimeStamp = 0;
ULARGE_INTEGER	llTimCountCur = {0};
// 得到当前时间,时间单位是0.1微妙...
::GetSystemTimeAsFileTime((FILETIME *)&llTimCountCur);
if( m_llTimCountFirst.QuadPart <= 0 ) {
    m_llTimCountFirst.QuadPart = llTimCountCur.QuadPart;
}
// 计算时间戳(毫秒),需要除以10000...
dwTimeStamp = (llTimCountCur.QuadPart - m_llTimCountFirst.QuadPart)/10000;

注意:这里使用的是 ::GetSystemTimeAsFileTime() 能够精确到0.1微妙,音视频数据帧使用的时间戳是毫秒但闻,转换成毫秒需要除以10000

最后,经过这样的时间戳改造之后,IPC长时间直播过程中,时间戳不会发生跳变,播放端保持稳定。

更多信息:

************************************************************
 * 浩一科技,提供云监控、云录播的全平台无插件解决方案。
 * 支持按需直播,多点布控,分布式海量存储,动态扩容;
 * 支持微信扫码登录,全平台帐号统一,关联微信小程序;
 * 支持多种数据输入:摄像头IPC、rtmp、rtsp、MP4文件;
 * 支持全实时、全动态、全网页管理,网页前后台兼容IE8;
 * 支持多终端无插件自适应播放,flvjs/hls/rtmp自动适配;
************************************************************
 * 官方网站 => https://myhaoyi.com
 * 技术博客 => http://blog.csdn.net/haoyitech
 * 开源代码 => https://github.com/HaoYiTech/

************************************************************

你可能感兴趣的:(live555,RTSP,协议)