GNOME Bugzilla – Bug 744379
gst-rtsp-server does not preroll when piping data into the media-pipeline
Last modified: 2015-05-29 18:24:25 UTC
so i've got this gst-rtsp-server application with a pipeline that essentially looks like fdsrc ! demux name=d d. ! audioparser ! queue ! rtpaudiopay d. ! videoparser ! queue ! rtpvideopay this contraption works as long as i feed data like this app < stream.ts but fails to preroll with cat stream.ts | app when gdp-(de)payloading the stream, then it doesn't preroll either way so i've done some debugging and with the help of slomo, noticed that there are queues missing in front of the multiudpsink elements
Created attachment 296664 [details] [review] rtsp-stream: add necessary queues in front of multiudpsinks this doesn't solve the whole problem yet
Why are those queues 'necessary'?
Because we always need queues after tee source pads :) If you don't have a queue there, what will happen is that the tee can send the first buffer to the multiudpsink (async=true!), which then waits for all other sinks (some of them connected to the same tee) to preroll.
Review of attachment 296664 [details] [review]: Looks almost good :) ::: gst/rtsp-server/rtsp-stream.c @@ +2163,3 @@ } else { + /* else only queue+udpsink needed, link it to the session */ + priv->udpqueue[i] = gst_element_factory_make ("queue", NULL); In the else case no queue is necessary because there is no tee
--- a/gst/rtsp-server/rtsp-media.c +++ b/gst/rtsp-server/rtsp-media.c @@ -2403,6 +2403,9 @@ start_preroll (GstRTSPMedia * media) goto state_failed; } + //HACK + priv->is_live = TRUE; + return TRUE; state_failed: after days and days of trying... hardwireing is_live to TRUE helps against my problem with the pipe. suggestions for an actual fix on this are welcome... i don't know if determining this solely by the state change result is the right thing. maybe a property for this ?
so i've discovered that app < stream.ts marks the fdsrc as seekable while cat stream.ts | app marks it as not seekable this sounds reasonable :) but here's another issue with these kind of "live" pipelines. when playing an rtsp stream with vlc for example, it always has a range field in the PLAY request (Range: npt=0.000-) so gst-rtsp-server tries to consider this and of course gst_rtsp_media_seek fails. with git 98b162f54b9168fe0745ddab98163d07109ca208, the PLAY request is then rejected with a 503 error (even though it's a NULL seek) this can be worked around by returning TRUE in gst_rtsp_media_seek if priv->is_live is set (which i set in my previous hack ^^ ) i know, this doesn't exactly get any prettier here :)
Why does it try to seek? It should see that the current media position is the same as the PLAY position (i.e. 0.000) and then don't try to seek. What are the debug logs telling you why it tries to seek?
Created attachment 296753 [details] [review] rtsp-stream: add necessary queues in front of multiudpsinks only in TCP case slomo's review considered
slomo: it tries to seek because the current position is GST_CLOCK_TIME_NONE at that time RTSP request message 0x22ff3d8 request line: method: 'PLAY' uri: 'rtsp://127.0.0.1:8554/stream/' version: '1.0' headers: key: 'CSeq', value: '6' key: 'User-Agent', value: 'LibVLC/2.1.5 (LIVE555 Streaming Media v2014.10.21)' key: 'Session', value: '2mpNiXS2m5fYW+1R' key: 'Range', value: 'npt=0.000-' body: 0:00:08.587246392 8936 0x21c94a0 INFO rtspclient rtsp-client.c:2694:handle_request: client 0x22f39d0: received a request PLAY rtsp://127.0.0.1:8554/stream/ 1.0 0:00:08.587271530 8936 0x21c94a0 DEBUG rtspmedia rtsp-media.c:1800:gst_rtsp_media_set_status: setting new status to 3 0:00:08.587378098 8936 0x21c94a0 INFO rtspmedia rtsp-media.c:1903:gst_rtsp_media_seek: got 0:00:00.000000000 - 99:99:99.999999999 0:00:08.587396655 8936 0x21c94a0 INFO rtspmedia rtsp-media.c:1905:gst_rtsp_media_seek: current 99:99:99.999999999 - 99:99:99.999999999 0:00:08.587410504 8936 0x21c94a0 INFO rtspmedia rtsp-media.c:1919:gst_rtsp_media_seek: seeking to 0:00:00.000000000 - 99:99:99.999999999 0:00:08.587423973 8936 0x21c94a0 DEBUG rtspmedia rtsp-media.c:1800:gst_rtsp_media_set_status: setting new status to 2 0:00:08.587647347 8936 0x21c94a0 INFO rtspmedia rtsp-media.c:1959:gst_rtsp_media_seek: done seeking 0 0:00:08.587666826 8936 0x21c94a0 INFO rtspmedia rtsp-media.c:2001:gst_rtsp_media_seek: seeking failed 0:00:08.587677590 8936 0x21c94a0 ERROR rtspclient rtsp-client.c:1247:handle_play_request: client 0x22f39d0: seek failed RTSP response message 0x7f4b16addb70 status line: code: '503' reason: 'Service Unavailable' version: '1.0' headers: key: 'CSeq', value: '6' key: 'Server', value: 'GStreamer RTSP server' body: length 0
It should not be GST_CLOCK_TIME_NONE though. The pipeline should be pre-rolled already, thus the demuxer at least should give us a position. You should see in the debug logs around the position query who answers it, which elements it travels through and why it becomes GST_CLOCK_TIME_NONE.
This should work better again, unless it is really the seek itself that fails.
Anything missing here?
I working on rtsp relay server for ip cameras using slightly modified gst-rtsp-media-factory-uri.c and encountered same issue with some models. On most cameras pipeline constructed works ok, but on some (mostly Falcon Eye models) it tries to preroll and fails due to timeout: rtspsrc gstrtspsrc.c:4678:gst_rtspsrc_loop_udp:<source> doing receive with timeout 49 seconds rtspmedia rtsp-media.c:1560:gst_rtsp_media_get_status: timeout, assuming error status rtspmedia rtsp-media.c:1566:gst_rtsp_media_get_status: got status 5 rtspmedia rtsp-media.c:2127:wait_preroll: failed to preroll pipeline rtspmedia rtsp-media.c:2384:gst_rtsp_media_prepare: failed to preroll pipeline Using gst-launch uridecodebin uri=rtsp://... ! autovideosink stream played ok.