11/* ******************************************************************************
2- * Copyright (C) 2018-2025 Intel Corporation
2+ * Copyright (C) 2018-2026 Intel Corporation
33 *
44 * SPDX-License-Identifier: MIT
55 ******************************************************************************/
@@ -114,7 +114,8 @@ InferenceBackend::MemoryType memoryTypeFromCaps(GstCaps *caps) {
114114} // namespace
115115
116116struct Impl {
117- Impl (GstVideoInfo *info, InferenceBackend::MemoryType mem_type, GstElement *element, bool disp_avgfps);
117+ Impl (GstVideoInfo *info, InferenceBackend::MemoryType mem_type, GstElement *element, bool displ_avgfps,
118+ gchar *displ_cfg);
118119 bool extract_primitives (GstBuffer *buffer);
119120 int get_num_primitives () const ;
120121 bool render (GstBuffer *buffer);
@@ -133,6 +134,7 @@ struct Impl {
133134 const std::vector<uint32_t > &dims, const std::vector<float > &confidence,
134135 const GVA::Rect<double > &rectangle, std::vector<render::Prim> &prims) const ;
135136 void find_gvafpscounter_element ();
137+ void parse_displ_config ();
136138 std::unique_ptr<Renderer> createRenderer (std::shared_ptr<ColorConverter> converter);
137139
138140 std::unique_ptr<Renderer> createGPURenderer (dlstreamer::ImageFormat format,
@@ -164,10 +166,14 @@ struct Impl {
164166 const double scale = 1.0 ;
165167 } _font;
166168 const bool _obb = false ;
167- bool _disp_avgfps = false ;
168- } ;
169+ bool _displ_avgfps = false ;
170+ gchar *_displ_cfg = nullptr ;
169171
170- enum { PROP_0, PROP_DEVICE, PROP_OBB, PROP_DISP_AVGFPS };
172+ struct DisplCfg {
173+ bool show_labels = true ;
174+ double text_scale = 1.0 ;
175+ } _displCfg;
176+ };
171177
172178G_DEFINE_TYPE_WITH_CODE (GstGvaWatermarkImpl, gst_gva_watermark_impl, GST_TYPE_BASE_TRANSFORM,
173179 GST_DEBUG_CATEGORY_INIT (gst_gva_watermark_impl_debug_category, " gvawatermarkimpl" , 0 ,
@@ -176,6 +182,8 @@ G_DEFINE_TYPE_WITH_CODE(GstGvaWatermarkImpl, gst_gva_watermark_impl, GST_TYPE_BA
176182static void gst_gva_watermark_impl_init (GstGvaWatermarkImpl *gvawatermark) {
177183 gvawatermark->device = DEFAULT_DEVICE;
178184 gvawatermark->obb = false ;
185+ gvawatermark->displ_avgfps = false ;
186+ gvawatermark->displ_cfg = nullptr ;
179187}
180188
181189void gst_gva_watermark_impl_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) {
@@ -191,8 +199,12 @@ void gst_gva_watermark_impl_set_property(GObject *object, guint prop_id, const G
191199 case PROP_OBB:
192200 gvawatermark->obb = g_value_get_boolean (value);
193201 break ;
194- case PROP_DISP_AVGFPS:
195- gvawatermark->disp_avgfps = g_value_get_boolean (value);
202+ case PROP_DISPL_AVGFPS:
203+ gvawatermark->displ_avgfps = g_value_get_boolean (value);
204+ break ;
205+ case PROP_DISPL_CFG:
206+ g_free (gvawatermark->displ_cfg );
207+ gvawatermark->displ_cfg = g_value_dup_string (value);
196208 break ;
197209 default :
198210 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -216,8 +228,11 @@ void gst_gva_watermark_impl_get_property(GObject *object, guint prop_id, GValue
216228 case PROP_OBB:
217229 g_value_set_boolean (value, self->obb );
218230 break ;
219- case PROP_DISP_AVGFPS:
220- g_value_set_boolean (value, self->disp_avgfps );
231+ case PROP_DISPL_AVGFPS:
232+ g_value_set_boolean (value, self->displ_avgfps );
233+ break ;
234+ case PROP_DISPL_CFG:
235+ g_value_set_string (value, self->displ_cfg );
221236 break ;
222237 default :
223238 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -334,8 +349,8 @@ static gboolean gst_gva_watermark_impl_set_caps(GstBaseTransform *trans, GstCaps
334349#endif
335350
336351 try {
337- gvawatermark->impl =
338- std::make_shared<Impl>(& gvawatermark->info , mem_type, GST_ELEMENT (trans), gvawatermark->disp_avgfps );
352+ gvawatermark->impl = std::make_shared<Impl>(&gvawatermark-> info , mem_type, GST_ELEMENT (trans),
353+ gvawatermark->displ_avgfps , gvawatermark->displ_cfg );
339354 } catch (const std::exception &e) {
340355 GST_ELEMENT_ERROR (gvawatermark, CORE, FAILED, (" Could not initialize" ),
341356 (" Cannot create watermark instance. %s" , Utils::createNestedErrorMsg (e).c_str ()));
@@ -660,28 +675,44 @@ static void gst_gva_watermark_impl_class_init(GstGvaWatermarkImplClass *klass) {
660675 base_transform_class->transform_ip = GST_DEBUG_FUNCPTR (gst_gva_watermark_impl_transform_ip);
661676 base_transform_class->propose_allocation = GST_DEBUG_FUNCPTR (gst_gva_watermark_impl_propose_allocation);
662677
678+ const auto kDefaultGParamFlags =
679+ static_cast <GParamFlags>(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT);
680+
663681 g_object_class_install_property (
664682 gobject_class, PROP_DEVICE,
665683 g_param_spec_string (
666684 " device" , " Target device" ,
667685 " Supported devices are CPU and GPU. Default is CPU on system memory and GPU on video memory" ,
668- DEFAULT_DEVICE, (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
686+ DEFAULT_DEVICE, kDefaultGParamFlags ));
687+
669688 g_object_class_install_property (gobject_class, PROP_OBB,
670689 g_param_spec_boolean (" obb" , " Oriented Bounding Box" ,
671690 " If true, draw oriented bounding box instead of object mask" ,
672- false ,
673- (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
691+ false , kDefaultGParamFlags ));
692+
674693 g_object_class_install_property (
675- gobject_class, PROP_DISP_AVGFPS ,
676- g_param_spec_boolean (" disp -avgfps" , " Display Average FPS" ,
694+ gobject_class, PROP_DISPL_AVGFPS ,
695+ g_param_spec_boolean (" displ -avgfps" , " Display Average FPS" ,
677696 " If true, display the average FPS read from gvafpscounter element on the output video."
678697 " The gvafpscounter element must be present in the pipeline."
679- " e.g. gwatermark ! gvafpscounter ! ..." ,
680- false , (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
698+ " e.g. gvawatermark displ-avgfps=true ! gvafpscounter ! ..." ,
699+ false , kDefaultGParamFlags ));
700+
701+ g_object_class_install_property (
702+ gobject_class, PROP_DISPL_CFG,
703+ g_param_spec_string (" displ-cfg" , " Gvawatermark element display configuration" ,
704+ " Comma separated list of KEY=VALUE parameters of displayed notations.\n "
705+ " \t\t\t Available options: \n "
706+ " \t\t\t show-labels=true|false - enable/disable display of text labels (default true)\n "
707+ " \t\t\t text-scale=<0.1-2.0> - scale factor for text labels (default 1.0)\n "
708+ " \t\t\t e.g.: displ-cfg=show-labels=off\n "
709+ " \t\t\t e.g.: displ-cfg=text-scale=0.5" ,
710+ nullptr , kDefaultGParamFlags ));
681711}
682712
683- Impl::Impl (GstVideoInfo *info, InferenceBackend::MemoryType mem_type, GstElement *element, bool disp_avgfps)
684- : _vinfo(info), _element(element), _mem_type(mem_type), _disp_avgfps(disp_avgfps) {
713+ Impl::Impl (GstVideoInfo *info, InferenceBackend::MemoryType mem_type, GstElement *element, bool displ_avgfps,
714+ gchar *displ_cfg)
715+ : _vinfo(info), _element(element), _mem_type(mem_type), _displ_avgfps(displ_avgfps), _displ_cfg(displ_cfg) {
685716 assert (_vinfo);
686717 if (GST_VIDEO_INFO_COLORIMETRY (_vinfo).matrix == GstVideoColorMatrix::GST_VIDEO_COLOR_MATRIX_UNKNOWN)
687718 throw std::runtime_error (" GST_VIDEO_COLOR_MATRIX_UNKNOWN" );
@@ -699,8 +730,12 @@ Impl::Impl(GstVideoInfo *info, InferenceBackend::MemoryType mem_type, GstElement
699730 _renderer_opencv = createOpenCVRenderer (std::move (converterBGR));
700731
701732 // Find gvafpscounter element in the pipeline to put avg-fps on output video
702- if (_disp_avgfps )
733+ if (_displ_avgfps )
703734 find_gvafpscounter_element ();
735+
736+ // Parse display configuration
737+ if (_displ_cfg)
738+ parse_displ_config ();
704739}
705740
706741size_t get_keypoint_index_by_name (const gchar *target_name, GValueArray *names) {
@@ -761,6 +796,13 @@ void Impl::find_gvafpscounter_element() {
761796 g_value_unset (&value);
762797 gst_iterator_free (it);
763798 }
799+
800+ if (_gvafpscounter_element == nullptr ) {
801+ GST_WARNING_OBJECT (
802+ _element, " displ-avgfps property is set to true, but gvafpscounter element is not found in the pipeline. "
803+ " Average FPS will not be displayed on output video." );
804+ _displ_avgfps = false ;
805+ }
764806}
765807
766808bool Impl::extract_primitives (GstBuffer *buffer) {
@@ -878,15 +920,17 @@ void Impl::preparePrimsForRoi(GVA::RegionOfInterest &roi, std::vector<render::Pr
878920 prims.emplace_back (render::Rect (bbox_rect, color, _thickness, roi.rotation ()));
879921
880922 // put text
881- if (text.str ().size () != 0 ) {
882- cv::Point2f pos (rect.x , rect.y - 5 .f );
883- if (pos.y < 0 )
884- pos.y = rect.y + 30 .f ;
885- prims.emplace_back (render::Text (text.str (), pos, _font.type , _font.scale , color));
886- }
923+ if (_displCfg.show_labels )
924+ if (text.str ().size () != 0 ) {
925+ cv::Point2f pos (rect.x , rect.y - 5 .f );
926+ if (pos.y < 0 )
927+ pos.y = rect.y + 30 .f ;
928+ double scale = (_displCfg.text_scale != _font.scale ) ? _displCfg.text_scale : _font.scale ;
929+ prims.emplace_back (render::Text (text.str (), pos, _font.type , scale, color));
930+ }
887931
888932 // put avg-fps from gvafpscounter element
889- if (_gvafpscounter_element != nullptr ) {
933+ if (_displ_avgfps ) {
890934 std::ostringstream fpstext;
891935 gfloat avg_fps = 0 .0f ;
892936 g_object_get (_gvafpscounter_element, " avg-fps" , &avg_fps, NULL );
@@ -1094,6 +1138,38 @@ void Impl::preparePrimsForKeypointConnections(GstStructure *s, const std::vector
10941138 g_value_array_free (point_names);
10951139}
10961140
1141+ void Impl::parse_displ_config () {
1142+ // Parse watermark display configuration
1143+ std::string displcfg_str = std::string (_displ_cfg);
1144+ auto cfg = Utils::stringToMap (displcfg_str);
1145+ auto iter = cfg.end ();
1146+ try {
1147+ iter = cfg.find (" text-scale" );
1148+ if (iter != cfg.end ()) {
1149+ _displCfg.text_scale = std::stof (iter->second );
1150+ if (_displCfg.text_scale > 2.0 || _displCfg.text_scale < 0.1 ) {
1151+ _displCfg.text_scale = 1.0 ;
1152+ GST_WARNING (
1153+ " [gvawatermarkimpl] 'text-scale' parameter value is out of range (0.1, 2.0], set to default 1.0" );
1154+ }
1155+ cfg.erase (iter);
1156+ }
1157+ iter = cfg.find (" show-labels" );
1158+ if (iter != cfg.end ()) {
1159+ if (iter->second == " true" || iter->second == " false" ) {
1160+ _displCfg.show_labels = (iter->second == " true" );
1161+ }
1162+ cfg.erase (iter);
1163+ }
1164+ } catch (...) {
1165+ if (iter == cfg.end ())
1166+ std::throw_with_nested (
1167+ std::runtime_error (" [gvawatermarkimpl] Error occured while parsing key/value parameters" ));
1168+ std::throw_with_nested (
1169+ std::runtime_error (" [gvawatermarkimpl] Invalid value provided for parameter: " + iter->first ));
1170+ }
1171+ }
1172+
10971173std::unique_ptr<Renderer> Impl::createRenderer (std::shared_ptr<ColorConverter> converter) {
10981174
10991175 dlstreamer::ImageFormat format = dlstreamer::gst_format_to_video_format (GST_VIDEO_INFO_FORMAT (_vinfo));
0 commit comments