如何开启ffmpeg库中的日志

2.  在C++类中,实现ffmpeg库日志的打开

// ffmpeg_sdk.h
#pragma once

#include <stdio.h>
#include <stdlib.h>
                                                                                                                                                                                         
#ifdef __cplusplus
extern "C" {
#endif

#include "libavutil/imgutils.h"
#include "libavutil/opt.h"
#include "libavcodec/avcodec.h"
#include "libavutil/mathematics.h"

#include "libavutil/log.h"

#ifdef __cplusplus
}
#endif

class FFmpegSDK{
public:
FFmpegSDK();
~FFmpegSDK();

public:
#define LOG_BUF_PREFIX_SIZE 512
#define LOG_BUF_SIZE 1024
    static char libffmpeg_log_buf_prefix[LOG_BUF_PREFIX_SIZE];                                                                                                                           
    static char libffmpeg_log_buf[LOG_BUF_SIZE];        
    static void libffmpeg_log_callback(void *ptr, int level, const char *fmt, va_list vl);
}



/* ffmpeg_sdk.cpp*/
char FFmpegSDK::libffmpeg_log_buf_prefix[LOG_BUF_PREFIX_SIZE];
char FFmpegSDK::libffmpeg_log_buf[LOG_BUF_SIZE];

void FFmpegSDK::libffmpeg_log_callback(void *ptr, int level, const char *fmt, va_list vl){

    int cnt;        
    memset(libffmpeg_log_buf_prefix, 0, LOG_BUF_PREFIX_SIZE);
    memset(libffmpeg_log_buf, 0, LOG_BUF_SIZE);

    cnt = snprintf(libffmpeg_log_buf_prefix, LOG_BUF_PREFIX_SIZE, "%s", fmt);        
    cnt = vsnprintf(libffmpeg_log_buf, LOG_BUF_SIZE, libffmpeg_log_buf_prefix, vl);        

    printf("%s", libffmpeg_log_buf);
    return;
}

int main(){

    /* Init ffmpeg log */
    ffmpeg_log_callback pcb_log = libffmpeg_log_callback;                                                                                                                                
    av_log_set_level(AV_LOG_DEBUG);
    av_log_set_flags(AV_LOG_SKIP_REPEATED);
    av_log_set_callback(pcb_log);
    
    printf("Current ffmpeg log_level = %d\n", av_log_get_level());

   。。。
}

 

1. 在示例代码环境中打开库日志并输出

ENV:

/opt/ffmpeg/ffmpeg-3.2.4

ffmpeg的示例代码位于:/opt/ffmpeg/ffmpeg-3.2.4-examples/examples

选择原型程序: transcode_aac

1.1 如何打开日志

#include "libavutil/log.h"

static FILE *fp_log;

#define LOG_BUF_PREFIX_SIZE 512
#define LOG_BUF_SIZE 1024
static char logBufPrefix[LOG_BUF_PREFIX_SIZE];
static char logBuffer[LOG_BUF_SIZE];
static pthread_mutex_t cb_av_log_lock;

typedef void (*ffmpeg_log_callback)(void *ptr, int level, const char *fmt, va_list vl);

static void log_callback_null(void *ptr, int level, const char *fmt, va_list vl){
    FILE *fp = (FILE*)fp_log;
    int cnt;    
    pthread_mutex_lock(&cb_av_log_lock);    
    cnt = snprintf(logBufPrefix, LOG_BUF_PREFIX_SIZE, "%s", fmt);    
    cnt = vsnprintf(logBuffer, LOG_BUF_SIZE, logBufPrefix, vl);    
    fprintf(fp, "%s", logBuffer);    
    fflush(fp);    
    pthread_mutex_unlock(&cb_av_log_lock);
}



int main(int argc char* argv){
// initialize log    
/* Init log_callback_null */
fp_log = fopen("debug.log", "w+");    
if ( NULL == fp_log){        
    printf("cant open log file %s\n", "debug.log");        
    return 0;    
}    
ffmpeg_log_callback fptrLog = log_callback_null;    
/* END */
av_log_set_level(AV_LOG_DEBUG);    
av_log_set_flags(AV_LOG_SKIP_REPEATED);    
av_log_set_callback(fptrLog);


printf("Current log_level = %d\n",av_log_get_level());
...
}

1.2. Makefile修改

修改后的Makefile如下:

#####

#

INCLUDES :=../ffmpeg-3.2.4/include/

CFLAGS := -Wall -g -o0 -fPIC

CFLAGS += $(addprefix -I, $(INCLUDES))

#

FFMPEG_LIBS= avdevice \

avformat \

avfilter \

avcodec \

swresample \

swscale \

avutil \

 

LIBDIR := ../ffmpeg-3.2.4/lib/

LIBS := $(FFMPEG_LIBS)

LDLIBS := $(addprefix -L,$(LIBDIR)) $(addprefix -l,$(LIBS)) -lm -lpthread -ldl -lrt

 

EXAMPLES= avio_dir_cmd \

avio_reading \

decoding_encoding \

demuxing_decoding \

extract_mvs \

filtering_video \

filtering_audio \

http_multiclient \

metadata \

muxing \

remuxing \

resampling_audio \

scaling_video \

transcode_aac \

transcode_aac_openliblog \

transcoding \

transcode_aac \

transcode_aac_openliblog \

transcoding \

 

OBJS=$(addsuffix .o,$(EXAMPLES))

 

.phony: all clean-test clean

 

all: $(OBJS) $(EXAMPLES)

 

clean-test:

$(RM) test*.pgm test.h264 test.mp2 test.sw test.mpg

 

clean: clean-test

$(RM) $(EXAMPLES) $(OBJS)

 

1.3. 运行命令:

./transcode_aac_openliblog ../test-samples/out-audio-1-jzaff2d9b383f94241992e4214e5dd1f5a-4-3288369-f-1514429532736-t-1514429648756.mp4 ../test-samples/transcode-aac-out-audio-1-jzaff2d9b383f94241992e4214e5dd1f5a-4-3288369-f-1514429532736-t-1514429648756.mp4

 

2. 原理:

先见libavutil/log.h的函数声明,从代码可见,ffmpeg库的日志使用的回调机制;

/**

* Get the current log level

* @see lavu_log_constants

* @return Current log level

*/

int av_log_get_level(void);

 

/**

* Set the log level

* @see lavu_log_constants

* @param level Logging level

*/

void av_log_set_level(int level);

 

/**

* Set the logging callback

* @note The callback must be thread safe, even if the application does not use

* threads itself as some codecs are multithreaded.

* @see av_log_default_callback

* @param callback A logging function with a compatible signature.

*/

void av_log_set_callback(void (*callback)(void*, int, const char*, va_list));

 

C语言的回调机制:

回调函数实现的机制是

1)定义一个回调函数;

2)提供函数实现的一方在初始化的时候,将回调函数的函数指针注册给调用者;

3)当特定的事件或条件发生的时候,调用者使用函数指针调用回调函数对事件进行处理。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

北雨南萍

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

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

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

打赏作者

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

抵扣说明:

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

余额充值