Rtmp sink creation in deepstream test5 application

Please provide complete information as applicable to your setup.

**• Hardware Platform GPU
• DeepStream Version - 6.2
• JetPack Version (valid for Jetson only)
• TensorRT Version
**• NVIDIA GPU Driver Version: 535.86.05
**•

**• I have created function for rtmp sink in deepstream_sink_bin.c. Can you please help with to suggest other changes i need to do in the application to run rtmp stream in output. Can you please tell how do i create rtmp sink in rac_deepstream_app_config.txt ?

rtmp.patch (8.1 KB)

You can refer this patch.

I have tried on DS-6.3 + SRS(simple realtime sever).
It work normally.

thanks for replying. I am able to create rtmp sink but not getting the desired output due to this problem. The log looks like this-

Active sources : 2

**PERF: FPS 0 (Avg) FPS 1 (Avg)
Mon Sep 18 18:05:25 2023
**PERF: 76.34 (2.83) 43.62 (2.77)
Active sources : 0
Mon Sep 18 18:05:30 2023
**PERF: 0.00 (0.62) 0.00 (0.62)
Active sources : 0
Mon Sep 18 18:05:35 2023
**PERF: 0.00 (0.35) 0.00 (0.35)
Active sources : 0
Mon Sep 18 18:05:40 2023
**PERF: 0.00 (0.24) 0.00 (0.24)
Active sources : 0
Mon Sep 18 18:05:45 2023
**PERF: 0.00 (0.19) 0.00 (0.19)

Also the sink config i have
sink3:
#source1 output as filesink
enable: 1
type: 7
#1=mp4 2=mkv 3=flv for rtmp

container: 5

#1=h264 2=h265
codec: 1
encoder type 0=Hardware 1=Software
#H265 Profile - 0=Main 1=Main10

set profile only for hw encoder, sw encoder selects profile based on sw-preset

profile: 0
sync: 0
#output-file=out_source1.mp4
output-uri: rtmp://localhost:1935/live/livestream
source-id: 0

Ignore the sink config in last reply.

sink3:
enable: 1
type: 7
codec: 1
profile: 0
sync: 0
output-uri: rtmp://localhost:1935/live/livestream
source-id: 0

i have created new type of sink where i have created the rtmp pipeline.

rtmp is just streaming flv, what does type=7 mean to you?

Have you tried my patch?

Type-7 is defined here

typedef enum
{
NV_DS_SINK_FAKE = 1,
#ifndef IS_TEGRA
NV_DS_SINK_RENDER_EGL,
else
NV_DS_SINK_RENDER_3D,
endif
NV_DS_SINK_ENCODE_FILE,
NV_DS_SINK_UDPSINK,
NV_DS_SINK_RENDER_DRM,
NV_DS_SINK_MSG_CONV_BROKER,
NV_DS_SINK_RTMPSINK,
} NvDsSinkType;

This is the function for type-7

