Audio and video codec — coding parameter CRF

Time:2022-5-11

Audio and video codec -- coding parameter CRF

I have been in contact with some codec parameters and CRF parameters before, but recently, when chatting with my friends, I talked about the CRF parameters and specific action process in the process of using ffmpeg. This has not been tracked or recorded in detail before, so I was curious, so I decided to find out and started this magical journey of CRF. Introduction to CRF:

Constant rate factor (CRF) is an encoding mode that can adjust the file data rate up or down to reach the selected quality level instead of a specific data rate.

If you want to maintain the best quality without worrying about file size, you can use CRF rate control mode. This is the recommended rate control mode in most cases. When the size of the output file is less important, this method allows the encoder to try to achieve the file output of the desired target video quality for the whole file, that is, the so-called one-time coding can obtain the maximum video compression efficiency under the expected video quality. The main principle of CRF mode is to dynamically adjust the QP value of each frame of video in the coding process, so as to obtain the bit rate to maintain the required video quality level.

However, the disadvantage of CRF is that it cannot tell the encoder that it expects to obtain a file of a specific size or not exceed a specific size or bit rate. At the same time, it should be noted that when CRF is adopted, it is not recommended to directly encode video for streaming media transmission.

Two rate control modes are generally recommended: constant rate factor (CRF) or 2-pass ABR. Rate control determines how many bits will be used per frame. This determines the file size and how the quality is allocated. CRF practice demonstration

Try to compress with parameter CRF through ffmpeg binary file, as shown in the following figure:

Ffmpeg is compressed with CRF of 18 and 24 respectively, and compared with the source file.

ffmpeg -i test.mp4 -c:v libx264 -crf 18 test18.mp4

Audio and video codec -- coding parameter CRF

Actual transcoding

Audio and video codec -- coding parameter CRF

After transcoding, specific coding related information will be displayed, including ref, CRF value, QP quantization step, and the proportion of I frame, P frame and B frame. It also contains audio related information, as shown in the figure below:

Audio and video codec -- coding parameter CRF

Use the command ffmpeg – I test mp4 -c:v libx264 -crf 24 test24. MP4, transcoding CRF = 24. The transcoding results are shown in the figure below:

Audio and video codec -- coding parameter CRF

After transcoding, the parameters of the three files are checked and compared. The results are shown in the following figure:

Audio and video codec -- coding parameter CRF

The above parameters can only roughly understand the basic information of three videos, and then view the visual diagram of the causes of the change through the professional tool elecard eye. The analysis results of three file bitstreams are as follows:

Audio and video codec -- coding parameter CRF

The comparison of the three documents is summarized as follows:

Audio and video codec -- coding parameter CRF

It can be seen that with the use of CRF parameters, the number of I frames decreases sharply and B frames are introduced at the same time; Entropy coding adopts CABAC mode, which improves the compression rate and reduces the file size. At the same time, as the CRF value increases, the compression ratio of P frame and B frame also increases, and the file is smaller. CRF code day reading

Although I have read ffmpeg code before, I haven’t fully noticed the reading of specific CRF parameters. In order not to understand the problem with a little knowledge, or force yourself to go through the code, enhance your impression and deep understanding, and lay the foundation for the little partners who care about the parameter. * • CRF definition

First, you can see the definition of this value in x264:

typedef struct X264Context {
    AVClass        *class;
    x264_param_t    params;
    ......

    float crf;

    ......
    }

The specific definitions in avoption are as follows:

static const AVOption options[] = {
    { "preset",        "Set the encoding preset (cf. x264 --fullhelp)",   OFFSET(preset),        AV_OPT_TYPE_STRING, { .str = "medium" }, 0, 0, VE},
    { "tune",          "Tune the encoding params (cf. x264 --fullhelp)",  OFFSET(tune),          AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE},
    { "profile",       "Set profile restrictions (cf. x264 --fullhelp) ", OFFSET(profile),       AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE},
......
    {"x264opts", "x264 options", OFFSET(x264opts), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, VE},
    { "crf",           "Select the quality for constant quality mode",    OFFSET(crf),           AV_OPT_TYPE_FLOAT,  {.dbl = -1 }, -1, FLT_MAX, VE },
    { "crf_max",       "In CRF mode, prevents VBV from lowering quality beyond this point.",OFFSET(crf_max), AV_OPT_TYPE_FLOAT, {.dbl = -1 }, -1, FLT_MAX, VE },
......
}

CRF still belongs to one of rate control, so you can see its RC related definitions as follows:

#define X264_RC_CQP                  0
#define X264_RC_CRF                  1
#define X264_RC_ABR                  2

• ffmpeg interface

Audio and video codec -- coding parameter CRF

There are too many parts related to ffmpeg code day reading. Here is just a brief description of the corresponding part of CRF. Other codec processes can be completed according to the code day reading processes of other great gods on the Internet. This article assumes that you have enough foundation: the codec entry of x264 complies with the definition of ffmpeg interface, and the corresponding relationship is shown in the following figure:

