多媒体科技

ijkplayer-日志输出

2019-05-29  本文已影响3人  smallest_one

目录

  1. 概述
  2. 日志输出实现
  3. 附录

参考

1. 概述

ijkplayer中日志打印模块控制日志的输出方式:

对于依赖库FFmpeg的日志输出,提供了设置日志级别的接口和控制是否按照FFmpeg默认的格式输出的开关。由于FFmpeg和ijkplayer的定义的日志级别有差异,需要定义一个转换关系。

日志输出控制的接口:

2. 日志输出实现

ijkplayer中日志输出实现主要涉及的源码文件如下所示:

├── ijkmedia
│   ├── ijkplayer
│   │   ├── ff_ffplay.c
│   └── ijksdl
│       ├── ijksdl_extra_log.c
│       ├── ijksdl_extra_log.h
│       ├── ijksdl_log.h

2.1 ijkplayer日志输出

//h264_nal.h
  ALOGE( "PPS too small after processing SPS/PPS %u", i_data_size );
//ff_ffplay.c
static void ffp_log_callback_report(void *ptr, int level, const char *fmt, va_list vl)
{
...
    int ffplv __unused = log_level_av_to_ijk(level);
...
    char line[1024];
...
    ALOG(ffplv, IJK_LOG_TAG, "%s", line);
}

在ijksdl_log.h中屏蔽了各平台日志输出实现的差异。

//ijksdl_log.h
#define IJK_LOG_DEBUG       ANDROID_LOG_DEBUG
...
#ifdef EXTRA_LOG_PRINT
#define VLOG(level, TAG, ...)    ffp_log_extra_vprint(level, TAG, __VA_ARGS__)
#define ALOG(level, TAG, ...)    ffp_log_extra_print(level, TAG, __VA_ARGS__)
#else
#define VLOG(level, TAG, ...)    ((void)__android_log_vprint(level, TAG, __VA_ARGS__))
#define ALOG(level, TAG, ...)    ((void)__android_log_print(level, TAG, __VA_ARGS__))
#endif

#else
...
#define IJK_LOG_VERBOSE     2
...

#define VLOG(level, TAG, ...)    ((void)vprintf(__VA_ARGS__))
#define ALOG(level, TAG, ...)    ((void)printf(__VA_ARGS__))

#endif

#define IJK_LOG_TAG "IJKMEDIA"

#define VLOGV(...)  VLOG(IJK_LOG_VERBOSE,   IJK_LOG_TAG, __VA_ARGS__)
...

#define ALOGV(...)  ALOG(IJK_LOG_VERBOSE,   IJK_LOG_TAG, __VA_ARGS__)
...
#define LOG_ALWAYS_FATAL(...)   do { ALOGE(__VA_ARGS__); exit(1); } while (0)

#endif

2.2 FFmpeg的日志输出

//ff_ffplay.c
inline static int log_level_av_to_ijk(int av_level)
{
    int ijk_level = IJK_LOG_VERBOSE;
    if      (av_level <= AV_LOG_PANIC)      ijk_level = IJK_LOG_FATAL;
    else if (av_level <= AV_LOG_FATAL)      ijk_level = IJK_LOG_FATAL;
    else if (av_level <= AV_LOG_ERROR)      ijk_level = IJK_LOG_ERROR;
    else if (av_level <= AV_LOG_WARNING)    ijk_level = IJK_LOG_WARN;
    else if (av_level <= AV_LOG_INFO)       ijk_level = IJK_LOG_INFO;
    // AV_LOG_VERBOSE means detailed info
    else if (av_level <= AV_LOG_VERBOSE)    ijk_level = IJK_LOG_INFO;
    else if (av_level <= AV_LOG_DEBUG)      ijk_level = IJK_LOG_DEBUG;
    else if (av_level <= AV_LOG_TRACE)      ijk_level = IJK_LOG_VERBOSE;
    else                                    ijk_level = IJK_LOG_VERBOSE;
    return ijk_level;
}

