diff options
Diffstat (limited to 'vp9/encoder')
-rw-r--r-- | vp9/encoder/vp9_encoder.c | 121 | ||||
-rw-r--r-- | vp9/encoder/vp9_encoder.h | 13 | ||||
-rw-r--r-- | vp9/encoder/vp9_firstpass.c | 53 | ||||
-rw-r--r-- | vp9/encoder/vp9_ratectrl.c | 40 | ||||
-rw-r--r-- | vp9/encoder/vp9_ratectrl.h | 2 | ||||
-rw-r--r-- | vp9/encoder/vp9_rd.c | 13 | ||||
-rw-r--r-- | vp9/encoder/vp9_speed_features.c | 191 | ||||
-rw-r--r-- | vp9/encoder/vp9_speed_features.h | 3 |
8 files changed, 257 insertions, 179 deletions
diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c index 72e11d668..2dc7a71ca 100644 --- a/vp9/encoder/vp9_encoder.c +++ b/vp9/encoder/vp9_encoder.c @@ -1625,7 +1625,8 @@ VP9_COMP *vp9_create_compressor(VP9EncoderConfig *oxcf) { } } - vp9_set_speed_features(cpi); + vp9_set_speed_features_framesize_independent(cpi); + vp9_set_speed_features_framesize_dependent(cpi); // Allocate memory to store variances for a frame. CHECK_MEM_ERROR(cm, cpi->source_diff_var, @@ -2309,7 +2310,6 @@ static void scale_and_extend_frame(const YV12_BUFFER_CONFIG *src, static int recode_loop_test(const VP9_COMP *cpi, int high_limit, int low_limit, int q, int maxq, int minq) { - const VP9_COMMON *const cm = &cpi->common; const RATE_CONTROL *const rc = &cpi->rc; const VP9EncoderConfig *const oxcf = &cpi->oxcf; int force_recode = 0; @@ -2323,8 +2323,7 @@ static int recode_loop_test(const VP9_COMP *cpi, // and the frame is a key frame, golden frame or alt_ref_frame } else if ((cpi->sf.recode_loop == ALLOW_RECODE) || ((cpi->sf.recode_loop == ALLOW_RECODE_KFARFGF) && - (cm->frame_type == KEY_FRAME || - cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame))) { + frame_is_kf_gf_arf(cpi))) { // General over and under shoot tests if ((rc->projected_frame_size > high_limit && q < maxq) || (rc->projected_frame_size < low_limit && q > minq)) { @@ -2505,8 +2504,10 @@ static void release_scaled_references(VP9_COMP *cpi) { const int idx = cpi->scaled_ref_idx[i]; RefCntBuffer *const buf = idx != INVALID_REF_BUFFER_IDX ? &cm->frame_bufs[idx] : NULL; - if (buf != NULL) + if (buf != NULL) { --buf->ref_count; + cpi->scaled_ref_idx[i] = INVALID_REF_BUFFER_IDX; + } } } @@ -2617,13 +2618,27 @@ static void set_mv_search_params(VP9_COMP *cpi) { } } +static void set_size_independent_vars(VP9_COMP *cpi) { + vp9_set_speed_features_framesize_independent(cpi); + vp9_set_rd_speed_thresholds(cpi); + vp9_set_rd_speed_thresholds_sub8x8(cpi); + cpi->common.interp_filter = cpi->sf.default_interp_filter; +} + static void set_size_dependent_vars(VP9_COMP *cpi, int *q, int *bottom_index, int *top_index) { VP9_COMMON *const cm = &cpi->common; const VP9EncoderConfig *const oxcf = &cpi->oxcf; // Setup variables that depend on the dimensions of the frame. - set_mv_search_params(cpi); + vp9_set_speed_features_framesize_dependent(cpi); + + // Decide q and q bounds. + *q = vp9_rc_pick_q_and_bounds(cpi, bottom_index, top_index); + + if (!frame_is_intra_only(cm)) { + vp9_set_high_precision_mv(cpi, (*q) < HIGH_PRECISION_MV_QTHRESH); + } // Configure experimental use of segmentation for enhanced coding of // static regions if indicated. @@ -2656,19 +2671,6 @@ static void set_size_dependent_vars(VP9_COMP *cpi, int *q, vp9_denoise(cpi->Source, cpi->Source, l); } #endif // CONFIG_VP9_POSTPROC - - vp9_set_speed_features(cpi); - - vp9_set_rd_speed_thresholds(cpi); - vp9_set_rd_speed_thresholds_sub8x8(cpi); - - // Decide q and q bounds. - *q = vp9_rc_pick_q_and_bounds(cpi, bottom_index, top_index); - - if (!frame_is_intra_only(cm)) { - cm->interp_filter = cpi->sf.default_interp_filter; - vp9_set_high_precision_mv(cpi, (*q) < HIGH_PRECISION_MV_QTHRESH); - } } static void init_motion_estimation(VP9_COMP *cpi) { @@ -2681,36 +2683,28 @@ static void init_motion_estimation(VP9_COMP *cpi) { } } -extern void vbr_rate_correction(VP9_COMP *cpi, - int * this_frame_target, - const int64_t vbr_bits_off_target); - void set_frame_size(VP9_COMP *cpi) { int ref_frame; VP9_COMMON *const cm = &cpi->common; - const RATE_CONTROL *const rc = &cpi->rc; const VP9EncoderConfig *const oxcf = &cpi->oxcf; MACROBLOCKD *const xd = &cpi->mb.e_mbd; - if ((oxcf->pass == 2) && - (!cpi->use_svc || - (is_two_pass_svc(cpi) && - cpi->svc.encode_empty_frame_state != ENCODING))) { - int target_rate = rc->base_frame_target; - if (oxcf->rc_mode == VPX_VBR) - vbr_rate_correction(cpi, &target_rate, rc->vbr_bits_off_target); - vp9_rc_set_frame_target(cpi, target_rate); - } - if (oxcf->pass == 2 && cm->current_video_frame == 0 && - oxcf->allow_spatial_resampling && + oxcf->resize_mode == RESIZE_FIXED && oxcf->rc_mode == VPX_VBR) { // Internal scaling is triggered on the first frame. vp9_set_size_literal(cpi, oxcf->scaled_frame_width, oxcf->scaled_frame_height); } + if ((oxcf->pass == 2) && + (!cpi->use_svc || + (is_two_pass_svc(cpi) && + cpi->svc.encode_empty_frame_state != ENCODING))) { + vp9_set_target_rate(cpi); + } + // Reset the frame pointers to the current frame size. vp9_realloc_frame_buffer(get_frame_new_buffer(cm), cm->width, cm->height, @@ -2748,9 +2742,8 @@ void set_frame_size(VP9_COMP *cpi) { } static void encode_without_recode_loop(VP9_COMP *cpi) { - int q; - int bottom_index, top_index; // Dummy. VP9_COMMON *const cm = &cpi->common; + int q, bottom_index, top_index; // Dummy variables. vp9_clear_system_state(); @@ -2763,8 +2756,11 @@ static void encode_without_recode_loop(VP9_COMP *cpi) { cpi->Last_Source = vp9_scale_if_required(cm, cpi->unscaled_last_source, &cpi->scaled_last_source); - vp9_scale_references(cpi); + if (frame_is_intra_only(cm) == 0) { + vp9_scale_references(cpi); + } + set_size_independent_vars(cpi); set_size_dependent_vars(cpi, &q, &bottom_index, &top_index); vp9_set_quantizer(cm, q); @@ -2792,8 +2788,6 @@ static void encode_with_recode_loop(VP9_COMP *cpi, uint8_t *dest) { VP9_COMMON *const cm = &cpi->common; RATE_CONTROL *const rc = &cpi->rc; - int q; - int q_low, q_high; int bottom_index, top_index; int loop_count = 0; int loop = 0; @@ -2801,31 +2795,42 @@ static void encode_with_recode_loop(VP9_COMP *cpi, int undershoot_seen = 0; int frame_over_shoot_limit; int frame_under_shoot_limit; + int q = 0, q_low = 0, q_high = 0; + int frame_size_changed = 0; + + set_size_independent_vars(cpi); do { vp9_clear_system_state(); - if (loop_count == 0) { - set_frame_size(cpi); + set_frame_size(cpi); - // Decide frame size bounds - vp9_rc_compute_frame_size_bounds(cpi, rc->this_frame_target, - &frame_under_shoot_limit, - &frame_over_shoot_limit); + if (loop_count == 0 || frame_size_changed != 0) { + set_size_dependent_vars(cpi, &q, &bottom_index, &top_index); + q_low = bottom_index; + q_high = top_index; - cpi->Source = vp9_scale_if_required(cm, cpi->un_scaled_source, - &cpi->scaled_source); + // TODO(agrange) Scale cpi->max_mv_magnitude if frame-size has changed. + set_mv_search_params(cpi); + } - if (cpi->unscaled_last_source != NULL) - cpi->Last_Source = vp9_scale_if_required(cm, cpi->unscaled_last_source, - &cpi->scaled_last_source); + // Decide frame size bounds + vp9_rc_compute_frame_size_bounds(cpi, rc->this_frame_target, + &frame_under_shoot_limit, + &frame_over_shoot_limit); - vp9_scale_references(cpi); + cpi->Source = vp9_scale_if_required(cm, cpi->un_scaled_source, + &cpi->scaled_source); - set_size_dependent_vars(cpi, &q, &bottom_index, &top_index); + if (cpi->unscaled_last_source != NULL) + cpi->Last_Source = vp9_scale_if_required(cm, cpi->unscaled_last_source, + &cpi->scaled_last_source); - q_low = bottom_index; - q_high = top_index; + if (frame_is_intra_only(cm) == 0) { + if (loop_count > 0) { + release_scaled_references(cpi); + } + vp9_scale_references(cpi); } vp9_set_quantizer(cm, q); @@ -3272,7 +3277,9 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, if (cm->seg.update_map) update_reference_segmentation_map(cpi); - release_scaled_references(cpi); + if (frame_is_intra_only(cm) == 0) { + release_scaled_references(cpi); + } vp9_update_reference_frames(cpi); for (t = TX_4X4; t <= TX_32X32; t++) @@ -3744,7 +3751,7 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags, cm->frame_contexts[cm->frame_context_idx] = *cm->fc; // No frame encoded, or frame was dropped, release scaled references. - if (*size == 0) { + if ((*size == 0) && (frame_is_intra_only(cm) == 0)) { release_scaled_references(cpi); } diff --git a/vp9/encoder/vp9_encoder.h b/vp9/encoder/vp9_encoder.h index f0c05430a..206d1df6e 100644 --- a/vp9/encoder/vp9_encoder.h +++ b/vp9/encoder/vp9_encoder.h @@ -110,6 +110,11 @@ typedef enum { AQ_MODE_COUNT // This should always be the last member of the enum } AQ_MODE; +typedef enum { + RESIZE_NONE = 0, // No frame resizing allowed (except for SVC). + RESIZE_FIXED = 1, // All frames are coded at the specified dimension. + RESIZE_DYNAMIC = 2 // Coded size of each frame is determined by the codec. +} RESIZE_TYPE; typedef struct VP9EncoderConfig { BITSTREAM_PROFILE profile; @@ -165,7 +170,7 @@ typedef struct VP9EncoderConfig { AQ_MODE aq_mode; // Adaptive Quantization mode // Internal frame size scaling. - int allow_spatial_resampling; + RESIZE_TYPE resize_mode; int scaled_frame_width; int scaled_frame_height; @@ -472,6 +477,12 @@ void vp9_set_svc(VP9_COMP *cpi, int use_svc); int vp9_get_quantizer(struct VP9_COMP *cpi); +static INLINE int frame_is_kf_gf_arf(const VP9_COMP *cpi) { + return frame_is_intra_only(&cpi->common) || + cpi->refresh_alt_ref_frame || + (cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref); +} + static INLINE int get_ref_frame_idx(const VP9_COMP *cpi, MV_REFERENCE_FRAME ref_frame) { if (ref_frame == LAST_FRAME) { diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c index 327082fcd..3f462c052 100644 --- a/vp9/encoder/vp9_firstpass.c +++ b/vp9/encoder/vp9_firstpass.c @@ -338,9 +338,9 @@ static unsigned int highbd_get_prediction_error(BLOCK_SIZE bsize, // Refine the motion search range according to the frame dimension // for first pass test. -static int get_search_range(const VP9_COMMON *cm) { +static int get_search_range(const VP9_COMP *cpi) { int sr = 0; - const int dim = MIN(cm->width, cm->height); + const int dim = MIN(cpi->initial_width, cpi->initial_height); while ((dim << sr) < MAX_FULL_PEL_VAL) ++sr; @@ -360,7 +360,7 @@ static void first_pass_motion_search(VP9_COMP *cpi, MACROBLOCK *x, int step_param = 3; int further_steps = (MAX_MVSEARCH_STEPS - 1) - step_param; - const int sr = get_search_range(&cpi->common); + const int sr = get_search_range(cpi); step_param += sr; further_steps -= sr; @@ -947,7 +947,8 @@ void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *source) { // Initial estimate here uses sqrt(mbs) to define the min_err, where the // number of mbs is proportional to the image area. const int num_mbs = - cpi->oxcf.allow_spatial_resampling ? cpi->initial_mbs : cpi->common.MBs; + cpi->oxcf.resize_mode == RESIZE_FIXED ? + cpi->initial_mbs : cpi->common.MBs; const double min_err = 200 * sqrt(num_mbs); intra_factor = intra_factor / (double)num_mbs; @@ -1088,7 +1089,8 @@ static int get_twopass_worst_quality(const VP9_COMP *cpi, return rc->worst_quality; // Highest value allowed } else { const int num_mbs = - cpi->oxcf.allow_spatial_resampling ? cpi->initial_mbs : cpi->common.MBs; + cpi->oxcf.resize_mode == RESIZE_FIXED ? + cpi->initial_mbs : cpi->common.MBs; const double section_err = stats->coded_error / stats->count; const double err_per_mb = section_err / num_mbs; const double speed_term = 1.0 + 0.04 * oxcf->speed; @@ -1206,7 +1208,8 @@ void vp9_init_second_pass(VP9_COMP *cpi) { static double get_sr_decay_rate(const VP9_COMP *cpi, const FIRSTPASS_STATS *frame) { const int num_mbs = - cpi->oxcf.allow_spatial_resampling ? cpi->initial_mbs : cpi->common.MBs; + cpi->oxcf.resize_mode == RESIZE_FIXED ? + cpi->initial_mbs : cpi->common.MBs; double sr_diff = (frame->sr_coded_error - frame->coded_error) / num_mbs; double sr_decay = 1.0; @@ -1333,7 +1336,8 @@ static double calc_frame_boost(VP9_COMP *cpi, cpi->common.bit_depth); const double boost_q_correction = MIN((0.5 + (lq * 0.015)), 1.5); const int num_mbs = - cpi->oxcf.allow_spatial_resampling ? cpi->initial_mbs : cpi->common.MBs; + cpi->oxcf.resize_mode == RESIZE_FIXED ? + cpi->initial_mbs : cpi->common.MBs; // Underlying boost factor is based on inter error ratio. frame_boost = (BASELINE_ERR_PER_MB * num_mbs) / @@ -1744,7 +1748,7 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { // Motion breakout threshold for loop below depends on image size. mv_ratio_accumulator_thresh = - (cpi->common.height + cpi->common.width) / 4.0; + (cpi->initial_height + cpi->initial_width) / 4.0; // Set a maximum and minimum interval for the GF group. // If the image appears almost completely static we can extend beyond this. @@ -1802,8 +1806,7 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { // Monitor for static sections. zero_motion_accumulator = - MIN(zero_motion_accumulator, - get_zero_motion_factor(cpi, &next_frame)); + MIN(zero_motion_accumulator, get_zero_motion_factor(cpi, &next_frame)); // Break clause to detect very still sections after motion. For example, // a static image after a fade or other transition. @@ -2237,36 +2240,6 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { twopass->modified_error_left -= kf_group_err; } -#define VBR_PCT_ADJUSTMENT_LIMIT 50 -// For VBR...adjustment to the frame target based on error from previous frames -void vbr_rate_correction(VP9_COMP *cpi, - int * this_frame_target, - const int64_t vbr_bits_off_target) { - int max_delta; - double position_factor = 1.0; - - // How far through the clip are we. - // This number is used to damp the per frame rate correction. - // Range 0 - 1.0 - if (cpi->twopass.total_stats.count) { - position_factor = sqrt((double)cpi->common.current_video_frame / - cpi->twopass.total_stats.count); - } - max_delta = (int)(position_factor * - ((*this_frame_target * VBR_PCT_ADJUSTMENT_LIMIT) / 100)); - - // vbr_bits_off_target > 0 means we have extra bits to spend - if (vbr_bits_off_target > 0) { - *this_frame_target += - (vbr_bits_off_target > max_delta) ? max_delta - : (int)vbr_bits_off_target; - } else { - *this_frame_target -= - (vbr_bits_off_target < -max_delta) ? max_delta - : (int)-vbr_bits_off_target; - } -} - // Define the reference buffers that will be updated post encode. void configure_buffer_updates(VP9_COMP *cpi) { TWO_PASS *const twopass = &cpi->twopass; diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c index 6f165797e..bd5b0df82 100644 --- a/vp9/encoder/vp9_ratectrl.c +++ b/vp9/encoder/vp9_ratectrl.c @@ -1575,3 +1575,43 @@ void vp9_rc_update_framerate(VP9_COMP *cpi) { vp9_rc_set_gf_max_interval(cpi, rc); } + +#define VBR_PCT_ADJUSTMENT_LIMIT 50 +// For VBR...adjustment to the frame target based on error from previous frames +static void vbr_rate_correction(VP9_COMP *cpi, + int *this_frame_target, + int64_t vbr_bits_off_target) { + int max_delta; + double position_factor = 1.0; + + // How far through the clip are we. + // This number is used to damp the per frame rate correction. + // Range 0 - 1.0 + if (cpi->twopass.total_stats.count) { + position_factor = sqrt((double)cpi->common.current_video_frame / + cpi->twopass.total_stats.count); + } + max_delta = (int)(position_factor * + ((*this_frame_target * VBR_PCT_ADJUSTMENT_LIMIT) / 100)); + + // vbr_bits_off_target > 0 means we have extra bits to spend + if (vbr_bits_off_target > 0) { + *this_frame_target += + (vbr_bits_off_target > max_delta) ? max_delta + : (int)vbr_bits_off_target; + } else { + *this_frame_target -= + (vbr_bits_off_target < -max_delta) ? max_delta + : (int)-vbr_bits_off_target; + } +} + +void vp9_set_target_rate(VP9_COMP *cpi) { + RATE_CONTROL *const rc = &cpi->rc; + int target_rate = rc->base_frame_target; + + // Correction to rate target based on prior over or under shoot. + if (cpi->oxcf.rc_mode == VPX_VBR) + vbr_rate_correction(cpi, &target_rate, rc->vbr_bits_off_target); + vp9_rc_set_frame_target(cpi, target_rate); +} diff --git a/vp9/encoder/vp9_ratectrl.h b/vp9/encoder/vp9_ratectrl.h index bc74129e5..2bc5b59f2 100644 --- a/vp9/encoder/vp9_ratectrl.h +++ b/vp9/encoder/vp9_ratectrl.h @@ -198,6 +198,8 @@ void vp9_rc_update_framerate(struct VP9_COMP *cpi); void vp9_rc_set_gf_max_interval(const struct VP9_COMP *const cpi, RATE_CONTROL *const rc); +void vp9_set_target_rate(struct VP9_COMP *cpi); + #ifdef __cplusplus } // extern "C" #endif diff --git a/vp9/encoder/vp9_rd.c b/vp9/encoder/vp9_rd.c index 2f19d2942..4ed324a0e 100644 --- a/vp9/encoder/vp9_rd.c +++ b/vp9/encoder/vp9_rd.c @@ -591,18 +591,13 @@ void vp9_set_rd_speed_thresholds(VP9_COMP *cpi) { } void vp9_set_rd_speed_thresholds_sub8x8(VP9_COMP *cpi) { - const SPEED_FEATURES *const sf = &cpi->sf; - RD_OPT *const rd = &cpi->rd; - int i; static const int thresh_mult[2][MAX_REFS] = {{2500, 2500, 2500, 4500, 4500, 2500}, {2000, 2000, 2000, 4000, 4000, 2000}}; - - for (i = 0; i < MAX_REFS; ++i) { - rd->thresh_mult_sub8x8[i] = - (sf->disable_split_mask & (1 << i)) ? - INT_MAX : thresh_mult[cpi->oxcf.mode == BEST][i]; - } + RD_OPT *const rd = &cpi->rd; + const int idx = cpi->oxcf.mode == BEST; + vpx_memcpy(rd->thresh_mult_sub8x8, thresh_mult[idx], + sizeof(thresh_mult[idx])); } void vp9_update_rd_thresh_fact(int (*factor_buf)[MAX_MODES], int rd_thresh, diff --git a/vp9/encoder/vp9_speed_features.c b/vp9/encoder/vp9_speed_features.c index 7a1b0cc1f..9225ae2c6 100644 --- a/vp9/encoder/vp9_speed_features.c +++ b/vp9/encoder/vp9_speed_features.c @@ -16,12 +16,61 @@ // Intra only frames, golden frames (except alt ref overlays) and // alt ref frames tend to be coded at a higher than ambient quality static int frame_is_boosted(const VP9_COMP *cpi) { - return frame_is_intra_only(&cpi->common) || - cpi->refresh_alt_ref_frame || - (cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref) || - vp9_is_upper_layer_key_frame(cpi); + return frame_is_kf_gf_arf(cpi) || vp9_is_upper_layer_key_frame(cpi); } +static void set_good_speed_feature_framesize_dependent(VP9_COMMON *cm, + SPEED_FEATURES *sf, + int speed) { + if (speed >= 1) { + if (MIN(cm->width, cm->height) >= 720) { + sf->disable_split_mask = cm->show_frame ? DISABLE_ALL_SPLIT + : DISABLE_ALL_INTER_SPLIT; + sf->partition_search_breakout_dist_thr = (1 << 23); + } else { + sf->disable_split_mask = DISABLE_COMPOUND_SPLIT; + sf->partition_search_breakout_dist_thr = (1 << 21); + } + } + + if (speed >= 2) { + if (MIN(cm->width, cm->height) >= 720) { + sf->disable_split_mask = cm->show_frame ? DISABLE_ALL_SPLIT + : DISABLE_ALL_INTER_SPLIT; + sf->adaptive_pred_interp_filter = 0; + sf->partition_search_breakout_dist_thr = (1 << 24); + sf->partition_search_breakout_rate_thr = 120; + } else { + sf->disable_split_mask = LAST_AND_INTRA_SPLIT_ONLY; + sf->partition_search_breakout_dist_thr = (1 << 22); + sf->partition_search_breakout_rate_thr = 100; + } + } + + if (speed >= 3) { + if (MIN(cm->width, cm->height) >= 720) { + sf->disable_split_mask = DISABLE_ALL_SPLIT; + sf->schedule_mode_search = cm->base_qindex < 220 ? 1 : 0; + sf->partition_search_breakout_dist_thr = (1 << 25); + sf->partition_search_breakout_rate_thr = 200; + } else { + sf->max_intra_bsize = BLOCK_32X32; + sf->disable_split_mask = DISABLE_ALL_INTER_SPLIT; + sf->schedule_mode_search = cm->base_qindex < 175 ? 1 : 0; + sf->partition_search_breakout_dist_thr = (1 << 23); + sf->partition_search_breakout_rate_thr = 120; + } + } + + if (speed >= 4) { + if (MIN(cm->width, cm->height) >= 720) { + sf->partition_search_breakout_dist_thr = (1 << 26); + } else { + sf->partition_search_breakout_dist_thr = (1 << 24); + } + sf->disable_split_mask = DISABLE_ALL_SPLIT; + } +} static void set_good_speed_feature(VP9_COMP *cpi, VP9_COMMON *cm, SPEED_FEATURES *sf, int speed) { @@ -34,11 +83,6 @@ static void set_good_speed_feature(VP9_COMP *cpi, VP9_COMMON *cm, sf->use_square_partition_only = !frame_is_intra_only(cm); sf->less_rectangular_check = 1; - if (MIN(cm->width, cm->height) >= 720) - sf->disable_split_mask = cm->show_frame ? DISABLE_ALL_SPLIT - : DISABLE_ALL_INTER_SPLIT; - else - sf->disable_split_mask = DISABLE_COMPOUND_SPLIT; sf->use_rd_breakout = 1; sf->adaptive_motion_search = 1; sf->mv.auto_mv_step_size = 1; @@ -54,11 +98,6 @@ static void set_good_speed_feature(VP9_COMP *cpi, VP9_COMMON *cm, sf->intra_uv_mode_mask[TX_16X16] = INTRA_DC_H_V; sf->tx_size_search_breakout = 1; - - if (MIN(cm->width, cm->height) >= 720) - sf->partition_search_breakout_dist_thr = (1 << 23); - else - sf->partition_search_breakout_dist_thr = (1 << 21); sf->partition_search_breakout_rate_thr = 80; } @@ -66,18 +105,6 @@ static void set_good_speed_feature(VP9_COMP *cpi, VP9_COMMON *cm, sf->tx_size_search_method = frame_is_boosted(cpi) ? USE_FULL_RD : USE_LARGESTALL; - if (MIN(cm->width, cm->height) >= 720) { - sf->disable_split_mask = cm->show_frame ? DISABLE_ALL_SPLIT - : DISABLE_ALL_INTER_SPLIT; - sf->adaptive_pred_interp_filter = 0; - sf->partition_search_breakout_dist_thr = (1 << 24); - sf->partition_search_breakout_rate_thr = 120; - } else { - sf->disable_split_mask = LAST_AND_INTRA_SPLIT_ONLY; - sf->partition_search_breakout_dist_thr = (1 << 22); - sf->partition_search_breakout_rate_thr = 100; - } - sf->reference_masking = 1; sf->mode_search_skip_flags = FLAG_SKIP_INTRA_DIRMISMATCH | FLAG_SKIP_INTRA_BESTINTER | @@ -93,18 +120,6 @@ static void set_good_speed_feature(VP9_COMP *cpi, VP9_COMMON *cm, if (speed >= 3) { sf->tx_size_search_method = frame_is_intra_only(cm) ? USE_FULL_RD : USE_LARGESTALL; - if (MIN(cm->width, cm->height) >= 720) { - sf->disable_split_mask = DISABLE_ALL_SPLIT; - sf->schedule_mode_search = cm->base_qindex < 220 ? 1 : 0; - sf->partition_search_breakout_dist_thr = (1 << 25); - sf->partition_search_breakout_rate_thr = 200; - } else { - sf->max_intra_bsize = BLOCK_32X32; - sf->disable_split_mask = DISABLE_ALL_INTER_SPLIT; - sf->schedule_mode_search = cm->base_qindex < 175 ? 1 : 0; - sf->partition_search_breakout_dist_thr = (1 << 23); - sf->partition_search_breakout_rate_thr = 120; - } sf->mv.subpel_search_method = SUBPEL_TREE_PRUNED; sf->adaptive_pred_interp_filter = 0; sf->adaptive_mode_search = 1; @@ -122,7 +137,6 @@ static void set_good_speed_feature(VP9_COMP *cpi, VP9_COMMON *cm, if (speed >= 4) { sf->use_square_partition_only = 1; sf->tx_size_search_method = USE_LARGESTALL; - sf->disable_split_mask = DISABLE_ALL_SPLIT; sf->mv.search_method = BIGDIA; sf->mv.subpel_search_method = SUBPEL_TREE_PRUNED_MORE; sf->adaptive_rd_thresh = 4; @@ -132,11 +146,6 @@ static void set_good_speed_feature(VP9_COMP *cpi, VP9_COMMON *cm, sf->use_fast_coef_updates = ONE_LOOP_REDUCED; sf->use_fast_coef_costing = 1; sf->motion_field_mode_search = !boosted; - - if (MIN(cm->width, cm->height) >= 720) - sf->partition_search_breakout_dist_thr = (1 << 26); - else - sf->partition_search_breakout_dist_thr = (1 << 24); sf->partition_search_breakout_rate_thr = 300; } @@ -154,6 +163,42 @@ static void set_good_speed_feature(VP9_COMP *cpi, VP9_COMMON *cm, } } +static void set_rt_speed_feature_framesize_dependent(VP9_COMP *cpi, + SPEED_FEATURES *sf, int speed) { + VP9_COMMON *const cm = &cpi->common; + + if (speed >= 1) { + if (MIN(cm->width, cm->height) >= 720) { + sf->disable_split_mask = cm->show_frame ? DISABLE_ALL_SPLIT + : DISABLE_ALL_INTER_SPLIT; + } else { + sf->disable_split_mask = DISABLE_COMPOUND_SPLIT; + } + } + + if (speed >= 2) { + if (MIN(cm->width, cm->height) >= 720) { + sf->disable_split_mask = cm->show_frame ? DISABLE_ALL_SPLIT + : DISABLE_ALL_INTER_SPLIT; + } else { + sf->disable_split_mask = LAST_AND_INTRA_SPLIT_ONLY; + } + } + + if (speed >= 5) { + if (MIN(cm->width, cm->height) >= 720) { + sf->partition_search_breakout_dist_thr = (1 << 25); + } else { + sf->partition_search_breakout_dist_thr = (1 << 23); + } + } + + if (speed >= 7) { + sf->encode_breakout_thresh = (MIN(cm->width, cm->height) >= 720) ? + 800 : 300; + } +} + static void set_rt_speed_feature(VP9_COMP *cpi, SPEED_FEATURES *sf, int speed, vp9e_tune_content content) { VP9_COMMON *const cm = &cpi->common; @@ -169,12 +214,6 @@ static void set_rt_speed_feature(VP9_COMP *cpi, SPEED_FEATURES *sf, sf->tx_size_search_method = frame_is_intra_only(cm) ? USE_FULL_RD : USE_LARGESTALL; - if (MIN(cm->width, cm->height) >= 720) - sf->disable_split_mask = cm->show_frame ? DISABLE_ALL_SPLIT - : DISABLE_ALL_INTER_SPLIT; - else - sf->disable_split_mask = DISABLE_COMPOUND_SPLIT; - sf->use_rd_breakout = 1; sf->adaptive_motion_search = 1; @@ -187,12 +226,6 @@ static void set_rt_speed_feature(VP9_COMP *cpi, SPEED_FEATURES *sf, } if (speed >= 2) { - if (MIN(cm->width, cm->height) >= 720) - sf->disable_split_mask = cm->show_frame ? DISABLE_ALL_SPLIT - : DISABLE_ALL_INTER_SPLIT; - else - sf->disable_split_mask = LAST_AND_INTRA_SPLIT_ONLY; - sf->mode_search_skip_flags = FLAG_SKIP_INTRA_DIRMISMATCH | FLAG_SKIP_INTRA_BESTINTER | FLAG_SKIP_COMP_BESTINTRA | @@ -270,11 +303,6 @@ static void set_rt_speed_feature(VP9_COMP *cpi, SPEED_FEATURES *sf, sf->adaptive_rd_thresh = 2; // This feature is only enabled when partition search is disabled. sf->reuse_inter_pred_sby = 1; - - if (MIN(cm->width, cm->height) >= 720) - sf->partition_search_breakout_dist_thr = (1 << 25); - else - sf->partition_search_breakout_dist_thr = (1 << 23); sf->partition_search_breakout_rate_thr = 200; } @@ -299,8 +327,6 @@ static void set_rt_speed_feature(VP9_COMP *cpi, SPEED_FEATURES *sf, sf->mv.search_method = FAST_DIAMOND; sf->mv.fullpel_search_step_param = 10; sf->lpf_pick = LPF_PICK_MINIMAL_LPF; - sf->encode_breakout_thresh = (MIN(cm->width, cm->height) >= 720) ? - 800 : 300; } if (speed >= 12) { @@ -316,7 +342,37 @@ static void set_rt_speed_feature(VP9_COMP *cpi, SPEED_FEATURES *sf, } } -void vp9_set_speed_features(VP9_COMP *cpi) { +void vp9_set_speed_features_framesize_dependent(VP9_COMP *cpi) { + SPEED_FEATURES *const sf = &cpi->sf; + VP9_COMMON *const cm = &cpi->common; + const VP9EncoderConfig *const oxcf = &cpi->oxcf; + RD_OPT *const rd = &cpi->rd; + int i; + + if (oxcf->mode == REALTIME) { + set_rt_speed_feature_framesize_dependent(cpi, sf, oxcf->speed); + } else if (oxcf->mode == GOOD) { + set_good_speed_feature_framesize_dependent(cm, sf, oxcf->speed); + } + + if (sf->disable_split_mask == DISABLE_ALL_SPLIT) { + sf->adaptive_pred_interp_filter = 0; + } + + if (cpi->encode_breakout && oxcf->mode == REALTIME && + sf->encode_breakout_thresh > cpi->encode_breakout) { + cpi->encode_breakout = sf->encode_breakout_thresh; + } + + // Check for masked out split cases. + for (i = 0; i < MAX_REFS; ++i) { + if (sf->disable_split_mask & (1 << i)) { + rd->thresh_mult_sub8x8[i] = INT_MAX; + } + } +} + +void vp9_set_speed_features_framesize_independent(VP9_COMP *cpi) { SPEED_FEATURES *const sf = &cpi->sf; VP9_COMMON *const cm = &cpi->common; const VP9EncoderConfig *const oxcf = &cpi->oxcf; @@ -427,14 +483,7 @@ void vp9_set_speed_features(VP9_COMP *cpi) { cpi->mb.optimize = sf->optimize_coefficients == 1 && oxcf->pass != 1; - if (sf->disable_split_mask == DISABLE_ALL_SPLIT) - sf->adaptive_pred_interp_filter = 0; - if (!cpi->oxcf.frame_periodic_boost) { sf->max_delta_qindex = 0; } - - if (cpi->encode_breakout && oxcf->mode == REALTIME && - sf->encode_breakout_thresh > cpi->encode_breakout) - cpi->encode_breakout = sf->encode_breakout_thresh; } diff --git a/vp9/encoder/vp9_speed_features.h b/vp9/encoder/vp9_speed_features.h index a314f6040..53b504113 100644 --- a/vp9/encoder/vp9_speed_features.h +++ b/vp9/encoder/vp9_speed_features.h @@ -416,7 +416,8 @@ typedef struct SPEED_FEATURES { struct VP9_COMP; -void vp9_set_speed_features(struct VP9_COMP *cpi); +void vp9_set_speed_features_framesize_independent(struct VP9_COMP *cpi); +void vp9_set_speed_features_framesize_dependent(struct VP9_COMP *cpi); #ifdef __cplusplus } // extern "C" |