Coverage Report

Created: 2026-04-01 07:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/x264/common/base.c
Line
Count
Source
1
/*****************************************************************************
2
 * base.c: misc common functions (bit depth independent)
3
 *****************************************************************************
4
 * Copyright (C) 2003-2025 x264 project
5
 *
6
 * Authors: Loren Merritt <lorenm@u.washington.edu>
7
 *          Laurent Aimar <fenrir@via.ecp.fr>
8
 *
9
 * This program is free software; you can redistribute it and/or modify
10
 * it under the terms of the GNU General Public License as published by
11
 * the Free Software Foundation; either version 2 of the License, or
12
 * (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program; if not, write to the Free Software
21
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
22
 *
23
 * This program is also available under a commercial proprietary license.
24
 * For more information, contact us at licensing@x264.com.
25
 *****************************************************************************/
26
27
#include "base.h"
28
29
#include <ctype.h>
30
31
#if HAVE_MALLOC_H
32
#include <malloc.h>
33
#endif
34
#if HAVE_THP
35
#include <sys/mman.h>
36
#endif
37
38
0
#define X264_ISDIGIT(x) isdigit((unsigned char)(x))
39
40
/****************************************************************************
41
 * x264_reduce_fraction:
42
 ****************************************************************************/
43
#define REDUCE_FRACTION( name, type )\
44
0
void name( type *n, type *d )\
45
0
{                   \
46
0
    type a = *n;    \
47
0
    type b = *d;    \
48
0
    type c;         \
49
0
    if( !a || !b )  \
50
0
        return;     \
51
0
    c = a % b;      \
52
0
    while( c )      \
53
0
    {               \
54
0
        a = b;      \
55
0
        b = c;      \
56
0
        c = a % b;  \
57
0
    }               \
58
0
    *n /= b;        \
59
0
    *d /= b;        \
60
0
}
Unexecuted instantiation: x264_reduce_fraction
Unexecuted instantiation: x264_reduce_fraction64
61
62
REDUCE_FRACTION( x264_reduce_fraction  , uint32_t )
63
REDUCE_FRACTION( x264_reduce_fraction64, uint64_t )
64
65
/****************************************************************************
66
 * x264_log:
67
 ****************************************************************************/
68
void x264_log_default( void *p_unused, int i_level, const char *psz_fmt, va_list arg )
69
0
{
70
0
    char *psz_prefix;
71
0
    switch( i_level )
72
0
    {
73
0
        case X264_LOG_ERROR:
74
0
            psz_prefix = "error";
75
0
            break;
76
0
        case X264_LOG_WARNING:
77
0
            psz_prefix = "warning";
78
0
            break;
79
0
        case X264_LOG_INFO:
80
0
            psz_prefix = "info";
81
0
            break;
82
0
        case X264_LOG_DEBUG:
83
0
            psz_prefix = "debug";
84
0
            break;
85
0
        default:
86
0
            psz_prefix = "unknown";
87
0
            break;
88
0
    }
89
0
    fprintf( stderr, "x264 [%s]: ", psz_prefix );
90
0
    x264_vfprintf( stderr, psz_fmt, arg );
91
0
}
92
93
void x264_log_internal( int i_level, const char *psz_fmt, ... )
94
0
{
95
0
    va_list arg;
96
0
    va_start( arg, psz_fmt );
97
0
    x264_log_default( NULL, i_level, psz_fmt, arg );
98
0
    va_end( arg );
99
0
}
100
101
/****************************************************************************
102
 * x264_malloc:
103
 ****************************************************************************/
104
void *x264_malloc( int64_t i_size )
105
0
{
106
0
#define HUGE_PAGE_SIZE 2*1024*1024
107
0
#define HUGE_PAGE_THRESHOLD HUGE_PAGE_SIZE*7/8 /* FIXME: Is this optimal? */
108
0
    if( i_size < 0 || (uint64_t)i_size > (SIZE_MAX - HUGE_PAGE_SIZE) /*|| (uint64_t)i_size > (SIZE_MAX - NATIVE_ALIGN - sizeof(void **))*/ )
109
0
    {
110
0
        x264_log_internal( X264_LOG_ERROR, "invalid size of malloc: %"PRId64"\n", i_size );
111
0
        return NULL;
112
0
    }
113
0
    uint8_t *align_buf = NULL;
114
0
#if HAVE_MALLOC_H
115
0
#if HAVE_THP
116
    /* Attempt to allocate huge pages to reduce TLB misses. */
117
0
    if( i_size >= HUGE_PAGE_THRESHOLD )
118
0
    {
119
0
        align_buf = memalign( HUGE_PAGE_SIZE, i_size );
120
0
        if( align_buf )
121
0
        {
122
            /* Round up to the next huge page boundary if we are close enough. */
123
0
            size_t madv_size = (i_size + HUGE_PAGE_SIZE - HUGE_PAGE_THRESHOLD) & ~(HUGE_PAGE_SIZE-1);
124
0
            madvise( align_buf, madv_size, MADV_HUGEPAGE );
125
0
        }
126
0
    }
127
0
    else
128
0
#endif
129
0
        align_buf = memalign( NATIVE_ALIGN, i_size );
130
#else
131
    uint8_t *buf = malloc( i_size + (NATIVE_ALIGN-1) + sizeof(void **) );
132
    if( buf )
133
    {
134
        align_buf = buf + (NATIVE_ALIGN-1) + sizeof(void **);
135
        align_buf -= (intptr_t) align_buf & (NATIVE_ALIGN-1);
136
        *( (void **) ( align_buf - sizeof(void **) ) ) = buf;
137
    }
138
#endif
139
0
    if( !align_buf )
140
0
        x264_log_internal( X264_LOG_ERROR, "malloc of size %"PRId64" failed\n", i_size );
141
0
    return align_buf;
142
0
#undef HUGE_PAGE_SIZE
143
0
#undef HUGE_PAGE_THRESHOLD
144
0
}
145
146
/****************************************************************************
147
 * x264_free:
148
 ****************************************************************************/
149
void x264_free( void *p )
150
0
{
151
0
    if( p )
152
0
    {
153
0
#if HAVE_MALLOC_H
154
0
        free( p );
155
#else
156
        free( *( ( ( void **) p ) - 1 ) );
157
#endif
158
0
    }
159
0
}
160
161
/****************************************************************************
162
 * x264_slurp_file:
163
 ****************************************************************************/
164
char *x264_slurp_file( const char *filename )
165
0
{
166
0
    int b_error = 0;
167
0
    int64_t i_size;
168
0
    char *buf;
169
0
    FILE *fh = x264_fopen( filename, "rb" );
170
0
    if( !fh )
171
0
        return NULL;
172
173
0
    b_error |= fseek( fh, 0, SEEK_END ) < 0;
174
0
    b_error |= ( i_size = ftell( fh ) ) <= 0;
175
0
    if( WORD_SIZE == 4 )
176
0
        b_error |= i_size > INT32_MAX;
177
0
    b_error |= fseek( fh, 0, SEEK_SET ) < 0;
178
0
    if( b_error )
179
0
        goto error;
180
181
0
    buf = x264_malloc( i_size+2 );
182
0
    if( !buf )
183
0
        goto error;
184
185
0
    b_error |= fread( buf, 1, i_size, fh ) != (uint64_t)i_size;
186
0
    fclose( fh );
187
0
    if( b_error )
188
0
    {
189
0
        x264_free( buf );
190
0
        return NULL;
191
0
    }
192
193
0
    if( buf[i_size-1] != '\n' )
194
0
        buf[i_size++] = '\n';
195
0
    buf[i_size] = '\0';
196
197
0
    return buf;
198
0
error:
199
0
    fclose( fh );
200
0
    return NULL;
201
0
}
202
203
/****************************************************************************
204
 * x264_param_strdup:
205
 ****************************************************************************/
206
typedef struct {
207
    int size;
208
    int count;
209
    void *ptr[];
210
} strdup_buffer;
211
212
0
#define BUFFER_OFFSET (int)offsetof(strdup_buffer, ptr)
213
0
#define BUFFER_DEFAULT_SIZE 16
214
215
char *x264_param_strdup( x264_param_t *param, const char *src )
216
0
{
217
0
    strdup_buffer *buf = param->opaque;
218
0
    if( !buf )
219
0
    {
220
0
        buf = malloc( BUFFER_OFFSET + BUFFER_DEFAULT_SIZE * sizeof(void *) );
221
0
        if( !buf )
222
0
            goto fail;
223
0
        buf->size = BUFFER_DEFAULT_SIZE;
224
0
        buf->count = 0;
225
0
        param->opaque = buf;
226
0
    }
227
0
    else if( buf->count == buf->size )
228
0
    {
229
0
        if( buf->size > (INT_MAX - BUFFER_OFFSET) / 2 / (int)sizeof(void *) )
230
0
            goto fail;
231
0
        int new_size = buf->size * 2;
232
0
        buf = realloc( buf, BUFFER_OFFSET + new_size * sizeof(void *) );
233
0
        if( !buf )
234
0
            goto fail;
235
0
        buf->size = new_size;
236
0
        param->opaque = buf;
237
0
    }
238
0
    char *res = strdup( src );
239
0
    if( !res )
240
0
        goto fail;
241
0
    buf->ptr[buf->count++] = res;
242
0
    return res;
243
0
fail:
244
0
    x264_log_internal( X264_LOG_ERROR, "x264_param_strdup failed\n" );
245
0
    return NULL;
246
0
}
247
248
/****************************************************************************
249
 * x264_param_cleanup:
250
 ****************************************************************************/
251
REALIGN_STACK void x264_param_cleanup( x264_param_t *param )
252
0
{
253
0
    strdup_buffer *buf = param->opaque;
254
0
    if( buf )
255
0
    {
256
0
        for( int i = 0; i < buf->count; i++ )
257
0
            free( buf->ptr[i] );
258
0
        free( buf );
259
0
        param->opaque = NULL;
260
0
    }
261
0
}
262
263
/****************************************************************************
264
 * x264_picture_init:
265
 ****************************************************************************/
