summaryrefslogtreecommitdiff
path: root/vp9/encoder
diff options
context:
space:
mode:
Diffstat (limited to 'vp9/encoder')
-rw-r--r--vp9/encoder/vp9_encoder.c121
-rw-r--r--vp9/encoder/vp9_encoder.h13
-rw-r--r--vp9/encoder/vp9_firstpass.c53
-rw-r--r--vp9/encoder/vp9_ratectrl.c40
-rw-r--r--vp9/encoder/vp9_ratectrl.h2
-rw-r--r--vp9/encoder/vp9_rd.c13
-rw-r--r--vp9/encoder/vp9_speed_features.c191
-rw-r--r--vp9/encoder/vp9_speed_features.h3
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"