From 47ce8c5fa80a391c0f72bd3554f72bf5627aef20 Mon Sep 17 00:00:00 2001 From: Barzan Hayati Date: Sat, 6 Sep 2025 22:03:34 +0000 Subject: [PATCH] Nvmultiurisrcbin --- .vscode/settings.json | 5 +- data/configuration.json | 28 +++- src/pipeline_manager.cpp | 216 +++++++++++++++++++++---------- src/pipeline_manager.hpp | 1 + src/source_bin.cpp | 267 ++++++++++++++++++++++++++++++++++++++- src/source_bin.hpp | 14 ++ 6 files changed, 464 insertions(+), 67 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index b591c07..cb8a66c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -75,6 +75,9 @@ "charconv": "cpp", "complex": "cpp", "typeindex": "cpp", - "variant": "cpp" + "variant": "cpp", + "shared_mutex": "cpp", + "cfenv": "cpp", + "stream_ref": "cpp" } } \ No newline at end of file diff --git a/data/configuration.json b/data/configuration.json index 2f3a2c1..af86b08 100644 --- a/data/configuration.json +++ b/data/configuration.json @@ -27,5 +27,31 @@ "FACE_NET_WIDTH": 160, "FACE_NET_HEIGHT": 160, "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 + } } \ No newline at end of file diff --git a/src/pipeline_manager.cpp b/src/pipeline_manager.cpp index 62f0651..c8a1617 100644 --- a/src/pipeline_manager.cpp +++ b/src/pipeline_manager.cpp @@ -27,6 +27,9 @@ PipelineManager::PipelineManager(int num_sources, char** url_camera) gst_init(&num_sources, &url_camera); g_run_forever = atoi("0"); 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() { @@ -204,6 +207,16 @@ bool PipelineManager::playing_pipeline(int num_sources, char** url_camera) { gst_object_unref(pipeline); 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; } @@ -229,59 +242,119 @@ bool PipelineManager::setup_pipeline() { // this is the running branch of the if statement for none-jetson platforms // (without a transform_jetson plugin before the sink plugin) custom_plugin // is dsexample pluging - if (sink_manager->display_output < 3) { - 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->sink, NULL); + if (dynamic_add_remove == false) { + if (sink_manager->display_output < 3) { + 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->sink, NULL); - /* we link the elements together - * nvstreammux -> nvinfer -> nvtiler -> nvvidconv -> nvosd -> - * video-renderer */ - 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->sink, NULL)) { - g_printerr("Elements could not be linked.\n"); - return false; + /* we link the elements together + * nvstreammux -> nvinfer -> nvtiler -> nvvidconv -> nvosd -> + * video-renderer */ + 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->sink, NULL)) { + 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 { - 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); + if (sink_manager->display_output < 3) { + 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->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; + /* we link the elements together + * nvstreammux -> nvinfer -> nvtiler -> nvvidconv -> nvosd -> + * video-renderer */ + 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->sink, NULL)) { + 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, + 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; @@ -316,24 +389,39 @@ bool PipelineManager::create_pipeline_elements(int num_sources, char** url_camera) { streammux_manager->create_streammux(num_sources); set_cuda_device(); - gst_bin_add(GST_BIN(pipeline), streammux_manager->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 + if (dynamic_add_remove == false) { + gst_bin_add(GST_BIN(pipeline), streammux_manager->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++) { - GstElement* source_bin; - // GstElement *source_bin = create_uridecode_bin (i, - // const_cast(first_video.c_str())); - g_print("Trying to create uridecode_bin for %s \n", url_camera[i + 1]); + for (guint i = 0; i < (guint)num_sources; i++) { + GstElement* source_bin; + // GstElement *source_bin = create_uridecode_bin (i, + // const_cast(first_video.c_str())); + g_print("Trying to create uridecode_bin for %s \n", + url_camera[i + 1]); - source_bin = SourceBin::create_uridecode_bin( - i, url_camera[i + 1], streammux_manager->streammux, prop); - if (!source_bin) { - g_printerr("Failed to create source bin for %s. Exiting.\n", - url_camera[i + 1]); - return false; + source_bin = SourceBin::create_uridecode_bin( + i, url_camera[i + 1], streammux_manager->streammux, prop); + if (!source_bin) { + g_printerr("Failed to create source bin for %s. Exiting.\n", + url_camera[i + 1]); + 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); } diff --git a/src/pipeline_manager.hpp b/src/pipeline_manager.hpp index c9c7f31..fdbbda0 100644 --- a/src/pipeline_manager.hpp +++ b/src/pipeline_manager.hpp @@ -55,6 +55,7 @@ class PipelineManager { public: int current_device = -1; struct cudaDeviceProp prop; + bool dynamic_add_remove; QueueManager queue_array[5]; PipelineManager(); diff --git a/src/source_bin.cpp b/src/source_bin.cpp index 99207e0..d62e31e 100644 --- a/src/source_bin.cpp +++ b/src/source_bin.cpp @@ -1,7 +1,87 @@ #include "source_bin.hpp" // 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(config, {"nvmultiurisrc", + // "drop-pipeline-eos"}); + + max_batch_size = config.at("nvmultiurisrc").at("max-batch-size").get(); + live_source = config.at("nvmultiurisrc").at("live-source").get(); + batched_push_timeout = + config.at("nvmultiurisrc").at("batched-push-timeout").get(); + rtsp_reconnect_interval = + config.at("nvmultiurisrc").at("rtsp-reconnect-interval").get(); + rtsp_reconnect_attempts = + config.at("nvmultiurisrc").at("rtsp-reconnect-attempts").get(); + drop_frame_interval = + config.at("nvmultiurisrc").at("drop-frame-interval").get(); + width = config.at("nvmultiurisrc").at("width").get(); + height = config.at("nvmultiurisrc").at("height").get(); + latency = config.at("nvmultiurisrc").at("latency").get(); + cudadec_memtype = + config.at("nvmultiurisrc").at("cudadec-memtype").get(); + buffer_pool_size = + config.at("nvmultiurisrc").at("buffer-pool-size").get(); + drop_pipeline_eos = + config.at("nvmultiurisrc").at("drop-pipeline-eos").get(); + file_loop = config.at("nvmultiurisrc").at("file-loop").get(); + disable_audio = config.at("nvmultiurisrc").at("disable-audio").get(); + ip_address = config.at("nvmultiurisrc").at("ip-address").get(); + port = config.at("nvmultiurisrc").at("port").get(); + uri_list = config.at("nvmultiurisrc").at("uri-list").get(); + sensor_id_list = + config.at("nvmultiurisrc").at("sensor-id-list").get(); + sensor_name_list = + config.at("nvmultiurisrc").at("sensor-name-list").get(); + config_file_path = + config.at("nvmultiurisrc").at("config-file-path").get(); + // ****************************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(); + num_extra_surfaces = + config.at("nvmultiurisrc").at("num-extra-surfaces").get(); + num_surfaces_per_frame = + config.at("nvmultiurisrc").at("num-surfaces-per-frame").get(); +} // Definition of static function 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; 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; } \ No newline at end of file diff --git a/src/source_bin.hpp b/src/source_bin.hpp index 76876b0..93be101 100644 --- a/src/source_bin.hpp +++ b/src/source_bin.hpp @@ -6,7 +6,10 @@ #include #include +#include "config_manager.hpp" #include "cuda_runtime_api.h" +#include "source_config.hpp" + #define GPU_ID 0 class SourceBin { @@ -17,14 +20,25 @@ class SourceBin { struct cudaDeviceProp prop; } StreamData; + static GstElement *nvmultiurisrcbin; // Static function declaration static void decodebin_child_added(GstChildProxy *, GObject *, gchar *, gpointer); static void cb_newpad(GstElement *, GstPad *, gpointer, gboolean *); static GstElement *create_uridecode_bin(guint, gchar *, GstElement *, cudaDeviceProp prop); + static GstElement *create_nv_multi_urisrc_bin(std::string); 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 int staticCounter; };