diff --git a/vp9/encoder/vp9_aq_cyclicrefresh.c b/vp9/encoder/vp9_aq_cyclicrefresh.c index 514ff7a52..1fc4ecdee 100644 --- a/vp9/encoder/vp9_aq_cyclicrefresh.c +++ b/vp9/encoder/vp9_aq_cyclicrefresh.c @@ -94,19 +94,17 @@ static int candidate_refresh_aq(const CYCLIC_REFRESH *cr, const MB_MODE_INFO *mbmi, BLOCK_SIZE bsize, int use_rd) { if (use_rd) { + MV mv = mbmi->mv[0].as_mv; // If projected rate is below the thresh_rate (well below target, // so undershoot expected), accept it for lower-qp coding. if (cr->projected_rate_sb < cr->thresh_rate_sb) return 1; // Otherwise, reject the block for lower-qp coding if any of the following: - // 1) prediction block size is below min_block_size - // 2) mode is non-zero mv and projected distortion is above thresh_dist - // 3) mode is an intra-mode (we may want to allow some of this under + // 1) mode uses large mv + // 2) mode is an intra-mode (we may want to allow some of this under // another thresh_dist) - else if (bsize < cr->min_block_size || - (mbmi->mv[0].as_int != 0 && - cr->projected_dist_sb > cr->thresh_dist_sb) || - !is_inter_block(mbmi)) + else if (mv.row > 32 || mv.row < -32 || + mv.col > 32 || mv.col < -32 || !is_inter_block(mbmi)) return 0; else return 1; @@ -135,8 +133,7 @@ void vp9_cyclic_refresh_update_segment(VP9_COMP *const cpi, const int xmis = MIN(cm->mi_cols - mi_col, bw); const int ymis = MIN(cm->mi_rows - mi_row, bh); const int block_index = mi_row * cm->mi_cols + mi_col; - const int refresh_this_block = cpi->mb.in_static_area || - candidate_refresh_aq(cr, mbmi, bsize, use_rd); + const int refresh_this_block = candidate_refresh_aq(cr, mbmi, bsize, use_rd); // Default is to not update the refresh map. int new_map_value = cr->map[block_index]; int x = 0; int y = 0; @@ -161,6 +158,7 @@ void vp9_cyclic_refresh_update_segment(VP9_COMP *const cpi, // Leave it marked as block that is not candidate for refresh. new_map_value = 1; } + // Update entries in the cyclic refresh map with new_map_value, and // copy mbmi->segment_id into global segmentation map. for (y = 0; y < ymis; y++) @@ -214,8 +212,8 @@ void vp9_cyclic_refresh_setup(VP9_COMP *const cpi) { if (cpi->sf.use_nonrd_pick_mode) { // May want to be more conservative with thresholds in non-rd mode for now // as rate/distortion are derived from model based on prediction residual. - cr->thresh_rate_sb = (rc->sb64_target_rate * 256) >> 3; - cr->thresh_dist_sb = 4 * (int)(q * q); + cr->thresh_rate_sb = (rc->sb64_target_rate * 256); + cr->thresh_dist_sb = 16 * (int)(q * q); } cr->num_seg_blocks = 0; diff --git a/vp9/encoder/vp9_block.h b/vp9/encoder/vp9_block.h index 5194c4c27..12fb886dc 100644 --- a/vp9/encoder/vp9_block.h +++ b/vp9/encoder/vp9_block.h @@ -98,8 +98,6 @@ struct macroblock { // note that token_costs is the cost when eob node is skipped vp9_coeff_cost token_costs[TX_SIZES]; - int in_static_area; - int optimize; // indicate if it is in the rd search loop or encoding process diff --git a/vp9/encoder/vp9_context_tree.h b/vp9/encoder/vp9_context_tree.h index 47d9580a8..1710783e7 100644 --- a/vp9/encoder/vp9_context_tree.h +++ b/vp9/encoder/vp9_context_tree.h @@ -46,6 +46,11 @@ typedef struct { int64_t tx_rd_diff[TX_MODES]; int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS]; + // TODO(jingning) Use RD_COST struct here instead. This involves a boarder + // scope of refactoring. + int rate; + int64_t dist; + #if CONFIG_VP9_TEMPORAL_DENOISING unsigned int newmv_sse; unsigned int zeromv_sse; diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index b87a28332..fdc8e653f 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -641,6 +641,9 @@ static void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx, // Else for cyclic refresh mode update the segment map, set the segment id // and then update the quantizer. if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) { + + vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh, + ctx->rate, ctx->dist); vp9_cyclic_refresh_update_segment(cpi, &xd->mi[0].src_mi->mbmi, mi_row, mi_col, bsize, 1); } @@ -910,6 +913,9 @@ static void rd_pick_sb_modes(VP9_COMP *cpi, // refactored to provide proper exit/return handle. if (rd_cost->rate == INT_MAX) rd_cost->rdcost = INT64_MAX; + + ctx->rate = rd_cost->rate; + ctx->dist = rd_cost->dist; } static void update_stats(VP9_COMMON *cm, const MACROBLOCK *x) { @@ -1334,6 +1340,8 @@ static void update_state_rt(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx, : cm->last_frame_seg_map; mbmi->segment_id = vp9_get_segment_id(cm, map, bsize, mi_row, mi_col); } else { + vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh, + ctx->rate, ctx->dist); // Setting segmentation map for cyclic_refresh vp9_cyclic_refresh_update_segment(cpi, mbmi, mi_row, mi_col, bsize, 1); } @@ -1725,10 +1733,6 @@ static void rd_use_partition(VP9_COMP *cpi, vp9_select_in_frame_q_segment(cpi, mi_row, mi_col, output_enabled, chosen_rdc.rate); } - - if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) - vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh, - chosen_rdc.rate, chosen_rdc.dist); encode_sb(cpi, tile_info, tp, mi_row, mi_col, output_enabled, bsize, pc_tree); } @@ -2467,10 +2471,6 @@ static void rd_pick_partition(VP9_COMP *cpi, if ((cpi->oxcf.aq_mode == COMPLEXITY_AQ) && cm->seg.update_map) vp9_select_in_frame_q_segment(cpi, mi_row, mi_col, output_enabled, best_rdc.rate); - if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) - vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh, - best_rdc.rate, best_rdc.dist); - encode_sb(cpi, tile_info, tp, mi_row, mi_col, output_enabled, bsize, pc_tree); } @@ -2638,7 +2638,7 @@ static void nonrd_pick_sb_modes(VP9_COMP *cpi, mbmi->sb_type = bsize; if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cm->seg.enabled) - if (mbmi->segment_id && x->in_static_area) + if (mbmi->segment_id) x->rdmult = vp9_cyclic_refresh_get_rdmult(cpi->cyclic_refresh); if (vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) @@ -2651,6 +2651,9 @@ static void nonrd_pick_sb_modes(VP9_COMP *cpi, if (rd_cost->rate == INT_MAX) vp9_rd_cost_reset(rd_cost); + + ctx->rate = rd_cost->rate; + ctx->dist = rd_cost->dist; } static void fill_mode_info_sb(VP9_COMMON *cm, MACROBLOCK *x, @@ -2973,11 +2976,6 @@ static void nonrd_pick_partition(VP9_COMP *cpi, vp9_select_in_frame_q_segment(cpi, mi_row, mi_col, output_enabled, best_rdc.rate); } - - if (oxcf->aq_mode == CYCLIC_REFRESH_AQ) - vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh, - best_rdc.rate, best_rdc.dist); - encode_sb_rt(cpi, tile_info, tp, mi_row, mi_col, output_enabled, bsize, pc_tree); } @@ -3114,12 +3112,8 @@ static void nonrd_select_partition(VP9_COMP *cpi, } } - if (bsize == BLOCK_64X64 && output_enabled) { - if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) - vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh, - rd_cost->rate, rd_cost->dist); + if (bsize == BLOCK_64X64 && output_enabled) encode_sb_rt(cpi, tile_info, tp, mi_row, mi_col, 1, bsize, pc_tree); - } } @@ -3232,13 +3226,9 @@ static void nonrd_use_partition(VP9_COMP *cpi, break; } - if (bsize == BLOCK_64X64 && output_enabled) { - if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) - vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh, - rd_cost->rate, rd_cost->dist); + if (bsize == BLOCK_64X64 && output_enabled) encode_sb_rt(cpi, &tile_data->tile_info, tp, mi_row, mi_col, 1, bsize, pc_tree); - } } static void encode_nonrd_sb_row(VP9_COMP *cpi, @@ -3263,7 +3253,6 @@ static void encode_nonrd_sb_row(VP9_COMP *cpi, const int idx_str = cm->mi_stride * mi_row + mi_col; MODE_INFO *mi = cm->mi + idx_str; BLOCK_SIZE bsize; - x->in_static_area = 0; x->source_variance = UINT_MAX; vp9_zero(x->pred_mv); vp9_rd_cost_init(&dummy_rdc); @@ -3290,10 +3279,8 @@ static void encode_nonrd_sb_row(VP9_COMP *cpi, break; case REFERENCE_PARTITION: set_offsets(cpi, tile_info, mi_row, mi_col, BLOCK_64X64); - x->in_static_area = is_background(cpi, tile_info, mi_row, mi_col); - if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cm->seg.enabled && - xd->mi[0].src_mi->mbmi.segment_id && x->in_static_area) { + xd->mi[0].src_mi->mbmi.segment_id) { auto_partition_range(cpi, tile_info, mi_row, mi_col, &sf->min_partition_size, &sf->max_partition_size);