【x264视频编码器应用与实现】五. x264编码参数与初始化


摘要:

本文作为 “x264视频编码器应用与实现” 系列博文的第五篇,主要讨论x264中参数结构及其设置方法。

1. x264参数设置方法的声明

在上节的example.c中,使用了x264_param_default_preset和x264_param_apply_profile两个函数进行参数的设置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int main(int argc, char **argv) {
// ......
/* Get default params for preset/tuning */
if (x264_param_default_preset(&param, "medium", NULL) < 0) {
goto fail;
}

/* Configure non-default params */
param.i_bitdepth = 8;
param.i_csp = X264_CSP_I420;
param.i_width = frame_width;
param.i_height = frame_height;
param.b_vfr_input = 0;
param.b_repeat_headers = 1;
param.b_annexb = 1;

/* Apply profile restrictions. */
result = x264_param_apply_profile(&param, "high");
if (result < 0) {
goto fail;
}
// ......
}

其中,x264_param_default_preset 和 x264_param_apply_profile 的实现将在后续小节中详述。

在头文件x264.h的注释说明中,x264定义了多个初始化以及设置参数的方法。其中具体可以分为两类,其一为基本参数设置方法,其声明如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/****************************************************************************
* Basic parameter handling functions
****************************************************************************/

/* x264_param_default:
* fill x264_param_t with default values and do CPU detection */
void x264_param_default( x264_param_t * );

/* x264_param_parse:
* set one parameter by name.
* returns 0 on success, or returns one of the following errors.
* note: BAD_VALUE occurs only if it can't even parse the value,
* numerical range is not checked until x264_encoder_open() or
* x264_encoder_reconfig().
* value=NULL means "true" for boolean options, but is a BAD_VALUE for non-booleans. */
#define X264_PARAM_BAD_NAME (-1)
#define X264_PARAM_BAD_VALUE (-2)
int x264_param_parse( x264_param_t *, const char *name, const char *value );

其二为高级参数设置方法,其声明如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/****************************************************************************
* Advanced parameter handling functions
****************************************************************************/

/* These functions expose the full power of x264's preset-tune-profile system for
* easy adjustment of large numbers of internal parameters.
*
* In order to replicate x264CLI's option handling, these functions MUST be called
* in the following order:
* 1) x264_param_default_preset
* 2) Custom user options (via param_parse or directly assigned variables)
* 3) x264_param_apply_fastfirstpass
* 4) x264_param_apply_profile
*
* Additionally, x264CLI does not apply step 3 if the preset chosen is "placebo"
* or --slow-firstpass is set. */

/* x264_param_default_preset:
* The same as x264_param_default, but also use the passed preset and tune
* to modify the default settings.
* (either can be NULL, which implies no preset or no tune, respectively)
*
* Currently available presets are, ordered from fastest to slowest: */
static const char * const x264_preset_names[] = { "ultrafast", "superfast", "veryfast", "faster", "fast", "medium", "slow", "slower", "veryslow", "placebo", 0 };

/* The presets can also be indexed numerically, as in:
* x264_param_default_preset( &param, "3", ... )
* with ultrafast mapping to "0" and placebo mapping to "9". This mapping may
* of course change if new presets are added in between, but will always be
* ordered from fastest to slowest.
*
* Warning: the speed of these presets scales dramatically. Ultrafast is a full
* 100 times faster than placebo!
*
* Currently available tunings are: */
static const char * const x264_tune_names[] = { "film", "animation", "grain", "stillimage", "psnr", "ssim", "fastdecode", "zerolatency", 0 };

/* Multiple tunings can be used if separated by a delimiter in ",./-+",
* however multiple psy tunings cannot be used.
* film, animation, grain, stillimage, psnr, and ssim are psy tunings.
*
* returns 0 on success, negative on failure (e.g. invalid preset/tune name). */
int x264_param_default_preset( x264_param_t *, const char *preset, const char *tune );

/* x264_param_apply_fastfirstpass:
* If first-pass mode is set (rc.b_stat_read == 0, rc.b_stat_write == 1),
* modify the encoder settings to disable options generally not useful on
* the first pass. */
void x264_param_apply_fastfirstpass( x264_param_t * );

/* x264_param_apply_profile:
* Applies the restrictions of the given profile.
* Currently available profiles are, from most to least restrictive: */
static const char * const x264_profile_names[] = { "baseline", "main", "high", "high10", "high422", "high444", 0 };

