一般使用Error, Warning, Debug3个级别即可(见下面的颜色)。AV_LOG_QUIET

核心函数只有一个:av_log()。使用av_log()在控制台输出日志的效果如下图所示。

av_log()

av_log()是FFmpeg中输出日志的函数。随便打开一个FFmpeg的源代码文件,就会发现其中遍布着av_log()函数。一般情况下FFmpeg类库的源代码中是不允许使用printf()这种的函数的,所有的输出一律使用av_log()。
av_log()的声明位于libavutil\log.h,如下所示。

  1. * Send the specified message to the log if the level is less than or equal
  2. * to the current av_log_level. By default, all logging messages are sent to
  3. * stderr. This behavior can be altered by setting a different logging callback
  4. * function.
  5. * @see av_log_set_callback
  6. *
  7. * @param avcl A pointer to an arbitrary struct of which the first field is a
  8. *        pointer to an AVClass struct.
  9. * @param level The importance level of the message expressed using a @ref
  10. *        lavu_log_constants "Logging Constant".
  11. * @param fmt The format string (printf-compatible) that specifies how
  12. *        subsequent arguments are converted to output.
  13. */
  14. void av_log(void *avcl, int level, constchar *fmt, ...) av_printf_format(3, 4);
 av_log(avctx, AV_LOG_ERROR, "Invalid Profile/Level.\n");
 av_log(avctx, AV_LOG_ERROR, "Dimensions %dx%d not supported.\n", width, avctx->height);

这个函数的声明有两个地方比较特殊:

(1)函数最后一个参数是“…”
在C语言中,在函数参数数量不确定的情况下使用“…”来代表参数。例如printf()的原型定义如下

int printf (const char*, ...);

(2)它的声明后面有一个av_printf_format(3, 4)。有关这个地方还没有深入研究,网上资料中说它的作用是按照printf()的格式检查av_log()的格式。

av_log()每个字段的含义如下:
avcl:指定一个包含AVClass的结构体。
level:log的级别
fmt:和printf()一样。

由此可见,av_log()和printf()的不同主要在于前面多了两个参数。其中第一个参数指定该log所属的结构体,例如AVFormatContext、AVCodecContext等等。第二个参数指定log的级别:

有一个级别不输出任何信息,即AV_LOG_QUIET。

可以通过av_log_get_level()获得当前Log的级别,通过另一个函数av_log_set_level()设置当前的Log级别。

我们看一下H.264编码的时候libx264的Log输出的示例:

下面回到av_log()函数的源代码。它的源代码位于libavutil\log.c,如下所示。

  1. void av_log(void* avcl, int level, constchar *fmt, ...)
  2. {
  3. AVClass* avc = avcl ? *(AVClass **) avcl : NULL;
  4. va_list vl;
  5. va_start(vl, fmt);
  6. if (avc && avc->version >= (50 << 16 | 15 << 8 | 2) &&
  7. avc->log_level_offset_offset && level >= AV_LOG_FATAL)
  8. level += *(int *) (((uint8_t *) avcl) + avc->log_level_offset_offset);
  9. av_vlog(avcl, level, fmt, vl);
  10. va_end(vl);
  11. }

首先来提一下C语言函数中“…”参数的含义。与它相关还涉及到以下4个部分:

(1)va_list变量
(2)va_start()
(3)va_arg()
(4)va_end()

va_list是一个指向函数的参数的指针。va_start()用于初始化va_list变量。va_arg()用于返回可变参数。va_end()用于结束可变参数的获取。有关它们的用法可以参考一个小demo,如下所示。

  1. [0m"

(3)颜色对应关系如下所示:
\e[30m -- \e[37m    设置前景色(字体颜色)
echo -e "\e[30m"    灰色
echo -e "\e[31m"    红色    
echo -e "\e[32m"    绿色
echo -e "\e[33m"    黄色
echo -e "\e[34m"    蓝色
echo -e "\e[35m"    紫色
echo -e "\e[36m"    淡蓝色
echo -e "\e[37m"    白色

\e[40m -- \e[47m    设置背景色
echo -e "\e[40m"    灰色
echo -e "\e[41m"    红色
echo -e "\e[42m"    绿色
echo -e "\e[43m"    黄色
echo -e "\e[44m"    蓝色
echo -e "\e[45m"    紫色
echo -e "\e[46m"    淡蓝色
echo -e "\e[47m"    白色

具体到编程中,printf() 颜色设置示例代码如下所示。

  1. int main()
  2. {
  3. printf("\e[31m Hello World. \e[0m \n"); // 红色字体
  4. return 0;
  5. }

Windows下控制台文字上色的方法

Windows下控制台颜色是通过SetConsoleTextAttribute()函数完成的。SetConsoleTextAttribute()函数的原型如下所示。

  1. BOOL SetConsoleTextAttribute(HANDLE hConsoleOutput, WORD wAttributes);

其中2个参数的含义如下所示:

hConsoleOutput:指向控制台的句柄。
wAttributes:文本属性。

hConsoleOutput可以选择以下3种句柄:

STD_INPUT_HANDLE:标准输入的句柄
STD_OUTPUT_HANDLE:标准输出的句柄
STD_ERROR_HANDLE:标准错误的句柄

wAttributes可以控制前景色和背景色:

FOREGROUND_BLUE:字体颜色:蓝
FOREGROUND_GREEN:字体颜色:绿
FOREGROUND_RED:字体颜色:红
FOREGROUND_INTENSITY:前景色高亮显示
BACKGROUND_BLUE:背景颜色:蓝
BACKGROUND_GREEN:背景颜色:绿
BACKGROUND_RED:背景颜色:红
BACKGROUND_INTENSITY背景色高亮显示

控制台文本上色demo代码如下所示。

  1. #include
  2. #include
  3. int main()
  4. {
  5. SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED);
  6. printf("red\n");
  7. SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN);
  8. printf("green\n");
  9. SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_BLUE);
  10. printf("blue\n");
  11. SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED|FOREGROUND_GREEN);
  12. printf("red+green=yellow\n");
  13. SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED|FOREGROUND_BLUE);
  14. printf("red+blue=purple\n");
  15. SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN|FOREGROUND_BLUE);
  16. printf("green+blue=cyan\n");
  17. SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED|BACKGROUND_GREEN);
  18. printf("Add background\n");
  19. return 0;
  20. }

