Before more or less contact with some codec parameters, CRF parameters are also used, but recently when chatting with friends, when it comes to using FFMPEG encountered in the process of CRF parameters, and the function of the specific process, before this, there has been no tracking, no detailed records, so lift his curiosity, he decided to clear it, Then began the magical journey of CRF. CRF introduction:

CRF (Constant Rate Factor) is an encoding mode that adjusts the file data Rate up or down to a selected level of quality, rather than a specific data Rate.

If you want to maintain the best quality without worrying too much about file size, you can use CRF rate control mode. This is the recommended rate control mode for most cases. When the size of the output file is not important, this method allows the encoder to attempt to achieve the desired file output of the desired video quality for the entire file, i.e., the maximum video compression efficiency with the desired video quality can be achieved with one encoding. The main principle of CRF mode is to dynamically adjust the QP value of each frame of video in the process of coding so as to obtain and maintain the required video quality level bit rate.

But CRF has the disadvantage of not being able to tell the encoder to expect a file of a certain size or not exceeding a certain size or bit rate. It should also be noted that CRF is not recommended to be directly used to 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 practical demonstration

Using FFMPEG binaries to try compression with parameter CRF, as shown below:

FFMPEG uses CRF 18, 24 respectively for compression, and comparison with the source file.

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

In actual transcoding

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

Run ffmpeg -i test.mp4 -c:v libx264-crf 24 test24.mp4 to convert CRF=24. The result is as follows:

After transcoding, check the parameters of the three files respectively and make a comparison. The results are shown in the figure below:

The above parameters can only roughly understand the basic information of three videos. Then, the direct view of the cause of the change can be viewed by professional tool Elecard Eye, and the code stream analysis results of three files are as follows:

The comparison of the three documents is summarized as follows:

It can be seen that the CRF parameter is used, the number of I frames is sharply reduced, while B frames are introduced. Entropy encoding uses CABAC mode, so the compression rate is increased a lot, the file size is smaller. At the same time, with the increase of CRF value, the compression rate of P frame and B frame also increases, and the file is smaller. CRF code reads

Although I’ve walked through the FFMPEG code before, I haven’t been fully aware of the CRF parameters. In order not to understand the problem, or force yourself to go through the code, enhance the impression, deep understanding, but also for the care of the parameters of the small partners lay a foundation. * CRF definition

First we can see the definition of this value in X264:

typedef struct X264Context { AVClass *class; x264_param_t params; . float crf; . }Copy the code

The definition in AVOption is 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 },
......
}
Copy the code

CRF still belongs to the Rate control, so we can see its RC definition as follows:

#define X264_RC_CQP                  0
#define X264_RC_CRF                  1
#define X264_RC_ABR                  2
Copy the code

•FFMPEG interface combing

Involves FFMPEG code walking part too much, in this just briefly describes the corresponding part of CRF, other coding and decoding process we can complete according to the other big god on the Internet code walking process. X264 codec entry conforms to FFMPEG interface definition, as shown in the following figure:

Borrow the thor a picture show here: (https://blog.csdn.net/leixiaohua1020/article/details/45960409)

  • X264_init()

The X264_init function passes the options assigned and initialized to libx264 to initialize X264 parameters and assign RC parameters. These values are passed in from AVCodecContext, and the default value for X264Context. For those familiar with FFMPEG, AVCodecContext contains the input command line codec option values and the FFMPEG command contains the option values, while X264Context contains x264 options. The combination of the two forms a complete X264 codec option value.

At the end of X264_init, the OPEN action of X264Codec is performed, along with the action of encoding the global header.

  • x264_param_default

X264_param_default Sets the default parameters, including other option values. Only CRF options are concerned here. X264_param_default turns CRF on by default and sets the CRF option f_RF_constant to 23, which is why many other articles use the default 23.

Also notice that in the x264_param_default default parameter, the B frame is set to be juxtaposed again and cabAC is turned on by default. Therefore, if the FFMPEG bin file is transcoded out of the file cabAC is enabled by default, which is also the root cause of the occurrence of CABAC and the increase of B frame in the tool side view.

  • x264_encoder_open

After initializing the parameters, the init function then performs x264_encoder_open(the relevant code is located in encoder\encoder.c), which opens the h264-related encoder in X264.

After that, x264_encoder_open is mainly used to open the encoder, which verifies and initializes various variables required by libx264 coding, and completes the initialization of SPS, PPS and QM.

  • validate_parameters

Calling validate_parameters validates the input parameters to prevent coding failures caused by input parameter anomalies. Check, update, and assign CRF parameters in this function.

For other parts of the process, please refer to the articles of other gods. X264 source code simple analysis: encoder trunk part -1_ Lei Xiaohua (Leixiaohua1020) column -CSDN blog

  • x264_ratecontrol_new

X264_encoder_open finally calls x264_ratecontrol_new to initialize the bit-rate control-related variables.

X264_ratecontrol_new is used to set the core parameter of bit ratecontrol.

X264_ratecontrol_new sets b_abr to 1, b_2pass to 0, and b_stat_read to 0. That is, the CRF mode is abR, not 2-pass, in rate_control.

In the X264_ratecontrol_init_re64x function, the VBV parameters are initialized and the base_cplx and rate_factor_constant parameters of CRF are updated.

At the same time, when the x264_ratecontrol_init_re64x is called, the parameter b_init=1 is passed in, and CRF sets the VBV mode, which provides a platform for rate_control.

  • X264_frame

X264_frame() is used to encode a complete frame of video data according to the incoming packet data. The partial definition of this function is shown below.

  • reconfig_encoder

The main function of reconfig_encoder is to compare rC-related parameters with parameters in AVCodecContext and reconfigure the encoder if they are inconsistent. For example, if the CRF value is initially set to 24 but the COMMAND line value is set to 18, the two values are inconsistent. In this case, you need to assign the value according to the command line value and reconfigure the encoder to meet the user’s expectation. The specific configuration is good to have a brief look, not to expand here.

  • x264_encoder_encode

X264_encoder_encode is the beginning of real encoding. In the function x264_encoder_encode, a complete YUV image is encoded into H264 video stream. This process can be referred to Thor’s article. Blog.csdn.net/leixiaohua1…

What we care about here is part of the content involved in CRF. In X264_encoder_encode, the content related to bit rate control is mainly the following interface:

X264_thread_sync_ratecontrol () :

X264_ratecontrol_zone_init () :

X264_ratecontrol_start () : enables bit ratecontrol for each frame. In x264_ratecontrol_start, different QPS are selected for compression according to different bit ratecontrol modes. According to the previous analysis, CRF belongs to ABR mode, and B frames are added, so the QP of each frame is different, so the size of the encoded file cannot be determined under the condition of the same quality after compression.

X264_ratecontrol_qp () :

Bit rate control is a large part of the content, the design of the algorithm is also more complex, this paper only focuses on how to convert CRF mode to VBV mode, as well as some parameters affecting the coding, the whole process of the next article we will analyze and track.

The above is some personal views, there may be incorrect places, welcome to discuss learning together.

If this article is helpful to you, welcome to like, favorites, forward, follow, continue to update the audio and video related content next.