From 67036f074b31bfd70ae22f4fbd25cfcc36519442 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=8F=E6=A5=9A?= <771730766@qq.com> Date: Thu, 16 Apr 2020 18:48:13 +0800 Subject: [PATCH] =?UTF-8?q?Created=20=E6=80=8E=E4=B9=88=E6=B5=8B=E8=AF=95Z?= =?UTF-8?q?LMediaKit=E7=9A=84=E5=BB=B6=E6=97=B6=EF=BC=9F=20(markdown)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 怎么测试ZLMediaKit的延时?.md | 66 +++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 怎么测试ZLMediaKit的延时?.md diff --git a/怎么测试ZLMediaKit的延时?.md b/怎么测试ZLMediaKit的延时?.md new file mode 100644 index 0000000..b6ae507 --- /dev/null +++ b/怎么测试ZLMediaKit的延时?.md @@ -0,0 +1,66 @@ +## 引言 +有些小伙伴们经常在群里面问我,为什么用ZLMediaKit拉流代理、推流转发的流播放延时好几秒,长的时候10多秒?为什么HLS延时更高,动辄延时半分钟?本文的目的在于澄清大家对延时的误解。 + +## 什么是延时 +很多小伙伴们并不能明白什么叫延时,认为随便一个播放器播放出来的画面跟原始流画面时间差就是延时,其实这是对延时最大的误解。 +延时不是表象,很多人在测试延时时很不专业,对延时测试的专业性认识不足,在此我特别提醒,不是随随便便的播放器都有资格做延时测试的! + +总而延时,一般整个延时有以下几部分累加组成: + +- **采集延时** + +在采集摄像头或显卡画面时,由于fps的限制和cpu性能、内存拷贝速度等客观限制下,采集画面成YUV/RGB等数据时会有一定的延时,一般延时为毫秒级别。由于一般编码器对输入数据格式存在限制,譬如要求统一输入YUV420P,这样在做RGB->YUV420P转换时,也会有转换计算延时(这个可以通过libyuv库来降低)。总而延时,采集延时大概为毫秒级别,如果fps为30,那么一般采集延时会有30毫秒以上的延时,在内存拷贝和颜色转换时,又可能增加若干毫秒的延时。 + + +- **编码延时** + +在把原始画面输入到编码器时,并不会立即输出编码后的数据,特别是在开启B帧时,由于需要参考后面的P帧,那么延时会更大,所以延时敏感的情况下一般不开启B帧,这种情况下编码延时应该是毫秒级别,不是很大。 + + +- **网络上行传输延时** + +编码后的数据,要经过一定的协议打包才能写入socket,然后传输给推流服务器或拉流代理服务器,协议打包会有一定的内存拷贝和计算量,那么会增加延时,不过这个延时很小,基本忽略不计。数据在上层到服务器时,这个延时可大可小,取决于网络质量。 + + +- **服务器转协议延时** + +服务器在收到数据后,要读socket缓存、协议解析、解复用、重新打包等操作,不过总体而言,这个延时比较小,基本没什么影响。有时,服务器为了提高性能,会采取合并写的机制,也就是收到一定量的数据后才会一并转发,这个延时一般为几百毫秒,ZLMediaKit默认300毫秒左右,不过ZLMediaKit默认关闭合并写,也就是这个延时也很小。 + +- **网络下行延时** + +流媒体在把视频数据转发给播放器时,会存在网络发送,这个延时大小取决于网络质量,ZLMediaKit在关闭低延时模式时,还会增加MSG_MORE和关闭TCP_NODELAY导致的延时,不过ZLMediaKit默认开启低延时模式。 + + +- **播放器延时** + +播放器延时主要有网路接收延时、协议解析解复用延时、解码延时、缓存延时、渲染延时组成,这些延时中**缓存延时**最大,因为一般的播放器为了保证在网络抖动情况下视频播放的流畅性,会以增加延时为代价,增加播放缓存,这样在网络变差时,不至于播放缓冲卡顿。而且为了音视频同步,也必须确保一定的缓存量。这种延时一般都是秒级别,一般5秒左右。 + +- **播放器GOP缓存** + +流媒体服务器为了能让播放器立即出画面,往往会缓存最近的一个I帧,这个I帧往后的所有音视频数据被称作为GOP缓存。如果不缓存GOP,那么播放器要等下一个I帧才能解码成功或不花屏,显然这个GOP缓存是不能去掉的。而一般GOP短则1~3秒,长则10几秒,这个跟采集端编码器设置有关,服务器改变不了。但是由于一般的播放器收到缓存后,并不会丢弃过多的画面来确保低延时。况且播放器还希望有一定的缓存来确保播放的流畅性,所以这个GOP缓存将会增大播放器的延时。 + + +- **综合延时** + +以上所有的延时累加,就是你观看到的直观延时,那么你看到的延时很高,能怪是服务器的问题吗?在理想的网络状况下,你观看到的直观延时,其实约等于播放器的播放缓存延时,这个锅得由播放器来背。 + + +## 怎么测试延时 +用vlc等通用播放器测试延时是很不专业的,这些播放器延时最少是秒级别的,为了播放流畅度和音视频同步,这些播放器是不可能给你真实的延时数据。 + +在此,我强烈推荐大家自己写个无缓存的播放器测试延时,但是这显然超过了大部人的能力,所以ZLMediaKit提供了一个简单的播放器测试延时: +[test_player](https://github.com/xiongziliang/ZLMediaKit/blob/master/tests/test_player.cpp) + +什么? 你告诉我你不会编译ZLMediaKit? 那好,退而求其次,我推荐你用ffplay测试: + +```bash +ffplay -i rtmp://xxxxxxx -fflags nobuffer +``` + +如果你不知道ffplay怎么安装,你可以从[这里](http://ffmpeg.org/download.html)下载编译好的. + + + +## 对于延时的更多信息 +[直播延时的本质](https://github.com/xiongziliang/ZLMediaKit/wiki/%E7%9B%B4%E6%92%AD%E5%BB%B6%E6%97%B6%E7%9A%84%E6%9C%AC%E8%B4%A8) +