266
REALIGN_STACK void x264_picture_init( x264_picture_t *pic )
267
0
{
268
0
    memset( pic, 0, sizeof( x264_picture_t ) );
269
0
    pic->i_type = X264_TYPE_AUTO;
270
0
    pic->i_qpplus1 = X264_QP_AUTO;
271
0
    pic->i_pic_struct = PIC_STRUCT_AUTO;
272
0
}
273
274
/****************************************************************************
275
 * x264_picture_alloc:
276
 ****************************************************************************/
277
REALIGN_STACK int x264_picture_alloc( x264_picture_t *pic, int i_csp, int i_width, int i_height )
278
0
{
279
0
    typedef struct
280
0
    {
281
0
        int planes;
282
0
        int width_fix8[3];
283
0
        int height_fix8[3];
284
0
    } x264_csp_tab_t;
285
286
0
    static const x264_csp_tab_t csp_tab[] =
287
0
    {
288
0
        [X264_CSP_I400] = { 1, { 256*1 },               { 256*1 }               },
289
0
        [X264_CSP_I420] = { 3, { 256*1, 256/2, 256/2 }, { 256*1, 256/2, 256/2 } },
290
0
        [X264_CSP_YV12] = { 3, { 256*1, 256/2, 256/2 }, { 256*1, 256/2, 256/2 } },
291
0
        [X264_CSP_NV12] = { 2, { 256*1, 256*1 },        { 256*1, 256/2 },       },
292
0
        [X264_CSP_NV21] = { 2, { 256*1, 256*1 },        { 256*1, 256/2 },       },
293
0
        [X264_CSP_I422] = { 3, { 256*1, 256/2, 256/2 }, { 256*1, 256*1, 256*1 } },
294
0
        [X264_CSP_YV16] = { 3, { 256*1, 256/2, 256/2 }, { 256*1, 256*1, 256*1 } },
295
0
        [X264_CSP_NV16] = { 2, { 256*1, 256*1 },        { 256*1, 256*1 },       },
296
0
        [X264_CSP_YUYV] = { 1, { 256*2 },               { 256*1 },              },
297
0
        [X264_CSP_UYVY] = { 1, { 256*2 },               { 256*1 },              },
298
0
        [X264_CSP_I444] = { 3, { 256*1, 256*1, 256*1 }, { 256*1, 256*1, 256*1 } },
299
0
        [X264_CSP_YV24] = { 3, { 256*1, 256*1, 256*1 }, { 256*1, 256*1, 256*1 } },
300
0
        [X264_CSP_BGR]  = { 1, { 256*3 },               { 256*1 },              },
301
0
        [X264_CSP_BGRA] = { 1, { 256*4 },               { 256*1 },              },
302
0
        [X264_CSP_RGB]  = { 1, { 256*3 },               { 256*1 },              },
303
0
    };
304
305
0
    int csp = i_csp & X264_CSP_MASK;
306
0
    if( csp <= X264_CSP_NONE || csp >= X264_CSP_MAX || csp == X264_CSP_V210 )
307
0
        return -1;
308
0
    x264_picture_init( pic );
309
0
    pic->img.i_csp = i_csp;
310
0
    pic->img.i_plane = csp_tab[csp].planes;
311
0
    int depth_factor = i_csp & X264_CSP_HIGH_DEPTH ? 2 : 1;
312
0
    int64_t plane_offset[3] = {0};
313
0
    int64_t frame_size = 0;
314
0
    for( int i = 0; i < pic->img.i_plane; i++ )
315
0
    {
316
0
        int stride = (((int64_t)i_width * csp_tab[csp].width_fix8[i]) >> 8) * depth_factor;
317
0
        int64_t plane_size = (((int64_t)i_height * csp_tab[csp].height_fix8[i]) >> 8) * stride;
318
0
        pic->img.i_stride[i] = stride;
319
0
        plane_offset[i] = frame_size;
320
0
        frame_size += plane_size;
321
0
    }
322
0
    pic->img.plane[0] = x264_malloc( frame_size );
323
0
    if( !pic->img.plane[0] )
324
0
        return -1;
325
0
    for( int i = 1; i < pic->img.i_plane; i++ )
326
0
        pic->img.plane[i] = pic->img.plane[0] + plane_offset[i];
327
0
    return 0;
328
0
}
329
330
/****************************************************************************
331
 * x264_picture_clean:
332
 ****************************************************************************/
333
REALIGN_STACK void x264_picture_clean( x264_picture_t *pic )
334
0
{
335
0
    x264_free( pic->img.plane[0] );
336
337
    /* just to be safe */
338
0
    memset( pic, 0, sizeof( x264_picture_t ) );
339
0
}
340
341
/****************************************************************************
342
 * x264_param_default:
343
 ****************************************************************************/
