Warum Verwendung von H264 in Sender / Empfänger-Pipelines einführen einfach riesig Verzögerung?

StackOverflow https://stackoverflow.com/questions/2893407

Frage

Wenn ich versuche Pipeline zu erstellen, dass Anwendungen H264 zu übertragen Video, ich eine enorme Verzögerung erhalten, bis zu 10 Sekunden zu übertragen Video von meinem Rechner ... meine Maschine! Das ist nicht akzeptabel für meine Ziele, und ich möchte über Stackoverflow konsultieren, was ich (oder jemand anderes) falsch machen.

Ich habe Pipelines von gstrtpbin Dokumentationsseite und leicht modifiziert sie Speex zu verwenden:

Dies ist Absender-Pipeline: #! / 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

Receiver-Pipeline:

! / 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

Diese Pipelines, eine Kombination aus H263 und Speex, Arbeit fein genug. Schnappe ich mir die Finger in der Nähe von Kamera und micropohne und dann sehe ich Bewegung und hören Klang zugleich.

Dann änderte es Pipelines H264 verwenden entlang des Videopfades.

Der Absender wird: #! / 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

Und Empfänger wird: #! / 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

Dies ist, was unter Ubuntu 10.04 passieren. Ich habe nicht so große Verzögerungen auf Ubuntu 9.04 bemerkt -. Die Verzögerungen dort war Bereich 2-3 Sekunden, AFAIR

War es hilfreich?

Lösung

Mit etwas Hilfe von "Sharktooth" in # x264 auf Freenode, fand ich heraus, dass die git-Version von gst-plugins-ugly unterstützt die "Zero-Latency" voreingestellt.

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

gezwickt ich dein Beispiel, um „x264enc pass = qual Quantisierer = 20 tune = ZeroLatency“ und die Latenz scheint bei 0,7 zu ??bleiben - 0.9 Sekunden. Ich kann nicht herausfinden, wie es noch tiefer zu erhalten.

Andere Tipps

Etwas dort puffert, höchstwahrscheinlich den Encoder. Je mehr Daten, die sie zur Arbeit haben mit, desto effektiver Kompression kann es erreichen. Ich bin nicht vertraut mit dem Encoder, aber es ist in der Regel eine Einstellung für die Menge an Pufferung.

x264 standardmäßig puffert die Eingabe mit mehr Daten zu Arbeit haben. Der Anstieg der Verzögerung von Ubuntu 10.04 ist höchstwahrscheinlich, weil es an einer alten x264 Version stecken geblieben war, vor der Einführung von --mbtree und --rc-Look-Ahead.

Diese Seite von Mewiki können Sie sehen, wie die Latenzzeit zu berechnen, in Nummer der Rahmen und die folgenden, auf was sollte man deaktivieren Sie bitte zuerst die Latenz zu reduzieren:

Latenz des x264 Reduzierung ist möglich, aber reduziert Qualität. Wenn Sie keine Latenz möchten, setzen Sie --tune ZeroLatency. Wenn Sie eine kleine Latenz (dh unter 1 Sekunde) verarbeiten kann, ist es lohnt sich Tuning die Möglichkeiten, dies zu ermöglichen. Hier ist eine Reihe von Schritten, die Sie schrittweise folgen können, um die Latenz reduzieren. Stop, wenn die Latenz niedrig genug ist:

  1. Start mit Standardwerten
  2. Kill-Sync-Look-Ahead
  3. Drop rc-Look-Ahead auf nicht weniger als ~ 10
  4. Drop Threads auf einen niedrigeren Wert (d.h. sagen 6 statt 12)
  5. Verwenden geschnittenes Gewinde
  6. Deaktivieren rc-Look-Ahead
  7. Deaktivieren B-Frames
  8. Jetzt sind Sie bei --tune ZeroLatency

Also, sollten Sie zunächst versuchen, auf Ihre Befehlszeile hinzuzufügen, so etwas wie

Sync-Look-Ahead-= 0, rc-Look-Ahead = 10 (Ich bin nicht sicher, ob die Formatierung der Befehlszeile in Ihrer Anwendung)

Dies sollte die meisten der Latenz bei einer niedrigen Komprimierungseffizienz Kosten rasieren. Wenn Sie viele Kerne (einen Quad-Core mit HT, zum Beispiel) haben, ist es auch wert do Nummer 4. bei einer kleinen Geschwindigkeit Kosten sein kann.

Mit tune = ZeroLatency, wie pro Sharktooth Beratung, wenn dies noch nicht genug.

Mehr zum Thema: http://x264dev.multimedia.cx/archives/249

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top