Search code examples
cgstreamerrtspnvidia-deepstream

RTSP Stream Won't Start/Times out When Adding `rtspsrc` to Running Gstreamer Pipeline


I have a Gstreamer pipeline (based on NVIDIA's "deepstream-app" reference implementation) that will successfully play RTSP streams using rtspsrc on startup.

However, if I try to instead add those same streams after the pipeline is running (say, a minute or two after), the stream won't start and appears to time out.

I'm reasonably certain I'm using the same code in both scenarios (i.e. pre-pipeline running and post-pipeline running), with the sole exception being the latter scenario has an explicit call to set the element's state to GST_STATE_PLAYING, which succeeds:

gboolean play_source(GstElement *source) {
  GstStateChangeReturn ret = gst_element_set_state(source, GST_STATE_PLAYING);
  /* 'ret' always contains GST_STATE_SUCCESS */
  /* ... */

I've tried various levels of logging output (down to DEBUG), and nothing really seems to stand out.

When set to WARN, in the first scenario, I see output like the following:

0:01:29.002271420     1 0x55c2ce502580 INFO                 rtspsrc gstrtspsrc.c:7788:gst_rtspsrc_retrieve_sdp:<src_elem0> Now using version: 1.0
0:01:30.079726768     1 0x55c2ce502580 INFO                 rtspsrc gstrtspsrc.c:3953:gst_rtspsrc_stream_configure_manager:<src_elem0> configure bandwidth in session 0x55c2cd870f70
0:01:35.084717848     1 0x55c2ce502580 WARN                 rtspsrc gstrtspsrc.c:5769:gst_rtspsrc_reconnect:<src_elem0> warning: Could not receive any UDP packets for 5.0000 seconds, maybe your firewall is blocking it. Retrying using a tcp connection.
WARNING from src_elem0: Could not read from resource.
Debug info: gstrtspsrc.c(5769): gst_rtspsrc_reconnect (): /GstPipeline:pipeline/GstBin:multi_src_bin/GstBin:src_sub_bin0/GstRTSPSrc:src_elem0:
Could not receive any UDP packets for 5.0000 seconds, maybe your firewall is blocking it. Retrying using a tcp connection.
0:01:35.089757408     1 0x55c2ce502580 INFO                 rtspsrc gstrtspsrc.c:7788:gst_rtspsrc_retrieve_sdp:<src_elem0> Now using version: 1.0
0:01:36.135689541     1 0x55c2ce502580 INFO                 rtspsrc gstrtspsrc.c:3953:gst_rtspsrc_stream_configure_manager:<src_elem0> configure bandwidth in session 0x55c2cd8712b0
** INFO: <bus_callback:225>: Pipeline running

(The last line was added to show that this is the "pre-running" scenario.)

If I attempt the second scenario, here's what I see:

0:02:29.560067176     1 0x55c2ce502400 INFO                 rtspsrc gstrtspsrc.c:7788:gst_rtspsrc_retrieve_sdp:<src_elem1> Now using version: 1.0
0:02:30.612917137     1 0x55c2ce502400 INFO                 rtspsrc gstrtspsrc.c:3953:gst_rtspsrc_stream_configure_manager:<src_elem1> configure bandwidth in session 0x7f7c14031910
0:02:35.619949661     1 0x55c2ce502400 WARN                 rtspsrc gstrtspsrc.c:5769:gst_rtspsrc_reconnect:<src_elem1> warning: Could not receive any UDP packets for 5.0000 seconds, maybe your firewall is blocking it. Retrying using a tcp connection.
WARNING from src_elem1: Could not read from resource.
Debug info: gstrtspsrc.c(5769): gst_rtspsrc_reconnect (): /GstPipeline:pipeline/GstBin:multi_src_bin/GstBin:src_sub_bin1/GstRTSPSrc:src_elem1:
Could not receive any UDP packets for 5.0000 seconds, maybe your firewall is blocking it. Retrying using a tcp connection.
0:02:35.624850991     1 0x55c2ce502400 INFO                 rtspsrc gstrtspsrc.c:7788:gst_rtspsrc_retrieve_sdp:<src_elem1> Now using version: 1.0
0:02:36.672111985     1 0x55c2ce502400 INFO                 rtspsrc gstrtspsrc.c:3953:gst_rtspsrc_stream_configure_manager:<src_elem1> configure bandwidth in session 0x7f7c14031c50
...
0:03:03.195704059     1 0x7f7c0402c520 WARN                 rtspsrc gstrtspsrc.c:3458:on_timeout_common:<src_elem1> source 27578672, stream 27578672 in session 0 timed out

In researching this issue, I compared against NVIDIA's example here: https://github.com/NVIDIA-AI-IOT/deepstream_reference_apps/blob/master/runtime_source_add_delete/deepstream_test_rt_src_add_del.c and, near as I can tell, it doesn't pause the pipeline or do anything special other than set the element's state to GST_STATE_PLAYING, which I also do as noted above.

All sinks/sources/pads are created/connected in the same way in both scenarios.

The RTSP streams themselves are fine (they're local to the same machine, in fact).

I'm by no means a Gstreamer expert, so if I'm doing something wrong or missing something, I'm happy to hear about it. I'm also happy to provide more details if necessary and able.

Thank you kindly in advance!

UPDATE

I remembered about the GST_DEBUG_BIN_TO_DOT_* macros/functions and applied it to my pipeline during runtime. I can see that despite my best efforts, I'm missing some elements in my pipeline necessary for streaming. If I'm able to chase it down and correct it, I'll update this question and close it.


Solution

  • Ok, so the story goes that I actually did have all of the necessary elements in place; however, I was setting the wrong element to GST_STATE_PLAYING. Specifically, I was trying to set the state of GstRTSPSrc element that I had access to when I should have been setting the state of the bin in which that element is located.

    In other words, the GstRTSPSrc element is but one part of all of the elements necessary to play the stream, and those elements are contained in a bin.

    I'd have seen this sooner if I'd used the GST_DEBUG_BIN_TO_* feature AND used it in the right place. (Pro tip: the legend for the resulting diagram can usually be found in the bottom left, and it's a big help.)