summaryrefslogtreecommitdiff
path: root/vp9
diff options
context:
space:
mode:
Diffstat (limited to 'vp9')
-rw-r--r--vp9/encoder/vp9_block.h1
-rw-r--r--vp9/encoder/vp9_encodeframe.c3
-rw-r--r--vp9/encoder/vp9_onyx_if.c15
-rw-r--r--vp9/encoder/vp9_onyx_int.h8
-rw-r--r--vp9/encoder/vp9_rdopt.c30
5 files changed, 45 insertions, 12 deletions
diff --git a/vp9/encoder/vp9_block.h b/vp9/encoder/vp9_block.h
index 800e3ba47..3e377cf6f 100644
--- a/vp9/encoder/vp9_block.h
+++ b/vp9/encoder/vp9_block.h
@@ -102,6 +102,7 @@ struct macroblock {
int mv_best_ref_index[MAX_REF_FRAMES];
unsigned int max_mv_context[MAX_REF_FRAMES];
+ unsigned int source_variance;
int nmvjointcost[MV_JOINTS];
int nmvcosts[2][MV_VALS];
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c
index f4490aed9..66eae41da 100644
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -581,6 +581,8 @@ static void pick_sb_modes(VP9_COMP *cpi, int mi_row, int mi_col,
set_offsets(cpi, mi_row, mi_col, bsize);
xd->mode_info_context->mbmi.sb_type = bsize;
+
+ x->source_variance = get_sb_variance(cpi, x, bsize);
if (cpi->oxcf.tuning == VP8_TUNE_SSIM)
vp9_activity_masking(cpi, x);
@@ -1922,6 +1924,7 @@ static void encode_sb_row(VP9_COMP *cpi, int mi_row, TOKENEXTRA **tp,
MODE_INFO *m = cm->mi + idx_str;
MODE_INFO *p = cm->prev_mi + idx_str;
+ cpi->mb.source_variance = UINT_MAX;
if (cpi->sf.use_one_partition_size_always) {
set_offsets(cpi, mi_row, mi_col, BLOCK_SIZE_SB64X64);
set_partitioning(cpi, m, cpi->sf.always_this_block_size);
diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c
index f2fa552f2..db039959f 100644
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -790,7 +790,8 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
sf->unused_mode_skip_lvl = BLOCK_32X32;
sf->mode_search_skip_flags = FLAG_SKIP_INTRA_DIRMISMATCH |
FLAG_SKIP_INTRA_BESTINTER |
- FLAG_SKIP_COMP_BESTINTRA;
+ FLAG_SKIP_COMP_BESTINTRA |
+ FLAG_SKIP_INTRA_LOWVAR;
sf->use_uv_intra_rd_estimate = 1;
sf->use_rd_breakout = 1;
sf->skip_encode_sb = 1;
@@ -818,7 +819,9 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
sf->mode_search_skip_flags = FLAG_SKIP_INTRA_DIRMISMATCH |
FLAG_SKIP_INTRA_BESTINTER |
FLAG_SKIP_COMP_BESTINTRA |
- FLAG_SKIP_COMP_REFMISMATCH;
+ FLAG_SKIP_COMP_REFMISMATCH |
+ FLAG_SKIP_INTRA_LOWVAR |
+ FLAG_EARLY_TERMINATE;
sf->last_chroma_intra_mode = DC_PRED;
sf->use_uv_intra_rd_estimate = 1;
sf->use_rd_breakout = 1;
@@ -839,7 +842,9 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
sf->mode_search_skip_flags = FLAG_SKIP_INTRA_DIRMISMATCH |
FLAG_SKIP_INTRA_BESTINTER |
FLAG_SKIP_COMP_BESTINTRA |
- FLAG_SKIP_COMP_REFMISMATCH;
+ FLAG_SKIP_COMP_REFMISMATCH |
+ FLAG_SKIP_INTRA_LOWVAR |
+ FLAG_EARLY_TERMINATE;
sf->use_rd_breakout = 1;
sf->skip_encode_sb = 1;
sf->disable_splitmv = 1;
@@ -857,7 +862,9 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
sf->mode_search_skip_flags = FLAG_SKIP_INTRA_DIRMISMATCH |
FLAG_SKIP_INTRA_BESTINTER |
FLAG_SKIP_COMP_BESTINTRA |
- FLAG_SKIP_COMP_REFMISMATCH;
+ FLAG_SKIP_COMP_REFMISMATCH |
+ FLAG_SKIP_INTRA_LOWVAR |
+ FLAG_EARLY_TERMINATE;
sf->use_rd_breakout = 1;
sf->optimize_coefficients = 0;
sf->auto_mv_step_size = 1;
diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h
index 4529ff083..c258829c2 100644
--- a/vp9/encoder/vp9_onyx_int.h
+++ b/vp9/encoder/vp9_onyx_int.h
@@ -145,6 +145,8 @@ 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,
@@ -152,8 +154,6 @@ typedef enum {
THR_NEARMV,
THR_COMP_NEARESTGA,
- THR_DC,
-
THR_NEWG,
THR_NEWA,
THR_NEARA,
@@ -224,6 +224,10 @@ typedef enum {
// skips oblique intra modes at angles 27, 63, 117, 153 if the best
// intra so far is not one of the neighboring directions
FLAG_SKIP_INTRA_DIRMISMATCH = 16,
+
+ // skips intra modes other than DC_PRED if the source variance
+ // is small
+ FLAG_SKIP_INTRA_LOWVAR = 32,
} MODE_SEARCH_SKIP_LOGIC;
typedef struct {
diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c
index f9c8f6e14..2d932500e 100644
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -54,6 +54,8 @@ DECLARE_ALIGNED(16, extern const uint8_t,
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},
@@ -61,8 +63,6 @@ const MODE_DEFINITION vp9_mode_order[MAX_MODES] = {
{NEARMV, LAST_FRAME, NONE},
{NEARESTMV, GOLDEN_FRAME, ALTREF_FRAME},
- {DC_PRED, INTRA_FRAME, NONE},
-
{NEWMV, GOLDEN_FRAME, NONE},
{NEWMV, ALTREF_FRAME, NONE},
{NEARMV, ALTREF_FRAME, NONE},
@@ -3518,6 +3518,16 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
tx_cache[i] = tx_cache[ONLY_4X4];
} else if (ref_frame == INTRA_FRAME) {
TX_SIZE uv_tx;
+ // Disable intra modes other than DC_PRED for blocks with low variance
+ // Threshold for intra skipping based on source variance
+ // TODO(debargha): Specialize the threshold for super block sizes
+ static const int skip_intra_var_thresh[BLOCK_SIZE_TYPES] = {
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ };
+ if ((cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_LOWVAR) &&
+ this_mode != DC_PRED &&
+ x->source_variance < skip_intra_var_thresh[mbmi->sb_type])
+ continue;
// Only search the oblique modes if the best so far is
// one of the neighboring directional modes
if ((cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_BESTINTER) &&
@@ -3844,8 +3854,6 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
if (this_rd < best_rd || x->skip) {
if (!mode_excluded) {
// Note index of best mode so far
- const int qstep = xd->plane[0].dequant[1];
-
best_mode_index = mode_index;
if (ref_frame == INTRA_FRAME) {
@@ -3868,9 +3876,19 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
// TODO(debargha): enhance this test with a better distortion prediction
// based on qp, activity mask and history
- if (cpi->sf.mode_search_skip_flags & FLAG_EARLY_TERMINATE)
- if (ref_frame > INTRA_FRAME && distortion2 * 4 < qstep * qstep)
+ if (cpi->sf.mode_search_skip_flags & FLAG_EARLY_TERMINATE) {
+ const int qstep = xd->plane[0].dequant[1];
+ // TODO(debargha): Enhance this by specializing for each mode_index
+ int scale = 4;
+ if (x->source_variance < UINT_MAX) {
+ const int var_adjust = (x->source_variance < 16);
+ scale -= var_adjust;
+ }
+ if (ref_frame > INTRA_FRAME &&
+ distortion2 * scale < qstep * qstep) {
early_term = 1;
+ }
+ }
}
#if 0
// Testing this mode gave rise to an improvement in best error score.