Please provide complete information as applicable to your setup.
• Hardware Platform (Jetson / GPU):4070Ti
• DeepStream Version: 7.1
Hi @fanzh
I’m trying to get multiple RTSP output. I’m using the below code:
static void start_rtsp_streaming(GstRTSPServer *server, guint updsink_port_num,
NvDsEncoderType enctype, char *mounts_point,
guint64 udp_buffer_size)
{
GstRTSPMountPoints *mounts;
GstRTSPMediaFactory *factory;
char udpsrc_pipeline[512];
char *encoder_name;
if (enctype == NV_DS_ENCODER_H264)
{
encoder_name = "H264";
}
else if (enctype == NV_DS_ENCODER_H265)
{
encoder_name = "H265";
}
else
{
g_print("%s failed", __func__);
return;
}
if (udp_buffer_size == 0)
udp_buffer_size = 512 * 1024;
sprintf(udpsrc_pipeline,
"( udpsrc name=pay0 port=%d buffer-size=%lu "
"caps=\"application/x-rtp, media=video, "
"clock-rate=90000, encoding-name=%s, payload=96 \" )",
updsink_port_num, udp_buffer_size, encoder_name);
mounts = gst_rtsp_server_get_mount_points(server);
factory = gst_rtsp_media_factory_new();
gst_rtsp_media_factory_set_shared(factory, TRUE);
gst_rtsp_media_factory_set_launch(factory, udpsrc_pipeline);
gst_rtsp_mount_points_add_factory(mounts, mounts_point, factory);
g_object_unref(mounts);
g_print("\n *** DeepStream: Launched RTSP Streaming at "
"rtsp://localhost:8554%s ***\n\n",
mounts_point);
}
GstElement* create_udpsink_bin(int index, guint udp_port,
NvDsEncMode enc_mode,
NvDsEncoderType enc_type)
{
GstCaps* caps = nullptr;
std::string elem_name;
std::string encode_name;
std::string rtppay_name;
elem_name = "sink_sub_bin_" + std::to_string(index);
GstElement* bin = gst_bin_new(elem_name.c_str());
if (!bin) {
g_print("Failed to create '%s'\n", elem_name.c_str());
return nullptr;
}
// Queue
elem_name = "sink_sub_bin_queue" + std::to_string(index);
GstElement* queue = gst_element_factory_make("queue", elem_name.c_str());
if (!queue) {
g_print("Failed to create '%s'\n", elem_name.c_str());
return nullptr;
}
// Transform
elem_name = "sink_sub_bin_transform" + std::to_string(index);
GstElement* transform = gst_element_factory_make("nvvideoconvert", elem_name.c_str());
if (!transform) {
g_print("Failed to create '%s'\n", elem_name.c_str());
return nullptr;
}
// Caps filter
elem_name = "sink_sub_bin_cap_filter" + std::to_string(index);
GstElement* cap_filter = gst_element_factory_make("capsfilter", elem_name.c_str());
if (!cap_filter) {
g_print("Failed to create '%s'\n", elem_name.c_str());
return nullptr;
}
encode_name = "sink_sub_bin_encoder" + std::to_string(index);
rtppay_name = "sink_sub_bin_rtppay" + std::to_string(index);
GstElement* codecparse = nullptr;
GstElement* rtppay = nullptr;
GstElement* encoder = nullptr;
switch (enc_type) {
case NV_DS_ENCODER_H264:
codecparse = gst_element_factory_make("h264parse", "h264-parser");
g_object_set(codecparse, "config-interval", 1, nullptr);
rtppay = gst_element_factory_make("rtph264pay", rtppay_name.c_str());
g_object_set(rtppay, "config-interval", 1, nullptr);
encoder = (enc_mode == NV_DS_ENCODER_MODE_SW) ?
gst_element_factory_make("x264enc", encode_name.c_str()) :
gst_element_factory_make("nvv4l2h264enc", encode_name.c_str());
if (!encoder && enc_mode != NV_DS_ENCODER_MODE_SW) {
g_print("Could not create HW encoder. Falling back to SW encoder\n");
encoder = gst_element_factory_make("x264enc", encode_name.c_str());
}
break;
case NV_DS_ENCODER_H265:
codecparse = gst_element_factory_make("h265parse", "h265-parser");
g_object_set(codecparse, "config-interval", 1, nullptr);
rtppay = gst_element_factory_make("rtph265pay", rtppay_name.c_str());
g_object_set(rtppay, "config-interval", 1, nullptr);
encoder = (enc_mode == NV_DS_ENCODER_MODE_SW) ?
gst_element_factory_make("x265enc", encode_name.c_str()) :
gst_element_factory_make("nvv4l2h265enc", encode_name.c_str());
if (!encoder && enc_mode != NV_DS_ENCODER_MODE_SW) {
g_print("Could not create HW encoder. Falling back to SW encoder\n");
encoder = gst_element_factory_make("x265enc", encode_name.c_str());
}
break;
default:
return nullptr;
}
if (!encoder) {
g_print("Failed to create encoder '%s'\n", encode_name.c_str());
return nullptr;
}
// Set caps
if (enc_mode == NV_DS_ENCODER_MODE_SW)
caps = gst_caps_from_string("video/x-raw, format=I420");
else
caps = gst_caps_from_string("video/x-raw(memory:NVMM), format=NV12");
g_object_set(cap_filter, "caps", caps, nullptr);
if (!rtppay) {
g_print("Failed to create '%s'\n", rtppay_name.c_str());
return nullptr;
}
if (enc_mode == NV_DS_ENCODER_MODE_SW)
{
// g_object_set(encoder, "bitrate", 4000000, nullptr);
g_object_set(encoder,
"bitrate", 5000, // kbps
"key-int-max", 25,
"speed-preset", 1, // ultrafast
"tune", 0x00000004, // zerolatency
"byte-stream", TRUE,
nullptr);
}
else
{
// g_object_set(encoder, "bitrate", 5000000, "profile", 0, "iframeinterval", 25, nullptr);
g_object_set(encoder,
"bitrate", 5000000, // bps
"iframeinterval", 25,
"profile", 0, // baseline
"insert-sps-pps", 1,
"control-rate", 1, // CBR
"preset-level", 1,
nullptr);
}
// GPU properties
cudaDeviceProp prop;
cudaGetDeviceProperties(&prop, 0);
if (prop.integrated && enc_mode == NV_DS_ENCODER_MODE_SW) {
g_object_set(encoder, "preset-level", 1, "insert-sps-pps", 1, "gpu-id", 0, nullptr);
} else {
g_object_set(transform, "gpu-id", 0, nullptr);
}
// UDP Sink
elem_name = "sink_sub_bin_udpsink" + std::to_string(index);
GstElement* sink = gst_element_factory_make("udpsink", elem_name.c_str());
if (!sink) {
g_print("Failed to create '%s'\n", elem_name.c_str());
return nullptr;
}
g_object_set(sink, "host", "127.0.0.1", "port", udp_port, "async", FALSE, "sync", FALSE, nullptr);
gst_bin_add_many(GST_BIN(bin), queue, cap_filter, transform, encoder,
codecparse, rtppay, sink, nullptr);
if (!gst_element_link_many(queue, cap_filter, transform, encoder, codecparse,
rtppay, sink, nullptr)) {
g_print("Failed to link elements in the bin\n");
return nullptr;
}
GstPad* pad = gst_element_get_static_pad(queue, "sink");
if (!pad) {
g_print("Could not get sink pad from queue\n");
return nullptr;
}
GstPad* ghost_pad = gst_ghost_pad_new("sink", pad);
gst_pad_set_active(ghost_pad, TRUE);
gst_element_add_pad(bin, ghost_pad);
gst_object_unref(pad);
if (caps)
gst_caps_unref(caps);
return bin;
}
The pipeline is as:
gst_bin_add_many(GST_BIN(pipeline), queue7, nvvidconv, queue3,
nvosd, queue4, demux, NULL);
// Add another branch (must use dynamic linking again)
GstPad *tee_src_pad2 = gst_element_request_pad_simple(tee_pre_osd, "src_%u");
GstPad *queue7_sink_pad = gst_element_get_static_pad(queue7, "sink");
if (gst_pad_link(tee_src_pad2, queue7_sink_pad) != GST_PAD_LINK_OK)
{
g_printerr("Failed to link tee to queue7. Exiting.\n");
return -1;
}
gst_object_unref (queue7_sink_pad);
gst_object_unref (tee_src_pad2);
/* we link the elements together */
if (!gst_element_link_many(queue7, nvvidconv, queue3,
nvosd, queue4, demux, NULL))
{
g_printerr("Elements could not be linked in rtsp. Exiting.\n");
return -1;
}
for (i = 0; i < num_sources; i++)
{
gchar pad_name[16] = {};
guint udp_port = 5400 + i;
g_snprintf(pad_name, 15, "src_%u", i);
g_snprintf(mounts_str, 15, "/ds-test%u", i);
GstPad *srcpad = gst_element_request_pad_simple(demux, pad_name);
if (!srcpad)
{
g_printerr("Failed to get src pad of demux. Exiting.\n");
continue;
}
g_print("mounts_str = %s\n", mounts_str);
GstElement *udpsink = create_udpsink_bin(i, udp_port, NV_DS_ENCODER_MODE_HW,
NV_DS_ENCODER_H264);
gst_bin_add_many(GST_BIN(pipeline), udpsink, NULL);
GstPad *sinkpad = gst_element_get_static_pad(udpsink, "sink");
if (!sinkpad)
{
g_printerr("Failed to get sink pad of udpsink. Exiting.\n");
continue;
}
gst_pad_link(srcpad, sinkpad);
gst_object_unref(srcpad);
gst_object_unref(sinkpad);
start_rtsp_streaming(server, udp_port, NV_DS_ENCODER_H264, mounts_str, 0);
}
gst_rtsp_server_attach(server, NULL);
The problem is RTSP stream when played with ffplay or viewed shows lots of distortion.
ffplay shows the below :
[h264 @ 0x7fa03919a380] negative number of zero coeffs at 102 7/0
[h264 @ 0x7fa03919a380] error while decoding MB 102 7
[h264 @ 0x7fa03919a380] concealing 7027 DC, 7027 AC, 7027 MV errors in P frame
[h264 @ 0x7fa0392dd180] Invalid level prefix097KB sq= 0B f=0/0
[h264 @ 0x7fa0392dd180] error while decoding MB 85 20
[h264 @ 0x7fa0392dd180] concealing 5484 DC, 5484 AC, 5484 MV errors in P frame
[h264 @ 0x7fa038066280] corrupted macroblock 38 17 (total_coeff=-1)
[h264 @ 0x7fa038066280] error while decoding MB 38 17
[h264 @ 0x7fa038066280] concealing 5891 DC, 5891 AC, 5891 MV errors in I frame
[h264 @ 0x7fa038a261c0] corrupted macroblock 67 28 (total_coeff=-1)
[h264 @ 0x7fa038a261c0] error while decoding MB 67 28
[h264 @ 0x7fa038a261c0] concealing 4542 DC, 4542 AC, 4542 MV errors in P frame
[h264 @ 0x7fa03921c380] corrupted macroblock 31 22 (total_coeff=-1)
[h264 @ 0x7fa03921c380] error while decoding MB 31 22
[h264 @ 0x7fa03921c380] concealing 5298 DC, 5298 AC, 5298 MV errors in P frame
[h264 @ 0x7fa038021c80] Invalid level prefix760KB sq= 0B f=0/0
[h264 @ 0x7fa038021c80] error while decoding MB 7 51
[h264 @ 0x7fa038021c80] concealing 1842 DC, 1842 AC, 1842 MV errors in P frame
[h264 @ 0x7fa038da0ac0] corrupted macroblock 37 9 (total_coeff=-1)
[h264 @ 0x7fa038da0ac0] error while decoding MB 37 9
[h264 @ 0x7fa038da0ac0] concealing 6852 DC, 6852 AC, 6852 MV errors in P frame
[h264 @ 0x7fa038da0ac0] corrupted macroblock 111 12 (total_coeff=-1)
[h264 @ 0x7fa038da0ac0] error while decoding MB 111 12
[h264 @ 0x7fa038da0ac0] concealing 6418 DC, 6418 AC, 6418 MV errors in P frame
[h264 @ 0x7fa03921c380] Invalid level prefix556KB sq= 0B f=0/0
[h264 @ 0x7fa03921c380] error while decoding MB 49 31
[h264 @ 0x7fa03921c380] concealing 4200 DC, 4200 AC, 4200 MV errors in P frame
[h264 @ 0x7fa038021c80] concealing 7020 DC, 7020 AC, 7020 MV errors in I frame
[h264 @ 0x7fa038a261c0] corrupted macroblock 44 5 (total_coeff=-1)
[h264 @ 0x7fa038a261c0] error while decoding MB 44 5
[h264 @ 0x7fa038a261c0] concealing 7325 DC, 7325 AC, 7325 MV errors in P frame
[h264 @ 0x7fa038a2b2c0] Invalid level prefix410KB sq= 0B f=0/0
[h264 @ 0x7fa038a2b2c0] error while decoding MB 57 15
[h264 @ 0x7fa038a2b2c0] concealing 6112 DC, 6112 AC, 6112 MV errors in I frame
[h264 @ 0x7fa03862d080] negative number of zero coeffs at 77 36/0
[h264 @ 0x7fa03862d080] error while decoding MB 77 36
[h264 @ 0x7fa03862d080] concealing 3572 DC, 3572 AC, 3572 MV errors in P frame
This is not acceptable for production scenario. Any help is highly appreciated.

