一般使用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. 使用ant运行testng的testng.xml并且使用testng-results.xsl美化结果

    先看build.xml <?xml version="1.0" encoding="UTF-8"?> <project basedir=&qu ...

  2. Node.js mm131图片批量下载爬虫1.01 增加断点续传功能

    这里的断点续传不是文件下载时的断点续传,而是指在爬行页面时有时会遇到各种网络中断而从中断前的页面及其数据继续爬行的过程,这个过程和断点续传原理上相似故以此命名.我的具体做法是:在下载出现故障或是图片已 ...

  3. 超酷的实时颜色数据跟踪javascript类库 - Tracking.js

    来源:GBin1.com 今天介绍这款超棒的Javascript类库是 - Tracking.js,它能够独立不依赖第三方类库帮助开发人员动态跟踪摄像头输出相关数据. 这些数据包括了颜色或者是人, 这 ...

  4. Android系统常用的权限

    开机自动允许  android.permission.RECEIVE_BOOT_COMPLETED,允许程序开机自动运行. 电量统计  android.permission.BATTERY_STATS ...

  5. ionic搜索头部

    <div class="item-input-inset bar"> <form action="javascript:;" style=&q ...

  6. 《暗黑世界V1.4》API说明文档

    <暗黑世界V1.4>API说明文档 阵法位置示意图 上方:                        下方:      账号注册   100 请求信息 { username   str ...

  7. raspberry pi install iceweasel

    sudo apt-get update sudo apt-get upgrade sudo apt-get install iceweasel

  8. 06-hibernate注解-一对多单向外键关联

    一对多单向外键 1,一方持有多方的集合,一个班级有多个学生(一对多). 2,@OneToMany(cascade={CascadeType.ALL}, fetch=FetchType.LAZY ) / ...

  9. JDBC数据库编程:callableStatement接口

    了解MySQL存储过程建立, 了解存储过程中参数传递的三种方式 了解callablestatement调用存储过程操作. 因为在现在开发中,使用存储过程的地方越来越少,所以,对于存储过程使用,只需要了 ...

  10. AsyncHttpClient来完成网页源代码的显示功能,json数据在服务器端的读取还有安卓上的读取

    一.使用AsyncHttpClient来完成网页源代码的显示功能: 首先.我们引入 步骤: 1.添加网络权限 2.判断网页地址是否为空 3.不为空的情况下创建客户端对象 4.处理get/post请求 ...