2016-09-19 2 views
0

Ich sende einen H.264 Bytestream über RTP mit gstreamer.Wie kann rtpjitterbuffer in einem Stream ohne Zeitstempel arbeiten?

# sender 
gst-launch-1.0 filesrc location=my_stream.h264 ! h264parse disable-passthrough=true ! rtph264pay config-interval=10 pt=96 ! udpsink host=localhost port=5004 

Dann empfange ich die Frames, Dekodierung und Anzeige in anderen Gstreamer-Instanz.

# receiver 
gst-launch-1.0 udpsrc port=5004 ! application/x-rtp,payload=96,media="video",encoding-name="H264",clock-rate="90000" ! rtph264depay ! h264parse ! decodebin ! xvimagesink 

Dies funktioniert wie es ist, aber ich möchte ein rtpjitterbuffer um die Wiedergabe zu perfekt glätten, um zu versuchen hinzufügen.

# receiver 
gst-launch-1.0 udpsrc port=5004 ! application/x-rtp,payload=96,media="video",encoding-name="H264",clock-rate="90000" ! rtpjitterbuffer ! rtph264depay ! h264parse ! decodebin ! xvimagesink 

Sobald ich das tue, zeigt der Empfänger nur ein einzelnes Bild an und friert ein.

Wenn ich die .h264-Datei durch eine MP4-Datei ersetzen, funktioniert die Wiedergabe großartig.

Ich nehme an, dass mein h264-Stream nicht die erforderlichen Zeitstempel hat, um den Jitter-Puffer zu aktivieren.

Ich machte leichte Fortschritte, indem ich identity datarate=1000000 hinzufüge. Dadurch kann der Jitterbuffer zwar abgespielt werden, allerdings wird dies mit meiner Framerate verschraubt, da P-Frames weniger Daten als I Frames haben. Natürlich fügt das identity Element die richtigen Zeitstempel hinzu, aber nur mit den falschen Zahlen.

Ist es möglich, Zeitstempel auf dem Absender automatisch zu generieren, indem Sie die "framerate" Caps irgendwo richtig angeben? Bis jetzt haben meine Versuche nicht funktioniert.

+0

mit dem Identity-Element an Ort und Stelle, haben Sie versucht, die "Latenz" auf dem Jitter-Puffer zu "tunen"? –

Antwort

1

Sie haben beantwortet teilweise das Problem bereits:

Wenn ich die .H264 Datei mit einer MP4-Datei zu ersetzen, die Wiedergabe funktioniert super.

Ich nehme an, dass mein h264-Stream nicht die erforderlichen Zeitstempel hat, um den Jitter-Puffer zu aktivieren.

Ihre Absender-Pipeline hat keine verhandelte Frame-Rate, weil Sie einen rohe h264 Stream verwenden, während Sie wirklich ein Container-Format (zum Beispiel MP4), die diese Informationen hat werden sollen. Ohne Zeitstempel udpsink kann nicht gegen Uhr synchronisiert werden, um zu drosseln, also spuckt der Sender Pakete so schnell aus, wie Rohrleitung sie verarbeiten kann. Es ist kein Live Waschbecken.

Wenn Sie jedoch eine rtpjitterbuffer hinzufügen, verhält sich Ihr Receiver wie live Quelle. Es friert ein, weil es versucht, mit der Flut von Paketen fehlerhafter Zeitstempel fertig zu werden. RTP überträgt keine "fehlenden" Zeitstempel nach bestem Wissen, so dass alle Pakete wahrscheinlich den gleichen Zeitstempel haben. Daher rekonstruiert es wahrscheinlich den ersten Rahmen und lässt den Rest als Duplikate fallen.

Ich muss mit user1998586 in dem Sinne einverstanden sein, dass es besser sein sollte für die Pipeline mit einer guten Fehlermeldung in diesem Fall eher zu versauen versuchen sein Bestes.

Ist es möglich, automatisch Zeitstempel auf dem Absender zu generieren, indem Sie die "framerate" Großbuchstaben irgendwo richtig angeben? Bis jetzt haben meine Versuche nicht funktioniert.

Nein. Sie sollten wirklich einen Container verwenden.

In der Theorie könnte jedoch ein au ausgerichteter H264-Stream Zeitstempel sein, aber es gibt keine gstreamer Elemente (die ich kenne), die dies tun.

0

Sie sollten versuchen, den rtpjitterbuffer Modus auf einen anderen Wert zu setzen als den Standard:

mode    : Control the buffering algorithm in use 
         flags: readable, writable 
         Enum "RTPJitterBufferMode" Default: 1, "slave" 
          (0): none    - Only use RTP timestamps 
          (1): slave   - Slave receiver to sender clock 
          (2): buffer   - Do low/high watermark buffering 
          (4): synced   - Synchronized sender and receiver clocks 

wie folgt aus:

... ! rtpjittrbuffer mode=0 ! ... 
+0

Mit einem "identity" -Element in der Senderpipeline hat mode = 0 die Wiedergabe abgehackt. Die Abstimmung der Datenrate hat nicht geholfen. Ohne ein "identity" -Element hatte Modus = 0 keine Wirkung: Die Empfänger-Pipeline friert immer noch auf dem ersten Frame. – matt

0

Ich hatte das gleiche Problem, und die beste Lösung, die ich gefunden war, dem Sender auf der Senderseite Zeitstempel hinzuzufügen, indem der Quelle do-timestamp=1 hinzugefügt wurde.

Ohne Zeitstempel konnte ich rtpjitterbuffer nicht erhalten mehr als einen Rahmen zu übergeben, egal welche Optionen ich es gab.

(Der Fall, mit dem ich es zu tun hatte, war Streaming von raspvid über fdsrc, ich nehme an, filesrc verhält sich ähnlich).

Es ist irgendwie saugen, dass gstreamer so leicht Streams sendet, die gstreamer selbst (und andere Tools) nicht richtig verarbeitet: wenn nicht Zeitstempel gültig ist, dann rtpjitterbuffer sollte damit umgehen; Wenn Timestamps nicht gültig sind, sollte rtph264pay sich weigern, ohne Timestamps zu senden. Ich denke, es war nie als Benutzeroberfläche gedacht ...

Verwandte Themen