FaceRecognition/src/pipeline_manager.cpp
2025-07-01 16:22:51 +00:00

214 lines
8.1 KiB
C++

#include "pipeline_manager.hpp"
PipelineManager::PipelineManager() { ; }
PipelineManager::PipelineManager(int num_sources, char** url_camera) {
g_setenv("GST_DEBUG_DUMP_DOT_DIR", ".", TRUE);
gst_init(&num_sources, &url_camera);
g_run_forever = atoi("0");
loop = g_main_loop_new(NULL, FALSE);
}
int PipelineManager::create_pipeline() {
g_mutex_init(&eos_lock);
/* Create Pipeline element that will form a connection of other elements */
pipeline = gst_pipeline_new("BodyDetectionPipeline");
if (!pipeline) {
g_printerr("pipeline could not be created. Exiting.");
return -1;
}
return 1;
}
void PipelineManager::set_cuda_device() {
cudaGetDevice(&current_device);
cudaGetDeviceProperties(&prop, current_device);
std::cout << "Device Number: " << prop.pciDeviceID << std::endl;
std::cout << "Device name: " << prop.name << std::endl;
std::cout << "Device Version: " << prop.major << "." << prop.minor
<< std::endl;
}
char* createName(const char* str, int num) {
// Calculate the required length
// Max digits in an int is about 10 (for 32-bit int), plus 1 for null
// terminator
int length =
strlen(str) + 12; // Extra space for the number and null terminator
// Allocate memory for the new string
char* result = new char[length];
// Format the string
snprintf(result, length, "%s%d", str, num);
return result;
}
void PipelineManager::playing_pipeline(int num_sources, char** url_camera) {
/* Set the pipeline to "playing" state */
g_print("Now playing... \n");
for (int i = 0; i < num_sources; i++) {
g_print("%s, \n", url_camera[i + 1]);
}
GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS(GST_BIN(pipeline),
GST_DEBUG_GRAPH_SHOW_ALL,
sink_manager->output_sink.c_str());
gst_element_set_state(pipeline, GST_STATE_PLAYING);
}
bool PipelineManager::setup_pipeline() {
/* Set up the pipeline */
/* add all elements into the 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),
// pgie, tracker,
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,
// pgie, tracker,
gstds_example_manager->custom_plugin,
tiler_manager->tiler, nv_osd_manager->nvosd,
sink_manager->sink, NULL)) {
g_printerr(
"\033[1;31m Elements could not be linked. Exiting.\033[0m\n");
return false;
}
} else {
gst_bin_add_many(GST_BIN(pipeline),
// pgie, tracker,
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,
// pgie, tracker,
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(
"\033[1;31m Elements could not be linked. Exiting.\033[0m\n");
return false;
}
}
return true;
}
gboolean PipelineManager::event_thread_func(gpointer arg) {
DataPointer* data = static_cast<DataPointer*>(arg);
// show which source camera. called every 4o ms.
// if (value==true){
// gst_element_set_state (pipeline, GST_STATE_PAUSED);
// gst_element_set_state (pipeline, GST_STATE_PLAYING);
// IMPORTANT:
guint show_source = -1; // which source to show: should be an integer
// between the range (0, num_sources-1)
// to show the selected source number only.
// choose show_source=-1 to show the results for all the videos at once
g_object_set(G_OBJECT(data->tiler_manager->tiler), "show-source",
show_source, NULL);
return true;
}
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
for (guint i = 0; i < (guint)num_sources; i++) {
GstElement* source_bin;
// GstElement *source_bin = create_uridecode_bin (i,
// const_cast<char*>(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;
}
// g_source_bin_list[i] = source_bin;
gst_bin_add(GST_BIN(pipeline), source_bin);
}
gstds_example_manager->create_gstds_example();
tiler_manager->create_tiler(num_sources,
streammux_manager->MUXER_OUTPUT_WIDTH,
streammux_manager->MUXER_OUTPUT_HEIGHT);
nv_video_convert_manager->create_nv_video_convert();
nv_osd_manager->create_nv_osd();
/* Add queue elements between every two elements */
const char* base = "queue";
for (int i = 0; i < 5; i++) {
char* name = createName(base, i);
queue_array[i] = QueueManager(name);
}
nv_ds_logger_manager->create_nv_ds_logger();
sink_manager->create_sink(prop);
message_handling->create_message_handler(pipeline, g_run_forever, loop);
setup_pipeline();
playing_pipeline(num_sources, url_camera);
rtsp_streaming_manager->start_rtsp_streaming();
/* Wait till pipeline encounters an error or EOS */
g_print("Running... \n");
// event executed every 40 ms for selecting show_source
DataPointer* pointer_data = new DataPointer{tiler_manager};
g_timeout_add(40, event_thread_func, pointer_data); // NULL
message_handling->pipeline_is_run = true;
g_main_loop_run(loop);
/* Out of the main loop, clean up nicely */
g_print("Returned, stopping playback \n");
gst_element_set_state(pipeline, GST_STATE_NULL);
g_print("Deleting pipeline \n");
gst_object_unref(GST_OBJECT(pipeline));
// g_source_remove (bus_watch_id);
message_handling->source_remove();
g_main_loop_unref(loop);
gst_deinit();
// g_free (g_source_bin_list);
// g_free (uri);
g_mutex_clear(&eos_lock);
rtsp_streaming_manager->destroy_sink_bin();
return true;
}