Commit | Line | Data |
---|---|---|
4b45de0e LA |
1 | /* |
2 | * log functions | |
3 | * Copyright (c) 2003 Michel Bardiaux | |
4 | * | |
2912e87a | 5 | * This file is part of Libav. |
b78e7197 | 6 | * |
2912e87a | 7 | * Libav is free software; you can redistribute it and/or |
4b45de0e LA |
8 | * modify it under the terms of the GNU Lesser General Public |
9 | * License as published by the Free Software Foundation; either | |
b78e7197 | 10 | * version 2.1 of the License, or (at your option) any later version. |
4b45de0e | 11 | * |
2912e87a | 12 | * Libav is distributed in the hope that it will be useful, |
4b45de0e LA |
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 | |
2912e87a | 18 | * License along with Libav; if not, write to the Free Software |
4b45de0e LA |
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
20 | */ | |
21 | ||
22 | /** | |
ba87f080 | 23 | * @file |
7d685b48 | 24 | * logging functions |
4b45de0e LA |
25 | */ |
26 | ||
51e026d1 | 27 | #include <unistd.h> |
62044024 | 28 | #include <stdlib.h> |
4b45de0e | 29 | #include "avutil.h" |
77652a6a | 30 | #include "log.h" |
4b45de0e | 31 | |
490a022d | 32 | static int av_log_level = AV_LOG_INFO; |
1c1c80f0 | 33 | static int flags; |
4b45de0e | 34 | |
3c467bac | 35 | #if defined(_WIN32) && !defined(__MINGW32CE__) |
4855f867 RP |
36 | #include <windows.h> |
37 | static const uint8_t color[] = {12,12,12,14,7,7,7}; | |
38 | static int16_t background, attr_orig; | |
39 | static HANDLE con; | |
db16e3ca | 40 | #define set_color(x) SetConsoleTextAttribute(con, background | color[x]) |
4855f867 RP |
41 | #define reset_color() SetConsoleTextAttribute(con, attr_orig) |
42 | #else | |
6e34a558 | 43 | static const uint8_t color[]={0x41,0x41,0x11,0x03,9,9,9}; |
4855f867 RP |
44 | #define set_color(x) fprintf(stderr, "\033[%d;3%dm", color[x]>>4, color[x]&15) |
45 | #define reset_color() fprintf(stderr, "\033[0m") | |
46 | #endif | |
a1c027e9 | 47 | static int use_color=-1; |
51e026d1 MN |
48 | |
49 | #undef fprintf | |
6e34a558 | 50 | static void colored_fputs(int level, const char *str){ |
a1c027e9 | 51 | if(use_color<0){ |
3c467bac | 52 | #if defined(_WIN32) && !defined(__MINGW32CE__) |
4855f867 RP |
53 | CONSOLE_SCREEN_BUFFER_INFO con_info; |
54 | con = GetStdHandle(STD_ERROR_HANDLE); | |
dfaa9f3c | 55 | use_color = (con != INVALID_HANDLE_VALUE) && !getenv("NO_COLOR") && !getenv("FFMPEG_FORCE_NOCOLOR"); |
4855f867 RP |
56 | if (use_color) { |
57 | GetConsoleScreenBufferInfo(con, &con_info); | |
58 | attr_orig = con_info.wAttributes; | |
59 | background = attr_orig & 0xF0; | |
60 | } | |
61 | #elif HAVE_ISATTY | |
3011ecde SS |
62 | use_color= !getenv("NO_COLOR") && !getenv("FFMPEG_FORCE_NOCOLOR") && |
63 | (getenv("TERM") && isatty(2) || getenv("FFMPEG_FORCE_COLOR")); | |
62044024 | 64 | #else |
3011ecde | 65 | use_color= getenv("FFMPEG_FORCE_COLOR") && !getenv("NO_COLOR") && !getenv("FFMPEG_FORCE_NOCOLOR"); |
62044024 MN |
66 | #endif |
67 | } | |
68 | ||
a1c027e9 | 69 | if(use_color){ |
4855f867 | 70 | set_color(level); |
51e026d1 MN |
71 | } |
72 | fputs(str, stderr); | |
a1c027e9 | 73 | if(use_color){ |
4855f867 | 74 | reset_color(); |
51e026d1 MN |
75 | } |
76 | } | |
77 | ||
8d2a5139 MN |
78 | const char* av_default_item_name(void* ptr){ |
79 | return (*(AVClass**)ptr)->class_name; | |
80 | } | |
81 | ||
411983c1 | 82 | void av_log_default_callback(void* ptr, int level, const char* fmt, va_list vl) |
4b45de0e LA |
83 | { |
84 | static int print_prefix=1; | |
b9c353ff | 85 | static int count; |
0247bdee RT |
86 | static char prev[1024]; |
87 | char line[1024]; | |
8a190533 | 88 | static int is_atty; |
4b45de0e LA |
89 | AVClass* avc= ptr ? *(AVClass**)ptr : NULL; |
90 | if(level>av_log_level) | |
91 | return; | |
4880cfd9 | 92 | line[0]=0; |
4b45de0e LA |
93 | #undef fprintf |
94 | if(print_prefix && avc) { | |
63de9e7d | 95 | if (avc->parent_log_context_offset) { |
4880cfd9 MN |
96 | AVClass** parent= *(AVClass***)(((uint8_t*)ptr) + avc->parent_log_context_offset); |
97 | if(parent && *parent){ | |
50061b62 | 98 | snprintf(line, sizeof(line), "[%s @ %p] ", (*parent)->item_name(parent), parent); |
4880cfd9 MN |
99 | } |
100 | } | |
50061b62 | 101 | snprintf(line + strlen(line), sizeof(line) - strlen(line), "[%s @ %p] ", avc->item_name(ptr), ptr); |
4880cfd9 | 102 | } |
4b45de0e | 103 | |
b9c353ff | 104 | vsnprintf(line + strlen(line), sizeof(line) - strlen(line), fmt, vl); |
4b45de0e | 105 | |
b9c353ff | 106 | print_prefix= line[strlen(line)-1] == '\n'; |
c157fe63 MN |
107 | |
108 | #if HAVE_ISATTY | |
8a190533 | 109 | if(!is_atty) is_atty= isatty(2) ? 1 : -1; |
c157fe63 MN |
110 | #endif |
111 | ||
0247bdee | 112 | if(print_prefix && (flags & AV_LOG_SKIP_REPEATED) && !strncmp(line, prev, sizeof line)){ |
b9c353ff | 113 | count++; |
8a190533 | 114 | if(is_atty==1) |
d7cd001f | 115 | fprintf(stderr, " Last message repeated %d times\r", count); |
b9c353ff MN |
116 | return; |
117 | } | |
118 | if(count>0){ | |
119 | fprintf(stderr, " Last message repeated %d times\n", count); | |
120 | count=0; | |
121 | } | |
6e34a558 | 122 | colored_fputs(av_clip(level>>3, 0, 6), line); |
0247bdee | 123 | strncpy(prev, line, sizeof line); |
4b45de0e LA |
124 | } |
125 | ||
126 | static void (*av_log_callback)(void*, int, const char*, va_list) = av_log_default_callback; | |
127 | ||
128 | void av_log(void* avcl, int level, const char *fmt, ...) | |
129 | { | |
3fe1ec39 | 130 | AVClass* avc= avcl ? *(AVClass**)avcl : NULL; |
4b45de0e LA |
131 | va_list vl; |
132 | va_start(vl, fmt); | |
3fe1ec39 MN |
133 | if(avc && avc->version >= (50<<16 | 15<<8 | 2) && avc->log_level_offset_offset && level>=AV_LOG_FATAL) |
134 | level += *(int*)(((uint8_t*)avcl) + avc->log_level_offset_offset); | |
4b45de0e LA |
135 | av_vlog(avcl, level, fmt, vl); |
136 | va_end(vl); | |
137 | } | |
138 | ||
139 | void av_vlog(void* avcl, int level, const char *fmt, va_list vl) | |
140 | { | |
141 | av_log_callback(avcl, level, fmt, vl); | |
142 | } | |
143 | ||
144 | int av_log_get_level(void) | |
145 | { | |
146 | return av_log_level; | |
147 | } | |
148 | ||
149 | void av_log_set_level(int level) | |
150 | { | |
151 | av_log_level = level; | |
152 | } | |
153 | ||
1c1c80f0 MN |
154 | void av_log_set_flags(int arg) |
155 | { | |
156 | flags= arg; | |
157 | } | |
158 | ||
4b45de0e LA |
159 | void av_log_set_callback(void (*callback)(void*, int, const char*, va_list)) |
160 | { | |
161 | av_log_callback = callback; | |
162 | } |