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.