如何无延迟地流式传输实时视频(ffplay、mplayer)以及 ffplay 可以使用哪种包装器?

Posted

技术标签:

【中文标题】如何无延迟地流式传输实时视频(ffplay、mplayer)以及 ffplay 可以使用哪种包装器?【英文标题】:how to stream live videos with no latency (ffplay, mplayer) and what kind of wrapper could be used with ffplay? 【发布时间】:2014-02-08 10:27:52 【问题描述】:

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

ffplay -fflags nobuffer 
mplayer -benchmark

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

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

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

【问题讨论】:

100 毫秒是一个完全不合理的低延迟量。大多数声卡都无法做到这么少的延迟。您需要专门构建的硬件来实现低延迟,而且它无法通过 Internet 运行。 我的流中没有声音,它被禁用了,无论如何......我在哪里可以买到这样的硬件? 这不是重点……我的意思是 100 毫秒是非常低的延迟,如果您需要这么低的延迟,那么您正在做一些非常专业的事情。我建议您重新审视您的要求,以便获得合理的解决方案。即使是大多数专业人士的东西也没有那么低:vtx.co.uk/product.aspx?id=205 而且,这不是通过互联网。 @Brad VLC 流非常慢,我得到的延迟非常高..这就是我不想使用它的原因 trac.ffmpeg.org/wiki/StreamingGuide 有一个关于延迟的部分.. 【参考方案1】:

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

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

如果您的意思是数字流媒体并且您想要良好的压缩比,即 1080p 通过 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 秒静默期间提高音量。后来,当我们获得更高保真度的音频电路时,广告实际上比节目播放的声音更大,但这只是他们提供与旧电视给广告商相同的影响的方式。

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

这是我在 Ubuntu 18.04 下使用股票 ffmpegmpv 取得的最好成绩。这需要第三代英特尔酷睿处理器或更高版本。有关使用 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 的情况下,这实现了大约 250 毫秒的延迟,这对于通过 wifi 流式传输的节目来说是可以的。 mpv 可以调整口型同步(播放期间 CTRL +-)。它可以用于流式传输桌面鼠标/键盘交互以进行媒体控制,但不能用于实时游戏(请参阅 NVidia Shield、Google Stadia 进行远程游戏)

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

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

【讨论】:

跳过 B 帧以降低延迟是很常见的。较新的系统会跳过 I 和 P 帧,而是使用混合 I+P 格式,其中有一列 I 块会随着时间移动。 没错,但我说如果“你想要任何一种有效的压缩方式”并丢弃 B 和 P 帧基本上会将其转换为 MJPEG 流。此外,我试图描绘所有导致延迟的因素,其中大部分是不可避免的......我也忘了提到显示器本身的输入延迟,这也可能是 OP 高度乐观的一个相当重要的部分“ mplayer 播放帧内刷新帧的 UDP 管道通过 WiFi 轻松击败 100 毫秒。输入延迟 20mS 或更少 压缩、传输、解压 60mS 输出延迟 20mS 或更少 完成。我最初不想发布它,因为它非常小众。 哇,非常感谢,它帮助我更接近我的目标(想想模拟器的游戏流) 我们的帧缓冲区非常小,所以带宽不是真正的问题。 (最多认为 640x480)这是我当前的个人资料:dpaste.com/0Y3T6M2 和当前结果 streamable.com/cftfv 仍然不存在,但更接近。虽然我在播放器方面仍然存在问题,但我希望我能做到。【参考方案2】:

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

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

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

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

【讨论】:

您的面板输入延迟预算非常乐观...并非不可能,但很少有人会遇到低于 9 毫秒的任何情况,典型值要高得多,甚至达到数百毫秒。但我会调整我的答案:-) @Wil,你能给我发一个“数百毫秒”面板的例子吗?我认为大多数面板没有做任何缓冲(或最多一个用于重新缩放的帧),然后会受到帧速率的限制。 电视的 3 岁使用 SmoothVision 就是一个很好的例子。给它一个 24FPS 的源,它将使用 3 个缓冲帧来插入 60FPS(或更高)的输出。这导致仅来自插值引擎的输入延迟为 125 毫秒。 Smoothvision(肥皂剧效果)在大多数电视上默认开启。许多人将电视用作显示器。最近(过去 3 年)游戏玩家的意识正在上升。电视制造商已开始添加低延迟“游戏”模式 (ALLM),有些甚至支持 FreeSync 以获得 随着处理资源变得更便宜和 8 位面板(现在每 RGB 抖动到 10 位和 12 位),可以在更短的时间内执行帧处理,在某些情况下甚至不需要缓冲多于几行光栅,这就是一些带有 FreeSync 的高端面板现在可以在禁用插值的情况下开始声称 这里是面板响应时间列表:displaylag.com/display-database 通过将

以上是关于如何无延迟地流式传输实时视频(ffplay、mplayer)以及 ffplay 可以使用哪种包装器?的主要内容,如果未能解决你的问题,请参考以下文章

从 ios 流式传输实时视频 [关闭]

将实时视频流式传输到浏览器(低延迟)[关闭]

随着时间的推移,使用 java websockets 实时流式传输模拟视频变得无响应

在 ffplay 中获得绿屏:使用 Live555 通过 RTP 流将桌面(DirectX 表面)流式传输为 H264 视频

Raspberry Pi无延迟(<10ms)视频流

IOS 设备的 Wowza 媒体服务器直播视频流延迟?