LCOV - code coverage report
Current view: top level - src/libavutil - log.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 116 167 69.5 %
Date: 2017-01-21 09:32:20 Functions: 14 21 66.7 %

          Line data    Source code
       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 <stdarg.h>
      36             : #include <stdlib.h>
      37             : #include "avutil.h"
      38             : #include "bprint.h"
      39             : #include "common.h"
      40             : #include "internal.h"
      41             : #include "log.h"
      42             : 
      43             : #if HAVE_PTHREADS
      44             : #include <pthread.h>
      45             : static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
      46             : #endif
      47             : 
      48             : #define LINE_SZ 1024
      49             : 
      50             : #if HAVE_VALGRIND_VALGRIND_H
      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             : 
      56             : static int av_log_level = AV_LOG_INFO;
      57             : static int flags;
      58             : 
      59             : #define NB_LEVELS 8
      60             : #if defined(_WIN32) && !defined(__MINGW32CE__) && HAVE_SETCONSOLETEXTATTRIBUTE
      61             : #include <windows.h>
      62             : static const uint8_t color[16 + AV_CLASS_CATEGORY_NB] = {
      63             :     [AV_LOG_PANIC  /8] = 12,
      64             :     [AV_LOG_FATAL  /8] = 12,
      65             :     [AV_LOG_ERROR  /8] = 12,
      66             :     [AV_LOG_WARNING/8] = 14,
      67             :     [AV_LOG_INFO   /8] =  7,
      68             :     [AV_LOG_VERBOSE/8] = 10,
      69             :     [AV_LOG_DEBUG  /8] = 10,
      70             :     [AV_LOG_TRACE  /8] = 8,
      71             :     [16+AV_CLASS_CATEGORY_NA              ] =  7,
      72             :     [16+AV_CLASS_CATEGORY_INPUT           ] = 13,
      73             :     [16+AV_CLASS_CATEGORY_OUTPUT          ] =  5,
      74             :     [16+AV_CLASS_CATEGORY_MUXER           ] = 13,
      75             :     [16+AV_CLASS_CATEGORY_DEMUXER         ] =  5,
      76             :     [16+AV_CLASS_CATEGORY_ENCODER         ] = 11,
      77             :     [16+AV_CLASS_CATEGORY_DECODER         ] =  3,
      78             :     [16+AV_CLASS_CATEGORY_FILTER          ] = 10,
      79             :     [16+AV_CLASS_CATEGORY_BITSTREAM_FILTER] =  9,
      80             :     [16+AV_CLASS_CATEGORY_SWSCALER        ] =  7,
      81             :     [16+AV_CLASS_CATEGORY_SWRESAMPLER     ] =  7,
      82             :     [16+AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT ] = 13,
      83             :     [16+AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT  ] = 5,
      84             :     [16+AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT ] = 13,
      85             :     [16+AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT  ] = 5,
      86             :     [16+AV_CLASS_CATEGORY_DEVICE_OUTPUT       ] = 13,
      87             :     [16+AV_CLASS_CATEGORY_DEVICE_INPUT        ] = 5,
      88             : };
      89             : 
      90             : static int16_t background, attr_orig;
      91             : static HANDLE con;
      92             : #else
      93             : 
      94             : static const uint32_t color[16 + AV_CLASS_CATEGORY_NB] = {
      95             :     [AV_LOG_PANIC  /8] =  52 << 16 | 196 << 8 | 0x41,
      96             :     [AV_LOG_FATAL  /8] = 208 <<  8 | 0x41,
      97             :     [AV_LOG_ERROR  /8] = 196 <<  8 | 0x11,
      98             :     [AV_LOG_WARNING/8] = 226 <<  8 | 0x03,
      99             :     [AV_LOG_INFO   /8] = 253 <<  8 | 0x09,
     100             :     [AV_LOG_VERBOSE/8] =  40 <<  8 | 0x02,
     101             :     [AV_LOG_DEBUG  /8] =  34 <<  8 | 0x02,
     102             :     [AV_LOG_TRACE  /8] =  34 <<  8 | 0x07,
     103             :     [16+AV_CLASS_CATEGORY_NA              ] = 250 << 8 | 0x09,
     104             :     [16+AV_CLASS_CATEGORY_INPUT           ] = 219 << 8 | 0x15,
     105             :     [16+AV_CLASS_CATEGORY_OUTPUT          ] = 201 << 8 | 0x05,
     106             :     [16+AV_CLASS_CATEGORY_MUXER           ] = 213 << 8 | 0x15,
     107             :     [16+AV_CLASS_CATEGORY_DEMUXER         ] = 207 << 8 | 0x05,
     108             :     [16+AV_CLASS_CATEGORY_ENCODER         ] =  51 << 8 | 0x16,
     109             :     [16+AV_CLASS_CATEGORY_DECODER         ] =  39 << 8 | 0x06,
     110             :     [16+AV_CLASS_CATEGORY_FILTER          ] = 155 << 8 | 0x12,
     111             :     [16+AV_CLASS_CATEGORY_BITSTREAM_FILTER] = 192 << 8 | 0x14,
     112             :     [16+AV_CLASS_CATEGORY_SWSCALER        ] = 153 << 8 | 0x14,
     113             :     [16+AV_CLASS_CATEGORY_SWRESAMPLER     ] = 147 << 8 | 0x14,
     114             :     [16+AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT ] = 213 << 8 | 0x15,
     115             :     [16+AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT  ] = 207 << 8 | 0x05,
     116             :     [16+AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT ] = 213 << 8 | 0x15,
     117             :     [16+AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT  ] = 207 << 8 | 0x05,
     118             :     [16+AV_CLASS_CATEGORY_DEVICE_OUTPUT       ] = 213 << 8 | 0x15,
     119             :     [16+AV_CLASS_CATEGORY_DEVICE_INPUT        ] = 207 << 8 | 0x05,
     120             : };
     121             : 
     122             : #endif
     123             : static int use_color = -1;
     124             : 
     125        5393 : static void check_color_terminal(void)
     126             : {
     127             : #if defined(_WIN32) && !defined(__MINGW32CE__) && HAVE_SETCONSOLETEXTATTRIBUTE
     128             :     CONSOLE_SCREEN_BUFFER_INFO con_info;
     129             :     con = GetStdHandle(STD_ERROR_HANDLE);
     130             :     use_color = (con != INVALID_HANDLE_VALUE) && !getenv("NO_COLOR") &&
     131             :                 !getenv("AV_LOG_FORCE_NOCOLOR");
     132             :     if (use_color) {
     133             :         GetConsoleScreenBufferInfo(con, &con_info);
     134             :         attr_orig  = con_info.wAttributes;
     135             :         background = attr_orig & 0xF0;
     136             :     }
     137             : #elif HAVE_ISATTY
     138        5393 :     char *term = getenv("TERM");
     139       10786 :     use_color = !getenv("NO_COLOR") && !getenv("AV_LOG_FORCE_NOCOLOR") &&
     140       10786 :                 (getenv("TERM") && isatty(2) || getenv("AV_LOG_FORCE_COLOR"));
     141        5393 :     if (   getenv("AV_LOG_FORCE_256COLOR")
     142        5393 :         || (term && strstr(term, "256color")))
     143           0 :         use_color *= 256;
     144             : #else
     145             :     use_color = getenv("AV_LOG_FORCE_COLOR") && !getenv("NO_COLOR") &&
     146             :                !getenv("AV_LOG_FORCE_NOCOLOR");
     147             : #endif
     148        5393 : }
     149             : 
     150     1167872 : static void colored_fputs(int level, int tint, const char *str)
     151             : {
     152             :     int local_use_color;
     153     1167872 :     if (!*str)
     154      880567 :         return;
     155             : 
     156      287305 :     if (use_color < 0)
     157        5393 :         check_color_terminal();
     158             : 
     159      287305 :     if (level == AV_LOG_INFO/8) local_use_color = 0;
     160       12670 :     else                        local_use_color = use_color;
     161             : 
     162             : #if defined(_WIN32) && !defined(__MINGW32CE__) && HAVE_SETCONSOLETEXTATTRIBUTE
     163             :     if (local_use_color)
     164             :         SetConsoleTextAttribute(con, background | color[level]);
     165             :     fputs(str, stderr);
     166             :     if (local_use_color)
     167             :         SetConsoleTextAttribute(con, attr_orig);
     168             : #else
     169      287305 :     if (local_use_color == 1) {
     170           0 :         fprintf(stderr,
     171             :                 "\033[%d;3%dm%s\033[0m",
     172           0 :                 (color[level] >> 4) & 15,
     173           0 :                 color[level] & 15,
     174             :                 str);
     175      287305 :     } else if (tint && use_color == 256) {
     176           0 :         fprintf(stderr,
     177             :                 "\033[48;5;%dm\033[38;5;%dm%s\033[0m",
     178           0 :                 (color[level] >> 16) & 0xff,
     179             :                 tint,
     180             :                 str);
     181      287305 :     } else if (local_use_color == 256) {
     182           0 :         fprintf(stderr,
     183             :                 "\033[48;5;%dm\033[38;5;%dm%s\033[0m",
     184           0 :                 (color[level] >> 16) & 0xff,
     185           0 :                 (color[level] >> 8) & 0xff,
     186             :                 str);
     187             :     } else
     188      287305 :         fputs(str, stderr);
     189             : #endif
     190             : 
     191             : }
     192             : 
     193        2193 : const char *av_default_item_name(void *ptr)
     194             : {
     195        2193 :     return (*(AVClass **) ptr)->class_name;
     196             : }
     197             : 
     198           0 : AVClassCategory av_default_get_category(void *ptr)
     199             : {
     200           0 :     return (*(AVClass **) ptr)->category;
     201             : }
     202             : 
     203     1167872 : static void sanitize(uint8_t *line){
     204    11068971 :     while(*line){
     205     8733227 :         if(*line < 0x08 || (*line > 0x0D && *line < 0x20))
     206           6 :             *line='?';
     207     8733227 :         line++;
     208             :     }
     209     1167872 : }
     210             : 
     211       10859 : static int get_category(void *ptr){
     212       10859 :     AVClass *avc = *(AVClass **) ptr;
     213       10859 :     if(    !avc
     214       10859 :         || (avc->version&0xFF)<100
     215       10859 :         ||  avc->version < (51 << 16 | 59 << 8)
     216       10859 :         ||  avc->category >= AV_CLASS_CATEGORY_NB) return AV_CLASS_CATEGORY_NA + 16;
     217             : 
     218       10859 :     if(avc->get_category)
     219        8254 :         return avc->get_category(ptr) + 16;
     220             : 
     221        2605 :     return avc->category + 16;
     222             : }
     223             : 
     224           0 : static const char *get_level_str(int level)
     225             : {
     226           0 :     switch (level) {
     227             :     case AV_LOG_QUIET:
     228           0 :         return "quiet";
     229             :     case AV_LOG_DEBUG:
     230           0 :         return "debug";
     231             :     case AV_LOG_VERBOSE:
     232           0 :         return "verbose";
     233             :     case AV_LOG_INFO:
     234           0 :         return "info";
     235             :     case AV_LOG_WARNING:
     236           0 :         return "warning";
     237             :     case AV_LOG_ERROR:
     238           0 :         return "error";
     239             :     case AV_LOG_FATAL:
     240           0 :         return "fatal";
     241             :     case AV_LOG_PANIC:
     242           0 :         return "panic";
     243             :     default:
     244           0 :         return "";
     245             :     }
     246             : }
     247             : 
     248      297872 : static void format_line(void *avcl, int level, const char *fmt, va_list vl,
     249             :                         AVBPrint part[4], int *print_prefix, int type[2])
     250             : {
     251      297872 :     AVClass* avc = avcl ? *(AVClass **) avcl : NULL;
     252      297872 :     av_bprint_init(part+0, 0, 1);
     253      297872 :     av_bprint_init(part+1, 0, 1);
     254      297872 :     av_bprint_init(part+2, 0, 1);
     255      297872 :     av_bprint_init(part+3, 0, 65536);
     256             : 
     257      297872 :     if(type) type[0] = type[1] = AV_CLASS_CATEGORY_NA + 16;
     258      297872 :     if (*print_prefix && avc) {
     259       10859 :         if (avc->parent_log_context_offset) {
     260        2176 :             AVClass** parent = *(AVClass ***) (((uint8_t *) avcl) +
     261        2176 :                                    avc->parent_log_context_offset);
     262        2176 :             if (parent && *parent) {
     263           0 :                 av_bprintf(part+0, "[%s @ %p] ",
     264           0 :                          (*parent)->item_name(parent), parent);
     265           0 :                 if(type) type[0] = get_category(parent);
     266             :             }
     267             :         }
     268       10859 :         av_bprintf(part+1, "[%s @ %p] ",
     269       10859 :                  avc->item_name(avcl), avcl);
     270       10859 :         if(type) type[1] = get_category(avcl);
     271             : 
     272       10859 :         if (flags & AV_LOG_PRINT_LEVEL)
     273           0 :             av_bprintf(part+2, "[%s] ", get_level_str(level));
     274             :     }
     275             : 
     276      297872 :     av_vbprintf(part+3, fmt, vl);
     277             : 
     278      297872 :     if(*part[0].str || *part[1].str || *part[2].str || *part[3].str) {
     279      287533 :         char lastc = part[3].len && part[3].len <= part[3].size ? part[3].str[part[3].len - 1] : 0;
     280      287533 :         *print_prefix = lastc == '\n' || lastc == '\r';
     281             :     }
     282      297872 : }
     283             : 
     284           0 : void av_log_format_line(void *ptr, int level, const char *fmt, va_list vl,
     285             :                         char *line, int line_size, int *print_prefix)
     286             : {
     287           0 :     av_log_format_line2(ptr, level, fmt, vl, line, line_size, print_prefix);
     288           0 : }
     289             : 
     290           0 : int av_log_format_line2(void *ptr, int level, const char *fmt, va_list vl,
     291             :                         char *line, int line_size, int *print_prefix)
     292             : {
     293             :     AVBPrint part[4];
     294             :     int ret;
     295             : 
     296           0 :     format_line(ptr, level, fmt, vl, part, print_prefix, NULL);
     297           0 :     ret = snprintf(line, line_size, "%s%s%s%s", part[0].str, part[1].str, part[2].str, part[3].str);
     298           0 :     av_bprint_finalize(part+3, NULL);
     299           0 :     return ret;
     300             : }
     301             : 
     302     4356865 : void av_log_default_callback(void* ptr, int level, const char* fmt, va_list vl)
     303             : {
     304             :     static int print_prefix = 1;
     305             :     static int count;
     306             :     static char prev[LINE_SZ];
     307             :     AVBPrint part[4];
     308             :     char line[LINE_SZ];
     309             :     static int is_atty;
     310             :     int type[2];
     311     4356865 :     unsigned tint = 0;
     312             : 
     313     4356865 :     if (level >= 0) {
     314     4346728 :         tint = level & 0xff00;
     315     4346728 :         level &= 0xff;
     316             :     }
     317             : 
     318     4356865 :     if (level > av_log_level)
     319     4058993 :         return;
     320             : #if HAVE_PTHREADS
     321      297872 :     pthread_mutex_lock(&mutex);
     322             : #endif
     323             : 
     324      297872 :     format_line(ptr, level, fmt, vl, part, &print_prefix, type);
     325      297872 :     snprintf(line, sizeof(line), "%s%s%s%s", part[0].str, part[1].str, part[2].str, part[3].str);
     326             : 
     327             : #if HAVE_ISATTY
     328      297872 :     if (!is_atty)
     329        5393 :         is_atty = isatty(2) ? 1 : -1;
     330             : #endif
     331             : 
     332      303776 :     if (print_prefix && (flags & AV_LOG_SKIP_REPEATED) && !strcmp(line, prev) &&
     333       11808 :         *line && line[strlen(line) - 1] != '\r'){
     334        5904 :         count++;
     335        5904 :         if (is_atty == 1)
     336           0 :             fprintf(stderr, "    Last message repeated %d times\r", count);
     337        5904 :         goto end;
     338             :     }
     339      291968 :     if (count > 0) {
     340         234 :         fprintf(stderr, "    Last message repeated %d times\n", count);
     341         234 :         count = 0;
     342             :     }
     343      291968 :     strcpy(prev, line);
     344      291968 :     sanitize(part[0].str);
     345      291968 :     colored_fputs(type[0], 0, part[0].str);
     346      291968 :     sanitize(part[1].str);
     347      291968 :     colored_fputs(type[1], 0, part[1].str);
     348      291968 :     sanitize(part[2].str);
     349      291968 :     colored_fputs(av_clip(level >> 3, 0, NB_LEVELS - 1), tint >> 8, part[2].str);
     350      291968 :     sanitize(part[3].str);
     351      291968 :     colored_fputs(av_clip(level >> 3, 0, NB_LEVELS - 1), tint >> 8, part[3].str);
     352             : 
     353             : #if CONFIG_VALGRIND_BACKTRACE
     354      291968 :     if (level <= BACKTRACE_LOGLEVEL)
     355       13153 :         VALGRIND_PRINTF_BACKTRACE("%s", "");
     356             : #endif
     357             : end:
     358      297872 :     av_bprint_finalize(part+3, NULL);
     359             : #if HAVE_PTHREADS
     360      297872 :     pthread_mutex_unlock(&mutex);
     361             : #endif
     362             : }
     363             : 
     364             : static void (*av_log_callback)(void*, int, const char*, va_list) =
     365             :     av_log_default_callback;
     366             : 
     367     4357470 : void av_log(void* avcl, int level, const char *fmt, ...)
     368             : {
     369     4357470 :     AVClass* avc = avcl ? *(AVClass **) avcl : NULL;
     370             :     va_list vl;
     371     4357470 :     va_start(vl, fmt);
     372     7962174 :     if (avc && avc->version >= (50 << 16 | 15 << 8 | 2) &&
     373     3858269 :         avc->log_level_offset_offset && level >= AV_LOG_FATAL)
     374      253565 :         level += *(int *) (((uint8_t *) avcl) + avc->log_level_offset_offset);
     375     4357470 :     av_vlog(avcl, level, fmt, vl);
     376     4357470 :     va_end(vl);
     377     4357470 : }
     378             : 
     379     4357470 : void av_vlog(void* avcl, int level, const char *fmt, va_list vl)
     380             : {
     381     4357470 :     void (*log_callback)(void*, int, const char*, va_list) = av_log_callback;
     382     4357470 :     if (log_callback)
     383     4357467 :         log_callback(avcl, level, fmt, vl);
     384     4357470 : }
     385             : 
     386       35413 : int av_log_get_level(void)
     387             : {
     388       35413 :     return av_log_level;
     389             : }
     390             : 
     391         134 : void av_log_set_level(int level)
     392             : {
     393         134 :     av_log_level = level;
     394         134 : }
     395             : 
     396        5186 : void av_log_set_flags(int arg)
     397             : {
     398        5186 :     flags = arg;
     399        5186 : }
     400             : 
     401          66 : int av_log_get_flags(void)
     402             : {
     403          66 :     return flags;
     404             : }
     405             : 
     406          67 : void av_log_set_callback(void (*callback)(void*, int, const char*, va_list))
     407             : {
     408          67 :     av_log_callback = callback;
     409          67 : }
     410             : 
     411           0 : static void missing_feature_sample(int sample, void *avc, const char *msg,
     412             :                                    va_list argument_list)
     413             : {
     414           0 :     av_vlog(avc, AV_LOG_WARNING, msg, argument_list);
     415           0 :     av_log(avc, AV_LOG_WARNING, " is not implemented. Update your FFmpeg "
     416             :            "version to the newest one from Git. If the problem still "
     417             :            "occurs, it means that your file has a feature which has not "
     418             :            "been implemented.\n");
     419           0 :     if (sample)
     420           0 :         av_log(avc, AV_LOG_WARNING, "If you want to help, upload a sample "
     421             :                "of this file to ftp://upload.ffmpeg.org/incoming/ "
     422             :                "and contact the ffmpeg-devel mailing list. (ffmpeg-devel@ffmpeg.org)\n");
     423           0 : }
     424             : 
     425           0 : void avpriv_request_sample(void *avc, const char *msg, ...)
     426             : {
     427             :     va_list argument_list;
     428             : 
     429           0 :     va_start(argument_list, msg);
     430           0 :     missing_feature_sample(1, avc, msg, argument_list);
     431           0 :     va_end(argument_list);
     432           0 : }
     433             : 
     434           0 : void avpriv_report_missing_feature(void *avc, const char *msg, ...)
     435             : {
     436             :     va_list argument_list;
     437             : 
     438           0 :     va_start(argument_list, msg);
     439           0 :     missing_feature_sample(0, avc, msg, argument_list);
     440           0 :     va_end(argument_list);
     441           0 : }

Generated by: LCOV version 1.12