The gst server sends the sdp for a long time

It touches on two previous topics:

I found that the reason for the long start-up time of gst server is related to the time when the server sends sdp. The following is the debugging information of the client. It can be seen that it takes about 3s for the client to receive the sdp description sent by the server.
I want to know why this is, and what is it related to?

05-10 08:42:48.605 [00000a2c] <info>  [SP] Start event loop++
05-10 08:42:48.605 [00000a2c] <info>  [SP] RtspEventLoop::Start thread->start++
05-10 08:42:48.605 [00000a2c] <info>  [SP] RtspEventLoop::Start thread->start--
05-10 08:42:48.605 [00000a2c] <info>  [SP] Run out of StartInternal--
***05-10 08:42:48.605 [000011c8] <info>  [SP] RtspSource::EventLoopRun++***
***05-10 08:42:52.298 [000011c8] <info>  [SP] describe s_c:0***
05-10 08:42:52.298 [000011c8] <info>  [SP] RTSP Got a SDP description:v=0
o=- 4675241958595024844 1 IN IP4 192.168.3.38
s=Session streamed with GStreamer
i=rtsp-server
t=0 0
a=tool:GStreamer
a=type:broadcast
a=control:*
a=range:npt=now-
m=video 0 RTP/AVP 96
c=IN IP4 0.0.0.0
a=rtpmap:96 H264/90000
a=framerate:30
a=fmtp:96 packetization-mode=1;sprop-parameter-sets=Z2QQKKwbGqB4AiflhAAAAwAEAAADAPI8IhGo,aO4xshs=
a=control:stream=0

05-10 08:42:52.323 [000011c8] <info>  [SP] rtsp client port:61984-61985
05-10 08:42:52.340 [000011c8] <info>  [SP] RTSP Set up subsession
05-10 08:42:52.340 [000011c8] <info>  [SP] RTSP Video SU-RS old:65536 new:2097152

What does your rtsp-server media pipeline look like?

Are capture elements or hardware video encoders being used?

If so, is it possible that they need some time to start up?

The pipeline used now is as follows:

char *instruction4 = "(v4l2src device=/dev/video11 ! video/x-raw,format=NV12,width=1920,height=1080 ! mpph264enc gop=1 ! rtph264pay name=pay0 pt=96 )";
gst_rtsp_media_factory_set_launch (factory, instruction4);

From what I understand, the pipeline uses mpph264enc, a Rockchip hardware encoding plugin for MPP, do you mean that the server needs to parse the pipe before it can send the sdp to the client?

The rtsp-server generates the SDP based on the output caps from the RTP payloader(s).

The RTP payloader is probably waiting for the video encoder to send output caps or even an initial buffer in order to generate output caps with the sprop-parameter-sets configuration data (which contains the SPS/PPS).

I’m not familiar with this particular encoder element, so you’d have to check the implementation to see what it does exactly.

In case the encoder can output both stream-format=avc or stream-format=byte-stream it might help to force it to output avc format (where the sps/pps are in the caps then in the codec_data field).

I would like to ask further, in which step does the rtsp-server send the sdp to the client, and specifically in which function process? For example, in one of these functions? If so, which one?

gst_rtsp_media_factory_set_launch (factory, instruction4);
gst_rtsp_mount_points_add_factory (mounts, "/test", factory);
id = gst_rtsp_server_attach (gst_server, NULL);
g_main_loop_run (loop);

I am currently tracing the source code and would like to try to send sdp to the client unactively. I am not sure if this is possible.

The pipeline will only be created and start up when the first client connects.

I don’t know what you said, I want to trace the source code to see how the server sends to sdp, which library file should I look at, I trace the function I mentioned before, but I don’t understand the steps of sending sdp

I would recommend enabling some GST_DEBUG=rtsp*:6 debug logging for rtsp-server and that will then give you the source files, function names and line numbers where things are happening.

ok, thank you. I’ll try it first.

Now I’m using x264enc to code, but unfortunately, it also takes about 3s to get the interface. I ran the rtsp-server example code with the following command and got the following output: Can you help me see what’s wrong? Thank you very much.

