送信者/レシーバーパイプラインでH264を使用すると、なぜ大きな遅延が発生するのですか?
質問
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秒の範囲であったことです。
解決
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秒にとどまるようです。私はそれをより低くする方法を理解することができません。
他のヒント
そこにあるものはバッファリング、おそらくエンコーダーです。より多くのデータを使用する必要があるほど、より効果的な圧縮を達成できます。私はそのエンコーダーに精通していませんが、通常、バッファリングの量の設定があります。
X264デフォルトでは、入力をバッファリングして、より多くのデータを使用するためのより多くのデータを用意します。 Ubuntu 10.04からの遅延の増加は、おそらく、-Mbtreeと-Rc-Lookaheadが導入される前に、古いX264バージョンで立ち往生していたためです。
の Mewikiのこのページ レイテンシの数、フレームの数、および以下の計算方法を確認することができます。
X264のレイテンシを減らすことは可能ですが、品質を低下させます。レイテンシが必要ない場合は、設定します - ゼロレーティを調整します。小さな待ち時間(つまり、1秒未満)を処理できる場合、これを許可するオプションを調整する価値があります。以下は、レイテンシを徐々に減らすために従うことができる一連のステップです。レイテンシが十分に低いときに停止します:
- デフォルトから始めます
- Sync-lookaheadを殺します
- RC-lookaheadを10以上にドロップします
- スレッドを低い値にドロップします(つまり、12ではなく6と言います)
- スライスしたスレッドを使用します
- RC-lookaheadを無効にします
- Bフレームを無効にします
- 今、あなたは - ゼロレーティを調整します
だから、あなたは最初にあなたのコマンドラインに次のようなものを追加しようとする必要があります
sync-lookahead = 0、rc-lookahead = 10(アプリケーションのコマンドラインのフォーマットがわからない)
これは、低い圧縮効率コストで、ほとんどのレイテンシを剃るはずです。多くのコア(たとえば、HTのQuadcore)がある場合、それはわずかな速度で、番号4の価値があるかもしれません。
Sharktoothのアドバイスによると、これで十分ではない場合、tune = Zerolatencyを使用してください。