00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00027 #include <unistd.h>
00028 #include <stdlib.h>
00029 #include "avutil.h"
00030 #include "log.h"
00031
00032 static int av_log_level = AV_LOG_INFO;
00033 static int flags;
00034
00035 #if defined(_WIN32) && !defined(__MINGW32CE__)
00036 #include <windows.h>
00037 static const uint8_t color[] = {12,12,12,14,7,7,7};
00038 static int16_t background, attr_orig;
00039 static HANDLE con;
00040 #define set_color(x) SetConsoleTextAttribute(con, background | color[x])
00041 #define reset_color() SetConsoleTextAttribute(con, attr_orig)
00042 #else
00043 static const uint8_t color[]={0x41,0x41,0x11,0x03,9,9,9};
00044 #define set_color(x) fprintf(stderr, "\033[%d;3%dm", color[x]>>4, color[x]&15)
00045 #define reset_color() fprintf(stderr, "\033[0m")
00046 #endif
00047 static int use_color=-1;
00048
00049 #undef fprintf
00050 static void colored_fputs(int level, const char *str){
00051 if(use_color<0){
00052 #if defined(_WIN32) && !defined(__MINGW32CE__)
00053 CONSOLE_SCREEN_BUFFER_INFO con_info;
00054 con = GetStdHandle(STD_ERROR_HANDLE);
00055 use_color = (con != INVALID_HANDLE_VALUE) && !getenv("NO_COLOR") && !getenv("FFMPEG_FORCE_NOCOLOR");
00056 if (use_color) {
00057 GetConsoleScreenBufferInfo(con, &con_info);
00058 attr_orig = con_info.wAttributes;
00059 background = attr_orig & 0xF0;
00060 }
00061 #elif HAVE_ISATTY
00062 use_color= !getenv("NO_COLOR") && !getenv("FFMPEG_FORCE_NOCOLOR") &&
00063 (getenv("TERM") && isatty(2) || getenv("FFMPEG_FORCE_COLOR"));
00064 #else
00065 use_color= getenv("FFMPEG_FORCE_COLOR") && !getenv("NO_COLOR") && !getenv("FFMPEG_FORCE_NOCOLOR");
00066 #endif
00067 }
00068
00069 if(use_color){
00070 set_color(level);
00071 }
00072 fputs(str, stderr);
00073 if(use_color){
00074 reset_color();
00075 }
00076 }
00077
00078 const char* av_default_item_name(void* ptr){
00079 return (*(AVClass**)ptr)->class_name;
00080 }
00081
00082 static void sanitize(uint8_t *line){
00083 while(*line){
00084 if(*line < 0x08 || (*line > 0x0D && *line < 0x20))
00085 *line='?';
00086 line++;
00087 }
00088 }
00089
00090 void av_log_default_callback(void* ptr, int level, const char* fmt, va_list vl)
00091 {
00092 static int print_prefix=1;
00093 static int count;
00094 static char prev[1024];
00095 char line[1024];
00096 static int is_atty;
00097 AVClass* avc= ptr ? *(AVClass**)ptr : NULL;
00098 if(level>av_log_level)
00099 return;
00100 line[0]=0;
00101 #undef fprintf
00102 if(print_prefix && avc) {
00103 if (avc->parent_log_context_offset) {
00104 AVClass** parent= *(AVClass***)(((uint8_t*)ptr) + avc->parent_log_context_offset);
00105 if(parent && *parent){
00106 snprintf(line, sizeof(line), "[%s @ %p] ", (*parent)->item_name(parent), parent);
00107 }
00108 }
00109 snprintf(line + strlen(line), sizeof(line) - strlen(line), "[%s @ %p] ", avc->item_name(ptr), ptr);
00110 }
00111
00112 vsnprintf(line + strlen(line), sizeof(line) - strlen(line), fmt, vl);
00113
00114 print_prefix = strlen(line) && line[strlen(line)-1] == '\n';
00115
00116 #if HAVE_ISATTY
00117 if(!is_atty) is_atty= isatty(2) ? 1 : -1;
00118 #endif
00119
00120 if(print_prefix && (flags & AV_LOG_SKIP_REPEATED) && !strcmp(line, prev)){
00121 count++;
00122 if(is_atty==1)
00123 fprintf(stderr, " Last message repeated %d times\r", count);
00124 return;
00125 }
00126 if(count>0){
00127 fprintf(stderr, " Last message repeated %d times\n", count);
00128 count=0;
00129 }
00130 strcpy(prev, line);
00131 sanitize(line);
00132 colored_fputs(av_clip(level>>3, 0, 6), line);
00133 }
00134
00135 static void (*av_log_callback)(void*, int, const char*, va_list) = av_log_default_callback;
00136
00137 void av_log(void* avcl, int level, const char *fmt, ...)
00138 {
00139 AVClass* avc= avcl ? *(AVClass**)avcl : NULL;
00140 va_list vl;
00141 va_start(vl, fmt);
00142 if(avc && avc->version >= (50<<16 | 15<<8 | 2) && avc->log_level_offset_offset && level>=AV_LOG_FATAL)
00143 level += *(int*)(((uint8_t*)avcl) + avc->log_level_offset_offset);
00144 av_vlog(avcl, level, fmt, vl);
00145 va_end(vl);
00146 }
00147
00148 void av_vlog(void* avcl, int level, const char *fmt, va_list vl)
00149 {
00150 av_log_callback(avcl, level, fmt, vl);
00151 }
00152
00153 int av_log_get_level(void)
00154 {
00155 return av_log_level;
00156 }
00157
00158 void av_log_set_level(int level)
00159 {
00160 av_log_level = level;
00161 }
00162
00163 void av_log_set_flags(int arg)
00164 {
00165 flags= arg;
00166 }
00167
00168 void av_log_set_callback(void (*callback)(void*, int, const char*, va_list))
00169 {
00170 av_log_callback = callback;
00171 }