diff options
author | Yaowu Xu <yaowu@google.com> | 2013-11-25 10:52:22 -0800 |
---|---|---|
committer | Gerrit Code Review <gerrit@gerrit.golo.chromium.org> | 2013-11-25 10:52:22 -0800 |
commit | cc1e05ca5f6b1be0ab22e18f18532bc4fc98caba (patch) | |
tree | 5cdd69fc6a6077015ff28a84d4bacdec465d88bf /vp9/encoder/vp9_onyx_if.c | |
parent | f547fb8e076e6ba218b7acb57bf72105e6b3f9af (diff) | |
parent | 644bd87e8e04fe5c70dd47b34f9ac19fe173dab5 (diff) | |
download | libvpx-cc1e05ca5f6b1be0ab22e18f18532bc4fc98caba.tar libvpx-cc1e05ca5f6b1be0ab22e18f18532bc4fc98caba.tar.gz libvpx-cc1e05ca5f6b1be0ab22e18f18532bc4fc98caba.tar.bz2 libvpx-cc1e05ca5f6b1be0ab22e18f18532bc4fc98caba.zip |
Merge "In frame Q adjustment experiment."
Diffstat (limited to 'vp9/encoder/vp9_onyx_if.c')
-rw-r--r-- | vp9/encoder/vp9_onyx_if.c | 89 |
1 files changed, 88 insertions, 1 deletions
diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c index 07f0c2ecd..8b2765104 100644 --- a/vp9/encoder/vp9_onyx_if.c +++ b/vp9/encoder/vp9_onyx_if.c @@ -109,6 +109,9 @@ extern unsigned __int64 Sectionbits[500]; extern void vp9_init_quantizer(VP9_COMP *cpi); +static const double in_frame_q_adj_ratio[MAX_SEGMENTS] = + {1.0, 1.5, 2.0, 1.0, 1.0, 1.0, 1.0, 1.0}; + static INLINE void Scale2Ratio(int mode, int *hr, int *hs) { switch (mode) { case NORMAL: @@ -192,6 +195,8 @@ static void dealloc_compressor_data(VP9_COMP *cpi) { vpx_free(cpi->coding_context.last_frame_seg_map_copy); cpi->coding_context.last_frame_seg_map_copy = 0; + vpx_free(cpi->complexity_map); + cpi->complexity_map = 0; vpx_free(cpi->active_map); cpi->active_map = 0; @@ -243,6 +248,79 @@ int vp9_compute_qdelta(VP9_COMP *cpi, double qstart, double qtarget) { return target_index - start_index; } +// Computes a q delta (in "q index" terms) to get from a starting q value +// to a value that should equate to thegiven rate ratio. + +int vp9_compute_qdelta_by_rate(VP9_COMP *cpi, + double base_q_index, double rate_target_ratio) { + int i; + int base_bits_per_mb; + int target_bits_per_mb; + int target_index = cpi->rc.worst_quality; + + // Make SURE use of floating point in this function is safe. + vp9_clear_system_state(); + + // Look up the current projected bits per block for the base index + base_bits_per_mb = vp9_bits_per_mb(cpi->common.frame_type, + base_q_index, 1.0); + + // Find the target bits per mb based on the base value and given ratio. + target_bits_per_mb = rate_target_ratio * base_bits_per_mb; + + // Convert the q target to an index + for (i = cpi->rc.best_quality; i < cpi->rc.worst_quality; i++) { + target_index = i; + if (vp9_bits_per_mb(cpi->common.frame_type, + i, 1.0) <= target_bits_per_mb ) + break; + } + + return target_index - base_q_index; +} + +// This function sets up a set of segments with delta Q values around +// the baseline frame quantizer. +static void setup_in_frame_q_adj(VP9_COMP *cpi) { + VP9_COMMON *cm = &cpi->common; + struct segmentation *seg = &cm->seg; + // double q_ratio; + int segment; + int qindex_delta; + + // Make SURE use of floating point in this function is safe. + vp9_clear_system_state(); + + if (cm->frame_type == KEY_FRAME || + cpi->refresh_alt_ref_frame || + (cpi->refresh_golden_frame && !cpi->is_src_frame_alt_ref)) { + // Clear down the segment map + vpx_memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols); + + // Clear down the complexity map used for rd + vpx_memset(cpi->complexity_map, 0, cm->mi_rows * cm->mi_cols); + + // Enable segmentation + vp9_enable_segmentation((VP9_PTR)cpi); + vp9_clearall_segfeatures(seg); + + // Select delta coding method + seg->abs_delta = SEGMENT_DELTADATA; + + // Segment 0 "Q" feature is disabled so it defaults to the baseline Q + vp9_disable_segfeature(seg, 0, SEG_LVL_ALT_Q); + + // Use some of the segments for in frame Q adjustment + for (segment = 1; segment < 3; segment++) { + qindex_delta = + vp9_compute_qdelta_by_rate(cpi, cm->base_qindex, + in_frame_q_adj_ratio[segment]); + vp9_enable_segfeature(seg, segment, SEG_LVL_ALT_Q); + vp9_set_segdata(seg, segment, SEG_LVL_ALT_Q, qindex_delta); + } + } +} + static void configure_static_seg_features(VP9_COMP *cpi) { VP9_COMMON *cm = &cpi->common; struct segmentation *seg = &cm->seg; @@ -1446,6 +1524,11 @@ VP9_PTR vp9_create_compressor(VP9_CONFIG *oxcf) { CHECK_MEM_ERROR(cm, cpi->segmentation_map, vpx_calloc(cm->mi_rows * cm->mi_cols, 1)); + // Create a complexity map used for rd adjustment + CHECK_MEM_ERROR(cm, cpi->complexity_map, + vpx_calloc(cm->mi_rows * cm->mi_cols, 1)); + + // And a place holder structure is the coding context // for use if we want to save and restore it CHECK_MEM_ERROR(cm, cpi->coding_context.last_frame_seg_map_copy, @@ -2630,8 +2713,12 @@ static void encode_with_recode_loop(VP9_COMP *cpi, } } + // Variance adaptive and in frame q adjustment experiments are mutually + // exclusive. if (cpi->oxcf.aq_mode == VARIANCE_AQ) { - vp9_vaq_frame_setup(cpi); + vp9_vaq_frame_setup(cpi); + } else if (cpi->oxcf.aq_mode == COMPLEXITY_AQ) { + setup_in_frame_q_adj(cpi); } // transform / motion compensation build reconstruction frame |