1 /*
2 * log functions
3 * Copyright (c) 2003 Michel Bardiaux
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 /**
23 * @file
24 * logging functions
25 */
26
27 #include "config.h"
28
29 #if HAVE_UNISTD_H
30 #include <unistd.h>
31 #endif
32 #if HAVE_IO_H
33 #include <io.h>
34 #endif
35 #include <inttypes.h>
36 #include <stdarg.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
47
49
51
52 #if HAVE_VALGRIND_VALGRIND_H && CONFIG_VALGRIND_BACKTRACE
53 #include <valgrind/valgrind.h>
54 /* this is the log level at which valgrind will output a full backtrace */
55 #define BACKTRACE_LOGLEVEL AV_LOG_ERROR
56 #endif
57
60
62 #if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE && HAVE_GETSTDHANDLE
63 #include <windows.h>
91 };
92
93 static int16_t background, attr_orig;
94 static HANDLE con;
95 #else
96
124 };
125
126 #endif
128
129 #if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE && HAVE_GETSTDHANDLE
130 static void win_console_puts(const char *str)
131 {
132 const uint8_t *q = str;
134
135 while (*q) {
136 uint16_t *buf =
line;
137 DWORD nb_chars = 0;
138 DWORD written;
139
140 while (*q && nb_chars <
LINE_SZ - 1) {
141 uint32_t ch;
143
144 GET_UTF8(ch, *q ? *q++ : 0, ch = 0xfffd;
goto continue_on_invalid;)
145 continue_on_invalid:
147 }
148
149 WriteConsoleW(con,
line, nb_chars, &written,
NULL);
150 }
151 }
152 #endif
153
155 {
156 char *term = getenv("TERM");
157
158 #if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE && HAVE_GETSTDHANDLE
159 CONSOLE_SCREEN_BUFFER_INFO con_info;
161 con = GetStdHandle(STD_ERROR_HANDLE);
162 if (con != INVALID_HANDLE_VALUE && !GetConsoleMode(con, &
dummy))
163 con = INVALID_HANDLE_VALUE;
164 if (con != INVALID_HANDLE_VALUE) {
165 GetConsoleScreenBufferInfo(con, &con_info);
166 attr_orig = con_info.wAttributes;
167 background = attr_orig & 0xF0;
168 }
169 #endif
170
171 if (getenv("AV_LOG_FORCE_NOCOLOR")) {
173 } else if (getenv("AV_LOG_FORCE_COLOR")) {
175 } else {
176 #if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE && HAVE_GETSTDHANDLE
177 use_color = (con != INVALID_HANDLE_VALUE);
178 #elif HAVE_ISATTY
180 #else
182 #endif
183 }
184
185 if (getenv("AV_LOG_FORCE_256COLOR") || term && strstr(term, "256color"))
187 }
188
190 {
191 if (local_use_color == 1) {
192 fprintf(stderr,
193 "033円[%"PRIu32";3%"PRIu32"m%s033円[0m",
196 str);
198 fprintf(stderr,
199 "033円[48;5;%"PRIu32"m033円[38;5;%dm%s033円[0m",
201 tint,
202 str);
203 } else if (local_use_color == 256) {
204 fprintf(stderr,
205 "033円[48;5;%"PRIu32"m033円[38;5;%"PRIu32"m%s033円[0m",
208 str);
209 } else
210 fputs(str, stderr);
211 }
212
214 {
215 int local_use_color;
216 if (!*str)
217 return;
218
221
224
225 #if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE && HAVE_GETSTDHANDLE
226 if (con != INVALID_HANDLE_VALUE) {
227 if (local_use_color)
228 SetConsoleTextAttribute(con, background |
color[
level]);
229 win_console_puts(str);
230 if (local_use_color)
231 SetConsoleTextAttribute(con, attr_orig);
232 } else {
234 }
235 #else
237 #endif
238
239 }
240
242 {
243 return (*(
AVClass **) ptr)->class_name;
244 }
245
247 {
248 return (*(
AVClass **) ptr)->category;
249 }
250
256 }
257 }
258
261 if( !avc
263 || avc->
version < (51 << 16 | 59 << 8)
265
268
270 }
271
273 {
276 return "quiet";
278 return "debug";
280 return "trace";
282 return "verbose";
284 return "info";
286 return "warning";
288 return "error";
290 return "fatal";
292 return "panic";
293 default:
294 return "";
295 }
296 }
297
299 {
301 }
302
304 {
305 struct tm *ptm, tmbuf;
307 const int64_t time_ms = time_us / 1000;
308 const time_t time_s = time_ms / 1000;
309 const int millisec = time_ms - (time_s * 1000);
311 if (ptm) {
312 if (include_date)
314
317 }
318 }
319
321 AVBPrint part[5],
int *print_prefix,
int type[2])
322 {
329
331 if (*print_prefix && avc) {
335 if (parent && *parent) {
339 }
340 }
344 }
345
348
351
353
354 if(*part[0].str || *part[1].str || *part[2].str || *part[3].str) {
355 char lastc = part[3].len && part[3].len <= part[3].size ? part[3].str[part[3].len - 1] : 0;
356 *print_prefix = lastc == '\n' || lastc == '\r';
357 }
358 }
359
361 char *
line,
int line_size,
int *print_prefix)
362 {
364 }
365
367 char *
line,
int line_size,
int *print_prefix)
368 {
369 AVBPrint part[5];
371
373 ret =
snprintf(
line, line_size,
"%s%s%s%s", part[0].str, part[1].str, part[2].str, part[3].str);
376 }
377
379 {
380 static int print_prefix = 1;
381 static int count;
383 AVBPrint part[5];
385 static int is_atty;
387 unsigned tint = 0;
388
390 tint =
level & 0xff00;
392 }
393
395 return;
397
399 snprintf(
line,
sizeof(
line),
"%s%s%s%s", part[0].str, part[1].str, part[2].str, part[3].str);
400
401 #if HAVE_ISATTY
402 if (!is_atty)
403 is_atty =
isatty(2) ? 1 : -1;
404 #endif
405
408 count++;
409 if (is_atty == 1)
410 fprintf(stderr, " Last message repeated %d times\r", count);
411 goto end;
412 }
413 if (count > 0) {
414 fprintf(stderr, " Last message repeated %d times\n", count);
415 count = 0;
416 }
418
429
430 #if CONFIG_VALGRIND_BACKTRACE
431 if (
level <= BACKTRACE_LOGLEVEL)
432 VALGRIND_PRINTF_BACKTRACE("%s", "");
433 #endif
434 end:
437 }
438
441
443 {
444 va_list vl;
445 va_start(vl, fmt);
447 va_end(vl);
448 }
449
450 void av_log_once(
void* avcl,
int initial_level,
int subsequent_level,
int *
state,
const char *fmt, ...)
451 {
452 va_list vl;
453 va_start(vl, fmt);
454 av_vlog(avcl, *
state ? subsequent_level : initial_level, fmt, vl);
455 va_end(vl);
457 }
458
460 {
463 if (avc && avc->
version >= (50 << 16 | 15 << 8 | 2) &&
468 }
469
471 {
473 }
474
476 {
478 }
479
481 {
483 }
484
486 {
488 }
489
491 {
493 }
494
496 va_list argument_list)
497 {
500 "version to the newest one from Git. If the problem still "
501 "occurs, it means that your file has a feature which has not "
502 "been implemented.\n");
505 "of this file to https://streams.videolan.org/upload/ "
506 "and contact the ffmpeg-devel mailing list. (ffmpeg-devel@ffmpeg.org)\n");
507 }
508
510 {
511 va_list argument_list;
512
513 va_start(argument_list, msg);
515 va_end(argument_list);
516 }
517
519 {
520 va_list argument_list;
521
522 va_start(argument_list, msg);
524 va_end(argument_list);
525 }