The problem about pixels

I want open 2 RTSP routes, one has 720P pixels, the other has 1080P pixels.
I use the deepstream-app.The following is my config:

[application]
enable-perf-measurement=1
perf-measurement-interval-sec=5
#gie-kitti-output-dir=streamscl

[tiled-display]
enable=1
rows=1
columns=1
width=1920
height=1080

[source0]
enable=1
#Type - 1=CameraV4L2 2=URI 3=MultiURI 4=RTSP 5=CSI
type=5
camera-width=1920
camera-height=1080
camera-fps-n=30
camera-fps-d=1

[sink0]
enable=1
#Type - 1=FakeSink 2=EglSink 3=File 4=RTSPStreaming 5=Overlay
type=4
#1=h264 2=h265
codec=1
sync=0
width=1280
height=720
bitrate=1000000
# set below properties in case of RTSPStreaming
rtsp-port=8554
udp-port=5400

[sink1]
enable=1
#Type - 1=FakeSink 2=EglSink 3=File 4=RTSPStreaming 5=Overlay
type=4
#1=h264 2=h265
codec=1
sync=0
width=1920
height=1080
bitrate=1000000
# set below properties in case of RTSPStreaming
rtsp-port=8555
udp-port=5401

[osd]
enable=1
border-width=2
text-size=15
text-color=1;1;1;1;
text-bg-color=0.3;0.3;0.3;1
font=Serif
show-clock=0
clock-x-offset=800
clock-y-offset=820
clock-text-size=12
clock-color=1;0;0;0

[streammux]
##Boolean property to inform muxer that sources are live
live-source=1
batch-size=1
##time out in usec, to wait after the first buffer is available
##to push the batch even if the complete batch is not formed
batched-push-timeout=40000
## Set muxer output width and height
width=1920
height=1080

# config-file property is mandatory for any gie section.
# Other properties are optional and if set will override the properties set in
# the infer config file.
[primary-gie]
enable=1
model-engine-file=../../models/Primary_Detector/resnet10.caffemodel_b30_int8.engine
#Required to display the PGIE labels, should be added even when using config-file
#property
batch-size=1
#Required by the app for OSD, not a plugin property
bbox-border-color0=1;0;0;1
bbox-border-color1=0;1;1;1
bbox-border-color2=0;0;1;1
bbox-border-color3=0;1;0;1
interval=0
#Required by the app for SGIE, when used along with config-file property
gie-unique-id=1
config-file=config_infer_primary.txt

[tests]
file-loop=0

Then I access two routes, I find that two routes both have 1080P pixels.
I want to know where is wrong.
Thanks.

Hi,
It is not supported in default sample. Please check create_udpsink_bin() in

deepstream_sdk_v4.0_jetson\sources\apps\apps-common\src\deepstream_sink_bin.c

By default the resolution is decided by settings in [tiled-display]. For having two sinks with different resolution, you may copy one more create_udpsink_bin_1(), add bin->cap_filter(with specific width and height) between bin->transform and bin->encoder.

Default architecture:
https://docs.nvidia.com/metropolis/deepstream/4.0/dev-guide/index.html#page/DeepStream_Development_Guide%2Fdeepstream_app_architecture.html%23

Hi,
I’m sorry late reply.
I’m still not sure how to modify it.
I have checked create_udpsink_bin() in

deepstream_sdk_v4.0_jetson\sources\apps\apps-common\src\deepstream_sink_bin.c

The following is the bin->cap_filter codes between bin->transform and bin->encoder:

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;
  }

  caps = gst_caps_from_string ("video/x-raw(memory:NVMM), format=I420");
  g_object_set (G_OBJECT (bin->cap_filter), "caps", caps, NULL);

I don’t know how to copy one more create_udpsink_bin_1() and how to add specific width and height.
If I copy one more create_udpsink_bin_1(), What other source files should I modify?
Can you give me some examples for my reference?
Or, How do I make Key(width and height) in Sink Group using for RTSP type?
Thanks.

Is it like this?

