ffmpeg里面的av_log实现

【版权申明】转载请附上出处链接

ffmpeg里面的av_log实现

话不多说,直接上demo:

#include <stdio.h>
#include <libavutil/log.h>

/**
 * Print no output.
 */
#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

#define AV_LOG_MAX_OFFSET (AV_LOG_TRACE - AV_LOG_QUIET)


int main(int argc, char *argv[])
{
    av_log_set_level(AV_LOG_MAX_OFFSET);

    av_log(NULL, AV_LOG_MAX_OFFSET, "AV_LOG_MAX_OFFSET\n");
    av_log(NULL, AV_LOG_TRACE, "AV_LOG_TRACE\n");
    av_log(NULL, AV_LOG_DEBUG, "AV_LOG_DEBUG\n");
    av_log(NULL, AV_LOG_VERBOSE, "AV_LOG_VERBOSE\n");
    av_log(NULL, AV_LOG_INFO, "AV_LOG_INFO\n");
    av_log(NULL, AV_LOG_WARNING, "AV_LOG_WARNING\n");
    av_log(NULL, AV_LOG_ERROR, "AV_LOG_ERROR\n");
    av_log(NULL, AV_LOG_FATAL, "AV_LOG_FATAL\n");
    av_log(NULL, AV_LOG_PANIC, "AV_LOG_PANIC\n");
    av_log(NULL, AV_LOG_QUIET, "AV_LOG_QUIET\n");

    return 0;
}

效果如下:

run

av_log_set_level(AV_LOG_MAX_OFFSET);

static int av_log_level = AV_LOG_INFO;

void av_log_set_level(int level)
{
    av_log_level = level;
}

赋值,修改全局变量av_log_level的值,可猜测得知小于这个数时这个av_log将会被打印出来。

av_log(NULL, AV_LOG_DEBUG, "AV_LOG_DEBUG\n");

/**
 * Send the specified message to the log if the level is less than or equal
 * to the current av_log_level. By default, all logging messages are sent to
 * stderr. This behavior can be altered by setting a different logging callback
 * function.
 * @see av_log_set_callback
 *
 * @param avcl A pointer to an arbitrary struct of which the first field is a
 *        pointer to an AVClass struct.
 * @param level The importance level of the message expressed using a @ref
 *        lavu_log_constants "Logging Constant".
 * @param fmt The format string (printf-compatible) that specifies how
 *        subsequent arguments are converted to output.
 */
void av_log(void* avcl, int level, const char *fmt, ...)
{
    AVClass* avc = avcl ? *(AVClass **) avcl : NULL;
    va_list vl;
    va_start(vl, fmt);
    if (avc && avc->version >= (50 << 16 | 15 << 8 | 2) &&
        avc->log_level_offset_offset && level >= AV_LOG_FATAL)
        level += *(int *) (((uint8_t *) avcl) + avc->log_level_offset_offset);
    av_vlog(avcl, level, fmt, vl);
    va_end(vl);
}

我们把avc1=NULL代入时,函数得到进一步的精简(因为我现在还不知道avc1怎么用,所以先放着):

void av_log(void* avcl, int level, const char *fmt, ...)
{
    va_list vl;
    va_start(vl, fmt);
    av_vlog(avcl, level, fmt, vl);
    va_end(vl);
}
插入小知识:va_list变量、va_start()/va_arg()/va_end()函数的讲解~
#include <stdio.h>
#include<stdarg.h>

// va_list实现不定参数C函数
void func(const char *fmt, ...)
{
	va_list vl;			// 定义va_list变量vl,该变量是指向可变参数的指针
	char *value_str;
	int  value_int;

	va_start(vl, fmt);	// 参数1:va_list变量vl;	参数2:函数参数的最后一个可变参数变量名,即这里的fmt
	value_str = va_arg(vl, char *);	//参数1:va_list变量vl;	参数2:可变参数的类型,返回值即为可变参数的数值(va_arg()之后会自动加1指向下一个arg,且va_arg()从可变参数的第1个参数开始,即这里的"haha")
	value_int = va_arg(vl, int);

	printf("value_str=%s, value_int=%d \n", value_str, value_int);

	va_end(vl); // 结束可变参数的获取
}

int main(int argc, char **argv)
{
	func("第0个参数用于标识后面的参数类型顺序,供函数中的fmt使用,详情:man va_arg看示例", "haha", 100);

	return 0;
}

结果为:

value_str=haha, value_int=60 

回到我们的av_vlog(avcl, level, fmt, vl);

static void (*av_log_callback)(void*, int, const char*, va_list) = av_log_default_callback;

av_vlog(void* avcl, int level, const char *fmt, va_list vl)
	void (*log_callback)(void*, int, const char*, va_list) = av_log_callback;
		av_log_default_callback(avcl, level, fmt, vl);
void av_log_default_callback(void* ptr, int level, const char* fmt, va_list vl)
{
    static int print_prefix = 1;
    static int count;
    static char prev[LINE_SZ];
    AVBPrint part[4];
    char line[LINE_SZ];
    static int is_atty;
    int type[2];
    unsigned tint = 0;

    if (level >= 0) {
        tint = level & 0xff00;
        level &= 0xff;
    }

    if (level > av_log_level)		// 当level大于我们所设置的av_log_level,这个log将不会被显示,在这里被直接返回了。
        return;
    ff_mutex_lock(&mutex);

    format_line(ptr, level, fmt, vl, part, &print_prefix, type);
    snprintf(line, sizeof(line), "%s%s%s%s", part[0].str, part[1].str, part[2].str, part[3].str);

#if HAVE_ISATTY
    if (!is_atty)
        is_atty = isatty(2) ? 1 : -1;
#endif

    if (print_prefix && (flags & AV_LOG_SKIP_REPEATED) && !strcmp(line, prev) &&
        *line && line[strlen(line) - 1] != '\r'){
        count++;
        if (is_atty == 1)
            fprintf(stderr, "    Last message repeated %d times\r", count);
        goto end;
    }
    if (count > 0) {
        fprintf(stderr, "    Last message repeated %d times\n", count);
        count = 0;
    }
    strcpy(prev, line);
    sanitize(part[0].str);
    colored_fputs(type[0], 0, part[0].str);
    sanitize(part[1].str);
    colored_fputs(type[1], 0, part[1].str);
    sanitize(part[2].str);
    colored_fputs(av_clip(level >> 3, 0, NB_LEVELS - 1), tint >> 8, part[2].str);
    sanitize(part[3].str);
    colored_fputs(av_clip(level >> 3, 0, NB_LEVELS - 1), tint >> 8, part[3].str);

#if CONFIG_VALGRIND_BACKTRACE
    if (level <= BACKTRACE_LOGLEVEL)
        VALGRIND_PRINTF_BACKTRACE("%s", "");
#endif
end:
    av_bprint_finalize(part+3, NULL);
    ff_mutex_unlock(&mutex);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安河桥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值