web-dev-qa-db-ja.com

ストリーミングRTP / RTSP:同期/タイムスタンプの問題

RTSP経由でH.264ビデオをストリーミングするのに問題があります。目標は、カメラ画像をRTSPクライアント(最終的にはブラウザプラグイン)にライブストリーミングすることです。これは、1つの問題を除いて、これまでのところかなりうまく機能しています。ビデオは起動時に遅れ、数秒ごとに途切れ、最大4秒の遅延があります。これは悪いです。

私たちのセットアップは、x264(ゼロレイテンシーと超高速)でエンコードし、ffmpeg0.6.5のlibavformatを使用してRTSP/RTPにパックすることです。テストのために、RTSPサーバーに接続するときに、gst-launchを備えたGStreamerパイプラインでストリームを受信して​​います。 ただし、RTPのみを使用して別のGStreamerインスタンスから直接ストリーミングする場合、同じ問題を再現することができました。

送信機:

gst-launch videotestsrc ! x264enc tune=zerolatency ! rtph264pay ! udpsink Host=10.89.6.3

受信機:

gst-launch udpsrc ! application/x-rtp,payload=96 ! rtph264depay ! decodebin ! xvimagesink

これらの両方を同じマシンで実行することもできます。送信側でホストを127.0.0.1に変更するだけです。受信側では、コンソールに繰り返し警告が表示されるとともに、途切れ途切れで一般的にパフォーマンスの低いビデオに気付くはずです。

WARNING: from element /GstPipeline:pipeline0/GstXvImageSink:xvimagesink0: A lot of buffers are being dropped.
Additional debug info:
gstbasesink.c(2875): gst_base_sink_is_too_late (): /GstPipeline:pipeline0/GstXvImageSink:xvimagesink0:
There may be a timestamping problem, or this computer is too slow.

私がインターネット全体で見た一般的に提案されている「修正」の1つは、xvimagesinkでsync=falseを使用することです。

gst-launch udpsrc ! application/x-rtp,payload=96 ! rtph264depay ! decodebin ! xvimagesink sync=false

その後、カメラソフトウェアでテストした場合でも、ビデオはほぼゼロの遅延で再生されます。これはテストには役立ちますが、Totem、VLC、またはそれらのブラウザープラグインの埋め込みでは機能しないため、展開にはあまり役立ちません。

ソースで問題を解決しようと思います。 x264によるH.264ストリームまたはおそらくRTPペイロード)に何らかのタイムスタンプ情報が欠落しているのではないかと疑っています。を変更する方法はありますか? sourcegstパイプラインを使用してnotレシーバーでsync=falseを使用する必要がありますか?

それが不可能な場合、ストリームを同期しないようにクライアントに(SDPまたはその他の方法で)伝えるにはどうすればよいですか?最終的には、ある種のVLCプラグインを使用してこれをブラウザーに埋め込むので、そこで機能するソリューションはさらに優れています。

13
Jacob Peddicord

ソースgstパイプラインに「sync = false」を追加できます。 Ubuntu 12.04では、ラグとエラーメッセージが削除されているようです。

ソースで使用したコマンドは次のとおりです。

gst-launch videotestsrc ! x264enc tune=zerolatency ! rtph264pay ! udpsink Host=127.0.0.1 sync=false

これが私がレシーバーで使用したものです:

gst-launch udpsrc ! application/x-rtp,payload=96 ! rtph264depay ! decodebin ! xvimagesink

残念ながら、それが機能する理由や、「sync = false」プロパティが(ソースパイプライン上で)どのコンポーネントに属しているのかさえわかりません。

8
ctrlc-root

Root.ctrlcが投稿したように、sync = FALSEを使用できます。ただし、送信者側でCPU使用率が大幅に増加していることに気付く場合があります。その理由は、sync = FALSEがシンクに、バッファを受信するとすぐにバッファをプッシュアウトするように指示するためです。シンクはパイプライン全体を駆動します。したがって、sync = FALSEを指定すると、パイプラインはビデオをエンコードし、UDPにできるだけ速くプッシュします。 100%CPUを使用します。

必要なのはgstrtpjitterbufferです。また、ここで壊れているタイムスタンプも処理します。

送信者の例:

gst-launch-0.10 -v videotestsrc ! videorate ! video/x-raw-yuv, framerate=30/1 ! ffmpegcolorspace ! x264enc ! rtph264pay ! udpsink port=50000 Host=<sender IP>

受信者の例:

gst-launch-0.10 udpsrc port=50000 caps="application/x-rtp, media=(string)video, clock-rate=(int)90000 , encoding-name=(string)H264 , payload=(int)96" ! gstrtpjitterbuffer ! rtph264depay ! ffdec_h264 ! ffmpegcolorspace ! videoscale ! "video/x-raw-yuv, width=320, height=240" ! xvimagesink
10
dv_

これがどれほど真実かはわかりませんが、バッテリー充電器をラップトップに接続せずにパイプラインを実行すると、同じ警告が表示され、電源を接続すると、動作したと信じてください。古いCMOSバッテリーが、クロック生成を担当しているため、正常に機能していないことが原因である可能性があります。

0
Sravan U