/* (can be NULL, in which case the function will do nothing)
*
* Does NOT guarantee that the given profile will be used: if the restrictions
* of "High" are applied to settings that are already Baseline-compatible, the
* stream will remain baseline. In short, it does not increase settings, only
* decrease them.
*
* returns 0 on success, negative on failure (e.g. invalid profile name). */
int x264_param_apply_profile( x264_param_t *, const char *profile );

在高级参数设置的注释中,还对设置参数的顺序进行了说明,即在设置的时候,函数的调用需依照下列顺序:

  1. x264_param_default_preset:设置preset和tune;
  2. 自定义参数,即直接对x264_param_t结构的成员赋值;
  3. x264_param_apply_fastfirstpass:加速1st pass的编码;
  4. x264_param_apply_profile:设置编码的profile;

另外,如果preset选择了“placebo”模式或设置了–slow-firstpass,那么第三步将不会执行。


2. x264初始化和设置方法实现

在example.c中使用了 x264_param_default_preset 实现了参数结构的初始化并设置了 profile 和 tune 参数。其实现在 base.c 文件中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
static int param_default_preset( x264_param_t *param, const char *preset, const char *tune )
{
param_default( param );

if( preset && param_apply_preset( param, preset ) < 0 )
return -1;
if( tune && param_apply_tune( param, tune ) < 0 )
return -1;
return 0;
}

int x264_param_default_preset( x264_param_t *param, const char *preset, const char *tune )
{
return x264_stack_align( param_default_preset, param, preset, tune );
}

声明中另一个的基本参数设置方法 x264_param_default 的实现为:

1
2
3
4
void x264_param_default( x264_param_t *param )
{
x264_stack_align( param_default, param );
}

从上述实现可知, x264_param_default_preset 实际上就是先调用了 x264_param_default 进行初始化设置,然后再用 param_apply_preset 和 param_apply_tune 设置 preset 和 tune。

3. x264的参数结构和默认设置

在运行x264的过程中所用到的参数都保存于一个名为 x264_param_t 的结构中。由于包含大量的数据,该结构的定义十分庞大,具体的定义内容在最后一节。x264_param_t 结构中参数的分类主要有以下类别:

  1. CPU标识位:说明cpu架构、线程并行等属性;
  2. 视频属性:如图像宽高、颜色空间等;
  3. HRD和vui参数;
  4. 码流参数;
  5. 输出日志参数;
  6. 编码分析参数;
  7. 码率控制相关;
  8. 图像裁切和封装相关参数;
  9. slice编码相关参数;
  10. 回调指针;

