summaryrefslogtreecommitdiff
path: root/vp9/encoder
diff options
context:
space:
mode:
Diffstat (limited to 'vp9/encoder')
-rw-r--r--vp9/encoder/vp9_encodeframe.c91
-rw-r--r--vp9/encoder/vp9_firstpass.c13
-rw-r--r--vp9/encoder/vp9_onyx_if.c28
-rw-r--r--vp9/encoder/vp9_onyx_int.h22
-rw-r--r--vp9/encoder/vp9_rdopt.c70
5 files changed, 137 insertions, 87 deletions
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c
index 45758e7cb..6a70e8e9d 100644
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -1547,7 +1547,7 @@ static void get_sb_partition_size_range(VP9_COMP *cpi, MODE_INFO * mi,
// Look at neighboring blocks and set a min and max partition size based on
// what they chose.
-static void rd_auto_partition_range(VP9_COMP *cpi,
+static void rd_auto_partition_range(VP9_COMP *cpi, int row, int col,
BLOCK_SIZE *min_block_size,
BLOCK_SIZE *max_block_size) {
MACROBLOCKD *const xd = &cpi->mb.e_mbd;
@@ -1565,38 +1565,48 @@ static void rd_auto_partition_range(VP9_COMP *cpi,
cpi->sf.auto_min_max_partition_interval;
*min_block_size = BLOCK_4X4;
*max_block_size = BLOCK_64X64;
- return;
} else {
--cpi->sf.auto_min_max_partition_count;
- }
- // Set default values if not left or above neighbour
- if (!left_in_image && !above_in_image) {
- *min_block_size = BLOCK_4X4;
- *max_block_size = BLOCK_64X64;
- } else {
- // Default "min to max" and "max to min"
- *min_block_size = BLOCK_64X64;
- *max_block_size = BLOCK_4X4;
-
- // Find the min and max partition sizes used in the left SB64
- if (left_in_image) {
- left_sb64_mi = &mi[-MI_BLOCK_SIZE];
- get_sb_partition_size_range(cpi, left_sb64_mi,
- min_block_size, max_block_size);
- }
+ // Set default values if no left or above neighbour
+ if (!left_in_image && !above_in_image) {
+ *min_block_size = BLOCK_4X4;
+ *max_block_size = BLOCK_64X64;
+ } else {
+ VP9_COMMON *const cm = &cpi->common;
+ int row8x8_remaining = cm->cur_tile_mi_row_end - row;
+ int col8x8_remaining = cm->cur_tile_mi_col_end - col;
+ int bh, bw;
+
+ // Default "min to max" and "max to min"
+ *min_block_size = BLOCK_64X64;
+ *max_block_size = BLOCK_4X4;
+
+ // Find the min and max partition sizes used in the left SB64
+ if (left_in_image) {
+ left_sb64_mi = &mi[-MI_BLOCK_SIZE];
+ get_sb_partition_size_range(cpi, left_sb64_mi,
+ min_block_size, max_block_size);
+ }
- // Find the min and max partition sizes used in the above SB64 taking
- // the values found for left as a starting point.
- if (above_in_image) {
- above_sb64_mi = &mi[-xd->mode_info_stride * MI_BLOCK_SIZE];
- get_sb_partition_size_range(cpi, above_sb64_mi,
- min_block_size, max_block_size);
- }
+ // Find the min and max partition sizes used in the above SB64 taking
+ // the values found for left as a starting point.
+ if (above_in_image) {
+ above_sb64_mi = &mi[-xd->mode_info_stride * MI_BLOCK_SIZE];
+ get_sb_partition_size_range(cpi, above_sb64_mi,
+ min_block_size, max_block_size);
+ }
+
+ // Give a bit of leaway either side of the observed min and max
+ *min_block_size = min_partition_size[*min_block_size];
+ *max_block_size = max_partition_size[*max_block_size];
- // give a bit of leaway either side of the observed min and max
- *min_block_size = min_partition_size[*min_block_size];
- *max_block_size = max_partition_size[*max_block_size];
+ // Check border cases where max and min from neighbours may not be legal.
+ *max_block_size = find_partition_size(*max_block_size,
+ row8x8_remaining, col8x8_remaining,
+ &bh, &bw);
+ *min_block_size = MIN(*min_block_size, *max_block_size);
+ }
}
}
@@ -1780,11 +1790,24 @@ static void rd_pick_partition(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row,
}
sum_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_dist);
if (sum_rd < best_rd) {
+ int64_t stop_thresh = 2048;
+
best_rate = this_rate;
best_dist = this_dist;
best_rd = sum_rd;
if (bsize >= BLOCK_8X8)
*(get_sb_partitioning(x, bsize)) = bsize;
+
+ // Adjust threshold according to partition size.
+ stop_thresh >>= 8 - (b_width_log2_lookup[bsize] +
+ b_height_log2_lookup[bsize]);
+
+ // If obtained distortion is very small, choose current partition
+ // and stop splitting.
+ if (this_dist < stop_thresh) {
+ do_split = 0;
+ do_rect = 0;
+ }
}
}
restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
@@ -1989,13 +2012,6 @@ static void encode_sb_row(VP9_COMP *cpi, int mi_row, TOKENEXTRA **tp,
int dummy_rate;
int64_t dummy_dist;
- // Initialize a mask of modes that we will not consider;
- // cpi->unused_mode_skip_mask = 0x0000000AAE17F800 (test no golden)
- if (cpi->common.frame_type == KEY_FRAME)
- cpi->unused_mode_skip_mask = 0;
- else
- cpi->unused_mode_skip_mask = 0xFFFFFFFFFFFFFE00;
-
if (cpi->sf.reference_masking)
rd_pick_reference_frame(cpi, mi_row, mi_col);
@@ -2025,7 +2041,7 @@ static void encode_sb_row(VP9_COMP *cpi, int mi_row, TOKENEXTRA **tp,
// If required set upper and lower partition size limits
if (cpi->sf.auto_min_max_partition_size) {
set_offsets(cpi, mi_row, mi_col, BLOCK_64X64);
- rd_auto_partition_range(cpi,
+ rd_auto_partition_range(cpi, mi_row, mi_col,
&cpi->sf.min_partition_size,
&cpi->sf.max_partition_size);
}
@@ -2041,7 +2057,8 @@ static void encode_sb_row(VP9_COMP *cpi, int mi_row, TOKENEXTRA **tp,
// If required set upper and lower partition size limits
if (cpi->sf.auto_min_max_partition_size) {
set_offsets(cpi, mi_row, mi_col, BLOCK_64X64);
- rd_auto_partition_range(cpi, &cpi->sf.min_partition_size,
+ rd_auto_partition_range(cpi, mi_row, mi_col,
+ &cpi->sf.min_partition_size,
&cpi->sf.max_partition_size);
}
diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c
index 0cbe3abb8..c5b348582 100644
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -1717,6 +1717,8 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
old_boost_score = boost_score;
}
+ cpi->gf_zeromotion_pct = (int)(zero_motion_accumulator * 1000.0);
+
// Don't allow a gf too near the next kf
if ((cpi->twopass.frames_to_key - i) < MIN_GF_INTERVAL) {
while (i < cpi->twopass.frames_to_key) {
@@ -2162,6 +2164,8 @@ void vp9_second_pass(VP9_COMP *cpi) {
// Define next gf group and assign bits to it
this_frame_copy = this_frame;
+ cpi->gf_zeromotion_pct = 0;
+
#if CONFIG_MULTIPLE_ARF
if (cpi->multi_arf_enabled) {
define_fixed_arf_period(cpi);
@@ -2172,6 +2176,15 @@ void vp9_second_pass(VP9_COMP *cpi) {
}
#endif
+ if (cpi->gf_zeromotion_pct > 995) {
+ // As long as max_thresh for encode breakout is small enough, it is ok
+ // to enable it for no-show frame, i.e. set enable_encode_breakout to 2.
+ if (!cpi->common.show_frame)
+ cpi->enable_encode_breakout = 0;
+ else
+ cpi->enable_encode_breakout = 2;
+ }
+
// If we are going to code an altref frame at the end of the group
// and the current frame is not a key frame....
// If the previous group used an arf this frame has already benefited
diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c
index 1484bbb54..f47025325 100644
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -743,9 +743,8 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
sf->use_fast_lpf_pick = 0;
sf->use_fast_coef_updates = 0;
sf->using_small_partition_info = 0;
- // Skip any mode not chosen at size < X for all sizes > X
- // Hence BLOCK_64X64 (skip is off)
- sf->unused_mode_skip_lvl = BLOCK_64X64;
+ sf->mode_skip_start = MAX_MODES; // Mode index at which mode skip mask set
+
#if CONFIG_MULTIPLE_ARF
// Switch segmentation off.
@@ -782,7 +781,6 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
cpi->common.show_frame == 0);
sf->disable_splitmv =
(MIN(cpi->common.width, cpi->common.height) >= 720)? 1 : 0;
- sf->unused_mode_skip_lvl = BLOCK_32X32;
sf->mode_search_skip_flags = FLAG_SKIP_INTRA_DIRMISMATCH |
FLAG_SKIP_INTRA_BESTINTER |
FLAG_SKIP_COMP_BESTINTRA |
@@ -804,6 +802,7 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
sf->intra_y_mode_mask = INTRA_DC_TM_H_V;
sf->intra_uv_mode_mask = INTRA_DC_TM_H_V;
sf->use_fast_coef_updates = 1;
+ sf->mode_skip_start = 9;
}
if (speed == 2) {
sf->adjust_thresholds_by_speed = 1;
@@ -813,7 +812,6 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
sf->use_lastframe_partitioning = 1;
sf->adjust_partitioning_from_last_frame = 1;
sf->last_partitioning_redo_frequency = 3;
- sf->unused_mode_skip_lvl = BLOCK_32X32;
sf->tx_size_search_method = ((cpi->common.frame_type == KEY_FRAME ||
cpi->common.intra_only ||
cpi->common.show_frame == 0) ?
@@ -843,6 +841,7 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
sf->disable_split_var_thresh = 32;
sf->disable_filter_search_var_thresh = 32;
sf->use_fast_coef_updates = 2;
+ sf->mode_skip_start = 9;
}
if (speed == 3) {
sf->comp_inter_joint_search_thresh = BLOCK_SIZES;
@@ -870,6 +869,7 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
sf->intra_y_mode_mask = INTRA_DC_ONLY;
sf->intra_uv_mode_mask = INTRA_DC_ONLY;
sf->use_fast_coef_updates = 2;
+ sf->mode_skip_start = 9;
}
if (speed == 4) {
sf->comp_inter_joint_search_thresh = BLOCK_SIZES;
@@ -901,20 +901,8 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
sf->intra_y_mode_mask = INTRA_DC_ONLY;
sf->intra_uv_mode_mask = INTRA_DC_ONLY;
sf->use_fast_coef_updates = 2;
+ sf->mode_skip_start = 9;
}
- /*
- if (speed == 2) {
- sf->first_step = 0;
- sf->comp_inter_joint_search_thresh = BLOCK_8X8;
- sf->max_partition_size = BLOCK_16X16;
- }
- if (speed == 3) {
- sf->first_step = 0;
- sf->comp_inter_joint_search_thresh = BLOCK_B8X8;
- sf->min_partition_size = BLOCK_8X8;
- }
- */
-
break;
}; /* switch */
@@ -1602,6 +1590,8 @@ VP9_PTR vp9_create_compressor(VP9_CONFIG *oxcf) {
cpi->output_pkt_list = oxcf->output_pkt_list;
+ cpi->enable_encode_breakout = 1;
+
if (cpi->pass == 1) {
vp9_init_first_pass(cpi);
} else if (cpi->pass == 2) {
@@ -3615,6 +3605,8 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
static void Pass2Encode(VP9_COMP *cpi, unsigned long *size,
unsigned char *dest, unsigned int *frame_flags) {
+ cpi->enable_encode_breakout = 1;
+
if (!cpi->refresh_alt_ref_frame)
vp9_second_pass(cpi);
diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h
index 2dbd7a01a..d83c3f7e0 100644
--- a/vp9/encoder/vp9_onyx_int.h
+++ b/vp9/encoder/vp9_onyx_int.h
@@ -147,18 +147,19 @@ typedef struct {
// const MODE_DEFINITION vp9_mode_order[MAX_MODES] used in the rd code.
typedef enum {
THR_NEARESTMV,
- THR_DC,
-
THR_NEARESTA,
THR_NEARESTG,
- THR_NEWMV,
- THR_COMP_NEARESTLA,
- THR_NEARMV,
- THR_COMP_NEARESTGA,
- THR_NEWG,
+ THR_DC,
+
+ THR_NEWMV,
THR_NEWA,
+ THR_NEWG,
+
+ THR_NEARMV,
THR_NEARA,
+ THR_COMP_NEARESTLA,
+ THR_COMP_NEARESTGA,
THR_TM,
@@ -273,7 +274,7 @@ typedef struct {
int use_one_partition_size_always;
int less_rectangular_check;
int use_square_partition_only;
- int unused_mode_skip_lvl;
+ int mode_skip_start;
int reference_masking;
BLOCK_SIZE always_this_block_size;
int auto_min_max_partition_size;
@@ -384,7 +385,7 @@ typedef struct VP9_COMP {
unsigned int mode_check_freq[MAX_MODES];
unsigned int mode_test_hit_counts[MAX_MODES];
unsigned int mode_chosen_counts[MAX_MODES];
- int64_t unused_mode_skip_mask;
+ int64_t mode_skip_mask;
int ref_frame_mask;
int set_ref_frame_mask;
@@ -494,6 +495,7 @@ typedef struct VP9_COMP {
int last_boost;
int kf_boost;
int kf_zeromotion_pct;
+ int gf_zeromotion_pct;
int64_t target_bandwidth;
struct vpx_codec_pkt_list *output_pkt_list;
@@ -655,6 +657,8 @@ typedef struct VP9_COMP {
int initial_height;
int number_spatial_layers;
+ int enable_encode_breakout; // Default value is 1. From first pass stats,
+ // encode_breakout may be disabled.
#if CONFIG_MULTIPLE_ARF
// ARF tracking variables.
diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c
index 41e43fe50..07850d4f6 100644
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -51,20 +51,25 @@ DECLARE_ALIGNED(16, extern const uint8_t,
#define I4X4_PRED 0x8000
#define SPLITMV 0x10000
+#define LAST_FRAME_MODE_MASK 0xFFDADCD60
+#define GOLDEN_FRAME_MODE_MASK 0xFFB5A3BB0
+#define ALT_REF_MODE_MASK 0xFF8C648D0
+
const MODE_DEFINITION vp9_mode_order[MAX_MODES] = {
{NEARESTMV, LAST_FRAME, NONE},
- {DC_PRED, INTRA_FRAME, NONE},
-
{NEARESTMV, ALTREF_FRAME, NONE},
{NEARESTMV, GOLDEN_FRAME, NONE},
- {NEWMV, LAST_FRAME, NONE},
- {NEARESTMV, LAST_FRAME, ALTREF_FRAME},
- {NEARMV, LAST_FRAME, NONE},
- {NEARESTMV, GOLDEN_FRAME, ALTREF_FRAME},
- {NEWMV, GOLDEN_FRAME, NONE},
+ {DC_PRED, INTRA_FRAME, NONE},
+
+ {NEWMV, LAST_FRAME, NONE},
{NEWMV, ALTREF_FRAME, NONE},
+ {NEWMV, GOLDEN_FRAME, NONE},
+
+ {NEARMV, LAST_FRAME, NONE},
{NEARMV, ALTREF_FRAME, NONE},
+ {NEARESTMV, LAST_FRAME, ALTREF_FRAME},
+ {NEARESTMV, GOLDEN_FRAME, ALTREF_FRAME},
{TM_PRED, INTRA_FRAME, NONE},
@@ -2856,7 +2861,7 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
if (cpi->common.mcomp_filter_type == SWITCHABLE)
*rate2 += get_switchable_rate(x);
- if (!is_comp_pred) {
+ if (!is_comp_pred && cpi->enable_encode_breakout) {
if (cpi->active_map_enabled && x->active_ptr[0] == 0)
x->skip = 1;
else if (x->encode_breakout) {
@@ -2867,18 +2872,23 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
unsigned int thresh_ac;
// The encode_breakout input
unsigned int encode_breakout = x->encode_breakout << 4;
+ int max_thresh = 36000;
+
+ // Use extreme low threshold for static frames to limit skipping.
+ if (cpi->enable_encode_breakout == 2)
+ max_thresh = 128;
// Calculate threshold according to dequant value.
thresh_ac = (xd->plane[0].dequant[1] * xd->plane[0].dequant[1]) / 9;
- // Set a maximum for threshold to avoid big PSNR loss in low bitrate case.
- if (thresh_ac > 36000)
- thresh_ac = 36000;
-
// Use encode_breakout input if it is bigger than internal threshold.
if (thresh_ac < encode_breakout)
thresh_ac = encode_breakout;
+ // Set a maximum for threshold to avoid big PSNR loss in low bitrate case.
+ if (thresh_ac > max_thresh)
+ thresh_ac = max_thresh;
+
var = cpi->fn_ptr[y_size].vf(x->plane[0].src.buf, x->plane[0].src.stride,
xd->plane[0].dst.buf,
xd->plane[0].dst.stride, &sse);
@@ -3187,10 +3197,31 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
ref_frame = vp9_mode_order[mode_index].ref_frame;
second_ref_frame = vp9_mode_order[mode_index].second_ref_frame;
- // Skip modes that have been masked off but always consider first mode.
- if (mode_index && (bsize > cpi->sf.unused_mode_skip_lvl) &&
- (cpi->unused_mode_skip_mask & (1 << mode_index)) )
- continue;
+ // Look at the reference frame of the best mode so far and set the
+ // skip mask to look at a subset of the remaining modes.
+ if (mode_index > cpi->sf.mode_skip_start) {
+ if (mode_index == (cpi->sf.mode_skip_start + 1)) {
+ switch (vp9_mode_order[best_mode_index].ref_frame) {
+ case INTRA_FRAME:
+ cpi->mode_skip_mask = 0;
+ break;
+ case LAST_FRAME:
+ cpi->mode_skip_mask = LAST_FRAME_MODE_MASK;
+ break;
+ case GOLDEN_FRAME:
+ cpi->mode_skip_mask = GOLDEN_FRAME_MODE_MASK;
+ break;
+ case ALTREF_FRAME:
+ cpi->mode_skip_mask = ALT_REF_MODE_MASK;
+ break;
+ case NONE:
+ case MAX_REF_FRAMES:
+ assert(!"Invalid Reference frame");
+ }
+ }
+ if (cpi->mode_skip_mask & (1 << mode_index))
+ continue;
+ }
// Skip if the current reference frame has been masked off
if (cpi->sf.reference_masking && !cpi->set_ref_frame_mask &&
@@ -3859,13 +3890,6 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
}
}
- // If indicated then mark the index of the chosen mode to be inspected at
- // other block sizes.
- if (bsize <= cpi->sf.unused_mode_skip_lvl) {
- cpi->unused_mode_skip_mask = cpi->unused_mode_skip_mask &
- (~((int64_t)1 << best_mode_index));
- }
-
// If we are using reference masking and the set mask flag is set then
// create the reference frame mask.
if (cpi->sf.reference_masking && cpi->set_ref_frame_mask)