JCHub

  • Home
  • Category
    • A/V
    • WebRTC
    • Beauty of Programming
    • Linux
    • Windows
    • Moments of Life
    • Campus Life
  • Reference
    • API Reference
    • Utilities
    • AV Test
    • Doc
  • Message Board
  • About
JCHub
Code as My Sword, Lost in Obsession
  1. Main page
  2. A/V
  3. Main content

安防视频播放秒开优化

2019年2月23日 3192hotness 3likes 0comments

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

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

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

发送端

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

摄像机设置

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

服务器设置

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

  • 服务端为每一路摄像机信号维护一个关键帧缓冲区,缓存最新的一组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速度,我一般按如下设置:

C++
1
2
3
format_ctx->probesize = 64 * 1024;
format_ctx->max_analyze_duration = 2 * AV_TIME_BASE;
ret = avformat_find_stream_info(format_ctx, nullptr);

限制流分析大小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传输时,需要做好抗丢包,拥塞控制等处理,这个我们以后会讨论。

This article is licensed with Creative Commons Attribution-NonCommercial-No Derivatives 4.0 International License
Tag: ffmpeg 音视频
Last updated:2022年3月27日

Jeff

管理员——代码为剑,如痴如醉

Tip the author Like
< Last article
Next article >

Comments

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
Cancel

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

文章目录
  • 发送端
    • 摄像机设置
    • 服务器设置
  • 播放端
    • 解复用(Demux)
    • 解码
    • 渲染
  • 网络传输
Related Posts
  • ffmpeg视频编码YUV与AVFrame对应关系
  • mp4文件elst研究
  • avcodec_decode_video2解码得不到图像
  • 告别CapCut收费!开源视频剪辑工具OpenCut 来了
  • 音视频开发入门:视频基础
Categories

COPYRIGHT © 2026 jianchihu.net. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang