18

我一直在测试使用不同的播放器播放多个直播流,因为我想获得最低的延迟值。我尝试了 gstreamer 播放器 (gst-launch-0.01)、mplayer、totem 和 ffmpeg 播放器 (ffplay)。我使用了不同的配置值来获得它们中的每一个的最低延迟,例如:

ffplay -fflags nobuffer 
mplayer -benchmark

我流式传输的协议是 udp,与 mplayer 或 gst-launch 相比,我使用 ffplay 获得了更好的价值。老实说,我不知道我需要什么样的配置才能让 gstreamer 获得更低的延迟。现在,我需要的是两件事:

  1. 我想知道是否有人对以低于 100 毫秒的低延迟流式传输直播流有更好的建议。我现在的时间超过了 100 毫秒,这对我来说并不是很有效。

  2. 由于我目前正在使用 ffplay,因为它是迄今为止最好的。我想做一个简单的 gui,带有播放和录制按钮和 3 个屏幕以从不同的视频服务器流式传输,我只是不知道使用哪种包装器(应该非常快)!

4

2 回答 2

15

好吧,对于非常低延迟的流媒体场景,您可以尝试 NTSC。理想情况下,它的延迟可以低于 63us(微秒)。

对于质量接近 NTSC 和 40ms 延迟预算的数字流,请参阅 rsaxvc 在 120hz 的答案。如果您需要无线流式传输,这是我见过的最好的低延迟选项,而且经过深思熟虑,分辨率将随硬件能力而扩展。

如果您的意思是数字流媒体并且您想要良好的压缩比,即 1080p over wifi,那么如果您希望今天的商品硬件延迟小于 100 毫秒,那么您就不走运了,因为为了让压缩算法提供良好的压缩比,它需要很多上下文。例如,Mpeg 1 在 ipbbpbbpbbpb GOP(图片组)排列中使用了 12 帧,其中 i 是一个“帧内”帧,实际上是一个 jpeg 静止图像,ap 是一个预测帧,它编码 i 和 p 帧之间的一些运动,以及 b 帧编码一些预测效果不佳的现场修正。无论如何,即使在 60fps 的情况下,12 帧仍然是 200 毫秒,所以这只是 200 毫秒来捕获数据,然后是一些时间来编码它,然后是一些时间来传输它,然后是一些时间来解码它,然后需要一些时间来缓冲音频,以便在 CPU 向 DMA 内存区域发送新块时声卡不会耗尽数据,同时需要排队 2-3 帧视频发送到视频显示器,以防止数字显示器撕裂。所以实际上至少有 15 帧或 250 毫秒,加上传输中产生的延迟。NTSC 没有这样的延迟,因为它是模拟传输的,唯一的“压缩”是两个偷偷摸摸的技巧:隔行扫描,每次只有一半的帧作为交替行传输,即使在一个帧上,在下一帧奇数,然后第二个技巧是通过使用 3 个黑白像素及其相位识别来确定显示什么颜色的颜色空间压缩,因此颜色以亮度 (luma) 信号带宽的 1/3 传输。酷吧?而且我猜你可以说音频也有一种“压缩”,因为自动增益控制可以用来使 20dB 的模拟音频信号看起来提供更接近 60dB 的体验,方法是将我们的耳朵从我们的头上炸开由于 AGC 在节目和广告之间的 2-3 秒静默期间提高音量。后来,当我们获得更高保真度的音频电路时,广告实际上比节目播放的声音更大,但这只是他们提供与旧电视给广告商相同的影响的方式。以及自动增益控制可用于使 20dB 模拟音频信号看起来提供更接近 60dB 的体验,因为 AGC 在 2-3 秒内提高音量节目和广告之间的沉默。后来,当我们获得更高保真度的音频电路时,广告实际上比节目播放的声音更大,但这只是他们提供与旧电视给广告商相同的影响的方式。以及自动增益控制可用于使 20dB 模拟音频信号看起来提供更接近 60dB 的体验,因为 AGC 在 2-3 秒内提高音量节目和广告之间的沉默。后来,当我们获得更高保真度的音频电路时,广告实际上比节目播放的声音更大,但这只是他们提供与旧电视给广告商相同的影响的方式。

Nostalgia(tm)带给您的这条记忆之路。购买 Nostalgia 品牌香皂!;-)

这是我在 Ubuntu 18.04 下使用 stockffmpegmpv. 这需要第三代英特尔酷睿处理器或更高版本。有关使用 NVidia 硬件编码的说明,请参阅 ffmpeg 站点。

ffmpeg -f x11grab -s 1920x1080 -framerate 60 -i :0.0 \
  -vaapi_device /dev/dri/renderD128 \
  -vf 'format=nv12,hwupload,scale_vaapi=w=1920:h=1080' \
  -c:v h264_vaapi -qp:v 26 -bf 0 -tune zerolatency -f mpegts \
  udp://$HOST_IP:12345

然后在媒体框上:

mpv --no-cache --untimed --no-demuxer-thread --video-sync=audio \
  --vd-lavc-threads=1 udp://$HOST_IP:12345 

对于 1080p@60hz 在大约 3Mbps 的情况下,这实现了大约 250ms 的延迟,这对于通过 wifi 流式传输的节目来说是可以的。mpv可以调整口型同步(播放期间 CTRL +-)。对于媒体控制的流式桌面鼠标/键盘交互是可以容忍的,但它不能用于实时游戏(请参阅 NVidia Shield、Google Stadia 进行远程游戏)

另一件事:LCD/OLED/等离子电视和一些 LCD 显示器具有帧插值,通过去隔行或通过 SmoothVision(“肥皂剧效果”)。此处理增加了输入延迟。您通常可以在显示器的设置中将其关闭,或者如果显示器有这样标记的端口,则可以通过连接到“PC”或“Console”输入端口来关闭它。有些显示器可以重命名输入。在这种情况下,选择“PC”或“Console”可能会减少输入延迟,但由于关闭了额外的处理,您可能会注意到色带、闪烁等。

CRT 显示器实际上具有零输入延迟。但是你会被电离辐射烤焦。选择你的毒药。

于 2015-06-10T10:56:09.480 回答
15

传统媒体播放器(如 VLC、ffmpeg 以及某种程度上的 mplayer)的问题在于,它们会尝试以一致的帧速率播放,这需要一些缓冲,从而消除了延迟目标。另一种方法是尽可能快地渲染传入的视频,而不关心其他任何事情。

@genpfault和我制作了一个自定义 UDP 协议,计划用于飞行遥控车和四轮摩托车。它的目标是低延迟,但牺牲了几乎所有其他东西(分辨率、比特率、数据包率、压缩效率)。在较小的分辨率下,我们让它运行超过 115200 波特的 UART 和 XBEE,但在这些限制下的视频并没有我们希望的那么有用。今天我在笔记本电脑(英特尔 i5-2540M)上运行 320x240 配置进行测试,因为我不再拥有原始设置。

您需要计划您的延迟预算,这是我花费的地方:

  1. 采集 - 我们选择了 125FPS PS3 Eye 相机。所以我们这里的延迟最多是 8 毫秒多一点。应避免使用板载压缩(h264 或 MJPEG)的“更智能”相机。此外,如果您的相机有任何类型的自动曝光时间,您需要禁用它以将其锁定在最快的帧速率,或提供充足的照明(今天,由于 AE,我的内置网络摄像头只能做 8 FPS)。
  2. 转换 - 如果可能,让相机以您可以直接压缩的格式发出帧(通常是 YUV 格式,Eye 本机支持)。然后你可以跳过这一步,但我在这里花费了 0.1mS。
  3. 编码 - 我们使用了经过特殊调整的 H.264。它需要大约 2.5 毫秒,并且不需要对未来的帧进行缓冲,但会以压缩比为代价。
  4. 传输 - 我们使用 UDP over WiFi,在没有一堆其他无线电干扰的情况下正常工作时 <5mS。
  5. 解码 - 这在很大程度上受到接收器 CPU 的限制。编码器可以通过发送可多线程解码的工作来提供帮助。这通常比编码更快。今天约 1.5 毫秒。
  6. 转换 - 您的解码器可能会为您执行此步骤,但通常编码器/解码器使用 YUV,显示器使用 RGB,并且必须有人在它们之间进行转换。在我的笔记本电脑上为 0.1 毫秒。
  7. 显示 - 如果没有 VSYNC,60 FPS 显示器的延迟高达 ~17 毫秒,加上一些 LCD 延迟,可能是 6 毫秒?这真的取决于显示器,我不确定这台笔记本电脑有哪个面板。

总计:40.2mS。

编码:

当时,X264 是我们能找到的最好的 H264-AnnexB 编码器。我们必须控制比特率、最大切片大小、vbv-bufsize、vbv-maxrate。从“superfast”和“zerolatency”的默认值开始,这将禁用 B 帧。

此外,帧内刷新是必须的!实际上,这允许切分正常的“I”帧并将其与以下 P 帧混合。如果没有这个,您将在比特率需求中出现“气泡”,这将暂时阻塞您的传输,增加延迟。

编码-传输-规划:

编码器经过调整以生成 UDP 大小的 H264 NALU。这样,当一个 UDP 数据包被丢弃时,整个 H264 NALU 被丢弃,我们不必重新同步,解码器只是有点......打嗝......并继续出现一些图形损坏。

最终结果 320x240

在此处输入图像描述

它......比我用手机指向我的笔记本电脑的相机可靠地测量要快。压缩比 320x240x2B = 150kB/帧,压缩到略高于 3kB/帧。

于 2018-07-07T06:59:46.697 回答