程序的运行结果如下图所示。

colored_fputs()源代码

从colored_fputs()的源代码中可以看出如下流程:
首先根据宏定义判定系统的类型,如果系统类型是Windows,那么就调用SetConsoleTextAttribute()方法设定控制台文本的颜色,然后调用fputs()将Log记录输出到stderr(注意不是stdout);

如果系统类型是Linux,则通过添加特定字符串的方式设定控制台文本的颜色,然后将Log记录输出到stderr。
至此FFmpeg的日志输出系统的源代码就分析完毕了。

av_log() 函数
avcl:指定一个包含 AVClass 的结构体,指定该 log 所属的结构体,如 AVFormatContext、AVCodecContext 等等,可以设置为 NULL
av_log(NULL, AV_LOG_DEBUG, "Hello World ! \n");

ffmpeg 日志系统av_log()的更多相关文章

  1. C++ 高性能无锁日志系统

    服务器编程中,日志系统需要满足几个条件 .高效,日志系统不应占用太多资源 .简洁,为了一个简单的日志功能引入大量第三方代码未必值得 .线程安全,服务器中各个线程都能同时写出日志 .轮替,服务器不出故障 ...

  2. Atitit.日志系统slf4j的使用

    Atitit.日志系统slf4j的使用 SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar ...

  3. Android源码——Logger日志系统

    Android的Logger日志系统是基于内核中的Logger日志驱动程序实现的. 日志保存在内核空间中 缓冲区保存日志   分类方法:日志的类型  +   日志的输出量   日志类型:   main ...

  4. 使用Slf4j集成Log4j2构建项目日志系统的完美解决方案

    一.背景 最近因为公司项目性能需要,我们考虑把以前基于的log4j的日志系统重构成基于Slf4j和log4j2的日志系统,因为,使用slf4j可以很好的保证我们的日志系统具有良好的兼容性,兼容当前常见 ...

  5. 日志系统实战(三)-分布式跟踪的Net实现

    介绍 在大型系统开发调试中,跨系统之间联调开始变得不好使了.莫名其妙一个错误爆出来了,日志虽然有记录,但到底是哪里出问题了呢? 是Ios端参数传的不对?还是A系统或B系统提供的接口导致?相信有不少人遇 ...

  6. 日志系统实战(一)—AOP静态注入

    背景 近期在写日志系统,需要在运行时在函数内注入日志记录,并附带函数信息,这时就想到用Aop注入的方式. AOP分动态注入和静态注入两种注入的方式. 动态注入方式 利用Remoting的Context ...

  7. Android性能优化之UncaughtExceptionHandler定制自己的错误日志系统

    前言: 每当我们app测试的时候,测试人员总是对我们说这里崩溃了,那里挂掉了!我们只能默默接受,然后尝试着重现bug,更可悲的是有时候bug很难复现,为了解决这种现状所以我们要尝试这建立一个自己的bu ...

  8. [Asp.net 5] Logging-其他日志系统的实现

    Microsoft.Framework.Logging.NLog 使用Nlog扩展日志系统:按照我们上节说的,对于扩展的日志系统都要实现俩个接口ILogger.ILoggerProvider.所以在当 ...

  9. 【转载】scribe、chukwa、kafka、flume日志系统对比

    原文地址:http://www.ttlsa.com/log-system/scribe-chukwa-kafka-flume-log-system-contrast/ 1. 背景介绍许多公司的平台每天 ...

随机推荐

  1. idea autoscroll from source

  2. [Angular] AfterContentChecked && AfterViewChecked

    AfterContentChecked & AfterViewChecked are called after 'OnChanges' lifecycle. And each time 'ng ...

  3. GET RESTful With Python

    Python调用RESTful:http://blog.akiban.com/get-restful-with-python/ 本文就是参考该英文做了一下试验,后续补充一下翻译. This post ...

  4. JMeter 八:录制脚本--使用Jmeter自带的代理服务器

    参考:http://jmeter.apache.org/usermanual/jmeter_proxy_step_by_step.pdf http://jmeter.apache.org/userma ...

  5. hibernate session的load和get方法

    @Test public void testLoad() {     Session session = sessionFactory.getCurrentSession();     session ...

  6. 获取SQL Server的安装时间

    近期安装SQL Server 2014时.还没有正式的License,仅仅能试用3个月.想知道什么时候到期,就要知道SQL Server 2014是什么时候安装的.假设你没有特意记录安装日期(实际大部 ...

  7. 转发:【PHP】转义和过滤html单、双引号及HTML标签

    一.单引号和双引号转义在PHP的数据存储过程中用得比较多,即往数据库里面存储数据时候需要注意转义单.双引号: 先说几个PHP函数: 1.addslashes — 使用反斜线引用(转义)字符串: 返回字 ...

  8. Apache服务器配置https协议/SSL证书的方法

    转载于:http://www.server110.com/apache/201309/1542.html

  9. Mysql 中 trim 的用法

    需求:去掉contract字段值中的% update gsfrankfurt set contract = trim(both "%" from contract);

  10. post请求方式的翻页爬取内容及思考

    1 #coding=utf-8 import urllib2 import urllib import json output = open('huizho.json', 'w') for page ...