diff --git a/vp9/encoder/vp9_block.h b/vp9/encoder/vp9_block.h index 5d6985624ef54ecdfaf135aaa0cb29ca8c60c8ff..168702e90cc06a39f5408c548756d7a12bbe3f89 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 10162096abf18461eff2ba9e1061be202905e96e..a52171c2c910a8c86cadcd97e6c1ef431ff62b42 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 c10b4f3e24eecd88e04d5118ae08ed86f08bfffe..146e23d5afe5bd3a976b8c763402a757ad9caa27 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 0542a344744ce11887c4589aa327235ab8900844..db079278350ddcabf0e3705899b70b6ce3b57446 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 @@ -3746,6 +3765,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 895fa16293d5f81183e53b3c708c55fd10c7a341..5ba8cdc8cbdce04110b43f6822c446c530c52794 100644 --- a/vp9/vp9_cx_iface.c +++ b/vp9/vp9_cx_iface.c @@ -1003,8 +1003,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,