写点什么

音视频开发必懂知识—低延迟相关知识整理

  • 2022 年 4 月 07 日
  • 本文字数:2797 字

    阅读完需:约 9 分钟

1:了解延迟

在推流,拉流相关业务(如直播),从数据的采集发送到客户端接收到数据后播放,其实是有一定的播放延迟的。

如下图:使用 rtmp(是基于 tcp 进行传输的)进行推流,然后使用不同方式对 rtmp 拉流播放,延迟误差。

​从图中可以看出:

​ ===》使用 ffplay 进行播放时延迟是比较大的,默认是有缓存的。

​ ===》如果去掉缓存,可以对延迟有一定的优化。

​ ===》以及使用其他的一些方案,其实是可以把播放延迟进行降低的,那么降低延迟的方案有那些呢?

2:从直播的流程上进行分析:

下图从老师的课程中截取得图片,描述了直播从数据采集,处理,推流===》到流媒体服务器===》再到客户端进行拉流播放的流程。

如果要考虑直播延迟,其实是要根据这个流程从推流端,流媒体服务器,以及拉流端进行分析,同时要考虑网络抖动

​3:从流程引入延迟分析

3.1:整体上分析延迟原因

3.1.1:延迟原因

音视频的直播一般流程是: 推流 ===》流媒体服务器 ===》拉流

影响音视频的原因一般有:

1:缓存 (有缓存就说明有数据的堆积,是延迟)

2:网络抖动(网络抖动会导致数据发送阻塞,或者一次性收到过多数据(需要做变速处理加快消费保证实时))

3.1.2:传输方案

udp 相对于 tcp,更适合音视频的低延迟传输。

rtmp 底层使用的是 tcp 传输,tcp 的可靠传输其实会丢失一定的实时性。

webrtc 基于 udp 进行传输的,相比 tcp,可以一定程度降低延迟。

除此之外,适用于音视频的另一套传输协议:quic(快速 UDP 互联网连接)

另外:现在市面上电商直播一般采用 rtmp h264+aac 因为 CDN 支持比较高,虽然 rtmp 使用 tcp 传输,有一定的延迟。

3.2:推流端延迟分析

推流端一般包括:音频的采集,音频处理,音频编码 和视频的采集,视频的处理,视频编码,以及最终的推流动作

3.2.1:音频流的处理延迟

3.2.1.1:采样数导致一次采样会耗时

音频流的采集:采样延迟与设置的一次采样样本数有关。

===》假设采样率是 44.1khz,设置一次采集 1024 个样本再处理,则采集等待耗时为 1024*(1/44100),耗时 23.2ms

===》如果采样率为其他,设置采样个数,其实采样上就已经有耗时。

2.2.1.2:音频处理会耗时

对采集到的音频做混音,降噪等处理,也是有延迟

2.2.1.3:音频编码也会有延迟

音频编码也有延迟 webrtc opus 延迟比较低,但是 aac 有 1~2 帧的延迟

3.2.2:视频流的处理延迟

视频采集:一般 25 帧,采集到一帧就去处理喽

视频处理:(水印,美颜,滤镜)相关处理耗时一定要跟得上(软件/硬件) opengl 比较快==》不要队列阻塞,处理耗时

视频编码: zero lantency(零延迟), 不要用 b 帧

3.2.3:推流策略会导致的延迟

推流涉及推流策略,消费采集处理后的音频帧和视频帧。

采样本来就是实时采集的,推流应该是有数据就立马推流,不要缓存,越快越好。 ==》有延迟啊

3.3:流媒体服务器分析延迟

流媒体服务器涉及功能: 读数据,以及把数据推出去

3.3.1:流媒体服务器读数据策略

读数据,可能同一个数据,需要写给多个端去发送(如直播场景,多个人看)如何转发数据?

==》1:只有一个队列,读数据后,直接遍历 fd 进行写(如果其中一个 fd 卡顿,会阻塞)

==》2:每个写端有一个自己的队列,负责自己的数据写入。 (每个 fd 有自己的队列不影响其他模块)

设计队列时,如果有队列过多,满了(写延迟,消费过慢),可以设置覆盖。

3.3.2:(推流到服务器)读数据导致的延迟(多次读和一次读(内核态/用户态切换影响))

合并读取数据有延迟(有 200ms 的数据,每 10ms 读一次,是需要切换用户态和内核态,需要 20 次)

如何合并数据读取,200 的数据读取一次,内核态/用户态切换 1 次 可以降低 cpu。

