通过 gstreamer udpsink 流式传输 h.264 时如何解决图像问题
Posted
技术标签:
【中文标题】通过 gstreamer udpsink 流式传输 h.264 时如何解决图像问题【英文标题】:How to fix image problems when streaming h.264 via gstreamer udpsink 【发布时间】:2019-02-15 09:48:47 【问题描述】:使用 gstreamer,我想以 RTP/h.264 格式将图像从多个 Logitech C920 网络摄像头传输到 Janus 媒体服务器。网络摄像头产生 h.264 编码的视频流,因此我可以将流发送到 UDP 接收器,而无需重新编码数据,只需对其进行负载。
我正在使用 gst-interpipe 插件在不同的网络摄像头之间切换,以便 Janus 接收到的视频流保持不变,但图像来自我选择的任何网络摄像头。
它可以工作,但我遇到了一些破碎帧的问题,其中颜色为灰色且细节模糊不清,主要是在我在网络摄像头源流之间切换后的前 5 到 10 秒。之后,图像会自行校正。
First frames
After 5 - 10 seconds or more
首先我认为这是一个特定于 gst-interpipe 的问题,但我可以通过简单地设置两个管道来重现它 - 一个将视频流发送到 UDP 接收器,一个从 UDP 源读取:
gst-launch-1.0 -v -e v4l2src device=/dev/video0 ! queue ! video/x-
h264,width=1280,height=720,framerate=30/1 ! rtph264pay
config-interval=1 ! udpsink host=127.0.0.1 port=8004
gst-launch-1.0 -v udpsrc port=8004 caps = "application/x-rtp,
media=video, clock-rate=90000, encoding-name=H264, payload=96" !
rtph264depay ! decodebin ! videoconvert ! xvimagesink
注意:如果我将视频流直接发送到 xvimagesink,即不使用 UDP 流时,我不会遇到此问题。
我是否缺少管道中的一些重要参数?这是缓冲问题吗?我真的不知道如何纠正这个问题。 非常感谢任何帮助。
【问题讨论】:
您最终找到解决此问题的方法了吗?我在传输 H264 相机时遇到了类似的问题,并且每隔几秒我就会注意到类似的灰色故障,尤其是当您快速打开灯时。 解决我的问题的方法是使用 uvch264src 而不是 v4l2src 然后设置 initial-bitrate=3000000 average-bitrate=3000000 iframe-period=1000 (您可以尝试根据需要稍微调整这些设置)。此外,我转储了 gst-interpipe 并改用了 input-selector。 【参考方案1】:由于视频流的时间依赖性,您不能只收听视频流并期望它可以立即解码。正确解码只能从随机访问点帧(例如 I 或 IDR 帧)开始。在此之前,您将获得依赖于您尚未收到的视频帧的图像数据 - 因此它们看起来会损坏。一些解码器提供了一些关于在这些情况下做什么的控制。 libavdec_h264
例如有一个 output-corrupt
选项。 (但实际上,对于缺少参考帧的“正确”帧,我不知道它的行为方式)。或者他们可以选择跳过所有内容,直到出现 RAP 帧。这取决于您的特定解码器实现。但请注意,在任何这些选项中,您看到任何图像之前的初始延迟都会增加。
【讨论】:
感谢弗洛里安的解释。因此,当我在上面设置我的 udpsink + udpsrc 示例时遇到的破碎帧是由于缺少数据缓冲造成的 - 这是有道理的。我想我的切换场景是不同的,因为 gst-interpipe 应该通过使用内部缓冲区传输而不需要数据复制来切换管道,包括时间戳同步。切换发生在这里:WebCam source -> Switch -> UDP Sink. 我不知道 gst-interpipe 的详细信息 - 但在切换到 H.264(和其他基于预测的编解码器)时,切换逻辑取决于特定的编解码器。这意味着需要为每个单独的编解码器实现一些特定的东西,这可能非常复杂。一个通用的方法可能总是以你所看到的结尾。以上是关于通过 gstreamer udpsink 流式传输 h.264 时如何解决图像问题的主要内容,如果未能解决你的问题,请参考以下文章