Search code examples
streaminggstreamerrtsp

Limiting gstreamer pipeline throughput to simulate live source


I'm developing an RTSP server that should emulate a live source, while streaming the data from a file.

What I currently have is mostly based on gst-rtsp-server example test-readme.c, only with the following pipeline:

gst_rtsp_media_factory_set_launch(factory, "( "
   "filesrc location=stream.mkv ! matroskademux name=demuxer "
   "demuxer. ! queue ! rtph264pay name=pay0 pt=96 "
   "demuxer. ! queue ! rtpmp4gpay name=pay1 pt=97 "
")");

This works very well, except for one problem: when the RTSP client (which uses RTSP/TCP interleave transport) is not able to receive data, the whole pipeline locks up until the client is ready again, and then resumes at the original position without any jump.

Since I want to emulate live source which cannot buffer its video indefinitely, the desired behavior in this case is to continue playing the file, so when the client blocks for 5 seconds, it will lose 5 seconds of recording.

I've attempted to achieve this by limiting queue sizes and setting them as leaky (by setting them as queue max-size-bytes=1000000 max-size-time=1000000000 leaky=upstream, which should provide buffer to ~1 second of video, but no more). This did not work entirely as I hoped: the source and demuxer filled the queue and then completely emptied themselves in 0.1 sec.

I figured I need some way to throttle pipeline throughput before the queue, either by limiting the demuxer to real-time demuxing, or finding/making a gstreamer filter that will let through 1 second of data per 1 second of real time.

Do you have any hints on how to do this?


Solution

  • So it seems that while leaky queue and limiter can be done, they don't help much in this regard as GStreamer RTSP implementation has its own queue for outgoing TCP data. What appears to work is keeping the pipeline unchanged and patching gst-rtsp-server module to limit its queue length (to 1 MB in this case, recent version also limit message count to 100):

    --- gst-rtsp-server-1.4.5/gst/rtsp-server/rtsp-client.c 2014-11-06 11:20:28.000000000 +0100
    +++ gst-rtsp-server-1.4.5-r1/gst/rtsp-server/rtsp-client.c      2015-04-28 14:25:14.207888281 +0200
    @@ -3435,11 +3435,11 @@
       gst_rtsp_client_set_send_func (client, do_send_message, priv->watch,
           (GDestroyNotify) gst_rtsp_watch_unref);
    
       /* FIXME make this configurable. We don't want to do this yet because it will
        * be superceeded by a cache object later */
    -  gst_rtsp_watch_set_send_backlog (priv->watch, 0, 100);
    +  gst_rtsp_watch_set_send_backlog (priv->watch, 1000000, 100);
    
       GST_INFO ("client %p: attaching to context %p", client, context);
       res = gst_rtsp_watch_attach (priv->watch, context);
    
       return res;