/src/vlc/include/vlc_tracer.h
Line | Count | Source (jump to first uncovered line) |
1 | | /***************************************************************************** |
2 | | * vlc_tracer.h: tracing interface |
3 | | * This library provides basic functions for threads to interact with user |
4 | | * interface, such as trace output. |
5 | | ***************************************************************************** |
6 | | * Copyright (C) 2021 VLC authors and VideoLAN |
7 | | * |
8 | | * This program is free software; you can redistribute it and/or modify it |
9 | | * under the terms of the GNU Lesser General Public License as published by |
10 | | * the Free Software Foundation; either version 2.1 of the License, or |
11 | | * (at your option) any later version. |
12 | | * |
13 | | * This program is distributed in the hope that it will be useful, |
14 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | | * GNU Lesser General Public License for more details. |
17 | | * |
18 | | * You should have received a copy of the GNU Lesser General Public License |
19 | | * along with this program; if not, write to the Free Software Foundation, |
20 | | * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. |
21 | | *****************************************************************************/ |
22 | | |
23 | | #ifndef VLC_TRACES_H |
24 | | #define VLC_TRACES_H |
25 | | |
26 | | #include <stdarg.h> |
27 | | |
28 | | #include <vlc_common.h> |
29 | | #include <vlc_threads.h> |
30 | | |
31 | | /** |
32 | | * \defgroup tracer Tracer module and API |
33 | | * \ingroup os |
34 | | * |
35 | | * Functions for modules to emit traces. |
36 | | * |
37 | | * @{ |
38 | | * \file |
39 | | * Tracing functions |
40 | | * |
41 | | * \defgroup tracer_module Tracer Module implementation |
42 | | * \ingroup tracer |
43 | | * |
44 | | * @{ |
45 | | */ |
46 | | |
47 | | /** |
48 | | * Trace message values |
49 | | */ |
50 | | enum vlc_tracer_value |
51 | | { |
52 | | VLC_TRACER_INT, |
53 | | VLC_TRACER_DOUBLE, |
54 | | VLC_TRACER_STRING, |
55 | | VLC_TRACER_UINT, |
56 | | }; |
57 | | |
58 | | typedef union |
59 | | { |
60 | | int64_t integer; |
61 | | double double_; |
62 | | const char *string; |
63 | | uint64_t uinteger; |
64 | | } vlc_tracer_value_t; |
65 | | |
66 | | /** |
67 | | * Trace message |
68 | | */ |
69 | | struct vlc_tracer_entry |
70 | | { |
71 | | const char *key; /**< Key to identify the value */ |
72 | | vlc_tracer_value_t value; /**< Trace value */ |
73 | | enum vlc_tracer_value type; /**< Type of the value */ |
74 | | }; |
75 | | |
76 | | struct vlc_tracer; |
77 | | |
78 | | /** |
79 | | * Trace record containing the key-values from the trace. |
80 | | */ |
81 | | struct vlc_tracer_trace |
82 | | { |
83 | | /** |
84 | | * Defines the list of key-value in the trace. The entries must link |
85 | | * towards an array terminated by a VLC_TRACE_END entry, which remains |
86 | | * valid as long as the trace itself should remain valid. |
87 | | **/ |
88 | | const struct vlc_tracer_entry *entries; |
89 | | }; |
90 | | |
91 | | |
92 | | /** |
93 | | * Tracer operations returned by the module probe function |
94 | | */ |
95 | | struct vlc_tracer_operations |
96 | | { |
97 | | /** |
98 | | * Called when tracing data |
99 | | * |
100 | | * \param sys data pointer set by vlc_tracer_open_cb() |
101 | | * \param ts timestamp of the trace (based on vlc_tick_now()) |
102 | | * \param entries can only be \ref vlc_tracer_entry and the va-args list |
103 | | * should be ended by a \ref vlc_tracer_entry with a NULL key. |
104 | | */ |
105 | | void (*trace)(void *sys, vlc_tick_t ts, const struct vlc_tracer_trace *trace); |
106 | | |
107 | | /** |
108 | | * Called to clean module specific resources |
109 | | * |
110 | | * \param sys data pointer set by vlc_tracer_open_cb() |
111 | | */ |
112 | | void (*destroy)(void *sys); |
113 | | }; |
114 | | |
115 | | /** |
116 | | * Module probe/open function signature |
117 | | * |
118 | | * \param obj a valid object |
119 | | * \param[out] sysp to module specific data |
120 | | * \return the operations implemented by the module or NULL in case of error |
121 | | * */ |
122 | | typedef struct vlc_tracer_operations *(*vlc_tracer_open_cb)(vlc_object_t *obj, |
123 | | void **restrict sysp); |
124 | | |
125 | | /** |
126 | | * @} |
127 | | * |
128 | | * \defgroup tracer_api Tracer API |
129 | | * \ingroup tracer |
130 | | * |
131 | | * @{ |
132 | | */ |
133 | | |
134 | | /** |
135 | | * Create a tracer object |
136 | | * |
137 | | * \note This function is for advanced debugging/testing. |
138 | | * Use vlc_object_get_tracer() to get the existing tracer. |
139 | | * |
140 | | * \param parent parent object used to create the tracer |
141 | | * \param name module to load or NULL for the default one |
142 | | * \return a valid tracer or NULL in case of error |
143 | | */ |
144 | | VLC_API struct vlc_tracer *vlc_tracer_Create(vlc_object_t *parent, |
145 | | const char *name); |
146 | | |
147 | | /** |
148 | | * Destroy a tracer object |
149 | | */ |
150 | | VLC_API void vlc_tracer_Destroy(struct vlc_tracer *tracer); |
151 | | |
152 | | /** |
153 | | * Emit traces |
154 | | * |
155 | | * \param tracer tracer emitting the traces |
156 | | * \param ts timestamp of the current trace |
157 | | * \param trace the trace to register with its list of key / value parameters. |
158 | | * Key must be a not NULL string. Value has to be defined with |
159 | | * one of the type defined in the \ref vlc_tracer_entry union. |
160 | | */ |
161 | | |
162 | | VLC_API void vlc_tracer_TraceWithTs(struct vlc_tracer *tracer, vlc_tick_t ts, |
163 | | const struct vlc_tracer_trace *trace); |
164 | | #define vlc_tracer_TraceWithTs(tracer, ts, ...) \ |
165 | 0 | (vlc_tracer_TraceWithTs)(tracer, ts, &(const struct vlc_tracer_trace) { \ |
166 | 0 | .entries = (const struct vlc_tracer_entry[]) { \ |
167 | 0 | __VA_ARGS__ \ |
168 | 0 | } \ |
169 | 0 | }) |
170 | | |
171 | | #define vlc_tracer_Trace(tracer, ...) \ |
172 | 0 | vlc_tracer_TraceWithTs(tracer, vlc_tick_now(), __VA_ARGS__) |
173 | | |
174 | | static inline struct vlc_tracer_entry vlc_tracer_entry_FromInt(const char *key, int64_t value) |
175 | 0 | { |
176 | 0 | vlc_tracer_value_t tracer_value; |
177 | 0 | tracer_value.integer = value; |
178 | 0 | struct vlc_tracer_entry trace = { key, tracer_value, VLC_TRACER_INT }; |
179 | 0 | return trace; |
180 | 0 | } Unexecuted instantiation: libvlc.c:vlc_tracer_entry_FromInt Unexecuted instantiation: decoder.c:vlc_tracer_entry_FromInt Unexecuted instantiation: dec.c:vlc_tracer_entry_FromInt Unexecuted instantiation: video_output.c:vlc_tracer_entry_FromInt Unexecuted instantiation: tracer.c:vlc_tracer_entry_FromInt Unexecuted instantiation: clock.c:vlc_tracer_entry_FromInt Unexecuted instantiation: es_out.c:vlc_tracer_entry_FromInt |
181 | | |
182 | | static inline struct vlc_tracer_entry vlc_tracer_entry_FromUnsigned(const char *key, uint64_t value) |
183 | 0 | { |
184 | 0 | vlc_tracer_value_t tracer_value; |
185 | 0 | tracer_value.uinteger = value; |
186 | 0 | struct vlc_tracer_entry trace = { key, tracer_value, VLC_TRACER_UINT }; |
187 | 0 | return trace; |
188 | 0 | } Unexecuted instantiation: libvlc.c:vlc_tracer_entry_FromUnsigned Unexecuted instantiation: decoder.c:vlc_tracer_entry_FromUnsigned Unexecuted instantiation: dec.c:vlc_tracer_entry_FromUnsigned Unexecuted instantiation: video_output.c:vlc_tracer_entry_FromUnsigned Unexecuted instantiation: tracer.c:vlc_tracer_entry_FromUnsigned Unexecuted instantiation: clock.c:vlc_tracer_entry_FromUnsigned Unexecuted instantiation: es_out.c:vlc_tracer_entry_FromUnsigned |
189 | | |
190 | | static inline struct vlc_tracer_entry vlc_tracer_entry_FromDouble(const char *key, double value) |
191 | 0 | { |
192 | 0 | vlc_tracer_value_t tracer_value = { |
193 | 0 | .double_ = value, |
194 | 0 | }; |
195 | 0 | struct vlc_tracer_entry trace = { key, tracer_value, VLC_TRACER_DOUBLE }; |
196 | 0 | return trace; |
197 | 0 | } Unexecuted instantiation: libvlc.c:vlc_tracer_entry_FromDouble Unexecuted instantiation: decoder.c:vlc_tracer_entry_FromDouble Unexecuted instantiation: dec.c:vlc_tracer_entry_FromDouble Unexecuted instantiation: video_output.c:vlc_tracer_entry_FromDouble Unexecuted instantiation: tracer.c:vlc_tracer_entry_FromDouble Unexecuted instantiation: clock.c:vlc_tracer_entry_FromDouble Unexecuted instantiation: es_out.c:vlc_tracer_entry_FromDouble |
198 | | |
199 | | static inline struct vlc_tracer_entry vlc_tracer_entry_FromString(const char *key, const char *value) |
200 | 0 | { |
201 | 0 | vlc_tracer_value_t tracer_value; |
202 | 0 | tracer_value.string = value; |
203 | 0 | struct vlc_tracer_entry trace = { key, tracer_value, VLC_TRACER_STRING }; |
204 | 0 | return trace; |
205 | 0 | } Unexecuted instantiation: libvlc.c:vlc_tracer_entry_FromString Unexecuted instantiation: decoder.c:vlc_tracer_entry_FromString Unexecuted instantiation: dec.c:vlc_tracer_entry_FromString Unexecuted instantiation: video_output.c:vlc_tracer_entry_FromString Unexecuted instantiation: tracer.c:vlc_tracer_entry_FromString Unexecuted instantiation: clock.c:vlc_tracer_entry_FromString Unexecuted instantiation: es_out.c:vlc_tracer_entry_FromString |
206 | | |
207 | | #ifndef __cplusplus |
208 | | #define VLC_TRACE_END \ |
209 | | vlc_tracer_entry_FromString(NULL, NULL) |
210 | | |
211 | | #define VLC_TRACE(key, value) \ |
212 | | _Generic((value), \ |
213 | | uint64_t: vlc_tracer_entry_FromUnsigned, \ |
214 | | int64_t: vlc_tracer_entry_FromInt, \ |
215 | | double: vlc_tracer_entry_FromDouble, \ |
216 | | char *: vlc_tracer_entry_FromString, \ |
217 | | const char *: vlc_tracer_entry_FromString) (key, value) |
218 | | #else |
219 | | #define VLC_TRACE_END \ |
220 | | vlc_tracer_entry_FromString(nullptr, nullptr) |
221 | | |
222 | | static inline struct vlc_tracer_entry VLC_TRACE(const char *key, int64_t value) |
223 | | { |
224 | | return vlc_tracer_entry_FromInt(key, value); |
225 | | } |
226 | | |
227 | | static inline struct vlc_tracer_entry VLC_TRACE(const char *key, uint64_t value) |
228 | | { |
229 | | return vlc_tracer_entry_FromUnsigned(key, value); |
230 | | } |
231 | | |
232 | | static inline struct vlc_tracer_entry VLC_TRACE(const char *key, char *value) |
233 | | { |
234 | | return vlc_tracer_entry_FromString(key, value); |
235 | | } |
236 | | |
237 | | static inline struct vlc_tracer_entry VLC_TRACE(const char *key, const char *value) |
238 | | { |
239 | | return vlc_tracer_entry_FromString(key, value); |
240 | | } |
241 | | #endif |
242 | | |
243 | | #define VLC_TRACE_TICK_NS(key, tick) VLC_TRACE((key), NS_FROM_VLC_TICK((tick))) |
244 | | |
245 | | /** |
246 | | * @} |
247 | | * |
248 | | * \defgroup tracer_helper Tracer helper functions |
249 | | * \ingroup tracer |
250 | | * |
251 | | * @{ |
252 | | */ |
253 | | |
254 | | static inline void vlc_tracer_TraceStreamPTS(struct vlc_tracer *tracer, const char *type, |
255 | | const char *id, const char* stream, |
256 | | vlc_tick_t pts) |
257 | 0 | { |
258 | 0 | vlc_tracer_Trace(tracer, VLC_TRACE("type", type), |
259 | 0 | VLC_TRACE("id", id), |
260 | 0 | VLC_TRACE("stream", stream), |
261 | 0 | VLC_TRACE_TICK_NS("pts", pts), |
262 | 0 | VLC_TRACE_END); |
263 | 0 | } Unexecuted instantiation: libvlc.c:vlc_tracer_TraceStreamPTS Unexecuted instantiation: decoder.c:vlc_tracer_TraceStreamPTS Unexecuted instantiation: dec.c:vlc_tracer_TraceStreamPTS Unexecuted instantiation: video_output.c:vlc_tracer_TraceStreamPTS Unexecuted instantiation: tracer.c:vlc_tracer_TraceStreamPTS Unexecuted instantiation: clock.c:vlc_tracer_TraceStreamPTS Unexecuted instantiation: es_out.c:vlc_tracer_TraceStreamPTS |
264 | | |
265 | | static inline void vlc_tracer_TraceStreamDTS(struct vlc_tracer *tracer, const char *type, |
266 | | const char *id, const char* stream, |
267 | | vlc_tick_t pts, vlc_tick_t dts) |
268 | 0 | { |
269 | 0 | vlc_tracer_Trace(tracer, VLC_TRACE("type", type), |
270 | 0 | VLC_TRACE("id", id), |
271 | 0 | VLC_TRACE("stream", stream), |
272 | 0 | VLC_TRACE_TICK_NS("pts", pts), |
273 | 0 | VLC_TRACE_TICK_NS("dts", dts), |
274 | 0 | VLC_TRACE_END); |
275 | 0 | } Unexecuted instantiation: libvlc.c:vlc_tracer_TraceStreamDTS Unexecuted instantiation: decoder.c:vlc_tracer_TraceStreamDTS Unexecuted instantiation: dec.c:vlc_tracer_TraceStreamDTS Unexecuted instantiation: video_output.c:vlc_tracer_TraceStreamDTS Unexecuted instantiation: tracer.c:vlc_tracer_TraceStreamDTS Unexecuted instantiation: clock.c:vlc_tracer_TraceStreamDTS Unexecuted instantiation: es_out.c:vlc_tracer_TraceStreamDTS |
276 | | |
277 | | static inline void vlc_tracer_TraceEvent(struct vlc_tracer *tracer, const char *type, |
278 | | const char *id, const char *event) |
279 | 0 | { |
280 | 0 | vlc_tracer_Trace(tracer, VLC_TRACE("type", type), |
281 | 0 | VLC_TRACE("id", id), |
282 | 0 | VLC_TRACE("event", event), |
283 | 0 | VLC_TRACE_END); |
284 | 0 | } Unexecuted instantiation: libvlc.c:vlc_tracer_TraceEvent Unexecuted instantiation: decoder.c:vlc_tracer_TraceEvent Unexecuted instantiation: dec.c:vlc_tracer_TraceEvent Unexecuted instantiation: video_output.c:vlc_tracer_TraceEvent Unexecuted instantiation: tracer.c:vlc_tracer_TraceEvent Unexecuted instantiation: clock.c:vlc_tracer_TraceEvent Unexecuted instantiation: es_out.c:vlc_tracer_TraceEvent |
285 | | |
286 | | static inline void vlc_tracer_TracePCR( struct vlc_tracer *tracer, const char *type, |
287 | | const char *id, vlc_tick_t pcr) |
288 | 0 | { |
289 | 0 | vlc_tracer_Trace(tracer, VLC_TRACE("type", type), |
290 | 0 | VLC_TRACE("id", id), |
291 | 0 | VLC_TRACE_TICK_NS("pcr", pcr), |
292 | 0 | VLC_TRACE_END); |
293 | 0 | } Unexecuted instantiation: libvlc.c:vlc_tracer_TracePCR Unexecuted instantiation: decoder.c:vlc_tracer_TracePCR Unexecuted instantiation: dec.c:vlc_tracer_TracePCR Unexecuted instantiation: video_output.c:vlc_tracer_TracePCR Unexecuted instantiation: tracer.c:vlc_tracer_TracePCR Unexecuted instantiation: clock.c:vlc_tracer_TracePCR Unexecuted instantiation: es_out.c:vlc_tracer_TracePCR |
294 | | |
295 | | /** |
296 | | * @} |
297 | | */ |
298 | | /** |
299 | | * @} |
300 | | */ |
301 | | #endif |