libxcoder 5.6.0
Loading...
Searching...
No Matches
ni_log.c
Go to the documentation of this file.
1/*******************************************************************************
2 *
3 * Copyright (C) 2022 NETINT Technologies
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
17 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
18 * SOFTWARE.
19 *
20 ******************************************************************************/
21
22/*!*****************************************************************************
23 * \file ni_log.c
24 *
25 * \brief Logging definitions
26 ******************************************************************************/
27
28#include <string.h>
29#include <stdio.h>
30#include <stdint.h>
31#include <time.h>
32#include <inttypes.h>
33#ifdef _WIN32
34#include <windows.h>
35#else
36#include <sys/time.h>
37#endif
38#include "ni_log.h"
39#include "ni_defs.h"
40#include "ni_device_api.h"
41#include "ni_util.h"
42
43
44static ni_log_level_t ni_log_level = NI_LOG_INFO;
45static void (*ni_log_callback)(int, const char*, va_list) =
47
48#ifdef _WIN32
49static ni_pthread_mutex_t ni_log2_mutex;
50static int ni_log2_mutex_initialized = 0;
51INIT_ONCE g_InitOnce_ni_log2_mutex = INIT_ONCE_STATIC_INIT;
52#else
53static ni_pthread_mutex_t ni_log2_mutex = PTHREAD_MUTEX_INITIALIZER;
54//pthread
55#endif
56static int ni_log2_print_with_mutex = 0;
57
58#define NI_LOG2_SESSION_ID_TIMESTAMP_FMT "[SID=%x, TS=" "%" PRIu64 "]"
59#define NI_LOG2_TIMESTAMP_FMT "[TS=" "%" PRIu64 "]"
60#define NI_LOG2_SESSION_ID_FMT "[SID=%x]"
61#define NI_LOG2_E2EID_FMT "|%s|"
62#define NI_LOG2_FMT_FMT "%s"
63#define NI_LOG2_SPACE " "
64
65#define NI_LOG2_PRINT_BUFF_SIZE 512
66
67#ifdef _ANDROID
68#include <android/log.h>
69
70static char ni_log_tag[128] = "libxcoder";
71
72#define ALOGV(fmt, ...) \
73 __android_log_vprint(ANDROID_LOG_VERBOSE, ni_log_tag, fmt, ##__VA_ARGS__)
74#define ALOGD(fmt, ...) \
75 __android_log_vprint(ANDROID_LOG_DEBUG, ni_log_tag, fmt, ##__VA_ARGS__)
76#define ALOGI(fmt, ...) \
77 __android_log_vprint(ANDROID_LOG_INFO, ni_log_tag, fmt, ##__VA_ARGS__)
78#define ALOGW(fmt, ...) \
79 __android_log_vprint(ANDROID_LOG_WARN, ni_log_tag, fmt, ##__VA_ARGS__)
80#define ALOGE(fmt, ...) \
81 __android_log_vprint(ANDROID_LOG_ERROR, ni_log_tag, fmt, ##__VA_ARGS__)
82#endif
83
84
85/*!*****************************************************************************
86 * \brief Get time for logs with microsecond timestamps
87 *
88 * \param[in/out] p_tp timeval struct
89 * \param[in] p_tzp timezone struct
90 *
91 * \return return 0 for success, -1 for error
92 ******************************************************************************/
93int32_t ni_log_gettimeofday(struct timeval *p_tp, struct timezone *p_tzp)
94{
95#ifdef _WIN32
96 FILETIME file_time;
97 SYSTEMTIME system_time;
98 ULARGE_INTEGER ularge;
100 static const unsigned __int64 epoch =
101 ((unsigned __int64)116444736000000000ULL);
102
103 // timezone information is stored outside the kernel so tzp isn't used
104 (void)p_tzp;
106 // Note: this function is not a precision timer. See elapsed_time().
107 GetSystemTime(&system_time);
108 SystemTimeToFileTime(&system_time, &file_time);
109 ularge.LowPart = file_time.dwLowDateTime;
110 ularge.HighPart = file_time.dwHighDateTime;
111 // Surpress cppcheck
112 (void)ularge.LowPart;
113 (void)ularge.HighPart;
114 p_tp->tv_sec = (long)((ularge.QuadPart - epoch) / 10000000L);
115 p_tp->tv_usec = (long)(system_time.wMilliseconds * 1000);
116
117 return 0;
118#else
119 return gettimeofday(p_tp, p_tzp);
120#endif
121}
122
123/*!*****************************************************************************
124 * \brief Default ni_log() callback
125 *
126 * \param[in] level log level
127 * \param[in] fmt printf format specifier
128 * \param[in] vl variadric args list
129 *
130 * \return
131 * \note This function doesn't automatically append a newline to the end of
132 * the log message.
133 ******************************************************************************/
134void ni_log_default_callback(int level, const char* fmt, va_list vl)
135{
136 if (level <= ni_log_level)
137 {
138#ifndef _ANDROID
139#ifdef NI_LOG_TRACE_TIMESTAMPS
140 if (level == NI_LOG_TRACE)
141 {
142 struct timeval tv;
143 ni_log_gettimeofday(&tv, NULL);
144 fprintf(stderr, "[%" PRIu64 "] ", (uint64_t) (tv.tv_sec * 1000000LL + tv.tv_usec));
145 }
146#endif
147#endif
148
149#ifdef _ANDROID
150 if (level >= NI_LOG_DEBUG)
151 ALOGD(fmt, vl);
152 else if (level == NI_LOG_INFO)
153 ALOGI(fmt, vl);
154 else
155 ALOGE(fmt, vl);
156#else
157 vfprintf(stderr, fmt, vl);
158#endif
159 }
160}
161
162/*!*****************************************************************************
163 * \brief Set ni_log() callback
164 *
165 * \param[in] callback
166 *
167 * \return
168 ******************************************************************************/
169void ni_log_set_callback(void (*log_callback)(int, const char*, va_list))
170{
171 ni_log_callback = log_callback;
172}
173
174/*!*****************************************************************************
175 * \brief print log message using ni_log_callback
176 *
177 * \param[in] level log level
178 * \param[in] format printf format specifier
179 * \param[in] ... additional arguments
180 *
181 * \return
182 ******************************************************************************/
183void ni_log(ni_log_level_t level, const char *fmt, ...)
184{
185 va_list vl;
186
187 va_start(vl, fmt);
188 if (ni_log_callback)
189 {
190 ni_log_callback(level, fmt, vl);
191 }
192 va_end(vl);
193}
194
195/*!*****************************************************************************
196 * \brief Set ni_log_level
197 *
198 * \param level log level
199 *
200 * \return
201 ******************************************************************************/
203{
204 ni_log_level = level;
205}
206
207/*!*****************************************************************************
208 * \brief Get ni_log_level
209 *
210 * \return ni_log_level
211 ******************************************************************************/
213{
214 return ni_log_level;
215}
216
217/*!*****************************************************************************
218 * \brief Convert ffmpeg log level integer to appropriate ni_log_level_t
219 *
220 * \param fflog_level integer representation of FFmpeg log level
221 *
222 * \return ni_log_level
223 ******************************************************************************/
225{
226 ni_log_level_t converted_ni_log_level = NI_LOG_ERROR;
227 if (fflog_level <= -8)
228 {
229 converted_ni_log_level = NI_LOG_NONE;
230 }
231 else if (fflog_level <= 8)
232 {
233 converted_ni_log_level = NI_LOG_FATAL;
234 }
235 else if (fflog_level <= 16)
236 {
237 converted_ni_log_level = NI_LOG_ERROR;
238 }
239 else if (fflog_level <= 32)
240 {
241 converted_ni_log_level = NI_LOG_INFO;
242 }
243 else if (fflog_level <= 48)
244 {
245 converted_ni_log_level = NI_LOG_DEBUG;
246 }
247 else
248 {
249 converted_ni_log_level = NI_LOG_TRACE;
250 }
251 return converted_ni_log_level;
252}
253
254
255/*!*****************************************************************************
256 * \brief Convert terminal arg string to ni_log_level_t
257 *
258 * \param log_str character pointer of log level arg in terminal
259 *
260 * \return ni_log_level
261 ******************************************************************************/
263{
264#ifdef _WIN32
265 int (*strcicmp) (const char*, const char *) = &_stricmp;
266#else
267 int (*strcicmp) (const char*, const char *) = &strcasecmp;
268#endif
269
270 if (!(*strcicmp)(arg_str, "none"))
271 {
272 return NI_LOG_NONE;
273 } else if (!(*strcicmp)(arg_str, "fatal"))
274 {
275 return NI_LOG_FATAL;
276 } else if (!(*strcicmp)(arg_str, "error"))
277 {
278 return NI_LOG_ERROR;
279 } else if (!(*strcicmp)(arg_str, "info"))
280 {
281 return NI_LOG_INFO;
282 } else if (!(*strcicmp)(arg_str, "debug"))
283 {
284 return NI_LOG_DEBUG;
285 } else if (!(*strcicmp)(arg_str, "trace"))
286 {
287 return NI_LOG_TRACE;
288 } else {
289 return NI_LOG_INVALID;
290 }
291}
292
293#ifdef _ANDROID
294/*!******************************************************************************
295 * \brief Set ni_log_tag
296 *
297 * \param log tag
298 *
299 * \return
300 *******************************************************************************/
301void ni_log_set_log_tag(const char *log_tag)
302{
303 strcpy(ni_log_tag, log_tag);
304 ni_log_tag[strlen(log_tag)] = '\0';
305}
306#endif
307
309{
310 struct timeval tv;
311 ni_log_gettimeofday(&tv, NULL);
312 return (uint64_t) (tv.tv_sec * 1000000LL + tv.tv_usec);
313}
314
315#ifdef _WIN32
316static BOOL CALLBACK ni_log2_init_mutex_once_callback(PINIT_ONCE InitOnce,
317 PVOID Parameter,
318 PVOID *Context)
319{
320 ni_pthread_mutex_init(&ni_log2_mutex);
321 ni_log2_mutex_initialized = 1;
322 return true;
323}
324#endif
325
327{
328#ifdef _WIN32
329 if(!ni_log2_mutex_initialized && on)
330 {
331 InitOnceExecuteOnce(&g_InitOnce_ni_log2_mutex, ni_log2_init_mutex_once_callback, NULL, NULL);
332 }
333#endif
334 ni_log2_print_with_mutex = on;
335}
336
337void ni_log2(const void *p_context, ni_log_level_t level, const char *fmt, ...)
338{
339 const ni_session_context_t *p_session_context = (const ni_session_context_t *)p_context;
340
341 if(level > ni_log_level)
342 {
343 return;
344 }
345
346 if(ni_log2_print_with_mutex)
347 {
348 ni_pthread_mutex_lock(&ni_log2_mutex);
349
350 if(p_session_context && level == NI_LOG_ERROR)
351 {
353 p_session_context->session_id, ni_log_get_utime(), p_session_context->E2EID);
354 }
355 else if(p_session_context)
356 {
358 p_session_context->session_id, p_session_context->E2EID);
359 }
360 else if (level == NI_LOG_ERROR)
361 {
364 }
365
366 va_list vl;
367 va_start(vl, fmt);
368 if (ni_log_callback)
369 {
370 ni_log_callback(level, fmt, vl);
371 }
372 va_end(vl);
373
374 ni_pthread_mutex_unlock(&ni_log2_mutex);
375 }
376 else
377 {
378 if(!p_session_context && level != NI_LOG_ERROR)
379 {
380 va_list vl;
381 va_start(vl, fmt);
382 if (ni_log_callback)
383 {
384 ni_log_callback(level, fmt, vl);
385 }
386 va_end(vl);
387
388 return;
389 }
390
391 char printbuf[NI_LOG2_PRINT_BUFF_SIZE];
392 // int used_size = 0;
393 // size_t free_size = NI_LOG2_PRINT_BUFF_SIZE;
394 int this_used_size = 0;
395
396 if(p_session_context && level == NI_LOG_ERROR)
397 {
398 this_used_size = snprintf(printbuf, NI_LOG2_PRINT_BUFF_SIZE,
400 p_session_context->session_id, ni_log_get_utime(), p_session_context->E2EID, fmt);
401 }
402 else if(p_session_context)
403 {
404 this_used_size = snprintf(printbuf, NI_LOG2_PRINT_BUFF_SIZE,
406 p_session_context->session_id, p_session_context->E2EID, fmt);
407 }
408 else if (level == NI_LOG_ERROR)
409 {
410 this_used_size = snprintf(printbuf, NI_LOG2_PRINT_BUFF_SIZE,
412 ni_log_get_utime(), fmt);
413 }
414
415 if(this_used_size < 0)
416 {
417 ni_log(NI_LOG_ERROR,"ni_log2: an error occurd in snprintf\n");
418
419 va_list vl;
420 va_start(vl, fmt);
421 if (ni_log_callback)
422 {
423 ni_log_callback(level, fmt, vl);
424 }
425 va_end(vl);
426
427 return;
428 }
429
430 if(this_used_size >= NI_LOG2_PRINT_BUFF_SIZE)
431 {
432 ni_log(NI_LOG_ERROR,"ni_log2: too many characters for output\n");
433
434 va_list vl;
435 va_start(vl, fmt);
436 if (ni_log_callback)
437 {
438 ni_log_callback(level, fmt, vl);
439 }
440 va_end(vl);
441
442 return;
443 }
444
445 va_list vl;
446 va_start(vl, fmt);
447 if (ni_log_callback)
448 {
449 ni_log_callback(level, printbuf, vl);
450 }
451 va_end(vl);
452
453 }
454}
Common NETINT definitions used by all modules.
Public definitions for operating NETINT video processing devices for video processing.
void ni_log_default_callback(int level, const char *fmt, va_list vl)
Default ni_log() callback.
Definition ni_log.c:134
ni_log_level_t ni_log_get_level(void)
Get ni_log_level.
Definition ni_log.c:212
#define NI_LOG2_SESSION_ID_FMT
Definition ni_log.c:60
#define NI_LOG2_FMT_FMT
Definition ni_log.c:62
#define NI_LOG2_TIMESTAMP_FMT
Definition ni_log.c:59
#define NI_LOG2_SPACE
Definition ni_log.c:63
#define NI_LOG2_E2EID_FMT
Definition ni_log.c:61
void ni_log2(const void *p_context, ni_log_level_t level, const char *fmt,...)
print log message and additional information using ni_log_callback,
Definition ni_log.c:337
ni_log_level_t ff_to_ni_log_level(int fflog_level)
Convert ffmpeg log level integer to appropriate ni_log_level_t.
Definition ni_log.c:224
void ni_log_set_callback(void(*log_callback)(int, const char *, va_list))
Set ni_log() callback.
Definition ni_log.c:169
uint64_t ni_log_get_utime()
Get time for logs with microsecond timestamps.
Definition ni_log.c:308
ni_log_level_t arg_to_ni_log_level(const char *arg_str)
Convert terminal arg string to ni_log_level_t.
Definition ni_log.c:262
void ni_log_set_level(ni_log_level_t level)
Set ni_log_level.
Definition ni_log.c:202
void ni_log2_with_mutex(int on)
set whether to use a lock or not in ni_log2
Definition ni_log.c:326
#define NI_LOG2_PRINT_BUFF_SIZE
Definition ni_log.c:65
void ni_log(ni_log_level_t level, const char *fmt,...)
print log message using ni_log_callback
Definition ni_log.c:183
int32_t ni_log_gettimeofday(struct timeval *p_tp, struct timezone *p_tzp)
Get time for logs with microsecond timestamps.
Definition ni_log.c:93
#define NI_LOG2_SESSION_ID_TIMESTAMP_FMT
Definition ni_log.c:58
Logging definitions.
ni_log_level_t
Definition ni_log.h:58
@ NI_LOG_NONE
Definition ni_log.h:60
@ NI_LOG_DEBUG
Definition ni_log.h:64
@ NI_LOG_TRACE
Definition ni_log.h:65
@ NI_LOG_FATAL
Definition ni_log.h:61
@ NI_LOG_ERROR
Definition ni_log.h:62
@ NI_LOG_INFO
Definition ni_log.h:63
@ NI_LOG_INVALID
Definition ni_log.h:59
int ni_pthread_mutex_lock(ni_pthread_mutex_t *mutex)
thread mutex lock
Definition ni_util.c:4686
int ni_pthread_mutex_unlock(ni_pthread_mutex_t *mutex)
thread mutex unlock
Definition ni_util.c:4712
int ni_pthread_mutex_init(ni_pthread_mutex_t *mutex)
initialize a mutex
Definition ni_util.c:4630
Utility definitions.