neardi@LPA3588:~/Downloads/gst-rtsp-server/examples$ ./test-192.168.3.40 --gst-debug-level=3 "( v4l2src device=/dev/video11 ! video/x-raw,format=NV12,width=640,height=480 ! x264enc tune=zerolatency ! rtph264pay name=pay0 pt=96 )"
0:00:14.998236691 107450   0x7fb4006360 FIXME                default gstutils.c:4025:gst_pad_create_stream_id_internal:<appsrc0:src> Creating random stream-id, consider implementing a deterministic way of creating a stream-id
0:00:15.006969567 107450   0x55a861b300 WARN                 v4l2src gstv4l2src.c:835:gst_v4l2src_query:<v4l2src0> Can't give latency since framerate isn't fixated !
0:00:15.008569613 107450   0x55a861b300 WARN                 v4l2src gstv4l2src.c:835:gst_v4l2src_query:<v4l2src0> Can't give latency since framerate isn't fixated !
0:00:15.008738192 107450   0x7fac01b5e0 WARN                    v4l2 gstv4l2object.c:4589:gst_v4l2_object_probe_caps:<v4l2src0:src> Failed to probe pixel aspect ratio with VIDIOC_CROPCAP: Invalid argument
0:00:15.009059893 107450   0x55a861b300 WARN                 v4l2src gstv4l2src.c:835:gst_v4l2src_query:<v4l2src0> Can't give latency since framerate isn't fixated !
0:00:15.009520132 107450   0x55a861b300 WARN                 v4l2src gstv4l2src.c:835:gst_v4l2src_query:<v4l2src0> Can't give latency since framerate isn't fixated !
0:00:18.164756065 107450   0x7fac01b5e0 WARN          v4l2bufferpool gstv4l2bufferpool.c:1373:gst_v4l2_buffer_pool_dqbuf:<v4l2src0:pool0:src> Driver should never set v4l2_buffer.field to ANY
0:00:18.236626362 107450   0x55a861b000 FIXME              rtspmedia rtsp-media.c:3425:gst_rtsp_media_suspend: suspend for dynamic pipelines needs fixing
0:00:18.264401996 107450   0x55a861b000 FIXME              rtspmedia rtsp-media.c:3425:gst_rtsp_media_suspend: suspend for dynamic pipelines needs fixing
0:00:18.264466452 107450   0x55a861b000 WARN               rtspmedia rtsp-media.c:3451:gst_rtsp_media_suspend: media 0x7fb40471a0 was not prepared
0:00:18.346979664 107450   0x7fac01b5e0 WARN                 v4l2src gstv4l2src.c:1164:gst_v4l2src_create:<v4l2src0> lost frames detected: count = 1 - ts: 0:00:03.300771464
0:00:18.404740546 107450   0x7fac01b5e0 WARN                 v4l2src gstv4l2src.c:1164:gst_v4l2src_create:<v4l2src0> lost frames detected: count = 1 - ts: 0:00:03.380834005
0:00:18.564615592 107450   0x7fac01b5e0 WARN                 v4l2src gstv4l2src.c:1164:gst_v4l2src_create:<v4l2src0> lost frames detected: count = 1 - ts: 0:00:03.540818172
0:00:18.764546021 107450   0x7fac01b5e0 WARN                 v4l2src gstv4l2src.c:1164:gst_v4l2src_create:<v4l2src0> lost frames detected: count = 1 - ts: 0:00:03.740775463

It looks like it’s taking a long time for the source element to start generating frames?

You could try this as rtsp-server pipeline:

v4l2src device=/dev/video11 ! video/x-raw,format=NV12,width=640,height=480 ! rtpvrawpay name=pay0

or just look at the first buffer timestamp of

gst-launch-1.0 -v v4l2src device=/dev/video11 ! video/x-raw,format=NV12,width=640,height=480 ! fakesink silent=false

If the source really takes that long to startup you can work around it either by

  1. always having a local client connected from the start (that just throws away the data it receives, but that way the pipeline will be up and running before external clients connect); this is only useful if it’s a shared media.
  2. start a producer (source) pipeline outside of rtsp-server and feed the data into the rtsp-server media pipeline using elements like intervideosink/intervideosrc or intersink/intersrc (or manually via appsink/appsrc)

Using this pipeline, I was unable to receive data on the pull side, and based on the debug information on the pull side, I was unable to fetch the sdp.

05-11 18:50:30.860 [00003218] <info>  [SP] Run out of StartInternal--
05-11 18:50:34.221 [00007cc8] <info>  [SP] describe s_c:503
05-11 18:50:34.221 [00007cc8] <error> [SP] RTSP Failed to get a SDP description:503 Service Unavailable

When I execute this command, I get the following output. I noticed a pause of about 3s in the output, after the following message starts with a >