static gboolean
create_rtmpsink_bin (NvDsSinkEncoderConfig * config, NvDsSinkBinSubBin * bin)
{
GstCaps *caps = NULL;
gboolean ret = FALSE;
gchar elem_name[50];
gchar encode_name[50];

uid++;

g_snprintf (elem_name, sizeof (elem_name), “sink_sub_bin%d”, uid);
bin->bin = gst_bin_new (elem_name);
if (!bin->bin) {
NVGSTDS_ERR_MSG_V (“Failed to create ‘%s’”, elem_name);
goto done;
}

g_snprintf (elem_name, sizeof (elem_name), “sink_sub_bin_queue%d”, uid);
bin->queue = gst_element_factory_make (NVDS_ELEM_QUEUE, elem_name);
if (!bin->queue) {
NVGSTDS_ERR_MSG_V (“Failed to create ‘%s’”, elem_name);
goto done;
}

g_snprintf (elem_name, sizeof (elem_name), “sink_sub_bin_transform%d”, uid);
bin->transform = gst_element_factory_make (NVDS_ELEM_VIDEO_CONV, elem_name);
if (!bin->transform) {
NVGSTDS_ERR_MSG_V (“Failed to create ‘%s’”, elem_name);
goto done;
}

g_snprintf (elem_name, sizeof (elem_name), “sink_sub_bin_cap_filter%d”, uid);
bin->cap_filter = gst_element_factory_make (NVDS_ELEM_CAPS_FILTER, elem_name);
if (!bin->cap_filter) {
NVGSTDS_ERR_MSG_V (“Failed to create ‘%s’”, elem_name);
goto done;
}

if (config->enc_type == NV_DS_ENCODER_TYPE_SW)
caps = gst_caps_from_string (“video/x-raw, format=I420”);
else
caps = gst_caps_from_string (“video/x-raw(memory:NVMM), format=I420”);

g_object_set (G_OBJECT (bin->cap_filter), “caps”, caps, NULL);

g_snprintf (encode_name, sizeof (encode_name), “sink_sub_bin_encoder%d”, uid);

switch (config->codec) {
case NV_DS_ENCODER_H264:
bin->codecparse = gst_element_factory_make (“h264parse”, “h264-parser”);
bin->encoder = gst_element_factory_make (NVDS_ELEM_ENC_H264_HW, encode_name);
if (config->enc_type == NV_DS_ENCODER_TYPE_SW)
bin->encoder = gst_element_factory_make (NVDS_ELEM_ENC_H264_SW, encode_name);
else
bin->encoder = gst_element_factory_make (NVDS_ELEM_ENC_H264_HW, encode_name);
break;
case NV_DS_ENCODER_H265:
bin->codecparse = gst_element_factory_make (“h265parse”, “h265-parser”);
if (config->enc_type == NV_DS_ENCODER_TYPE_SW)
bin->encoder = gst_element_factory_make (NVDS_ELEM_ENC_H265_SW, encode_name);
else
bin->encoder = gst_element_factory_make (NVDS_ELEM_ENC_H265_HW, encode_name);
break;
default:
goto done;
}

if (!bin->encoder) {
NVGSTDS_ERR_MSG_V (“Failed to create ‘%s’”, encode_name);
goto done;
}

if (config->enc_type == NV_DS_ENCODER_TYPE_SW) {
//bitrate is in kbits/sec for software encoder x264enc and x265enc
g_object_set (G_OBJECT (bin->encoder), “bitrate”, config->bitrate/1000, NULL);
} else {
g_object_set (G_OBJECT (bin->encoder), “bitrate”, config->bitrate, NULL);
g_object_set (G_OBJECT (bin->encoder), “profile”, config->profile, NULL);
g_object_set (G_OBJECT (bin->encoder), “iframeinterval”, config->iframeinterval, NULL);
}

ifdef IS_TEGRA
g_object_set (G_OBJECT (bin->encoder), “preset-level”, 1, NULL);
g_object_set (G_OBJECT (bin->encoder), “insert-sps-pps”, 1, NULL);
g_object_set (G_OBJECT (bin->encoder), “bufapi-version”, 1, NULL);
else
g_object_set (G_OBJECT (bin->transform), “gpu-id”, config->gpu_id, NULL);
endif

bin->flv_mux = gst_element_factory_make (“flvmux”, elem_name);
if (!bin->flv_mux) {
NVGSTDS_ERR_MSG_V (“Failed to create ‘%s’”, elem_name);
goto done;
}
g_object_set (G_OBJECT (bin->flv_mux), “name”, “mux”, “streamable”, TRUE, NULL);

bin->sink = gst_element_factory_make (“rtmpsink”, elem_name);
if (!bin->sink) {
NVGSTDS_ERR_MSG_V (“Failed to create ‘%s’”, elem_name);
goto done;
}
g_object_set (G_OBJECT (bin->sink), “location”, config->output_uri, NULL);

g_print (“%s: DEBUGGER create_rtmp_sinkn \n”, config->output_uri);

gst_bin_add_many (GST_BIN (bin->bin), bin->queue, bin->transform,
bin->encoder, bin->codecparse, bin->flv_mux, bin->sink, NULL);

NVGSTDS_LINK_ELEMENT (bin->queue, bin->transform);
NVGSTDS_LINK_ELEMENT (bin->transform, bin->encoder);
NVGSTDS_LINK_ELEMENT (bin->encoder, bin->codecparse);
NVGSTDS_LINK_ELEMENT (bin->codecparse, bin->flv_mux);
// NVGSTDS_LINK_ELEMENT (bin->flvmux, bin->sink);
NVGSTDS_BIN_ADD_GHOST_PAD (bin->bin, bin->queue, “sink”);

ret = TRUE;

if (ret != TRUE) {
g_print (“%s: start_rtmp_straming function failed\n”, func);
}
g_print (“%s: Started streaming RTMP\n”, func);

done:
if (caps) {
gst_caps_unref (caps);
}
if (!ret) {
NVGSTDS_ERR_MSG_V (“%s failed”, func);
}
return ret;
}

getting this error while trying with your patch

ERROR from sink_sub_bin_sink2: Could not open resource for writing.
Debug info: gstrtmpsink.c(293): gst_rtmp_sink_render (): /GstPipeline:pipeline/GstBin:processing_bin_0/GstBin:sink_bin/GstBin:sink_sub_bin2/GstRTMPSink:sink_sub_bin_sink2:
Could not connect to RTMP stream “rtmp://localhost:1935/live/livestream” for writing
ERROR from sink_sub_bin_sink4: Could not open resource for writing.
Debug info: gstrtmpsink.c(293): gst_rtmp_sink_render (): /GstPipeline:pipeline/GstBin:processing_bin_1/GstBin:sink_bin/GstBin:sink_sub_bin4/GstRTMPSink:sink_sub_bin_sink4:
Could not connect to RTMP stream “rtmp://localhost:1936/live/livestream” for writing

Even with creating new type=7 as mentioned above, i am getting the same error

Do you start a rtmp-server such as SRS ?This error means rtmpsink can’t push to server.

Now it’s working fine with Installing and Configuring Nginx-RTMP. Thanks for your support.