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

Generated by: LCOV version 1.13