From ccbc4e23bd862e5246d8ef609d08fb18df78d14c Mon Sep 17 00:00:00 2001 From: pbartosik Date: Sat, 14 Mar 2026 04:51:07 +0100 Subject: [PATCH 1/5] exposed detection count for internal use --- src/gst/elements/gvafpscounter/fpscounter.cpp | 18 ++++++++++++++++++ src/gst/elements/gvafpscounter/fpscounter.h | 7 ++++++- .../elements/gvafpscounter/fpscounter_c.cpp | 4 +++- .../elements/gvafpscounter/gstgvafpscounter.c | 15 ++++++++++++++- .../elements/gvafpscounter/gstgvafpscounter.h | 1 + 5 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/gst/elements/gvafpscounter/fpscounter.cpp b/src/gst/elements/gvafpscounter/fpscounter.cpp index dd08a5b53..bc14fcff1 100644 --- a/src/gst/elements/gvafpscounter/fpscounter.cpp +++ b/src/gst/elements/gvafpscounter/fpscounter.cpp @@ -17,6 +17,8 @@ #include #include +#include + namespace { constexpr double TIME_THRESHOLD = 0.1; using seconds_double = std::chrono::duration; @@ -35,6 +37,22 @@ bool IterativeFpsCounter::NewFrame(const std::string &element_name, FILE *output if (output == nullptr) return false; + // Count detected regions of interest + GstAnalyticsRelationMeta *relation_meta = gst_buffer_get_analytics_relation_meta(buffer); + if (relation_meta) { + gpointer state = NULL; + GstAnalyticsODMtd od_mtd; + size_t count = 0; + + while ( + gst_analytics_relation_meta_iterate(relation_meta, &state, gst_analytics_od_mtd_get_mtd_type(), &od_mtd)) { + ++count; + } + + detections += count; + } + + auto now = std::chrono::high_resolution_clock::now(); if (print_std_dev) { double millis = std::chrono::duration_cast(now - last_time).count() * MICRO_TO_MILLI; diff --git a/src/gst/elements/gvafpscounter/fpscounter.h b/src/gst/elements/gvafpscounter/fpscounter.h index d1a0485e5..ccd836067 100644 --- a/src/gst/elements/gvafpscounter/fpscounter.h +++ b/src/gst/elements/gvafpscounter/fpscounter.h @@ -29,7 +29,7 @@ class IterativeFpsCounter : public FpsCounter { IterativeFpsCounter(unsigned starting_frame, unsigned interval, bool average, bool print_std_dev, bool print_latency) : starting_frame(starting_frame), interval(interval), average(average), print_each_stream(true), - total_frames(0), avg_fps(0.0), eos_result_reported(false), print_std_dev(print_std_dev), + total_frames(0), detections(0), avg_fps(0.0), eos_result_reported(false), print_std_dev(print_std_dev), print_latency(print_latency) { } bool NewFrame(const std::string &element_name, FILE *output, GstBuffer *buffer) override; @@ -40,6 +40,10 @@ class IterativeFpsCounter : public FpsCounter { std::lock_guard lock(mutex); return avg_fps; } + unsigned get_detections() { + std::lock_guard lock(mutex); + return detections; + } protected: unsigned starting_frame; @@ -47,6 +51,7 @@ class IterativeFpsCounter : public FpsCounter { bool average; bool print_each_stream; unsigned total_frames; + unsigned detections; float avg_fps; std::chrono::time_point init_time; std::chrono::time_point last_time; diff --git a/src/gst/elements/gvafpscounter/fpscounter_c.cpp b/src/gst/elements/gvafpscounter/fpscounter_c.cpp index de16b8d63..e0c450183 100644 --- a/src/gst/elements/gvafpscounter/fpscounter_c.cpp +++ b/src/gst/elements/gvafpscounter/fpscounter_c.cpp @@ -89,8 +89,10 @@ void fps_counter_new_frame(GstBuffer *buffer, const char *element_name, void *gs counter->second->NewFrame(element_name, output, buffer); if (gstgvafpscounter && counter->first == "average") { auto iterative_counter = std::dynamic_pointer_cast(counter->second); - if (iterative_counter) + if (iterative_counter) { ((GstGvaFpscounter *)gstgvafpscounter)->avg_fps = iterative_counter->get_avg_fps(); + ((GstGvaFpscounter *)gstgvafpscounter)->detections = iterative_counter->get_detections(); + } } } } catch (std::exception &e) { diff --git a/src/gst/elements/gvafpscounter/gstgvafpscounter.c b/src/gst/elements/gvafpscounter/gstgvafpscounter.c index f67deb125..c6253257b 100644 --- a/src/gst/elements/gvafpscounter/gstgvafpscounter.c +++ b/src/gst/elements/gvafpscounter/gstgvafpscounter.c @@ -34,7 +34,8 @@ enum { PROP_READ_PIPE, PROP_PRINT_STD_DEV, PROP_PRINT_LATENCY, - PROP_AVG_FPS + PROP_AVG_FPS, + PROP_DETECTIONS }; #define DEFAULT_INTERVAL "1" @@ -47,6 +48,9 @@ enum { #define DEFAULT_AVG_FPS 0.0 #define DEFAULT_AVG_FPS_MIN 0.0 #define DEFAULT_AVG_FPS_MAX G_MAXFLOAT +#define DEFAULT_DETECTIONS 0 +#define DEFAULT_MIN_DETECTIONS 0 +#define DEFAULT_MAX_DETECTIONS UINT_MAX /* prototypes */ static void gst_gva_fpscounter_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); @@ -123,6 +127,11 @@ static void gst_gva_fpscounter_class_init(GstGvaFpscounterClass *klass) { "The average frames per second, read-only parameter", DEFAULT_AVG_FPS_MIN, DEFAULT_AVG_FPS_MAX, DEFAULT_AVG_FPS, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property(gobject_class, PROP_DETECTIONS, + g_param_spec_uint("detections", "For internal use only", + "For internal use only", + DEFAULT_MIN_DETECTIONS, DEFAULT_MAX_DETECTIONS, DEFAULT_DETECTIONS, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); } static void gst_gva_fpscounter_init(GstGvaFpscounter *gva_fpscounter) { @@ -137,6 +146,7 @@ static void gst_gva_fpscounter_init(GstGvaFpscounter *gva_fpscounter) { gva_fpscounter->print_std_dev = DEFAULT_PRINT_STD_DEV; gva_fpscounter->print_latency = DEFAULT_PRINT_LATENCY; gva_fpscounter->avg_fps = DEFAULT_AVG_FPS; + gva_fpscounter->detections = DEFAULT_DETECTIONS; } void gst_gva_fpscounter_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { @@ -165,6 +175,9 @@ void gst_gva_fpscounter_get_property(GObject *object, guint property_id, GValue case PROP_AVG_FPS: g_value_set_float(value, gvafpscounter->avg_fps); break; + case PROP_DETECTIONS: + g_value_set_uint(value, gvafpscounter->detections); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); break; diff --git a/src/gst/elements/gvafpscounter/gstgvafpscounter.h b/src/gst/elements/gvafpscounter/gstgvafpscounter.h index 8a03c4a98..00c9cc2ee 100644 --- a/src/gst/elements/gvafpscounter/gstgvafpscounter.h +++ b/src/gst/elements/gvafpscounter/gstgvafpscounter.h @@ -26,6 +26,7 @@ struct _GstGvaFpscounter { GstBaseTransform base_gvafpscounter; gchar *interval; guint starting_frame; + guint detections; gfloat avg_fps; gchar *write_pipe; gchar *read_pipe; From a518563528ff30cf7c4c698e1e2fe808ac5c37ad Mon Sep 17 00:00:00 2001 From: pbartosik Date: Sat, 14 Mar 2026 05:13:30 +0100 Subject: [PATCH 2/5] separated roit counting to a different function --- src/gst/elements/gvafpscounter/fpscounter.cpp | 38 ++++++++++--------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/src/gst/elements/gvafpscounter/fpscounter.cpp b/src/gst/elements/gvafpscounter/fpscounter.cpp index bc14fcff1..af70eaf81 100644 --- a/src/gst/elements/gvafpscounter/fpscounter.cpp +++ b/src/gst/elements/gvafpscounter/fpscounter.cpp @@ -25,33 +25,37 @@ using seconds_double = std::chrono::duration; constexpr int ELEMENT_NAME_MAX_SIZE = 64; constexpr double MICRO_TO_MILLI = 0.001; constexpr double SECOND_TO_MILLI = 1000.0; -} // namespace - -//////////////////////////////////////////////////////////////////////////////// -// IterativeFpsCounter - -bool IterativeFpsCounter::NewFrame(const std::string &element_name, FILE *output, GstBuffer *buffer) { - std::lock_guard lock(mutex); - if (++total_frames <= starting_frame) - return false; - if (output == nullptr) - return false; - // Count detected regions of interest +unsigned count_rois(GstBuffer *buffer) { GstAnalyticsRelationMeta *relation_meta = gst_buffer_get_analytics_relation_meta(buffer); + size_t count = 0; + if (relation_meta) { gpointer state = NULL; GstAnalyticsODMtd od_mtd; - size_t count = 0; while ( gst_analytics_relation_meta_iterate(relation_meta, &state, gst_analytics_od_mtd_get_mtd_type(), &od_mtd)) { ++count; } - - detections += count; } + return count; +} + +} // namespace + +//////////////////////////////////////////////////////////////////////////////// +// IterativeFpsCounter + +bool IterativeFpsCounter::NewFrame(const std::string &element_name, FILE *output, GstBuffer *buffer) { + std::lock_guard lock(mutex); + if (++total_frames <= starting_frame) + return false; + if (output == nullptr) + return false; + + detections += count_rois(buffer); auto now = std::chrono::high_resolution_clock::now(); if (print_std_dev) { @@ -174,8 +178,8 @@ void IterativeFpsCounter::PrintFPS(FILE *output, double sec, bool eos) { } else { fprintf(output, "FpsCounter(last %.2fsec): ", sec); } - fprintf(output, "total=%.2f fps, number-streams=%zu, per-stream=%.2f fps", total, num_frames.size(), - total / num_frames.size()); + fprintf(output, "total=%.2f fps, number-streams=%zu, per-stream=%.2f fps, detections=%d", total, num_frames.size(), + total / num_frames.size(), detections); if (num_frames.size() > 1 && print_each_stream) { fprintf(output, " ("); auto num = num_frames.begin(); From 796b8a65a8e9acb24588056633ed55c2f5b1ea1f Mon Sep 17 00:00:00 2001 From: pbartosik Date: Sat, 14 Mar 2026 05:15:17 +0100 Subject: [PATCH 3/5] removed debug print --- src/gst/elements/gvafpscounter/fpscounter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gst/elements/gvafpscounter/fpscounter.cpp b/src/gst/elements/gvafpscounter/fpscounter.cpp index af70eaf81..2da4f8fde 100644 --- a/src/gst/elements/gvafpscounter/fpscounter.cpp +++ b/src/gst/elements/gvafpscounter/fpscounter.cpp @@ -178,8 +178,8 @@ void IterativeFpsCounter::PrintFPS(FILE *output, double sec, bool eos) { } else { fprintf(output, "FpsCounter(last %.2fsec): ", sec); } - fprintf(output, "total=%.2f fps, number-streams=%zu, per-stream=%.2f fps, detections=%d", total, num_frames.size(), - total / num_frames.size(), detections); + fprintf(output, "total=%.2f fps, number-streams=%zu, per-stream=%.2f fps", total, num_frames.size(), + total / num_frames.size()); if (num_frames.size() > 1 && print_each_stream) { fprintf(output, " ("); auto num = num_frames.begin(); From 2762e900984b9de836290ac42744a1742db622d2 Mon Sep 17 00:00:00 2001 From: pbartosik Date: Sat, 14 Mar 2026 06:53:19 +0100 Subject: [PATCH 4/5] fixed lints --- scripts/optimizer/optimizer.py | 1 + src/gst/elements/gvafpscounter/fpscounter.h | 2 +- src/gst/elements/gvafpscounter/fpscounter_c.cpp | 2 +- src/gst/elements/gvafpscounter/gstgvafpscounter.c | 9 ++++----- src/gst/elements/gvafpscounter/gstgvafpscounter.h | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/scripts/optimizer/optimizer.py b/scripts/optimizer/optimizer.py index 8b28d314c..034690f31 100644 --- a/scripts/optimizer/optimizer.py +++ b/scripts/optimizer/optimizer.py @@ -250,6 +250,7 @@ def sample_pipeline(pipelines, sample_duration): del pipeline fps = fps_counter.get_property("avg-fps") + detections = fps_counter.get_property("detections") logger.debug("Sampled fps: %.2f", fps) return fps diff --git a/src/gst/elements/gvafpscounter/fpscounter.h b/src/gst/elements/gvafpscounter/fpscounter.h index ccd836067..1d284424c 100644 --- a/src/gst/elements/gvafpscounter/fpscounter.h +++ b/src/gst/elements/gvafpscounter/fpscounter.h @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2018-2025 Intel Corporation + * Copyright (C) 2018-2026 Intel Corporation * * SPDX-License-Identifier: MIT ******************************************************************************/ diff --git a/src/gst/elements/gvafpscounter/fpscounter_c.cpp b/src/gst/elements/gvafpscounter/fpscounter_c.cpp index e0c450183..1f1377fec 100644 --- a/src/gst/elements/gvafpscounter/fpscounter_c.cpp +++ b/src/gst/elements/gvafpscounter/fpscounter_c.cpp @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2021-2025 Intel Corporation + * Copyright (C) 2021-2026 Intel Corporation * * SPDX-License-Identifier: MIT ******************************************************************************/ diff --git a/src/gst/elements/gvafpscounter/gstgvafpscounter.c b/src/gst/elements/gvafpscounter/gstgvafpscounter.c index c6253257b..b3fc84cdb 100644 --- a/src/gst/elements/gvafpscounter/gstgvafpscounter.c +++ b/src/gst/elements/gvafpscounter/gstgvafpscounter.c @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2018-2025 Intel Corporation + * Copyright (C) 2018-2026 Intel Corporation * * SPDX-License-Identifier: MIT ******************************************************************************/ @@ -128,10 +128,9 @@ static void gst_gva_fpscounter_class_init(GstGvaFpscounterClass *klass) { DEFAULT_AVG_FPS_MIN, DEFAULT_AVG_FPS_MAX, DEFAULT_AVG_FPS, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property(gobject_class, PROP_DETECTIONS, - g_param_spec_uint("detections", "For internal use only", - "For internal use only", - DEFAULT_MIN_DETECTIONS, DEFAULT_MAX_DETECTIONS, DEFAULT_DETECTIONS, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + g_param_spec_uint("detections", "For internal use only", "For internal use only", + DEFAULT_MIN_DETECTIONS, DEFAULT_MAX_DETECTIONS, + DEFAULT_DETECTIONS, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); } static void gst_gva_fpscounter_init(GstGvaFpscounter *gva_fpscounter) { diff --git a/src/gst/elements/gvafpscounter/gstgvafpscounter.h b/src/gst/elements/gvafpscounter/gstgvafpscounter.h index 00c9cc2ee..23f2fd834 100644 --- a/src/gst/elements/gvafpscounter/gstgvafpscounter.h +++ b/src/gst/elements/gvafpscounter/gstgvafpscounter.h @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2018-2025 Intel Corporation + * Copyright (C) 2018-2026 Intel Corporation * * SPDX-License-Identifier: MIT ******************************************************************************/ From 19c2ecb7ca01aa105787af72d0d03d4893f410cd Mon Sep 17 00:00:00 2001 From: pbartosik Date: Tue, 17 Mar 2026 02:18:56 +0100 Subject: [PATCH 5/5] removed accidental optimizer change --- scripts/optimizer/optimizer.py | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/optimizer/optimizer.py b/scripts/optimizer/optimizer.py index 034690f31..8b28d314c 100644 --- a/scripts/optimizer/optimizer.py +++ b/scripts/optimizer/optimizer.py @@ -250,7 +250,6 @@ def sample_pipeline(pipelines, sample_duration): del pipeline fps = fps_counter.get_property("avg-fps") - detections = fps_counter.get_property("detections") logger.debug("Sampled fps: %.2f", fps) return fps