Nvmultiurisrcbin
This commit is contained in:
parent
87afe7ac37
commit
47ce8c5fa8
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
@ -75,6 +75,9 @@
|
|||||||
"charconv": "cpp",
|
"charconv": "cpp",
|
||||||
"complex": "cpp",
|
"complex": "cpp",
|
||||||
"typeindex": "cpp",
|
"typeindex": "cpp",
|
||||||
"variant": "cpp"
|
"variant": "cpp",
|
||||||
|
"shared_mutex": "cpp",
|
||||||
|
"cfenv": "cpp",
|
||||||
|
"stream_ref": "cpp"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -27,5 +27,31 @@
|
|||||||
"FACE_NET_WIDTH": 160,
|
"FACE_NET_WIDTH": 160,
|
||||||
"FACE_NET_HEIGHT": 160,
|
"FACE_NET_HEIGHT": 160,
|
||||||
"ll-config-file": "../data/tracker_configs/config_tracker_NvDCF_perf.yml",
|
"ll-config-file": "../data/tracker_configs/config_tracker_NvDCF_perf.yml",
|
||||||
"ll-lib-file": "../data/tracker_configs/libnvds_nvmultiobjecttracker.so"
|
"ll-lib-file": "../data/tracker_configs/libnvds_nvmultiobjecttracker.so",
|
||||||
|
"dynamic_add_remove": true,
|
||||||
|
"nvmultiurisrc": {
|
||||||
|
"uri-list": "",
|
||||||
|
"max-batch-size": 20,
|
||||||
|
"live-source": 1,
|
||||||
|
"batched-push-timeout": 33333,
|
||||||
|
"rtsp-reconnect-interval": 1,
|
||||||
|
"rtsp-reconnect-attempts": 10,
|
||||||
|
"drop-pipeline-eos": true,
|
||||||
|
"drop-frame-interval": 5,
|
||||||
|
"file-loop": false,
|
||||||
|
"width": 1920,
|
||||||
|
"height": 1080,
|
||||||
|
"cudadec-memtype": 0,
|
||||||
|
"latency": 200,
|
||||||
|
"sensor-id-list": "",
|
||||||
|
"sensor-name-list": "",
|
||||||
|
"buffer-pool-size": 16,
|
||||||
|
"ip-address": "localhost",
|
||||||
|
"port": "9456",
|
||||||
|
"disable-audio": true,
|
||||||
|
"config-file-path": "",
|
||||||
|
"max-latency": 1000000,
|
||||||
|
"num-extra-surfaces": 1,
|
||||||
|
"num-surfaces-per-frame": 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -27,6 +27,9 @@ PipelineManager::PipelineManager(int num_sources, char** url_camera)
|
|||||||
gst_init(&num_sources, &url_camera);
|
gst_init(&num_sources, &url_camera);
|
||||||
g_run_forever = atoi("0");
|
g_run_forever = atoi("0");
|
||||||
loop = g_main_loop_new(NULL, FALSE);
|
loop = g_main_loop_new(NULL, FALSE);
|
||||||
|
const auto& config = ConfigManager::get_instance().get_config();
|
||||||
|
|
||||||
|
dynamic_add_remove = config["dynamic_add_remove"];
|
||||||
}
|
}
|
||||||
|
|
||||||
int PipelineManager::create_pipeline() {
|
int PipelineManager::create_pipeline() {
|
||||||
@ -204,6 +207,16 @@ bool PipelineManager::playing_pipeline(int num_sources, char** url_camera) {
|
|||||||
gst_object_unref(pipeline);
|
gst_object_unref(pipeline);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Wait for state change to complete
|
||||||
|
// GstState state;
|
||||||
|
// GstState pending;
|
||||||
|
// GstStateChangeReturn state_ret = gst_element_get_state(pipeline, &state,
|
||||||
|
// &pending, 5 * GST_SECOND); if (state_ret == GST_STATE_CHANGE_SUCCESS) {
|
||||||
|
// g_print("***************Pipeline is in PLAYING state\n");
|
||||||
|
// } else {
|
||||||
|
// g_printerr("***************Failed to change pipeline state\n");
|
||||||
|
// }
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,59 +242,119 @@ bool PipelineManager::setup_pipeline() {
|
|||||||
// this is the running branch of the if statement for none-jetson platforms
|
// this is the running branch of the if statement for none-jetson platforms
|
||||||
// (without a transform_jetson plugin before the sink plugin) custom_plugin
|
// (without a transform_jetson plugin before the sink plugin) custom_plugin
|
||||||
// is dsexample pluging
|
// is dsexample pluging
|
||||||
if (sink_manager->display_output < 3) {
|
if (dynamic_add_remove == false) {
|
||||||
gst_bin_add_many(GST_BIN(pipeline),
|
if (sink_manager->display_output < 3) {
|
||||||
nv_infer_server_manager->primary_detector,
|
gst_bin_add_many(GST_BIN(pipeline),
|
||||||
nv_tracker_manager->tracker,
|
nv_infer_server_manager->primary_detector,
|
||||||
face_nv_infer_server_manager->face_detector,
|
nv_tracker_manager->tracker,
|
||||||
// gstds_example_manager->custom_plugin,
|
face_nv_infer_server_manager->face_detector,
|
||||||
tiler_manager->tiler, queue_array[2].queue,
|
// gstds_example_manager->custom_plugin,
|
||||||
nv_video_convert_manager->nvvidconv,
|
tiler_manager->tiler, queue_array[2].queue,
|
||||||
nv_osd_manager->nvosd, sink_manager->sink, NULL);
|
nv_video_convert_manager->nvvidconv,
|
||||||
|
nv_osd_manager->nvosd, sink_manager->sink, NULL);
|
||||||
|
|
||||||
/* we link the elements together
|
/* we link the elements together
|
||||||
* nvstreammux -> nvinfer -> nvtiler -> nvvidconv -> nvosd ->
|
* nvstreammux -> nvinfer -> nvtiler -> nvvidconv -> nvosd ->
|
||||||
* video-renderer */
|
* video-renderer */
|
||||||
if (!gst_element_link_many(streammux_manager->streammux,
|
if (!gst_element_link_many(
|
||||||
nv_video_convert_manager->nvvidconv,
|
streammux_manager->streammux,
|
||||||
nv_infer_server_manager->primary_detector,
|
nv_video_convert_manager->nvvidconv,
|
||||||
nv_tracker_manager->tracker,
|
nv_infer_server_manager->primary_detector,
|
||||||
face_nv_infer_server_manager->face_detector,
|
nv_tracker_manager->tracker,
|
||||||
// gstds_example_manager->custom_plugin,
|
face_nv_infer_server_manager->face_detector,
|
||||||
tiler_manager->tiler, nv_osd_manager->nvosd,
|
// gstds_example_manager->custom_plugin,
|
||||||
sink_manager->sink, NULL)) {
|
tiler_manager->tiler, nv_osd_manager->nvosd,
|
||||||
g_printerr("Elements could not be linked.\n");
|
sink_manager->sink, NULL)) {
|
||||||
return false;
|
g_printerr("Elements could not be linked.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
gst_bin_add_many(
|
||||||
|
GST_BIN(pipeline), nv_infer_server_manager->primary_detector,
|
||||||
|
nv_tracker_manager->tracker,
|
||||||
|
face_nv_infer_server_manager->face_detector,
|
||||||
|
// gstds_example_manager->custom_plugin,
|
||||||
|
tiler_manager->tiler, queue_array[2].queue,
|
||||||
|
nv_video_convert_manager->nvvidconv, nv_osd_manager->nvosd,
|
||||||
|
sink_manager->nvvidconv_postosd, sink_manager->caps,
|
||||||
|
sink_manager->encoder, sink_manager->rtppay, sink_manager->sink,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
// Link the elements together:
|
||||||
|
// file-source -> h264-parser -> nvh264-decoder ->
|
||||||
|
// nvinfer -> nvvidconv -> nvosd -> nvvidconv_postosd ->
|
||||||
|
// caps -> encoder -> rtppay -> udpsink
|
||||||
|
if (!gst_element_link_many(
|
||||||
|
streammux_manager->streammux,
|
||||||
|
nv_video_convert_manager->nvvidconv,
|
||||||
|
nv_infer_server_manager->primary_detector,
|
||||||
|
nv_tracker_manager->tracker,
|
||||||
|
face_nv_infer_server_manager->face_detector,
|
||||||
|
// gstds_example_manager->custom_plugin,
|
||||||
|
tiler_manager->tiler, nv_osd_manager->nvosd,
|
||||||
|
sink_manager->nvvidconv_postosd, sink_manager->caps,
|
||||||
|
sink_manager->encoder, sink_manager->rtppay,
|
||||||
|
sink_manager->sink, NULL)) {
|
||||||
|
g_printerr("Elements could not be linked.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
gst_bin_add_many(GST_BIN(pipeline),
|
if (sink_manager->display_output < 3) {
|
||||||
nv_infer_server_manager->primary_detector,
|
gst_bin_add_many(GST_BIN(pipeline),
|
||||||
nv_tracker_manager->tracker,
|
nv_infer_server_manager->primary_detector,
|
||||||
face_nv_infer_server_manager->face_detector,
|
nv_tracker_manager->tracker,
|
||||||
// gstds_example_manager->custom_plugin,
|
face_nv_infer_server_manager->face_detector,
|
||||||
tiler_manager->tiler, queue_array[2].queue,
|
// gstds_example_manager->custom_plugin,
|
||||||
nv_video_convert_manager->nvvidconv,
|
tiler_manager->tiler, queue_array[2].queue,
|
||||||
nv_osd_manager->nvosd, sink_manager->nvvidconv_postosd,
|
nv_video_convert_manager->nvvidconv,
|
||||||
sink_manager->caps, sink_manager->encoder,
|
nv_osd_manager->nvosd, sink_manager->sink, NULL);
|
||||||
sink_manager->rtppay, sink_manager->sink, NULL);
|
|
||||||
|
|
||||||
// Link the elements together:
|
/* we link the elements together
|
||||||
// file-source -> h264-parser -> nvh264-decoder ->
|
* nvstreammux -> nvinfer -> nvtiler -> nvvidconv -> nvosd ->
|
||||||
// nvinfer -> nvvidconv -> nvosd -> nvvidconv_postosd ->
|
* video-renderer */
|
||||||
// caps -> encoder -> rtppay -> udpsink
|
if (!gst_element_link_many( // streammux_manager->streammux,
|
||||||
if (!gst_element_link_many(streammux_manager->streammux,
|
SourceBin::nvmultiurisrcbin,
|
||||||
nv_video_convert_manager->nvvidconv,
|
// nv_video_convert_manager->nvvidconv,
|
||||||
nv_infer_server_manager->primary_detector,
|
nv_infer_server_manager->primary_detector,
|
||||||
nv_tracker_manager->tracker,
|
nv_tracker_manager->tracker,
|
||||||
face_nv_infer_server_manager->face_detector,
|
face_nv_infer_server_manager->face_detector,
|
||||||
// gstds_example_manager->custom_plugin,
|
// gstds_example_manager->custom_plugin,
|
||||||
tiler_manager->tiler, nv_osd_manager->nvosd,
|
tiler_manager->tiler, nv_osd_manager->nvosd,
|
||||||
sink_manager->nvvidconv_postosd,
|
sink_manager->sink, NULL)) {
|
||||||
sink_manager->caps, sink_manager->encoder,
|
g_printerr("Elements could not be linked.\n");
|
||||||
sink_manager->rtppay, sink_manager->sink,
|
return false;
|
||||||
NULL)) {
|
}
|
||||||
g_printerr("Elements could not be linked.\n");
|
} else {
|
||||||
return false;
|
gst_bin_add_many(
|
||||||
|
GST_BIN(pipeline), nv_infer_server_manager->primary_detector,
|
||||||
|
nv_tracker_manager->tracker,
|
||||||
|
face_nv_infer_server_manager->face_detector,
|
||||||
|
// gstds_example_manager->custom_plugin,
|
||||||
|
tiler_manager->tiler, queue_array[2].queue,
|
||||||
|
nv_video_convert_manager->nvvidconv, nv_osd_manager->nvosd,
|
||||||
|
sink_manager->nvvidconv_postosd, sink_manager->caps,
|
||||||
|
sink_manager->encoder, sink_manager->rtppay, sink_manager->sink,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
// Link the elements together:
|
||||||
|
// file-source -> h264-parser -> nvh264-decoder ->
|
||||||
|
// nvinfer -> nvvidconv -> nvosd -> nvvidconv_postosd ->
|
||||||
|
// caps -> encoder -> rtppay -> udpsink
|
||||||
|
if (!gst_element_link_many( // streammux_manager->streammux,
|
||||||
|
SourceBin::nvmultiurisrcbin,
|
||||||
|
// nv_video_convert_manager->nvvidconv,
|
||||||
|
nv_infer_server_manager->primary_detector,
|
||||||
|
nv_tracker_manager->tracker,
|
||||||
|
face_nv_infer_server_manager->face_detector,
|
||||||
|
// gstds_example_manager->custom_plugin,
|
||||||
|
tiler_manager->tiler, nv_osd_manager->nvosd,
|
||||||
|
sink_manager->nvvidconv_postosd, sink_manager->caps,
|
||||||
|
sink_manager->encoder, sink_manager->rtppay,
|
||||||
|
sink_manager->sink, NULL)) {
|
||||||
|
g_printerr("Elements could not be linked.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -316,24 +389,39 @@ bool PipelineManager::create_pipeline_elements(int num_sources,
|
|||||||
char** url_camera) {
|
char** url_camera) {
|
||||||
streammux_manager->create_streammux(num_sources);
|
streammux_manager->create_streammux(num_sources);
|
||||||
set_cuda_device();
|
set_cuda_device();
|
||||||
gst_bin_add(GST_BIN(pipeline), streammux_manager->streammux);
|
if (dynamic_add_remove == false) {
|
||||||
// for each source generate a pad for the source, generate another pad for
|
gst_bin_add(GST_BIN(pipeline), streammux_manager->streammux);
|
||||||
// streammux, then connect the source pad to the pad of streammux
|
// for each source generate a pad for the source, generate another pad
|
||||||
|
// for streammux, then connect the source pad to the pad of streammux
|
||||||
|
|
||||||
for (guint i = 0; i < (guint)num_sources; i++) {
|
for (guint i = 0; i < (guint)num_sources; i++) {
|
||||||
GstElement* source_bin;
|
GstElement* source_bin;
|
||||||
// GstElement *source_bin = create_uridecode_bin (i,
|
// GstElement *source_bin = create_uridecode_bin (i,
|
||||||
// const_cast<char*>(first_video.c_str()));
|
// const_cast<char*>(first_video.c_str()));
|
||||||
g_print("Trying to create uridecode_bin for %s \n", url_camera[i + 1]);
|
g_print("Trying to create uridecode_bin for %s \n",
|
||||||
|
url_camera[i + 1]);
|
||||||
|
|
||||||
source_bin = SourceBin::create_uridecode_bin(
|
source_bin = SourceBin::create_uridecode_bin(
|
||||||
i, url_camera[i + 1], streammux_manager->streammux, prop);
|
i, url_camera[i + 1], streammux_manager->streammux, prop);
|
||||||
if (!source_bin) {
|
if (!source_bin) {
|
||||||
g_printerr("Failed to create source bin for %s. Exiting.\n",
|
g_printerr("Failed to create source bin for %s. Exiting.\n",
|
||||||
url_camera[i + 1]);
|
url_camera[i + 1]);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
// g_source_bin_list[i] = source_bin;
|
||||||
|
gst_bin_add(GST_BIN(pipeline), source_bin);
|
||||||
}
|
}
|
||||||
// g_source_bin_list[i] = source_bin;
|
} else {
|
||||||
|
std::ostringstream oss;
|
||||||
|
for (uint i = 0; i < (guint)num_sources; ++i) {
|
||||||
|
if (i) {
|
||||||
|
oss << ",";
|
||||||
|
}
|
||||||
|
oss << url_camera[i + 1];
|
||||||
|
}
|
||||||
|
std::string uri_list = oss.str();
|
||||||
|
GstElement* source_bin;
|
||||||
|
source_bin = SourceBin::create_nv_multi_urisrc_bin(uri_list);
|
||||||
gst_bin_add(GST_BIN(pipeline), source_bin);
|
gst_bin_add(GST_BIN(pipeline), source_bin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -55,6 +55,7 @@ class PipelineManager {
|
|||||||
public:
|
public:
|
||||||
int current_device = -1;
|
int current_device = -1;
|
||||||
struct cudaDeviceProp prop;
|
struct cudaDeviceProp prop;
|
||||||
|
bool dynamic_add_remove;
|
||||||
|
|
||||||
QueueManager queue_array[5];
|
QueueManager queue_array[5];
|
||||||
PipelineManager();
|
PipelineManager();
|
||||||
|
|||||||
@ -1,7 +1,87 @@
|
|||||||
#include "source_bin.hpp"
|
#include "source_bin.hpp"
|
||||||
|
|
||||||
// Initialize static member (required for non-const static members)
|
// Initialize static member (required for non-const static members)
|
||||||
// int MyClass::staticCounter = 0;
|
// the linker needs real storage for them.
|
||||||
|
|
||||||
|
// string statics
|
||||||
|
std::string SourceBin::ip_address;
|
||||||
|
std::string SourceBin::port;
|
||||||
|
std::string SourceBin::uri_list;
|
||||||
|
std::string SourceBin::sensor_id_list;
|
||||||
|
std::string SourceBin::sensor_name_list;
|
||||||
|
std::string SourceBin::config_file_path;
|
||||||
|
|
||||||
|
// int statics
|
||||||
|
int SourceBin::max_batch_size = 0;
|
||||||
|
int SourceBin::batched_push_timeout = 0;
|
||||||
|
int SourceBin::rtsp_reconnect_interval = 0;
|
||||||
|
int SourceBin::rtsp_reconnect_attempts = 0;
|
||||||
|
int SourceBin::drop_frame_interval = 0;
|
||||||
|
int SourceBin::width = 0;
|
||||||
|
int SourceBin::height = 0;
|
||||||
|
int SourceBin::latency = 0;
|
||||||
|
int SourceBin::cudadec_memtype = 0;
|
||||||
|
int SourceBin::buffer_pool_size = 0;
|
||||||
|
int SourceBin::max_latency = 0;
|
||||||
|
int SourceBin::num_extra_surfaces = 0;
|
||||||
|
int SourceBin::num_surfaces_per_frame = 0;
|
||||||
|
int SourceBin::live_source = 0;
|
||||||
|
|
||||||
|
// bool statics
|
||||||
|
bool SourceBin::drop_pipeline_eos = false;
|
||||||
|
bool SourceBin::file_loop = false;
|
||||||
|
bool SourceBin::disable_audio = false;
|
||||||
|
|
||||||
|
GstElement *SourceBin::nvmultiurisrcbin = NULL;
|
||||||
|
|
||||||
|
void SourceBin::configs() {
|
||||||
|
const auto &config = ConfigManager::get_instance().get_config();
|
||||||
|
// MUXER_OUTPUT_HEIGHT = config["MUXER_OUTPUT_HEIGHT"];
|
||||||
|
// MUXER_OUTPUT_WIDTH = config["MUXER_OUTPUT_WIDTH"];
|
||||||
|
// config.at("nvmultiurisrc").at("max-batch-size").get_to(max_batch_size);
|
||||||
|
// auto eos = get_nested_value<bool>(config, {"nvmultiurisrc",
|
||||||
|
// "drop-pipeline-eos"});
|
||||||
|
|
||||||
|
max_batch_size = config.at("nvmultiurisrc").at("max-batch-size").get<int>();
|
||||||
|
live_source = config.at("nvmultiurisrc").at("live-source").get<int>();
|
||||||
|
batched_push_timeout =
|
||||||
|
config.at("nvmultiurisrc").at("batched-push-timeout").get<int>();
|
||||||
|
rtsp_reconnect_interval =
|
||||||
|
config.at("nvmultiurisrc").at("rtsp-reconnect-interval").get<int>();
|
||||||
|
rtsp_reconnect_attempts =
|
||||||
|
config.at("nvmultiurisrc").at("rtsp-reconnect-attempts").get<int>();
|
||||||
|
drop_frame_interval =
|
||||||
|
config.at("nvmultiurisrc").at("drop-frame-interval").get<int>();
|
||||||
|
width = config.at("nvmultiurisrc").at("width").get<int>();
|
||||||
|
height = config.at("nvmultiurisrc").at("height").get<int>();
|
||||||
|
latency = config.at("nvmultiurisrc").at("latency").get<int>();
|
||||||
|
cudadec_memtype =
|
||||||
|
config.at("nvmultiurisrc").at("cudadec-memtype").get<int>();
|
||||||
|
buffer_pool_size =
|
||||||
|
config.at("nvmultiurisrc").at("buffer-pool-size").get<int>();
|
||||||
|
drop_pipeline_eos =
|
||||||
|
config.at("nvmultiurisrc").at("drop-pipeline-eos").get<bool>();
|
||||||
|
file_loop = config.at("nvmultiurisrc").at("file-loop").get<bool>();
|
||||||
|
disable_audio = config.at("nvmultiurisrc").at("disable-audio").get<bool>();
|
||||||
|
ip_address = config.at("nvmultiurisrc").at("ip-address").get<std::string>();
|
||||||
|
port = config.at("nvmultiurisrc").at("port").get<std::string>();
|
||||||
|
uri_list = config.at("nvmultiurisrc").at("uri-list").get<std::string>();
|
||||||
|
sensor_id_list =
|
||||||
|
config.at("nvmultiurisrc").at("sensor-id-list").get<std::string>();
|
||||||
|
sensor_name_list =
|
||||||
|
config.at("nvmultiurisrc").at("sensor-name-list").get<std::string>();
|
||||||
|
config_file_path =
|
||||||
|
config.at("nvmultiurisrc").at("config-file-path").get<std::string>();
|
||||||
|
// ****************************config_files*****************************
|
||||||
|
// /opt/nvidia/deepstream/deepstream/service-maker/sources/apps/cpp/deepstream_test5_app/test5_b16_dynamic_source.yaml
|
||||||
|
// ****************************source_config_files*****************************
|
||||||
|
// /opt/nvidia/deepstream/deepstream/service-maker/sources/apps/cpp/deepstream_test5_app/source_list_dynamic.yaml
|
||||||
|
max_latency = config.at("nvmultiurisrc").at("max-latency").get<int>();
|
||||||
|
num_extra_surfaces =
|
||||||
|
config.at("nvmultiurisrc").at("num-extra-surfaces").get<int>();
|
||||||
|
num_surfaces_per_frame =
|
||||||
|
config.at("nvmultiurisrc").at("num-surfaces-per-frame").get<int>();
|
||||||
|
}
|
||||||
|
|
||||||
// Definition of static function
|
// Definition of static function
|
||||||
void SourceBin::decodebin_child_added(GstChildProxy *child_proxy,
|
void SourceBin::decodebin_child_added(GstChildProxy *child_proxy,
|
||||||
@ -109,4 +189,189 @@ GstElement *SourceBin::create_uridecode_bin(guint index, gchar *filename,
|
|||||||
// g_source_enabled[index] = TRUE;
|
// g_source_enabled[index] = TRUE;
|
||||||
|
|
||||||
return decodebin;
|
return decodebin;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static void check_versions() {
|
||||||
|
// guint major, minor, micro, nano;
|
||||||
|
// gst_version(&major, &minor, µ, &nano);
|
||||||
|
// g_print("GStreamer version: %u.%u.%u.%u\n", major, minor, micro, nano);
|
||||||
|
|
||||||
|
// // Check if nvmultiurisrcbin is available
|
||||||
|
// GstElementFactory *factory =
|
||||||
|
// gst_element_factory_find("nvmultiurisrcbin"); if (factory) {
|
||||||
|
// // Get the plugin name from the factory
|
||||||
|
// const gchar *plugin_name =
|
||||||
|
// gst_plugin_feature_get_plugin_name(GST_PLUGIN_FEATURE(factory));
|
||||||
|
|
||||||
|
// // Find the plugin in the registry
|
||||||
|
// GstRegistry *registry = gst_registry_get();
|
||||||
|
// GstPlugin *plugin = gst_registry_find_plugin(registry, plugin_name);
|
||||||
|
|
||||||
|
// if (plugin) {
|
||||||
|
// const gchar *version = gst_plugin_get_version(plugin);
|
||||||
|
// g_print("nvmultiurisrcbin plugin: %s, version: %s\n",
|
||||||
|
// plugin_name, version); gst_object_unref(plugin);
|
||||||
|
// } else {
|
||||||
|
// g_print("nvmultiurisrcbin found (plugin: %s), but couldn't get
|
||||||
|
// version\n", plugin_name);
|
||||||
|
// }
|
||||||
|
// gst_object_unref(factory);
|
||||||
|
// } else {
|
||||||
|
// g_print("nvmultiurisrcbin not found\n");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// static void check_versions() {
|
||||||
|
// guint major, minor, micro, nano;
|
||||||
|
// gst_version(&major, &minor, µ, &nano);
|
||||||
|
// g_print("GStreamer version: %u.%u.%u.%u\n", major, minor, micro, nano);
|
||||||
|
|
||||||
|
// // Check nvmultiurisrcbin version
|
||||||
|
// GstPluginFeature *feature = gst_registry_find_feature(
|
||||||
|
// gst_registry_get(), "nvmultiurisrcbin", GST_TYPE_ELEMENT_FACTORY);
|
||||||
|
// if (feature) {
|
||||||
|
// const gchar *plugin_name =
|
||||||
|
// gst_plugin_feature_get_plugin_name(feature); GstPlugin *plugin =
|
||||||
|
// gst_registry_find_plugin(gst_registry_get(), plugin_name); if
|
||||||
|
// (plugin) {
|
||||||
|
// const gchar *version = gst_plugin_get_version(plugin);
|
||||||
|
// g_print("nvmultiurisrcbin plugin version: %s\n", version);
|
||||||
|
// gst_object_unref(plugin);
|
||||||
|
// }
|
||||||
|
// gst_object_unref(feature);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
GstElement *SourceBin::create_nv_multi_urisrc_bin(std::string filenames) {
|
||||||
|
configs();
|
||||||
|
g_print("Creating nvmultiurisrcbin for stream %s \n", filenames.c_str());
|
||||||
|
// g_source_id_list[index] = index;
|
||||||
|
gchar nvmultiurisrcbin_name[32] = {};
|
||||||
|
// the buffer can hold 31 characters + 1 null terminator.
|
||||||
|
// In g_snprintf() the second argument is the maximum number of characters
|
||||||
|
// (including the '\0') that can be written into the buffer.
|
||||||
|
g_snprintf(nvmultiurisrcbin_name, sizeof(nvmultiurisrcbin_name),
|
||||||
|
"nvmultiurisrc-bin-%02d", 0);
|
||||||
|
nvmultiurisrcbin =
|
||||||
|
gst_element_factory_make("nvmultiurisrcbin", nvmultiurisrcbin_name);
|
||||||
|
if (!nvmultiurisrcbin) {
|
||||||
|
std::cerr << "Failed to create nvmultiurisrcbin" << std::endl;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// // Try setting a config file that enables REST API
|
||||||
|
// // g_object_set(G_OBJECT(nvmultiurisrcbin), "config-file-path",
|
||||||
|
// "/etc/deepstream/rest_api.conf", NULL);
|
||||||
|
// g_object_set(G_OBJECT(nvmultiurisrcbin), "uri-list",
|
||||||
|
// ""/*filenames.c_str()*/, NULL); g_object_set(G_OBJECT(nvmultiurisrcbin),
|
||||||
|
// "max-batch-size", 20/*(gint)filenames.size()*/, NULL);
|
||||||
|
// g_object_set(G_OBJECT(nvmultiurisrcbin), "live-source", 1, NULL); //1 for
|
||||||
|
// RTSP/camera, 0 for file g_object_set(G_OBJECT(nvmultiurisrcbin),
|
||||||
|
// "batched-push-timeout", 33333, NULL); //1 for RTSP/camera, 0 for file
|
||||||
|
// g_object_set(G_OBJECT(nvmultiurisrcbin), "rtsp-reconnect-interval", 1,
|
||||||
|
// NULL);
|
||||||
|
// // g_object_set(G_OBJECT(nvmultiurisrcbin), "rtsp-reconnect-attempts",
|
||||||
|
// 10, NULL); g_object_set(G_OBJECT(nvmultiurisrcbin), "drop-pipeline-eos",
|
||||||
|
// TRUE, NULL); g_object_set(G_OBJECT(nvmultiurisrcbin),
|
||||||
|
// "drop-frame-interval", 5, NULL); //Skip frames if decoding lags behind.
|
||||||
|
// g_object_set(G_OBJECT(nvmultiurisrcbin), "cudadec-memtype", 0, NULL); //
|
||||||
|
// Memory type for CUDA decoding (0=default, 1=NVBUF_MEM_CUDA_PINNED,
|
||||||
|
// 2=NVBUF_MEM_CUDA_DEVICE, 3=NVBUF_MEM_CUDA_UNIFIED).
|
||||||
|
// g_object_set(G_OBJECT(nvmultiurisrcbin), "latency", 200, NULL); //Network
|
||||||
|
// jitter buffer latency (milliseconds). Used for RTSP.
|
||||||
|
// g_object_set(G_OBJECT(nvmultiurisrcbin), "sensor-id-list",
|
||||||
|
// ""/*"UniqueSensorId1"*/, NULL); g_object_set(G_OBJECT(nvmultiurisrcbin),
|
||||||
|
// "sensor-name-list", ""/*"UniqueSensorName1"*/, NULL);
|
||||||
|
|
||||||
|
// The property **`buffer-pool-size`** of `nvmultiurisrcbin` is **the number
|
||||||
|
// of decoded frame buffers allocated per source stream** in the internal
|
||||||
|
// buffer pool.
|
||||||
|
// ### 🔎 Details
|
||||||
|
// * Each URI (RTSP/file) source inside `nvmultiurisrcbin` uses NVIDIA’s
|
||||||
|
// decoder (`nvdec` / `nvv4l2decoder`).
|
||||||
|
// * The decoder requires a pool of surfaces (video frame buffers in GPU/CPU
|
||||||
|
// memory) that it cycles through while decoding.
|
||||||
|
// * `buffer-pool-size` defines **how many such surfaces per stream** are
|
||||||
|
// preallocated and kept ready.
|
||||||
|
|
||||||
|
// ### ⚖️ Trade-offs
|
||||||
|
|
||||||
|
// * **Small pool size**
|
||||||
|
|
||||||
|
// * Saves GPU/CPU memory.
|
||||||
|
// * But if your pipeline lags, or downstream elements (like inference or
|
||||||
|
// tiler) are slower, the decoder may run out of free buffers → frame drops
|
||||||
|
// or stuttering.
|
||||||
|
|
||||||
|
// * **Large pool size**
|
||||||
|
|
||||||
|
// * Reduces risk of frame drops during spikes in processing latency.
|
||||||
|
// * Increases GPU memory usage (each 1080p NV12 buffer is \~6 MB, so with
|
||||||
|
// 16 buffers → \~96 MB per stream).
|
||||||
|
|
||||||
|
// ### 📌 Default
|
||||||
|
|
||||||
|
// * If you don’t set it, the plugin picks an internal default (usually
|
||||||
|
// `8`).
|
||||||
|
// * Many NVIDIA sample configs set `16` for stable real-time decoding.
|
||||||
|
// means each camera/file gets 16 GPU decode buffers reserved.
|
||||||
|
|
||||||
|
// ### ✅ When to tune
|
||||||
|
|
||||||
|
// * If you have **high-resolution streams (4K, 8K)** or **many concurrent
|
||||||
|
// sources**, and see frame drops → increase `buffer-pool-size` (e.g., `24`
|
||||||
|
// or `32`).
|
||||||
|
// * If you are memory-constrained (e.g., Jetson devices), you can lower it
|
||||||
|
// (but risk frame loss).
|
||||||
|
|
||||||
|
// gchar *file_uri = g_strdup("file:///root/Put.mp4"); //=
|
||||||
|
// g_strdup_printf("file://%s", filename);
|
||||||
|
// g_object_set(G_OBJECT(nvmultiurisrcbin),
|
||||||
|
// "uri-list", "",
|
||||||
|
// "max-batch-size",20,
|
||||||
|
// "sensor-id-list","",
|
||||||
|
// "width", 1920,
|
||||||
|
// "height", 1080,
|
||||||
|
// // "gpu-id", GPU_ID,
|
||||||
|
// "sensor-name-list", "",
|
||||||
|
// "ip-address", "localhost",
|
||||||
|
// "port", "9456",
|
||||||
|
// "batched-push-timeout", 33000,
|
||||||
|
// NULL);
|
||||||
|
// g_free(file_uri);
|
||||||
|
|
||||||
|
g_object_set(G_OBJECT(nvmultiurisrcbin), "port", port.c_str(), nullptr);
|
||||||
|
g_object_set(G_OBJECT(nvmultiurisrcbin), "ip-address", ip_address.c_str(),
|
||||||
|
nullptr);
|
||||||
|
g_object_set(G_OBJECT(nvmultiurisrcbin), "batched-push-timeout",
|
||||||
|
batched_push_timeout, nullptr);
|
||||||
|
g_object_set(G_OBJECT(nvmultiurisrcbin), "max-batch-size", max_batch_size,
|
||||||
|
nullptr);
|
||||||
|
g_object_set(G_OBJECT(nvmultiurisrcbin), "drop-pipeline-eos",
|
||||||
|
drop_pipeline_eos, nullptr);
|
||||||
|
g_object_set(G_OBJECT(nvmultiurisrcbin), "rtsp-reconnect-interval",
|
||||||
|
rtsp_reconnect_interval, nullptr);
|
||||||
|
g_object_set(G_OBJECT(nvmultiurisrcbin), "live-source", live_source,
|
||||||
|
nullptr);
|
||||||
|
g_object_set(G_OBJECT(nvmultiurisrcbin), "width", width, nullptr);
|
||||||
|
g_object_set(G_OBJECT(nvmultiurisrcbin), "height", height, nullptr);
|
||||||
|
|
||||||
|
if (!nvmultiurisrcbin) {
|
||||||
|
std::cerr << "Failed to create nvmultiurisrcbin" << std::endl;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// // Set to READY state first to initialize REST server
|
||||||
|
// gst_element_set_state(nvmultiurisrcbin, GST_STATE_READY);
|
||||||
|
|
||||||
|
// // Wait a bit for initialization
|
||||||
|
// GstState state, pending;
|
||||||
|
// gst_element_get_state(nvmultiurisrcbin, &state, &pending, 2 *
|
||||||
|
// GST_SECOND);
|
||||||
|
|
||||||
|
// // Then set to PLAYING
|
||||||
|
// gst_element_set_state(nvmultiurisrcbin, GST_STATE_PLAYING);
|
||||||
|
// gst_element_get_state(nvmultiurisrcbin, &state, &pending, 2 *
|
||||||
|
// GST_SECOND);
|
||||||
|
|
||||||
|
return nvmultiurisrcbin;
|
||||||
}
|
}
|
||||||
@ -6,7 +6,10 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "config_manager.hpp"
|
||||||
#include "cuda_runtime_api.h"
|
#include "cuda_runtime_api.h"
|
||||||
|
#include "source_config.hpp"
|
||||||
|
|
||||||
#define GPU_ID 0
|
#define GPU_ID 0
|
||||||
|
|
||||||
class SourceBin {
|
class SourceBin {
|
||||||
@ -17,14 +20,25 @@ class SourceBin {
|
|||||||
struct cudaDeviceProp prop;
|
struct cudaDeviceProp prop;
|
||||||
} StreamData;
|
} StreamData;
|
||||||
|
|
||||||
|
static GstElement *nvmultiurisrcbin;
|
||||||
// Static function declaration
|
// Static function declaration
|
||||||
static void decodebin_child_added(GstChildProxy *, GObject *, gchar *,
|
static void decodebin_child_added(GstChildProxy *, GObject *, gchar *,
|
||||||
gpointer);
|
gpointer);
|
||||||
static void cb_newpad(GstElement *, GstPad *, gpointer, gboolean *);
|
static void cb_newpad(GstElement *, GstPad *, gpointer, gboolean *);
|
||||||
static GstElement *create_uridecode_bin(guint, gchar *, GstElement *,
|
static GstElement *create_uridecode_bin(guint, gchar *, GstElement *,
|
||||||
cudaDeviceProp prop);
|
cudaDeviceProp prop);
|
||||||
|
static GstElement *create_nv_multi_urisrc_bin(std::string);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static void configs();
|
||||||
|
|
||||||
|
static int max_batch_size, live_source, batched_push_timeout,
|
||||||
|
rtsp_reconnect_interval, rtsp_reconnect_attempts, drop_frame_interval,
|
||||||
|
width, height, latency, cudadec_memtype, buffer_pool_size, max_latency,
|
||||||
|
num_extra_surfaces, num_surfaces_per_frame;
|
||||||
|
static bool drop_pipeline_eos, file_loop, disable_audio;
|
||||||
|
static std::string ip_address, port, uri_list, sensor_id_list,
|
||||||
|
sensor_name_list, config_file_path;
|
||||||
// Static data member (if needed)
|
// Static data member (if needed)
|
||||||
// static int staticCounter;
|
// static int staticCounter;
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user