Wie streame ich MPEG-TS über UDP?

Wie streame ich MPEG-TS über UDP?

Ich verwende gstreamer, um über einen benutzerdefinierten AppSink zu streamen, der den UdpSink nachahmt. Wir machen das so, damit wir das Abhören anderer Ports für einige Metadaten integrieren können. Außerdem ist der Standard-UdpSink defekt. Wie auch immer, ich habe erfolgreich Videos gestreamt, aber die UDP-Pakete scheinen nicht richtig verpackt zu sein. Ich frage mich, ob ich einen Schritt übersehen habe.

Hier ist meine Sende-Pipeline:

filesrc (mpeg TS file) ! displayQueue ! streamTee ! tsdemux ! decoder ! videosink

streamTee ! sendQueue ! udpSink (our custom one)

die Empfangsseite:

UdpSrc (custom) ! queue ! mpegtsdemux ! queue ! (mpegdecode || h264decode) ! ... ! videosink

Das Streaming funktioniert. Aber es scheint sehr fragil zu sein. Manchmal hört es einfach auf. Es gibt viele Artefakte.

Also habe ich VLC ausprobiert. Ich habe es so eingerichtet, dass es über UDP Unicast streamt. Es funktioniert super. Mir ist aufgefallen, dass VLC das Video ganz anders sendet als meine Pipeline. Ich habe Wireshark verwendet, um die Pakete zu analysieren:

Verwendete Protokolle: VLC: IP:UDP:MP2T(und PET, PMTPakete und alle anderen Arten von TS-bezogenem Zeug)

Meins:IP:UDP:Data

Es scheint, als würde die von mir verwendete Pipeline nur Rohvideos ohne Fehlerkorrektur über UDP senden. Was übersehe ich? Die verwendeten Videos sind h264- oder mpeg-codierte .mpgDateien.

Ich verwende gstreamer-java, um die benutzerdefinierten UdpSink- und UdpSrc-Elemente zu programmieren, kann gstreamer in der Konsole jedoch nicht zum Testen verwenden, da der BestandDas UdpSink-Plugin ist defekt. Ich habe eine einfache Pipeline in einer Linux-VM ausprobiert und eine ähnliche Menge an Paketen wie VLC erhalten:

gst-launch-0.10 -v videotestsrc ! mpeg2enc ! mpegtsmux ! udpsink host=192.168.2.100 port=1234

Antwort1

Das ist nur so eine Idee. Ich kenne mich mit Gstreamer nicht so gut aus, daher weiß ich nicht, wie es filesrcfunktioniert, aber ich nehme an, dass es MPEG-TS nicht versteht. MPEG-TS erfordert, dass Pakete innerhalb bestimmter Grenzen eingehen (normalerweise 188 Bytes). Ich würde versuchen, Ihr T-Shirt nach dem Demux zu platzieren und dann ein mpegtsmux vor Ihrem hinzuzufügen udpSink.

Mir ist klar, dass das mehr Arbeit macht, als wirklich nötig ist (Demuxen, nur um wieder zu muxen), aber es stellt sicher, dass die Pakete richtig ausgerichtet sind. Wenn es funktioniert und Sie den Overhead eliminieren müssen, müssen Sie möglicherweise eine intelligentere Dateiquelle implementieren.

Antwort2

Sie sind nah dran. Das filesrc-Plugin weiß nichts über den Inhalt der Datei, die es liest. GStreamer muss wissen, dass die Daten ein Transportstrom sind, um sie richtig streamen zu können. Während das Demuxen und Muxen des Stroms diese Aufgabe erledigt, gibt es einen besseren Weg:

Source: gst-launch -v filesrc location=myvideo.ts ! tsparse set-timestamps=true ! udpsink host=192.168.2.100 port=1234

Dest:   gst-launch udpsrc caps="video/mpegts, systemstream=(boolean)true, packetsize=(int)188" port=1234 ! tsdemux ! (video decoder) ! autovideosink

Das Plugin tsparse liest den Stream und analysiert Informationen über den Stream. Es identifiziert seine Ausgabe auch als Transportstream. Das allein kann für Ihre Streaming-Anforderungen ausreichend sein, da udpsink dadurch erkennt, dass die Daten in 188-Byte-Paketen vorliegen. Auf der Empfangsseite wird tsdemux benötigt, um den eigentlichen Videostream zu analysieren. Das Element „set-timestamps“ weist tsparse an, Zeitstempel auf die ausgehenden Pakete zu setzen, damit udpsink jedes Frame pünktlich und nicht so schnell wie möglich sendet.

Sie können auch rtpmp2tpay und rptmp2depay verwenden, die die Daten paketieren, damit sie von udpsink gesendet werden können. Außerdem wird der Kodierungsname auf MP2T gesetzt. Sie können es auf beide Arten versuchen.

Source: gst-launch -v filesrc location=myvideo.ts ! tsparse set-timestamps=true ! rtpmp2tpay ! udpsink host=192.168.2.100 port=1234

Dest:   gst-launch udpsrc caps="application/x-rtp, systemstream=(boolean)true, packetsize=(int)188" port=1234 ! rtpmp2tdepay ! tsdemux ! (video decoder) ! autovideosink

verwandte Informationen