1

当我尝试创建使用 H264 传输视频的管道时,我得到了一些巨大的延迟,将视频从我的机器传输到......我的机器长达 10 秒!这对我的目标来说是不可接受的,我想咨询 StackOverflow 我(或其他人)做错了什么。

我从 gstrtpbin 文档页面获取管道并稍微修改它们以使用 Speex:

这是发送方管道:#!/bin/sh

gst-launch -v gstrtpbin name=rtpbin \
        v4l2src ! ffmpegcolorspace ! ffenc_h263 ! rtph263ppay ! rtpbin.send_rtp_sink_0 \
                  rtpbin.send_rtp_src_0 ! udpsink host=127.0.0.1 port=5000                            \
                  rtpbin.send_rtcp_src_0 ! udpsink host=127.0.0.1 port=5001 sync=false async=false    \
                  udpsrc port=5005 ! rtpbin.recv_rtcp_sink_0                           \
        pulsesrc ! audioconvert ! audioresample  ! audio/x-raw-int,rate=16000 !    \
                  speexenc bitrate=16000 ! rtpspeexpay ! rtpbin.send_rtp_sink_1                   \
                  rtpbin.send_rtp_src_1 ! udpsink host=127.0.0.1 port=5002                            \
                  rtpbin.send_rtcp_src_1 ! udpsink host=127.0.0.1 port=5003 sync=false async=false    \
                  udpsrc port=5007 ! rtpbin.recv_rtcp_sink_1

接收器管道:

!/bin/sh

gst-launch -v\
    gstrtpbin name=rtpbin                                          \
    udpsrc caps="application/x-rtp,media=(string)video, clock-rate=(int)90000, encoding-name=(string)H263-1998" \
            port=5000 ! rtpbin.recv_rtp_sink_0                                \
        rtpbin. ! rtph263pdepay ! ffdec_h263 ! xvimagesink                    \
     udpsrc port=5001 ! rtpbin.recv_rtcp_sink_0                               \
     rtpbin.send_rtcp_src_0 ! udpsink port=5005 sync=false async=false        \
    udpsrc caps="application/x-rtp,media=(string)audio, clock-rate=(int)16000, encoding-name=(string)SPEEX, encoding-params=(string)1, payload=(int)110" \
            port=5002 ! rtpbin.recv_rtp_sink_1                                \
        rtpbin. ! rtpspeexdepay ! speexdec ! audioresample ! audioconvert ! alsasink \
     udpsrc port=5003 ! rtpbin.recv_rtcp_sink_1                               \
     rtpbin.send_rtcp_src_1 ! udpsink host=127.0.0.1 port=5007 sync=false async=false

这些管道,H263 和 Speex 的组合,工作得很好。我在相机和麦克风附近打了个响指,然后我同时看到运动和听到声音。

然后我更改了管道以沿视频路径使用 H264。

发件人变成:#!/bin/sh

gst-launch -v gstrtpbin name=rtpbin \
        v4l2src ! ffmpegcolorspace ! x264enc bitrate=300 ! rtph264pay ! rtpbin.send_rtp_sink_0 \
                  rtpbin.send_rtp_src_0 ! udpsink host=127.0.0.1 port=5000                            \
                  rtpbin.send_rtcp_src_0 ! udpsink host=127.0.0.1 port=5001 sync=false async=false    \
                  udpsrc port=5005 ! rtpbin.recv_rtcp_sink_0                           \
        pulsesrc ! audioconvert ! audioresample  ! audio/x-raw-int,rate=16000 !    \
                  speexenc bitrate=16000 ! rtpspeexpay ! rtpbin.send_rtp_sink_1                   \
                  rtpbin.send_rtp_src_1 ! udpsink host=127.0.0.1 port=5002                            \
                  rtpbin.send_rtcp_src_1 ! udpsink host=127.0.0.1 port=5003 sync=false async=false    \
                  udpsrc port=5007 ! rtpbin.recv_rtcp_sink_1

接收器变为:#!/bin/sh

gst-launch -v\
    gstrtpbin name=rtpbin                                          \
    udpsrc caps="application/x-rtp,media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264" \
            port=5000 ! rtpbin.recv_rtp_sink_0                                \
        rtpbin. ! rtph264depay ! ffdec_h264 ! xvimagesink                    \
     udpsrc port=5001 ! rtpbin.recv_rtcp_sink_0                               \
     rtpbin.send_rtcp_src_0 ! udpsink port=5005 sync=false async=false        \
    udpsrc caps="application/x-rtp,media=(string)audio, clock-rate=(int)16000, encoding-name=(string)SPEEX, encoding-params=(string)1, payload=(int)110" \
            port=5002 ! rtpbin.recv_rtp_sink_1                                \
        rtpbin. ! rtpspeexdepay ! speexdec ! audioresample ! audioconvert ! alsasink \
     udpsrc port=5003 ! rtpbin.recv_rtcp_sink_1                               \
     rtpbin.send_rtcp_src_1 ! udpsink host=127.0.0.1 port=5007 sync=false async=false

这就是在 Ubuntu 10.04 下发生的情况。我没有注意到 Ubuntu 9.04 上有如此巨大的延迟——延迟在 2-3 秒之间,AFAIR。

4

3 回答 3

2

在 Freenode 上 #x264 中“Sharktooth”的帮助下,我发现 gst-plugins-ugly 的 git 版本支持“零延迟”预设。

http://cgit.freedesktop.org/gstreamer/gst-plugins-ugly

我调整了您的示例以设置“x264enc pass=qual quantizer=20 tune=zerolatency”,延迟似乎保持在 0.7 - 0.9 秒。我不知道如何降低它。

于 2010-08-30T03:53:52.630 回答
1

里面有缓冲,很可能是编码器。它必须处理的数据越多,它可以实现的压缩就越有效。我不熟悉那个编码器,但通常有一个缓冲量的设置。

于 2010-05-23T22:01:39.257 回答
1

默认情况下,x264 会缓冲输入以使用更多数据。Ubuntu 10.04 延迟的增加很可能是因为它停留在旧的 x264 版本,在引入 --mbtree 和 --rc-lookahead 之前。

Mewiki 的此页面中,您可以了解如何计算延迟、帧数以及以下内容,以及应首先禁用哪些内容以减少延迟:

减少 x264 的延迟是可能的,但会降低质量。如果您不想要延迟,请设置 --tune zerolatency。如果您可以处理较小的延迟(即小于 1 秒),那么非常值得调整选项以允许这样做。以下是您可以遵循的一系列步骤,以逐步减少延迟。当您的延迟足够低时停止:

  1. 从默认值开始
  2. 杀死同步前瞻
  3. 将 rc-lookahead 降到不少于 ~10
  4. 将线程降低到较低的值(即说 6 而不是 12)
  5. 使用切片线程
  6. 禁用 rc-lookahead
  7. 禁用 b 帧
  8. 现在你在 --tune zerolatency

因此,您应该首先尝试在命令行中添加类似

sync-lookahead=0, rc-lookahead=10(我不确定应用程序中命令行的格式)

这应该以较低的压缩效率成本减少大部分延迟。如果您有许多内核(例如,具有 HT 的四核),那么可能也值得做第 4 项,但需要一点速度成本。

根据 Sharktooth 的建议,使用 tune=zerolatency,如果这还不够的话。

有关该主题的更多信息:http: //x264dev.multimedia.cx/archives/249

于 2012-01-24T00:35:23.747 回答