static gboolean
create_udpsink_bin_1 (NvDsSinkEncoderConfig * config, NvDsSinkBinSubBin * bin)
{
...
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;
  }

  caps = gst_caps_from_string ("video/x-raw(memory:NVMM), format=I420, width=1920, height=1080");
  g_object_set (G_OBJECT (bin->cap_filter), "caps", caps, NULL);
...
}
static gboolean
create_udpsink_bin_2 (NvDsSinkEncoderConfig * config, NvDsSinkBinSubBin * bin)
{
...
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;
  }

  caps = gst_caps_from_string ("video/x-raw(memory:NVMM), format=I420, width=1280, height=720");
  g_object_set (G_OBJECT (bin->cap_filter), "caps", caps, NULL);
...
}

So how do I choose to call create_udpsink_bin_1() or create_udpsink_bin_2()?
Are there any other code files that need to be modified?
Thanks.

Hi,

case NV_DS_SINK_UDPSINK:
if (!create_udpsink_bin (&config_array[i].encoder_config,
        &bin->sub_bins[i]))
  goto done;
break;

config_array[i] maps to sink0, sink1, sink2, etc. You may distinguish it from the index.

I changed it to look like this,

case NV_DS_SINK_UDPSINK:
		if (i = 0) {
			if (!create_udpsink_bin_0 (&config_array[i].encoder_config,
                &bin->sub_bins[i]))
            goto done;
		} else if (i = 1) {
			if (!create_udpsink_bin_1 (&config_array[i].encoder_config,
				&bin->sub_bins[i]))
            goto done;
		} else {
			if (!create_udpsink_bin_0 (&config_array[i].encoder_config,
                &bin->sub_bins[i]))
            goto done;
		}
        break;

I will try again.
I hope to add it in deepstream-app. Every output’s resolution is decided by its sink’s config settings, just like the type-5(Overlay)'s using.
Each new resolution mean copy one more create_udpsink_bin(), and it doesn’t support customization from config.
I think that user needs different resolution in Client.
Thank you for your help!

Hi,
After I changed deepstream_sink_bin.c, I recompile the deepstream-app, I get errors:

*** DeepStream: Launched RTSP Streaming at rtsp://localhost:8555/ds-test ***

(deepstream-app:9456): GStreamer-CRITICAL **: 15:50:24.224: gst_element_get_static_pad: assertion 'GST_IS_ELEMENT (element)' failed
Segmentation fault (core dumped)

I don’t know where is wrong. I just copy create_udpsink_bin() and modify “case NV_DS_SINK_UDPSINK:…”. The following is the code of the modified deepstream_sink_bin.c:

/*
 * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>

#include "deepstream_common.h"
#include "deepstream_sinks.h"
#include <gst/rtsp-server/rtsp-server.h>

static guint uid = 0;

GST_DEBUG_CATEGORY_EXTERN (NVDS_APP);

/**
 * Function to create sink bin for Display / Fakesink.
 */
static gboolean
create_render_bin (NvDsSinkRenderConfig * config, NvDsSinkBinSubBin * bin)
{
  gboolean ret = FALSE;
  gchar elem_name[50];
  GstElement *connect_to;
  GstCaps *caps = NULL;

  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_sink%d", uid);
  switch (config->type) {
    case NV_DS_SINK_RENDER_EGL:
      GST_CAT_INFO (NVDS_APP, "NVvideo renderer\n");
      bin->sink = gst_element_factory_make (NVDS_ELEM_SINK_EGL, elem_name);
      g_object_set (G_OBJECT (bin->sink), "window-x", config->offset_x,
          "window-y", config->offset_y, "window-width", config->width,
          "window-height", config->height, NULL);
      break;
    case NV_DS_SINK_RENDER_OVERLAY:
#ifndef IS_TEGRA
      NVGSTDS_ERR_MSG_V ("Overlay is only supported for Jetson");
      return FALSE;
#endif
      GST_CAT_INFO (NVDS_APP, "NVvideo renderer\n");
      bin->sink = gst_element_factory_make (NVDS_ELEM_SINK_OVERLAY, elem_name);
      g_object_set (G_OBJECT (bin->sink), "display-id", config->display_id,
          NULL);
      g_object_set (G_OBJECT (bin->sink), "overlay", config->overlay_id, NULL);
      g_object_set (G_OBJECT (bin->sink), "overlay-x", config->offset_x, NULL);
      g_object_set (G_OBJECT (bin->sink), "overlay-y", config->offset_y, NULL);
      g_object_set (G_OBJECT (bin->sink), "overlay-w", config->width, NULL);
      g_object_set (G_OBJECT (bin->sink), "overlay-h", config->height, NULL);
      break;
    case NV_DS_SINK_FAKE:
      bin->sink = gst_element_factory_make (NVDS_ELEM_SINK_FAKESINK, elem_name);
      break;
    default:
      return FALSE;
  }

  if (!bin->sink) {
    NVGSTDS_ERR_MSG_V ("Failed to create '%s'", elem_name);
    goto done;
  }

  g_object_set (G_OBJECT (bin->sink), "sync", config->sync, "max-lateness", -1,
      "async", FALSE, "qos", config->qos, NULL);

#ifndef IS_TEGRA
  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;
  }
  gst_bin_add (GST_BIN (bin->bin), bin->cap_filter);
