Rework cut-off decisions in cyclic refresh aq mode
This commit removes the cyclic aq mode dependency on in_static_area and reworks the corresponding cut-off thresholds. It improves the compression performance of speed -5 by 1.47% in PSNR and 2.07% in SSIM, and the compression performance of speed -6 by 3.10% in PSNR and 5.25% in SSIM. Speed wise, about 1% faster in both settings at high bit-rates. Change-Id: I1ffc775afdc047964448d9dff5751491ba4ff4a9
This commit is contained in:
parent
7e491de1c4
commit
caaf63b2c4
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user