NVIDIA DeepStream SDK API Reference

9.2 Release
9.2/sources/gst-plugins/gst-nvdsbins/gstnvdsbinutils.h
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2020-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3  * SPDX-License-Identifier: Apache-2.0
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #ifndef __GST_DS_DEEPSTREAM_BINS_UTILS_H__
19 #define __GST_DS_DEEPSTREAM_BINS_UTILS_H__
20 
21 #include <gst/gst.h>
22 #include <memory>
23 
24 /* Forward only select properties from child type to parent element class */
25 static inline void
26 forward_select_properties (GObjectClass * parent_elem_class,
27  const gchar * (*property_name_map)[2], guint map_size,
28  GType child_elem_type, guint * prop_index,
29  GPtrArray * orig_prop_names_ordered)
30 {
31  GObject *child_obj = G_OBJECT (g_type_create_instance (child_elem_type));
32  GObjectClass *child_class = G_OBJECT_GET_CLASS (child_obj);
33  if (orig_prop_names_ordered)
34  g_ptr_array_set_size (orig_prop_names_ordered, *prop_index + map_size);
35 
36  for (guint i = 0; i < map_size; i++) {
37  GParamSpec *spec =
38  g_object_class_find_property (child_class, property_name_map[i][0]);
39  if (!spec) {
40  g_printerr ("Property '%s' not found on element '%s'\n",
41  property_name_map[i][0], G_OBJECT_CLASS_NAME (child_class));
42  continue;
43  }
44  GParamSpec *binspec = NULL;
45  switch (spec->value_type) {
46  case G_TYPE_STRING:
47  {
48  gchar *default_val = NULL;
49  g_object_get (child_obj, property_name_map[i][0], &default_val, NULL);
50  binspec =
51  g_param_spec_string (property_name_map[i][1], spec->_nick,
52  spec->_blurb, default_val, spec->flags);
53  g_free (default_val);
54  }
55  break;
56  case G_TYPE_BOOLEAN:
57  {
58  gboolean default_val = FALSE;
59  g_object_get (child_obj, property_name_map[i][0], &default_val, NULL);
60  binspec =
61  g_param_spec_boolean (property_name_map[i][1], spec->_nick,
62  spec->_blurb, default_val, spec->flags);
63  }
64  break;
65  case G_TYPE_UINT:
66  {
67  GParamSpecUInt *puint = G_PARAM_SPEC_UINT (spec);
68  guint default_val = 0;
69  g_object_get (child_obj, property_name_map[i][0], &default_val, NULL);
70 
71  binspec =
72  g_param_spec_uint (property_name_map[i][1], spec->_nick,
73  spec->_blurb, puint->minimum, puint->maximum,
74  default_val, spec->flags);
75  }
76  break;
77  case G_TYPE_INT:
78  {
79  GParamSpecInt *pint = G_PARAM_SPEC_INT (spec);
80  gint default_val = 0;
81  g_object_get (child_obj, property_name_map[i][0], &default_val, NULL);
82  binspec =
83  g_param_spec_int (property_name_map[i][1], spec->_nick,
84  spec->_blurb, pint->minimum, pint->maximum,
85  default_val, spec->flags);
86  }
87  break;
88  case G_TYPE_POINTER:
89  {
90  binspec =
91  g_param_spec_pointer (spec->name, spec->_nick,
92  spec->_blurb, spec->flags);
93  }
94  break;
95  default:
96  if (G_IS_PARAM_SPEC_ENUM (spec)) {
97  gint default_val;
98  g_object_get (child_obj, property_name_map[i][0], &default_val, NULL);
99  binspec = g_param_spec_enum (property_name_map[i][1], spec->_nick,
100  spec->_blurb, spec->value_type, default_val, spec->flags);
101  }
102  break;
103  }
104  if (binspec)
105  g_object_class_install_property (parent_elem_class, *prop_index, binspec);
106  else {
107  g_printerr ("Cannot forward '%s' property '%s' of type '%s'\n",
108  G_OBJECT_CLASS_NAME (child_class), property_name_map[i][0],
109  g_type_name (spec->value_type));
110  continue;
111  }
112  if (orig_prop_names_ordered)
113  g_ptr_array_insert (orig_prop_names_ordered, *prop_index,
114  (gpointer) property_name_map[i][0]);
115  (*prop_index)++;
116  }
117  g_object_unref (child_obj);
118 }
119 
120 /* Forward all properties of child element type to parent element class */
121 static inline void
122 forward_properties (GObjectClass * parent_elem_class, GType child_elem_type,
123  guint * prop_id = NULL)
124 {
125  GObject *child_obj = G_OBJECT (g_type_create_instance (child_elem_type));
126  GObjectClass *child_class = G_OBJECT_GET_CLASS (child_obj);
127  guint param_id = prop_id ? *prop_id : 1;
128 
129  guint num_specs = 0;
130  GParamSpec **spec = g_object_class_list_properties (child_class, &num_specs);
131  for (uint prop_index = 0; prop_index < num_specs; ++prop_index) {
132  GParamSpec *cur_spec = spec[prop_index];
133  GParamSpec *binspec = NULL;
134  //parent and name prop are a part of GstBin element and need not be forwarded
135  if (!g_strcmp0 (cur_spec->name, "parent")
136  || !g_strcmp0 (cur_spec->name, "name"))
137  continue;
138  switch (cur_spec->value_type) {
139  case G_TYPE_STRING:
140  {
141  gchar *default_val = NULL;
142  g_object_get (child_obj, cur_spec->name, &default_val, NULL);
143  binspec =
144  g_param_spec_string (cur_spec->name, cur_spec->_nick,
145  cur_spec->_blurb, default_val, cur_spec->flags);
146  g_free (default_val);
147  }
148  break;
149  case G_TYPE_BOOLEAN:
150  {
151  gboolean default_val = FALSE;
152  g_object_get (child_obj, cur_spec->name, &default_val, NULL);
153  binspec =
154  g_param_spec_boolean (cur_spec->name, cur_spec->_nick,
155  cur_spec->_blurb, default_val, cur_spec->flags);
156  }
157  break;
158  case G_TYPE_UINT:
159  {
160  GParamSpecUInt *puint = G_PARAM_SPEC_UINT (cur_spec);
161  guint default_val = 0;
162  g_object_get (child_obj, cur_spec->name, &default_val, NULL);
163  binspec =
164  g_param_spec_uint (cur_spec->name, cur_spec->_nick,
165  cur_spec->_blurb, puint->minimum, puint->maximum,
166  default_val, cur_spec->flags);
167  }
168  break;
169  case G_TYPE_INT:
170  {
171  GParamSpecInt *pint = G_PARAM_SPEC_INT (cur_spec);
172  gint default_val = 0;
173  g_object_get (child_obj, cur_spec->name, &default_val, NULL);
174  binspec =
175  g_param_spec_int (cur_spec->name, cur_spec->_nick,
176  cur_spec->_blurb, pint->minimum, pint->maximum,
177  default_val, cur_spec->flags);
178  }
179  break;
180  case G_TYPE_POINTER:
181  {
182  binspec =
183  g_param_spec_pointer (cur_spec->name, cur_spec->_nick,
184  cur_spec->_blurb, cur_spec->flags);
185  }
186  break;
187  default:
188  if (G_IS_PARAM_SPEC_ENUM (cur_spec)) {
189  gint default_val;
190  g_object_get (child_obj, cur_spec->name, &default_val, NULL);
191  binspec = g_param_spec_enum (cur_spec->name, cur_spec->_nick,
192  cur_spec->_blurb, cur_spec->value_type, default_val,
193  cur_spec->flags);
194  }
195  break;
196  }
197  if (binspec)
198  g_object_class_install_property (parent_elem_class, param_id, binspec);
199  else {
200  g_printerr ("Cannot forward '%s' property '%s' of type '%s'\n",
201  G_OBJECT_CLASS_NAME (child_class), cur_spec->name,
202  g_type_name (cur_spec->value_type));
203  continue;
204  }
205  param_id++;
206  }
207  g_free (spec);
208  g_object_unref (child_obj);
209  if (prop_id)
210  *prop_id = param_id;
211 }
212 
213 static inline void
214 forward_pad_template (GstElementClass * bin_class, GType child_elem_type,
215  const gchar * child_tmpl_name, const gchar * pad_tmpl_name = nullptr)
216 {
217  GstElementClass *child_elem_class =
218  (GstElementClass *) g_type_class_ref (child_elem_type);
219  GstPadTemplate *tmpl =
220  gst_element_class_get_pad_template (child_elem_class, child_tmpl_name);
221  tmpl = gst_pad_template_new (pad_tmpl_name ? pad_tmpl_name : child_tmpl_name,
222  tmpl->direction, tmpl->presence, tmpl->caps);
223  gst_element_class_add_pad_template (bin_class, tmpl);
224  g_type_class_unref (child_elem_class);
225 }
226 
227 template <class T>
228 class GstObjectUPtr:public std::unique_ptr<T, void (*)(T *)>
229 {
230 public:
231  GstObjectUPtr (T * t = nullptr): std::unique_ptr<T, void (*)(T *)>(t, (void (*)(T *)) gst_object_unref) {}
232  operator T* () const { return this->get (); }
233 };
234 
235 class GstCapsUPtr:public std::unique_ptr <GstCaps, void (*)(GstCaps *)>
236 {
237 public:
238  GstCapsUPtr (GstCaps * t = nullptr): std::unique_ptr < GstCaps, void (*)(GstCaps *) > (t, gst_caps_unref) {}
239  operator GstCaps* () const { return this->get (); }
240 };
241 
243 
244 #define NVGSTDS_ELEM_ADD_PROBE(parent_elem, elem, pad, probe_func, probe_type, probe_data) \
245  ({ \
246  gulong probe_id = 0; \
247  GstPad *gstpad = gst_element_get_static_pad (elem, pad); \
248  if (!gstpad) { \
249  GST_ELEMENT_ERROR(parent_elem, RESOURCE, FAILED, \
250  ("Could not find '%s' in '%s'", pad, \
251  GST_ELEMENT_NAME(elem)), (NULL)); \
252  } else { \
253  probe_id = gst_pad_add_probe(gstpad, (GstPadProbeType) (probe_type), probe_func, probe_data, NULL); \
254  gst_object_unref (gstpad); \
255  } \
256  probe_id; \
257  })
258 
259 #define NVGSTDS_LINK_ELEMENT(elem1, elem2, ...) \
260  ({ \
261  if (!gst_element_link (elem1,elem2)) { \
262  GstCaps * src_caps, *sink_caps; \
263  src_caps = gst_pad_query_caps ((GstPad *) (elem1)->srcpads->data, NULL); \
264  sink_caps = gst_pad_query_caps ((GstPad *) (elem2)->sinkpads->data, NULL); \
265  GST_ELEMENT_ERROR (GST_ELEMENT_PARENT(elem1), STREAM, FAILED, \
266  ("Failed to link '%s' (%s) and '%s' (%s)", \
267  GST_ELEMENT_NAME (elem1), \
268  gst_caps_to_string (src_caps), \
269  GST_ELEMENT_NAME (elem2), \
270  gst_caps_to_string (sink_caps)), (NULL)); \
271  return __VA_ARGS__; \
272  } \
273  })
274 
275 #define NVGSTDS_BIN_ADD_GHOST_PAD(bin, elem, pad, ...) \
276  do { \
277  GstPadUPtr gstpad = gst_element_get_static_pad (elem, pad); \
278  if (!gstpad) { \
279  GST_ELEMENT_ERROR(bin, STREAM, FAILED, ("Could not find '%s' in '%s'", pad, \
280  GST_ELEMENT_NAME(elem)), (NULL)); \
281  return __VA_ARGS__; \
282  } \
283  GstElementClass *klass = GST_ELEMENT_GET_CLASS(bin); \
284  GstPadTemplate *tmpl = gst_element_class_get_pad_template(klass, pad); \
285  gst_element_add_pad (bin, gst_ghost_pad_new_from_template (pad, gstpad, tmpl)); \
286  } while (0)
287 
288 #define NVGSTDS_BIN_SET_GHOST_PAD_TARGET(bin, bin_pad, target, target_pad_name, ...) \
289  do { \
290  GstPadUPtr pad = gst_element_get_static_pad (target, target_pad_name); \
291  if (!pad) { \
292  GST_ELEMENT_ERROR(bin, STREAM, FAILED, ("Could not find '%s' in '%s'", target_pad_name, \
293  GST_ELEMENT_NAME(target)), (NULL)); \
294  return __VA_ARGS__; \
295  } \
296  if (!gst_ghost_pad_set_target (GST_GHOST_PAD \
297  (bin_pad), pad)) { \
298  GST_ELEMENT_ERROR (bin, RESOURCE, NOT_FOUND, \
299  ("Failed to set '%s' as target of '%s' pad", \
300  GST_ELEMENT_NAME (target), \
301  GST_PAD_NAME (bin_pad)), (NULL)); \
302  return __VA_ARGS__; \
303  } \
304  } while (0)
305 
306 static inline void
307 remove_all_children (GstBin * bin)
308 {
309  GstIterator *it = gst_bin_iterate_elements (bin);
310  GValue elem = G_VALUE_INIT;
311  while (gst_iterator_next (it, &elem) == GST_ITERATOR_OK) {
312  gst_bin_remove (bin, GST_ELEMENT (g_value_get_object (&elem)));
313  gst_iterator_resync (it);
314  }
315  gst_iterator_free (it);
316 }
317 
318 #endif /* __GST_DS_DEEPSTREAM_BINS_UTILS_H__ */
FALSE
#define FALSE
Definition: sources/libs/nvll_batch_jpeg_encode/oss/jmorecfg.h:247
nostd::unique_ptr
std::unique_ptr< _Types... > unique_ptr
Definition: includes/opentelemetry/std/unique_ptr.h:19
pydeepstreamdoc::node::NodeDoc::get
constexpr const char * get
Definition: service-maker/sources/python/src/bindings/docstrings/nodedoc.h:34
GstObjectUPtr
Definition: sources/gst-plugins/gst-nvdsbins/gstnvdsbinutils.h:228
GstObjectUPtr::GstObjectUPtr
GstObjectUPtr(T *t=nullptr)
Definition: 9.2/sources/gst-plugins/gst-nvdsbins/gstnvdsbinutils.h:231
remove_all_children
static void remove_all_children(GstBin *bin)
Definition: 9.2/sources/gst-plugins/gst-nvdsbins/gstnvdsbinutils.h:307
uint
unsigned int uint
Definition: sources/libs/nvmultiobjecttracker/include/modules/cuDCFv2/helper_math.h:25
forward_pad_template
static void forward_pad_template(GstElementClass *bin_class, GType child_elem_type, const gchar *child_tmpl_name, const gchar *pad_tmpl_name=nullptr)
Definition: 9.2/sources/gst-plugins/gst-nvdsbins/gstnvdsbinutils.h:214
forward_properties
static void forward_properties(GObjectClass *parent_elem_class, GType child_elem_type, guint *prop_id=NULL)
Definition: 9.2/sources/gst-plugins/gst-nvdsbins/gstnvdsbinutils.h:122
GstCapsUPtr
Definition: sources/gst-plugins/gst-nvdsbins/gstnvdsbinutils.h:235
GValue
struct _GValue GValue
Definition: service-maker/includes/object.hpp:38
GstCapsUPtr::GstCapsUPtr
GstCapsUPtr(GstCaps *t=nullptr)
Definition: 9.2/sources/gst-plugins/gst-nvdsbins/gstnvdsbinutils.h:238
forward_select_properties
static void forward_select_properties(GObjectClass *parent_elem_class, const gchar *(*property_name_map)[2], guint map_size, GType child_elem_type, guint *prop_index, GPtrArray *orig_prop_names_ordered)
Definition: 9.2/sources/gst-plugins/gst-nvdsbins/gstnvdsbinutils.h:26
std
Extensions to the C++ standard library.
Definition: includes/opentelemetry/nostd/string_view.h:212