#endif

  g_snprintf (elem_name, sizeof (elem_name), "sink_sub_bin_transform%d", uid);
  if (config->type == NV_DS_SINK_RENDER_EGL) {
#ifdef IS_TEGRA
    bin->transform =
        gst_element_factory_make (NVDS_ELEM_EGLTRANSFORM, elem_name);
    g_object_set (G_OBJECT (bin->transform), "bufapi-version", 1, NULL);
#else
    bin->transform = gst_element_factory_make (NVDS_ELEM_VIDEO_CONV, elem_name);
#endif
    if (!bin->transform) {
      NVGSTDS_ERR_MSG_V ("Failed to create '%s'", elem_name);
      goto done;
    }
    gst_bin_add (GST_BIN (bin->bin), bin->transform);

#ifndef IS_TEGRA
    caps = gst_caps_new_empty_simple ("video/x-raw");

    GstCapsFeatures *feature = NULL;
    feature = gst_caps_features_new (MEMORY_FEATURES, NULL);
    gst_caps_set_features (caps, 0, feature);
    g_object_set (G_OBJECT (bin->cap_filter), "caps", caps, NULL);

    g_object_set (G_OBJECT (bin->transform), "gpu-id", config->gpu_id, NULL);
    g_object_set (G_OBJECT (bin->transform), "nvbuf-memory-type",
        config->nvbuf_memory_type, NULL);
#endif
  }

  g_snprintf (elem_name, sizeof (elem_name), "render_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;
  }

  gst_bin_add_many (GST_BIN (bin->bin), bin->queue, bin->sink, NULL);

  connect_to = bin->sink;

  if (bin->cap_filter) {
    NVGSTDS_LINK_ELEMENT (bin->cap_filter, connect_to);
    connect_to = bin->cap_filter;
  }

  if (bin->transform) {
    NVGSTDS_LINK_ELEMENT (bin->transform, connect_to);
    connect_to = bin->transform;
  }

  NVGSTDS_LINK_ELEMENT (bin->queue, connect_to);

  NVGSTDS_BIN_ADD_GHOST_PAD (bin->bin, bin->queue, "sink");

  ret = TRUE;

done:
  if (caps) {
    gst_caps_unref (caps);
  }
  if (!ret) {
    NVGSTDS_ERR_MSG_V ("%s failed", __func__);
  }
  return ret;
}

/**
 * Function to create sink bin to generate encoded output.
 */