344
REALIGN_STACK void x264_param_default( x264_param_t *param )
345
0
{
346
    /* */
347
0
    memset( param, 0, sizeof( x264_param_t ) );
348
349
    /* CPU autodetect */
350
0
    param->cpu = x264_cpu_detect();
351
0
    param->i_threads = X264_THREADS_AUTO;
352
0
    param->i_lookahead_threads = X264_THREADS_AUTO;
353
0
    param->b_deterministic = 1;
354
0
    param->i_sync_lookahead = X264_SYNC_LOOKAHEAD_AUTO;
355
356
    /* Video properties */
357
0
    param->i_csp           = X264_CHROMA_FORMAT ? X264_CHROMA_FORMAT : X264_CSP_I420;
358
0
    param->i_width         = 0;
359
0
    param->i_height        = 0;
360
0
    param->vui.i_sar_width = 0;
361
0
    param->vui.i_sar_height= 0;
362
0
    param->vui.i_overscan  = 0;  /* undef */
363
0
    param->vui.i_vidformat = 5;  /* undef */
364
0
    param->vui.b_fullrange = -1; /* default depends on input */
365
0
    param->vui.i_colorprim = 2;  /* undef */
366
0
    param->vui.i_transfer  = 2;  /* undef */
367
0
    param->vui.i_colmatrix = -1; /* default depends on input */
368
0
    param->vui.i_chroma_loc= 0;  /* left center */
369
0
    param->i_fps_num       = 25;
370
0
    param->i_fps_den       = 1;
371
0
    param->i_level_idc     = -1;
372
0
    param->i_slice_max_size = 0;
373
0
    param->i_slice_max_mbs = 0;
374
0
    param->i_slice_count = 0;
375
0
#if HAVE_BITDEPTH8
376
0
    param->i_bitdepth = 8;
377
#elif HAVE_BITDEPTH10
378
    param->i_bitdepth = 10;
379
#else
380
    param->i_bitdepth = 8;
381
#endif
382
383
    /* Encoder parameters */
384
0
    param->i_frame_reference = 3;
385
0
    param->i_keyint_max = 250;
386
0
    param->i_keyint_min = X264_KEYINT_MIN_AUTO;
387
0
    param->i_bframe = 3;
388
0
    param->i_scenecut_threshold = 40;
389
0
    param->i_bframe_adaptive = X264_B_ADAPT_FAST;
390
0
    param->i_bframe_bias = 0;
391
0
    param->i_bframe_pyramid = X264_B_PYRAMID_NORMAL;
392
0
    param->b_interlaced = 0;
393
0
    param->b_constrained_intra = 0;
394
395
0
    param->b_deblocking_filter = 1;
396
0
    param->i_deblocking_filter_alphac0 = 0;
397
0
    param->i_deblocking_filter_beta = 0;
398
399
0
    param->b_cabac = 1;
400
0
    param->i_cabac_init_idc = 0;
401
402
0
    param->rc.i_rc_method = X264_RC_CRF;
403
0
    param->rc.i_bitrate = 0;
404
0
    param->rc.f_rate_tolerance = 1.0;
405
0
    param->rc.i_vbv_max_bitrate = 0;
406
0
    param->rc.i_vbv_buffer_size = 0;
407
0
    param->rc.f_vbv_buffer_init = 0.9;
408
0
    param->rc.i_qp_constant = -1;
409
0
    param->rc.f_rf_constant = 23;
410
0
    param->rc.i_qp_min = 0;
411
0
    param->rc.i_qp_max = INT_MAX;
412
0
    param->rc.i_qp_step = 4;
413
0
    param->rc.f_ip_factor = 1.4;
414
0
    param->rc.f_pb_factor = 1.3;
415
0
    param->rc.i_aq_mode = X264_AQ_VARIANCE;
416
0
    param->rc.f_aq_strength = 1.0;
417
0
    param->rc.i_lookahead = 40;
418
419
0
    param->rc.b_stat_write = 0;
420
0
    param->rc.psz_stat_out = "x264_2pass.log";
421
0
    param->rc.b_stat_read = 0;
422
0
    param->rc.psz_stat_in = "x264_2pass.log";
423
0
    param->rc.f_qcompress = 0.6;
424
0
    param->rc.f_qblur = 0.5;
425
0
    param->rc.f_complexity_blur = 20;
426
0
    param->rc.i_zones = 0;
427
0
    param->rc.b_mb_tree = 1;
428
429
    /* Log */
430
0
    param->pf_log = x264_log_default;
431
0
    param->p_log_private = NULL;
432
0
    param->i_log_level = X264_LOG_INFO;
433
434
    /* */
435
0
    param->analyse.intra = X264_ANALYSE_I4x4 | X264_ANALYSE_I8x8;
436
0
    param->analyse.inter = X264_ANALYSE_I4x4 | X264_ANALYSE_I8x8
437
0
                         | X264_ANALYSE_PSUB16x16 | X264_ANALYSE_BSUB16x16;
438
0
    param->analyse.i_direct_mv_pred = X264_DIRECT_PRED_SPATIAL;
439
0
    param->analyse.i_me_method = X264_ME_HEX;
440
0
    param->analyse.f_psy_rd = 1.0;
441
0
    param->analyse.b_psy = 1;
442
0
    param->analyse.f_psy_trellis = 0;
443
0
    param->analyse.i_me_range = 16;
444
0
    param->analyse.i_subpel_refine = 7;
445
0
    param->analyse.b_mixed_references = 1;
446
0
    param->analyse.b_chroma_me = 1;
447
0
    param->analyse.i_mv_range_thread = -1;
448
0
    param->analyse.i_mv_range = -1; // set from level_idc
449
0
    param->analyse.i_chroma_qp_offset = 0;
450
0
    param->analyse.b_fast_pskip = 1;
451
0
    param->analyse.b_weighted_bipred = 1;
452
0
    param->analyse.i_weighted_pred = X264_WEIGHTP_SMART;
453
0
    param->analyse.b_dct_decimate = 1;
454
0
    param->analyse.b_transform_8x8 = 1;
455
0
    param->analyse.i_trellis = 1;
456
0
    param->analyse.i_luma_deadzone[0] = 21;
457
0
    param->analyse.i_luma_deadzone[1] = 11;
458
0
    param->analyse.b_psnr = 0;
459
0
    param->analyse.b_ssim = 0;
460
461
0
    param->i_cqm_preset = X264_CQM_FLAT;
462
0
    memset( param->cqm_4iy, 16, sizeof( param->cqm_4iy ) );
463
0
    memset( param->cqm_4py, 16, sizeof( param->cqm_4py ) );
464
0
    memset( param->cqm_4ic, 16, sizeof( param->cqm_4ic ) );
465
0
    memset( param->cqm_4pc, 16, sizeof( param->cqm_4pc ) );
466
0
    memset( param->cqm_8iy, 16, sizeof( param->cqm_8iy ) );
467
0
    memset( param->cqm_8py, 16, sizeof( param->cqm_8py ) );
468
0
    memset( param->cqm_8ic, 16, sizeof( param->cqm_8ic ) );
469
0
    memset( param->cqm_8pc, 16, sizeof( param->cqm_8pc ) );
470
471
0
    param->b_repeat_headers = 1;
472
0
    param->b_annexb = 1;
473
0
    param->b_aud = 0;
474
0
    param->b_vfr_input = 1;
475
0
    param->i_nal_hrd = X264_NAL_HRD_NONE;
476
0
    param->b_tff = 1;
477
0
    param->b_pic_struct = 0;
478
0
    param->b_fake_interlaced = 0;
479
0
    param->i_frame_packing = -1;
480
0
    param->i_alternative_transfer = 2; /* undef */
481
0
    param->b_opencl = 0;
482
0
    param->i_opencl_device = 0;
483
0
    param->opencl_device_id = NULL;
484
0
    param->psz_clbin_file = NULL;
485
0
    param->i_avcintra_class = 0;
486
0
    param->i_avcintra_flavor = X264_AVCINTRA_FLAVOR_PANASONIC;
487
0
}
488
489
static int param_apply_preset( x264_param_t *param, const char *preset )
490
0
{
491
0
    char *end;
492
0
    int i = strtol( preset, &end, 10 );
493
0
    if( *end == 0 && i >= 0 && i < ARRAY_ELEMS(x264_preset_names)-1 )
494
0
        preset = x264_preset_names[i];
495
496
0
    if( !strcasecmp( preset, "ultrafast" ) )
497
0
    {
498
0
        param->i_frame_reference = 1;
499
0
        param->i_scenecut_threshold = 0;
500
0
        param->b_deblocking_filter = 0;
501
0
        param->b_cabac = 0;
502
0
        param->i_bframe = 0;
503
0
        param->analyse.intra = 0;
504
0
        param->analyse.inter = 0;
505
0
        param->analyse.b_transform_8x8 = 0;
506
0
        param->analyse.i_me_method = X264_ME_DIA;
507
0
        param->analyse.i_subpel_refine = 0;
508
0
        param->rc.i_aq_mode = 0;
509
0
        param->analyse.b_mixed_references = 0;
510
0
        param->analyse.i_trellis = 0;
511
0
        param->i_bframe_adaptive = X264_B_ADAPT_NONE;
512
0
        param->rc.b_mb_tree = 0;
513
0
        param->analyse.i_weighted_pred = X264_WEIGHTP_NONE;
514
0
        param->analyse.b_weighted_bipred = 0;
515
0
        param->rc.i_lookahead = 0;
516
0
    }
517
0
    else if( !strcasecmp( preset, "superfast" ) )
518
0
    {
519
0
        param->analyse.inter = X264_ANALYSE_I8x8|X264_ANALYSE_I4x4;
520
0
        param->analyse.i_me_method = X264_ME_DIA;
521
0
        param->analyse.i_subpel_refine = 1;
522
0
        param->i_frame_reference = 1;
523
0
        param->analyse.b_mixed_references = 0;
524
0
        param->analyse.i_trellis = 0;
525
0
        param->rc.b_mb_tree = 0;
526
0
        param->analyse.i_weighted_pred = X264_WEIGHTP_SIMPLE;
527
0
        param->rc.i_lookahead = 0;
528
0
    }
529
0
    else if( !strcasecmp( preset, "veryfast" ) )
530
0
    {
531
0
        param->analyse.i_subpel_refine = 2;
532
0
        param->i_frame_reference = 1;
533
0
        param->analyse.b_mixed_references = 0;
534
0
        param->analyse.i_trellis = 0;
535
0
        param->analyse.i_weighted_pred = X264_WEIGHTP_SIMPLE;
536
0
        param->rc.i_lookahead = 10;
537
0
    }
538
0
    else if( !strcasecmp( preset, "faster" ) )
539
0
    {
540
0
        param->analyse.b_mixed_references = 0;
541
0
        param->i_frame_reference = 2;
542
0
        param->analyse.i_subpel_refine = 4;
543
0
        param->analyse.i_weighted_pred = X264_WEIGHTP_SIMPLE;
544
0
        param->rc.i_lookahead = 20;
545
0
    }
546
0
    else if( !strcasecmp( preset, "fast" ) )
547
0
    {
548
0
        param->i_frame_reference = 2;
549
0
        param->analyse.i_subpel_refine = 6;
550
0
        param->analyse.i_weighted_pred = X264_WEIGHTP_SIMPLE;
551
0
        param->rc.i_lookahead = 30;
552
0
    }
553
0
    else if( !strcasecmp( preset, "medium" ) )
554
0
    {
555
        /* Default is medium */
556
0
    }
557
0
    else if( !strcasecmp( preset, "slow" ) )
558
0
    {
559
0
        param->analyse.i_subpel_refine = 8;
560
0
        param->i_frame_reference = 5;
561
0
        param->analyse.i_direct_mv_pred = X264_DIRECT_PRED_AUTO;
562
0
        param->analyse.i_trellis = 2;
563
0
        param->rc.i_lookahead = 50;
564
0
    }
565
0
    else if( !strcasecmp( preset, "slower" ) )
566
0
    {
567
0
        param->analyse.i_me_method = X264_ME_UMH;
568
0
        param->analyse.i_subpel_refine = 9;
569
0
        param->i_frame_reference = 8;
570
0
        param->i_bframe_adaptive = X264_B_ADAPT_TRELLIS;
571
0
        param->analyse.i_direct_mv_pred = X264_DIRECT_PRED_AUTO;
572
0
        param->analyse.inter |= X264_ANALYSE_PSUB8x8;
573
0
        param->analyse.i_trellis = 2;
574
0
        param->rc.i_lookahead = 60;
575
0
    }
576
0
    else if( !strcasecmp( preset, "veryslow" ) )
577
0
    {
578
0
        param->analyse.i_me_method = X264_ME_UMH;
579
0
        param->analyse.i_subpel_refine = 10;
580
0
        param->analyse.i_me_range = 24;
581
0
        param->i_frame_reference = 16;
582
0
        param->i_bframe_adaptive = X264_B_ADAPT_TRELLIS;
583
0
        param->analyse.i_direct_mv_pred = X264_DIRECT_PRED_AUTO;
584
0
        param->analyse.inter |= X264_ANALYSE_PSUB8x8;
585
0
        param->analyse.i_trellis = 2;
586
0
        param->i_bframe = 8;
587
0
        param->rc.i_lookahead = 60;
588
0
    }
589
0
    else if( !strcasecmp( preset, "placebo" ) )
590
0
    {
591
0
        param->analyse.i_me_method = X264_ME_TESA;
592
0
        param->analyse.i_subpel_refine = 11;
593
0
        param->analyse.i_me_range = 24;
594
0
        param->i_frame_reference = 16;
595
0
        param->i_bframe_adaptive = X264_B_ADAPT_TRELLIS;
596
0
        param->analyse.i_direct_mv_pred = X264_DIRECT_PRED_AUTO;
597
0
        param->analyse.inter |= X264_ANALYSE_PSUB8x8;
598
0
        param->analyse.b_fast_pskip = 0;
599
0
        param->analyse.i_trellis = 2;
600
0
        param->i_bframe = 16;
601
0
        param->rc.i_lookahead = 60;
602
0
    }
603
0
    else
604
0
    {
605
0
        x264_log_internal( X264_LOG_ERROR, "invalid preset '%s'\n", preset );
606
0
        return -1;
607
0
    }
608
0
    return 0;
609
0
}
610
611
static int param_apply_tune( x264_param_t *param, const char *tune )
612
0
{
613
0
    int psy_tuning_used = 0;
614
0
    for( int len; tune += strspn( tune, ",./-+" ), (len = strcspn( tune, ",./-+" )); tune += len )
615
0
    {
616
0
        if( len == 4 && !strncasecmp( tune, "film", 4 ) )
617
0
        {
618
0
            if( psy_tuning_used++ ) goto psy_failure;
619
0
            param->i_deblocking_filter_alphac0 = -1;
620
0
            param->i_deblocking_filter_beta = -1;
621
0
            param->analyse.f_psy_trellis = 0.15;
622
0
        }
623
0
        else if( len == 9 && !strncasecmp( tune, "animation", 9 ) )
624
0
        {
625
0
            if( psy_tuning_used++ ) goto psy_failure;
626
0
            param->i_frame_reference = param->i_frame_reference > 1 ? param->i_frame_reference*2 : 1;
627
0
            param->i_deblocking_filter_alphac0 = 1;
628
0
            param->i_deblocking_filter_beta = 1;
629
0
            param->analyse.f_psy_rd = 0.4;
630
0
            param->rc.f_aq_strength = 0.6;
631
0
            param->i_bframe += 2;
632
0
        }
633
0
        else if( len == 5 && !strncasecmp( tune, "grain", 5 ) )
634
0
        {
635
0
            if( psy_tuning_used++ ) goto psy_failure;
636
0
            param->i_deblocking_filter_alphac0 = -2;
637
0
            param->i_deblocking_filter_beta = -2;
638
0
            param->analyse.f_psy_trellis = 0.25;
639
0
            param->analyse.b_dct_decimate = 0;
640
0
            param->rc.f_pb_factor = 1.1;
641
0
            param->rc.f_ip_factor = 1.1;
642
0
            param->rc.f_aq_strength = 0.5;
643
0
            param->analyse.i_luma_deadzone[0] = 6;
644
0
            param->analyse.i_luma_deadzone[1] = 6;
645
0
            param->rc.f_qcompress = 0.8;
646
0
        }
647
0
        else if( len == 10 && !strncasecmp( tune, "stillimage", 10 ) )
648
0
        {
649
0
            if( psy_tuning_used++ ) goto psy_failure;
650
0
            param->i_deblocking_filter_alphac0 = -3;
651
0
            param->i_deblocking_filter_beta = -3;
652
0
            param->analyse.f_psy_rd = 2.0;
653
0
            param->analyse.f_psy_trellis = 0.7;
654
0
            param->rc.f_aq_strength = 1.2;
655
0
        }
656
0
        else if( len == 4 && !strncasecmp( tune, "psnr", 4 ) )
657
0
        {
658
0
            if( psy_tuning_used++ ) goto psy_failure;
659
0
            param->rc.i_aq_mode = X264_AQ_NONE;
660
0
            param->analyse.b_psy = 0;
661
0
        }
662
0
        else if( len == 4 && !strncasecmp( tune, "ssim", 4 ) )
663
0
        {
664
0
            if( psy_tuning_used++ ) goto psy_failure;
665
0
            param->rc.i_aq_mode = X264_AQ_AUTOVARIANCE;
666
0
            param->analyse.b_psy = 0;
667
0
        }
668
0
        else if( len == 10 && !strncasecmp( tune, "fastdecode", 10 ) )
669
0
        {
670
0
            param->b_deblocking_filter = 0;
671
0
            param->b_cabac = 0;
672
0
            param->analyse.b_weighted_bipred = 0;
673
0
            param->analyse.i_weighted_pred = X264_WEIGHTP_NONE;
674
0
        }
675
0
        else if( len == 11 && !strncasecmp( tune, "zerolatency", 11 ) )
676
0
        {
677
0
            param->rc.i_lookahead = 0;
678
0
            param->i_sync_lookahead = 0;
679
0
            param->i_bframe = 0;
680
0
            param->b_sliced_threads = 1;
681
0
            param->b_vfr_input = 0;
682
0
            param->rc.b_mb_tree = 0;
683
0
        }
684
0
        else if( len == 6 && !strncasecmp( tune, "touhou", 6 ) )
685
0
        {
686
0
            if( psy_tuning_used++ ) goto psy_failure;
687
0
            param->i_frame_reference = param->i_frame_reference > 1 ? param->i_frame_reference*2 : 1;
688
0
            param->i_deblocking_filter_alphac0 = -1;
689
0
            param->i_deblocking_filter_beta = -1;
690
0
            param->analyse.f_psy_trellis = 0.2;
691
0
            param->rc.f_aq_strength = 1.3;
692
0
            if( param->analyse.inter & X264_ANALYSE_PSUB16x16 )
693
0
                param->analyse.inter |= X264_ANALYSE_PSUB8x8;
694
0
        }
695
0
        else
696
0
        {
697
0
            x264_log_internal( X264_LOG_ERROR, "invalid tune '%.*s'\n", len, tune );
698
0
            return -1;
699
0
    psy_failure:
700
0
            x264_log_internal( X264_LOG_WARNING, "only 1 psy tuning can be used: ignoring tune %.*s\n", len, tune );
701
0
        }
702
0
    }
703
0
    return 0;
704
0
}
705
706
REALIGN_STACK int x264_param_default_preset( x264_param_t *param, const char *preset, const char *tune )
707
0
{
708
0
    x264_param_default( param );
709
710
0
    if( preset && param_apply_preset( param, preset ) < 0 )
711
0
        return -1;
712
0
    if( tune && param_apply_tune( param, tune ) < 0 )
713
0
        return -1;
714
0
    return 0;
715
0
}
716
717
REALIGN_STACK void x264_param_apply_fastfirstpass( x264_param_t *param )
718
0
{
719
    /* Set faster options in case of turbo firstpass. */
720
0
    if( param->rc.b_stat_write && !param->rc.b_stat_read )
721
0
    {
722
0
        param->i_frame_reference = 1;
723
0
        param->analyse.b_transform_8x8 = 0;
724
0
        param->analyse.inter = 0;
725
0
        param->analyse.i_me_method = X264_ME_DIA;
726
0
        param->analyse.i_subpel_refine = X264_MIN( 2, param->analyse.i_subpel_refine );
727
0
        param->analyse.i_trellis = 0;
728
0
        param->analyse.b_fast_pskip = 1;
729
0
    }
730
0
}
731
732
static int profile_string_to_int( const char *str )
733
0
{
734
0
    if( !strcasecmp( str, "baseline" ) )
735
0
        return PROFILE_BASELINE;
736
0
    if( !strcasecmp( str, "main" ) )
737
0
        return PROFILE_MAIN;
738
0
    if( !strcasecmp( str, "high" ) )
739
0
        return PROFILE_HIGH;
740
0
    if( !strcasecmp( str, "high10" ) )
741
0
        return PROFILE_HIGH10;
742
0
    if( !strcasecmp( str, "high422" ) )
743
0
        return PROFILE_HIGH422;
744
0
    if( !strcasecmp( str, "high444" ) )
745
0
        return PROFILE_HIGH444_PREDICTIVE;
746
0
    return -1;
747
0
}
748
749
REALIGN_STACK int x264_param_apply_profile( x264_param_t *param, const char *profile )
750
0
{
751
0
    if( !profile )
752
0
        return 0;
753
754
0
    const int qp_bd_offset = 6 * (param->i_bitdepth-8);
755
0
    int p = profile_string_to_int( profile );
756
0
    if( p < 0 )
757
0
    {
758
0
        x264_log_internal( X264_LOG_ERROR, "invalid profile: %s\n", profile );
759
0
        return -1;
760
0
    }
761
0
    if( p < PROFILE_HIGH444_PREDICTIVE && ((param->rc.i_rc_method == X264_RC_CQP && param->rc.i_qp_constant <= 0) ||
762
0
        (param->rc.i_rc_method == X264_RC_CRF && (int)(param->rc.f_rf_constant + qp_bd_offset) <= 0)) )
763
0
    {
764
0
        x264_log_internal( X264_LOG_ERROR, "%s profile doesn't support lossless\n", profile );
765
0
        return -1;
766
0
    }
767
0
    if( p < PROFILE_HIGH444_PREDICTIVE && (param->i_csp & X264_CSP_MASK) >= X264_CSP_I444 )
768
0
    {
769
0
        x264_log_internal( X264_LOG_ERROR, "%s profile doesn't support 4:4:4\n", profile );
770
0
        return -1;
771
0
    }
772
0
    if( p < PROFILE_HIGH422 && (param->i_csp & X264_CSP_MASK) >= X264_CSP_I422 )
773
0
    {
774
0
        x264_log_internal( X264_LOG_ERROR, "%s profile doesn't support 4:2:2\n", profile );
775
0
        return -1;
776
0
    }
777
0
    if( p < PROFILE_HIGH10 && param->i_bitdepth > 8 )
778
0
    {
779
0
        x264_log_internal( X264_LOG_ERROR, "%s profile doesn't support a bit depth of %d\n", profile, param->i_bitdepth );
780
0
        return -1;
781
0
    }
782
0
    if( p < PROFILE_HIGH && (param->i_csp & X264_CSP_MASK) == X264_CSP_I400 )
783
0
    {
784
0
        x264_log_internal( X264_LOG_ERROR, "%s profile doesn't support 4:0:0\n", profile );
785
0
        return -1;
786
0
    }
787
788
0
    if( p == PROFILE_BASELINE )
789
0
    {
790
0
        param->analyse.b_transform_8x8 = 0;
791
0
        param->b_cabac = 0;
792
0
        param->i_cqm_preset = X264_CQM_FLAT;
793
0
        param->psz_cqm_file = NULL;
794
0
        param->i_bframe = 0;
795
0
        param->analyse.i_weighted_pred = X264_WEIGHTP_NONE;
796
0
        if( param->b_interlaced )
797
0
        {
798
0
            x264_log_internal( X264_LOG_ERROR, "baseline profile doesn't support interlacing\n" );
799
0
            return -1;
800
0
        }
801
0
        if( param->b_fake_interlaced )
802
0
        {
803
0
            x264_log_internal( X264_LOG_ERROR, "baseline profile doesn't support fake interlacing\n" );
804
0
            return -1;
805
0
        }
806
0
    }
807
0
    else if( p == PROFILE_MAIN )
808
0
    {
809
0
        param->analyse.b_transform_8x8 = 0;
810
0
        param->i_cqm_preset = X264_CQM_FLAT;
811
0
        param->psz_cqm_file = NULL;
812
0
    }
813
0
    return 0;
814
0
}
815
816
static int parse_enum( const char *arg, const char * const *names, int *dst )
817
0
{
818
0
    for( int i = 0; names[i]; i++ )
819
0
        if( *names[i] && !strcasecmp( arg, names[i] ) )
820
0
        {
821
0
            *dst = i;
822
0
            return 0;
823
0
        }
824
0
    return -1;
825
0
}
826
827
static int parse_cqm( const char *str, uint8_t *cqm, int length )
828
0
{
829
0
    int i = 0;
830
0
    do {
831
0
        int coef;
832
0
        if( !sscanf( str, "%d", &coef ) || coef < 1 || coef > 255 )
833
0
            return -1;
834
0
        cqm[i++] = coef;
835
0
    } while( i < length && (str = strchr( str, ',' )) && str++ );
836
0
    return (i == length) ? 0 : -1;
837
0
}
838
839
static int atobool_internal( const char *str, int *b_error )
840
0
{
841
0
    if( !strcmp(str, "1") ||
842
0
        !strcasecmp(str, "true") ||
843
0
        !strcasecmp(str, "yes") )
844
0
        return 1;
845
0
    if( !strcmp(str, "0") ||
846
0
        !strcasecmp(str, "false") ||
847
0
        !strcasecmp(str, "no") )
848
0
        return 0;
849
0
    *b_error = 1;
850
0
    return 0;
851
0
}
852
853
static int atoi_internal( const char *str, int *b_error )
854
0
{
855
0
    char *end;
856
0
    int v = strtol( str, &end, 0 );
857
0
    if( end == str || *end != '\0' )
858
0
        *b_error = 1;
859
0
    return v;
860
0
}
861
862
static double atof_internal( const char *str, int *b_error )
863
0
{
864
0
    char *end;
865
0
    double v = strtod( str, &end );
866
0
    if( end == str || *end != '\0' )
867
0
        *b_error = 1;
868
0
    return v;
869
0
}
870
871
0
#define atobool(str) ( name_was_bool = 1, atobool_internal( str, &b_error ) )
872
#undef atoi
873
#undef atof
874
0
#define atoi(str) atoi_internal( str, &b_error )
875
0
#define atof(str) atof_internal( str, &b_error )
876
0
#define CHECKED_ERROR_PARAM_STRDUP( var, param, src )\
877
0
do {\
878
0
    var = x264_param_strdup( param, src );\
879
0
    if( !var )\
880
0
    {\
881
0
        b_error = 1;\
882
0
        errortype = X264_PARAM_ALLOC_FAILED;\
883
0
    }\
884
0
} while( 0 )
885
886
REALIGN_STACK int x264_param_parse( x264_param_t *p, const char *name, const char *value )
887
0
{
888
0
    char *name_buf = NULL;
889
0
    int b_error = 0;
890
0
    int errortype = X264_PARAM_BAD_VALUE;
891
0
    int name_was_bool;
892
0
    int value_was_null = !value;
893
894
0
    if( !name )
895
0
        return X264_PARAM_BAD_NAME;
896
0
    if( !value )
897
0
        value = "true";
898
899
0
    if( value[0] == '=' )
900
0
        value++;
901
902
0
    if( strchr( name, '_' ) ) // s/_/-/g
903
0
    {
904
0
        char *c;
905
0
        name_buf = strdup(name);
906
0
        if( !name_buf )
907
0
            return X264_PARAM_ALLOC_FAILED;
908
0
        while( (c = strchr( name_buf, '_' )) )
909
0
            *c = '-';
910
0
        name = name_buf;
911
0
    }
912
913
0
    if( !strncmp( name, "no", 2 ) )
914
0
    {
915
0
        name += 2;
916
0
        if( name[0] == '-' )
917
0
            name++;
918
0
        value = atobool(value) ? "false" : "true";
919
0
    }
920
0
    name_was_bool = 0;
921
922
0
#define OPT(STR) else if( !strcmp( name, STR ) )
923
0
#define OPT2(STR0, STR1) else if( !strcmp( name, STR0 ) || !strcmp( name, STR1 ) )
924
0
    if( 0 );
925
0
    OPT("asm")
926
0
    {
927
0
        p->cpu = X264_ISDIGIT(value[0]) ? (uint32_t)atoi(value) :
928
0
                 !strcasecmp(value, "auto") || atobool(value) ? x264_cpu_detect() : 0;
929
0
        if( b_error )
930
0
        {
931
0
            char *buf = strdup( value );
932
0
            if( buf )
933
0
            {
934
0
                char *tok, UNUSED *saveptr=NULL, *init;
935
0
                b_error = 0;
936
0
                p->cpu = 0;
937
0
                for( init=buf; (tok=strtok_r(init, ",", &saveptr)); init=NULL )
938
0
                {
939
0
                    int i = 0;
940
0
                    while( x264_cpu_names[i].flags && strcasecmp(tok, x264_cpu_names[i].name) )
941
0
                        i++;
942
0
                    p->cpu |= x264_cpu_names[i].flags;
943
0
                    if( !x264_cpu_names[i].flags )
944
0
                        b_error = 1;
945
0
                }
946
0
                free( buf );
947
0
                if( (p->cpu&X264_CPU_SSSE3) && !(p->cpu&X264_CPU_SSE2_IS_SLOW) )
948
0
                    p->cpu |= X264_CPU_SSE2_IS_FAST;
949
0
            }
950
0
            else
951
0
                errortype = X264_PARAM_ALLOC_FAILED;
952
0
        }
953
0
    }
954
0
    OPT("threads")
955
0
    {
956
0
        if( !strcasecmp(value, "auto") )
957
0
            p->i_threads = X264_THREADS_AUTO;
958
0
        else
959
0
            p->i_threads = atoi(value);
960
0
    }
961
0
    OPT("lookahead-threads")
962
0
    {
963
0
        if( !strcasecmp(value, "auto") )
964
0
            p->i_lookahead_threads = X264_THREADS_AUTO;
965
0
        else
966
0
            p->i_lookahead_threads = atoi(value);
967
0
    }
968
0
    OPT("sliced-threads")
969
0
        p->b_sliced_threads = atobool(value);
970
0
    OPT("sync-lookahead")
971
0
    {
972
0
        if( !strcasecmp(value, "auto") )
973
0
            p->i_sync_lookahead = X264_SYNC_LOOKAHEAD_AUTO;
974
0
        else
975
0
            p->i_sync_lookahead = atoi(value);
976
0
    }
977
0
    OPT2("deterministic", "n-deterministic")
978
0
        p->b_deterministic = atobool(value);
979
0
    OPT("cpu-independent")
980
0
        p->b_cpu_independent = atobool(value);
981
0
    OPT2("level", "level-idc")
982
0
    {
983
0
        if( !strcmp(value, "1b") )
984
0
            p->i_level_idc = 9;
985
0
        else if( atof(value) < 7 )
986
0
            p->i_level_idc = (int)(10*atof(value)+.5);
987
0
        else
988
0
            p->i_level_idc = atoi(value);
989
0
    }
990
0
    OPT("bluray-compat")
991
0
        p->b_bluray_compat = atobool(value);
992
0
    OPT("avcintra-class")
993
0
        p->i_avcintra_class = atoi(value);
994
0
    OPT("avcintra-flavor")
995
0
        b_error |= parse_enum( value, x264_avcintra_flavor_names, &p->i_avcintra_flavor );
996
0
    OPT("sar")
997
0
    {
998
0
        b_error |= ( 2 != sscanf( value, "%d:%d", &p->vui.i_sar_width, &p->vui.i_sar_height ) &&
999
0
                     2 != sscanf( value, "%d/%d", &p->vui.i_sar_width, &p->vui.i_sar_height ) );
1000
0
    }
1001
0
    OPT("overscan")
1002
0
        b_error |= parse_enum( value, x264_overscan_names, &p->vui.i_overscan );
1003
0
    OPT("videoformat")
1004
0
        b_error |= parse_enum( value, x264_vidformat_names, &p->vui.i_vidformat );
1005
0
    OPT("fullrange")
1006
0
        b_error |= parse_enum( value, x264_fullrange_names, &p->vui.b_fullrange );
1007
0
    OPT("colorprim")
1008
0
        b_error |= parse_enum( value, x264_colorprim_names, &p->vui.i_colorprim );
1009
0
    OPT("transfer")
1010
0
        b_error |= parse_enum( value, x264_transfer_names, &p->vui.i_transfer );
1011
0
    OPT("colormatrix")
1012
0
        b_error |= parse_enum( value, x264_colmatrix_names, &p->vui.i_colmatrix );
1013
0
    OPT("chromaloc")
1014
0
    {
1015
0
        p->vui.i_chroma_loc = atoi(value);
1016
0
        b_error |= ( p->vui.i_chroma_loc < 0 || p->vui.i_chroma_loc > 5 );
1017
0
    }
1018
0
    OPT("mastering-display")
1019
0
    {
1020
0
        if( strcasecmp( value, "undef" ) )
1021
0
        {
1022
0
            b_error |= sscanf( value, "G(%d,%d)B(%d,%d)R(%d,%d)WP(%d,%d)L(%"SCNd64",%"SCNd64")",
1023
0
                               &p->mastering_display.i_green_x, &p->mastering_display.i_green_y,
1024
0
                               &p->mastering_display.i_blue_x, &p->mastering_display.i_blue_y,
1025
0
                               &p->mastering_display.i_red_x, &p->mastering_display.i_red_y,
1026
0
                               &p->mastering_display.i_white_x, &p->mastering_display.i_white_y,
1027
0
                               &p->mastering_display.i_display_max, &p->mastering_display.i_display_min ) != 10;
1028
0
            p->mastering_display.b_mastering_display = !b_error;
1029
0
        }
1030
0
        else
1031
0
            p->mastering_display.b_mastering_display = 0;
1032
0
    }
1033
0
    OPT("cll")
1034
0
    {
1035
0
        if( strcasecmp( value, "undef" ) )
1036
0
        {
1037
0
            b_error |= sscanf( value, "%d,%d",
1038
0
                               &p->content_light_level.i_max_cll, &p->content_light_level.i_max_fall ) != 2;
1039
0
            p->content_light_level.b_cll = !b_error;
1040
0
        }
1041
0
        else
1042
0
            p->content_light_level.b_cll = 0;
1043
0
    }
1044
0
    OPT("alternative-transfer")
1045
0
        b_error |= parse_enum( value, x264_transfer_names, &p->i_alternative_transfer );
1046
0
    OPT("fps")
1047
0
    {
1048
0
        int64_t i_fps_num;
1049
0
        int64_t i_fps_den;
1050
0
        if( sscanf( value, "%"SCNd64"/%"SCNd64, &i_fps_num, &i_fps_den ) == 2 )
1051
0
        {
1052
0
            p->i_fps_num = i_fps_num;
1053
0
            p->i_fps_den = i_fps_den;
1054
0
            b_error |= i_fps_num < 1 || i_fps_num > UINT32_MAX || i_fps_den < 1 || i_fps_den > UINT32_MAX;
1055
0
        }
1056
0
        else
1057
0
        {
1058
0
            double fps = atof(value);
1059
0
            if( fps < 0.0005 || fps > INT_MAX )
1060
0
                b_error = 1;
1061
0
            else if( fps <= INT_MAX/1000.0 )
1062
0
            {
1063
0
                p->i_fps_num = (int)(fps * 1000.0 + .5);
1064
0
                p->i_fps_den = 1000;
1065
0
            }
1066
0
            else
1067
0
            {
1068
0
                p->i_fps_num = atoi(value);
1069
0
                p->i_fps_den = 1;
1070
0
            }
1071
0
        }
1072
0
    }
1073
0
    OPT2("ref", "frameref")
1074
0
        p->i_frame_reference = atoi(value);
1075
0
    OPT("dpb-size")
1076
0
        p->i_dpb_size = atoi(value);
1077
0
    OPT("keyint")
1078
0
    {
1079
0
        if( strstr( value, "infinite" ) )
1080
0
            p->i_keyint_max = X264_KEYINT_MAX_INFINITE;
1081
0
        else
1082
0
            p->i_keyint_max = atoi(value);
1083
0
    }
1084
0
    OPT2("min-keyint", "keyint-min")
1085
0
    {
1086
0
        p->i_keyint_min = atoi(value);
1087
0
        if( p->i_keyint_max < p->i_keyint_min )
1088
0
            p->i_keyint_max = p->i_keyint_min;
1089
0
    }
1090
0
    OPT("scenecut")
1091
0
    {
1092
0
        p->i_scenecut_threshold = atobool(value);
1093
0
        if( b_error || p->i_scenecut_threshold )
1094
0
        {
1095
0
            b_error = 0;
1096
0
            p->i_scenecut_threshold = atoi(value);
1097
0
        }
1098
0
    }
1099
0
    OPT("intra-refresh")
1100
0
        p->b_intra_refresh = atobool(value);
1101
0
    OPT("bframes")
1102
0
        p->i_bframe = atoi(value);
1103
0
    OPT("b-adapt")
1104
0
    {
1105
0
        p->i_bframe_adaptive = atobool(value);
1106
0
        if( b_error )
1107
0
        {
1108
0
            b_error = 0;
1109
0
            p->i_bframe_adaptive = atoi(value);
1110
0
        }
1111
0
    }
1112
0
    OPT("b-bias")
1113
0
        p->i_bframe_bias = atoi(value);
1114
0
    OPT("b-pyramid")
1115
0
    {
1116
0
        b_error |= parse_enum( value, x264_b_pyramid_names, &p->i_bframe_pyramid );
1117
0
        if( b_error )
1118
0
        {
1119
0
            b_error = 0;
1120
0
            p->i_bframe_pyramid = atoi(value);
1121
0
        }
1122
0
    }
1123
0
    OPT("open-gop")
1124
0
        p->b_open_gop = atobool(value);
1125
0
    OPT("nf")
1126
0
        p->b_deblocking_filter = !atobool(value);
1127
0
    OPT2("filter", "deblock")
1128
0
    {
1129
0
        if( 2 == sscanf( value, "%d:%d", &p->i_deblocking_filter_alphac0, &p->i_deblocking_filter_beta ) ||
1130
0
            2 == sscanf( value, "%d,%d", &p->i_deblocking_filter_alphac0, &p->i_deblocking_filter_beta ) )
1131
0
        {
1132
0
            p->b_deblocking_filter = 1;
1133
0
        }
1134
0
        else if( sscanf( value, "%d", &p->i_deblocking_filter_alphac0 ) )
1135
0
        {
1136
0
            p->b_deblocking_filter = 1;
1137
0
            p->i_deblocking_filter_beta = p->i_deblocking_filter_alphac0;
1138
0
        }
1139
0
        else
1140
0
            p->b_deblocking_filter = atobool(value);
1141
0
    }
1142
0
    OPT("slice-max-size")
1143
0
        p->i_slice_max_size = atoi(value);
1144
0
    OPT("slice-max-mbs")
1145
0
        p->i_slice_max_mbs = atoi(value);
1146
0
    OPT("slice-min-mbs")
1147
0
        p->i_slice_min_mbs = atoi(value);
1148
0
    OPT("slices")
1149
0
        p->i_slice_count = atoi(value);
1150
0
    OPT("slices-max")
1151
0
        p->i_slice_count_max = atoi(value);
1152
0
    OPT("cabac")
1153
0
        p->b_cabac = atobool(value);
1154
0
    OPT("cabac-idc")
1155
0
        p->i_cabac_init_idc = atoi(value);
1156
0
    OPT("interlaced")
1157
0
        p->b_interlaced = atobool(value);
1158
0
    OPT("tff")
1159
0
        p->b_interlaced = p->b_tff = atobool(value);
1160
0
    OPT("bff")
1161
0
    {
1162
0
        p->b_interlaced = atobool(value);
1163
0
        p->b_tff = !p->b_interlaced;
1164
0
    }
1165
0
    OPT("constrained-intra")
1166
0
        p->b_constrained_intra = atobool(value);
1167
0
    OPT("cqm")
1168
0
    {
1169
0
        if( strstr( value, "flat" ) )
1170
0
            p->i_cqm_preset = X264_CQM_FLAT;
1171
0
        else if( strstr( value, "jvt" ) )
1172
0
            p->i_cqm_preset = X264_CQM_JVT;
1173
0
        else
1174
0
            CHECKED_ERROR_PARAM_STRDUP( p->psz_cqm_file, p, value );
1175
0
    }
1176
0
    OPT("cqmfile")
1177
0
        CHECKED_ERROR_PARAM_STRDUP( p->psz_cqm_file, p, value );
1178
0
    OPT("cqm4")
1179
0
    {
1180
0
        p->i_cqm_preset = X264_CQM_CUSTOM;
1181
0
        b_error |= parse_cqm( value, p->cqm_4iy, 16 );
1182
0
        b_error |= parse_cqm( value, p->cqm_4py, 16 );
1183
0
        b_error |= parse_cqm( value, p->cqm_4ic, 16 );
1184
0
        b_error |= parse_cqm( value, p->cqm_4pc, 16 );
1185
0
    }
1186
0
    OPT("cqm8")
1187
0
    {
1188
0
        p->i_cqm_preset = X264_CQM_CUSTOM;
1189
0
        b_error |= parse_cqm( value, p->cqm_8iy, 64 );
1190
0
        b_error |= parse_cqm( value, p->cqm_8py, 64 );
1191
0
        b_error |= parse_cqm( value, p->cqm_8ic, 64 );
1192
0
        b_error |= parse_cqm( value, p->cqm_8pc, 64 );
1193
0
    }
1194
0
    OPT("cqm4i")
1195
0
    {
1196
0
        p->i_cqm_preset = X264_CQM_CUSTOM;
1197
0
        b_error |= parse_cqm( value, p->cqm_4iy, 16 );
1198
0
        b_error |= parse_cqm( value, p->cqm_4ic, 16 );
1199
0
    }
1200
0
    OPT("cqm4p")
1201
0
    {
1202
0
        p->i_cqm_preset = X264_CQM_CUSTOM;
1203
0
        b_error |= parse_cqm( value, p->cqm_4py, 16 );
1204
0
        b_error |= parse_cqm( value, p->cqm_4pc, 16 );
1205
0
    }
1206
0
    OPT("cqm4iy")
1207
0
    {
1208
0
        p->i_cqm_preset = X264_CQM_CUSTOM;
1209
0
        b_error |= parse_cqm( value, p->cqm_4iy, 16 );
1210
0
    }
1211
0
    OPT("cqm4ic")
1212
0
    {
1213
0
        p->i_cqm_preset = X264_CQM_CUSTOM;
1214
0
        b_error |= parse_cqm( value, p->cqm_4ic, 16 );
1215
0
    }
1216
0
    OPT("cqm4py")
1217
0
    {
1218
0
        p->i_cqm_preset = X264_CQM_CUSTOM;
1219
0
        b_error |= parse_cqm( value, p->cqm_4py, 16 );
1220
0
    }
1221
0
    OPT("cqm4pc")
1222
0
    {
1223
0
        p->i_cqm_preset = X264_CQM_CUSTOM;
1224
0
        b_error |= parse_cqm( value, p->cqm_4pc, 16 );
1225
0
    }
1226
0
    OPT("cqm8i")
1227
0
    {
1228
0
        p->i_cqm_preset = X264_CQM_CUSTOM;
1229
0
        b_error |= parse_cqm( value, p->cqm_8iy, 64 );
1230
0
        b_error |= parse_cqm( value, p->cqm_8ic, 64 );
1231
0
    }
1232
0
    OPT("cqm8p")
1233
0
    {
1234
0
        p->i_cqm_preset = X264_CQM_CUSTOM;
1235
0
        b_error |= parse_cqm( value, p->cqm_8py, 64 );
1236
0
        b_error |= parse_cqm( value, p->cqm_8pc, 64 );
1237
0
    }
1238
0
    OPT("log")
1239
0
        p->i_log_level = atoi(value);
1240
0
    OPT("dump-yuv")
1241
0
        CHECKED_ERROR_PARAM_STRDUP( p->psz_dump_yuv, p, value );
1242
0
    OPT2("analyse", "partitions")
1243
0
    {
1244
0
        p->analyse.inter = 0;
1245
0
        if( strstr( value, "none" ) )  p->analyse.inter =  0;
1246
0
        if( strstr( value, "all" ) )   p->analyse.inter = ~0;
1247
1248
0
        if( strstr( value, "i4x4" ) )  p->analyse.inter |= X264_ANALYSE_I4x4;
1249
0
        if( strstr( value, "i8x8" ) )  p->analyse.inter |= X264_ANALYSE_I8x8;
1250
0
        if( strstr( value, "p8x8" ) )  p->analyse.inter |= X264_ANALYSE_PSUB16x16;
1251
0
        if( strstr( value, "p4x4" ) )  p->analyse.inter |= X264_ANALYSE_PSUB8x8;
1252
0
        if( strstr( value, "b8x8" ) )  p->analyse.inter |= X264_ANALYSE_BSUB16x16;
1253
0
    }
1254
0
    OPT("8x8dct")
1255
0
        p->analyse.b_transform_8x8 = atobool(value);
1256
0
    OPT2("weightb", "weight-b")
1257
0
        p->analyse.b_weighted_bipred = atobool(value);
1258
0
    OPT("weightp")
1259
0
        p->analyse.i_weighted_pred = atoi(value);
1260
0
    OPT2("direct", "direct-pred")
1261
0
        b_error |= parse_enum( value, x264_direct_pred_names, &p->analyse.i_direct_mv_pred );
1262
0
    OPT("chroma-qp-offset")
1263
0
        p->analyse.i_chroma_qp_offset = atoi(value);
1264
0
    OPT("me")
1265
0
        b_error |= parse_enum( value, x264_motion_est_names, &p->analyse.i_me_method );
1266
0
    OPT2("merange", "me-range")
1267
0
        p->analyse.i_me_range = atoi(value);
1268
0
    OPT2("mvrange", "mv-range")
1269
0
        p->analyse.i_mv_range = atoi(value);
1270
0
    OPT2("mvrange-thread", "mv-range-thread")
1271
0
        p->analyse.i_mv_range_thread = atoi(value);
1272
0
    OPT2("subme", "subq")
1273
0
        p->analyse.i_subpel_refine = atoi(value);
1274
0
    OPT("psy-rd")
1275
0
    {
1276
0
        if( 2 == sscanf( value, "%f:%f", &p->analyse.f_psy_rd, &p->analyse.f_psy_trellis ) ||
1277
0
            2 == sscanf( value, "%f,%f", &p->analyse.f_psy_rd, &p->analyse.f_psy_trellis ) ||
1278
0
            2 == sscanf( value, "%f|%f", &p->analyse.f_psy_rd, &p->analyse.f_psy_trellis ))
1279
0
        { }
1280
0
        else if( sscanf( value, "%f", &p->analyse.f_psy_rd ) )
1281
0
        {
1282
0
            p->analyse.f_psy_trellis = 0;
1283
0
        }
1284
0
        else
1285
0
        {
1286
0
            p->analyse.f_psy_rd = 0;
1287
0
            p->analyse.f_psy_trellis = 0;
1288
0
        }
1289
0
    }
1290
0
    OPT("psy")
1291
0
        p->analyse.b_psy = atobool(value);
1292
0
    OPT("chroma-me")
1293
0
        p->analyse.b_chroma_me = atobool(value);
1294
0
    OPT("mixed-refs")
1295
0
        p->analyse.b_mixed_references = atobool(value);
1296
0
    OPT("trellis")
1297
0
        p->analyse.i_trellis = atoi(value);
1298
0
    OPT("fast-pskip")
1299
0
        p->analyse.b_fast_pskip = atobool(value);
1300
0
    OPT("dct-decimate")
1301
0
        p->analyse.b_dct_decimate = atobool(value);
1302
0
    OPT("deadzone-inter")
1303
0
        p->analyse.i_luma_deadzone[0] = atoi(value);
1304
0
    OPT("deadzone-intra")
1305
0
        p->analyse.i_luma_deadzone[1] = atoi(value);
1306
0
    OPT("nr")
1307
0
        p->analyse.i_noise_reduction = atoi(value);
1308
0
    OPT("bitrate")
1309
0
    {
1310
0
        p->rc.i_bitrate = atoi(value);
1311
0
        p->rc.i_rc_method = X264_RC_ABR;
1312
0
    }
1313
0
    OPT2("qp", "qp_constant")
1314
0
    {
1315
0
        p->rc.i_qp_constant = atoi(value);
1316
0
        p->rc.i_rc_method = X264_RC_CQP;
1317
0
    }
1318
0
    OPT("crf")
1319
0
    {
1320
0
        p->rc.f_rf_constant = atof(value);
1321
0
        p->rc.i_rc_method = X264_RC_CRF;
1322
0
    }
1323
0
    OPT("crf-max")
1324
0
        p->rc.f_rf_constant_max = atof(value);
1325
0
    OPT("rc-lookahead")
1326
0
        p->rc.i_lookahead = atoi(value);
1327
0
    OPT2("qpmin", "qp-min")
1328
0
        p->rc.i_qp_min = atoi(value);
1329
0
    OPT2("qpmax", "qp-max")
1330
0
        p->rc.i_qp_max = atoi(value);
1331
0
    OPT2("qpstep", "qp-step")
1332
0
        p->rc.i_qp_step = atoi(value);
1333
0
    OPT("ratetol")
1334
0
        p->rc.f_rate_tolerance = !strncmp("inf", value, 3) ? 1e9 : atof(value);
1335
0
    OPT("vbv-maxrate")
1336
0
        p->rc.i_vbv_max_bitrate = atoi(value);
1337
0
    OPT("vbv-bufsize")
1338
0
        p->rc.i_vbv_buffer_size = atoi(value);
1339
0
    OPT("vbv-init")
1340
0
        p->rc.f_vbv_buffer_init = atof(value);
1341
0
    OPT2("ipratio", "ip-factor")
1342
0
        p->rc.f_ip_factor = atof(value);
1343
0
    OPT2("pbratio", "pb-factor")
1344
0
        p->rc.f_pb_factor = atof(value);
1345
0
    OPT("aq-mode")
1346
0
        p->rc.i_aq_mode = atoi(value);
1347
0
    OPT("aq-strength")
1348
0
        p->rc.f_aq_strength = atof(value);
1349
0
    OPT("pass")
1350
0
    {
1351
0
        int pass = x264_clip3( atoi(value), 0, 3 );
1352
0
        p->rc.b_stat_write = pass & 1;
1353
0
        p->rc.b_stat_read = pass & 2;
1354
0
    }
1355
0
    OPT("stats")
1356
0
    {
1357
0
        CHECKED_ERROR_PARAM_STRDUP( p->rc.psz_stat_in, p, value );
1358
0
        CHECKED_ERROR_PARAM_STRDUP( p->rc.psz_stat_out, p, value );
1359
0
    }
1360
0
    OPT("qcomp")
1361
0
        p->rc.f_qcompress = atof(value);
1362
0
    OPT("mbtree")
1363
0
        p->rc.b_mb_tree = atobool(value);
1364
0
    OPT("qblur")
1365
0
        p->rc.f_qblur = atof(value);
1366
0
    OPT2("cplxblur", "cplx-blur")
1367
0
        p->rc.f_complexity_blur = atof(value);
1368
0
    OPT("zones")
1369
0
        CHECKED_ERROR_PARAM_STRDUP( p->rc.psz_zones, p, value );
1370
0
    OPT("crop-rect")
1371
0
        b_error |= sscanf( value, "%d,%d,%d,%d", &p->crop_rect.i_left, &p->crop_rect.i_top,
1372
0
                                                 &p->crop_rect.i_right, &p->crop_rect.i_bottom ) != 4;
1373
0
    OPT("psnr")
1374
0
        p->analyse.b_psnr = atobool(value);
1375
0
    OPT("ssim")
1376
0
        p->analyse.b_ssim = atobool(value);
1377
0
    OPT("aud")
1378
0
        p->b_aud = atobool(value);
1379
0
    OPT("sps-id")
1380
0
        p->i_sps_id = atoi(value);
1381
0
    OPT("global-header")
1382
0
        p->b_repeat_headers = !atobool(value);
1383
0
    OPT("repeat-headers")
1384
0
        p->b_repeat_headers = atobool(value);
1385
0
    OPT("annexb")
1386
0
        p->b_annexb = atobool(value);
1387
0
    OPT("force-cfr")
1388
0
        p->b_vfr_input = !atobool(value);
1389
0
    OPT("nal-hrd")
1390
0
        b_error |= parse_enum( value, x264_nal_hrd_names, &p->i_nal_hrd );
1391
0
    OPT("filler")
1392
0
        p->rc.b_filler = atobool(value);
1393
0
    OPT("pic-struct")
1394
0
        p->b_pic_struct = atobool(value);
1395
0
    OPT("fake-interlaced")
1396
0
        p->b_fake_interlaced = atobool(value);
1397
0
    OPT("frame-packing")
1398
0
        p->i_frame_packing = atoi(value);
1399
0
    OPT("stitchable")
1400
0
        p->b_stitchable = atobool(value);
1401
0
    OPT("opencl")
1402
0
        p->b_opencl = atobool( value );
1403
0
    OPT("opencl-clbin")
1404
0
        CHECKED_ERROR_PARAM_STRDUP( p->psz_clbin_file, p, value );
1405
0
    OPT("opencl-device")
1406
0
        p->i_opencl_device = atoi( value );
1407
0
    else
1408
0
    {
1409
0
        b_error = 1;
1410
0
        errortype = X264_PARAM_BAD_NAME;
1411
0
    }
1412
0
#undef OPT
1413
0
#undef OPT2
1414
0
#undef atobool
1415
0
#undef atoi
1416
0
#undef atof
1417
1418
0
    if( name_buf )
1419
0
        free( name_buf );
1420
1421
0
    b_error |= value_was_null && !name_was_bool;
1422
0
    return b_error ? errortype : 0;
1423
0
}
1424
1425
/****************************************************************************
1426
 * x264_param2string:
1427
 ****************************************************************************/
