Audio and video series 3: log printing of ffmpeg

Posted by Colleen78 on Tue, 30 Nov 2021 23:21:07 +0100

title: audio and video series 3: log printing of ffmpeg
categories:[ffmpeg]
tags: [audio and video programming]
date: 2021/11/27

< div align = 'right' > Author: Hackett < / div >

<div align ='right'> WeChat official account: overtime apes </div>

In the last article Visual studio 2019 integrating ffmpeg hello world In, we have configured the development environment of visual studio, and then continue to learn the log printing of ffmpeg according to the environment of the previous article;

Log printing plays a decisive role in locating problems or finding bug s.

1, Introduction to FFmpeg print log output

The core function method of FFmpeg log output is: av_log() . Why av_log() is the core function of outputting logs in FFmpeg?

Because we just open an FFmpeg source code file (the source code file needs to go to the official website to download the version with source code), we will find AV everywhere_ Log() function. In general, the source code of FFmpeg class library does not allow the use of printf() function, so all printed outputs use av_log().

2, av_log() function description

av_ The declaration of log () is located in libavutil\log.h. The specific declaration code is as follows:

/**
 * 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 or NULL if general log.
 * @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, const char *fmt, ...) av_printf_format(3, 4);

The first parameter specifies the structure of the log, such as AVFormatContext, AVCodecContext, and so on. The second parameter specifies the level of log, and the third parameter is the content to be output. The following levels are defined in the source code:

/**
 * Print no output.
 */
#define AV_LOG_QUIET    -8

/**
 * Something went really wrong and we will crash now.
 */
#define AV_LOG_PANIC     0

/**
 * Something went wrong and recovery is not possible.
 * For example, no header was found for a format which depends
 * on headers or an illegal combination of parameters is used.
 */
#define AV_LOG_FATAL     8

/**
 * Something went wrong and cannot losslessly be recovered.
 * However, not all future data is affected.
 */
#define AV_LOG_ERROR    16

/**
 * Something somehow does not look correct. This may or may not
 * lead to problems. An example would be the use of '-vstrict -2'.
 */
#define AV_LOG_WARNING  24

/**
 * Standard information.
 */
#define AV_LOG_INFO     32

/**
 * Detailed information.
 */
#define AV_LOG_VERBOSE  40

/**
 * Stuff which is only useful for libav* developers.
 */
#define AV_LOG_DEBUG    48

/**
 * Extremely verbose debugging, useful for libav* development.
 */
#define AV_LOG_TRACE    56

#define AV_LOG_MAX_OFFSET (AV_LOG_TRACE - AV_LOG_QUIET)

As can be seen from the definition, AV_ The log levels of log() are:

AV_LOG_PANIC,AV_LOG_FATAL,AV_LOG_ERROR,AV_LOG_WARNING,AV_LOG_INFO,AV_LOG_VERBOSE,AV_LOG_DEBUG,AV_LOG_TRACE.

The value defined for each level represents the severity, and the smaller the value, the more serious it is.

Default AV_ The level of log() output is AV_LOG_INFO.

3, Set / get log output level

Above, we talk about AV_ The Log() function can set the level of Log content. For the output Log content, we can also set the level. FFmpeg provides av_log_set_level() is used to set the level of the current Log, av_log_get_level is used to get the level of the current Log.

av_ log_ set_ The level function is declared as follows:

/**
 * Set the log level
 *
 * @see lavu_log_constants
 *
 * @param level Logging level
 */
void av_log_set_level(int level);

av_ log_ set_ The level function is declared as follows:

/**
 * Get the current log level
 *
 * @see lavu_log_constants
 *
 * @return Current log level
 */
int av_log_get_level(void);

4, Log output practice

Through the following code, we can understand the log output and the logic of setting the log output level.

#include <iostream>

extern "C"{
#include "libavutil/log.h"
}

int main(int argc, char* argv[]) {
    av_log_set_level(AV_LOG_DEBUG); //Set log level
    av_log(NULL, AV_LOG_DEBUG, "hello world log"); //Print log
    printf("av_log_get_level: %d\n",av_log_get_level());
    system("pause"); //Window waiting
    return 0;
}

5, Custom FFmpeg log output

Check the implementation source code of ffmpeg log. You can find that av_log() called av_vlog(),av_log() calls a function pointer av_log_callback. av_log_callback is a global static variable, which is defined as follows:

static void (*av_log_callback)(void*, int, const char*, va_list) = av_log_default_callback;

As you can see from the code, AV_ Log_ The callback pointer points to a function AV by default_ Log_ default_ callback(). av_log_default_callback() is the default Log function of FFmpeg.

Note that this Log function can be customized. After defining a custom function according to the specified parameters, you can use another API function AV of FFmpeg_ Log_ set_ Callback() is set as the Log function.

View the source code, you can see AV_ log_ set_ The statement of callback() is as follows:

/**
 * 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));

It can be seen from the declaration that a function with a parameter of (void, int, const char, va_list) and a return value of void needs to be specified as the Log function.

View av_log_set_callback() source code. It can be seen that this method only does a function pointer assignment. The code is as follows:

void av_log_set_callback(void (*callback)(void*, int, const char*, va_list)) {
    av_log_callback = callback;
}

So we can customize a my_ The logoutput() function is used as the output function of Log:

void my_log_printf(void* ptr, int level, const char* fmt,va_list vl){
    ellipsis...
}

After editing the function, use AV_ Log_ set_ The callback() function can be set as a Log output function.

av_log_set_callback(my_log_printf);

The following is the example source code of custom log output:

#include<iostream>
using namespace std;

extern "C" {//Include C header file
#include "libavutil/log.h" 
};

void my_log_printf(void* ptr, int level, const char* fmt, va_list vl) {
    printf("my_log_printf enter! Content : %s\nlog level : %d\n", fmt, level);
}

int main(int argc, char* argv[]) {

    av_log_set_level(AV_LOG_DEBUG); //Set log level
    av_log_set_callback(my_log_printf);  // Set custom log output method
    av_log(NULL, AV_LOG_DEBUG, "hello world log"); //Print log

    system("pause"); //Window waiting
    return 0;
}

If you think the article is good, you can give it a "three company"

I'm an overtime ape. I'll see you next time

Topics: ffmpeg