static gboolean
create_encode_file_bin (NvDsSinkEncoderConfig * config, NvDsSinkBinSubBin * bin)
{
  GstCaps *caps = NULL;
  gboolean ret = FALSE;
  gchar elem_name[50];
  gulong bitrate = config->bitrate;

  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->codec == NV_DS_ENCODER_MPEG4)
    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 (elem_name, sizeof (elem_name), "sink_sub_bin_encoder%d", uid);
  switch (config->codec) {
    case NV_DS_ENCODER_H264:
      bin->encoder = gst_element_factory_make (NVDS_ELEM_ENC_H264, elem_name);
      break;
    case NV_DS_ENCODER_H265:
      bin->encoder = gst_element_factory_make (NVDS_ELEM_ENC_H265, elem_name);
      break;
    case NV_DS_ENCODER_MPEG4:
      bin->encoder = gst_element_factory_make (NVDS_ELEM_ENC_MPEG4, elem_name);
      break;
    default:
      goto done;
  }
  if (!bin->encoder) {
    NVGSTDS_ERR_MSG_V ("Failed to create '%s'", elem_name);
    goto done;
  }

  g_object_set (G_OBJECT (bin->encoder), "bitrate", bitrate, NULL);
  g_object_set (G_OBJECT (bin->encoder), "iframeinterval", config->iframeinterval, NULL);
  g_object_set (G_OBJECT (bin->encoder), "bufapi-version", 1, NULL);

  switch (config->codec) {
    case NV_DS_ENCODER_H264:
      bin->codecparse = gst_element_factory_make ("h264parse", "h264-parser");
      break;
    case NV_DS_ENCODER_H265:
      bin->codecparse = gst_element_factory_make ("h265parse", "h265-parser");
      break;
    case NV_DS_ENCODER_MPEG4:
      bin->codecparse = gst_element_factory_make ("mpeg4videoparse", "mpeg4-parser");
      break;
    default:
      goto done;
  }

  g_snprintf (elem_name, sizeof (elem_name), "sink_sub_bin_mux%d", uid);
  switch (config->container) {
    case NV_DS_CONTAINER_MP4:
      bin->mux = gst_element_factory_make (NVDS_ELEM_MUX_MP4, elem_name);
      break;
    case NV_DS_CONTAINER_MKV:
      bin->mux = gst_element_factory_make (NVDS_ELEM_MKV, elem_name);
      break;
    default:
      goto done;
  }
  if (!bin->mux) {
    NVGSTDS_ERR_MSG_V ("Failed to create '%s'", elem_name);
    goto done;
  }

  g_snprintf (elem_name, sizeof (elem_name), "sink_sub_bin_sink%d", uid);
  bin->sink = gst_element_factory_make (NVDS_ELEM_SINK_FILE, 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_file_path,
      "sync", FALSE, "async", FALSE, NULL);
  g_object_set (G_OBJECT (bin->transform), "gpu-id", config->gpu_id, NULL);
  gst_bin_add_many (GST_BIN (bin->bin), bin->queue,
      bin->transform, bin->codecparse, bin->cap_filter,
      bin->encoder, bin->mux, bin->sink, NULL);

  NVGSTDS_LINK_ELEMENT (bin->queue, bin->transform);

  NVGSTDS_LINK_ELEMENT (bin->transform, bin->cap_filter);
  NVGSTDS_LINK_ELEMENT (bin->cap_filter, bin->encoder);

  NVGSTDS_LINK_ELEMENT (bin->encoder, bin->codecparse);
  NVGSTDS_LINK_ELEMENT (bin->codecparse, bin->mux);
  NVGSTDS_LINK_ELEMENT (bin->mux, bin->sink);

  NVGSTDS_BIN_ADD_GHOST_PAD (bin->bin, bin->queue, "sink");

  ret = TRUE;

done:
  if (caps) {
    gst_caps_unref (caps);
  }
  if (!ret) {
    NVGSTDS_ERR_MSG_V ("%s failed", __func__);
  }
  return ret;
}

