Home | History | Annotate | Download | only in encoder
      1 /*
      2  *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 #include <limits.h>
     12 
     13 #include "vp9/encoder/vp9_encoder.h"
     14 #include "vp9/encoder/vp9_speed_features.h"
     15 #include "vp9/encoder/vp9_rdopt.h"
     16 #include "vpx_dsp/vpx_dsp_common.h"
     17 
     18 // Mesh search patters for various speed settings
     19 static MESH_PATTERN best_quality_mesh_pattern[MAX_MESH_STEP] = {
     20   { 64, 4 }, { 28, 2 }, { 15, 1 }, { 7, 1 }
     21 };
     22 
     23 // Define 3 mesh density levels to control the number of searches.
     24 #define MESH_DENSITY_LEVELS 3
     25 static MESH_PATTERN
     26     good_quality_mesh_patterns[MESH_DENSITY_LEVELS][MAX_MESH_STEP] = {
     27       { { 64, 8 }, { 28, 4 }, { 15, 1 }, { 7, 1 } },
     28       { { 64, 8 }, { 14, 2 }, { 7, 1 }, { 7, 1 } },
     29       { { 64, 16 }, { 24, 8 }, { 12, 4 }, { 7, 1 } },
     30     };
     31 
     32 // Intra only frames, golden frames (except alt ref overlays) and
     33 // alt ref frames tend to be coded at a higher than ambient quality
     34 static int frame_is_boosted(const VP9_COMP *cpi) {
     35   return frame_is_kf_gf_arf(cpi) || vp9_is_upper_layer_key_frame(cpi);
     36 }
     37 
     38 // Sets a partition size down to which the auto partition code will always
     39 // search (can go lower), based on the image dimensions. The logic here
     40 // is that the extent to which ringing artefacts are offensive, depends
     41 // partly on the screen area that over which they propogate. Propogation is
     42 // limited by transform block size but the screen area take up by a given block
     43 // size will be larger for a small image format stretched to full screen.
     44 static BLOCK_SIZE set_partition_min_limit(VP9_COMMON *const cm) {
     45   unsigned int screen_area = (cm->width * cm->height);
     46 
     47   // Select block size based on image format size.
     48   if (screen_area < 1280 * 720) {
     49     // Formats smaller in area than 720P
     50     return BLOCK_4X4;
     51   } else if (screen_area < 1920 * 1080) {
     52     // Format >= 720P and < 1080P
     53     return BLOCK_8X8;
     54   } else {
     55     // Formats 1080P and up
     56     return BLOCK_16X16;
     57   }
     58 }
     59 
     60 static void set_good_speed_feature_framesize_dependent(VP9_COMP *cpi,
     61                                                        SPEED_FEATURES *sf,
     62                                                        int speed) {
     63   VP9_COMMON *const cm = &cpi->common;
     64 
     65   // speed 0 features
     66   sf->partition_search_breakout_thr.dist = (1 << 20);
     67   sf->partition_search_breakout_thr.rate = 80;
     68 
     69   // Currently, the machine-learning based partition search early termination
     70   // is only used while VPXMIN(cm->width, cm->height) >= 480 and speed = 0.
     71   if (VPXMIN(cm->width, cm->height) >= 480) {
     72     sf->ml_partition_search_early_termination = 1;
     73   }
     74 
     75   if (speed >= 1) {
     76     sf->ml_partition_search_early_termination = 0;
     77 
     78     if (VPXMIN(cm->width, cm->height) >= 720) {
     79       sf->disable_split_mask =
     80           cm->show_frame ? DISABLE_ALL_SPLIT : DISABLE_ALL_INTER_SPLIT;
     81       sf->partition_search_breakout_thr.dist = (1 << 23);
     82     } else {
     83       sf->disable_split_mask = DISABLE_COMPOUND_SPLIT;
     84       sf->partition_search_breakout_thr.dist = (1 << 21);
     85     }
     86   }
     87 
     88   if (speed >= 2) {
     89     if (VPXMIN(cm->width, cm->height) >= 720) {
     90       sf->disable_split_mask =
     91           cm->show_frame ? DISABLE_ALL_SPLIT : DISABLE_ALL_INTER_SPLIT;
     92       sf->adaptive_pred_interp_filter = 0;
     93       sf->partition_search_breakout_thr.dist = (1 << 24);
     94       sf->partition_search_breakout_thr.rate = 120;
     95     } else {
     96       sf->disable_split_mask = LAST_AND_INTRA_SPLIT_ONLY;
     97       sf->partition_search_breakout_thr.dist = (1 << 22);
     98       sf->partition_search_breakout_thr.rate = 100;
     99     }
    100     sf->rd_auto_partition_min_limit = set_partition_min_limit(cm);
    101 
    102     // Use a set of speed features for 4k videos.
    103     if (VPXMIN(cm->width, cm->height) >= 2160) {
    104       sf->use_square_partition_only = 1;
    105       sf->intra_y_mode_mask[TX_32X32] = INTRA_DC;
    106       sf->intra_uv_mode_mask[TX_32X32] = INTRA_DC;
    107       sf->alt_ref_search_fp = 1;
    108       sf->cb_pred_filter_search = 1;
    109       sf->adaptive_interp_filter_search = 1;
    110       sf->disable_split_mask = DISABLE_ALL_SPLIT;
    111     }
    112   }
    113 
    114   if (speed >= 3) {
    115     if (VPXMIN(cm->width, cm->height) >= 720) {
    116       sf->disable_split_mask = DISABLE_ALL_SPLIT;
    117       sf->schedule_mode_search = cm->base_qindex < 220 ? 1 : 0;
    118       sf->partition_search_breakout_thr.dist = (1 << 25);
    119       sf->partition_search_breakout_thr.rate = 200;
    120     } else {
    121       sf->max_intra_bsize = BLOCK_32X32;
    122       sf->disable_split_mask = DISABLE_ALL_INTER_SPLIT;
    123       sf->schedule_mode_search = cm->base_qindex < 175 ? 1 : 0;
    124       sf->partition_search_breakout_thr.dist = (1 << 23);
    125       sf->partition_search_breakout_thr.rate = 120;
    126     }
    127   }
    128 
    129   // If this is a two pass clip that fits the criteria for animated or
    130   // graphics content then reset disable_split_mask for speeds 1-4.
    131   // Also if the image edge is internal to the coded area.
    132   if ((speed >= 1) && (cpi->oxcf.pass == 2) &&
    133       ((cpi->twopass.fr_content_type == FC_GRAPHICS_ANIMATION) ||
    134        (vp9_internal_image_edge(cpi)))) {
    135     sf->disable_split_mask = DISABLE_COMPOUND_SPLIT;
    136   }
    137 
    138   if (speed >= 4) {
    139     sf->partition_search_breakout_thr.rate = 300;
    140     if (VPXMIN(cm->width, cm->height) >= 720) {
    141       sf->partition_search_breakout_thr.dist = (1 << 26);
    142     } else {
    143       sf->partition_search_breakout_thr.dist = (1 << 24);
    144     }
    145     sf->disable_split_mask = DISABLE_ALL_SPLIT;
    146   }
    147 
    148   if (speed >= 5) {
    149     sf->partition_search_breakout_thr.rate = 500;
    150   }
    151 }
    152 
    153 static double tx_dom_thresholds[6] = { 99.0, 14.0, 12.0, 8.0, 4.0, 0.0 };
    154 static double qopt_thresholds[6] = { 99.0, 12.0, 10.0, 4.0, 2.0, 0.0 };
    155 
    156 static void set_good_speed_feature_framesize_independent(VP9_COMP *cpi,
    157                                                          VP9_COMMON *cm,
    158                                                          SPEED_FEATURES *sf,
    159                                                          int speed) {
    160   const int boosted = frame_is_boosted(cpi);
    161   int i;
    162 
    163   sf->tx_size_search_breakout = 1;
    164   sf->adaptive_rd_thresh = 1;
    165   sf->adaptive_rd_thresh_row_mt = 0;
    166   sf->allow_skip_recode = 1;
    167   sf->less_rectangular_check = 1;
    168   sf->use_square_partition_only = !frame_is_boosted(cpi);
    169   sf->use_square_only_threshold = BLOCK_16X16;
    170 
    171   if (cpi->twopass.fr_content_type == FC_GRAPHICS_ANIMATION) {
    172     sf->exhaustive_searches_thresh = (1 << 22);
    173     for (i = 0; i < MAX_MESH_STEP; ++i) {
    174       int mesh_density_level = 0;
    175       sf->mesh_patterns[i].range =
    176           good_quality_mesh_patterns[mesh_density_level][i].range;
    177       sf->mesh_patterns[i].interval =
    178           good_quality_mesh_patterns[mesh_density_level][i].interval;
    179     }
    180   } else {
    181     sf->exhaustive_searches_thresh = INT_MAX;
    182   }
    183 
    184   if (speed >= 1) {
    185     if (cpi->oxcf.pass == 2) {
    186       TWO_PASS *const twopass = &cpi->twopass;
    187       if ((twopass->fr_content_type == FC_GRAPHICS_ANIMATION) ||
    188           vp9_internal_image_edge(cpi)) {
    189         sf->use_square_partition_only = !frame_is_boosted(cpi);
    190       } else {
    191         sf->use_square_partition_only = !frame_is_intra_only(cm);
    192       }
    193     } else {
    194       sf->use_square_partition_only = !frame_is_intra_only(cm);
    195     }
    196 
    197     sf->allow_txfm_domain_distortion = 1;
    198     sf->tx_domain_thresh = tx_dom_thresholds[(speed < 6) ? speed : 5];
    199     sf->allow_quant_coeff_opt = sf->optimize_coefficients;
    200     sf->quant_opt_thresh = qopt_thresholds[(speed < 6) ? speed : 5];
    201 
    202     sf->use_square_only_threshold = BLOCK_4X4;
    203     sf->less_rectangular_check = 1;
    204 
    205     sf->use_rd_breakout = 1;
    206     sf->adaptive_motion_search = 1;
    207     sf->mv.auto_mv_step_size = 1;
    208     sf->adaptive_rd_thresh = 2;
    209     sf->mv.subpel_iters_per_step = 1;
    210     sf->mode_skip_start = 10;
    211     sf->adaptive_pred_interp_filter = 1;
    212     sf->allow_acl = 0;
    213 
    214     sf->intra_y_mode_mask[TX_32X32] = INTRA_DC_H_V;
    215     sf->intra_uv_mode_mask[TX_32X32] = INTRA_DC_H_V;
    216     sf->intra_y_mode_mask[TX_16X16] = INTRA_DC_H_V;
    217     sf->intra_uv_mode_mask[TX_16X16] = INTRA_DC_H_V;
    218 
    219     sf->recode_tolerance_low = 15;
    220     sf->recode_tolerance_high = 30;
    221 
    222     sf->exhaustive_searches_thresh =
    223         (cpi->twopass.fr_content_type == FC_GRAPHICS_ANIMATION) ? (1 << 23)
    224                                                                 : INT_MAX;
    225   }
    226 
    227   if (speed >= 2) {
    228     sf->recode_loop = ALLOW_RECODE_KFARFGF;
    229     sf->tx_size_search_method =
    230         frame_is_boosted(cpi) ? USE_FULL_RD : USE_LARGESTALL;
    231 
    232     // Reference masking is not supported in dynamic scaling mode.
    233     sf->reference_masking = cpi->oxcf.resize_mode != RESIZE_DYNAMIC ? 1 : 0;
    234 
    235     sf->mode_search_skip_flags =
    236         (cm->frame_type == KEY_FRAME)
    237             ? 0
    238             : FLAG_SKIP_INTRA_DIRMISMATCH | FLAG_SKIP_INTRA_BESTINTER |
    239                   FLAG_SKIP_COMP_BESTINTRA | FLAG_SKIP_INTRA_LOWVAR;
    240     sf->disable_filter_search_var_thresh = 100;
    241     sf->comp_inter_joint_search_thresh = BLOCK_SIZES;
    242     sf->auto_min_max_partition_size = RELAXED_NEIGHBORING_MIN_MAX;
    243     sf->allow_partition_search_skip = 1;
    244     sf->recode_tolerance_low = 15;
    245     sf->recode_tolerance_high = 45;
    246 
    247     if (cpi->twopass.fr_content_type == FC_GRAPHICS_ANIMATION) {
    248       for (i = 0; i < MAX_MESH_STEP; ++i) {
    249         int mesh_density_level = 1;
    250         sf->mesh_patterns[i].range =
    251             good_quality_mesh_patterns[mesh_density_level][i].range;
    252         sf->mesh_patterns[i].interval =
    253             good_quality_mesh_patterns[mesh_density_level][i].interval;
    254       }
    255     }
    256   }
    257 
    258   if (speed >= 3) {
    259     sf->use_square_partition_only = !frame_is_intra_only(cm);
    260     sf->tx_size_search_method =
    261         frame_is_intra_only(cm) ? USE_FULL_RD : USE_LARGESTALL;
    262     sf->mv.subpel_search_method = SUBPEL_TREE_PRUNED;
    263     sf->adaptive_pred_interp_filter = 0;
    264     sf->adaptive_mode_search = 1;
    265     sf->cb_partition_search = !boosted;
    266     sf->cb_pred_filter_search = 1;
    267     sf->alt_ref_search_fp = 1;
    268     sf->recode_loop = ALLOW_RECODE_KFMAXBW;
    269     sf->adaptive_rd_thresh = 3;
    270     sf->mode_skip_start = 6;
    271     sf->intra_y_mode_mask[TX_32X32] = INTRA_DC;
    272     sf->intra_uv_mode_mask[TX_32X32] = INTRA_DC;
    273     sf->adaptive_interp_filter_search = 1;
    274 
    275     if (cpi->twopass.fr_content_type == FC_GRAPHICS_ANIMATION) {
    276       for (i = 0; i < MAX_MESH_STEP; ++i) {
    277         int mesh_density_level = 2;
    278         sf->mesh_patterns[i].range =
    279             good_quality_mesh_patterns[mesh_density_level][i].range;
    280         sf->mesh_patterns[i].interval =
    281             good_quality_mesh_patterns[mesh_density_level][i].interval;
    282       }
    283     }
    284   }
    285 
    286   if (speed >= 4) {
    287     sf->use_square_partition_only = 1;
    288     sf->tx_size_search_method = USE_LARGESTALL;
    289     sf->mv.search_method = BIGDIA;
    290     sf->mv.subpel_search_method = SUBPEL_TREE_PRUNED_MORE;
    291     sf->adaptive_rd_thresh = 4;
    292     if (cm->frame_type != KEY_FRAME)
    293       sf->mode_search_skip_flags |= FLAG_EARLY_TERMINATE;
    294     sf->disable_filter_search_var_thresh = 200;
    295     sf->use_lp32x32fdct = 1;
    296     sf->use_fast_coef_updates = ONE_LOOP_REDUCED;
    297     sf->use_fast_coef_costing = 1;
    298     sf->motion_field_mode_search = !boosted;
    299   }
    300 
    301   if (speed >= 5) {
    302     int i;
    303     sf->optimize_coefficients = 0;
    304     sf->mv.search_method = HEX;
    305     sf->disable_filter_search_var_thresh = 500;
    306     for (i = 0; i < TX_SIZES; ++i) {
    307       sf->intra_y_mode_mask[i] = INTRA_DC;
    308       sf->intra_uv_mode_mask[i] = INTRA_DC;
    309     }
    310     sf->mv.reduce_first_step_size = 1;
    311     sf->simple_model_rd_from_var = 1;
    312   }
    313 }
    314 
    315 static void set_rt_speed_feature_framesize_dependent(VP9_COMP *cpi,
    316                                                      SPEED_FEATURES *sf,
    317                                                      int speed) {
    318   VP9_COMMON *const cm = &cpi->common;
    319 
    320   if (speed >= 1) {
    321     if (VPXMIN(cm->width, cm->height) >= 720) {
    322       sf->disable_split_mask =
    323           cm->show_frame ? DISABLE_ALL_SPLIT : DISABLE_ALL_INTER_SPLIT;
    324     } else {
    325       sf->disable_split_mask = DISABLE_COMPOUND_SPLIT;
    326     }
    327   }
    328 
    329   if (speed >= 2) {
    330     if (VPXMIN(cm->width, cm->height) >= 720) {
    331       sf->disable_split_mask =
    332           cm->show_frame ? DISABLE_ALL_SPLIT : DISABLE_ALL_INTER_SPLIT;
    333     } else {
    334       sf->disable_split_mask = LAST_AND_INTRA_SPLIT_ONLY;
    335     }
    336   }
    337 
    338   if (speed >= 5) {
    339     sf->partition_search_breakout_thr.rate = 200;
    340     if (VPXMIN(cm->width, cm->height) >= 720) {
    341       sf->partition_search_breakout_thr.dist = (1 << 25);
    342     } else {
    343       sf->partition_search_breakout_thr.dist = (1 << 23);
    344     }
    345   }
    346 
    347   if (speed >= 7) {
    348     sf->encode_breakout_thresh =
    349         (VPXMIN(cm->width, cm->height) >= 720) ? 800 : 300;
    350   }
    351 }
    352 
    353 static void set_rt_speed_feature_framesize_independent(
    354     VP9_COMP *cpi, SPEED_FEATURES *sf, int speed, vp9e_tune_content content) {
    355   VP9_COMMON *const cm = &cpi->common;
    356   const int is_keyframe = cm->frame_type == KEY_FRAME;
    357   const int frames_since_key = is_keyframe ? 0 : cpi->rc.frames_since_key;
    358   sf->static_segmentation = 0;
    359   sf->adaptive_rd_thresh = 1;
    360   sf->adaptive_rd_thresh_row_mt = 0;
    361   sf->use_fast_coef_costing = 1;
    362   sf->exhaustive_searches_thresh = INT_MAX;
    363   sf->allow_acl = 0;
    364   sf->copy_partition_flag = 0;
    365   sf->use_source_sad = 0;
    366   sf->use_simple_block_yrd = 0;
    367 
    368   if (speed >= 1) {
    369     sf->allow_txfm_domain_distortion = 1;
    370     sf->tx_domain_thresh = 0.0;
    371     sf->allow_quant_coeff_opt = 0;
    372     sf->quant_opt_thresh = 0.0;
    373     sf->use_square_partition_only = !frame_is_intra_only(cm);
    374     sf->less_rectangular_check = 1;
    375     sf->tx_size_search_method =
    376         frame_is_intra_only(cm) ? USE_FULL_RD : USE_LARGESTALL;
    377 
    378     sf->use_rd_breakout = 1;
    379 
    380     sf->adaptive_motion_search = 1;
    381     sf->adaptive_pred_interp_filter = 1;
    382     sf->mv.auto_mv_step_size = 1;
    383     sf->adaptive_rd_thresh = 2;
    384     sf->intra_y_mode_mask[TX_32X32] = INTRA_DC_H_V;
    385     sf->intra_uv_mode_mask[TX_32X32] = INTRA_DC_H_V;
    386     sf->intra_uv_mode_mask[TX_16X16] = INTRA_DC_H_V;
    387   }
    388 
    389   if (speed >= 2) {
    390     sf->mode_search_skip_flags =
    391         (cm->frame_type == KEY_FRAME)
    392             ? 0
    393             : FLAG_SKIP_INTRA_DIRMISMATCH | FLAG_SKIP_INTRA_BESTINTER |
    394                   FLAG_SKIP_COMP_BESTINTRA | FLAG_SKIP_INTRA_LOWVAR;
    395     sf->adaptive_pred_interp_filter = 2;
    396 
    397     // Reference masking only enabled for 1 spatial layer, and if none of the
    398     // references have been scaled. The latter condition needs to be checked
    399     // for external or internal dynamic resize.
    400     sf->reference_masking = (cpi->svc.number_spatial_layers == 1);
    401     if (sf->reference_masking == 1 &&
    402         (cpi->external_resize == 1 ||
    403          cpi->oxcf.resize_mode == RESIZE_DYNAMIC)) {
    404       MV_REFERENCE_FRAME ref_frame;
    405       static const int flag_list[4] = { 0, VP9_LAST_FLAG, VP9_GOLD_FLAG,
    406                                         VP9_ALT_FLAG };
    407       for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
    408         const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame);
    409         if (yv12 != NULL && (cpi->ref_frame_flags & flag_list[ref_frame])) {
    410           const struct scale_factors *const scale_fac =
    411               &cm->frame_refs[ref_frame - 1].sf;
    412           if (vp9_is_scaled(scale_fac)) sf->reference_masking = 0;
    413         }
    414       }
    415     }
    416 
    417     sf->disable_filter_search_var_thresh = 50;
    418     sf->comp_inter_joint_search_thresh = BLOCK_SIZES;
    419     sf->auto_min_max_partition_size = RELAXED_NEIGHBORING_MIN_MAX;
    420     sf->lf_motion_threshold = LOW_MOTION_THRESHOLD;
    421     sf->adjust_partitioning_from_last_frame = 1;
    422     sf->last_partitioning_redo_frequency = 3;
    423     sf->use_lp32x32fdct = 1;
    424     sf->mode_skip_start = 11;
    425     sf->intra_y_mode_mask[TX_16X16] = INTRA_DC_H_V;
    426   }
    427 
    428   if (speed >= 3) {
    429     sf->use_square_partition_only = 1;
    430     sf->disable_filter_search_var_thresh = 100;
    431     sf->use_uv_intra_rd_estimate = 1;
    432     sf->skip_encode_sb = 1;
    433     sf->mv.subpel_iters_per_step = 1;
    434     sf->adaptive_rd_thresh = 4;
    435     sf->mode_skip_start = 6;
    436     sf->allow_skip_recode = 0;
    437     sf->optimize_coefficients = 0;
    438     sf->disable_split_mask = DISABLE_ALL_SPLIT;
    439     sf->lpf_pick = LPF_PICK_FROM_Q;
    440   }
    441 
    442   if (speed >= 4) {
    443     int i;
    444     sf->last_partitioning_redo_frequency = 4;
    445     sf->adaptive_rd_thresh = 5;
    446     sf->use_fast_coef_costing = 0;
    447     sf->auto_min_max_partition_size = STRICT_NEIGHBORING_MIN_MAX;
    448     sf->adjust_partitioning_from_last_frame =
    449         cm->last_frame_type != cm->frame_type ||
    450         (0 == (frames_since_key + 1) % sf->last_partitioning_redo_frequency);
    451     sf->mv.subpel_force_stop = 1;
    452     for (i = 0; i < TX_SIZES; i++) {
    453       sf->intra_y_mode_mask[i] = INTRA_DC_H_V;
    454       sf->intra_uv_mode_mask[i] = INTRA_DC;
    455     }
    456     sf->intra_y_mode_mask[TX_32X32] = INTRA_DC;
    457     sf->frame_parameter_update = 0;
    458     sf->mv.search_method = FAST_HEX;
    459 
    460     sf->inter_mode_mask[BLOCK_32X32] = INTER_NEAREST_NEAR_NEW;
    461     sf->inter_mode_mask[BLOCK_32X64] = INTER_NEAREST;
    462     sf->inter_mode_mask[BLOCK_64X32] = INTER_NEAREST;
    463     sf->inter_mode_mask[BLOCK_64X64] = INTER_NEAREST;
    464     sf->max_intra_bsize = BLOCK_32X32;
    465     sf->allow_skip_recode = 1;
    466   }
    467 
    468   if (speed >= 5) {
    469     sf->use_quant_fp = !is_keyframe;
    470     sf->auto_min_max_partition_size =
    471         is_keyframe ? RELAXED_NEIGHBORING_MIN_MAX : STRICT_NEIGHBORING_MIN_MAX;
    472     sf->default_max_partition_size = BLOCK_32X32;
    473     sf->default_min_partition_size = BLOCK_8X8;
    474     sf->force_frame_boost =
    475         is_keyframe ||
    476         (frames_since_key % (sf->last_partitioning_redo_frequency << 1) == 1);
    477     sf->max_delta_qindex = is_keyframe ? 20 : 15;
    478     sf->partition_search_type = REFERENCE_PARTITION;
    479     if (cpi->oxcf.rc_mode == VPX_VBR && cpi->oxcf.lag_in_frames > 0 &&
    480         cpi->rc.is_src_frame_alt_ref) {
    481       sf->partition_search_type = VAR_BASED_PARTITION;
    482     }
    483     sf->use_nonrd_pick_mode = 1;
    484     sf->allow_skip_recode = 0;
    485     sf->inter_mode_mask[BLOCK_32X32] = INTER_NEAREST_NEW_ZERO;
    486     sf->inter_mode_mask[BLOCK_32X64] = INTER_NEAREST_NEW_ZERO;
    487     sf->inter_mode_mask[BLOCK_64X32] = INTER_NEAREST_NEW_ZERO;
    488     sf->inter_mode_mask[BLOCK_64X64] = INTER_NEAREST_NEW_ZERO;
    489     sf->adaptive_rd_thresh = 2;
    490     // This feature is only enabled when partition search is disabled.
    491     sf->reuse_inter_pred_sby = 1;
    492     sf->coeff_prob_appx_step = 4;
    493     sf->use_fast_coef_updates = is_keyframe ? TWO_LOOP : ONE_LOOP_REDUCED;
    494     sf->mode_search_skip_flags = FLAG_SKIP_INTRA_DIRMISMATCH;
    495     sf->tx_size_search_method = is_keyframe ? USE_LARGESTALL : USE_TX_8X8;
    496     sf->simple_model_rd_from_var = 1;
    497     if (cpi->oxcf.rc_mode == VPX_VBR) sf->mv.search_method = NSTEP;
    498 
    499     if (!is_keyframe) {
    500       int i;
    501       if (content == VP9E_CONTENT_SCREEN) {
    502         for (i = 0; i < BLOCK_SIZES; ++i)
    503           sf->intra_y_mode_bsize_mask[i] = INTRA_DC_TM_H_V;
    504       } else {
    505         for (i = 0; i < BLOCK_SIZES; ++i)
    506           if (i > BLOCK_16X16)
    507             sf->intra_y_mode_bsize_mask[i] = INTRA_DC;
    508           else
    509             // Use H and V intra mode for block sizes <= 16X16.
    510             sf->intra_y_mode_bsize_mask[i] = INTRA_DC_H_V;
    511       }
    512     }
    513     if (content == VP9E_CONTENT_SCREEN) {
    514       sf->short_circuit_flat_blocks = 1;
    515     }
    516     if (cpi->oxcf.rc_mode == VPX_CBR &&
    517         cpi->oxcf.content != VP9E_CONTENT_SCREEN) {
    518       sf->limit_newmv_early_exit = 1;
    519       if (!cpi->use_svc) sf->bias_golden = 1;
    520     }
    521   }
    522 
    523   if (speed >= 6) {
    524     sf->partition_search_type = VAR_BASED_PARTITION;
    525     // Turn on this to use non-RD key frame coding mode.
    526     sf->use_nonrd_pick_mode = 1;
    527     sf->mv.search_method = NSTEP;
    528     sf->mv.reduce_first_step_size = 1;
    529     sf->skip_encode_sb = 0;
    530     if (cpi->oxcf.rc_mode == VPX_CBR && content != VP9E_CONTENT_SCREEN) {
    531       // Enable short circuit for low temporal variance.
    532       sf->short_circuit_low_temp_var = 1;
    533     }
    534     if (cpi->svc.temporal_layer_id > 0) {
    535       sf->adaptive_rd_thresh = 4;
    536       sf->limit_newmv_early_exit = 0;
    537       sf->mv.subpel_force_stop = (cpi->svc.temporal_layer_id == 1) ? 1 : 2;
    538       sf->base_mv_aggressive =
    539           (cpi->svc.temporal_layer_id == cpi->svc.number_temporal_layers - 1)
    540               ? 1
    541               : 0;
    542     }
    543   }
    544 
    545   if (speed >= 7) {
    546     sf->adaptive_rd_thresh = 3;
    547     sf->mv.search_method = FAST_DIAMOND;
    548     sf->mv.fullpel_search_step_param = 10;
    549     if (cpi->svc.number_temporal_layers > 2 &&
    550         cpi->svc.temporal_layer_id == 0) {
    551       sf->mv.search_method = NSTEP;
    552       sf->mv.fullpel_search_step_param = 6;
    553     }
    554     if (!cpi->external_resize) sf->use_source_sad = 1;
    555     if (sf->use_source_sad) {
    556       if (cpi->content_state_sb_fd == NULL &&
    557           (!cpi->use_svc ||
    558            cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1)) {
    559         cpi->content_state_sb_fd = (uint8_t *)vpx_calloc(
    560             (cm->mi_stride >> 3) * ((cm->mi_rows >> 3) + 1), sizeof(uint8_t));
    561       }
    562     }
    563   }
    564 
    565   if (speed >= 8) {
    566     sf->adaptive_rd_thresh = 4;
    567     // Enable partition copy. For SVC, only enabled for top resolution layer,
    568     if (!cpi->last_frame_dropped && cpi->resize_state == ORIG &&
    569         !cpi->external_resize &&
    570         (!cpi->use_svc ||
    571          cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1)) {
    572       sf->copy_partition_flag = 1;
    573       cpi->max_copied_frame = 4;
    574     }
    575 
    576     if (cpi->row_mt && cpi->oxcf.max_threads > 1)
    577       sf->adaptive_rd_thresh_row_mt = 1;
    578 
    579     if (content == VP9E_CONTENT_SCREEN)
    580       sf->mv.subpel_force_stop = 3;
    581     else if (cm->width * cm->height > 352 * 288)
    582       sf->mv.subpel_force_stop = 2;
    583 
    584     if (content == VP9E_CONTENT_SCREEN) sf->lpf_pick = LPF_PICK_MINIMAL_LPF;
    585     // Only keep INTRA_DC mode for speed 8.
    586     if (!is_keyframe) {
    587       int i = 0;
    588       for (i = 0; i < BLOCK_SIZES; ++i)
    589         sf->intra_y_mode_bsize_mask[i] = INTRA_DC;
    590     }
    591     if (!cpi->use_svc && cpi->oxcf.rc_mode == VPX_CBR &&
    592         content != VP9E_CONTENT_SCREEN) {
    593       // More aggressive short circuit for speed 8.
    594       sf->short_circuit_low_temp_var = 3;
    595       // Use level 2 for noisey cases as there is a regression in some
    596       // noisy clips with level 3.
    597       if (cpi->noise_estimate.enabled && cm->width >= 1280 &&
    598           cm->height >= 720) {
    599         NOISE_LEVEL noise_level =
    600             vp9_noise_estimate_extract_level(&cpi->noise_estimate);
    601         if (noise_level >= kMedium) sf->short_circuit_low_temp_var = 2;
    602       }
    603       // Since the short_circuit_low_temp_var is used, reduce the
    604       // adaptive_rd_thresh level.
    605       if (cm->width * cm->height > 352 * 288)
    606         sf->adaptive_rd_thresh = 1;
    607       else
    608         sf->adaptive_rd_thresh = 2;
    609     }
    610     sf->limit_newmv_early_exit = 0;
    611     sf->use_simple_block_yrd = 1;
    612   }
    613 }
    614 
    615 void vp9_set_speed_features_framesize_dependent(VP9_COMP *cpi) {
    616   SPEED_FEATURES *const sf = &cpi->sf;
    617   const VP9EncoderConfig *const oxcf = &cpi->oxcf;
    618   RD_OPT *const rd = &cpi->rd;
    619   int i;
    620 
    621   // best quality defaults
    622   // Some speed-up features even for best quality as minimal impact on quality.
    623   sf->partition_search_breakout_thr.dist = (1 << 19);
    624   sf->partition_search_breakout_thr.rate = 80;
    625   sf->ml_partition_search_early_termination = 0;
    626 
    627   if (oxcf->mode == REALTIME) {
    628     set_rt_speed_feature_framesize_dependent(cpi, sf, oxcf->speed);
    629   } else if (oxcf->mode == GOOD) {
    630     set_good_speed_feature_framesize_dependent(cpi, sf, oxcf->speed);
    631   }
    632 
    633   if (sf->disable_split_mask == DISABLE_ALL_SPLIT) {
    634     sf->adaptive_pred_interp_filter = 0;
    635   }
    636 
    637   if (cpi->encode_breakout && oxcf->mode == REALTIME &&
    638       sf->encode_breakout_thresh > cpi->encode_breakout) {
    639     cpi->encode_breakout = sf->encode_breakout_thresh;
    640   }
    641 
    642   // Check for masked out split cases.
    643   for (i = 0; i < MAX_REFS; ++i) {
    644     if (sf->disable_split_mask & (1 << i)) {
    645       rd->thresh_mult_sub8x8[i] = INT_MAX;
    646     }
    647   }
    648 
    649   // With row based multi-threading, the following speed features
    650   // have to be disabled to guarantee that bitstreams encoded with single thread
    651   // and multiple threads match.
    652   // It can be used in realtime when adaptive_rd_thresh_row_mt is enabled since
    653   // adaptive_rd_thresh is defined per-row for non-rd pickmode.
    654   if (!sf->adaptive_rd_thresh_row_mt && cpi->row_mt_bit_exact)
    655     sf->adaptive_rd_thresh = 0;
    656 
    657   // This is only used in motion vector unit test.
    658   if (cpi->oxcf.motion_vector_unit_test == 1)
    659     cpi->find_fractional_mv_step = vp9_return_max_sub_pixel_mv;
    660   else if (cpi->oxcf.motion_vector_unit_test == 2)
    661     cpi->find_fractional_mv_step = vp9_return_min_sub_pixel_mv;
    662 }
    663 
    664 void vp9_set_speed_features_framesize_independent(VP9_COMP *cpi) {
    665   SPEED_FEATURES *const sf = &cpi->sf;
    666   VP9_COMMON *const cm = &cpi->common;
    667   MACROBLOCK *const x = &cpi->td.mb;
    668   const VP9EncoderConfig *const oxcf = &cpi->oxcf;
    669   int i;
    670 
    671   // best quality defaults
    672   sf->frame_parameter_update = 1;
    673   sf->mv.search_method = NSTEP;
    674   sf->recode_loop = ALLOW_RECODE_FIRST;
    675   sf->mv.subpel_search_method = SUBPEL_TREE;
    676   sf->mv.subpel_iters_per_step = 2;
    677   sf->mv.subpel_force_stop = 0;
    678   sf->optimize_coefficients = !is_lossless_requested(&cpi->oxcf);
    679   sf->mv.reduce_first_step_size = 0;
    680   sf->coeff_prob_appx_step = 1;
    681   sf->mv.auto_mv_step_size = 0;
    682   sf->mv.fullpel_search_step_param = 6;
    683   sf->comp_inter_joint_search_thresh = BLOCK_4X4;
    684   sf->tx_size_search_method = USE_FULL_RD;
    685   sf->use_lp32x32fdct = 0;
    686   sf->adaptive_motion_search = 0;
    687   sf->adaptive_pred_interp_filter = 0;
    688   sf->adaptive_mode_search = 0;
    689   sf->cb_pred_filter_search = 0;
    690   sf->cb_partition_search = 0;
    691   sf->motion_field_mode_search = 0;
    692   sf->alt_ref_search_fp = 0;
    693   sf->use_quant_fp = 0;
    694   sf->reference_masking = 0;
    695   sf->partition_search_type = SEARCH_PARTITION;
    696   sf->less_rectangular_check = 0;
    697   sf->use_square_partition_only = 0;
    698   sf->use_square_only_threshold = BLOCK_SIZES;
    699   sf->auto_min_max_partition_size = NOT_IN_USE;
    700   sf->rd_auto_partition_min_limit = BLOCK_4X4;
    701   sf->default_max_partition_size = BLOCK_64X64;
    702   sf->default_min_partition_size = BLOCK_4X4;
    703   sf->adjust_partitioning_from_last_frame = 0;
    704   sf->last_partitioning_redo_frequency = 4;
    705   sf->disable_split_mask = 0;
    706   sf->mode_search_skip_flags = 0;
    707   sf->force_frame_boost = 0;
    708   sf->max_delta_qindex = 0;
    709   sf->disable_filter_search_var_thresh = 0;
    710   sf->adaptive_interp_filter_search = 0;
    711   sf->allow_partition_search_skip = 0;
    712   sf->allow_txfm_domain_distortion = 0;
    713   sf->tx_domain_thresh = 99.0;
    714   sf->allow_quant_coeff_opt = sf->optimize_coefficients;
    715   sf->quant_opt_thresh = 99.0;
    716   sf->allow_acl = 1;
    717 
    718   for (i = 0; i < TX_SIZES; i++) {
    719     sf->intra_y_mode_mask[i] = INTRA_ALL;
    720     sf->intra_uv_mode_mask[i] = INTRA_ALL;
    721   }
    722   sf->use_rd_breakout = 0;
    723   sf->skip_encode_sb = 0;
    724   sf->use_uv_intra_rd_estimate = 0;
    725   sf->allow_skip_recode = 0;
    726   sf->lpf_pick = LPF_PICK_FROM_FULL_IMAGE;
    727   sf->use_fast_coef_updates = TWO_LOOP;
    728   sf->use_fast_coef_costing = 0;
    729   sf->mode_skip_start = MAX_MODES;  // Mode index at which mode skip mask set
    730   sf->schedule_mode_search = 0;
    731   sf->use_nonrd_pick_mode = 0;
    732   for (i = 0; i < BLOCK_SIZES; ++i) sf->inter_mode_mask[i] = INTER_ALL;
    733   sf->max_intra_bsize = BLOCK_64X64;
    734   sf->reuse_inter_pred_sby = 0;
    735   // This setting only takes effect when partition_search_type is set
    736   // to FIXED_PARTITION.
    737   sf->always_this_block_size = BLOCK_16X16;
    738   sf->search_type_check_frequency = 50;
    739   sf->encode_breakout_thresh = 0;
    740   // Recode loop tolerance %.
    741   sf->recode_tolerance_low = 12;
    742   sf->recode_tolerance_high = 25;
    743   sf->default_interp_filter = SWITCHABLE;
    744   sf->simple_model_rd_from_var = 0;
    745   sf->short_circuit_flat_blocks = 0;
    746   sf->short_circuit_low_temp_var = 0;
    747   sf->limit_newmv_early_exit = 0;
    748   sf->bias_golden = 0;
    749   sf->base_mv_aggressive = 0;
    750 
    751   // Some speed-up features even for best quality as minimal impact on quality.
    752   sf->adaptive_rd_thresh = 1;
    753   sf->tx_size_search_breakout = 1;
    754 
    755   sf->exhaustive_searches_thresh =
    756       (cpi->twopass.fr_content_type == FC_GRAPHICS_ANIMATION) ? (1 << 20)
    757                                                               : INT_MAX;
    758   if (cpi->twopass.fr_content_type == FC_GRAPHICS_ANIMATION) {
    759     for (i = 0; i < MAX_MESH_STEP; ++i) {
    760       sf->mesh_patterns[i].range = best_quality_mesh_pattern[i].range;
    761       sf->mesh_patterns[i].interval = best_quality_mesh_pattern[i].interval;
    762     }
    763   }
    764 
    765   if (oxcf->mode == REALTIME)
    766     set_rt_speed_feature_framesize_independent(cpi, sf, oxcf->speed,
    767                                                oxcf->content);
    768   else if (oxcf->mode == GOOD)
    769     set_good_speed_feature_framesize_independent(cpi, cm, sf, oxcf->speed);
    770 
    771   cpi->full_search_sad = vp9_full_search_sad;
    772   cpi->diamond_search_sad = vp9_diamond_search_sad;
    773 
    774   // Slow quant, dct and trellis not worthwhile for first pass
    775   // so make sure they are always turned off.
    776   if (oxcf->pass == 1) sf->optimize_coefficients = 0;
    777 
    778   // No recode for 1 pass.
    779   if (oxcf->pass == 0) {
    780     sf->recode_loop = DISALLOW_RECODE;
    781     sf->optimize_coefficients = 0;
    782   }
    783 
    784   if (sf->mv.subpel_force_stop == 3) {
    785     // Whole pel only
    786     cpi->find_fractional_mv_step = vp9_skip_sub_pixel_tree;
    787   } else if (sf->mv.subpel_search_method == SUBPEL_TREE) {
    788     cpi->find_fractional_mv_step = vp9_find_best_sub_pixel_tree;
    789   } else if (sf->mv.subpel_search_method == SUBPEL_TREE_PRUNED) {
    790     cpi->find_fractional_mv_step = vp9_find_best_sub_pixel_tree_pruned;
    791   } else if (sf->mv.subpel_search_method == SUBPEL_TREE_PRUNED_MORE) {
    792     cpi->find_fractional_mv_step = vp9_find_best_sub_pixel_tree_pruned_more;
    793   } else if (sf->mv.subpel_search_method == SUBPEL_TREE_PRUNED_EVENMORE) {
    794     cpi->find_fractional_mv_step = vp9_find_best_sub_pixel_tree_pruned_evenmore;
    795   }
    796 
    797   x->optimize = sf->optimize_coefficients == 1 && oxcf->pass != 1;
    798 
    799   x->min_partition_size = sf->default_min_partition_size;
    800   x->max_partition_size = sf->default_max_partition_size;
    801 
    802   if (!cpi->oxcf.frame_periodic_boost) {
    803     sf->max_delta_qindex = 0;
    804   }
    805 
    806   // With row based multi-threading, the following speed features
    807   // have to be disabled to guarantee that bitstreams encoded with single thread
    808   // and multiple threads match.
    809   // It can be used in realtime when adaptive_rd_thresh_row_mt is enabled since
    810   // adaptive_rd_thresh is defined per-row for non-rd pickmode.
    811   if (!sf->adaptive_rd_thresh_row_mt && cpi->row_mt_bit_exact)
    812     sf->adaptive_rd_thresh = 0;
    813 
    814   // This is only used in motion vector unit test.
    815   if (cpi->oxcf.motion_vector_unit_test == 1)
    816     cpi->find_fractional_mv_step = vp9_return_max_sub_pixel_mv;
    817   else if (cpi->oxcf.motion_vector_unit_test == 2)
    818     cpi->find_fractional_mv_step = vp9_return_min_sub_pixel_mv;
    819 }
    820