开始分析源码之前的想法
- 在开始分析一个源码的时候,我所想到的第一件事情,就是看看文件夹结构,然后找到被封装的打印函数,没错就是printf helloworld。当然,像ffmpeg这种c语言项目,感觉是肯定会封装自己的打印函数(不可能这都没有吧),还有可能像linux内核里面一样,搞一个log系统,然后设置一个打印级别。如果没有这些东西,那我就应该去找一些ffmpeg应用程序的源码,看看有什么重要的结构体,那个里面应该封装了大量的音视频处理相关信息。
找到log系统
-
由于我目前的工作环境是win,就不能用grep * *printf* * -nR这种命令找printf的封装函数了, 我先是用listary在ffmpeg的封装目录里面搜索有没有printf相关的文件,没有,再搜索log,找到了,log.h,位于libavutil,等会百度搜搜这些文件夹都是干啥的。现在暂时不搞,不然看了也记不住。
-
打开log.h一看,好家伙,一大堆宏,看不懂,一个AVClass,好家伙根本看不懂,接着下面就是一系列的宏。
好家伙终于找到有点熟悉的东西了,log函数和log级别函数。
log日志系统分析
1.日志级别
下面是宏定义,可以看出日志系统的级别宏,数值越小,警告级别越高,能打印出来的消息越少。
(这样,能大致猜想出,log函数的源码,里有一系列的宏定义,如果当前系统设置的打印级别大于log函数里面的宏,就用printf打印出空,如果小于,就把log的字符传参打印出来。
#define AV_LOG_QUIET -8
#define AV_LOG_PANIC 0
#define AV_LOG_FATAL 8
#define AV_LOG_ERROR 16 //错误
#define AV_LOG_WARNING 24 //警告
#define AV_LOG_INFO 32
#define AV_LOG_VERBOSE 40
#define AV_LOG_DEBUG 48 //调试
#define AV_LOG_TRACE 56
2.设置日志级别和log函数
-
当前的系统需要一个打印标准,高于标准就能打印,低于就不能。在头文件里面找到了log级别读取和设置函数:
void av_log_set_level(int level);
和int av_log_get_level(void);
设置级别函数的传参为上面的 log级别宏。
-
log函数是一个变参函数,在默认情况下,所有信息被发送进stderr,可以利用log回调函数来改变这个行为。
void av_log(void *avcl, int level, const char *fmt, ...) av_printf_format(3, 4);
@param avcl: 这个传参是任意一个结构体指针,但是这个结构体的第一各成员必须是AVClass,如果是普通log,就传NULL。
@param level: log 级别宏
@fmt,变参,和printf一样,"%s",xxx
-
这些函数的定义大概我能想出来啥样,而且跟音视频是没多大关系,以后再搞,不然耽误分析流程。
3. 例子
示例代码如下,代码比较简单:
#include "stdafx.h"
#define __STDC_CONSTANT_MACROS
extern "C"
{
#include "libavutil\log.h"
}
int main(int argc, char *argv[])
{
char *input = "hello world";
av_log(NULL, AV_LOG_INFO, "Hello world ,this is a test,input is %s",input);
getchar(); //暂停
return 0;
}