1428
char *x264_param2string( x264_param_t *p, int b_res )
1429
0
{
1430
0
    int len = 2000;
1431
0
    char *buf, *s;
1432
0
    if( p->rc.psz_zones )
1433
0
        len += strlen(p->rc.psz_zones);
1434
0
    buf = s = x264_malloc( len );
1435
0
    if( !buf )
1436
0
        return NULL;
1437
1438
0
    if( b_res )
1439
0
    {
1440
0
        s += sprintf( s, "%dx%d ", p->i_width, p->i_height );
1441
0
        s += sprintf( s, "fps=%u/%u ", p->i_fps_num, p->i_fps_den );
1442
0
        s += sprintf( s, "timebase=%u/%u ", p->i_timebase_num, p->i_timebase_den );
1443
0
        s += sprintf( s, "bitdepth=%d ", p->i_bitdepth );
1444
0
    }
1445
1446
0
    if( p->b_opencl )
1447
0
        s += sprintf( s, "opencl=%d ", p->b_opencl );
1448
0
    s += sprintf( s, "cabac=%d", p->b_cabac );
1449
0
    s += sprintf( s, " ref=%d", p->i_frame_reference );
1450
0
    s += sprintf( s, " deblock=%d:%d:%d", p->b_deblocking_filter,
1451
0
                  p->i_deblocking_filter_alphac0, p->i_deblocking_filter_beta );
1452
0
    s += sprintf( s, " analyse=%#x:%#x", p->analyse.intra, p->analyse.inter );
1453
0
    s += sprintf( s, " me=%s", x264_motion_est_names[ p->analyse.i_me_method ] );
1454
0
    s += sprintf( s, " subme=%d", p->analyse.i_subpel_refine );
1455
0
    s += sprintf( s, " psy=%d", p->analyse.b_psy );
1456
0
    if( p->analyse.b_psy )
1457
0
        s += sprintf( s, " psy_rd=%.2f:%.2f", p->analyse.f_psy_rd, p->analyse.f_psy_trellis );
1458
0
    s += sprintf( s, " mixed_ref=%d", p->analyse.b_mixed_references );
1459
0
    s += sprintf( s, " me_range=%d", p->analyse.i_me_range );
1460
0
    s += sprintf( s, " chroma_me=%d", p->analyse.b_chroma_me );
1461
0
    s += sprintf( s, " trellis=%d", p->analyse.i_trellis );
1462
0
    s += sprintf( s, " 8x8dct=%d", p->analyse.b_transform_8x8 );
1463
0
    s += sprintf( s, " cqm=%d", p->i_cqm_preset );
1464
0
    s += sprintf( s, " deadzone=%d,%d", p->analyse.i_luma_deadzone[0], p->analyse.i_luma_deadzone[1] );
1465
0
    s += sprintf( s, " fast_pskip=%d", p->analyse.b_fast_pskip );
1466
0
    s += sprintf( s, " chroma_qp_offset=%d", p->analyse.i_chroma_qp_offset );
1467
0
    s += sprintf( s, " threads=%d", p->i_threads );
1468
0
    s += sprintf( s, " lookahead_threads=%d", p->i_lookahead_threads );
1469
0
    s += sprintf( s, " sliced_threads=%d", p->b_sliced_threads );
1470
0
    if( p->i_slice_count )
1471
0
        s += sprintf( s, " slices=%d", p->i_slice_count );
1472
0
    if( p->i_slice_count_max )
1473
0
        s += sprintf( s, " slices_max=%d", p->i_slice_count_max );
1474
0
    if( p->i_slice_max_size )
1475
0
        s += sprintf( s, " slice_max_size=%d", p->i_slice_max_size );
1476
0
    if( p->i_slice_max_mbs )
1477
0
        s += sprintf( s, " slice_max_mbs=%d", p->i_slice_max_mbs );
1478
0
    if( p->i_slice_min_mbs )
1479
0
        s += sprintf( s, " slice_min_mbs=%d", p->i_slice_min_mbs );
1480
0
    s += sprintf( s, " nr=%d", p->analyse.i_noise_reduction );
1481
0
    s += sprintf( s, " decimate=%d", p->analyse.b_dct_decimate );
1482
0
    s += sprintf( s, " interlaced=%s", p->b_interlaced ? p->b_tff ? "tff" : "bff" : p->b_fake_interlaced ? "fake" : "0" );
1483
0
    s += sprintf( s, " bluray_compat=%d", p->b_bluray_compat );
1484
0
    if( p->b_stitchable )
1485
0
        s += sprintf( s, " stitchable=%d", p->b_stitchable );
1486
1487
0
    s += sprintf( s, " constrained_intra=%d", p->b_constrained_intra );
1488
1489
0
    s += sprintf( s, " bframes=%d", p->i_bframe );
1490
0
    if( p->i_bframe )
1491
0
    {
1492
0
        s += sprintf( s, " b_pyramid=%d b_adapt=%d b_bias=%d direct=%d weightb=%d open_gop=%d",
1493
0
                      p->i_bframe_pyramid, p->i_bframe_adaptive, p->i_bframe_bias,
1494
0
                      p->analyse.i_direct_mv_pred, p->analyse.b_weighted_bipred, p->b_open_gop );
1495
0
    }
1496
0
    s += sprintf( s, " weightp=%d", p->analyse.i_weighted_pred > 0 ? p->analyse.i_weighted_pred : 0 );
1497
1498
0
    if( p->i_keyint_max == X264_KEYINT_MAX_INFINITE )
1499
0
        s += sprintf( s, " keyint=infinite" );
1500
0
    else
1501
0
        s += sprintf( s, " keyint=%d", p->i_keyint_max );
1502
0
    s += sprintf( s, " keyint_min=%d scenecut=%d intra_refresh=%d",
1503
0
                  p->i_keyint_min, p->i_scenecut_threshold, p->b_intra_refresh );
1504
1505
0
    if( p->rc.b_mb_tree || p->rc.i_vbv_buffer_size )
1506
0
        s += sprintf( s, " rc_lookahead=%d", p->rc.i_lookahead );
1507
1508
0
    s += sprintf( s, " rc=%s mbtree=%d", p->rc.i_rc_method == X264_RC_ABR ?
1509
0
                               ( p->rc.b_stat_read ? "2pass" : p->rc.i_vbv_max_bitrate == p->rc.i_bitrate ? "cbr" : "abr" )
1510
0
                               : p->rc.i_rc_method == X264_RC_CRF ? "crf" : "cqp", p->rc.b_mb_tree );
1511
0
    if( p->rc.i_rc_method == X264_RC_ABR || p->rc.i_rc_method == X264_RC_CRF )
1512
0
    {
1513
0
        if( p->rc.i_rc_method == X264_RC_CRF )
1514
0
            s += sprintf( s, " crf=%.1f", p->rc.f_rf_constant );
1515
0
        else
1516
0
            s += sprintf( s, " bitrate=%d ratetol=%.1f",
1517
0
                          p->rc.i_bitrate, p->rc.f_rate_tolerance );
1518
0
        s += sprintf( s, " qcomp=%.2f qpmin=%d qpmax=%d qpstep=%d",
1519
0
                      p->rc.f_qcompress, p->rc.i_qp_min, p->rc.i_qp_max, p->rc.i_qp_step );
1520
0
        if( p->rc.b_stat_read )
1521
0
            s += sprintf( s, " cplxblur=%.1f qblur=%.1f",
1522
0
                          p->rc.f_complexity_blur, p->rc.f_qblur );
1523
0
        if( p->rc.i_vbv_buffer_size )
1524
0
        {
1525
0
            s += sprintf( s, " vbv_maxrate=%d vbv_bufsize=%d",
1526
0
                          p->rc.i_vbv_max_bitrate, p->rc.i_vbv_buffer_size );
1527
0
            if( p->rc.i_rc_method == X264_RC_CRF )
1528
0
                s += sprintf( s, " crf_max=%.1f", p->rc.f_rf_constant_max );
1529
0
        }
1530
0
    }
1531
0
    else if( p->rc.i_rc_method == X264_RC_CQP )
1532
0
        s += sprintf( s, " qp=%d", p->rc.i_qp_constant );
1533
1534
0
    if( p->rc.i_vbv_buffer_size )
1535
0
        s += sprintf( s, " nal_hrd=%s filler=%d", x264_nal_hrd_names[p->i_nal_hrd], p->rc.b_filler );
1536
0
    if( p->crop_rect.i_left | p->crop_rect.i_top | p->crop_rect.i_right | p->crop_rect.i_bottom )
1537
0
        s += sprintf( s, " crop_rect=%d,%d,%d,%d", p->crop_rect.i_left, p->crop_rect.i_top,
1538
0
                                                   p->crop_rect.i_right, p->crop_rect.i_bottom );
1539
0
    if( p->mastering_display.b_mastering_display )
1540
0
        s += sprintf( s, " mastering-display=G(%d,%d)B(%d,%d)R(%d,%d)WP(%d,%d)L(%"PRId64",%"PRId64")",
1541
0
                      p->mastering_display.i_green_x, p->mastering_display.i_green_y,
1542
0
                      p->mastering_display.i_blue_x, p->mastering_display.i_blue_y,
1543
0
                      p->mastering_display.i_red_x, p->mastering_display.i_red_y,
1544
0
                      p->mastering_display.i_white_x, p->mastering_display.i_white_y,
1545
0
                      p->mastering_display.i_display_max, p->mastering_display.i_display_min );
1546
0
    if( p->content_light_level.b_cll )
1547
0
        s += sprintf( s, " cll=%d,%d",
1548
0
                      p->content_light_level.i_max_cll, p->content_light_level.i_max_fall );
1549
0
    if( p->i_frame_packing >= 0 )
1550
0
        s += sprintf( s, " frame-packing=%d", p->i_frame_packing );
1551
1552
0
    if( !(p->rc.i_rc_method == X264_RC_CQP && p->rc.i_qp_constant == 0) )
1553
0
    {
1554
0
        s += sprintf( s, " ip_ratio=%.2f", p->rc.f_ip_factor );
1555
0
        if( p->i_bframe && !p->rc.b_mb_tree )
1556
0
            s += sprintf( s, " pb_ratio=%.2f", p->rc.f_pb_factor );
1557
0
        s += sprintf( s, " aq=%d", p->rc.i_aq_mode );
1558
0
        if( p->rc.i_aq_mode )
1559
0
            s += sprintf( s, ":%.2f", p->rc.f_aq_strength );
1560
0
        if( p->rc.psz_zones )
1561
0
            s += sprintf( s, " zones=%s", p->rc.psz_zones );
1562
0
        else if( p->rc.i_zones )
1563
0
            s += sprintf( s, " zones" );
1564
0
    }
1565
1566
0
    return buf;
1567
0
}