NVIDIA DeepStream SDK API Reference

8.0 Release
9.0/sources/apps/apps-common/includes/deepstream_common.h
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2018-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3  * SPDX-License-Identifier: LicenseRef-NvidiaProprietary
4  *
5  * NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
6  * property and proprietary rights in and to this material, related
7  * documentation and any modifications thereto. Any use, reproduction,
8  * disclosure or distribution of this material and related documentation
9  * without an express license agreement from NVIDIA CORPORATION or
10  * its affiliates is strictly prohibited.
11  */
12 
13 #ifndef __NVGSTDS_COMMON_H__
14 #define __NVGSTDS_COMMON_H__
15 
16 #include <gst/gst.h>
17 #include <stdarg.h>
18 
19 #ifdef __cplusplus
20 extern "C"
21 {
22 #endif
23 
24 #include "deepstream_config.h"
25 
26 /* Global error buffer for capturing last error message */
27 /* Using weak symbol so apps don't need to link deepstream_common.c */
28 __attribute__((weak)) gchar *g_nvds_last_error_message = NULL;
29 
30 /* Helper function to capture and store error messages */
31 static inline void nvds_capture_error(const gchar *func, gint line, const gchar *msg, ...) {
32  va_list args;
33  gchar *formatted_msg;
34  gchar *clean_msg;
35 
36  va_start(args, msg);
37  formatted_msg = g_strdup_vprintf(msg, args);
38  va_end(args);
39 
40  /* Print to console as before */
41  g_print("** ERROR: <%s:%d>: %s\n", func, line, formatted_msg);
42 
43  /* Store in global buffer ONLY IF it's the first error (root cause) */
44  if (!g_nvds_last_error_message) {
45  /* Strip prefix before first colon (e.g. "sink_sub_bin_sink2: error" -> "error") */
46  gchar *colon_pos = strchr(formatted_msg, ':');
47  if (colon_pos) {
48  /* Skip the colon and any leading whitespace */
49  clean_msg = g_strstrip(g_strdup(colon_pos + 1));
50  g_nvds_last_error_message = clean_msg;
51  } else {
52  /* No colon found, use the whole message */
53  g_nvds_last_error_message = g_strdup(formatted_msg);
54  }
55  }
56 
57  g_free(formatted_msg);
58 }
59 
60 #define NVGSTDS_ERR_MSG_V(msg, ...) \
61  nvds_capture_error(__func__, __LINE__, msg, ##__VA_ARGS__)
62 
63 #define NVGSTDS_INFO_MSG_V(msg, ...) \
64  g_print("** INFO: <%s:%d>: " msg "\n", __func__, __LINE__, ##__VA_ARGS__)
65 
66 #define NVGSTDS_WARN_MSG_V(msg, ...) \
67  g_print("** WARN: <%s:%d>: " msg "\n", __func__, __LINE__, ##__VA_ARGS__)
68 
69 #define NVGSTDS_LINK_ELEMENT(elem1, elem2) \
70  do { \
71  if (!gst_element_link (elem1,elem2)) { \
72  GstCaps *src_caps, *sink_caps; \
73  src_caps = gst_pad_query_caps ((GstPad *) (elem1)->srcpads->data, NULL); \
74  sink_caps = gst_pad_query_caps ((GstPad *) (elem2)->sinkpads->data, NULL); \
75  NVGSTDS_ERR_MSG_V ("Failed to link '%s' (%s) and '%s' (%s)", \
76  GST_ELEMENT_NAME (elem1), \
77  gst_caps_to_string (src_caps), \
78  GST_ELEMENT_NAME (elem2), \
79  gst_caps_to_string (sink_caps)); \
80  goto done; \
81  } \
82  } while (0)
83 
84 #define NVGSTDS_LINK_ELEMENT_FULL(elem1, elem1_pad_name, elem2, elem2_pad_name) \
85  do { \
86  GstPad *elem1_pad = gst_element_get_static_pad(elem1, elem1_pad_name); \
87  GstPad *elem2_pad = gst_element_get_static_pad(elem2, elem2_pad_name); \
88  GstPadLinkReturn ret = gst_pad_link (elem1_pad,elem2_pad); \
89  if (ret != GST_PAD_LINK_OK) { \
90  gchar *n1 = gst_pad_get_name (elem1_pad); \
91  gchar *n2 = gst_pad_get_name (elem2_pad); \
92  NVGSTDS_ERR_MSG_V ("Failed to link '%s' and '%s': %d", \
93  n1, n2, ret); \
94  g_free (n1); \
95  g_free (n2); \
96  gst_object_unref (elem1_pad); \
97  gst_object_unref (elem2_pad); \
98  goto done; \
99  } \
100  gst_object_unref (elem1_pad); \
101  gst_object_unref (elem2_pad); \
102  } while (0)
103 
104 #define NVGSTDS_BIN_ADD_GHOST_PAD_NAMED(bin, elem, pad, ghost_pad_name) \
105  do { \
106  GstPad *gstpad = gst_element_get_static_pad (elem, pad); \
107  if (!gstpad) { \
108  NVGSTDS_ERR_MSG_V ("Could not find '%s' in '%s'", pad, \
109  GST_ELEMENT_NAME(elem)); \
110  goto done; \
111  } \
112  gst_element_add_pad (bin, gst_ghost_pad_new (ghost_pad_name, gstpad)); \
113  gst_object_unref (gstpad); \
114  } while (0)
115 
116 #define NVGSTDS_BIN_ADD_GHOST_PAD(bin, elem, pad) \
117  NVGSTDS_BIN_ADD_GHOST_PAD_NAMED (bin, elem, pad, pad)
118 
119 #define NVGSTDS_ELEM_ADD_PROBE(probe_id, elem, pad, probe_func, probe_type, probe_data) \
120  do { \
121  GstPad *gstpad = gst_element_get_static_pad (elem, pad); \
122  if (!gstpad) { \
123  NVGSTDS_ERR_MSG_V ("Could not find '%s' in '%s'", pad, \
124  GST_ELEMENT_NAME(elem)); \
125  goto done; \
126  } \
127  probe_id = gst_pad_add_probe(gstpad, (probe_type), probe_func, probe_data, NULL); \
128  gst_object_unref (gstpad); \
129  } while (0)
130 
131 #define NVGSTDS_ELEM_REMOVE_PROBE(probe_id, elem, pad) \
132  do { \
133  if (probe_id == 0 || !elem) { \
134  break; \
135  } \
136  GstPad *gstpad = gst_element_get_static_pad (elem, pad); \
137  if (!gstpad) { \
138  NVGSTDS_ERR_MSG_V ("Could not find '%s' in '%s'", pad, \
139  GST_ELEMENT_NAME(elem)); \
140  break; \
141  } \
142  gst_pad_remove_probe(gstpad, probe_id); \
143  gst_object_unref (gstpad); \
144  } while (0)
145 
146 #define GET_FILE_PATH(path) ((path) + (((path) && strstr ((path), "file://")) ? 7 : 0))
147 
148 
157 gboolean
158 link_element_to_tee_src_pad (GstElement * tee, GstElement * sinkelem);
159 
169 gboolean
170 link_element_to_streammux_sink_pad (GstElement *streammux, GstElement *elem,
171  gint index);
172 
181 gboolean
182 unlink_element_from_streammux_sink_pad (GstElement *streammux, GstElement *elem);
183 
193 gboolean
194 link_element_to_demux_src_pad (GstElement *demux, GstElement *elem,
195  guint index);
196 
197 /*
198  * Function to replace string with another string.
199  * Make sure @ref src is big enough to accommodate replacements.
200  *
201  * @param[in] str string to search in.
202  * @param[in] replace string to replace.
203  * @param[in] replace_with string to replace @ref replace with.
204  */
205 void
206 str_replace (gchar * str, const gchar * replace, const gchar * replace_with);
207 
208 #ifdef __cplusplus
209 }
210 #endif
211 
212 #endif
link_element_to_demux_src_pad
gboolean link_element_to_demux_src_pad(GstElement *demux, GstElement *elem, guint index)
Function to link sink pad of an element to source pad of demux element.
link_element_to_streammux_sink_pad
gboolean link_element_to_streammux_sink_pad(GstElement *streammux, GstElement *elem, gint index)
Function to link source pad of an element to sink pad of muxer element.
str_replace
void str_replace(gchar *str, const gchar *replace, const gchar *replace_with)
nvds_capture_error
static void nvds_capture_error(const gchar *func, gint line, const gchar *msg,...)
Definition: 9.0/sources/apps/apps-common/includes/deepstream_common.h:31
__attribute__
__attribute__((weak)) gchar *g_nvds_last_error_message
unlink_element_from_streammux_sink_pad
gboolean unlink_element_from_streammux_sink_pad(GstElement *streammux, GstElement *elem)
Function to unlink source pad of an element from sink pad of muxer element.
link_element_to_tee_src_pad
gboolean link_element_to_tee_src_pad(GstElement *tee, GstElement *sinkelem)
Function to link sink pad of an element to source pad of tee.
deepstream_config.h