无论是调用 x264_param_default_preset 还是直接调用 x264_param_default,最终都会在param_default中为x264_param_t 结构赋值进行初始化。param_default的实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/****************************************************************************
* x264_param_default:
****************************************************************************/
static void param_default( x264_param_t *param )
{
/* */
memset( param, 0, sizeof( x264_param_t ) );

/* CPU autodetect */
param->cpu = x264_cpu_detect();
param->i_threads = X264_THREADS_AUTO;
param->i_lookahead_threads = X264_THREADS_AUTO;
param->b_deterministic = 1;
param->i_sync_lookahead = X264_SYNC_LOOKAHEAD_AUTO;

/* Video properties */
param->i_csp = X264_CHROMA_FORMAT ? X264_CHROMA_FORMAT : X264_CSP_I420;
param->i_width = 0;
param->i_height = 0;
param->vui.i_sar_width = 0;
param->vui.i_sar_height= 0;
param->vui.i_overscan = 0; /* undef */
param->vui.i_vidformat = 5; /* undef */
param->vui.b_fullrange = -1; /* default depends on input */
param->vui.i_colorprim = 2; /* undef */
param->vui.i_transfer = 2; /* undef */
param->vui.i_colmatrix = -1; /* default depends on input */
param->vui.i_chroma_loc= 0; /* left center */
param->i_fps_num = 25;
param->i_fps_den = 1;
param->i_level_idc = -1;
param->i_slice_max_size = 0;
param->i_slice_max_mbs = 0;
param->i_slice_count = 0;
#if HAVE_BITDEPTH8
param->i_bitdepth = 8;
#elif HAVE_BITDEPTH10
param->i_bitdepth = 10;
#else
param->i_bitdepth = 8;
#endif

/* Encoder parameters */
param->i_frame_reference = 3;
param->i_keyint_max = 250;
param->i_keyint_min = X264_KEYINT_MIN_AUTO;
param->i_bframe = 3;
param->i_scenecut_threshold = 40;
param->i_bframe_adaptive = X264_B_ADAPT_FAST;
param->i_bframe_bias = 0;
param->i_bframe_pyramid = X264_B_PYRAMID_NORMAL;
param->b_interlaced = 0;
param->b_constrained_intra = 0;

param->b_deblocking_filter = 1;
param->i_deblocking_filter_alphac0 = 0;
param->i_deblocking_filter_beta = 0;

param->b_cabac = 1;
param->i_cabac_init_idc = 0;

param->rc.i_rc_method = X264_RC_CRF;
param->rc.i_bitrate = 0;
param->rc.f_rate_tolerance = 1.0;
param->rc.i_vbv_max_bitrate = 0;
param->rc.i_vbv_buffer_size = 0;
param->rc.f_vbv_buffer_init = 0.9;
param->rc.i_qp_constant = -1;
param->rc.f_rf_constant = 23;
param->rc.i_qp_min = 0;
param->rc.i_qp_max = INT_MAX;
param->rc.i_qp_step = 4;
param->rc.f_ip_factor = 1.4;
param->rc.f_pb_factor = 1.3;
param->rc.i_aq_mode = X264_AQ_VARIANCE;
param->rc.f_aq_strength = 1.0;
param->rc.i_lookahead = 40;

param->rc.b_stat_write = 0;
param->rc.psz_stat_out = "x264_2pass.log";
param->rc.b_stat_read = 0;
param->rc.psz_stat_in = "x264_2pass.log";
param->rc.f_qcompress = 0.6;
param->rc.f_qblur = 0.5;
param->rc.f_complexity_blur = 20;
param->rc.i_zones = 0;
param->rc.b_mb_tree = 1;

/* Log */
param->pf_log = x264_log_default;
param->p_log_private = NULL;
param->i_log_level = X264_LOG_INFO;

/* */
param->analyse.intra = X264_ANALYSE_I4x4 | X264_ANALYSE_I8x8;
param->analyse.inter = X264_ANALYSE_I4x4 | X264_ANALYSE_I8x8
| X264_ANALYSE_PSUB16x16 | X264_ANALYSE_BSUB16x16;
param->analyse.i_direct_mv_pred = X264_DIRECT_PRED_SPATIAL;
param->analyse.i_me_method = X264_ME_HEX;
param->analyse.f_psy_rd = 1.0;
param->analyse.b_psy = 1;
param->analyse.f_psy_trellis = 0;
param->analyse.i_me_range = 16;
param->analyse.i_subpel_refine = 7;
param->analyse.b_mixed_references = 1;
param->analyse.b_chroma_me = 1;
param->analyse.i_mv_range_thread = -1;
param->analyse.i_mv_range = -1; // set from level_idc
param->analyse.i_chroma_qp_offset = 0;
param->analyse.b_fast_pskip = 1;
param->analyse.b_weighted_bipred = 1;
param->analyse.i_weighted_pred = X264_WEIGHTP_SMART;
param->analyse.b_dct_decimate = 1;
param->analyse.b_transform_8x8 = 1;
param->analyse.i_trellis = 1;
param->analyse.i_luma_deadzone[0] = 21;
param->analyse.i_luma_deadzone[1] = 11;
param->analyse.b_psnr = 0;
param->analyse.b_ssim = 0;

param->i_cqm_preset = X264_CQM_FLAT;
memset( param->cqm_4iy, 16, sizeof( param->cqm_4iy ) );
memset( param->cqm_4py, 16, sizeof( param->cqm_4py ) );
memset( param->cqm_4ic, 16, sizeof( param->cqm_4ic ) );
memset( param->cqm_4pc, 16, sizeof( param->cqm_4pc ) );
memset( param->cqm_8iy, 16, sizeof( param->cqm_8iy ) );
memset( param->cqm_8py, 16, sizeof( param->cqm_8py ) );
memset( param->cqm_8ic, 16, sizeof( param->cqm_8ic ) );
memset( param->cqm_8pc, 16, sizeof( param->cqm_8pc ) );

param->b_repeat_headers = 1;
param->b_annexb = 1;
param->b_aud = 0;
param->b_vfr_input = 1;
param->i_nal_hrd = X264_NAL_HRD_NONE;
param->b_tff = 1;
param->b_pic_struct = 0;
param->b_fake_interlaced = 0;
param->i_frame_packing = -1;
param->i_alternative_transfer = 2; /* undef */
param->b_opencl = 0;
param->i_opencl_device = 0;
param->opencl_device_id = NULL;
param->psz_clbin_file = NULL;
param->i_avcintra_class = 0;
param->i_avcintra_flavor = X264_AVCINTRA_FLAVOR_PANASONIC;
}

