首页 > 音视频 > 安防视频播放秒开优化
2019
02-23

安防视频播放秒开优化

在视频播放中,播放器立即出图像(秒开)非常重要。能够极大提高用户的体验度。网上有很多关于直播行业秒开的优化经验,但是没有安防行业的,安防行业跟直播还是有些不一样的,下面说下一些安防行业视频秒开的优化经验。

直播行业视频封装传输遵循RTMP/HLS/DASH这些标准。安防行业视频播放都是遵循GBT28181。目前常见的视频编码格式有H264/H265/MPEG-4/Svac,通常都封装为PS流(Program Stream,封装标准参考iso13818-1 2.5小节)格式,然后作为负载封装成RTP包传输。在直播行业,视频流的采集主要是用户的手机或者PC设备,而安防行业视频流的采集来自于各大厂商的摄像头。

视频秒开需要从播放端,发送端以及网络传输考虑。视频秒开关键点是要立马获取到关键帧,后续视频帧的解码都得参考关键帧,有了关键帧,解码器才能立刻解码,然后出图像。

发送端

发送端一般分为两种:直连的设备以及流媒体服务器。直连设备是指播放端直接连接摄像机播放。

摄像机设置

由于视频来自摄像机,无论发送端是哪种,我们都要修改摄像机的关键帧间隔(GOP),一般设置2倍的帧率。这样确保在较短时间内,能够获取到关键帧播放,设置太短,会增大数据量,设置太长会造成等待关键帧时间太久,一旦出现丢包等异常,影响较大。如下图是某款海康摄像机配置,我们配置视频帧率为25帧,关键帧(I帧)间隔为2s,即50帧。
安防视频播放秒开优化 - 第1张  | 剑痴乎

服务器设置

如果不是摄像机直连,通过我们自己的流媒体服务器的话就需要对我们的服务器做处理。这时我们需要做关键帧缓存,确保推给播放端的流第一帧就是关键帧。在互联网直播中通常用到了CDN,很多CDN厂商都会缓存一组GOP数据。安防行业一般都是私有网络,没有CDN,那服务端具体要怎么做呢?
安防视频播放秒开优化 - 第2张  | 剑痴乎

  • 服务端为每一路摄像机信号维护一个关键帧缓冲区,缓存最新的一组GOP数据(关键帧以及相关的一组P帧),每当该摄像机有新关键帧数据来时,都要更新这个缓冲区
  • 当有播放端请求某摄像机信号时,先判断当前摄像机实时流是否是关键帧第一个包
  • 是的话直接推实时流,同时更新缓冲区
  • 不是的话就得从关键帧缓冲区拿数据推给播放端,直到实时流来了关键帧,此时切换到从实时流推流,然后更新缓冲区

播放端

解复用(Demux)

Demux是指解析视频的封装格式,得到包含的音视频原始码流,Demux时间越短,就越快得到视频流,从而加快秒开速度。我们这里的Demux过程主要是解析RTP负载数据,对于每个RTP包,去除头部12字节头部数据后就是负载数据。由于国标视频基本都是封装为PS流格式,所以需要解复用PS流,从PS流里得到原始视频数据。对于PS流的Demux有两个方法,一个是自己写,PS流结构不是很复杂,1000行以内代码可以搞定,如果嫌麻烦,还有一个方法是使用ffmpeg,对于ffmpeg如何demux PS流,可以参考ffmpeg的avio_reading例子,通过探测流的方式demux PS流。

如果是自己写的Demux程序,我们在Demux PS流需要搜索各种头部,由于存在丢包等异常情况,所以搜索头部太久时需要做处理,丢弃无用的数据,避免耗时太久。由于PS中包长度都是用两字节表示,长度为2^16,所以我们可以设置一个值,比2^16大点,当搜索的字节数大于这个值还没搜索一个PS流的包头(0x000001开头),此时就要丢弃之前数据,处理新数据,因为之前数据很大可能丢包或其他问题。

如果是使用ffmpeg做PS流的Demux,有几点需要注意。由于ffmpeg Demux未知流时,需要探测一定大小数据,甚至会尝试解码未知流,这个过程如果不做优化会耗时很久。

ffmpeg通过AVIO方式探测流格式主要通过 avformat_find_stream_info 函数实现,我们可以通过设置 AVFormatContext 的probesize与max_analyze_duration 限制ffmpeg探测大小与时长,提高Demux速度,我一般按如下设置:

限制流分析大小64K,时长2s。但有点需要注意的是如果送入播放端首帧视频不是关键帧, avformat_find_stream_info 很大可能性失败,因为ffmpeg在max_analyze_duration内如果获取不到关键帧数据基本会探测失败。所以使用ffmpeg探测PS流时需要确保首帧视频就是关键帧(视频重要参数都存储在关键帧内),这样在max_analyze_duration内才能获取到PS流信息。至于如何判断PS流的关键帧数据,这个很简单,可以根据PS流头部判断,PS流封装的关键帧都含有system_header(0x000001BB开头)与program_stream_map(0x000001BC开头)。

解码

Demux得到原始视频码流后就可以开始解码了,能硬解码就硬解码,硬解码速度会优于软解,尤其在解码路数多时。

渲染

解码得到YUV或RGB数据后,我们需要渲染到屏幕显示,这是最后一步了。渲染也存在是否硬件加速的区别。比如windows平台,优先D3D硬件加速渲染,充分发挥显卡的能力,加快渲染速度。如果前面解码是用硬解码,此时也必须硬件加速渲染。否则又要搬运显存中的硬解数据到内存,由于解码后的数据一般较大,所以这个过程很耗时,同时影响性能,提高CPU占用率。

网络传输

传输分为TCP与UDP。由于TCP的特性,所以TCP获取到首帧视频耗时长点,同时延时也大。所以优先UDP传输。但是UDP传输又存在丢包,乱序问题,造成视频花屏,所以使用UDP传输时,需要做好抗丢包的处理,这个我们以后会讨论。

本文已发表到本人微信公众号:码上Play,欢迎关注。
安防视频播放秒开优化 - 第3张  | 剑痴乎

最后编辑:
作者:Jeff
Avatar
管理员——代码为剑,如痴如醉

留下一个回复

你的email不会被公开。

This site uses Akismet to reduce spam. Learn how your comment data is processed.