13

I'm having some trouble streaming H.264 video over RTSP. The goal is to live-stream a camera image to an RTSP client (ideally a browser plugin in the end). This has been working pretty well so far, except for one problem: the video will lag on startup, stutter every few seconds, and has a ~4-second delay. This is bad.

Our setup is to encode with x264 (w/ zerolatency & ultrafast) and packed into RTSP/RTP with libavformat from ffmpeg 0.6.5. For testing, I'm receiving the stream with a GStreamer pipeline with gst-launch when connecting to an RTSP server. However, I've been able to reproduce the same issue when streaming straight from another GStreamer instance with just RTP.

Sending machine:

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

Receiving machine:

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

You can also run these both on the same machine, just change the host to 127.0.0.1 on the sender. On the receiving end, you should notice stuttering and generally poor-performing video, along with repeated warnings on the console:

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.

One commonly-suggested "fix" that I've seen all over the Internet is to use sync=false with xvimagesink:

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

The video will then play back with near-zero latency, even when tested with our camera software. This is useful for testing, but is not very useful for deployment, as it won't work with Totem, VLC, or their browser plugin embeds.

I'd like to try to solve the issue at the source; I'm suspicious that there's some sort of timestamp info missing on the H.264 stream by x264 or perhaps on the RTP payloads. Is there any way to modify the source gst pipeline so that I do not need to use sync=false on the receiver?

If that's not possible, how can I tell clients (via SDP or otherwise) that the stream should not be synchronized? Ultimately, we'd embed this in the browser using a VLC plugin of sorts, so a solution that would work there would be even better.

3 Answers 3

11

As root.ctrlc posted, you can use sync=FALSE. However, you might notice a huge increase in CPU usage on the sender's end. The reason is that sync=FALSE tells the sink to just push out buffers as soon as it receives them. The sink drives the whole pipeline. Therefore, sync=FALSE will cause the pipeline to encode video and push it to UDP as fast as possible; it will use 100% CPU.

What you need is the gstrtpjitterbuffer. It also takes care of the timestamps, which are broken here.

Example sender:

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

Example receiver:

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
4
  • +1 but how do you use the gstrtpjitterbuffer when we use gst-launch-0.10 -v gstrtpbin name=rtpbin latency=40 udpsrc caps=".." port=50000, can you please share the receiver part while using gstrtpbin used?
    – user285594
    Nov 18, 2013 at 17:19
  • The gsrtpbin includes a gstrtpjitterbuffer already. As for the command line, I will try to get back to you. Currently I cannot try it out, since I do not have GStreamer 0.10 installed here. (BTW you really should move to 1.0 , this comes strongly recommended.)
    – dv_
    Feb 18, 2014 at 13:28
  • @dv_ Thanks for pointing to gstrtpjitterbuffer and for the explanation of sink=false. Could you please explain how is the pipe driven otherwise (when sync=true)?
    – joanpau
    May 6, 2015 at 19:52
  • Why are the timestamps broken here? Jul 15, 2016 at 22:02
9

You can add "sync=false" to the source gst pipeline. On Ubuntu 12.04 that seems to remove the lag and error messages.

Here's the command I used on the source:

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

and here's what I used on the receiver:

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

Unfortunately, I have no idea why that works or even which component the "sync=false" property belongs to (on the source pipeline).

1
  • Thank you.. same problem but i have given "sync=false" in receiver side and it worked for me. Aug 12, 2016 at 10:41
0

I don't know how much is this true, but when i run my pipeline without connecting the battery charger to my laptop, it used to throw me the same warning, and when i plugged in the power supply, trust me it worked. I think it is may be because of the old CMOS battery, which isn't working as it should be. as it is responsible for clock generation.

1
  • 3
    In this case, I would suspect that your laptop has a power configuration option to reduce maximum available CPU power when running on battery. When you run with charger, you get 100% CPU, when you run on battery, you get less. Hence the "or this computer is too slow".
    – KevinM
    May 26, 2014 at 7:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.