从海康28181的PS流解析H264的补充

前文 《简单解析海康PS流获取H264》 针对海康摄像头的PS流解析做了简单处理,基本逻辑是正确的,但最近几个摄像头出现了一些奇怪的问题,需要针对相关现象进行查询。

RTP传输层

项目中为了可靠处理且因其他原因使用了TCP来传输28181的RTP数据,根据 rfc4571 记录,使用TCP传输的时候只需要在RTP包之前打上2个字节的长度,用来控制,毕竟TCP是流式传输,只能靠长度字段进行包的区分。

因此使用了TCP方式的RTP看起来问题不大,简单处理下就可以提取出PS数据了,事实也基本如此。但是出问题的摄像头却经常在解析RTP的时候出错,即判断RTP标志和SSRC出错,证明不是RTP包或者说包错乱。经过调试,打印出RTP头的所有信息,确实是在某个包后就出错了。打开二进制进行查看,发现出错之后往后部分数据之后,还能发现新的RTP包,看来是丢数据了。

将抓包数据写个测试程序测试,测试程序在解析RTP出错之后,往后查新的RTP包(主要靠SSRC),然后打印每个包的时间戳和序列号,发现确实是中间丢了几个包,TCP还能丢包?再看看日志发现,出现问题的摄像头都是上传速度非常慢的摄像头,即每秒仅能上传几帧视频的,而且丢包丢的都是I帧,毕竟I帧非常大。

因此猜测摄像头本身逻辑可能有点问题,即内部编码数据后,可能累积了大量未发送的数据,然后进行了内部丢包,而且这个丢包应该并没有按照一个RTP包去丢,而是直接丢弃的缓存数据,因而造成了上述问题。当然这只是根据现象的猜测,至于具体嘛,咱也不知道,咱也没有问。

还有一个现象是,这种丢包发生一会之后网络连接就被摄像头给断了。因为暂时不确定其他推流速度正常的摄像头是否会偶发这种现象,因此暂时任务可能偶发,针对性的类似测试程序一样,出现问题了通过查找下一个包来缓解挽救。但这由于丢包肯定会导致解析媒体数据出现错误,也就是下面的问题。

PS解析的错误处理

网络丢包造成的无法解析

如上,在丢包后,肯定会造成数据无法解析,这个时候肯定不能再继续处理了,肯定要结束当前的解析状态。也就是要上面网络层的配合,即网络层发现丢包之后要反馈给PS解析,让PS解析器及时的停止和重置,具体说来,大概是如果当前已经解析了一些媒体数据了,则提交这些数据,等待下一个PS包的到来(0x000001ba)。

PS数据格式错误?

在没有丢包的情况下,在解析PS的时候依然出现了问题,其格式大概如下

如上 0x000372F0 偏移处是前一个PES包(大小65478),里面解析了一个I帧0x000372FC,然后下一个PES包是 0x0004C72C 偏移处。二者偏移远远超过了 0xFFFF 大小,而PES的大小就是两个字节表示的。那么这就意味着格式有误,同时在RTP层解析确认此处的RTP流是顺序的,是没有丢包发生的。

虽然这个软件能解析出来后续的,但确实是对不上格式定义的,那这个也是一个坑。这个地方我也打算同上处理,解析的时候发生错误时候,查找下一个 0x000001XX 即可。同时也会兼顾RTP层的包及新的PS包 0x000001BA 出现。

其他问题

PS中媒体的真正时间戳

一般一个PS中存在了一个时间戳的视频包和一个时间戳的音频包,但是这个音频包和视频包可能时间戳是不相同的,为了表示准确,解析的时候尽量是按照时间戳变化后提交一次数据,无论是音频还是视频,基本上时间戳就没问题了。

最近的文章

FMP4不支持直播

因为在直播中,H5侧目前主要是B站的 flv.js 这个项目来做FLV的直播,但是H5原生支持MP4,而且SRS等均只输出简单的FLV视频。因此可以考虑尝试使用直接输出MP4的方法来实现,这样就可以跳过很多控制,直接原生支持,结果验证失败了。 测试前思考想要输出MP4,势必先要了解MP4的格式,然后 …

技术 继续阅读
更早的文章

使用VS开发Linux程序

VisualStudio的新版本已经开始支持远程编译调试Linux了,我安装了VS2017,尝试在Windows上写了一个Linux服务程序,非常方便。 基本原理能支持Linux开发的也只是在最新的版本中才行,好像应该是2015起。当然在安装VS的时候必须勾选跨平台下的Linux,没有安装的打开安装 …

技术 继续阅读