From 1663eff7f8e8e820c6037157fcc9917d8ece9c28 Mon Sep 17 00:00:00 2001 From: Paul Wilkins Date: Thu, 20 Nov 2014 17:28:21 -0800 Subject: Switch AQ1 segment basis from q ratio to rate ratio. In defining the Q deltas for segments in AQ1 use a rate ratio rather than a q ratio. Change-Id: Id31a74fcf2b7e55437e42a51c21b3cbcb57028d4 --- vp9/encoder/vp9_aq_variance.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/vp9/encoder/vp9_aq_variance.c b/vp9/encoder/vp9_aq_variance.c index 5a9f8a661..8a4fe8862 100644 --- a/vp9/encoder/vp9_aq_variance.c +++ b/vp9/encoder/vp9_aq_variance.c @@ -25,10 +25,9 @@ #define ENERGY_IN_BOUNDS(energy)\ assert((energy) >= ENERGY_MIN && (energy) <= ENERGY_MAX) -static double q_ratio[MAX_SEGMENTS] = - {1.0, 0.875, 1.143, 1.0, 1.0, 1.0, 1.0, 1.0}; - -static int segment_id[ENERGY_SPAN] = {1, 0, 2}; +static double rate_ratio[MAX_SEGMENTS] = + {1.143, 1.0, 0.875, 1.0, 1.0, 1.0, 1.0, 1.0}; +static int segment_id[ENERGY_SPAN] = {0, 1, 2}; #define SEGMENT_ID(i) segment_id[(i) - ENERGY_MIN] @@ -45,7 +44,6 @@ unsigned int vp9_vaq_segment_id(int energy) { void vp9_vaq_frame_setup(VP9_COMP *cpi) { VP9_COMMON *cm = &cpi->common; struct segmentation *seg = &cm->seg; - const double base_q = vp9_convert_qindex_to_q(cm->base_qindex, cm->bit_depth); int i; if (cm->frame_type == KEY_FRAME || @@ -59,15 +57,23 @@ void vp9_vaq_frame_setup(VP9_COMP *cpi) { vp9_clear_system_state(); for (i = 0; i < MAX_SEGMENTS; i++) { - int qindex_delta; + int qindex_delta = + vp9_compute_qdelta_by_rate(&cpi->rc, cm->frame_type, cm->base_qindex, + rate_ratio[i], cm->bit_depth); + + // We don't allow Q0 in a segment if the base Q is not 0. + // Q0 (lossless) implies 4x4 only and in AQ mode a segment + // Q delta is sometimes applied without going back around the rd loop. + // This could lead to an illegal combination of partition size and q. + if ((cm->base_qindex != 0) && ((cm->base_qindex + qindex_delta) == 0)) { + qindex_delta = -cm->base_qindex + 1; + } // No need to enable SEG_LVL_ALT_Q for this segment - if (q_ratio[i] == 1.0) { + if (rate_ratio[i] == 1.0) { continue; } - qindex_delta = vp9_compute_qdelta(&cpi->rc, base_q, base_q * q_ratio[i], - cm->bit_depth); vp9_set_segdata(seg, i, SEG_LVL_ALT_Q, qindex_delta); vp9_enable_segfeature(seg, i, SEG_LVL_ALT_Q); } -- cgit v1.2.3 From f5209d7e018eee95e75ee03d519a8ba65987f264 Mon Sep 17 00:00:00 2001 From: Paul Wilkins Date: Thu, 20 Nov 2014 18:32:44 -0800 Subject: Remove rate component adjustment for AQ1 In AQ1 a rate adjustment was applied for blocks coded with a deltaq. This tends to skew the partition selection and cause rate overshoot. For example, consider a 64x64 super block where some but not all sub blocks are in a low q segment and some are in a high q segment. The choice of Q when considering large partition and transform sizes is defined by the lowest sub block segment id (currently this implies the lowest Q). If some parts of the larger partition are very hard this will cause a high rate component. The correct behavior here is for the rd code to discard the large partition choice and break down to sub blocks where some have low and some have high Q. However the rate correction factor above mask the high cost of coding at a larger partition size. Change-Id: Ie077edd0b1b43c094898f481df772ea280b35960 --- vp9/encoder/vp9_encodeframe.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index 7ab240b01..49272590d 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -807,10 +807,8 @@ static void rd_pick_sb_modes(VP9_COMP *cpi, struct macroblockd_plane *const pd = xd->plane; const AQ_MODE aq_mode = cpi->oxcf.aq_mode; int i, orig_rdmult; - double rdmult_ratio; vp9_clear_system_state(); - rdmult_ratio = 1.0; // avoid uninitialized warnings // Use the lower precision, but faster, 32x32 fdct for mode selection. x->use_lp32x32fdct = 1; @@ -866,8 +864,6 @@ static void rd_pick_sb_modes(VP9_COMP *cpi, segment_qindex = vp9_get_qindex(&cm->seg, mbmi->segment_id, cm->base_qindex); x->rdmult = vp9_compute_rd_mult(cpi, segment_qindex + cm->y_dc_delta_q); - vp9_clear_system_state(); - rdmult_ratio = (double)x->rdmult / orig_rdmult; } else if (aq_mode == COMPLEXITY_AQ) { const int mi_offset = mi_row * cm->mi_cols + mi_col; unsigned char complexity = cpi->complexity_map[mi_offset]; @@ -901,12 +897,6 @@ static void rd_pick_sb_modes(VP9_COMP *cpi, } } - if (aq_mode == VARIANCE_AQ && rd_cost->rate != INT_MAX) { - vp9_clear_system_state(); - rd_cost->rate = (int)round(rd_cost->rate * rdmult_ratio); - rd_cost->rdcost = RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist); - } - x->rdmult = orig_rdmult; // TODO(jingning) The rate-distortion optimization flow needs to be -- cgit v1.2.3