ffmpeg 日志系统av_log()
核心函数只有一个:av_log()。使用av_log()在控制台输出日志的效果如下图所示。
av_log()
av_log()是FFmpeg中输出日志的函数。随便打开一个FFmpeg的源代码文件,就会发现其中遍布着av_log()函数。一般情况下FFmpeg类库的源代码中是不允许使用printf()这种的函数的,所有的输出一律使用av_log()。
av_log()的声明位于libavutil\log.h,如下所示。
- * 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, constchar *fmt, ...) av_printf_format(3, 4);
这个函数的声明有两个地方比较特殊:
(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,如下所示。
- void av_log(void* avcl, int level, constchar *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);
- }
首先来提一下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,如下所示。
- [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() 颜色设置示例代码如下所示。
- int main()
- {
- printf("\e[31m Hello World. \e[0m \n"); // 红色字体
- return 0;
- }
Windows下控制台文字上色的方法
Windows下控制台颜色是通过SetConsoleTextAttribute()函数完成的。SetConsoleTextAttribute()函数的原型如下所示。
- 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代码如下所示。
- #include
- #include
- int main()
- {
- SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED);
- printf("red\n");
- SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN);
- printf("green\n");
- SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_BLUE);
- printf("blue\n");
- SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED|FOREGROUND_GREEN);
- printf("red+green=yellow\n");
- SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED|FOREGROUND_BLUE);
- printf("red+blue=purple\n");
- SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN|FOREGROUND_BLUE);
- printf("green+blue=cyan\n");
- SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED|BACKGROUND_GREEN);
- printf("Add background\n");
- return 0;
- }
程序的运行结果如下图所示。

colored_fputs()源代码
从colored_fputs()的源代码中可以看出如下流程:
首先根据宏定义判定系统的类型,如果系统类型是Windows,那么就调用SetConsoleTextAttribute()方法设定控制台文本的颜色,然后调用fputs()将Log记录输出到stderr(注意不是stdout);
至此FFmpeg的日志输出系统的源代码就分析完毕了。
av_log() 函数
av_log(NULL, AV_LOG_DEBUG,
"Hello World ! \n"
);
ffmpeg 日志系统av_log()的更多相关文章
- C++ 高性能无锁日志系统
服务器编程中,日志系统需要满足几个条件 .高效,日志系统不应占用太多资源 .简洁,为了一个简单的日志功能引入大量第三方代码未必值得 .线程安全,服务器中各个线程都能同时写出日志 .轮替,服务器不出故障 ...
- Atitit.日志系统slf4j的使用
Atitit.日志系统slf4j的使用 SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar ...
- Android源码——Logger日志系统
Android的Logger日志系统是基于内核中的Logger日志驱动程序实现的. 日志保存在内核空间中 缓冲区保存日志 分类方法:日志的类型 + 日志的输出量 日志类型: main ...
- 使用Slf4j集成Log4j2构建项目日志系统的完美解决方案
一.背景 最近因为公司项目性能需要,我们考虑把以前基于的log4j的日志系统重构成基于Slf4j和log4j2的日志系统,因为,使用slf4j可以很好的保证我们的日志系统具有良好的兼容性,兼容当前常见 ...
- 日志系统实战(三)-分布式跟踪的Net实现
介绍 在大型系统开发调试中,跨系统之间联调开始变得不好使了.莫名其妙一个错误爆出来了,日志虽然有记录,但到底是哪里出问题了呢? 是Ios端参数传的不对?还是A系统或B系统提供的接口导致?相信有不少人遇 ...
- 日志系统实战(一)—AOP静态注入
背景 近期在写日志系统,需要在运行时在函数内注入日志记录,并附带函数信息,这时就想到用Aop注入的方式. AOP分动态注入和静态注入两种注入的方式. 动态注入方式 利用Remoting的Context ...
- Android性能优化之UncaughtExceptionHandler定制自己的错误日志系统
前言: 每当我们app测试的时候,测试人员总是对我们说这里崩溃了,那里挂掉了!我们只能默默接受,然后尝试着重现bug,更可悲的是有时候bug很难复现,为了解决这种现状所以我们要尝试这建立一个自己的bu ...
- [Asp.net 5] Logging-其他日志系统的实现
Microsoft.Framework.Logging.NLog 使用Nlog扩展日志系统:按照我们上节说的,对于扩展的日志系统都要实现俩个接口ILogger.ILoggerProvider.所以在当 ...
- 【转载】scribe、chukwa、kafka、flume日志系统对比
原文地址:http://www.ttlsa.com/log-system/scribe-chukwa-kafka-flume-log-system-contrast/ 1. 背景介绍许多公司的平台每天 ...
随机推荐
- idea autoscroll from source
- [Angular] AfterContentChecked && AfterViewChecked
AfterContentChecked & AfterViewChecked are called after 'OnChanges' lifecycle. And each time 'ng ...
- GET RESTful With Python
Python调用RESTful:http://blog.akiban.com/get-restful-with-python/ 本文就是参考该英文做了一下试验,后续补充一下翻译. This post ...
- JMeter 八:录制脚本--使用Jmeter自带的代理服务器
参考:http://jmeter.apache.org/usermanual/jmeter_proxy_step_by_step.pdf http://jmeter.apache.org/userma ...
- hibernate session的load和get方法
@Test public void testLoad() { Session session = sessionFactory.getCurrentSession(); session ...
- 获取SQL Server的安装时间
近期安装SQL Server 2014时.还没有正式的License,仅仅能试用3个月.想知道什么时候到期,就要知道SQL Server 2014是什么时候安装的.假设你没有特意记录安装日期(实际大部 ...
- 转发:【PHP】转义和过滤html单、双引号及HTML标签
一.单引号和双引号转义在PHP的数据存储过程中用得比较多,即往数据库里面存储数据时候需要注意转义单.双引号: 先说几个PHP函数: 1.addslashes — 使用反斜线引用(转义)字符串: 返回字 ...
- Apache服务器配置https协议/SSL证书的方法
转载于:http://www.server110.com/apache/201309/1542.html
- Mysql 中 trim 的用法
需求:去掉contract字段值中的% update gsfrankfurt set contract = trim(both "%" from contract);
- post请求方式的翻页爬取内容及思考
1 #coding=utf-8 import urllib2 import urllib import json output = open('huizho.json', 'w') for page ...