summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Converse <aconverse@google.com>2014-03-11 13:39:33 -0700
committerGerrit Code Review <gerrit@gerrit.golo.chromium.org>2014-03-11 13:39:33 -0700
commit75272c97cbc9edc7ada65df9bf17159038bb71ae (patch)
tree83b0c044ae5686111cb99ff99f5109e0b3a23674
parent61ecd7f10583f6b68a25d906c2bf8251ed0fdd35 (diff)
parent29a487c77f81a4c864b8f9dd07325d10f0515a98 (diff)
downloadlibvpx-75272c97cbc9edc7ada65df9bf17159038bb71ae.tar
libvpx-75272c97cbc9edc7ada65df9bf17159038bb71ae.tar.gz
libvpx-75272c97cbc9edc7ada65df9bf17159038bb71ae.tar.bz2
libvpx-75272c97cbc9edc7ada65df9bf17159038bb71ae.zip
Merge "Add a conservative RD based active map in vp9."
-rw-r--r--vp9/encoder/vp9_block.h2
-rw-r--r--vp9/encoder/vp9_encodeframe.c37
-rw-r--r--vp9/encoder/vp9_pickmode.c2
-rw-r--r--vp9/encoder/vp9_rdopt.c39
-rw-r--r--vp9/vp9_cx_iface.c13
5 files changed, 83 insertions, 10 deletions
diff --git a/vp9/encoder/vp9_block.h b/vp9/encoder/vp9_block.h
index 5d6985624..168702e90 100644
--- a/vp9/encoder/vp9_block.h
+++ b/vp9/encoder/vp9_block.h
@@ -154,7 +154,7 @@ struct macroblock {
int encode_breakout;
- unsigned char *active_ptr;
+ int in_active_map;
// note that token_costs is the cost when eob node is skipped
vp9_coeff_cost token_costs[TX_SIZES];
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c
index c7ba70ac1..9cc43f9e3 100644
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -571,6 +571,32 @@ void vp9_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src,
x->e_mbd.plane[i].subsampling_y);
}
+static int is_block_in_mb_map(VP9_COMP *cpi, int mi_row, int mi_col,
+ BLOCK_SIZE bsize) {
+ VP9_COMMON *const cm = &cpi->common;
+ const int mb_rows = cm->mb_rows;
+ const int mb_cols = cm->mb_cols;
+ const int mb_row = mi_row >> 1;
+ const int mb_col = mi_col >> 1;
+ const int mb_width = num_8x8_blocks_wide_lookup[bsize] >> 1;
+ const int mb_height = num_8x8_blocks_high_lookup[bsize] >> 1;
+ int r, c;
+ if (bsize <= BLOCK_16X16) {
+ return cpi->active_map[mb_row * mb_cols + mb_col];
+ }
+ for (r = 0; r < mb_height; ++r) {
+ for (c = 0; c < mb_width; ++c) {
+ int row = mb_row + r;
+ int col = mb_col + c;
+ if (row >= mb_rows || col >= mb_cols)
+ continue;
+ if (cpi->active_map[row * mb_cols + col])
+ return 1;
+ }
+ }
+ return 0;
+}
+
static void set_offsets(VP9_COMP *cpi, const TileInfo *const tile,
int mi_row, int mi_col, BLOCK_SIZE bsize) {
MACROBLOCK *const x = &cpi->mb;
@@ -589,7 +615,12 @@ static void set_offsets(VP9_COMP *cpi, const TileInfo *const tile,
// Activity map pointer
x->mb_activity_ptr = &cpi->mb_activity_map[idx_map];
- x->active_ptr = cpi->active_map + idx_map;
+
+ if (cpi->active_map_enabled && !x->e_mbd.lossless) {
+ x->in_active_map = is_block_in_mb_map(cpi, mi_row, mi_col, bsize);
+ } else {
+ x->in_active_map = 1;
+ }
xd->mi_8x8 = cm->mi_grid_visible + idx_str;
xd->prev_mi_8x8 = cm->prev_mi_grid_visible + idx_str;
@@ -1773,6 +1804,10 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
}
}
}
+ if (!x->in_active_map) {
+ do_split = 0;
+ do_rect = 0;
+ }
restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
}
diff --git a/vp9/encoder/vp9_pickmode.c b/vp9/encoder/vp9_pickmode.c
index c10b4f3e2..146e23d5a 100644
--- a/vp9/encoder/vp9_pickmode.c
+++ b/vp9/encoder/vp9_pickmode.c
@@ -248,7 +248,7 @@ int64_t vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
x->skip_encode = cpi->sf.skip_encode_frame && x->q_index < QIDX_SKIP_THRESH;
x->skip = 0;
- if (cpi->active_map_enabled && x->active_ptr[0] == 0)
+ if (!x->in_active_map)
x->skip = 1;
// initialize mode decisions
diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c
index 7db3e4f73..e957b1553 100644
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -2917,9 +2917,12 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
*rate2 += get_switchable_rate(x);
if (!is_comp_pred) {
- if (cpi->active_map_enabled && x->active_ptr[0] == 0)
+ if (!x->in_active_map) {
+ if (psse)
+ *psse = 0;
+ *distortion = 0;
x->skip = 1;
- else if (cpi->allow_encode_breakout && x->encode_breakout) {
+ } else if (cpi->allow_encode_breakout && x->encode_breakout) {
const BLOCK_SIZE y_size = get_plane_block_size(bsize, &xd->plane[0]);
const BLOCK_SIZE uv_size = get_plane_block_size(bsize, &xd->plane[1]);
unsigned int var, sse;
@@ -3162,7 +3165,7 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
const int bhs = num_8x8_blocks_high_lookup[bsize] / 2;
int best_skip2 = 0;
int mode_skip_mask = 0;
- const int mode_skip_start = cpi->sf.mode_skip_start + 1;
+ int mode_skip_start = cpi->sf.mode_skip_start + 1;
const int *const rd_threshes = cpi->rd_threshes[segment_id][bsize];
const int *const rd_thresh_freq_fact = cpi->rd_thresh_freq_fact[bsize];
const int mode_search_skip_flags = cpi->sf.mode_search_skip_flags;
@@ -3271,6 +3274,19 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
mode_skip_mask |= 0xFF30808;
}
+ if (!x->in_active_map) {
+ int mode_index;
+ assert(cpi->ref_frame_flags & VP9_LAST_FLAG);
+ if (frame_mv[NEARESTMV][LAST_FRAME].as_int == 0)
+ mode_index = THR_NEARESTMV;
+ else if (frame_mv[NEARMV][LAST_FRAME].as_int == 0)
+ mode_index = THR_NEARMV;
+ else
+ mode_index = THR_ZEROMV;
+ mode_skip_mask = ~(1 << mode_index);
+ mode_skip_start = MAX_MODES;
+ }
+
for (mode_index = 0; mode_index < MAX_MODES; ++mode_index) {
int mode_excluded = 0;
int64_t this_rd = INT64_MAX;
@@ -3360,8 +3376,11 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
}
}
} else {
+ // TODO(aconverse): Find out if this is still productive then clean up or
+ // remove
// if we're near/nearest and mv == 0,0, compare to zeromv
- if (!(disable_inter_mode_mask & (1 << INTER_OFFSET(ZEROMV))) &&
+ if (x->in_active_map &&
+ !(disable_inter_mode_mask & (1 << INTER_OFFSET(ZEROMV))) &&
(this_mode == NEARMV || this_mode == NEARESTMV ||
this_mode == ZEROMV) &&
frame_mv[this_mode][ref_frame].as_int == 0 &&
@@ -3400,7 +3419,7 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
}
mbmi->mode = this_mode;
- mbmi->uv_mode = DC_PRED;
+ mbmi->uv_mode = x->in_active_map ? DC_PRED : this_mode;
mbmi->ref_frame[0] = ref_frame;
mbmi->ref_frame[1] = second_ref_frame;
// Evaluate all sub-pel filters irrespective of whether we can use
@@ -3743,6 +3762,16 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
vp9_zero(best_tx_diff);
}
+ if (!x->in_active_map) {
+ assert(mbmi->ref_frame[0] == LAST_FRAME);
+ assert(mbmi->ref_frame[1] == NONE);
+ assert(mbmi->mode == NEARESTMV ||
+ mbmi->mode == NEARMV ||
+ mbmi->mode == ZEROMV);
+ assert(frame_mv[mbmi->mode][LAST_FRAME].as_int == 0);
+ assert(mbmi->mode == mbmi->uv_mode);
+ }
+
set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
store_coding_context(x, ctx, best_mode_index,
&mbmi->ref_mvs[mbmi->ref_frame[0]][0],
diff --git a/vp9/vp9_cx_iface.c b/vp9/vp9_cx_iface.c
index 220fed9bd..a20209f9c 100644
--- a/vp9/vp9_cx_iface.c
+++ b/vp9/vp9_cx_iface.c
@@ -997,8 +997,17 @@ static vpx_codec_err_t vp9e_set_roi_map(vpx_codec_alg_priv_t *ctx,
static vpx_codec_err_t vp9e_set_activemap(vpx_codec_alg_priv_t *ctx,
int ctr_id,
va_list args) {
- // TODO(yaowu): Need to re-implement and test for VP9.
- return VPX_CODEC_INVALID_PARAM;
+ vpx_active_map_t *data = va_arg(args, vpx_active_map_t *);
+
+ if (data) {
+ vpx_active_map_t *map = (vpx_active_map_t *)data;
+ if (!vp9_set_active_map(ctx->cpi, map->active_map, map->rows, map->cols))
+ return VPX_CODEC_OK;
+ else
+ return VPX_CODEC_INVALID_PARAM;
+ } else {
+ return VPX_CODEC_INVALID_PARAM;
+ }
}
static vpx_codec_err_t vp9e_set_scalemode(vpx_codec_alg_priv_t *ctx,