A picture of Raytheon is used here to illustrate:( https://blog.csdn.net/leixiaohua1020/article/details/45960409 )

Audio and video codec -- coding parameter CRF

  • X264_init()

X264_ The init function is mainly used to transfer the previously assigned and initialized option values to libx264 module in turn for x264 parameter initialization and RC parameter assignment. These values are passed from AVCodecContext and the default values of x264context. People familiar with ffmpeg know that AVCodecContext contains the codec option value in the input command line and the option value contained in ffmpeg command, while x264context contains x264 related options. The combination of the two constitutes a complete x264 codec option value.

Audio and video codec -- coding parameter CRF

In x264_ At the end of init, open the x264codec and encode the global header.

Audio and video codec -- coding parameter CRF

  • x264_param_default

x264_ param_ Default sets default parameters, including other option values. Only CRF related options are concerned here. x264_ param_ Default will enable CRF by default, and set the CRF option F_ rf_ Constant is set to 23, which is why the default value of 23 is mentioned in many other articles.

Also note that at x264_ param_ In the default parameter, frame B is set and set again, and CABAC is on by default. Therefore, if CABAC is turned on by default in the file transcoded with ffmpeg bin file, this is also the fundamental reason for the appearance of CABAC and the addition of B frames when viewing on the tool side.

Audio and video codec -- coding parameter CRF

  • x264_encoder_open

After initializing the specific parameters, the init function proceeds to x264_ encoder_ Open (the relevant code is located in encoder \ encoder. C). At this time, it will be specifically opened to the H264 encoder in x264.

Audio and video codec -- coding parameter CRF

Then in x264_ encoder_ Open is mainly used to open the encoder, which verifies and initializes various variables required for libx264 coding, and completes the initialization of SPS, PPS and QM.

  • validate_parameters

Call validate_ Parameters will verify the input parameters to prevent coding failure caused by abnormal input parameters. This function completes the verification, update and assignment of CRF related parameters.

Audio and video codec -- coding parameter CRF

Other process parts can refer to the articles of other great gods, and will not be described again. (Raytheon’s analysis is very detailed. Please worship it and simply analyze the x264 source code: the main part of the encoder -1_; Lei Xiaohua’s column CSDN blog)

  • x264_ratecontrol_new

x264_ encoder_ Open finally calls x264_ ratecontrol_ New completes the initialization of rate control related variables.

Audio and video codec -- coding parameter CRF

x264_ ratecontrol_ New, which mainly sets the core parameters of rate control. You need to have a better understanding of x264 rate control to really understand it, otherwise it will be easy to get dizzy.

x264_ ratecontrol_ The new function is based on the CRF mode and B_ stat_ The default value of read is 0, and then B_ The ABR parameter is set to 1, and B_ 2pass is set to 0, that is, the CRF mode is at rate_ In control, it is processed according to ABR and non-2-pass.

Audio and video codec -- coding parameter CRF

In x264_ ratecontrol_ init_ The reconfigurable function initializes VBV parameters and CRF related parameters_ cplx、rate_ factor_ Constant update.

Audio and video codec -- coding parameter CRF

Simultaneous x264_ ratecontrol_ init_ When the setting in reconfigurable is called, B is passed in_ Init = 1. At this time, CRF sets the VBV mode to the subsequent rate_ Control paved the way.

Audio and video codec -- coding parameter CRF

  • X264_frame

X264_ Frame () is used to completely encode a frame of video data according to the incoming packet data. The function part is defined as follows.

Audio and video codec -- coding parameter CRF

  • reconfig_encoder

reconfig_ The main function of encoder is to compare RC related parameters with those in AVCodecContext. If they are inconsistent, reconfigure the encoder. For example, the CRF value is initially set to 24, but it is set to 18 on the command line. At this time, the two values are inconsistent. You need to assign a value according to the median value on the command line and reconfigure the encoder to meet the user’s expectations. Just have a brief look at the specific configuration. It will not be expanded here.

  • x264_encoder_encode

Audio and video codec -- coding parameter CRF

x264_ encoder_ Encode is the beginning of real coding, in x264_ encoder_ The encode function encodes a complete YUV image into an H264 video stream. For this process, please refer to Raytheon’s article. The analysis is very good, https://blog.csdn.net/leixiao…

Audio and video codec -- coding parameter CRF

We are concerned about some contents involved in CRF, which are in x264_ encoder_ The contents related to bit rate control in encode mainly include the following interfaces:

x264_thread_sync_ratecontrol():

x264_ratecontrol_zone_init():

x264_ ratecontrol_ Start (): enable rate control, and control the rate for each frame. In x264_ ratecontrol_ In start, different QPS will be selected for compression according to different rate control modes. According to the previous analysis, CRF belongs to ABR mode, and B frames are added at the same time, so the QP of each frame image is different. In this way, the file size after coding can not be determined under the condition of the same quality after compression.

Audio and video codec -- coding parameter CRF

x264_ratecontrol_qp():

Rate control is a large part of content, and the designed algorithm is also complex. This paper only focuses on how to convert CRF mode to VBV mode, and some parameters that affect the coding. We will analyze and track the whole process in the next article.

The above are some personal views, which may be incorrect. Welcome to discuss and study together.

If this article is helpful to you, you are welcome to like, collect, forward and follow it. I will continue to update the audio and video related content.