static gboolean
start_rtsp_streaming (guint rtsp_port_num, guint updsink_port_num,
                      NvDsEncoderType enctype)
{
  GstRTSPServer *server;
  GstRTSPMountPoints *mounts;
  GstRTSPMediaFactory *factory;
  char udpsrc_pipeline[512];

  char port_num_Str[64] = { 0 };
  char *encoder_name;

  if (enctype == NV_DS_ENCODER_H264) {
    encoder_name = "H264";
  } else if (enctype == NV_DS_ENCODER_H265) {
    encoder_name = "H265";
  } else {
    NVGSTDS_ERR_MSG_V ("%s failed", __func__);
    return FALSE;
  }

  sprintf (udpsrc_pipeline,
      "( udpsrc name=pay0 port=%d caps=\"application/x-rtp, media=video, "
      "clock-rate=90000, encoding-name=%s, payload=96 \" )",
      updsink_port_num, encoder_name);

  sprintf (port_num_Str, "%d", rtsp_port_num);

  server = gst_rtsp_server_new ();
  g_object_set (server, "service", port_num_Str, NULL);

  mounts = gst_rtsp_server_get_mount_points (server);

  factory = gst_rtsp_media_factory_new ();
  gst_rtsp_media_factory_set_launch (factory, udpsrc_pipeline);

  gst_rtsp_mount_points_add_factory (mounts, "/ds-test", factory);

  g_object_unref (mounts);

  gst_rtsp_server_attach (server, NULL);

  g_print
      ("\n *** DeepStream: Launched RTSP Streaming at rtsp://localhost:%d/ds-test ***\n\n",
      rtsp_port_num);

  return TRUE;
}

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

  //guint rtsp_port_num = g_rtsp_port_num++;
  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;
  }

  caps = gst_caps_from_string ("video/x-raw(memory:NVMM), format=I420, width=1920, height=1080");
  g_object_set (G_OBJECT (bin->cap_filter), "caps", caps, NULL);

  g_snprintf (encode_name, sizeof (encode_name), "sink_sub_bin_encoder%d", uid);
  g_snprintf (rtppay_name, sizeof (rtppay_name), "sink_sub_bin_rtppay%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, encode_name);
      bin->rtppay = gst_element_factory_make ("rtph264pay", rtppay_name);
      break;
    case NV_DS_ENCODER_H265:
      bin->codecparse = gst_element_factory_make ("h265parse", "h265-parser");
      bin->encoder = gst_element_factory_make (NVDS_ELEM_ENC_H265, encode_name);
      bin->rtppay = gst_element_factory_make ("rtph265pay", rtppay_name);
      break;
    default:
      goto done;
  }

  if (!bin->encoder) {
    NVGSTDS_ERR_MSG_V ("Failed to create '%s'", encode_name);
    goto done;
  }

  if (!bin->rtppay) {
    NVGSTDS_ERR_MSG_V ("Failed to create '%s'", rtppay_name);
    goto done;
  }

  g_object_set (G_OBJECT (bin->encoder), "bitrate", config->bitrate, 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

  g_snprintf (elem_name, sizeof (elem_name), "sink_sub_bin_udpsink%d", uid);
  bin->sink = gst_element_factory_make ("udpsink", elem_name);
  if (!bin->sink) {
    NVGSTDS_ERR_MSG_V ("Failed to create '%s'", elem_name);
    goto done;
  }
  g_object_set (G_OBJECT (bin->sink), "host", "224.224.255.255", "port",
      config->udp_port, "async", FALSE, "sync", 0, NULL);

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

  NVGSTDS_LINK_ELEMENT (bin->queue, bin->transform);
  NVGSTDS_LINK_ELEMENT (bin->transform, bin->cap_filter);
  NVGSTDS_LINK_ELEMENT (bin->cap_filter, bin->encoder);
  NVGSTDS_LINK_ELEMENT (bin->encoder, bin->rtppay);
  NVGSTDS_LINK_ELEMENT (bin->rtppay, bin->sink);

  NVGSTDS_BIN_ADD_GHOST_PAD (bin->bin, bin->queue, "sink");

  ret = TRUE;

  ret = start_rtsp_streaming (config->rtsp_port, config->udp_port, config->codec);
  if (ret != TRUE) {
    g_print ("%s: start_rtsp_straming function failed\n", __func__);
  }

done:
  if (caps) {
    gst_caps_unref (caps);
  }
  if (!ret) {
    NVGSTDS_ERR_MSG_V ("%s failed", __func__);
  }
  return ret;
}
static gboolean
create_udpsink_bin_1 (NvDsSinkEncoderConfig * config, NvDsSinkBinSubBin * bin)
{
  GstCaps *caps = NULL;
  gboolean ret = FALSE;
  gchar elem_name[50];
  gchar encode_name[50];
  gchar rtppay_name[50];

  //guint rtsp_port_num = g_rtsp_port_num++;
  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;
  }

  caps = gst_caps_from_string ("video/x-raw(memory:NVMM), format=I420, width=1280, height=720");
  g_object_set (G_OBJECT (bin->cap_filter), "caps", caps, NULL);

  g_snprintf (encode_name, sizeof (encode_name), "sink_sub_bin_encoder%d", uid);
  g_snprintf (rtppay_name, sizeof (rtppay_name), "sink_sub_bin_rtppay%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, encode_name);
      bin->rtppay = gst_element_factory_make ("rtph264pay", rtppay_name);
      break;
    case NV_DS_ENCODER_H265:
      bin->codecparse = gst_element_factory_make ("h265parse", "h265-parser");
      bin->encoder = gst_element_factory_make (NVDS_ELEM_ENC_H265, encode_name);
      bin->rtppay = gst_element_factory_make ("rtph265pay", rtppay_name);
      break;
    default:
      goto done;
  }

  if (!bin->encoder) {
    NVGSTDS_ERR_MSG_V ("Failed to create '%s'", encode_name);
    goto done;
  }

  if (!bin->rtppay) {
    NVGSTDS_ERR_MSG_V ("Failed to create '%s'", rtppay_name);
    goto done;
  }

  g_object_set (G_OBJECT (bin->encoder), "bitrate", config->bitrate, 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

  g_snprintf (elem_name, sizeof (elem_name), "sink_sub_bin_udpsink%d", uid);
  bin->sink = gst_element_factory_make ("udpsink", elem_name);
  if (!bin->sink) {
    NVGSTDS_ERR_MSG_V ("Failed to create '%s'", elem_name);
    goto done;
  }
  g_object_set (G_OBJECT (bin->sink), "host", "224.224.255.255", "port",
      config->udp_port, "async", FALSE, "sync", 0, NULL);

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

  NVGSTDS_LINK_ELEMENT (bin->queue, bin->transform);
  NVGSTDS_LINK_ELEMENT (bin->transform, bin->cap_filter);
  NVGSTDS_LINK_ELEMENT (bin->cap_filter, bin->encoder);
  NVGSTDS_LINK_ELEMENT (bin->encoder, bin->rtppay);
  NVGSTDS_LINK_ELEMENT (bin->rtppay, bin->sink);

  NVGSTDS_BIN_ADD_GHOST_PAD (bin->bin, bin->queue, "sink");

  ret = TRUE;

  ret = start_rtsp_streaming (config->rtsp_port, config->udp_port, config->codec);
  if (ret != TRUE) {
    g_print ("%s: start_rtsp_straming function failed\n", __func__);
  }

done:
  if (caps) {
    gst_caps_unref (caps);
  }
  if (!ret) {
    NVGSTDS_ERR_MSG_V ("%s failed", __func__);
  }
  return ret;
}
gboolean
create_sink_bin (guint num_sub_bins, NvDsSinkSubBinConfig * config_array,
    NvDsSinkBin * bin, guint index)
{
  gboolean ret = FALSE;
  guint i;

  bin->bin = gst_bin_new ("sink_bin");
  if (!bin->bin) {
    NVGSTDS_ERR_MSG_V ("Failed to create element 'sink_bin'");
    goto done;
  }

  bin->queue = gst_element_factory_make (NVDS_ELEM_QUEUE, "sink_bin_queue");
  if (!bin->queue) {
    NVGSTDS_ERR_MSG_V ("Failed to create element 'sink_bin_queue'");
    goto done;
  }

  gst_bin_add (GST_BIN (bin->bin), bin->queue);

  NVGSTDS_BIN_ADD_GHOST_PAD (bin->bin, bin->queue, "sink");

  bin->tee = gst_element_factory_make (NVDS_ELEM_TEE, "sink_bin_tee");
  if (!bin->tee) {
    NVGSTDS_ERR_MSG_V ("Failed to create element 'sink_bin_tee'");
    goto done;
  }

  gst_bin_add (GST_BIN (bin->bin), bin->tee);

  NVGSTDS_LINK_ELEMENT (bin->queue, bin->tee);

  for (i = 0; i < num_sub_bins; i++) {
    if (!config_array[i].enable) {
      continue;
    }
    if (config_array[i].source_id != index) {
      continue;
    }
    switch (config_array[i].type) {
      case NV_DS_SINK_RENDER_EGL:
      case NV_DS_SINK_RENDER_OVERLAY:
      case NV_DS_SINK_FAKE:
        config_array[i].render_config.type = config_array[i].type;
        if (!create_render_bin (&config_array[i].render_config,
                &bin->sub_bins[i]))
          goto done;
        break;
      case NV_DS_SINK_ENCODE_FILE:
        if (!create_encode_file_bin (&config_array[i].encoder_config,
                &bin->sub_bins[i]))
          goto done;
        break;
      case NV_DS_SINK_UDPSINK:
		if (i = 0) {
			if (!create_udpsink_bin_0 (&config_array[i].encoder_config,
                                &bin->sub_bins[i]))
                          goto done;
		} else if (i = 1) {
			if (!create_udpsink_bin_1 (&config_array[i].encoder_config,
				&bin->sub_bins[i]))
                          goto done;
		} else {
			if (!create_udpsink_bin_0 (&config_array[i].encoder_config,
                                &bin->sub_bins[i]))
                          goto done;
		}
        break;
      default:
        goto done;
    }
    gst_bin_add (GST_BIN (bin->bin), bin->sub_bins[i].bin);

    if (!link_element_to_tee_src_pad (bin->tee, bin->sub_bins[i].bin)) {
      goto done;
    }
    bin->num_bins++;
  }

  if (bin->num_bins == 0) {
    NvDsSinkRenderConfig config;
    config.type = NV_DS_SINK_FAKE;
    if (!create_render_bin (&config, &bin->sub_bins[0]))
      goto done;
    gst_bin_add (GST_BIN (bin->bin), bin->sub_bins[0].bin);
    if (!link_element_to_tee_src_pad (bin->tee, bin->sub_bins[0].bin)) {
      goto done;
    }
    bin->num_bins = 1;
  }

  ret = TRUE;
done:
  if (!ret) {
    NVGSTDS_ERR_MSG_V ("%s failed", __func__);
  }
  return ret;
}

