0

I'm using gstreamer to stream over a custom AppSink that mimics the UdpSink. We are doing it this way so we can incorporate listening on other ports for some metadata. Plus, the stock UdpSink is broken. Anyway, I've successfully had video streamed, but the UDP packets seem to be not packaged correctly. I'm wondering if I have missed some step.

Here's my sending pipeline:

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

streamTee ! sendQueue ! udpSink (our custom one)

the receiving end:

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

Streaming works. But it seems very fragile. Sometimes it just stops. There are lots of artifacts.

So, I tried VLC. I set it up to stream over UDP unicast. It works great. I noticed that VLC sends out the video way different than my pipeline. I used Wireshark to analyze the packets:

Protocols used: VLC: IP:UDP:MP2T (and PET, PMT packets and all other sorts of TS-related stuff)

Mine: IP:UDP:Data

It seems like the pipeline I'm using is just sending raw video over UDP without any error correction. What am I missing? The videos used are h264 or mpeg encoded .mpg files.

I am using gstreamer-java to program the custom UdpSink and UdpSrc elements, but cannot use gstreamer in the console to test since the stock UdpSink plugin is broken. I tried a simple pipeline in a Linux VM, and got a similar bunch of packets as VLC:

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

2
  • In your send pipeline you have a tsdemux whereas in the linux VM you were using mpegtsmux, you should have a mux not a demux on the send side.
    – heavyd
    Feb 28, 2013 at 17:08
  • Oops, yeah, after the tee, that end goes to a videosink. Just edited it.
    – Nick
    Feb 28, 2013 at 19:21

2 Answers 2

1

This is just a thought, I'm not really that familiar with gstreamer, so I don't know how the filesrc works, but I'm assuming that it doesn't understand MPEG-TS. MPEG-TS requires packets to come in on certain boundaries (usually 188 bytes). I would try putting your tee after the demux, then add a mpegtsmux before your udpSink.

I realize this is going to do more work then is really needed (demux just to mux again), but it will insure the packets are aligned correctly. If it works and you need to eliminate the overhead, you may need to look into implementing a smarter file source.

3
  • I think this is a step in the right direction. I tried streaming the file in the Linux VM: filesrc ! queue ! udpsink and it doesn't have the TS protocol. Using filesrc ! mpegtsdemux ! mpegtsmux ! udpsink and it does. Looks like the filesrc is stripping out the TS info.
    – Nick
    Feb 28, 2013 at 22:13
  • Either that or your original file is not really MPEG-TS :)
    – heavyd
    Feb 28, 2013 at 22:20
  • ffmpeg -i file.mpg reports MPEG-TS stream.
    – Nick
    Mar 1, 2013 at 14:44
2

You are close. The filesrc plugin knows nothing about the contents of the file it is reading. GStreamer needs to know that the data is a transport stream in order to stream it properly. While demuxing and the muxing the stream does that job, there's a better way:

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

The plugin tsparse reads the stream and parses out information about the stream. It also identifies it's output as a transport stream. That by itself may be sufficient for your streaming needs as it allows udpsink to know that the data is in 188 byte packets. On the receiving side, tsdemux is needed to parse out the actual video stream. The element "set-timestamps" tells tsparse to set timestamps on the outgoing packets so the udpsink sends each frame on time rather than as fast as it can.

You can also use rtpmp2tpay and rptmp2depay which packetizes the data for udpsink to send. It also sets the encoding-name to MP2T. You can try it both ways.

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .