encoder.c 129 KB
Newer Older
Laurent Aimar's avatar
Laurent Aimar committed
1
/*****************************************************************************
Fiona Glaser's avatar
Fiona Glaser committed
2
 * encoder.c: top-level encoder functions
Laurent Aimar's avatar
Laurent Aimar committed
3
 *****************************************************************************
Sean McGovern's avatar
Sean McGovern committed
4
 * Copyright (C) 2003-2011 x264 project
Laurent Aimar's avatar
Laurent Aimar committed
5 6
 *
 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
7
 *          Loren Merritt <lorenm@u.washington.edu>
8
 *          Fiona Glaser <fiona@x264.com>
Laurent Aimar's avatar
Laurent Aimar committed
9 10 11 12 13 14 15 16 17 18 19 20 21
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
22
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
Fiona Glaser's avatar
Fiona Glaser committed
23 24 25
 *
 * This program is also available under a commercial proprietary license.
 * For more information, contact us at licensing@x264.com.
Laurent Aimar's avatar
Laurent Aimar committed
26 27 28 29
 *****************************************************************************/

#include <math.h>

30
#include "common/common.h"
Laurent Aimar's avatar
Laurent Aimar committed
31 32 33 34 35

#include "set.h"
#include "analyse.h"
#include "ratecontrol.h"
#include "macroblock.h"
36
#include "me.h"
Laurent Aimar's avatar
Laurent Aimar committed
37

Steven Walters's avatar
Steven Walters committed
38
#if HAVE_VISUALIZE
Loren Merritt's avatar
Loren Merritt committed
39 40 41
#include "common/visualize.h"
#endif

Laurent Aimar's avatar
Laurent Aimar committed
42 43
//#define DEBUG_MB_TYPE

Fiona Glaser's avatar
Fiona Glaser committed
44 45
#define bs_write_ue bs_write_ue_big

Fiona Glaser's avatar
Fiona Glaser committed
46
static int x264_encoder_frame_end( x264_t *h, x264_t *thread_current,
47 48
                                   x264_nal_t **pp_nal, int *pi_nal,
                                   x264_picture_t *pic_out );
Loren Merritt's avatar
Loren Merritt committed
49

Laurent Aimar's avatar
Laurent Aimar committed
50 51 52 53 54
/****************************************************************************
 *
 ******************************* x264 libs **********************************
 *
 ****************************************************************************/
Fiona Glaser's avatar
Fiona Glaser committed
55
static double x264_psnr( double sqe, double size )
56
{
Fiona Glaser's avatar
Fiona Glaser committed
57 58
    double mse = sqe / (PIXEL_MAX*PIXEL_MAX * size);
    if( mse <= 0.0000000001 ) /* Max 100dB */
59 60
        return 100;

Fiona Glaser's avatar
Fiona Glaser committed
61
    return -10.0 * log10( mse );
62 63
}

Fiona Glaser's avatar
Fiona Glaser committed
64
static double x264_ssim( double ssim )
65 66 67 68
{
    return -10.0 * log10( 1 - ssim );
}

69
static void x264_frame_dump( x264_t *h )
Laurent Aimar's avatar
Laurent Aimar committed
70
{
71
    FILE *f = fopen( h->param.psz_dump_yuv, "r+b" );
72 73 74
    if( !f )
        return;
    /* Write the frame in display order */
75 76 77 78 79
    fseek( f, (uint64_t)h->fdec->i_frame * h->param.i_height * h->param.i_width * 3/2 * sizeof(pixel), SEEK_SET );
    for( int y = 0; y < h->param.i_height; y++ )
        fwrite( &h->fdec->plane[0][y*h->fdec->i_stride[0]], sizeof(pixel), h->param.i_width, f );
    int cw = h->param.i_width>>1;
    int ch = h->param.i_height>>1;
80 81
    pixel *planeu = x264_malloc( (cw*ch*2+32)*sizeof(pixel) );
    pixel *planev = planeu + cw*ch + 16;
82
    h->mc.plane_copy_deinterleave( planeu, cw, planev, cw, h->fdec->plane[1], h->fdec->i_stride[1], cw, ch );
83 84
    fwrite( planeu, 1, cw*ch*sizeof(pixel), f );
    fwrite( planev, 1, cw*ch*sizeof(pixel), f );
85
    x264_free( planeu );
Laurent Aimar's avatar
Laurent Aimar committed
86 87 88 89 90
    fclose( f );
}


/* Fill "default" values */
91
static void x264_slice_header_init( x264_t *h, x264_slice_header_t *sh,
Laurent Aimar's avatar
Laurent Aimar committed
92
                                    x264_sps_t *sps, x264_pps_t *pps,
Loren Merritt's avatar
Loren Merritt committed
93
                                    int i_idr_pic_id, int i_frame, int i_qp )
Laurent Aimar's avatar
Laurent Aimar committed
94
{
95 96
    x264_param_t *param = &h->param;

97
    /* First we fill all fields */
Laurent Aimar's avatar
Laurent Aimar committed
98 99 100 101
    sh->sps = sps;
    sh->pps = pps;

    sh->i_first_mb  = 0;
Fiona Glaser's avatar
Fiona Glaser committed
102
    sh->i_last_mb   = h->mb.i_mb_count - 1;
Laurent Aimar's avatar
Laurent Aimar committed
103 104 105 106
    sh->i_pps_id    = pps->i_id;

    sh->i_frame_num = i_frame;

107 108 109
    sh->b_mbaff = h->param.b_interlaced;
    sh->b_field_pic = 0;    /* no field support for now */
    sh->b_bottom_field = 0; /* not yet used */
Laurent Aimar's avatar
Laurent Aimar committed
110 111 112 113

    sh->i_idr_pic_id = i_idr_pic_id;

    /* poc stuff, fixed later */
114
    sh->i_poc = 0;
Laurent Aimar's avatar
Laurent Aimar committed
115 116 117 118 119 120
    sh->i_delta_poc_bottom = 0;
    sh->i_delta_poc[0] = 0;
    sh->i_delta_poc[1] = 0;

    sh->i_redundant_pic_cnt = 0;

121 122 123 124 125
    h->mb.b_direct_auto_write = h->param.analyse.i_direct_mv_pred == X264_DIRECT_PRED_AUTO
                                && h->param.i_bframe
                                && ( h->param.rc.b_stat_write || !h->param.rc.b_stat_read );

    if( !h->mb.b_direct_auto_read && sh->i_type == SLICE_TYPE_B )
Loren Merritt's avatar
Loren Merritt committed
126
    {
127
        if( h->fref[1][0]->i_poc_l0ref0 == h->fref[0][0]->i_poc )
128 129 130 131 132 133
        {
            if( h->mb.b_direct_auto_write )
                sh->b_direct_spatial_mv_pred = ( h->stat.i_direct_score[1] > h->stat.i_direct_score[0] );
            else
                sh->b_direct_spatial_mv_pred = ( param->analyse.i_direct_mv_pred == X264_DIRECT_PRED_SPATIAL );
        }
Loren Merritt's avatar
Loren Merritt committed
134
        else
135 136 137 138
        {
            h->mb.b_direct_auto_write = 0;
            sh->b_direct_spatial_mv_pred = 1;
        }
Loren Merritt's avatar
Loren Merritt committed
139 140
    }
    /* else b_direct_spatial_mv_pred was read from the 2pass statsfile */
Laurent Aimar's avatar
Laurent Aimar committed
141 142 143 144 145

    sh->b_num_ref_idx_override = 0;
    sh->i_num_ref_idx_l0_active = 1;
    sh->i_num_ref_idx_l1_active = 1;

146 147
    sh->b_ref_pic_list_reordering[0] = h->b_ref_reorder[0];
    sh->b_ref_pic_list_reordering[1] = h->b_ref_reorder[1];
148 149

    /* If the ref list isn't in the default order, construct reordering header */
150
    for( int list = 0; list < 2; list++ )
151
    {
152
        if( sh->b_ref_pic_list_reordering[list] )
153
        {
154 155 156 157 158 159 160 161
            int pred_frame_num = i_frame;
            for( int i = 0; i < h->i_ref[list]; i++ )
            {
                int diff = h->fref[list][i]->i_frame_num - pred_frame_num;
                sh->ref_pic_list_order[list][i].idc = ( diff > 0 );
                sh->ref_pic_list_order[list][i].arg = (abs(diff) - 1) & ((1 << sps->i_log2_max_frame_num) - 1);
                pred_frame_num = h->fref[list][i]->i_frame_num;
            }
162 163 164
        }
    }

Laurent Aimar's avatar
Laurent Aimar committed
165 166
    sh->i_cabac_init_idc = param->i_cabac_init_idc;

Fiona Glaser's avatar
Fiona Glaser committed
167 168
    sh->i_qp = SPEC_QP(i_qp);
    sh->i_qp_delta = sh->i_qp - pps->i_pic_init_qp;
Laurent Aimar's avatar
Laurent Aimar committed
169 170 171
    sh->b_sp_for_swidth = 0;
    sh->i_qs_delta = 0;

172
    int deblock_thresh = i_qp + 2 * X264_MIN(param->i_deblocking_filter_alphac0, param->i_deblocking_filter_beta);
173
    /* If effective qp <= 15, deblocking would have no effect anyway */
174
    if( param->b_deblocking_filter && (h->mb.b_variable_qp || 15 < deblock_thresh ) )
175
        sh->i_disable_deblocking_filter_idc = param->b_sliced_threads ? 2 : 0;
Laurent Aimar's avatar
Laurent Aimar committed
176 177 178 179 180 181 182 183
    else
        sh->i_disable_deblocking_filter_idc = 1;
    sh->i_alpha_c0_offset = param->i_deblocking_filter_alphac0 << 1;
    sh->i_beta_offset = param->i_deblocking_filter_beta << 1;
}

static void x264_slice_header_write( bs_t *s, x264_slice_header_t *sh, int i_nal_ref_idc )
{
184 185 186 187 188 189 190 191
    if( sh->b_mbaff )
    {
        assert( sh->i_first_mb % (2*sh->sps->i_mb_width) == 0 );
        bs_write_ue( s, sh->i_first_mb >> 1 );
    }
    else
        bs_write_ue( s, sh->i_first_mb );

Laurent Aimar's avatar
Laurent Aimar committed
192 193
    bs_write_ue( s, sh->i_type + 5 );   /* same type things */
    bs_write_ue( s, sh->i_pps_id );
Fiona Glaser's avatar
Fiona Glaser committed
194
    bs_write( s, sh->sps->i_log2_max_frame_num, sh->i_frame_num & ((1<<sh->sps->i_log2_max_frame_num)-1) );
Laurent Aimar's avatar
Laurent Aimar committed
195

196 197 198
    if( !sh->sps->b_frame_mbs_only )
    {
        bs_write1( s, sh->b_field_pic );
Fiona Glaser's avatar
Fiona Glaser committed
199
        if( sh->b_field_pic )
200 201 202
            bs_write1( s, sh->b_bottom_field );
    }

Laurent Aimar's avatar
Laurent Aimar committed
203 204 205 206 207
    if( sh->i_idr_pic_id >= 0 ) /* NAL IDR */
        bs_write_ue( s, sh->i_idr_pic_id );

    if( sh->sps->i_poc_type == 0 )
    {
208
        bs_write( s, sh->sps->i_log2_max_poc_lsb, sh->i_poc & ((1<<sh->sps->i_log2_max_poc_lsb)-1) );
Laurent Aimar's avatar
Laurent Aimar committed
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
        if( sh->pps->b_pic_order && !sh->b_field_pic )
            bs_write_se( s, sh->i_delta_poc_bottom );
    }
    else if( sh->sps->i_poc_type == 1 && !sh->sps->b_delta_pic_order_always_zero )
    {
        bs_write_se( s, sh->i_delta_poc[0] );
        if( sh->pps->b_pic_order && !sh->b_field_pic )
            bs_write_se( s, sh->i_delta_poc[1] );
    }

    if( sh->pps->b_redundant_pic_cnt )
        bs_write_ue( s, sh->i_redundant_pic_cnt );

    if( sh->i_type == SLICE_TYPE_B )
        bs_write1( s, sh->b_direct_spatial_mv_pred );
224

225
    if( sh->i_type == SLICE_TYPE_P || sh->i_type == SLICE_TYPE_B )
Laurent Aimar's avatar
Laurent Aimar committed
226 227 228 229 230 231 232 233 234 235 236 237 238
    {
        bs_write1( s, sh->b_num_ref_idx_override );
        if( sh->b_num_ref_idx_override )
        {
            bs_write_ue( s, sh->i_num_ref_idx_l0_active - 1 );
            if( sh->i_type == SLICE_TYPE_B )
                bs_write_ue( s, sh->i_num_ref_idx_l1_active - 1 );
        }
    }

    /* ref pic list reordering */
    if( sh->i_type != SLICE_TYPE_I )
    {
239 240
        bs_write1( s, sh->b_ref_pic_list_reordering[0] );
        if( sh->b_ref_pic_list_reordering[0] )
Laurent Aimar's avatar
Laurent Aimar committed
241
        {
242
            for( int i = 0; i < sh->i_num_ref_idx_l0_active; i++ )
243 244 245 246 247
            {
                bs_write_ue( s, sh->ref_pic_list_order[0][i].idc );
                bs_write_ue( s, sh->ref_pic_list_order[0][i].arg );
            }
            bs_write_ue( s, 3 );
Laurent Aimar's avatar
Laurent Aimar committed
248 249 250 251
        }
    }
    if( sh->i_type == SLICE_TYPE_B )
    {
252 253
        bs_write1( s, sh->b_ref_pic_list_reordering[1] );
        if( sh->b_ref_pic_list_reordering[1] )
Laurent Aimar's avatar
Laurent Aimar committed
254
        {
255
            for( int i = 0; i < sh->i_num_ref_idx_l1_active; i++ )
256 257 258 259 260
            {
                bs_write_ue( s, sh->ref_pic_list_order[1][i].idc );
                bs_write_ue( s, sh->ref_pic_list_order[1][i].arg );
            }
            bs_write_ue( s, 3 );
Laurent Aimar's avatar
Laurent Aimar committed
261 262 263
        }
    }

264
    if( sh->pps->b_weighted_pred && sh->i_type == SLICE_TYPE_P )
Laurent Aimar's avatar
Laurent Aimar committed
265
    {
Dylan Yudaken's avatar
Dylan Yudaken committed
266 267 268
        /* pred_weight_table() */
        bs_write_ue( s, sh->weight[0][0].i_denom );
        bs_write_ue( s, sh->weight[0][1].i_denom );
269
        for( int i = 0; i < sh->i_num_ref_idx_l0_active; i++ )
Dylan Yudaken's avatar
Dylan Yudaken committed
270 271 272 273 274 275 276 277 278 279 280 281
        {
            int luma_weight_l0_flag = !!sh->weight[i][0].weightfn;
            int chroma_weight_l0_flag = !!sh->weight[i][1].weightfn || !!sh->weight[i][2].weightfn;
            bs_write1( s, luma_weight_l0_flag );
            if( luma_weight_l0_flag )
            {
                bs_write_se( s, sh->weight[i][0].i_scale );
                bs_write_se( s, sh->weight[i][0].i_offset );
            }
            bs_write1( s, chroma_weight_l0_flag );
            if( chroma_weight_l0_flag )
            {
282
                for( int j = 1; j < 3; j++ )
Dylan Yudaken's avatar
Dylan Yudaken committed
283 284 285 286 287 288 289 290 291 292
                {
                    bs_write_se( s, sh->weight[i][j].i_scale );
                    bs_write_se( s, sh->weight[i][j].i_offset );
                }
            }
        }
    }
    else if( sh->pps->b_weighted_bipred == 1 && sh->i_type == SLICE_TYPE_B )
    {
      /* TODO */
Laurent Aimar's avatar
Laurent Aimar committed
293 294 295 296 297 298 299 300 301 302 303
    }

    if( i_nal_ref_idc != 0 )
    {
        if( sh->i_idr_pic_id >= 0 )
        {
            bs_write1( s, 0 );  /* no output of prior pics flag */
            bs_write1( s, 0 );  /* long term reference flag */
        }
        else
        {
Lamont Alston's avatar
Lamont Alston committed
304 305 306
            bs_write1( s, sh->i_mmco_command_count > 0 ); /* adaptive_ref_pic_marking_mode_flag */
            if( sh->i_mmco_command_count > 0 )
            {
307
                for( int i = 0; i < sh->i_mmco_command_count; i++ )
Lamont Alston's avatar
Lamont Alston committed
308 309 310 311 312 313
                {
                    bs_write_ue( s, 1 ); /* mark short term ref as unused */
                    bs_write_ue( s, sh->mmco[i].i_difference_of_pic_nums - 1 );
                }
                bs_write_ue( s, 0 ); /* end command list */
            }
Laurent Aimar's avatar
Laurent Aimar committed
314 315 316 317 318
        }
    }

    if( sh->pps->b_cabac && sh->i_type != SLICE_TYPE_I )
        bs_write_ue( s, sh->i_cabac_init_idc );
319

Laurent Aimar's avatar
Laurent Aimar committed
320 321 322 323 324 325 326 327 328 329 330 331 332
    bs_write_se( s, sh->i_qp_delta );      /* slice qp delta */

    if( sh->pps->b_deblocking_filter_control )
    {
        bs_write_ue( s, sh->i_disable_deblocking_filter_idc );
        if( sh->i_disable_deblocking_filter_idc != 1 )
        {
            bs_write_se( s, sh->i_alpha_c0_offset >> 1 );
            bs_write_se( s, sh->i_beta_offset >> 1 );
        }
    }
}

333 334
/* If we are within a reasonable distance of the end of the memory allocated for the bitstream, */
/* reallocate, adding an arbitrary amount of space (100 kilobytes). */
335
static int x264_bitstream_check_buffer( x264_t *h )
336
{
337
    uint8_t *bs_bak = h->out.p_bitstream;
338 339
    if( (h->param.b_cabac && (h->cabac.p_end - h->cabac.p < 2500)) ||
        (h->out.bs.p_end - h->out.bs.p < 2500) )
340 341
    {
        h->out.i_bitstream += 100000;
342 343
        CHECKED_MALLOC( h->out.p_bitstream, h->out.i_bitstream );
        h->mc.memcpy_aligned( h->out.p_bitstream, bs_bak, (h->out.i_bitstream - 100000) & ~15 );
344
        intptr_t delta = h->out.p_bitstream - bs_bak;
345 346 347 348 349 350 351 352 353

        h->out.bs.p_start += delta;
        h->out.bs.p += delta;
        h->out.bs.p_end = h->out.p_bitstream + h->out.i_bitstream;

        h->cabac.p_start += delta;
        h->cabac.p += delta;
        h->cabac.p_end = h->out.p_bitstream + h->out.i_bitstream;

354
        for( int i = 0; i <= h->out.i_nal; i++ )
355
            h->out.nal[i].p_payload += delta;
356
        x264_free( bs_bak );
357
    }
358 359 360 361
    return 0;
fail:
    x264_free( bs_bak );
    return -1;
362 363
}

364
#if HAVE_THREAD
365 366 367 368 369 370 371 372 373 374 375 376 377
static void x264_encoder_thread_init( x264_t *h )
{
    if( h->param.i_sync_lookahead )
        x264_lower_thread_priority( 10 );

#if HAVE_MMX
    /* Misalign mask has to be set separately for each thread. */
    if( h->param.cpu&X264_CPU_SSE_MISALIGN )
        x264_cpu_mask_misalign_sse();
#endif
}
#endif

Laurent Aimar's avatar
Laurent Aimar committed
378 379 380 381 382 383 384 385
/****************************************************************************
 *
 ****************************************************************************
 ****************************** External API*********************************
 ****************************************************************************
 *
 ****************************************************************************/

386
static int x264_validate_parameters( x264_t *h )
Laurent Aimar's avatar
Laurent Aimar committed
387
{
Steven Walters's avatar
Steven Walters committed
388
#if HAVE_MMX
389
#ifdef __SSE__
390
    if( !(x264_cpu_detect() & X264_CPU_SSE) )
391
    {
392
        x264_log( h, X264_LOG_ERROR, "your cpu does not support SSE1, but x264 was compiled with asm support\n");
393 394 395 396 397
#else
    if( !(x264_cpu_detect() & X264_CPU_MMXEXT) )
    {
        x264_log( h, X264_LOG_ERROR, "your cpu does not support MMXEXT, but x264 was compiled with asm support\n");
#endif
398 399 400 401
        x264_log( h, X264_LOG_ERROR, "to run x264, recompile without asm support (configure --disable-asm)\n");
        return -1;
    }
#endif
402
    if( h->param.i_width <= 0 || h->param.i_height <= 0 )
Laurent Aimar's avatar
Laurent Aimar committed
403
    {
404
        x264_log( h, X264_LOG_ERROR, "invalid width x height (%dx%d)\n",
405 406
                  h->param.i_width, h->param.i_height );
        return -1;
Laurent Aimar's avatar
Laurent Aimar committed
407 408
    }

Loren Merritt's avatar
Loren Merritt committed
409
    if( h->param.i_width % 2 || h->param.i_height % 2 )
Laurent Aimar's avatar
Laurent Aimar committed
410
    {
Loren Merritt's avatar
Loren Merritt committed
411
        x264_log( h, X264_LOG_ERROR, "width or height not divisible by 2 (%dx%d)\n",
412 413
                  h->param.i_width, h->param.i_height );
        return -1;
Laurent Aimar's avatar
Laurent Aimar committed
414
    }
415
    int i_csp = h->param.i_csp & X264_CSP_MASK;
416
    if( i_csp <= X264_CSP_NONE || i_csp >= X264_CSP_MAX )
Laurent Aimar's avatar
Laurent Aimar committed
417
    {
418
        x264_log( h, X264_LOG_ERROR, "invalid CSP (only I420/YV12/NV12 supported)\n" );
419
        return -1;
Laurent Aimar's avatar
Laurent Aimar committed
420 421
    }

422 423 424 425 426 427 428 429
    if( (h->param.crop_rect.i_left + h->param.crop_rect.i_right ) >= h->param.i_width ||
        (h->param.crop_rect.i_top  + h->param.crop_rect.i_bottom) >= h->param.i_height )
    {
        x264_log( h, X264_LOG_ERROR, "invalid crop-rect %u,%u,%u,%u\n", h->param.crop_rect.i_left,
                  h->param.crop_rect.i_top, h->param.crop_rect.i_right,  h->param.crop_rect.i_bottom );
        return -1;
    }

Steven Walters's avatar
Steven Walters committed
430
    if( h->param.i_threads == X264_THREADS_AUTO )
Fiona Glaser's avatar
Fiona Glaser committed
431
        h->param.i_threads = x264_cpu_num_processors() * (h->param.b_sliced_threads?2:3)/2;
Loren Merritt's avatar
Loren Merritt committed
432
    h->param.i_threads = x264_clip3( h->param.i_threads, 1, X264_THREAD_MAX );
Loren Merritt's avatar
Loren Merritt committed
433 434
    if( h->param.i_threads > 1 )
    {
435 436
#if !HAVE_THREAD
        x264_log( h, X264_LOG_WARNING, "not compiled with thread support!\n");
Loren Merritt's avatar
Loren Merritt committed
437
        h->param.i_threads = 1;
Loren Merritt's avatar
Loren Merritt committed
438
#endif
439 440 441 442 443 444 445
        /* Avoid absurdly small thread slices as they can reduce performance
         * and VBV compliance.  Capped at an arbitrary 4 rows per thread. */
        if( h->param.b_sliced_threads )
        {
            int max_threads = (h->param.i_height+15)/16 / 4;
            h->param.i_threads = X264_MIN( h->param.i_threads, max_threads );
        }
Loren Merritt's avatar
Loren Merritt committed
446
    }
447 448
    else
        h->param.b_sliced_threads = 0;
449
    h->i_thread_frames = h->param.b_sliced_threads ? 1 : h->param.i_threads;
450 451
    if( h->i_thread_frames > 1 )
        h->param.nalu_process = NULL;
Loren Merritt's avatar
Loren Merritt committed
452

453 454 455 456 457 458 459
    h->param.i_keyint_max = x264_clip3( h->param.i_keyint_max, 1, X264_KEYINT_MAX_INFINITE );
    if( h->param.i_keyint_max == 1 )
    {
        h->param.b_intra_refresh = 0;
        h->param.analyse.i_weighted_pred = 0;
    }

460 461
    if( h->param.b_interlaced )
    {
462
        if( h->param.analyse.i_me_method >= X264_ME_ESA )
463 464 465 466
        {
            x264_log( h, X264_LOG_WARNING, "interlace + me=esa is not implemented\n" );
            h->param.analyse.i_me_method = X264_ME_UMH;
        }
Dylan Yudaken's avatar
Dylan Yudaken committed
467 468 469 470 471
        if( h->param.analyse.i_weighted_pred > 0 )
        {
            x264_log( h, X264_LOG_WARNING, "interlace + weightp is not implemented\n" );
            h->param.analyse.i_weighted_pred = X264_WEIGHTP_NONE;
        }
472 473
    }

474 475
    h->param.i_frame_packing = x264_clip3( h->param.i_frame_packing, -1, 5 );

476 477 478 479 480 481 482 483 484 485 486 487 488 489 490
    /* Detect default ffmpeg settings and terminate with an error. */
    {
        int score = 0;
        score += h->param.analyse.i_me_range == 0;
        score += h->param.rc.i_qp_step == 3;
        score += h->param.i_keyint_max == 12;
        score += h->param.rc.i_qp_min == 2;
        score += h->param.rc.i_qp_max == 31;
        score += h->param.rc.f_qcompress == 0.5;
        score += fabs(h->param.rc.f_ip_factor - 1.25) < 0.01;
        score += fabs(h->param.rc.f_pb_factor - 1.25) < 0.01;
        score += h->param.analyse.inter == 0 && h->param.analyse.i_subpel_refine == 8;
        if( score >= 5 )
        {
            x264_log( h, X264_LOG_ERROR, "broken ffmpeg default settings detected\n" );
491 492 493 494
            x264_log( h, X264_LOG_ERROR, "use an encoding preset (e.g. -vpre medium)\n" );
            x264_log( h, X264_LOG_ERROR, "preset usage: -vpre <speed> -vpre <profile>\n" );
            x264_log( h, X264_LOG_ERROR, "speed presets are listed in x264 --help\n" );
            x264_log( h, X264_LOG_ERROR, "profile is optional; x264 defaults to high\n" );
495 496 497 498
            return -1;
        }
    }

499 500
    if( h->param.rc.i_rc_method < 0 || h->param.rc.i_rc_method > 2 )
    {
501
        x264_log( h, X264_LOG_ERROR, "no ratecontrol method specified\n" );
502 503
        return -1;
    }
Fiona Glaser's avatar
Fiona Glaser committed
504
    h->param.rc.f_rf_constant = x264_clip3f( h->param.rc.f_rf_constant, -QP_BD_OFFSET, 51 );
505
    h->param.rc.i_qp_constant = x264_clip3( h->param.rc.i_qp_constant, 0, QP_MAX );
506
    if( h->param.rc.i_rc_method == X264_RC_CRF )
Fiona Glaser's avatar
Fiona Glaser committed
507
    {
Fiona Glaser's avatar
Fiona Glaser committed
508
        h->param.rc.i_qp_constant = h->param.rc.f_rf_constant + QP_BD_OFFSET;
Fiona Glaser's avatar
Fiona Glaser committed
509 510
        h->param.rc.i_bitrate = 0;
    }
511 512
    if( (h->param.rc.i_rc_method == X264_RC_CQP || h->param.rc.i_rc_method == X264_RC_CRF)
        && h->param.rc.i_qp_constant == 0 )
Loren Merritt's avatar
Loren Merritt committed
513 514
    {
        h->mb.b_lossless = 1;
Loren Merritt's avatar
Loren Merritt committed
515
        h->param.i_cqm_preset = X264_CQM_FLAT;
Loren Merritt's avatar
Loren Merritt committed
516
        h->param.psz_cqm_file = NULL;
517
        h->param.rc.i_rc_method = X264_RC_CQP;
Loren Merritt's avatar
Loren Merritt committed
518 519 520
        h->param.rc.f_ip_factor = 1;
        h->param.rc.f_pb_factor = 1;
        h->param.analyse.b_psnr = 0;
521
        h->param.analyse.b_ssim = 0;
522
        h->param.analyse.i_chroma_qp_offset = 0;
523
        h->param.analyse.i_trellis = 0;
Loren Merritt's avatar
Loren Merritt committed
524
        h->param.analyse.b_fast_pskip = 0;
525
        h->param.analyse.i_noise_reduction = 0;
Anton Mitrofanov's avatar
Anton Mitrofanov committed
526
        h->param.analyse.b_psy = 0;
527
        h->param.i_bframe = 0;
528 529
        /* 8x8dct is not useful without RD in CAVLC lossless */
        if( !h->param.b_cabac && h->param.analyse.i_subpel_refine < 6 )
530
            h->param.analyse.b_transform_8x8 = 0;
Loren Merritt's avatar
Loren Merritt committed
531
    }
Loren Merritt's avatar
Loren Merritt committed
532 533 534
    if( h->param.rc.i_rc_method == X264_RC_CQP )
    {
        float qp_p = h->param.rc.i_qp_constant;
535 536
        float qp_i = qp_p - 6*log2f( h->param.rc.f_ip_factor );
        float qp_b = qp_p + 6*log2f( h->param.rc.f_pb_factor );
537 538
        h->param.rc.i_qp_min = x264_clip3( (int)(X264_MIN3( qp_p, qp_i, qp_b )), 0, QP_MAX );
        h->param.rc.i_qp_max = x264_clip3( (int)(X264_MAX3( qp_p, qp_i, qp_b ) + .999), 0, QP_MAX );
Loren Merritt's avatar
Loren Merritt committed
539
        h->param.rc.i_aq_mode = 0;
Fiona Glaser's avatar
Fiona Glaser committed
540
        h->param.rc.b_mb_tree = 0;
Loren Merritt's avatar
Loren Merritt committed
541
    }
542
    h->param.rc.i_qp_max = x264_clip3( h->param.rc.i_qp_max, 0, QP_MAX );
543
    h->param.rc.i_qp_min = x264_clip3( h->param.rc.i_qp_min, 0, h->param.rc.i_qp_max );
544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576
    if( h->param.rc.i_vbv_buffer_size )
    {
        if( h->param.rc.i_rc_method == X264_RC_CQP )
        {
            x264_log( h, X264_LOG_WARNING, "VBV is incompatible with constant QP, ignored.\n" );
            h->param.rc.i_vbv_max_bitrate = 0;
            h->param.rc.i_vbv_buffer_size = 0;
        }
        else if( h->param.rc.i_vbv_max_bitrate == 0 )
        {
            if( h->param.rc.i_rc_method == X264_RC_ABR )
            {
                x264_log( h, X264_LOG_WARNING, "VBV maxrate unspecified, assuming CBR\n" );
                h->param.rc.i_vbv_max_bitrate = h->param.rc.i_bitrate;
            }
            else
            {
                x264_log( h, X264_LOG_WARNING, "VBV bufsize set but maxrate unspecified, ignored\n" );
                h->param.rc.i_vbv_buffer_size = 0;
            }
        }
        else if( h->param.rc.i_vbv_max_bitrate < h->param.rc.i_bitrate &&
                 h->param.rc.i_rc_method == X264_RC_ABR )
        {
            x264_log( h, X264_LOG_WARNING, "max bitrate less than average bitrate, assuming CBR\n" );
            h->param.rc.i_vbv_max_bitrate = h->param.rc.i_bitrate;
        }
    }
    else if( h->param.rc.i_vbv_max_bitrate )
    {
        x264_log( h, X264_LOG_WARNING, "VBV maxrate specified, but no bufsize, ignored\n" );
        h->param.rc.i_vbv_max_bitrate = 0;
    }
Loren Merritt's avatar
Loren Merritt committed
577

578 579 580 581 582 583 584 585 586 587
    if( h->param.b_interlaced && h->param.i_slice_max_size )
    {
        x264_log( h, X264_LOG_WARNING, "interlaced + slice-max-size is not implemented\n" );
        h->param.i_slice_max_size = 0;
    }
    if( h->param.b_interlaced && h->param.i_slice_max_mbs )
    {
        x264_log( h, X264_LOG_WARNING, "interlaced + slice-max-mbs is not implemented\n" );
        h->param.i_slice_max_mbs = 0;
    }
Fiona Glaser's avatar
Fiona Glaser committed
588
    int max_slices = (h->param.i_height+((16<<h->param.b_interlaced)-1))/(16<<h->param.b_interlaced);
589 590 591
    if( h->param.b_sliced_threads )
        h->param.i_slice_count = x264_clip3( h->param.i_threads, 0, max_slices );
    else
Fiona Glaser's avatar
Fiona Glaser committed
592
    {
593 594 595 596 597
        h->param.i_slice_count = x264_clip3( h->param.i_slice_count, 0, max_slices );
        h->param.i_slice_max_size = X264_MAX( h->param.i_slice_max_size, 0 );
        h->param.i_slice_max_mbs = X264_MAX( h->param.i_slice_max_mbs, 0 );
        if( h->param.i_slice_max_mbs || h->param.i_slice_max_size )
            h->param.i_slice_count = 0;
Fiona Glaser's avatar
Fiona Glaser committed
598 599
    }

600 601
    h->param.i_frame_reference = x264_clip3( h->param.i_frame_reference, 1, X264_REF_MAX );
    h->param.i_dpb_size = x264_clip3( h->param.i_dpb_size, 1, X264_REF_MAX );
Fiona Glaser's avatar
Fiona Glaser committed
602 603
    if( h->param.i_scenecut_threshold < 0 )
        h->param.i_scenecut_threshold = 0;
604 605 606 607 608
    if( !h->param.analyse.i_subpel_refine && h->param.analyse.i_direct_mv_pred > X264_DIRECT_PRED_SPATIAL )
    {
        x264_log( h, X264_LOG_WARNING, "subme=0 + direct=temporal is not supported\n" );
        h->param.analyse.i_direct_mv_pred = X264_DIRECT_PRED_SPATIAL;
    }
Lamont Alston's avatar
Lamont Alston committed
609
    h->param.i_bframe = x264_clip3( h->param.i_bframe, 0, X264_MIN( X264_BFRAME_MAX, h->param.i_keyint_max-1 ) );
610
    h->param.i_open_gop = x264_clip3( h->param.i_open_gop, X264_OPEN_GOP_NONE, X264_OPEN_GOP_BLURAY );
611
    h->param.i_bframe_bias = x264_clip3( h->param.i_bframe_bias, -90, 100 );
Lamont Alston's avatar
Lamont Alston committed
612 613 614
    if( h->param.i_bframe <= 1 )
        h->param.i_bframe_pyramid = X264_B_PYRAMID_NONE;
    h->param.i_bframe_pyramid = x264_clip3( h->param.i_bframe_pyramid, X264_B_PYRAMID_NONE, X264_B_PYRAMID_NORMAL );
615
    if( !h->param.i_bframe )
616
    {
617
        h->param.i_bframe_adaptive = X264_B_ADAPT_NONE;
618 619
        h->param.analyse.i_direct_mv_pred = 0;
        h->param.analyse.b_weighted_bipred = 0;
Lamont Alston's avatar
Lamont Alston committed
620
        h->param.i_open_gop = X264_OPEN_GOP_NONE;
621
    }
Fiona Glaser's avatar
Fiona Glaser committed
622 623 624 625 626
    if( h->param.b_intra_refresh && h->param.i_bframe_pyramid == X264_B_PYRAMID_NORMAL )
    {
        x264_log( h, X264_LOG_WARNING, "b-pyramid normal + intra-refresh is not supported\n" );
        h->param.i_bframe_pyramid = X264_B_PYRAMID_STRICT;
    }
627
    if( h->param.b_intra_refresh && (h->param.i_frame_reference > 1 || h->param.i_dpb_size > 1) )
Fiona Glaser's avatar
Fiona Glaser committed
628 629 630
    {
        x264_log( h, X264_LOG_WARNING, "ref > 1 + intra-refresh is not supported\n" );
        h->param.i_frame_reference = 1;
631
        h->param.i_dpb_size = 1;
Fiona Glaser's avatar
Fiona Glaser committed
632
    }
Lamont Alston's avatar
Lamont Alston committed
633 634 635 636 637
    if( h->param.b_intra_refresh && h->param.i_open_gop )
    {
        x264_log( h, X264_LOG_WARNING, "intra-refresh is not compatible with open-gop\n" );
        h->param.i_open_gop = X264_OPEN_GOP_NONE;
    }
638
    float fps = h->param.i_fps_num > 0 && h->param.i_fps_den > 0 ? (float) h->param.i_fps_num / h->param.i_fps_den : 25.0;
Fiona Glaser's avatar
Fiona Glaser committed
639
    if( h->param.i_keyint_min == X264_KEYINT_MIN_AUTO )
640
        h->param.i_keyint_min = X264_MIN( h->param.i_keyint_max / 10, fps );
Fiona Glaser's avatar
Fiona Glaser committed
641
    h->param.i_keyint_min = x264_clip3( h->param.i_keyint_min, 1, h->param.i_keyint_max/2+1 );
Fiona Glaser's avatar
Fiona Glaser committed
642
    h->param.rc.i_lookahead = x264_clip3( h->param.rc.i_lookahead, 0, X264_LOOKAHEAD_MAX );
Fiona Glaser's avatar
Fiona Glaser committed
643 644 645 646 647 648
    {
        int maxrate = X264_MAX( h->param.rc.i_vbv_max_bitrate, h->param.rc.i_bitrate );
        float bufsize = maxrate ? (float)h->param.rc.i_vbv_buffer_size / maxrate : 0;
        h->param.rc.i_lookahead = X264_MIN( h->param.rc.i_lookahead, X264_MAX( h->param.i_keyint_max, bufsize*fps ) );
    }

649
    if( !h->param.i_timebase_num || !h->param.i_timebase_den || !(h->param.b_vfr_input || h->param.b_pulldown) )
650 651 652 653 654
    {
        h->param.i_timebase_num = h->param.i_fps_den;
        h->param.i_timebase_den = h->param.i_fps_num;
    }

655
    h->param.rc.f_qcompress = x264_clip3f( h->param.rc.f_qcompress, 0.0, 1.0 );
Fiona Glaser's avatar
Fiona Glaser committed
656
    if( h->param.i_keyint_max == 1 || h->param.rc.f_qcompress == 1 )
657
        h->param.rc.b_mb_tree = 0;
658 659
    if( (!h->param.b_intra_refresh && h->param.i_keyint_max != X264_KEYINT_MAX_INFINITE) &&
        !h->param.rc.i_lookahead && h->param.rc.b_mb_tree )
Fiona Glaser's avatar
Fiona Glaser committed
660
    {
661
        x264_log( h, X264_LOG_WARNING, "lookaheadless mb-tree requires intra refresh or infinite keyint\n" );
Fiona Glaser's avatar
Fiona Glaser committed
662 663
        h->param.rc.b_mb_tree = 0;
    }
Fiona Glaser's avatar
Fiona Glaser committed
664 665
    if( h->param.rc.b_stat_read )
        h->param.rc.i_lookahead = 0;
666
#if HAVE_THREAD
667 668 669
    if( h->param.i_sync_lookahead < 0 )
        h->param.i_sync_lookahead = h->param.i_bframe + 1;
    h->param.i_sync_lookahead = X264_MIN( h->param.i_sync_lookahead, X264_LOOKAHEAD_MAX );
670
    if( h->param.rc.b_stat_read || h->i_thread_frames == 1 )
Steven Walters's avatar
Steven Walters committed
671 672 673 674
        h->param.i_sync_lookahead = 0;
#else
    h->param.i_sync_lookahead = 0;
#endif
Fiona Glaser's avatar
Fiona Glaser committed
675

Laurent Aimar's avatar
Laurent Aimar committed
676 677
    h->param.i_deblocking_filter_alphac0 = x264_clip3( h->param.i_deblocking_filter_alphac0, -6, 6 );
    h->param.i_deblocking_filter_beta    = x264_clip3( h->param.i_deblocking_filter_beta, -6, 6 );
678 679
    h->param.analyse.i_luma_deadzone[0] = x264_clip3( h->param.analyse.i_luma_deadzone[0], 0, 32 );
    h->param.analyse.i_luma_deadzone[1] = x264_clip3( h->param.analyse.i_luma_deadzone[1], 0, 32 );
Laurent Aimar's avatar
Laurent Aimar committed
680

681
    h->param.i_cabac_init_idc = x264_clip3( h->param.i_cabac_init_idc, 0, 2 );
Laurent Aimar's avatar
Laurent Aimar committed
682

Loren Merritt's avatar
Loren Merritt committed
683 684 685
    if( h->param.i_cqm_preset < X264_CQM_FLAT || h->param.i_cqm_preset > X264_CQM_CUSTOM )
        h->param.i_cqm_preset = X264_CQM_FLAT;

686
    if( h->param.analyse.i_me_method < X264_ME_DIA ||
687
        h->param.analyse.i_me_method > X264_ME_TESA )
688
        h->param.analyse.i_me_method = X264_ME_HEX;
689 690 691
    if( h->param.analyse.i_me_range < 4 )
        h->param.analyse.i_me_range = 4;
    if( h->param.analyse.i_me_range > 16 && h->param.analyse.i_me_method <= X264_ME_HEX )
692
        h->param.analyse.i_me_range = 16;
693 694 695
    if( h->param.analyse.i_me_method == X264_ME_TESA &&
        (h->mb.b_lossless || h->param.analyse.i_subpel_refine <= 1) )
        h->param.analyse.i_me_method = X264_ME_ESA;
Fiona Glaser's avatar
Fiona Glaser committed
696
    h->param.analyse.i_subpel_refine = x264_clip3( h->param.analyse.i_subpel_refine, 0, 10 );
697 698 699 700
    h->param.analyse.b_mixed_references = h->param.analyse.b_mixed_references && h->param.i_frame_reference > 1;
    h->param.analyse.inter &= X264_ANALYSE_PSUB16x16|X264_ANALYSE_PSUB8x8|X264_ANALYSE_BSUB16x16|
                              X264_ANALYSE_I4x4|X264_ANALYSE_I8x8;
    h->param.analyse.intra &= X264_ANALYSE_I4x4|X264_ANALYSE_I8x8;
701 702
    if( !(h->param.analyse.inter & X264_ANALYSE_PSUB16x16) )
        h->param.analyse.inter &= ~X264_ANALYSE_PSUB8x8;
703 704 705 706 707
    if( !h->param.analyse.b_transform_8x8 )
    {
        h->param.analyse.inter &= ~X264_ANALYSE_I8x8;
        h->param.analyse.intra &= ~X264_ANALYSE_I8x8;
    }
708
    h->param.analyse.i_chroma_qp_offset = x264_clip3(h->param.analyse.i_chroma_qp_offset, -12, 12);
709
    h->param.analyse.i_trellis = x264_clip3( h->param.analyse.i_trellis, 0, 2 );
Fiona Glaser's avatar
Fiona Glaser committed
710 711 712 713 714
    if( !h->param.analyse.b_psy )
    {
        h->param.analyse.f_psy_rd = 0;
        h->param.analyse.f_psy_trellis = 0;
    }
715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732
    if( !h->param.analyse.i_trellis )
        h->param.analyse.f_psy_trellis = 0;
    h->param.analyse.f_psy_rd = x264_clip3f( h->param.analyse.f_psy_rd, 0, 10 );
    h->param.analyse.f_psy_trellis = x264_clip3f( h->param.analyse.f_psy_trellis, 0, 10 );
    if( h->param.analyse.i_subpel_refine < 6 )
        h->param.analyse.f_psy_rd = 0;
    h->mb.i_psy_rd = FIX8( h->param.analyse.f_psy_rd );
    /* Psy RDO increases overall quantizers to improve the quality of luma--this indirectly hurts chroma quality */
    /* so we lower the chroma QP offset to compensate */
    /* This can be triggered repeatedly on multiple calls to parameter_validate, but since encoding
     * uses the pps chroma qp offset not the param chroma qp offset, this is not a problem. */
    if( h->mb.i_psy_rd )
        h->param.analyse.i_chroma_qp_offset -= h->param.analyse.f_psy_rd < 0.25 ? 1 : 2;
    h->mb.i_psy_trellis = FIX8( h->param.analyse.f_psy_trellis / 4 );
    /* Psy trellis has a similar effect. */
    if( h->mb.i_psy_trellis )
        h->param.analyse.i_chroma_qp_offset -= h->param.analyse.f_psy_trellis < 0.25 ? 1 : 2;
    h->param.analyse.i_chroma_qp_offset = x264_clip3(h->param.analyse.i_chroma_qp_offset, -12, 12);
Anton Mitrofanov's avatar
Anton Mitrofanov committed
733
    h->param.rc.i_aq_mode = x264_clip3( h->param.rc.i_aq_mode, 0, 2 );
734 735
    h->param.rc.f_aq_strength = x264_clip3f( h->param.rc.f_aq_strength, 0, 3 );
    if( h->param.rc.f_aq_strength == 0 )
736
        h->param.rc.i_aq_mode = 0;
Fiona Glaser's avatar
Fiona Glaser committed
737 738 739 740 741 742
    /* MB-tree requires AQ to be on, even if the strength is zero. */
    if( !h->param.rc.i_aq_mode && h->param.rc.b_mb_tree )
    {
        h->param.rc.i_aq_mode = 1;
        h->param.rc.f_aq_strength = 0;
    }
743
    h->param.analyse.i_noise_reduction = x264_clip3( h->param.analyse.i_noise_reduction, 0, 1<<16 );
Fiona Glaser's avatar
Fiona Glaser committed
744 745
    if( h->param.analyse.i_subpel_refine == 10 && (h->param.analyse.i_trellis != 2 || !h->param.rc.i_aq_mode) )
        h->param.analyse.i_subpel_refine = 9;
746

747 748
    {
        const x264_level_t *l = x264_levels;
749
        if( h->param.i_level_idc < 0 )
750
        {
Loren Merritt's avatar
Loren Merritt committed
751
            int maxrate_bak = h->param.rc.i_vbv_max_bitrate;
752 753 754 755 756 757
            if( h->param.rc.i_rc_method == X264_RC_ABR && h->param.rc.i_vbv_buffer_size <= 0 )
                h->param.rc.i_vbv_max_bitrate = h->param.rc.i_bitrate * 2;
            h->sps = h->sps_array;
            x264_sps_init( h->sps, h->param.i_sps_id, &h->param );
            do h->param.i_level_idc = l->level_idc;
                while( l[1].level_idc && x264_validate_levels( h, 0 ) && l++ );
Loren Merritt's avatar
Loren Merritt committed
758
            h->param.rc.i_vbv_max_bitrate = maxrate_bak;
759 760 761 762 763 764 765 766 767 768
        }
        else
        {
            while( l->level_idc && l->level_idc != h->param.i_level_idc )
                l++;
            if( l->level_idc == 0 )
            {
                x264_log( h, X264_LOG_ERROR, "invalid level_idc: %d\n", h->param.i_level_idc );
                return -1;
            }
769 770
        }
        if( h->param.analyse.i_mv_range <= 0 )
771
            h->param.analyse.i_mv_range = l->mv_range >> h->param.b_interlaced;
772
        else
773
            h->param.analyse.i_mv_range = x264_clip3(h->param.analyse.i_mv_range, 32, 512 >> h->param.b_interlaced);
774 775
    }

776
    h->param.analyse.i_weighted_pred = x264_clip3( h->param.analyse.i_weighted_pred, X264_WEIGHTP_NONE, X264_WEIGHTP_SMART );
Dylan Yudaken's avatar
Dylan Yudaken committed
777 778 779
    if( !h->param.analyse.i_weighted_pred && h->param.rc.b_mb_tree && h->param.analyse.b_psy && !h->param.b_interlaced )
        h->param.analyse.i_weighted_pred = X264_WEIGHTP_FAKE;

780
    if( h->i_thread_frames > 1 )
Loren Merritt's avatar
Loren Merritt committed
781 782 783 784 785 786 787 788 789
    {
        int r = h->param.analyse.i_mv_range_thread;
        int r2;
        if( r <= 0 )
        {
            // half of the available space is reserved and divided evenly among the threads,
            // the rest is allocated to whichever thread is far enough ahead to use it.
            // reserving more space increases quality for some videos, but costs more time
            // in thread synchronization.
790
            int max_range = (h->param.i_height + X264_THREAD_HEIGHT) / h->i_thread_frames - X264_THREAD_HEIGHT;
Loren Merritt's avatar
Loren Merritt committed
791 792 793 794 795 796 797 798 799 800 801 802
            r = max_range / 2;
        }
        r = X264_MAX( r, h->param.analyse.i_me_range );
        r = X264_MIN( r, h->param.analyse.i_mv_range );
        // round up to use the whole mb row
        r2 = (r & ~15) + ((-X264_THREAD_HEIGHT) & 15);
        if( r2 < r )
            r2 += 16;
        x264_log( h, X264_LOG_DEBUG, "using mv_range_thread = %d\n", r2 );
        h->param.analyse.i_mv_range_thread = r2;
    }

Loren Merritt's avatar
Loren Merritt committed
803 804 805 806 807
    if( h->param.rc.f_qblur < 0 )
        h->param.rc.f_qblur = 0;
    if( h->param.rc.f_complexity_blur < 0 )
        h->param.rc.f_complexity_blur = 0;

808 809
    h->param.i_sps_id &= 31;

810 811 812 813 814 815
    if( h->param.i_log_level < X264_LOG_INFO )
    {
        h->param.analyse.b_psnr = 0;
        h->param.analyse.b_ssim = 0;
    }

816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831
    if( h->param.b_interlaced )
        h->param.b_pic_struct = 1;

    if( h->param.i_nal_hrd && !h->param.rc.i_vbv_buffer_size )
    {
        x264_log( h, X264_LOG_WARNING, "NAL HRD parameters require VBV parameters\n" );
        h->param.i_nal_hrd = X264_NAL_HRD_NONE;
    }

    if( h->param.i_nal_hrd == X264_NAL_HRD_CBR &&
       (h->param.rc.i_bitrate != h->param.rc.i_vbv_max_bitrate || !h->param.rc.i_vbv_max_bitrate) )
    {
        x264_log( h, X264_LOG_WARNING, "CBR HRD requires constant bitrate\n" );
        h->param.i_nal_hrd = X264_NAL_HRD_VBR;
    }

832 833 834
    /* ensure the booleans are 0 or 1 so they can be used in math */
#define BOOLIFY(x) h->param.x = !!h->param.x
    BOOLIFY( b_cabac );
835
    BOOLIFY( b_constrained_intra );
836
    BOOLIFY( b_deblocking_filter );
837
    BOOLIFY( b_deterministic );
838
    BOOLIFY( b_sliced_threads );
839
    BOOLIFY( b_interlaced );
Fiona Glaser's avatar
Fiona Glaser committed
840
    BOOLIFY( b_intra_refresh );
841 842 843 844
    BOOLIFY( b_visualize );
    BOOLIFY( b_aud );
    BOOLIFY( b_repeat_headers );
    BOOLIFY( b_annexb );
845 846
    BOOLIFY( b_vfr_input );
    BOOLIFY( b_pic_struct );
Kieran Kunhya's avatar
Kieran Kunhya committed
847
    BOOLIFY( b_fake_interlaced );
848
    BOOLIFY( analyse.b_transform_8x8 );
849
    BOOLIFY( analyse.b_weighted_bipred );
850
    BOOLIFY( analyse.b_chroma_me );
851
    BOOLIFY( analyse.b_mixed_references );
852
    BOOLIFY( analyse.b_fast_pskip );
853 854 855 856
    BOOLIFY( analyse.b_dct_decimate );
    BOOLIFY( analyse.b_psy );
    BOOLIFY( analyse.b_psnr );
    BOOLIFY( analyse.b_ssim );
857 858
    BOOLIFY( rc.b_stat_write );
    BOOLIFY( rc.b_stat_read );
859
    BOOLIFY( rc.b_mb_tree );
860 861
#undef BOOLIFY

862 863 864
    return 0;
}

865 866
static void mbcmp_init( x264_t *h )
{
867
    int satd = !h->mb.b_lossless && h->param.analyse.i_subpel_refine > 1;
868 869
    memcpy( h->pixf.mbcmp, satd ? h->pixf.satd : h->pixf.sad_aligned, sizeof(h->pixf.mbcmp) );
    memcpy( h->pixf.mbcmp_unaligned, satd ? h->pixf.satd : h->pixf.sad, sizeof(h->pixf.mbcmp_unaligned) );
870
    h->pixf.intra_mbcmp_x3_16x16 = satd ? h->pixf.intra_satd_x3_16x16 : h->pixf.intra_sad_x3_16x16;
Fiona Glaser's avatar
Fiona Glaser committed
871
    h->pixf.intra_mbcmp_x3_8x8c = satd ? h->pixf.intra_satd_x3_8x8c : h->pixf.intra_sad_x3_8x8c;
Fiona Glaser's avatar
Fiona Glaser committed
872
    h->pixf.intra_mbcmp_x3_8x8 = satd ? h->pixf.intra_sa8d_x3_8x8 : h->pixf.intra_sad_x3_8x8;
Fiona Glaser's avatar
Fiona Glaser committed
873
    h->pixf.intra_mbcmp_x3_4x4 = satd ? h->pixf.intra_satd_x3_4x4 : h->pixf.intra_sad_x3_4x4;
874 875 876 877
    satd &= h->param.analyse.i_me_method == X264_ME_TESA;
    memcpy( h->pixf.fpelcmp, satd ? h->pixf.satd : h->pixf.sad, sizeof(h->pixf.fpelcmp) );
    memcpy( h->pixf.fpelcmp_x3, satd ? h->pixf.satd_x3 : h->pixf.sad_x3, sizeof(h->pixf.fpelcmp_x3) );
    memcpy( h->pixf.fpelcmp_x4, satd ? h->pixf.satd_x4 : h->pixf.sad_x4, sizeof(h->pixf.fpelcmp_x4) );
878 879
}

880 881 882 883 884
static void x264_set_aspect_ratio( x264_t *h, x264_param_t *param, int initial )
{
    /* VUI */
    if( param->vui.i_sar_width > 0 && param->vui.i_sar_height > 0 )
    {
885 886 887 888
        uint32_t i_w = param->vui.i_sar_width;
        uint32_t i_h = param->vui.i_sar_height;
        uint32_t old_w = h->param.vui.i_sar_width;
        uint32_t old_h = h->param.vui.i_sar_height;
889 890 891 892 893 894 895 896 897

        x264_reduce_fraction( &i_w, &i_h );

        while( i_w > 65535 || i_h > 65535 )
        {
            i_w /= 2;
            i_h /= 2;
        }

898 899
        x264_reduce_fraction( &i_w, &i_h );