4. 指定编码的 profile

无论是从上一节的 param_default 方法,还是x264_param_t结构的定义中,都没有设置编码 profile 的参数。而 x264_param_apply_profile 的实现如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
static int param_apply_profile( x264_param_t *param, const char *profile )
{
if( !profile )
return 0;

const int qp_bd_offset = 6 * (param->i_bitdepth-8);
int p = profile_string_to_int( profile );
if( p < 0 )
{
x264_log_internal( X264_LOG_ERROR, "invalid profile: %s\n", profile );
return -1;
}
if( p < PROFILE_HIGH444_PREDICTIVE && ((param->rc.i_rc_method == X264_RC_CQP && param->rc.i_qp_constant <= 0) ||
(param->rc.i_rc_method == X264_RC_CRF && (int)(param->rc.f_rf_constant + qp_bd_offset) <= 0)) )
{
x264_log_internal( X264_LOG_ERROR, "%s profile doesn't support lossless\n", profile );
return -1;
}
if( p < PROFILE_HIGH444_PREDICTIVE && (param->i_csp & X264_CSP_MASK) >= X264_CSP_I444 )
{
x264_log_internal( X264_LOG_ERROR, "%s profile doesn't support 4:4:4\n", profile );
return -1;
}
if( p < PROFILE_HIGH422 && (param->i_csp & X264_CSP_MASK) >= X264_CSP_I422 )
{
x264_log_internal( X264_LOG_ERROR, "%s profile doesn't support 4:2:2\n", profile );
return -1;
}
if( p < PROFILE_HIGH10 && param->i_bitdepth > 8 )
{
x264_log_internal( X264_LOG_ERROR, "%s profile doesn't support a bit depth of %d\n", profile, param->i_bitdepth );
return -1;
}
if( p < PROFILE_HIGH && (param->i_csp & X264_CSP_MASK) == X264_CSP_I400 )
{
x264_log_internal( X264_LOG_ERROR, "%s profile doesn't support 4:0:0\n", profile );
return -1;
}

if( p == PROFILE_BASELINE )
{
param->analyse.b_transform_8x8 = 0;
param->b_cabac = 0;
param->i_cqm_preset = X264_CQM_FLAT;
param->psz_cqm_file = NULL;
param->i_bframe = 0;
param->analyse.i_weighted_pred = X264_WEIGHTP_NONE;
if( param->b_interlaced )
{
x264_log_internal( X264_LOG_ERROR, "baseline profile doesn't support interlacing\n" );
return -1;
}
if( param->b_fake_interlaced )
{
x264_log_internal( X264_LOG_ERROR, "baseline profile doesn't support fake interlacing\n" );
return -1;
}
}
else if( p == PROFILE_MAIN )
{
param->analyse.b_transform_8x8 = 0;
param->i_cqm_preset = X264_CQM_FLAT;
param->psz_cqm_file = NULL;
}
return 0;
}

int x264_param_apply_profile( x264_param_t *param, const char *profile )
{
return x264_stack_align( param_apply_profile, param, profile );
}

param_apply_profile 所做的工作主要有,首先是对传入的 profile 参数进行判断,主要判别依据有:

  • 传入 profile 参数非法;
  • 指定的 profile 与其他设置冲突;

在一开始进行了6项判断后,最后两部分分别对 BASELINEMAIN profile 进行了参数的设置。因此我们可以知道,x264 默认设置了 HIGH profile,在设置为 BASELINE 和 MAIN profile 时针对部分参数进行修正。