Thanks.

Hi,
FYI. Please refer to following modification:

static gboolean
create_udpsink_bin (NvDsSinkEncoderConfig * config, NvDsSinkBinSubBin * bin, <b>gint i</b>)
{
...
g_print("i = %d \n", i);
if (i > 1)
  caps = gst_caps_from_string ("video/x-raw(memory:NVMM),format=I420,width=1280,height=720");
else
  caps = gst_caps_from_string ("video/x-raw(memory:NVMM), format=I420");
...
}
case NV_DS_SINK_UDPSINK:
  if (!create_udpsink_bin (&config_array[i].encoder_config,
          &bin->sub_bins[i], <b>i</b>))
    goto done;

The print shows two RTSP streams are launched:

i = 1

 *** DeepStream: Launched RTSP Streaming at rtsp://localhost:8554/ds-test ***

i = 2

 *** DeepStream: Launched RTSP Streaming at rtsp://localhost:8555/ds-test ***

Hi,
I solved it, too.
My solution is that I used “switch…case…” replaced “if…else…”, It worked well.
I don’t know why I used “if…else…”, it has error.
The following is the code segment:

case NV_DS_SINK_UDPSINK:
	switch (i) {
	  case 0:
            if (!create_udpsink_bin_720p (&config_array[i].encoder_config,
                    &bin->sub_bins[i]))
            goto done;
	    break;
	  case 1:
            if (!create_udpsink_bin_1080p (&config_array[i].encoder_config,
                    &bin->sub_bins[i]))
            goto done;
	    break;
	}
      break;

Hoping to help someone who has this need, too.

Thanks.