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>
45
47
49
50 #if HAVE_VALGRIND_VALGRIND_H && CONFIG_VALGRIND_BACKTRACE
51 #include <valgrind/valgrind.h>
52 /* this is the log level at which valgrind will output a full backtrace */
53 #define BACKTRACE_LOGLEVEL AV_LOG_ERROR
54 #endif
55
58
60 #if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE && HAVE_GETSTDHANDLE
61 #include <windows.h>
88 };
89
90 static int16_t background, attr_orig;
91 static HANDLE con;
92 #else
93
120 };
121
122 #endif
124
125 #if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE && HAVE_GETSTDHANDLE
126 static void win_console_puts(const char *str)
127 {
128 const uint8_t *q = str;
130
131 while (*q) {
132 uint16_t *buf =
line;
133 DWORD nb_chars = 0;
134 DWORD written;
135
136 while (*q && nb_chars <
LINE_SZ - 1) {
137 uint32_t ch;
139
140 GET_UTF8(ch, *q ? *q++ : 0, ch = 0xfffd;
goto continue_on_invalid;)
141 continue_on_invalid:
143 }
144
145 WriteConsoleW(con,
line, nb_chars, &written,
NULL);
146 }
147 }
148 #endif
149
151 {
152 char *term = getenv("TERM");
153
154 #if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE && HAVE_GETSTDHANDLE
155 CONSOLE_SCREEN_BUFFER_INFO con_info;
157 con = GetStdHandle(STD_ERROR_HANDLE);
158 if (con != INVALID_HANDLE_VALUE && !GetConsoleMode(con, &
dummy))
159 con = INVALID_HANDLE_VALUE;
160 if (con != INVALID_HANDLE_VALUE) {
161 GetConsoleScreenBufferInfo(con, &con_info);
162 attr_orig = con_info.wAttributes;
163 background = attr_orig & 0xF0;
164 }
165 #endif
166
167 if (getenv("AV_LOG_FORCE_NOCOLOR")) {
169 } else if (getenv("AV_LOG_FORCE_COLOR")) {
171 } else {
172 #if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE && HAVE_GETSTDHANDLE
173 use_color = (con != INVALID_HANDLE_VALUE);
174 #elif HAVE_ISATTY
176 #else
178 #endif
179 }
180
181 if (getenv("AV_LOG_FORCE_256COLOR") || term && strstr(term, "256color"))
183 }
184
186 {
187 if (local_use_color == 1) {
188 fprintf(stderr,
189 "033円[%"PRIu32";3%"PRIu32"m%s033円[0m",
192 str);
194 fprintf(stderr,
195 "033円[48;5;%"PRIu32"m033円[38;5;%dm%s033円[0m",
197 tint,
198 str);
199 } else if (local_use_color == 256) {
200 fprintf(stderr,
201 "033円[48;5;%"PRIu32"m033円[38;5;%"PRIu32"m%s033円[0m",
204 str);
205 } else
206 fputs(str, stderr);
207 }
208
210 {
211 int local_use_color;
212 if (!*str)
213 return;
214
217
220
221 #if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE && HAVE_GETSTDHANDLE
222 if (con != INVALID_HANDLE_VALUE) {
223 if (local_use_color)
224 SetConsoleTextAttribute(con, background |
color[
level]);
225 win_console_puts(str);
226 if (local_use_color)
227 SetConsoleTextAttribute(con, attr_orig);
228 } else {
230 }
231 #else
233 #endif
234
235 }
236
238 {
239 return (*(
AVClass **) ptr)->class_name;
240 }
241
243 {
244 return (*(
AVClass **) ptr)->category;
245 }
246
252 }
253 }
254
257 if( !avc
259 || avc->
version < (51 << 16 | 59 << 8)
261
264
266 }
267
269 {
272 return "quiet";
274 return "debug";
276 return "trace";
278 return "verbose";
280 return "info";
282 return "warning";
284 return "error";
286 return "fatal";
288 return "panic";
289 default:
290 return "";
291 }
292 }
293
295 {
297 }
298
300 AVBPrint part[4],
int *print_prefix,
int type[2])
301 {
307
309 if (*print_prefix && avc) {
313 if (parent && *parent) {
317 }
318 }
322 }
323
326
328
329 if(*part[0].str || *part[1].str || *part[2].str || *part[3].str) {
330 char lastc = part[3].len && part[3].len <= part[3].size ? part[3].str[part[3].len - 1] : 0;
331 *print_prefix = lastc == '\n' || lastc == '\r';
332 }
333 }
334
336 char *
line,
int line_size,
int *print_prefix)
337 {
339 }
340
342 char *
line,
int line_size,
int *print_prefix)
343 {
344 AVBPrint part[4];
346
348 ret =
snprintf(
line, line_size,
"%s%s%s%s", part[0].str, part[1].str, part[2].str, part[3].str);
351 }
352
354 {
355 static int print_prefix = 1;
356 static int count;
358 AVBPrint part[4];
360 static int is_atty;
362 unsigned tint = 0;
363
365 tint =
level & 0xff00;
367 }
368
370 return;
372
374 snprintf(
line,
sizeof(
line),
"%s%s%s%s", part[0].str, part[1].str, part[2].str, part[3].str);
375
376 #if HAVE_ISATTY
377 if (!is_atty)
378 is_atty =
isatty(2) ? 1 : -1;
379 #endif
380
383 count++;
384 if (is_atty == 1)
385 fprintf(stderr, " Last message repeated %d times\r", count);
386 goto end;
387 }
388 if (count > 0) {
389 fprintf(stderr, " Last message repeated %d times\n", count);
390 count = 0;
391 }
401
402 #if CONFIG_VALGRIND_BACKTRACE
403 if (
level <= BACKTRACE_LOGLEVEL)
404 VALGRIND_PRINTF_BACKTRACE("%s", "");
405 #endif
406 end:
409 }
410
413
415 {
416 va_list vl;
417 va_start(vl, fmt);
419 va_end(vl);
420 }
421
422 void av_log_once(
void* avcl,
int initial_level,
int subsequent_level,
int *
state,
const char *fmt, ...)
423 {
424 va_list vl;
425 va_start(vl, fmt);
426 av_vlog(avcl, *
state ? subsequent_level : initial_level, fmt, vl);
427 va_end(vl);
429 }
430
432 {
435 if (avc && avc->
version >= (50 << 16 | 15 << 8 | 2) &&
440 }
441
443 {
445 }
446
448 {
450 }
451
453 {
455 }
456
458 {
460 }
461
463 {
465 }
466
468 va_list argument_list)
469 {
472 "version to the newest one from Git. If the problem still "
473 "occurs, it means that your file has a feature which has not "
474 "been implemented.\n");
477 "of this file to https://streams.videolan.org/upload/ "
478 "and contact the ffmpeg-devel mailing list. (ffmpeg-devel@ffmpeg.org)\n");
479 }
480
482 {
483 va_list argument_list;
484
485 va_start(argument_list, msg);
487 va_end(argument_list);
488 }
489
491 {
492 va_list argument_list;
493
494 va_start(argument_list, msg);
496 va_end(argument_list);
497 }