FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavutil/log.c
Date: 2025-03-08 20:38:41
Exec Total Coverage
Lines: 144 207 69.6%
Functions: 19 25 76.0%
Branches: 101 148 68.2%

Line Branch Exec Source
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>
40 #include "bprint.h"
41 #include "common.h"
42 #include "internal.h"
43 #include "log.h"
44 #include "thread.h"
45 #include "time.h"
46 #include "time_internal.h"
47
48 static AVMutex mutex = AV_MUTEX_INITIALIZER;
49
50 #define LINE_SZ 1024
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
58 static int av_log_level = AV_LOG_INFO;
59 static int flags;
60
61 #define NB_LEVELS 8
62 #if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE && HAVE_GETSTDHANDLE
63 #include <windows.h>
64 static const uint8_t color[16 + AV_CLASS_CATEGORY_NB] = {
65 [AV_LOG_PANIC /8] = 12,
66 [AV_LOG_FATAL /8] = 12,
67 [AV_LOG_ERROR /8] = 12,
68 [AV_LOG_WARNING/8] = 14,
69 [AV_LOG_INFO /8] = 7,
70 [AV_LOG_VERBOSE/8] = 10,
71 [AV_LOG_DEBUG /8] = 10,
72 [AV_LOG_TRACE /8] = 8,
73 [16+AV_CLASS_CATEGORY_NA ] = 7,
74 [16+AV_CLASS_CATEGORY_INPUT ] = 13,
75 [16+AV_CLASS_CATEGORY_OUTPUT ] = 5,
76 [16+AV_CLASS_CATEGORY_MUXER ] = 13,
77 [16+AV_CLASS_CATEGORY_DEMUXER ] = 5,
78 [16+AV_CLASS_CATEGORY_ENCODER ] = 11,
79 [16+AV_CLASS_CATEGORY_DECODER ] = 3,
80 [16+AV_CLASS_CATEGORY_FILTER ] = 10,
81 [16+AV_CLASS_CATEGORY_BITSTREAM_FILTER] = 9,
82 [16+AV_CLASS_CATEGORY_SWSCALER ] = 7,
83 [16+AV_CLASS_CATEGORY_SWRESAMPLER ] = 7,
84 [16+AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT ] = 13,
85 [16+AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT ] = 5,
86 [16+AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT ] = 13,
87 [16+AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT ] = 5,
88 [16+AV_CLASS_CATEGORY_DEVICE_OUTPUT ] = 13,
89 [16+AV_CLASS_CATEGORY_DEVICE_INPUT ] = 5,
90 };
91
92 static int16_t background, attr_orig;
93 static HANDLE con;
94 #else
95
96 static const uint32_t color[16 + AV_CLASS_CATEGORY_NB] = {
97 [AV_LOG_PANIC /8] = 52 << 16 | 196 << 8 | 0x41,
98 [AV_LOG_FATAL /8] = 208 << 8 | 0x41,
99 [AV_LOG_ERROR /8] = 196 << 8 | 0x11,
100 [AV_LOG_WARNING/8] = 226 << 8 | 0x03,
101 [AV_LOG_INFO /8] = 253 << 8 | 0x09,
102 [AV_LOG_VERBOSE/8] = 40 << 8 | 0x02,
103 [AV_LOG_DEBUG /8] = 34 << 8 | 0x02,
104 [AV_LOG_TRACE /8] = 34 << 8 | 0x07,
105 [16+AV_CLASS_CATEGORY_NA ] = 250 << 8 | 0x09,
106 [16+AV_CLASS_CATEGORY_INPUT ] = 219 << 8 | 0x15,
107 [16+AV_CLASS_CATEGORY_OUTPUT ] = 201 << 8 | 0x05,
108 [16+AV_CLASS_CATEGORY_MUXER ] = 213 << 8 | 0x15,
109 [16+AV_CLASS_CATEGORY_DEMUXER ] = 207 << 8 | 0x05,
110 [16+AV_CLASS_CATEGORY_ENCODER ] = 51 << 8 | 0x16,
111 [16+AV_CLASS_CATEGORY_DECODER ] = 39 << 8 | 0x06,
112 [16+AV_CLASS_CATEGORY_FILTER ] = 155 << 8 | 0x12,
113 [16+AV_CLASS_CATEGORY_BITSTREAM_FILTER] = 192 << 8 | 0x14,
114 [16+AV_CLASS_CATEGORY_SWSCALER ] = 153 << 8 | 0x14,
115 [16+AV_CLASS_CATEGORY_SWRESAMPLER ] = 147 << 8 | 0x14,
116 [16+AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT ] = 213 << 8 | 0x15,
117 [16+AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT ] = 207 << 8 | 0x05,
118 [16+AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT ] = 213 << 8 | 0x15,
119 [16+AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT ] = 207 << 8 | 0x05,
120 [16+AV_CLASS_CATEGORY_DEVICE_OUTPUT ] = 213 << 8 | 0x15,
121 [16+AV_CLASS_CATEGORY_DEVICE_INPUT ] = 207 << 8 | 0x05,
122 };
123
124 #endif
125 static int use_color = -1;
126
127 #if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE && HAVE_GETSTDHANDLE
128 static void win_console_puts(const char *str)
129 {
130 const uint8_t *q = str;
131 uint16_t line[LINE_SZ];
132
133 while (*q) {
134 uint16_t *buf = line;
135 DWORD nb_chars = 0;
136 DWORD written;
137
138 while (*q && nb_chars < LINE_SZ - 1) {
139 uint32_t ch;
140 uint16_t tmp;
141
142 GET_UTF8(ch, *q ? *q++ : 0, ch = 0xfffd; goto continue_on_invalid;)
143 continue_on_invalid:
144 PUT_UTF16(ch, tmp, *buf++ = tmp; nb_chars++;)
145 }
146
147 WriteConsoleW(con, line, nb_chars, &written, NULL);
148 }
149 }
150 #endif
151
152 8161 static void check_color_terminal(void)
153 {
154 8161 char *term = getenv("TERM");
155
156 #if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE && HAVE_GETSTDHANDLE
157 CONSOLE_SCREEN_BUFFER_INFO con_info;
158 DWORD dummy;
159 con = GetStdHandle(STD_ERROR_HANDLE);
160 if (con != INVALID_HANDLE_VALUE && !GetConsoleMode(con, &dummy))
161 con = INVALID_HANDLE_VALUE;
162 if (con != INVALID_HANDLE_VALUE) {
163 GetConsoleScreenBufferInfo(con, &con_info);
164 attr_orig = con_info.wAttributes;
165 background = attr_orig & 0xF0;
166 }
167 #endif
168
169
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8161 times.
8161 if (getenv("AV_LOG_FORCE_NOCOLOR")) {
170 use_color = 0;
171
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8161 times.
8161 } else if (getenv("AV_LOG_FORCE_COLOR")) {
172 use_color = 1;
173 } else {
174 #if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE && HAVE_GETSTDHANDLE
175 use_color = (con != INVALID_HANDLE_VALUE);
176 #elif HAVE_ISATTY
177
2/4
✓ Branch 0 taken 8161 times.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 8161 times.
8161 use_color = (term && isatty(2));
178 #else
179 use_color = 0;
180 #endif
181 }
182
183
3/6
✓ Branch 1 taken 8161 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8161 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 8161 times.
✗ Branch 6 not taken.
8161 if (getenv("AV_LOG_FORCE_256COLOR") || term && strstr(term, "256color"))
184 8161 use_color *= 256;
185 8161 }
186
187 441614 static void ansi_fputs(int level, int tint, const char *str, int local_use_color)
188 {
189
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 441614 times.
441614 if (local_use_color == 1) {
190 fprintf(stderr,
191 "\033[%"PRIu32";3%"PRIu32"m%s\033[0m",
192 (color[level] >> 4) & 15,
193 color[level] & 15,
194 str);
195
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 441614 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
441614 } else if (tint && use_color == 256) {
196 fprintf(stderr,
197 "\033[48;5;%"PRIu32"m\033[38;5;%dm%s\033[0m",
198 (color[level] >> 16) & 0xff,
199 tint,
200 str);
201
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 441614 times.
441614 } else if (local_use_color == 256) {
202 fprintf(stderr,
203 "\033[48;5;%"PRIu32"m\033[38;5;%"PRIu32"m%s\033[0m",
204 (color[level] >> 16) & 0xff,
205 (color[level] >> 8) & 0xff,
206 str);
207 } else
208 441614 fputs(str, stderr);
209 441614 }
210
211 2184670 static void colored_fputs(int level, int tint, const char *str)
212 {
213 int local_use_color;
214
2/2
✓ Branch 0 taken 1743056 times.
✓ Branch 1 taken 441614 times.
2184670 if (!*str)
215 1743056 return;
216
217
2/2
✓ Branch 0 taken 8161 times.
✓ Branch 1 taken 433453 times.
441614 if (use_color < 0)
218 8161 check_color_terminal();
219
220
2/2
✓ Branch 0 taken 409250 times.
✓ Branch 1 taken 32364 times.
441614 if (level == AV_LOG_INFO/8) local_use_color = 0;
221 32364 else local_use_color = use_color;
222
223 #if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE && HAVE_GETSTDHANDLE
224 if (con != INVALID_HANDLE_VALUE) {
225 if (local_use_color)
226 SetConsoleTextAttribute(con, background | color[level]);
227 win_console_puts(str);
228 if (local_use_color)
229 SetConsoleTextAttribute(con, attr_orig);
230 } else {
231 ansi_fputs(level, tint, str, local_use_color);
232 }
233 #else
234 441614 ansi_fputs(level, tint, str, local_use_color);
235 #endif
236
237 }
238
239 2229 const char *av_default_item_name(void *ptr)
240 {
241 2229 return (*(AVClass **) ptr)->class_name;
242 }
243
244 AVClassCategory av_default_get_category(void *ptr)
245 {
246 return (*(AVClass **) ptr)->category;
247 }
248
249 2184670 static void sanitize(uint8_t *line){
250
2/2
✓ Branch 0 taken 13954661 times.
✓ Branch 1 taken 2184670 times.
16139331 while(*line){
251
5/6
✓ Branch 0 taken 13954661 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13747251 times.
✓ Branch 3 taken 207410 times.
✓ Branch 4 taken 14 times.
✓ Branch 5 taken 13747237 times.
13954661 if(*line < 0x08 || (*line > 0x0D && *line < 0x20))
252 14 *line='?';
253 13954661 line++;
254 }
255 2184670 }
256
257 23022 static int get_category(void *ptr){
258 23022 AVClass *avc = *(AVClass **) ptr;
259
1/2
✓ Branch 0 taken 23022 times.
✗ Branch 1 not taken.
23022 if( !avc
260
1/2
✓ Branch 0 taken 23022 times.
✗ Branch 1 not taken.
23022 || (avc->version&0xFF)<100
261
1/2
✓ Branch 0 taken 23022 times.
✗ Branch 1 not taken.
23022 || avc->version < (51 << 16 | 59 << 8)
262
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23022 times.
23022 || avc->category >= AV_CLASS_CATEGORY_NB) return AV_CLASS_CATEGORY_NA + 16;
263
264
2/2
✓ Branch 0 taken 6029 times.
✓ Branch 1 taken 16993 times.
23022 if(avc->get_category)
265 6029 return avc->get_category(ptr) + 16;
266
267 16993 return avc->category + 16;
268 }
269
270 static const char *get_level_str(int level)
271 {
272 switch (level) {
273 case AV_LOG_QUIET:
274 return "quiet";
275 case AV_LOG_DEBUG:
276 return "debug";
277 case AV_LOG_TRACE:
278 return "trace";
279 case AV_LOG_VERBOSE:
280 return "verbose";
281 case AV_LOG_INFO:
282 return "info";
283 case AV_LOG_WARNING:
284 return "warning";
285 case AV_LOG_ERROR:
286 return "error";
287 case AV_LOG_FATAL:
288 return "fatal";
289 case AV_LOG_PANIC:
290 return "panic";
291 default:
292 return "";
293 }
294 }
295
296 23022 static const char *item_name(void *obj, const AVClass *cls)
297 {
298
1/2
✓ Branch 0 taken 23022 times.
✗ Branch 1 not taken.
23022 return (cls->item_name ? cls->item_name : av_default_item_name)(obj);
299 }
300
301 static void format_date_now(AVBPrint* bp_time, int include_date)
302 {
303 struct tm *ptm, tmbuf;
304 const int64_t time_us = av_gettime();
305 const int64_t time_ms = time_us / 1000;
306 const time_t time_s = time_ms / 1000;
307 const int millisec = time_ms - (time_s * 1000);
308 ptm = localtime_r(&time_s, &tmbuf);
309 if (ptm) {
310 if (include_date)
311 av_bprint_strftime(bp_time, "%Y-%m-%d ", ptm);
312
313 av_bprint_strftime(bp_time, "%H:%M:%S", ptm);
314 av_bprintf(bp_time, ".%03d ", millisec);
315 }
316 }
317
318 439031 static void format_line(void *avcl, int level, const char *fmt, va_list vl,
319 AVBPrint part[5], int *print_prefix, int type[2])
320 {
321
2/2
✓ Branch 0 taken 22258 times.
✓ Branch 1 taken 416773 times.
439031 AVClass* avc = avcl ? *(AVClass **) avcl : NULL;
322 439031 av_bprint_init(part+0, 0, AV_BPRINT_SIZE_AUTOMATIC);
323 439031 av_bprint_init(part+1, 0, AV_BPRINT_SIZE_AUTOMATIC);
324 439031 av_bprint_init(part+2, 0, AV_BPRINT_SIZE_AUTOMATIC);
325 439031 av_bprint_init(part+3, 0, 65536);
326 439031 av_bprint_init(part+4, 0, AV_BPRINT_SIZE_AUTOMATIC);
327
328
1/2
✓ Branch 0 taken 439031 times.
✗ Branch 1 not taken.
439031 if(type) type[0] = type[1] = AV_CLASS_CATEGORY_NA + 16;
329
4/4
✓ Branch 0 taken 224858 times.
✓ Branch 1 taken 214173 times.
✓ Branch 2 taken 22144 times.
✓ Branch 3 taken 202714 times.
439031 if (*print_prefix && avc) {
330
2/2
✓ Branch 0 taken 3345 times.
✓ Branch 1 taken 18799 times.
22144 if (avc->parent_log_context_offset) {
331 3345 AVClass** parent = *(AVClass ***) (((uint8_t *) avcl) +
332 3345 avc->parent_log_context_offset);
333
3/4
✓ Branch 0 taken 878 times.
✓ Branch 1 taken 2467 times.
✓ Branch 2 taken 878 times.
✗ Branch 3 not taken.
3345 if (parent && *parent) {
334 878 av_bprintf(part+0, "[%s @ %p] ",
335 item_name(parent, *parent), parent);
336
1/2
✓ Branch 0 taken 878 times.
✗ Branch 1 not taken.
878 if(type) type[0] = get_category(parent);
337 }
338 }
339 22144 av_bprintf(part+1, "[%s @ %p] ",
340 item_name(avcl, avc), avcl);
341
1/2
✓ Branch 0 taken 22144 times.
✗ Branch 1 not taken.
22144 if(type) type[1] = get_category(avcl);
342 }
343
344
5/6
✓ Branch 0 taken 224858 times.
✓ Branch 1 taken 214173 times.
✓ Branch 2 taken 209009 times.
✓ Branch 3 taken 15849 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 209009 times.
439031 if (*print_prefix && (level > AV_LOG_QUIET) && (flags & (AV_LOG_PRINT_TIME | AV_LOG_PRINT_DATETIME)))
345 format_date_now(&part[4], flags & AV_LOG_PRINT_DATETIME);
346
347
5/6
✓ Branch 0 taken 224858 times.
✓ Branch 1 taken 214173 times.
✓ Branch 2 taken 209009 times.
✓ Branch 3 taken 15849 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 209009 times.
439031 if (*print_prefix && (level > AV_LOG_QUIET) && (flags & AV_LOG_PRINT_LEVEL))
348 av_bprintf(part+2, "[%s] ", get_level_str(level));
349
350 439031 av_vbprintf(part+3, fmt, vl);
351
352
7/8
✓ Branch 0 taken 438153 times.
✓ Branch 1 taken 878 times.
✓ Branch 2 taken 416887 times.
✓ Branch 3 taken 21266 times.
✓ Branch 4 taken 416887 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 400736 times.
✓ Branch 7 taken 16151 times.
439031 if(*part[0].str || *part[1].str || *part[2].str || *part[3].str) {
353
2/4
✓ Branch 0 taken 422880 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 422880 times.
✗ Branch 3 not taken.
422880 char lastc = part[3].len && part[3].len <= part[3].size ? part[3].str[part[3].len - 1] : 0;
354
4/4
✓ Branch 0 taken 213897 times.
✓ Branch 1 taken 208983 times.
✓ Branch 2 taken 26 times.
✓ Branch 3 taken 213871 times.
422880 *print_prefix = lastc == '\n' || lastc == '\r';
355 }
356 439031 }
357
358 void av_log_format_line(void *ptr, int level, const char *fmt, va_list vl,
359 char *line, int line_size, int *print_prefix)
360 {
361 av_log_format_line2(ptr, level, fmt, vl, line, line_size, print_prefix);
362 }
363
364 int av_log_format_line2(void *ptr, int level, const char *fmt, va_list vl,
365 char *line, int line_size, int *print_prefix)
366 {
367 AVBPrint part[5];
368 int ret;
369
370 format_line(ptr, level, fmt, vl, part, print_prefix, NULL);
371 ret = snprintf(line, line_size, "%s%s%s%s", part[0].str, part[1].str, part[2].str, part[3].str);
372 av_bprint_finalize(part+3, NULL);
373 return ret;
374 }
375
376 16043515 void av_log_default_callback(void* ptr, int level, const char* fmt, va_list vl)
377 {
378 static int print_prefix = 1;
379 static int count;
380 static char prev[LINE_SZ];
381 AVBPrint part[5];
382 char line[LINE_SZ];
383 static int is_atty;
384 int type[2];
385 16043515 unsigned tint = 0;
386
387
2/2
✓ Branch 0 taken 16027666 times.
✓ Branch 1 taken 15849 times.
16043515 if (level >= 0) {
388 16027666 tint = level & 0xff00;
389 16027666 level &= 0xff;
390 }
391
392
2/2
✓ Branch 0 taken 15604484 times.
✓ Branch 1 taken 439031 times.
16043515 if (level > av_log_level)
393 15604484 return;
394 439031 ff_mutex_lock(&mutex);
395
396 439031 format_line(ptr, level, fmt, vl, part, &print_prefix, type);
397 439031 snprintf(line, sizeof(line), "%s%s%s%s", part[0].str, part[1].str, part[2].str, part[3].str);
398
399 #if HAVE_ISATTY
400
2/2
✓ Branch 0 taken 8161 times.
✓ Branch 1 taken 430870 times.
439031 if (!is_atty)
401
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8161 times.
8161 is_atty = isatty(2) ? 1 : -1;
402 #endif
403
404
6/6
✓ Branch 0 taken 224858 times.
✓ Branch 1 taken 214173 times.
✓ Branch 2 taken 222026 times.
✓ Branch 3 taken 2832 times.
✓ Branch 4 taken 2097 times.
✓ Branch 5 taken 219929 times.
439031 if (print_prefix && (flags & AV_LOG_SKIP_REPEATED) && !strcmp(line, prev) &&
405
2/4
✓ Branch 0 taken 2097 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2097 times.
✗ Branch 3 not taken.
2097 *line && line[strlen(line) - 1] != '\r'){
406 2097 count++;
407
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2097 times.
2097 if (is_atty == 1)
408 fprintf(stderr, " Last message repeated %d times\r", count);
409 2097 goto end;
410 }
411
2/2
✓ Branch 0 taken 381 times.
✓ Branch 1 taken 436553 times.
436934 if (count > 0) {
412 381 fprintf(stderr, " Last message repeated %d times\n", count);
413 381 count = 0;
414 }
415 436934 strcpy(prev, line);
416
417 436934 sanitize(part[4].str);
418 436934 colored_fputs(7, 0, part[4].str);
419 436934 sanitize(part[0].str);
420 436934 colored_fputs(type[0], 0, part[0].str);
421 436934 sanitize(part[1].str);
422 436934 colored_fputs(type[1], 0, part[1].str);
423 436934 sanitize(part[2].str);
424 436934 colored_fputs(av_clip(level >> 3, 0, NB_LEVELS - 1), tint >> 8, part[2].str);
425 436934 sanitize(part[3].str);
426 436934 colored_fputs(av_clip(level >> 3, 0, NB_LEVELS - 1), tint >> 8, part[3].str);
427
428 #if CONFIG_VALGRIND_BACKTRACE
429
2/2
✓ Branch 0 taken 416887 times.
✓ Branch 1 taken 20047 times.
436934 if (level <= BACKTRACE_LOGLEVEL)
430 20047 VALGRIND_PRINTF_BACKTRACE("%s", "");
431 #endif
432 416887 end:
433 439031 av_bprint_finalize(part+3, NULL);
434 439031 ff_mutex_unlock(&mutex);
435 }
436
437 static void (*av_log_callback)(void*, int, const char*, va_list) =
438 av_log_default_callback;
439
440 16043843 void av_log(void* avcl, int level, const char *fmt, ...)
441 {
442 va_list vl;
443 16043843 va_start(vl, fmt);
444 16043843 av_vlog(avcl, level, fmt, vl);
445 16043843 va_end(vl);
446 16043843 }
447
448 39 void av_log_once(void* avcl, int initial_level, int subsequent_level, int *state, const char *fmt, ...)
449 {
450 va_list vl;
451 39 va_start(vl, fmt);
452
2/2
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 5 times.
39 av_vlog(avcl, *state ? subsequent_level : initial_level, fmt, vl);
453 39 va_end(vl);
454 39 *state = 1;
455 39 }
456
457 16044036 void av_vlog(void* avcl, int level, const char *fmt, va_list vl)
458 {
459
2/2
✓ Branch 0 taken 14871585 times.
✓ Branch 1 taken 1172451 times.
16044036 AVClass* avc = avcl ? *(AVClass **) avcl : NULL;
460 16044036 void (*log_callback)(void*, int, const char*, va_list) = av_log_callback;
461
4/4
✓ Branch 0 taken 14871585 times.
✓ Branch 1 taken 1172451 times.
✓ Branch 2 taken 14871545 times.
✓ Branch 3 taken 40 times.
16044036 if (avc && avc->version >= (50 << 16 | 15 << 8 | 2) &&
462
3/4
✓ Branch 0 taken 405074 times.
✓ Branch 1 taken 14466471 times.
✓ Branch 2 taken 405074 times.
✗ Branch 3 not taken.
14871545 avc->log_level_offset_offset && level >= AV_LOG_FATAL)
463 405074 level += *(int *) (((uint8_t *) avcl) + avc->log_level_offset_offset);
464
2/2
✓ Branch 0 taken 16044033 times.
✓ Branch 1 taken 3 times.
16044036 if (log_callback)
465 16044033 log_callback(avcl, level, fmt, vl);
466 16044036 }
467
468 56968 int av_log_get_level(void)
469 {
470 56968 return av_log_level;
471 }
472
473 3752 void av_log_set_level(int level)
474 {
475 3752 av_log_level = level;
476 3752 }
477
478 8112 void av_log_set_flags(int arg)
479 {
480 8112 flags = arg;
481 8112 }
482
483 64 int av_log_get_flags(void)
484 {
485 64 return flags;
486 }
487
488 86 void av_log_set_callback(void (*callback)(void*, int, const char*, va_list))
489 {
490 86 av_log_callback = callback;
491 86 }
492
493 14 static void missing_feature_sample(int sample, void *avc, const char *msg,
494 va_list argument_list)
495 {
496 14 av_vlog(avc, AV_LOG_WARNING, msg, argument_list);
497 14 av_log(avc, AV_LOG_WARNING, " is not implemented. Update your FFmpeg "
498 "version to the newest one from Git. If the problem still "
499 "occurs, it means that your file has a feature which has not "
500 "been implemented.\n");
501
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (sample)
502 av_log(avc, AV_LOG_WARNING, "If you want to help, upload a sample "
503 "of this file to https://streams.videolan.org/upload/ "
504 "and contact the ffmpeg-devel mailing list. (ffmpeg-devel@ffmpeg.org)\n");
505 14 }
506
507 void avpriv_request_sample(void *avc, const char *msg, ...)
508 {
509 va_list argument_list;
510
511 va_start(argument_list, msg);
512 missing_feature_sample(1, avc, msg, argument_list);
513 va_end(argument_list);
514 }
515
516 14 void avpriv_report_missing_feature(void *avc, const char *msg, ...)
517 {
518 va_list argument_list;
519
520 14 va_start(argument_list, msg);
521 14 missing_feature_sample(0, avc, msg, argument_list);
522 14 va_end(argument_list);
523 14 }
524