3.3.3:服务器内部缓存队列会不会导致延迟

这里一般不会导致延迟,但是涉及队列消费过慢,如客户端卡顿,会队列中数据有过多。

客户端出现卡顿,客户端卡了 5s,服务端对应的队列会缓存 5s,恢复要让其发出去

网络恢复,如果一次拉取过多 5s 的数据,如果不做音频变速处理,客户端队列一直有延迟了。

3.3.4:(从服务器拉流)服务器写数据延迟

写数据(合并写处理)

==》有 200ms 要写,20ms 写一次,与 200ms 写一次的问题。

==》效率高,更高吞吐量(带宽),但是有延迟,实时性差。

3.3.5:服务器配置(srs),gop cache 开启的影响(视频帧 i,b,p 帧)

视频帧有 i 帧,b 帧,p 帧的差异:gop 就是两个 i 帧的差距

如果开启 gop cache:服务器缓存一个 gop,客户端从这个缓存的 gop 中 i 帧开始播放

===>最优场景: 客户端链接,gop 中刚好获得 i 帧

===>最差场景: 客户端链接,gop 中刚好从上一个 i 帧开始,客户端拉到上一帧的数据快速显示(如果不做变速播放,这里就会有延迟了,总是差一个帧)

===》开启 gop cache 的优点:可以快速显示画面。

===》开启 gop cache 的缺点:GOP 可能直接至少延迟一个 cache(网络抖动渲染等其他延迟)

如果不开 Gop cache,也有最优和最差:(p 帧和 b 帧是不现实画面的,黑屏)

===》最优:拉到 i 帧,直接解码显示

===》最差:刚好错过 i 帧,错过 i 帧,画面至少黑屏一个 gop 的时长,等到下一个 i 帧才能显示

webrtc 有一个优化技术:

​ 客户端有请求连接时,服务器端先立马回复一个 i 帧的技术。

3.4:拉流端延迟分析

从上图可以看到拉流数据的流程:

拉取到服务器端的流后,音频流和视频流分别由专门的队列做缓存处理,去解码播放。

3.4.1:拉流端现象

1:缓存数据过多,要实时计算缓存队列的数据能播放的时长

===》帧间隔*帧数

===》最大的 pts-最小的 pts (pts 显示时间戳)

2:为什么打开有些播放器后,能听到声音的快速播放,如我在腾讯课堂听直播时就感受过

==》变速播放,为了快速消耗缓存中的数据 (直播场景,缓存其实就是延迟)

3.4.2:拉流端解决延迟(加速播放策略)

拉流端的延迟主要是:拉流后,缓存队列中数据有堆积,一直得不到消费(缓存导致了延迟)

==》尽快处理,加速消费就好了~

可以设置策略,使用加速播放来进行处理:

==》一些参数:缓存时间(触发变速),抖动值(回复正常参数),以及变速系数(控制变速速度)

起播:

========>检测缓存大于设置的缓存时间,开始播放,做变速处理,

========>如果缓存小于设置的缓存时间,则恢复正常播放

播放过程中:

==》抖动值:因为网络传输是有抖动的,抖动带来的缓存,如果按起播一样处理,就会陷入频繁的变速恢复中。

==》如果音频缓存大于 抖动值+设置的缓存时间 ==》触发变速播放

==》检测到小于设置的缓存时间,恢复正常播放。

注意:设置队列的缓存时间和设置抖动值,可以根据网络场景进行自己设置。

4:总结

推流 ==》服务器转发 ==》拉流

1:推流:注意采集延迟,音效处理,视频特效处理,编码延迟,有数据则直接推流,不要等待。

=========> 可以对队列帧数进行检测,根据帧数,判断网络,可以通过调整码率进行网络适配

2:服务器转发:

=========>合并读,数据队列,合并写

3:拉流

==========>数据队列,变速播放(sonic),变速触发和恢复机制的设置

技术参考:

音视频流媒体服务器高级开发学习地址:

FFmpeg/WebRTC/RTMP/RTSP/HLS/RTP播放器-音视频流媒体高级开发学习

音视频流媒体服务器高级开发学习视频资料点击 音视频学习资料 进去自取


用户头像

Linux服务器开发qun720209036,欢迎来交流 2020.11.26 加入

专注C/C++ Linux后台服务器开发。

评论

发布
暂无评论
音视频开发必懂知识—低延迟相关知识整理_WebRTC_Linux服务器开发_InfoQ写作平台