5. x264_param_t 结构的定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
typedef struct x264_param_t
{
/* CPU flags */
unsigned int cpu;
int i_threads; /* encode multiple frames in parallel */
int i_lookahead_threads; /* multiple threads for lookahead analysis */
int b_sliced_threads; /* Whether to use slice-based threading. */
int b_deterministic; /* whether to allow non-deterministic optimizations when threaded */
int b_cpu_independent; /* force canonical behavior rather than cpu-dependent optimal algorithms */
int i_sync_lookahead; /* threaded lookahead buffer */

/* Video Properties */
int i_width;
int i_height;
int i_csp; /* CSP of encoded bitstream */
int i_bitdepth;
int i_level_idc;
int i_frame_total; /* number of frames to encode if known, else 0 */

/* NAL HRD
* Uses Buffering and Picture Timing SEIs to signal HRD
* The HRD in H.264 was not designed with VFR in mind.
* It is therefore not recommendeded to use NAL HRD with VFR.
* Furthermore, reconfiguring the VBV (via x264_encoder_reconfig)
* will currently generate invalid HRD. */
int i_nal_hrd;

struct
{
/* they will be reduced to be 0 < x <= 65535 and prime */
int i_sar_height;
int i_sar_width;

int i_overscan; /* 0=undef, 1=no overscan, 2=overscan */

/* see h264 annex E for the values of the following */
int i_vidformat;
int b_fullrange;
int i_colorprim;
int i_transfer;
int i_colmatrix;
int i_chroma_loc; /* both top & bottom */
} vui;

/* Bitstream parameters */
int i_frame_reference; /* Maximum number of reference frames */
int i_dpb_size; /* Force a DPB size larger than that implied by B-frames and reference frames.
* Useful in combination with interactive error resilience. */
int i_keyint_max; /* Force an IDR keyframe at this interval */
int i_keyint_min; /* Scenecuts closer together than this are coded as I, not IDR. */
int i_scenecut_threshold; /* how aggressively to insert extra I frames */
int b_intra_refresh; /* Whether or not to use periodic intra refresh instead of IDR frames. */

int i_bframe; /* how many b-frame between 2 references pictures */
int i_bframe_adaptive;
int i_bframe_bias;
int i_bframe_pyramid; /* Keep some B-frames as references: 0=off, 1=strict hierarchical, 2=normal */
int b_open_gop;
int b_bluray_compat;
int i_avcintra_class;
int i_avcintra_flavor;

int b_deblocking_filter;
int i_deblocking_filter_alphac0; /* [-6, 6] -6 light filter, 6 strong */
int i_deblocking_filter_beta; /* [-6, 6] idem */

int b_cabac;
int i_cabac_init_idc;

int b_interlaced;
int b_constrained_intra;

int i_cqm_preset;
char *psz_cqm_file; /* filename (in UTF-8) of CQM file, JM format */
uint8_t cqm_4iy[16]; /* used only if i_cqm_preset == X264_CQM_CUSTOM */
uint8_t cqm_4py[16];
uint8_t cqm_4ic[16];
uint8_t cqm_4pc[16];
uint8_t cqm_8iy[64];
uint8_t cqm_8py[64];
uint8_t cqm_8ic[64];
uint8_t cqm_8pc[64];

/* Log */
void (*pf_log)( void *, int i_level, const char *psz, va_list );
void *p_log_private;
int i_log_level;
int b_full_recon; /* fully reconstruct frames, even when not necessary for encoding. Implied by psz_dump_yuv */
char *psz_dump_yuv; /* filename (in UTF-8) for reconstructed frames */

/* Encoder analyser parameters */
struct
{
unsigned int intra; /* intra partitions */
unsigned int inter; /* inter partitions */

int b_transform_8x8;
int i_weighted_pred; /* weighting for P-frames */
int b_weighted_bipred; /* implicit weighting for B-frames */
int i_direct_mv_pred; /* spatial vs temporal mv prediction */
int i_chroma_qp_offset;

int i_me_method; /* motion estimation algorithm to use (X264_ME_*) */
int i_me_range; /* integer pixel motion estimation search range (from predicted mv) */
int i_mv_range; /* maximum length of a mv (in pixels). -1 = auto, based on level */
int i_mv_range_thread; /* minimum space between threads. -1 = auto, based on number of threads. */
int i_subpel_refine; /* subpixel motion estimation quality */
int b_chroma_me; /* chroma ME for subpel and mode decision in P-frames */
int b_mixed_references; /* allow each mb partition to have its own reference number */
int i_trellis; /* trellis RD quantization */
int b_fast_pskip; /* early SKIP detection on P-frames */
int b_dct_decimate; /* transform coefficient thresholding on P-frames */
int i_noise_reduction; /* adaptive pseudo-deadzone */
float f_psy_rd; /* Psy RD strength */
float f_psy_trellis; /* Psy trellis strength */
int b_psy; /* Toggle all psy optimizations */

int b_mb_info; /* Use input mb_info data in x264_picture_t */
int b_mb_info_update; /* Update the values in mb_info according to the results of encoding. */

/* the deadzone size that will be used in luma quantization */
int i_luma_deadzone[2]; /* {inter, intra} */

int b_psnr; /* compute and print PSNR stats */
int b_ssim; /* compute and print SSIM stats */
} analyse;

/* Rate control parameters */
struct
{
int i_rc_method; /* X264_RC_* */

int i_qp_constant; /* 0=lossless */
int i_qp_min; /* min allowed QP value */
int i_qp_max; /* max allowed QP value */
int i_qp_step; /* max QP step between frames */

int i_bitrate;
float f_rf_constant; /* 1pass VBR, nominal QP */
float f_rf_constant_max; /* In CRF mode, maximum CRF as caused by VBV */
float f_rate_tolerance;
int i_vbv_max_bitrate;
int i_vbv_buffer_size;
float f_vbv_buffer_init; /* <=1: fraction of buffer_size. >1: kbit */
float f_ip_factor;
float f_pb_factor;

/* VBV filler: force CBR VBV and use filler bytes to ensure hard-CBR.
* Implied by NAL-HRD CBR. */
int b_filler;

int i_aq_mode; /* psy adaptive QP. (X264_AQ_*) */
float f_aq_strength;
int b_mb_tree; /* Macroblock-tree ratecontrol. */
int i_lookahead;

/* 2pass */
int b_stat_write; /* Enable stat writing in psz_stat_out */
char *psz_stat_out; /* output filename (in UTF-8) of the 2pass stats file */
int b_stat_read; /* Read stat from psz_stat_in and use it */
char *psz_stat_in; /* input filename (in UTF-8) of the 2pass stats file */

/* 2pass params (same as ffmpeg ones) */
float f_qcompress; /* 0.0 => cbr, 1.0 => constant qp */
float f_qblur; /* temporally blur quants */
float f_complexity_blur; /* temporally blur complexity */
x264_zone_t *zones; /* ratecontrol overrides */
int i_zones; /* number of zone_t's */
char *psz_zones; /* alternate method of specifying zones */
} rc;

/* Cropping Rectangle parameters: added to those implicitly defined by
non-mod16 video resolutions. */
struct
{
unsigned int i_left;
unsigned int i_top;
unsigned int i_right;
unsigned int i_bottom;
} crop_rect;

/* frame packing arrangement flag */
int i_frame_packing;

/* alternative transfer SEI */
int i_alternative_transfer;

/* Muxing parameters */
int b_aud; /* generate access unit delimiters */
int b_repeat_headers; /* put SPS/PPS before each keyframe */
int b_annexb; /* if set, place start codes (4 bytes) before NAL units,
* otherwise place size (4 bytes) before NAL units. */
int i_sps_id; /* SPS and PPS id number */
int b_vfr_input; /* VFR input. If 1, use timebase and timestamps for ratecontrol purposes.
* If 0, use fps only. */
int b_pulldown; /* use explicity set timebase for CFR */
uint32_t i_fps_num;
uint32_t i_fps_den;
uint32_t i_timebase_num; /* Timebase numerator */
uint32_t i_timebase_den; /* Timebase denominator */

int b_tff;

/* Pulldown:
* The correct pic_struct must be passed with each input frame.
* The input timebase should be the timebase corresponding to the output framerate. This should be constant.
* e.g. for 3:2 pulldown timebase should be 1001/30000
* The PTS passed with each frame must be the PTS of the frame after pulldown is applied.
* Frame doubling and tripling require b_vfr_input set to zero (see H.264 Table D-1)
*
* Pulldown changes are not clearly defined in H.264. Therefore, it is the calling app's responsibility to manage this.
*/

int b_pic_struct;

/* Fake Interlaced.
*
* Used only when b_interlaced=0. Setting this flag makes it possible to flag the stream as PAFF interlaced yet
* encode all frames progessively. It is useful for encoding 25p and 30p Blu-Ray streams.
*/

int b_fake_interlaced;

/* Don't optimize header parameters based on video content, e.g. ensure that splitting an input video, compressing
* each part, and stitching them back together will result in identical SPS/PPS. This is necessary for stitching
* with container formats that don't allow multiple SPS/PPS. */
int b_stitchable;

int b_opencl; /* use OpenCL when available */
int i_opencl_device; /* specify count of GPU devices to skip, for CLI users */
void *opencl_device_id; /* pass explicit cl_device_id as void*, for API users */
char *psz_clbin_file; /* filename (in UTF-8) of the compiled OpenCL kernel cache file */

/* Slicing parameters */
int i_slice_max_size; /* Max size per slice in bytes; includes estimated NAL overhead. */
int i_slice_max_mbs; /* Max number of MBs per slice; overrides i_slice_count. */
int i_slice_min_mbs; /* Min number of MBs per slice */
int i_slice_count; /* Number of slices per frame: forces rectangular slices. */
int i_slice_count_max; /* Absolute cap on slices per frame; stops applying slice-max-size
* and slice-max-mbs if this is reached. */

/* Optional callback for freeing this x264_param_t when it is done being used.
* Only used when the x264_param_t sits in memory for an indefinite period of time,
* i.e. when an x264_param_t is passed to x264_t in an x264_picture_t or in zones.
* Not used when x264_encoder_reconfig is called directly. */
void (*param_free)( void* );

/* Optional low-level callback for low-latency encoding. Called for each output NAL unit
* immediately after the NAL unit is finished encoding. This allows the calling application
* to begin processing video data (e.g. by sending packets over a network) before the frame
* is done encoding.
*
* This callback MUST do the following in order to work correctly:
* 1) Have available an output buffer of at least size nal->i_payload*3/2 + 5 + 64.
* 2) Call x264_nal_encode( h, dst, nal ), where dst is the output buffer.
* After these steps, the content of nal is valid and can be used in the same way as if
* the NAL unit were output by x264_encoder_encode.
*
* This does not need to be synchronous with the encoding process: the data pointed to
* by nal (both before and after x264_nal_encode) will remain valid until the next
* x264_encoder_encode call. The callback must be re-entrant.
*
* This callback does not work with frame-based threads; threads must be disabled
* or sliced-threads enabled. This callback also does not work as one would expect
* with HRD -- since the buffering period SEI cannot be calculated until the frame
* is finished encoding, it will not be sent via this callback.
*
* Note also that the NALs are not necessarily returned in order when sliced threads is
* enabled. Accordingly, the variable i_first_mb and i_last_mb are available in
* x264_nal_t to help the calling application reorder the slices if necessary.
*
* When this callback is enabled, x264_encoder_encode does not return valid NALs;
* the calling application is expected to acquire all output NALs through the callback.
*
* It is generally sensible to combine this callback with a use of slice-max-mbs or
* slice-max-size.
*
* The opaque pointer is the opaque pointer from the input frame associated with this
* NAL unit. This helps distinguish between nalu_process calls from different sources,
* e.g. if doing multiple encodes in one process.
*/
void (*nalu_process)( x264_t *h, x264_nal_t *nal, void *opaque );
} x264_param_t;

Author: Yin Wenjie
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint polocy. If reproduced, please indicate source Yin Wenjie !
 Previous
【x264视频编码器应用与实现】六. x264的图像与码流结构 【x264视频编码器应用与实现】六. x264的图像与码流结构
摘要:本文作为 “x264视频编码器应用与实现” 系列博文的第六篇,主要讨论x264中图像与码流结构体的定义和使用。
2022-02-24 Yin Wenjie
Next 
【x264视频编码器应用与实现】四. x264-example:自定义x264编码器的实现 【x264视频编码器应用与实现】四. x264-example:自定义x264编码器的实现
摘要:本文作为“x264视频编码器应用与实现”系列博文的第四篇,主要讨论如何利用编译生成的libx264的库文件实现x264的编码器示例程序。
2021-12-16 Yin Wenjie
  TOC