546 lines
19 KiB
C
Executable File
546 lines
19 KiB
C
Executable File
/*
|
|
* Copyright (c) 2018-2021, 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 <string.h>
|
|
#include "deepstream_app.h"
|
|
#include "deepstream_config_file_parser.h"
|
|
|
|
#define CONFIG_GROUP_APP "application"
|
|
#define CONFIG_GROUP_APP_ENABLE_PERF_MEASUREMENT "enable-perf-measurement"
|
|
#define CONFIG_GROUP_APP_PERF_MEASUREMENT_INTERVAL "perf-measurement-interval-sec"
|
|
#define CONFIG_GROUP_APP_GIE_OUTPUT_DIR "gie-kitti-output-dir"
|
|
#define CONFIG_GROUP_APP_GIE_TRACK_OUTPUT_DIR "kitti-track-output-dir"
|
|
|
|
#define CONFIG_GROUP_TESTS "tests"
|
|
#define CONFIG_GROUP_TESTS_FILE_LOOP "file-loop"
|
|
#define CONFIG_GROUP_TESTS_PIPELINE_RECREATE_SEC "pipeline-recreate-sec"
|
|
|
|
#define CONFIG_GROUP_SOURCE_SGIE_BATCH_SIZE "sgie-batch-size"
|
|
|
|
GST_DEBUG_CATEGORY_EXTERN (APP_CFG_PARSER_CAT);
|
|
|
|
|
|
#define CHECK_ERROR(error) \
|
|
if (error) { \
|
|
GST_CAT_ERROR (APP_CFG_PARSER_CAT, "%s", error->message); \
|
|
goto done; \
|
|
}
|
|
|
|
NvDsSourceConfig global_source_config;
|
|
|
|
static gboolean
|
|
parse_source_list (NvDsConfig * config, GKeyFile * key_file,
|
|
gchar * cfg_file_path)
|
|
{
|
|
gboolean ret = FALSE;
|
|
gchar **keys = NULL;
|
|
gchar **key = NULL;
|
|
GError *error = NULL;
|
|
gsize num_strings;
|
|
|
|
keys = g_key_file_get_keys (key_file, CONFIG_GROUP_SOURCE_LIST, NULL, &error);
|
|
CHECK_ERROR (error);
|
|
|
|
for (key = keys; *key; key++) {
|
|
if (!g_strcmp0 (*key, CONFIG_GROUP_SOURCE_LIST_NUM_SOURCE_BINS)) {
|
|
config->total_num_sources =
|
|
g_key_file_get_integer (key_file, CONFIG_GROUP_SOURCE_LIST,
|
|
CONFIG_GROUP_SOURCE_LIST_NUM_SOURCE_BINS, &error);
|
|
CHECK_ERROR (error);
|
|
} else if (!g_strcmp0 (*key, CONFIG_GROUP_SOURCE_LIST_URI_LIST)) {
|
|
config->uri_list =
|
|
g_key_file_get_string_list (key_file, CONFIG_GROUP_SOURCE_LIST,
|
|
CONFIG_GROUP_SOURCE_LIST_URI_LIST, &num_strings, &error);
|
|
if (num_strings > MAX_SOURCE_BINS) {
|
|
NVGSTDS_ERR_MSG_V ("App supports max %d sources", MAX_SOURCE_BINS);
|
|
goto done;
|
|
}
|
|
CHECK_ERROR (error);
|
|
} else if (!g_strcmp0 (*key, CONFIG_GROUP_SOURCE_SGIE_BATCH_SIZE)) {
|
|
config->sgie_batch_size =
|
|
g_key_file_get_integer (key_file, CONFIG_GROUP_SOURCE_LIST,
|
|
CONFIG_GROUP_SOURCE_SGIE_BATCH_SIZE, &error);
|
|
CHECK_ERROR (error);
|
|
} else {
|
|
NVGSTDS_WARN_MSG_V ("Unknown key '%s' for group [%s]", *key,
|
|
CONFIG_GROUP_SOURCE_LIST);
|
|
}
|
|
}
|
|
|
|
if (g_key_file_has_key (key_file, CONFIG_GROUP_SOURCE_LIST,
|
|
CONFIG_GROUP_SOURCE_LIST_URI_LIST, &error)) {
|
|
if (g_key_file_has_key (key_file, CONFIG_GROUP_SOURCE_LIST,
|
|
CONFIG_GROUP_SOURCE_LIST_NUM_SOURCE_BINS, &error)) {
|
|
if (num_strings != config->total_num_sources) {
|
|
NVGSTDS_ERR_MSG_V ("Mismatch in URIs provided and num-source-bins.");
|
|
goto done;
|
|
}
|
|
} else {
|
|
config->total_num_sources = num_strings;
|
|
}
|
|
}
|
|
|
|
ret = TRUE;
|
|
done:
|
|
if (error) {
|
|
g_error_free (error);
|
|
}
|
|
if (keys) {
|
|
g_strfreev (keys);
|
|
}
|
|
if (!ret) {
|
|
NVGSTDS_ERR_MSG_V ("%s failed", __func__);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static gboolean
|
|
set_source_all_configs (NvDsConfig * config, gchar * cfg_file_path)
|
|
{
|
|
guint i = 0;
|
|
for (i = 0; i < config->total_num_sources; i++) {
|
|
config->multi_source_config[i] = global_source_config;
|
|
config->multi_source_config[i].camera_id = i;
|
|
if (config->uri_list) {
|
|
char *uri = config->uri_list[i];
|
|
if (g_str_has_prefix (config->uri_list[i], "file://")) {
|
|
config->multi_source_config[i].type = NV_DS_SOURCE_URI;
|
|
config->multi_source_config[i].uri = g_strdup (uri + 7);
|
|
config->multi_source_config[i].uri =
|
|
g_strdup_printf ("file://%s",
|
|
get_absolute_file_path (cfg_file_path,
|
|
config->multi_source_config[i].uri));
|
|
} else if (g_str_has_prefix (config->uri_list[i], "rtsp://")) {
|
|
config->multi_source_config[i].type = NV_DS_SOURCE_RTSP;
|
|
config->multi_source_config[i].uri = config->uri_list[i];
|
|
} else {
|
|
gchar *source_id_start_ptr = uri + 4;
|
|
gchar *source_id_end_ptr = NULL;
|
|
long camera_id =
|
|
g_ascii_strtoull (source_id_start_ptr, &source_id_end_ptr, 10);
|
|
if (source_id_start_ptr == source_id_end_ptr
|
|
|| *source_id_end_ptr != '\0') {
|
|
NVGSTDS_ERR_MSG_V
|
|
("Incorrect URI for camera source %s. FORMAT: <usb/csi>:<dev_node/sensor_id>",
|
|
uri);
|
|
return FALSE;
|
|
}
|
|
if (g_str_has_prefix (config->uri_list[i], "csi:")) {
|
|
config->multi_source_config[i].type = NV_DS_SOURCE_CAMERA_CSI;
|
|
config->multi_source_config[i].camera_csi_sensor_id = camera_id;
|
|
} else if (g_str_has_prefix (config->uri_list[i], "usb:")) {
|
|
config->multi_source_config[i].type = NV_DS_SOURCE_CAMERA_V4L2;
|
|
config->multi_source_config[i].camera_v4l2_dev_node = camera_id;
|
|
} else {
|
|
NVGSTDS_ERR_MSG_V ("URI %d (%s) not in proper format.", i,
|
|
config->uri_list[i]);
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
static gboolean
|
|
parse_tests (NvDsConfig *config, GKeyFile *key_file)
|
|
{
|
|
gboolean ret = FALSE;
|
|
gchar **keys = NULL;
|
|
gchar **key = NULL;
|
|
GError *error = NULL;
|
|
|
|
keys = g_key_file_get_keys (key_file, CONFIG_GROUP_TESTS, NULL, &error);
|
|
CHECK_ERROR (error);
|
|
|
|
for (key = keys; *key; key++) {
|
|
if (!g_strcmp0 (*key, CONFIG_GROUP_TESTS_FILE_LOOP)) {
|
|
config->file_loop =
|
|
g_key_file_get_integer (key_file, CONFIG_GROUP_TESTS,
|
|
CONFIG_GROUP_TESTS_FILE_LOOP, &error);
|
|
CHECK_ERROR (error);
|
|
} else if (!g_strcmp0 (*key, CONFIG_GROUP_TESTS_PIPELINE_RECREATE_SEC)) {
|
|
config->pipeline_recreate_sec =
|
|
g_key_file_get_integer (key_file, CONFIG_GROUP_TESTS,
|
|
CONFIG_GROUP_TESTS_PIPELINE_RECREATE_SEC, &error);
|
|
CHECK_ERROR (error);
|
|
} else {
|
|
NVGSTDS_WARN_MSG_V ("Unknown key '%s' for group [%s]", *key,
|
|
CONFIG_GROUP_TESTS);
|
|
}
|
|
}
|
|
|
|
ret = TRUE;
|
|
done:
|
|
if (error) {
|
|
g_error_free (error);
|
|
}
|
|
if (keys) {
|
|
g_strfreev (keys);
|
|
}
|
|
if (!ret) {
|
|
NVGSTDS_ERR_MSG_V ("%s failed", __func__);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static gboolean
|
|
parse_app (NvDsConfig *config, GKeyFile *key_file, gchar *cfg_file_path)
|
|
{
|
|
gboolean ret = FALSE;
|
|
gchar **keys = NULL;
|
|
gchar **key = NULL;
|
|
GError *error = NULL;
|
|
|
|
keys = g_key_file_get_keys (key_file, CONFIG_GROUP_APP, NULL, &error);
|
|
CHECK_ERROR (error);
|
|
|
|
for (key = keys; *key; key++) {
|
|
if (!g_strcmp0 (*key, CONFIG_GROUP_APP_ENABLE_PERF_MEASUREMENT)) {
|
|
config->enable_perf_measurement =
|
|
g_key_file_get_integer (key_file, CONFIG_GROUP_APP,
|
|
CONFIG_GROUP_APP_ENABLE_PERF_MEASUREMENT, &error);
|
|
CHECK_ERROR (error);
|
|
} else if (!g_strcmp0 (*key, CONFIG_GROUP_APP_PERF_MEASUREMENT_INTERVAL)) {
|
|
config->perf_measurement_interval_sec =
|
|
g_key_file_get_integer (key_file, CONFIG_GROUP_APP,
|
|
CONFIG_GROUP_APP_PERF_MEASUREMENT_INTERVAL, &error);
|
|
CHECK_ERROR (error);
|
|
} else if (!g_strcmp0 (*key, CONFIG_GROUP_APP_GIE_OUTPUT_DIR)) {
|
|
config->bbox_dir_path = get_absolute_file_path (cfg_file_path,
|
|
g_key_file_get_string (key_file, CONFIG_GROUP_APP,
|
|
CONFIG_GROUP_APP_GIE_OUTPUT_DIR, &error));
|
|
CHECK_ERROR (error);
|
|
} else if (!g_strcmp0 (*key, CONFIG_GROUP_APP_GIE_TRACK_OUTPUT_DIR)) {
|
|
config->kitti_track_dir_path = get_absolute_file_path (cfg_file_path,
|
|
g_key_file_get_string (key_file, CONFIG_GROUP_APP,
|
|
CONFIG_GROUP_APP_GIE_TRACK_OUTPUT_DIR, &error));
|
|
CHECK_ERROR (error);
|
|
} else {
|
|
NVGSTDS_WARN_MSG_V ("Unknown key '%s' for group [%s]", *key,
|
|
CONFIG_GROUP_APP);
|
|
}
|
|
}
|
|
|
|
ret = TRUE;
|
|
done:
|
|
if (error) {
|
|
g_error_free (error);
|
|
}
|
|
if (keys) {
|
|
g_strfreev (keys);
|
|
}
|
|
if (!ret) {
|
|
NVGSTDS_ERR_MSG_V ("%s failed", __func__);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
gboolean
|
|
parse_config_file (NvDsConfig *config, gchar *cfg_file_path)
|
|
{
|
|
GKeyFile *cfg_file = g_key_file_new ();
|
|
GError *error = NULL;
|
|
gboolean ret = FALSE;
|
|
gchar **groups = NULL;
|
|
gchar **group;
|
|
guint i, j;
|
|
|
|
config->source_list_enabled = FALSE;
|
|
|
|
if (!APP_CFG_PARSER_CAT) {
|
|
GST_DEBUG_CATEGORY_INIT (APP_CFG_PARSER_CAT, "NVDS_CFG_PARSER", 0, NULL);
|
|
}
|
|
|
|
if (!g_key_file_load_from_file (cfg_file, cfg_file_path, G_KEY_FILE_NONE,
|
|
&error)) {
|
|
GST_CAT_ERROR (APP_CFG_PARSER_CAT, "Failed to load uri file: %s",
|
|
error->message);
|
|
goto done;
|
|
}
|
|
|
|
if (g_key_file_has_group (cfg_file, CONFIG_GROUP_SOURCE_LIST)) {
|
|
if (!parse_source_list (config, cfg_file, cfg_file_path)) {
|
|
GST_CAT_ERROR (APP_CFG_PARSER_CAT, "Failed to parse '%s' group",
|
|
CONFIG_GROUP_SOURCE_LIST);
|
|
goto done;
|
|
}
|
|
config->num_source_sub_bins = config->total_num_sources;
|
|
config->source_list_enabled = TRUE;
|
|
if (!g_key_file_has_group (cfg_file, CONFIG_GROUP_SOURCE_ALL)) {
|
|
NVGSTDS_ERR_MSG_V ("[source-attr-all] group not present.");
|
|
ret = FALSE;
|
|
goto done;
|
|
}
|
|
g_key_file_remove_group (cfg_file, CONFIG_GROUP_SOURCE_LIST, &error);
|
|
}
|
|
if (g_key_file_has_group (cfg_file, CONFIG_GROUP_SOURCE_ALL)) {
|
|
if (!parse_source (&global_source_config,
|
|
cfg_file, CONFIG_GROUP_SOURCE_ALL, cfg_file_path)) {
|
|
GST_CAT_ERROR (APP_CFG_PARSER_CAT, "Failed to parse '%s' group",
|
|
CONFIG_GROUP_SOURCE_LIST);
|
|
goto done;
|
|
}
|
|
if (!set_source_all_configs (config, cfg_file_path)) {
|
|
ret = FALSE;
|
|
goto done;
|
|
}
|
|
g_key_file_remove_group (cfg_file, CONFIG_GROUP_SOURCE_ALL, &error);
|
|
}
|
|
|
|
groups = g_key_file_get_groups (cfg_file, NULL);
|
|
for (group = groups; *group; group++) {
|
|
gboolean parse_err = FALSE;
|
|
GST_CAT_DEBUG (APP_CFG_PARSER_CAT, "Parsing group: %s", *group);
|
|
if (!g_strcmp0 (*group, CONFIG_GROUP_APP)) {
|
|
parse_err = !parse_app (config, cfg_file, cfg_file_path);
|
|
}
|
|
|
|
if (!strncmp (*group, CONFIG_GROUP_SOURCE,
|
|
sizeof (CONFIG_GROUP_SOURCE) - 1)) {
|
|
if (config->num_source_sub_bins == MAX_SOURCE_BINS) {
|
|
NVGSTDS_ERR_MSG_V ("App supports max %d sources", MAX_SOURCE_BINS);
|
|
ret = FALSE;
|
|
goto done;
|
|
}
|
|
gchar *source_id_start_ptr = *group + strlen (CONFIG_GROUP_SOURCE);
|
|
gchar *source_id_end_ptr = NULL;
|
|
guint index =
|
|
g_ascii_strtoull (source_id_start_ptr, &source_id_end_ptr, 10);
|
|
if (source_id_start_ptr == source_id_end_ptr
|
|
|| *source_id_end_ptr != '\0') {
|
|
NVGSTDS_ERR_MSG_V
|
|
("Source group \"[%s]\" is not in the form \"[source<%%d>]\"",
|
|
*group);
|
|
ret = FALSE;
|
|
goto done;
|
|
}
|
|
guint source_id = 0;
|
|
if (config->source_list_enabled) {
|
|
if (index >= config->total_num_sources) {
|
|
NVGSTDS_ERR_MSG_V
|
|
("Invalid source group index %d, index cannot exceed %d", index,
|
|
config->total_num_sources);
|
|
ret = FALSE;
|
|
goto done;
|
|
}
|
|
source_id = index;
|
|
NVGSTDS_INFO_MSG_V ("Some parameters to be overwritten for group [%s]",
|
|
*group);
|
|
} else {
|
|
source_id = config->num_source_sub_bins;
|
|
}
|
|
parse_err = !parse_source (&config->multi_source_config[source_id],
|
|
cfg_file, *group, cfg_file_path);
|
|
if (config->source_list_enabled
|
|
&& config->multi_source_config[source_id].type ==
|
|
NV_DS_SOURCE_URI_MULTIPLE) {
|
|
NVGSTDS_ERR_MSG_V
|
|
("MultiURI support not available if [source-list] is provided");
|
|
ret = FALSE;
|
|
goto done;
|
|
}
|
|
if (config->multi_source_config[source_id].enable
|
|
&& !config->source_list_enabled) {
|
|
config->num_source_sub_bins++;
|
|
}
|
|
}
|
|
|
|
if (!g_strcmp0 (*group, CONFIG_GROUP_STREAMMUX)) {
|
|
parse_err = !parse_streammux (&config->streammux_config, cfg_file, cfg_file_path);
|
|
}
|
|
|
|
if (!g_strcmp0 (*group, CONFIG_GROUP_OSD)) {
|
|
parse_err = !parse_osd (&config->osd_config, cfg_file);
|
|
}
|
|
|
|
if (!g_strcmp0 (*group, CONFIG_GROUP_PREPROCESS)) {
|
|
parse_err = !parse_preprocess (&config->preprocess_config, cfg_file, cfg_file_path);
|
|
}
|
|
|
|
if (!g_strcmp0 (*group, CONFIG_GROUP_PRIMARY_GIE)) {
|
|
parse_err =
|
|
!parse_gie (&config->primary_gie_config, cfg_file,
|
|
CONFIG_GROUP_PRIMARY_GIE, cfg_file_path);
|
|
}
|
|
|
|
if (!g_strcmp0 (*group, CONFIG_GROUP_TRACKER)) {
|
|
parse_err = !parse_tracker (&config->tracker_config, cfg_file, cfg_file_path);
|
|
}
|
|
|
|
if (!strncmp (*group, CONFIG_GROUP_SECONDARY_GIE,
|
|
sizeof (CONFIG_GROUP_SECONDARY_GIE) - 1)) {
|
|
if (config->num_secondary_gie_sub_bins == MAX_SECONDARY_GIE_BINS) {
|
|
NVGSTDS_ERR_MSG_V ("App supports max %d secondary GIEs", MAX_SECONDARY_GIE_BINS);
|
|
ret = FALSE;
|
|
goto done;
|
|
}
|
|
parse_err =
|
|
!parse_gie (&config->secondary_gie_sub_bin_config[config->
|
|
num_secondary_gie_sub_bins],
|
|
cfg_file, *group, cfg_file_path);
|
|
if (config->secondary_gie_sub_bin_config[config->num_secondary_gie_sub_bins].enable){
|
|
config->num_secondary_gie_sub_bins++;
|
|
}
|
|
}
|
|
|
|
if (!strncmp (*group, CONFIG_GROUP_SINK, sizeof (CONFIG_GROUP_SINK) - 1)) {
|
|
if (config->num_sink_sub_bins == MAX_SINK_BINS) {
|
|
NVGSTDS_ERR_MSG_V ("App supports max %d sinks", MAX_SINK_BINS);
|
|
ret = FALSE;
|
|
goto done;
|
|
}
|
|
parse_err =
|
|
!parse_sink (&config->
|
|
sink_bin_sub_bin_config[config->num_sink_sub_bins], cfg_file, *group,
|
|
cfg_file_path);
|
|
if (config->
|
|
sink_bin_sub_bin_config[config->num_sink_sub_bins].enable){
|
|
config->num_sink_sub_bins++;
|
|
}
|
|
}
|
|
|
|
if (!strncmp (*group, CONFIG_GROUP_MSG_CONSUMER,
|
|
sizeof (CONFIG_GROUP_MSG_CONSUMER) - 1)) {
|
|
if (config->num_message_consumers == MAX_MESSAGE_CONSUMERS) {
|
|
NVGSTDS_ERR_MSG_V ("App supports max %d consumers", MAX_MESSAGE_CONSUMERS);
|
|
ret = FALSE;
|
|
goto done;
|
|
}
|
|
parse_err = !parse_msgconsumer (
|
|
&config->message_consumer_config[config->num_message_consumers],
|
|
cfg_file, *group, cfg_file_path);
|
|
|
|
if (config->message_consumer_config[config->num_message_consumers].enable) {
|
|
config->num_message_consumers++;
|
|
}
|
|
}
|
|
|
|
if (!g_strcmp0 (*group, CONFIG_GROUP_TILED_DISPLAY)) {
|
|
parse_err = !parse_tiled_display (&config->tiled_display_config, cfg_file);
|
|
}
|
|
|
|
if (!g_strcmp0 (*group, CONFIG_GROUP_IMG_SAVE)) {
|
|
parse_err = !parse_image_save (&config->image_save_config , cfg_file, *group, cfg_file_path);
|
|
}
|
|
|
|
if (!g_strcmp0 (*group, CONFIG_GROUP_DSANALYTICS)) {
|
|
parse_err = !parse_dsanalytics (&config->dsanalytics_config, cfg_file, cfg_file_path);
|
|
}
|
|
|
|
if (!g_strcmp0 (*group, CONFIG_GROUP_DSEXAMPLE)) {
|
|
parse_err = !parse_dsexample (&config->dsexample_config, cfg_file);
|
|
}
|
|
|
|
if (!g_strcmp0 (*group, CONFIG_GROUP_MSG_CONVERTER)) {
|
|
parse_err = !parse_msgconv (&config->msg_conv_config, cfg_file, *group, cfg_file_path);
|
|
}
|
|
|
|
if (!g_strcmp0 (*group, CONFIG_GROUP_TESTS)) {
|
|
parse_err = !parse_tests (config, cfg_file);
|
|
}
|
|
|
|
if (parse_err) {
|
|
GST_CAT_ERROR (APP_CFG_PARSER_CAT, "Failed to parse '%s' group", *group);
|
|
goto done;
|
|
}
|
|
}
|
|
|
|
/* Updating batch size when source list is enabled */
|
|
if (config->source_list_enabled == TRUE) {
|
|
/* For streammux and pgie, batch size is set to number of sources */
|
|
config->streammux_config.batch_size = config->num_source_sub_bins;
|
|
config->primary_gie_config.batch_size = config->num_source_sub_bins;
|
|
if (config->sgie_batch_size != 0) {
|
|
for (i = 0; i < config->num_secondary_gie_sub_bins; i++) {
|
|
config->secondary_gie_sub_bin_config[i].batch_size = config->sgie_batch_size;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < config->num_secondary_gie_sub_bins; i++) {
|
|
if (config->secondary_gie_sub_bin_config[i].unique_id ==
|
|
config->primary_gie_config.unique_id) {
|
|
NVGSTDS_ERR_MSG_V ("Non unique gie ids found");
|
|
ret = FALSE;
|
|
goto done;
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < config->num_secondary_gie_sub_bins; i++) {
|
|
for (j = i + 1; j < config->num_secondary_gie_sub_bins; j++) {
|
|
if (config->secondary_gie_sub_bin_config[i].unique_id ==
|
|
config->secondary_gie_sub_bin_config[j].unique_id) {
|
|
NVGSTDS_ERR_MSG_V ("Non unique gie id %d found",
|
|
config->secondary_gie_sub_bin_config[i].unique_id);
|
|
ret = FALSE;
|
|
goto done;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < config->num_source_sub_bins; i++) {
|
|
if (config->multi_source_config[i].type == NV_DS_SOURCE_URI_MULTIPLE) {
|
|
if (config->multi_source_config[i].num_sources < 1) {
|
|
config->multi_source_config[i].num_sources = 1;
|
|
}
|
|
for (j = 1; j < config->multi_source_config[i].num_sources; j++) {
|
|
if (config->num_source_sub_bins == MAX_SOURCE_BINS) {
|
|
NVGSTDS_ERR_MSG_V ("App supports max %d sources", MAX_SOURCE_BINS);
|
|
ret = FALSE;
|
|
goto done;
|
|
}
|
|
memcpy (&config->multi_source_config[config->num_source_sub_bins],
|
|
&config->multi_source_config[i],
|
|
sizeof (config->multi_source_config[i]));
|
|
config->multi_source_config[config->num_source_sub_bins].type =
|
|
NV_DS_SOURCE_URI;
|
|
config->multi_source_config[config->num_source_sub_bins].uri =
|
|
g_strdup_printf (config->multi_source_config[config->
|
|
num_source_sub_bins].uri, j);
|
|
config->num_source_sub_bins++;
|
|
}
|
|
config->multi_source_config[i].type = NV_DS_SOURCE_URI;
|
|
config->multi_source_config[i].uri =
|
|
g_strdup_printf (config->multi_source_config[i].uri, 0);
|
|
}
|
|
}
|
|
ret = TRUE;
|
|
|
|
done:
|
|
if (cfg_file) {
|
|
g_key_file_free (cfg_file);
|
|
}
|
|
|
|
if (groups) {
|
|
g_strfreev (groups);
|
|
}
|
|
|
|
if (error) {
|
|
g_error_free (error);
|
|
}
|
|
if (!ret) {
|
|
NVGSTDS_ERR_MSG_V ("%s failed", __func__);
|
|
}
|
|
return ret;
|
|
}
|