From de3a911d509526f4c3d3156fdc05ec6ae194bb16 Mon Sep 17 00:00:00 2001 From: Barzan Hayati Date: Sun, 6 Jul 2025 23:07:14 +0000 Subject: [PATCH] Write fps into csv --- src/pipeline_manager.cpp | 56 +++++++++++++++++++++++++++++++--------- src/pipeline_manager.hpp | 11 +++++++- 2 files changed, 54 insertions(+), 13 deletions(-) diff --git a/src/pipeline_manager.cpp b/src/pipeline_manager.cpp index 06c4a77..961ec09 100644 --- a/src/pipeline_manager.cpp +++ b/src/pipeline_manager.cpp @@ -1,5 +1,8 @@ #include "pipeline_manager.hpp" +double PipelineManager::fps_buffer_probe = 0; +double PipelineManager::fps_probe = 0; +double PipelineManager::fps_osd = 0; guint64 PipelineManager::frame_count_osd_sink = 0; guint64 PipelineManager::frame_count_fps_probe = 0; guint64 PipelineManager::frame_count_buffer_probe = 0; @@ -12,7 +15,15 @@ std::chrono::time_point PipelineManager::PipelineManager() { ; } -PipelineManager::PipelineManager(int num_sources, char** url_camera) { +PipelineManager::PipelineManager(int num_sources, char** url_camera) +: csv_fp("csv_fps.csv") + { + if (!csv_fp.is_open()) { + std::cerr << "Failed to open csv_fp csv file.\n"; + throw std::runtime_error("Failed to open csv_fps_buffer_probe.csv"); + } + // Write CSV header + csv_fp << "Name,FPS\n"; g_setenv("GST_DEBUG_DUMP_DOT_DIR", ".", TRUE); gst_init(&num_sources, &url_camera); g_run_forever = atoi("0"); @@ -58,10 +69,24 @@ char* createName(const char* str, int num) { return result; } +void PipelineManager::set_row_csv_fps(const std::string& name, double fps){ + if (!csv_fp.is_open()) { + std::cerr << "Failed to write: stream not open for " << name << "\n"; + return; + } + else{ + csv_fp << name << "," << fps << "\n"; + std::cout << "Wrote: " << name << " = " << fps << "\n"; + } +} + + GstPadProbeReturn PipelineManager::osd_sink_pad_buffer_probe( GstPad* pad, GstPadProbeInfo* info, gpointer user_data) { (void)pad; // This explicitly marks it as unused (void)user_data; // This explicitly marks it as unused + auto* self = static_cast(user_data); + GstBuffer* buf = (GstBuffer*)info->data; NvDsBatchMeta* batch_meta = gst_buffer_get_nvds_batch_meta(buf); @@ -73,8 +98,10 @@ GstPadProbeReturn PipelineManager::osd_sink_pad_buffer_probe( long long ms = std::chrono::duration_cast( now - last_time_osd_sink) .count(); - double fps = 60000.0 / ms; - g_print("FPS_osd_sink: %.2f\n", fps); + fps_osd = 60000.0 / ms; + self->set_row_csv_fps("fps_osd", fps_osd); + std::cout << "Writing fps_osd...\n"; + g_print("FPS_osd_sink: %.2f\n", fps_osd); last_time_osd_sink = now; } return GST_PAD_PROBE_OK; @@ -85,15 +112,16 @@ void PipelineManager::get_fps_osd() { GST_BIN(pipeline), "nv-onscreendisplay"); // Or "nvinfer", etc. GstPad* sink_pad = gst_element_get_static_pad(osd, "sink"); gst_pad_add_probe(sink_pad, GST_PAD_PROBE_TYPE_BUFFER, - osd_sink_pad_buffer_probe, NULL, NULL); + osd_sink_pad_buffer_probe, this, NULL); gst_object_unref(sink_pad); gst_object_unref(osd); } -GstPadProbeReturn PipelineManager::fps_probe(GstPad* pad, GstPadProbeInfo* info, +GstPadProbeReturn PipelineManager::probe_fps(GstPad* pad, GstPadProbeInfo* info, gpointer user_data) { (void)pad; // This explicitly marks it as unused (void)user_data; // This explicitly marks it as unused + auto* self = static_cast(user_data); if (GST_PAD_PROBE_INFO_TYPE(info) & GST_PAD_PROBE_TYPE_BUFFER) { frame_count_fps_probe++; @@ -104,9 +132,11 @@ GstPadProbeReturn PipelineManager::fps_probe(GstPad* pad, GstPadProbeInfo* info, std::chrono::duration_cast( current_time_fps_probe - last_time_fps_probe) .count(); - double fps = 30000.0 / duration; - g_print("fps_probe FPS: %.2f\n", fps); + fps_probe = 30000.0 / duration; + g_print("fps_probe FPS: %.2f\n", fps_probe); last_time_fps_probe = current_time_fps_probe; + self->set_row_csv_fps("fps_probe", fps_probe); + std::cout << "Writing fps_probe...\n"; } } return GST_PAD_PROBE_OK; @@ -117,7 +147,7 @@ void PipelineManager::get_fps_probe() { GstElement* element = gst_bin_get_by_name( GST_BIN(pipeline), "nvvideo-converter"); // or any processing element GstPad* pad = gst_element_get_static_pad(element, "src"); - gst_pad_add_probe(pad, GST_PAD_PROBE_TYPE_BUFFER, fps_probe, NULL, NULL); + gst_pad_add_probe(pad, GST_PAD_PROBE_TYPE_BUFFER, probe_fps, this, NULL); gst_object_unref(pad); gst_object_unref(element); } @@ -129,19 +159,21 @@ GstPadProbeReturn PipelineManager::buffer_probe(GstPad* pad, (void)info; // This explicitly marks it as unused (void)user_data; // This explicitly marks it as unused + auto* self = static_cast(user_data); frame_count_buffer_probe++; std::chrono::time_point current_time_buffer_probe = std::chrono::steady_clock::now(); long long elapsed = std::chrono::duration_cast( current_time_buffer_probe - last_time_buffer_probe) .count(); - + fps_buffer_probe = (double)(frame_count_buffer_probe * 1000 / (double)elapsed); if (elapsed >= 1000) { // Update every second - g_print("FPS_buffer_probe: %.2f\n", - (double)(frame_count_buffer_probe * 1000 / (double)elapsed)); + g_print("FPS_buffer_probe: %.2f\n", fps_buffer_probe); frame_count_buffer_probe = 0; last_time_buffer_probe = current_time_buffer_probe; } + self->set_row_csv_fps("fps_buffer_probe", fps_buffer_probe); + std::cout << "Writing fps_buffer_probe...\n"; return GST_PAD_PROBE_OK; } @@ -150,7 +182,7 @@ void PipelineManager::get_fps_buffer_probe() { // --- BUFFER PROBE FOR FPS --- GstPad* sink_pad = gst_element_get_static_pad( nv_video_convert_manager->nvvidconv, "src"); // Or any element's pad - gst_pad_add_probe(sink_pad, GST_PAD_PROBE_TYPE_BUFFER, buffer_probe, NULL, + gst_pad_add_probe(sink_pad, GST_PAD_PROBE_TYPE_BUFFER, buffer_probe, this, NULL); gst_object_unref(sink_pad); } diff --git a/src/pipeline_manager.hpp b/src/pipeline_manager.hpp index b5fb47b..d44ebb6 100644 --- a/src/pipeline_manager.hpp +++ b/src/pipeline_manager.hpp @@ -1,6 +1,8 @@ #include #include #include +#include + #include "cuda_runtime_api.h" #include "gstds_example_manager.hpp" @@ -32,6 +34,13 @@ class PipelineManager { SinkManager *sink_manager = new SinkManager(); MessageHandling *message_handling = new MessageHandling(); RtspStreamingManager *rtsp_streaming_manager = new RtspStreamingManager(); + static double fps_buffer_probe; + static double fps_probe; + static double fps_osd; + std::ofstream csv_fp; + + void set_row_csv_fps(const std::string& , double); + typedef struct { TilerManager *tiler_manager; @@ -63,7 +72,7 @@ class PipelineManager { static gboolean check_pipeline_state(gpointer); static GstPadProbeReturn buffer_probe(GstPad *, GstPadProbeInfo *, gpointer); - static GstPadProbeReturn fps_probe(GstPad *, GstPadProbeInfo *, gpointer); + static GstPadProbeReturn probe_fps(GstPad *, GstPadProbeInfo *, gpointer); static GstPadProbeReturn osd_sink_pad_buffer_probe(GstPad *, GstPadProbeInfo *, gpointer);