当我尝试创建使用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
接收器管道:
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的组合,运行得很好。我用手指靠近相机和micropohne,然后我看到了移动并同时听到了声音。
然后我改变了管道以沿着视频路径使用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。
答案 0 :(得分: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秒。我无法弄清楚如何降低它。
答案 1 :(得分:1)
其中有东西是缓冲,很可能是编码器。它必须处理的数据越多,它可以实现的压缩效率就越高。我不熟悉那个编码器,但通常有缓冲量的设置。
答案 2 :(得分:1)
默认情况下,x264缓冲输入以使更多数据可供使用。 Ubuntu 10.04的延迟增加很可能是因为它在引入-mbtree和--rc-lookahead之前停留在旧的x264版本上。
在This page of Mewiki中,您可以看到如何计算延迟,帧数和以下内容,以及应首先禁用的内容,以减少延迟:
可以降低x264的延迟,但会降低质量。如果您不想延迟,请设置--tune zerolatency。如果你可以处理一个小的延迟(即不到1秒),那么调整选项以允许这一点是非常值得的。以下是您可以遵循的一系列步骤,以逐步减少延迟。当您的延迟足够低时停止:
- 以默认值开头
- Kill sync-lookahead
- 将rc-lookahead降至不低于~10
- 将线程拖放到较低的值(即说6而不是12)
- 使用切片线程
- 禁用rc-lookahead
- 禁用b帧
- 现在你正处于--tune zerolatency
醇>
因此,您应该首先尝试添加类似
的命令行sync-lookahead = 0,rc-lookahead = 10(我不确定应用程序中命令行的格式化)
这应该以低压缩效率成本削减大部分延迟。如果你有很多核心(例如一个带有HT的四核),它也可能值得做4号,速度很快。
根据Sharktooth的建议,使用tune = zerolatency,如果这还不够。
有关该主题的更多信息:http://x264dev.multimedia.cx/archives/249