inline static int log_level_ijk_to_av(int ijk_level)
{
    int av_level = IJK_LOG_VERBOSE;
    if      (ijk_level >= IJK_LOG_SILENT)   av_level = AV_LOG_QUIET;
    else if (ijk_level >= IJK_LOG_FATAL)    av_level = AV_LOG_FATAL;
    else if (ijk_level >= IJK_LOG_ERROR)    av_level = AV_LOG_ERROR;
    else if (ijk_level >= IJK_LOG_WARN)     av_level = AV_LOG_WARNING;
    else if (ijk_level >= IJK_LOG_INFO)     av_level = AV_LOG_INFO;
    // AV_LOG_VERBOSE means detailed info
    else if (ijk_level >= IJK_LOG_DEBUG)    av_level = AV_LOG_DEBUG;
    else if (ijk_level >= IJK_LOG_VERBOSE)  av_level = AV_LOG_TRACE;
    else if (ijk_level >= IJK_LOG_DEFAULT)  av_level = AV_LOG_TRACE;
    else if (ijk_level >= IJK_LOG_UNKNOWN)  av_level = AV_LOG_TRACE;
    else                                    av_level = AV_LOG_TRACE;
    return av_level;
}

static void ffp_log_callback_brief(void *ptr, int level, const char *fmt, va_list vl)
{
    if (level > av_log_get_level())
        return;

    int ffplv __unused = log_level_av_to_ijk(level);
    VLOG(ffplv, IJK_LOG_TAG, fmt, vl);
}

static void ffp_log_callback_report(void *ptr, int level, const char *fmt, va_list vl)
{
    if (level > av_log_get_level())
        return;

    int ffplv __unused = log_level_av_to_ijk(level);

    va_list vl2;
    char line[1024];
    static int print_prefix = 1;

    va_copy(vl2, vl);
    // av_log_default_callback(ptr, level, fmt, vl);
    av_log_format_line(ptr, level, fmt, vl2, line, sizeof(line), &print_prefix);
    va_end(vl2);

    ALOG(ffplv, IJK_LOG_TAG, "%s", line);
}

void ffp_global_set_log_report(int use_report)
{
    if (use_report) {
        av_log_set_callback(ffp_log_callback_report);
    } else {
        av_log_set_callback(ffp_log_callback_brief);
    }
}

void ffp_global_set_log_level(int log_level)
{
    int av_level = log_level_ijk_to_av(log_level);
    av_log_set_level(av_level);
}

2.3 日志输出控制示例

iOS示例

//ijkplayer\ios\IJKMediaDemo\IJKMediaDemo\IJKMoviePlayerViewController.m
#ifdef DEBUG
    [IJKFFMoviePlayerController setLogReport:YES];
    [IJKFFMoviePlayerController setLogLevel:k_IJK_LOG_DEBUG];
#else
    [IJKFFMoviePlayerController setLogReport:NO];
    [IJKFFMoviePlayerController setLogLevel:k_IJK_LOG_INFO];
#endif

3. 附录

3.1. __unused

__unused宏实际上的扩展是GCC编译属性的__attribute__((unused)),用于告诉编译器“如果没有使用这个变量,不要发出警告”。[3]

3.2. __android_log_print__android_log_vprint函数的定义

__android_log_print(int prio, const char *tag, const char *fmt, ...);
__android_log_vprint(int prio, const char *tag, const char *fmt, va_list ap);

3.3. FFmpeg中日志级别的定义

//avutil/log.h
#define AV_LOG_QUIET    -8

/**
 * Something went really wrong and we will crash now.
 */
#define AV_LOG_PANIC     0

/**
 * Something went wrong and recovery is not possible.
 * For example, no header was found for a format which depends
 * on headers or an illegal combination of parameters is used.
 */
#define AV_LOG_FATAL     8

/**
 * Something went wrong and cannot losslessly be recovered.
 * However, not all future data is affected.
 */
#define AV_LOG_ERROR    16

/**
 * Something somehow does not look correct. This may or may not
 * lead to problems. An example would be the use of '-vstrict -2'.
 */
#define AV_LOG_WARNING  24

/**
 * Standard information.
 */
#define AV_LOG_INFO     32

/**
 * Detailed information.
 */
#define AV_LOG_VERBOSE  40

/**
 * Stuff which is only useful for libav* developers.
 */
#define AV_LOG_DEBUG    48

/**
 * Extremely verbose debugging, useful for libav* development.
 */
#define AV_LOG_TRACE    56

3.4. av_log_format_line

void av_log_format_line (   void *  ptr,
int     level,
const char *    fmt,
va_list     vl,
char *  line,
int     line_size,
int *   print_prefix 
)   
上一篇 下一篇

猜你喜欢

热点阅读