Probe nvinferserver inspect nvdsobjectmeta nvdsframemeta

This commit is contained in:
Barzan Hayati 2025-07-20 19:54:24 +00:00
parent a99fb4ba14
commit 2c5f678201
4 changed files with 88 additions and 3 deletions

View File

@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.19)
project(BodyPipeline LANGUAGES CXX)
project(BodyPipeline LANGUAGES CXX CUDA)
# Set C++ standard and enable modern practices
set(CMAKE_CXX_STANDARD 17)
@ -27,7 +27,7 @@ endif()
find_package(PkgConfig REQUIRED)
find_package(CUDA REQUIRED)
# find_package(CUDA REQUIRED)
find_package(prometheus-cpp REQUIRED)
pkg_check_modules(GLIB REQUIRED glib-2.0 gobject-2.0 nlohmann_json gstreamer-base-1.0
gstreamer-rtsp-server-1.0 gstreamer-rtsp-1.0 gstreamer-1.0 gstreamer-video-1.0)
@ -94,6 +94,18 @@ if(WIN32)
target_compile_definitions(${PROJECT_NAME} PRIVATE _CRT_SECURE_NO_WARNINGS)
endif()
# Optionally set CUDA-specific flags
set_target_properties(${PROJECT_NAME} PROPERTIES
CUDA_STANDARD 17 # or 14, 20 depending on your code. Specifies which C++ standard to use for both host and device code.
CUDA_STANDARD_REQUIRED ON # Enforces the standard. Enforces that standardavoids falling back to older versions silently.
CUDA_SEPARABLE_COMPILATION ON # Needed if kernels are in .cu files. Required if your project has multiple .cu files calling each other.
# CUDA_ARCHITECTURES 86 # Set to your GPU's arch (e.g., 86 for Ampere)Helps CMake compile only for the correct GPU architecture (you can use CMake's CUDA_ARCHITECTURES values).
)
# https://cmake.org/cmake/help/latest/prop_tgt/CUDA_ARCHITECTURES.html
# https://cmake.org/cmake/help/latest/policy/CMP0146.html
# Include current directory for headers
target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_include_directories(${PROJECT_NAME} PRIVATE ${GLIB_INCLUDE_DIRS})

View File

@ -1,7 +1,7 @@
#include "nv_infer_server_manager.hpp"
NvInferServerManager::NvInferServerManager() {
const auto& config = ConfigManager::get_instance().get_config();
const auto &config = ConfigManager::get_instance().get_config();
pgie_batch_size = config["pgie_batch_size"];
inferserver_pgie_config_file =
config["inferserver_pgie_config_file"].get<std::string>();
@ -26,5 +26,66 @@ bool NvInferServerManager::create_nv_infer_server(int num_sources) {
g_object_set(G_OBJECT(primary_detector), "batch-size", num_sources,
NULL);
}
// std::cout << "✅ Found element: " << GST_ELEMENT_NAME(primary_detector)
// << std::endl;
return true;
}
// Probe function to inspect NvDsObjectMeta
GstPadProbeReturn NvInferServerManager::osd_sink_pad_buffer_probe(
GstPad *pad, GstPadProbeInfo *info, gpointer user_data) {
(void)pad;
(void)user_data;
GstBuffer *buf = (GstBuffer *)info->data;
// Retrieve batch metadata from buffer
NvDsBatchMeta *batch_meta = gst_buffer_get_nvds_batch_meta(buf);
if (!batch_meta) {
std::cerr << "No batch metadata found\n";
exit(-1);
return GST_PAD_PROBE_OK;
}
// probe sees the frame metadata (NvDsFrameMeta) —
// but no object metadata (NvDsObjectMeta) was attached to that frame.
for (NvDsMetaList *l_frame = batch_meta->frame_meta_list; l_frame != NULL;
l_frame = l_frame->next) {
NvDsFrameMeta *frame_meta = (NvDsFrameMeta *)(l_frame->data);
// std::cout << "Frame number: " << frame_meta->frame_num << std::endl;
// if (frame_meta->obj_meta_list == NULL) {
// std::cout << " ⚠️ No object metadata for this frame.\n";
// }
for (NvDsMetaList *l_obj = frame_meta->obj_meta_list; l_obj != NULL;
l_obj = l_obj->next) {
NvDsObjectMeta *obj_meta = (NvDsObjectMeta *)(l_obj->data);
std::cout << " Object ID: " << obj_meta->object_id << std::endl;
std::cout << " Class ID: " << obj_meta->class_id << std::endl;
std::cout << " Label: "
<< (obj_meta->obj_label ? obj_meta->obj_label : "N/A")
<< std::endl;
std::cout << " BBox: x=" << obj_meta->rect_params.left
<< " y=" << obj_meta->rect_params.top
<< " w=" << obj_meta->rect_params.width
<< " h=" << obj_meta->rect_params.height << std::endl;
}
}
return GST_PAD_PROBE_OK;
}
// Attach probe to a pad in the pipeline
void NvInferServerManager::attach_probe_to_element() {
GstPad *sink_pad = gst_element_get_static_pad(primary_detector, "sink");
if (!sink_pad) {
std::cerr << "Unable to get sink pad\n";
return;
}
gst_pad_add_probe(sink_pad, GST_PAD_PROBE_TYPE_BUFFER,
osd_sink_pad_buffer_probe, NULL, NULL);
gst_object_unref(sink_pad);
}

View File

@ -4,6 +4,7 @@
#include <iostream>
#include "config_manager.hpp"
#include "gstnvdsmeta.h"
class NvInferServerManager {
private:
@ -14,4 +15,8 @@ class NvInferServerManager {
NvInferServerManager();
bool create_nv_infer_server(int);
~NvInferServerManager();
static GstPadProbeReturn osd_sink_pad_buffer_probe(GstPad *,
GstPadProbeInfo *,
gpointer);
void attach_probe_to_element();
};

View File

@ -350,6 +350,13 @@ bool PipelineManager::create_pipeline_elements(int num_sources,
rtsp_streaming_manager->updsink_port_num);
nv_infer_server_manager->create_nv_infer_server(num_sources);
// GstElement *nvinfer = gst_bin_get_by_name(GST_BIN(pipeline),
// "primary-nvinference-engine");
nv_infer_server_manager
->attach_probe_to_element(); // nvinfer Or use "nvtracker" if after
// tracker
// gst_object_unref(nvinfer);
message_handling->create_message_handler(pipeline, g_run_forever, loop);
setup_pipeline();