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

レシーバー パイプライン:

!/ビン/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 からの遅延の増加は、おそらく --mbtree と --rc-lookahead の導入前に古い x264 バージョンでスタックしていたためです。

Mewikiのこのページでは、レイテンシーをフレーム数で計算する方法と、レイテンシーを減らすために最初に何を無効にする必要があるかについて、以下を確認できます。

x264 の遅延を減らすことは可能ですが、品質が低下します。レイテンシーが必要ない場合は、 --tune zerolatency を設定します。わずかな遅延 (つまり 1 秒未満) を処理できる場合は、これを可能にするようにオプションを調整する価値があります。レイテンシを段階的に削減するために従うことができる一連の手順を次に示します。レイテンシーが十分に低くなったら停止します。

  1. デフォルトから始める
  2. 同期先読みを殺す
  3. rc-lookahead を最大 10 以下に下げます
  4. スレッドをより低い値にドロップします (つまり、12 ではなく 6 とします)。
  5. 切り糸を使用
  6. rc 先読みを無効にする
  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 に答える