Merge "Adjustments to aq-mode=3."
This commit is contained in:
commit
fc2da4c5ba
@ -30,10 +30,11 @@ struct CYCLIC_REFRESH {
|
||||
// excess of the cycle time, i.e., in the case of all zero motion, block
|
||||
// will be refreshed every (100/percent_refresh + time_for_refresh) frames.
|
||||
int time_for_refresh;
|
||||
// // Target number of (8x8) blocks that are set for delta-q (segment 1).
|
||||
// Target number of (8x8) blocks that are set for delta-q.
|
||||
int target_num_seg_blocks;
|
||||
// Actual number of (8x8) blocks that were applied delta-q (segment 1).
|
||||
int actual_num_seg_blocks;
|
||||
// Actual number of (8x8) blocks that were applied delta-q.
|
||||
int actual_num_seg1_blocks;
|
||||
int actual_num_seg2_blocks;
|
||||
// RD mult. parameters for segment 1.
|
||||
int rdmult;
|
||||
// Cyclic refresh map.
|
||||
@ -48,6 +49,8 @@ struct CYCLIC_REFRESH {
|
||||
// Rate target ratio to set q delta.
|
||||
double rate_ratio_qdelta;
|
||||
double low_content_avg;
|
||||
int qindex_delta_seg1;
|
||||
int qindex_delta_seg2;
|
||||
};
|
||||
|
||||
CYCLIC_REFRESH *vp9_cyclic_refresh_alloc(int mi_rows, int mi_cols) {
|
||||
@ -110,7 +113,7 @@ static int candidate_refresh_aq(const CYCLIC_REFRESH *cr,
|
||||
mv.col > cr->motion_thresh || mv.col < -cr->motion_thresh ||
|
||||
!is_inter_block(mbmi)))
|
||||
return CR_SEGMENT_ID_BASE;
|
||||
else if (bsize >= BLOCK_32X32 &&
|
||||
else if (bsize >= BLOCK_16X16 &&
|
||||
rate < cr->thresh_rate_sb &&
|
||||
is_inter_block(mbmi) &&
|
||||
mbmi->mv[0].as_int == 0)
|
||||
@ -146,15 +149,19 @@ int vp9_cyclic_refresh_estimate_bits_at_q(const VP9_COMP *cpi,
|
||||
int num8x8bl = mbs << 2;
|
||||
// Weight for non-base segments: use actual number of blocks refreshed in
|
||||
// previous/just encoded frame. Note number of blocks here is in 8x8 units.
|
||||
double weight_segment = (double)cr->actual_num_seg_blocks / num8x8bl;
|
||||
// Compute delta-q that was used in the just encoded frame.
|
||||
int deltaq = compute_deltaq(cpi, cm->base_qindex, cr->rate_ratio_qdelta);
|
||||
double weight_segment1 = (double)cr->actual_num_seg1_blocks / num8x8bl;
|
||||
double weight_segment2 = (double)cr->actual_num_seg2_blocks / num8x8bl;
|
||||
// Take segment weighted average for estimated bits.
|
||||
estimated_bits = (int)((1.0 - weight_segment) *
|
||||
estimated_bits = (int)((1.0 - weight_segment1 - weight_segment2) *
|
||||
vp9_estimate_bits_at_q(cm->frame_type, cm->base_qindex, mbs,
|
||||
correction_factor, cm->bit_depth) +
|
||||
weight_segment *
|
||||
vp9_estimate_bits_at_q(cm->frame_type, cm->base_qindex + deltaq, mbs,
|
||||
weight_segment1 *
|
||||
vp9_estimate_bits_at_q(cm->frame_type,
|
||||
cm->base_qindex + cr->qindex_delta_seg1, mbs,
|
||||
correction_factor, cm->bit_depth) +
|
||||
weight_segment2 *
|
||||
vp9_estimate_bits_at_q(cm->frame_type,
|
||||
cm->base_qindex + cr->qindex_delta_seg2, mbs,
|
||||
correction_factor, cm->bit_depth));
|
||||
return estimated_bits;
|
||||
}
|
||||
@ -170,15 +177,11 @@ int vp9_cyclic_refresh_rc_bits_per_mb(const VP9_COMP *cpi, int i,
|
||||
CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
|
||||
int bits_per_mb;
|
||||
int num8x8bl = cm->MBs << 2;
|
||||
// Weight for segment 1 prior to encoding: take the target number for the
|
||||
// frame to be encoded. Number of blocks here is in 8x8 units.
|
||||
// Note that this is called in rc_regulate_q, which is called before the
|
||||
// cyclic_refresh_setup (which sets cr->target_num_seg_blocks). So a mismatch
|
||||
// may occur between the cr->target_num_seg_blocks value here and the
|
||||
// cr->target_num_seg_block set for encoding the frame. For the current use
|
||||
// case of fixed cr->percent_refresh and cr->time_for_refresh = 0, mismatch
|
||||
// does not occur/is very small.
|
||||
double weight_segment = (double)cr->target_num_seg_blocks / num8x8bl;
|
||||
// Weight for segment prior to encoding: take the average of the target
|
||||
// number for the frame to be encoded and the actual from the previous frame.
|
||||
double weight_segment = (double)((cr->target_num_seg_blocks +
|
||||
cr->actual_num_seg1_blocks + cr->actual_num_seg2_blocks) >> 1) /
|
||||
num8x8bl;
|
||||
// Compute delta-q corresponding to qindex i.
|
||||
int deltaq = compute_deltaq(cpi, i, cr->rate_ratio_qdelta);
|
||||
// Take segment weighted average for bits per mb.
|
||||
@ -198,7 +201,8 @@ void vp9_cyclic_refresh_update_segment(VP9_COMP *const cpi,
|
||||
int mi_row, int mi_col,
|
||||
BLOCK_SIZE bsize,
|
||||
int64_t rate,
|
||||
int64_t dist) {
|
||||
int64_t dist,
|
||||
int skip) {
|
||||
const VP9_COMMON *const cm = &cpi->common;
|
||||
CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
|
||||
const int bw = num_8x8_blocks_wide_lookup[bsize];
|
||||
@ -214,8 +218,12 @@ void vp9_cyclic_refresh_update_segment(VP9_COMP *const cpi,
|
||||
|
||||
// If this block is labeled for refresh, check if we should reset the
|
||||
// segment_id.
|
||||
if (cyclic_refresh_segment_id_boosted(mbmi->segment_id))
|
||||
if (cyclic_refresh_segment_id_boosted(mbmi->segment_id)) {
|
||||
mbmi->segment_id = refresh_this_block;
|
||||
// Reset segment_id if will be skipped.
|
||||
if (skip)
|
||||
mbmi->segment_id = CR_SEGMENT_ID_BASE;
|
||||
}
|
||||
|
||||
// Update the cyclic refresh map, to be used for setting segmentation map
|
||||
// for the next frame. If the block will be refreshed this frame, mark it
|
||||
@ -250,12 +258,16 @@ void vp9_cyclic_refresh_postencode(VP9_COMP *const cpi) {
|
||||
CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
|
||||
unsigned char *const seg_map = cpi->segmentation_map;
|
||||
int mi_row, mi_col;
|
||||
cr->actual_num_seg_blocks = 0;
|
||||
cr->actual_num_seg1_blocks = 0;
|
||||
cr->actual_num_seg2_blocks = 0;
|
||||
for (mi_row = 0; mi_row < cm->mi_rows; mi_row++)
|
||||
for (mi_col = 0; mi_col < cm->mi_cols; mi_col++) {
|
||||
if (cyclic_refresh_segment_id_boosted(
|
||||
seg_map[mi_row * cm->mi_cols + mi_col]))
|
||||
cr->actual_num_seg_blocks++;
|
||||
if (cyclic_refresh_segment_id(
|
||||
seg_map[mi_row * cm->mi_cols + mi_col]) == CR_SEGMENT_ID_BOOST1)
|
||||
cr->actual_num_seg1_blocks++;
|
||||
else if (cyclic_refresh_segment_id(
|
||||
seg_map[mi_row * cm->mi_cols + mi_col]) == CR_SEGMENT_ID_BOOST2)
|
||||
cr->actual_num_seg2_blocks++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -413,7 +425,7 @@ void vp9_cyclic_refresh_setup(VP9_COMP *const cpi) {
|
||||
cr->time_for_refresh = 0;
|
||||
// Set rate threshold to some multiple (set to 2 for now) of the target
|
||||
// rate (target is given by sb64_target_rate and scaled by 256).
|
||||
cr->thresh_rate_sb = ((int64_t)(rc->sb64_target_rate) << 8) << 1;
|
||||
cr->thresh_rate_sb = ((int64_t)(rc->sb64_target_rate) << 8) << 2;
|
||||
// Distortion threshold, quadratic in Q, scale factor to be adjusted.
|
||||
// q will not exceed 457, so (q * q) is within 32bit; see:
|
||||
// vp9_convert_qindex_to_q(), vp9_ac_quant(), ac_qlookup*[].
|
||||
@ -442,9 +454,11 @@ void vp9_cyclic_refresh_setup(VP9_COMP *const cpi) {
|
||||
|
||||
// Set the q delta for segment BOOST1.
|
||||
qindex_delta = compute_deltaq(cpi, cm->base_qindex, cr->rate_ratio_qdelta);
|
||||
cr->qindex_delta_seg1 = qindex_delta;
|
||||
|
||||
// Compute rd-mult for segment BOOST1.
|
||||
qindex2 = clamp(cm->base_qindex + cm->y_dc_delta_q + qindex_delta, 0, MAXQ);
|
||||
|
||||
cr->rdmult = vp9_compute_rd_mult(cpi, qindex2);
|
||||
|
||||
vp9_set_segdata(seg, CR_SEGMENT_ID_BOOST1, SEG_LVL_ALT_Q, qindex_delta);
|
||||
@ -453,6 +467,7 @@ void vp9_cyclic_refresh_setup(VP9_COMP *const cpi) {
|
||||
qindex_delta = compute_deltaq(cpi, cm->base_qindex,
|
||||
MIN(CR_MAX_RATE_TARGET_RATIO,
|
||||
CR_BOOST2_FAC * cr->rate_ratio_qdelta));
|
||||
cr->qindex_delta_seg2 = qindex_delta;
|
||||
vp9_set_segdata(seg, CR_SEGMENT_ID_BOOST2, SEG_LVL_ALT_Q, qindex_delta);
|
||||
|
||||
// Update the segmentation and refresh map.
|
||||
|
@ -55,7 +55,7 @@ int vp9_cyclic_refresh_rc_bits_per_mb(const struct VP9_COMP *cpi, int i,
|
||||
void vp9_cyclic_refresh_update_segment(struct VP9_COMP *const cpi,
|
||||
MB_MODE_INFO *const mbmi,
|
||||
int mi_row, int mi_col, BLOCK_SIZE bsize,
|
||||
int64_t rate, int64_t dist);
|
||||
int64_t rate, int64_t dist, int skip);
|
||||
|
||||
// Update the segmentation map, and related quantities: cyclic refresh map,
|
||||
// refresh sb_index, and target number of blocks to be refreshed.
|
||||
@ -83,6 +83,15 @@ static INLINE int cyclic_refresh_segment_id_boosted(int segment_id) {
|
||||
segment_id == CR_SEGMENT_ID_BOOST2;
|
||||
}
|
||||
|
||||
static INLINE int cyclic_refresh_segment_id(int segment_id) {
|
||||
if (segment_id == CR_SEGMENT_ID_BOOST1)
|
||||
return CR_SEGMENT_ID_BOOST1;
|
||||
else if (segment_id == CR_SEGMENT_ID_BOOST2)
|
||||
return CR_SEGMENT_ID_BOOST2;
|
||||
else
|
||||
return CR_SEGMENT_ID_BASE;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
@ -868,7 +868,8 @@ static void update_state(VP9_COMP *cpi, ThreadData *td,
|
||||
// and then update the quantizer.
|
||||
if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
|
||||
vp9_cyclic_refresh_update_segment(cpi, &xd->mi[0].src_mi->mbmi, mi_row,
|
||||
mi_col, bsize, ctx->rate, ctx->dist);
|
||||
mi_col, bsize, ctx->rate, ctx->dist,
|
||||
x->skip);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1557,7 +1558,7 @@ static void update_state_rt(VP9_COMP *cpi, ThreadData *td,
|
||||
} else {
|
||||
// Setting segmentation map for cyclic_refresh.
|
||||
vp9_cyclic_refresh_update_segment(cpi, mbmi, mi_row, mi_col, bsize,
|
||||
ctx->rate, ctx->dist);
|
||||
ctx->rate, ctx->dist, x->skip);
|
||||
}
|
||||
vp9_init_plane_quantizers(cpi, x);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user