> neardi@LPA3588:~/Downloads/gst-rtsp-server/examples$ gst-launch-1.0 -v v4l2src device=/dev/video11 ! video/x-raw,format=NV12,width=640,height=480 ! fakesink silent=false
> Setting pipeline to PAUSED ...
> Pipeline is live and does not need PREROLL ...
> Pipeline is PREROLLED ...
> Setting pipeline to PLAYING ...
> /GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = event   ******* (fakesink0:sink) E (type: stream-start (10254), GstEventStreamStart, stream-id=(string)5e6bccc21c287358c0288817f3068f1e663ede66b9c81cdc1dc2e6df47fb4e5c, flags=(GstStreamFlags)GST_STREAM_FLAG_NONE, group-id=(uint)1;) 0x55bdf778f0
> New clock: GstSystemClock
> /GstPipeline:pipeline0/GstV4l2Src:v4l2src0.GstPad:src: caps = video/x-raw, format=(string)NV12, width=(int)640, height=(int)480, framerate=(fraction)30/1, interlace-mode=(string)progressive, colorimetry=(string)bt601
> /GstPipeline:pipeline0/GstCapsFilter:capsfilter0.GstPad:src: caps = video/x-raw, format=(string)NV12, width=(int)640, height=(int)480, framerate=(fraction)30/1, interlace-mode=(string)progressive, colorimetry=(string)bt601
> /GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = event   ******* (fakesink0:sink) E (type: caps (12814), GstEventCaps, caps=(GstCaps)"video/x-raw\,\ format\=\(string\)NV12\,\ width\=\(int\)640\,\ height\=\(int\)480\,\ framerate\=\(fraction\)30/1\,\ interlace-mode\=\(string\)progressive\,\ colorimetry\=\(string\)bt601";) 0x55bdf779d0
> /GstPipeline:pipeline0/GstFakeSink:fakesink0.GstPad:sink: caps = video/x-raw, format=(string)NV12, width=(int)640, height=(int)480, framerate=(fraction)30/1, interlace-mode=(string)progressive, colorimetry=(string)bt601
> /GstPipeline:pipeline0/GstCapsFilter:capsfilter0.GstPad:sink: caps = video/x-raw, format=(string)NV12, width=(int)640, height=(int)480, framerate=(fraction)30/1, interlace-mode=(string)progressive, colorimetry=(string)bt601
/GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = event   ******* (fakesink0:sink) E (type: segment (17934), GstEventSegment, segment=(GstSegment)"segment, flags=(GstSegmentFlags)GST_SEGMENT_FLAG_NONE, rate=(double)1, applied-rate=(double)1, format=(GstFormat)time, base=(guint64)0, offset=(guint64)0, start=(guint64)0, stop=(guint64)18446744073709551615, time=(guint64)0, position=(guint64)0, duration=(guint64)18446744073709551615;";) 0x55bdf77a40
/GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = preroll   ******* 
Redistribute latency...
/GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = chain   ******* (fakesink0:sink) (460800 bytes, dts: none, pts: 0:00:03.128215803, duration: 0:00:00.033333333, offset: 0, offset_end: 1, flags: 00000040 discont , meta: none) 0x55be0bc5a0
/GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = chain   ******* (fakesink0:sink) (460800 bytes, dts: none, pts: 0:00:03.168308094, duration: 0:00:00.033333333, offset: 2, offset_end: 3, flags: 00000000 , meta: none) 0x55be0bc6c0
/GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = chain   ******* (fakesink0:sink) (460800 bytes, dts: none, pts: 0:00:03.208259136, duration: 0:00:00.033333333, offset: 3, offset_end: 4, flags: 00000000 , meta: none) 0x55be0bc7e0
/GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = chain   ******* (fakesink0:sink) (460800 bytes, dts: none, pts: 0:00:03.248201136, duration: 0:00:00.033333333, offset: 4, offset_end: 5, flags: 00000000 , meta: none) 0x55be0bc900
/GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = chain   ******* (fakesink0:sink) (460800 bytes, dts: none, pts: 0:00:03.288196844, duration: 0:00:00.033333333, offset: 5, offset_end: 6, flags: 00000000 , meta: none) 0x55be0bc5a0

This method was tried when I read the rtsp-server sample application, as you said, if you set up shared pipes, when one client is connected, another client can open the video interface in millimeters. However, this does not fully meet my use situation, I will switch different sources to observe different pictures in use, in order to achieve the randomness and real-time switching, I cannot ask other clients to pull streams in advance.This makes me very upset.

I’m sorry, but I don’t understand what you mean. Could you further explain the idea and purpose of this?

Right, sorry. mistake on my part. rtpvrawpay does not support NV12 format so this won’t work.

So the problem seems to be with the source element taking a long time to start up?

Well, I think so. I have a little doubt whether the source element is slow to start is related to the camera hardware, or to the gst framework? Will gst not be compatible with the hardware? In view of the present situation, should I give priority to finding the cause from the hardware device or CPU? I look forward to your reply.