From e4f3b970ad10718fc3276eb3e514dbdf149e37bf Mon Sep 17 00:00:00 2001 From: Guillaume Martres Date: Thu, 14 Nov 2013 19:23:57 +0100 Subject: [PATCH] vpxenc: add --aq-mode flag to control adaptive quantization Change-Id: I2a08c00e8576099abc84b6ef05cb3567426e29cf --- vp9/common/vp9_onyx.h | 7 +++++++ vp9/encoder/vp9_encodeframe.c | 10 +++++----- vp9/encoder/vp9_firstpass.c | 10 +++++----- vp9/encoder/vp9_onyx_if.c | 6 ++---- vp9/encoder/vp9_onyx_int.h | 1 - vp9/vp9_cx_iface.c | 7 +++++++ vpx/vp8cx.h | 3 +++ vpxenc.c | 7 +++++-- 8 files changed, 34 insertions(+), 17 deletions(-) diff --git a/vp9/common/vp9_onyx.h b/vp9/common/vp9_onyx.h index 452dd6b89..cda68a285 100644 --- a/vp9/common/vp9_onyx.h +++ b/vp9/common/vp9_onyx.h @@ -64,6 +64,12 @@ extern "C" FRAMEFLAGS_ALTREF = 4, } FRAMETYPE_FLAGS; + typedef enum { + NO_AQ = 0, + VARIANCE_AQ = 1, + AQ_MODES_COUNT // This should always be the last member of the enum + } AQ_MODES; + typedef struct { int version; // 4 versions of bitstream defined: // 0 - best quality/slowest decode, @@ -128,6 +134,7 @@ extern "C" int best_allowed_q; int cq_level; int lossless; + int aq_mode; // Adaptive Quantization mode // two pass datarate control int two_pass_vbrbias; // two pass datarate control tweaks diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index 3e75f3b28..8e71d6b57 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -409,7 +409,7 @@ static void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx, && (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height > y) xd->mi_8x8[x_idx + y * mis] = mi_addr; - if (cpi->sf.variance_adaptive_quantization) { + if (cpi->oxcf.aq_mode == VARIANCE_AQ) { vp9_mb_init_quantizer(cpi, x); } @@ -558,7 +558,7 @@ static void set_offsets(VP9_COMP *cpi, const TileInfo *const tile, /* segment ID */ if (seg->enabled) { - if (!cpi->sf.variance_adaptive_quantization) { + if (!cpi->oxcf.aq_mode == VARIANCE_AQ) { uint8_t *map = seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map; mbmi->segment_id = vp9_get_segment_id(cm, map, bsize, mi_row, mi_col); @@ -635,7 +635,7 @@ static void pick_sb_modes(VP9_COMP *cpi, const TileInfo *const tile, x->source_variance = get_sby_perpixel_variance(cpi, x, bsize); - if (cpi->sf.variance_adaptive_quantization) { + if (cpi->oxcf.aq_mode == VARIANCE_AQ) { int energy; if (bsize <= BLOCK_16X16) { energy = x->mb_energy; @@ -651,7 +651,7 @@ static void pick_sb_modes(VP9_COMP *cpi, const TileInfo *const tile, if (cpi->oxcf.tuning == VP8_TUNE_SSIM) vp9_activity_masking(cpi, x); - if (cpi->sf.variance_adaptive_quantization) { + if (cpi->oxcf.aq_mode == VARIANCE_AQ) { vp9_clear_system_state(); // __asm emms; x->rdmult = round(x->rdmult * rdmult_ratio); } @@ -670,7 +670,7 @@ static void pick_sb_modes(VP9_COMP *cpi, const TileInfo *const tile, totaldist, bsize, ctx, best_rd); } - if (cpi->sf.variance_adaptive_quantization) { + if (cpi->oxcf.aq_mode == VARIANCE_AQ) { x->rdmult = orig_rdmult; if (*totalrate != INT_MAX) { vp9_clear_system_state(); // __asm emms; diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c index 974c300e6..791bc9ef7 100644 --- a/vp9/encoder/vp9_firstpass.c +++ b/vp9/encoder/vp9_firstpass.c @@ -602,14 +602,14 @@ void vp9_first_pass(VP9_COMP *cpi) { num_8x8_blocks_wide_lookup[xd->mi_8x8[0]->mbmi.sb_type], cm->mi_rows, cm->mi_cols); - if (cpi->sf.variance_adaptive_quantization) { + if (cpi->oxcf.aq_mode == VARIANCE_AQ) { int energy = vp9_block_energy(cpi, x, xd->mi_8x8[0]->mbmi.sb_type); error_weight = vp9_vaq_inv_q_ratio(energy); } // do intra 16x16 prediction this_error = vp9_encode_intra(x, use_dc_pred); - if (cpi->sf.variance_adaptive_quantization) { + if (cpi->oxcf.aq_mode == VARIANCE_AQ) { vp9_clear_system_state(); // __asm emms; this_error *= error_weight; } @@ -647,7 +647,7 @@ void vp9_first_pass(VP9_COMP *cpi) { first_pass_motion_search(cpi, x, &best_ref_mv, &mv.as_mv, lst_yv12, &motion_error, recon_yoffset); - if (cpi->sf.variance_adaptive_quantization) { + if (cpi->oxcf.aq_mode == VARIANCE_AQ) { vp9_clear_system_state(); // __asm emms; motion_error *= error_weight; } @@ -658,7 +658,7 @@ void vp9_first_pass(VP9_COMP *cpi) { tmp_err = INT_MAX; first_pass_motion_search(cpi, x, &zero_ref_mv, &tmp_mv.as_mv, lst_yv12, &tmp_err, recon_yoffset); - if (cpi->sf.variance_adaptive_quantization) { + if (cpi->oxcf.aq_mode == VARIANCE_AQ) { vp9_clear_system_state(); // __asm emms; tmp_err *= error_weight; } @@ -678,7 +678,7 @@ void vp9_first_pass(VP9_COMP *cpi) { first_pass_motion_search(cpi, x, &zero_ref_mv, &tmp_mv.as_mv, gld_yv12, &gf_motion_error, recon_yoffset); - if (cpi->sf.variance_adaptive_quantization) { + if (cpi->oxcf.aq_mode == VARIANCE_AQ) { vp9_clear_system_state(); // __asm emms; gf_motion_error *= error_weight; } diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c index dd4705da0..b7874d515 100644 --- a/vp9/encoder/vp9_onyx_if.c +++ b/vp9/encoder/vp9_onyx_if.c @@ -764,8 +764,6 @@ void vp9_set_speed_features(VP9_COMP *cpi) { sf->static_segmentation = 0; #endif - sf->variance_adaptive_quantization = 0; - switch (mode) { case 0: // This is the best quality mode. break; @@ -3188,7 +3186,7 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, } } - if (cpi->sf.variance_adaptive_quantization) { + if (cpi->oxcf.aq_mode == VARIANCE_AQ) { vp9_vaq_frame_setup(cpi); } @@ -3975,7 +3973,7 @@ int vp9_get_compressed_data(VP9_PTR ptr, unsigned int *frame_flags, vp9_setup_interp_filters(&cpi->mb.e_mbd, DEFAULT_INTERP_FILTER, cm); - if (cpi->sf.variance_adaptive_quantization) { + if (cpi->oxcf.aq_mode == VARIANCE_AQ) { vp9_vaq_init(); } diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h index 9e802123c..c098b5ed8 100644 --- a/vp9/encoder/vp9_onyx_int.h +++ b/vp9/encoder/vp9_onyx_int.h @@ -248,7 +248,6 @@ typedef struct { int auto_mv_step_size; int optimize_coefficients; int static_segmentation; - int variance_adaptive_quantization; int comp_inter_joint_search_thresh; int adaptive_rd_thresh; int skip_encode_sb; diff --git a/vp9/vp9_cx_iface.c b/vp9/vp9_cx_iface.c index 194203967..9a23ebd53 100644 --- a/vp9/vp9_cx_iface.c +++ b/vp9/vp9_cx_iface.c @@ -38,6 +38,7 @@ struct vp9_extracfg { unsigned int rc_max_intra_bitrate_pct; unsigned int lossless; unsigned int frame_parallel_decoding_mode; + unsigned int aq_mode; }; struct extraconfig_map { @@ -66,6 +67,7 @@ static const struct extraconfig_map extracfg_map[] = { 0, /* rc_max_intra_bitrate_pct */ 0, /* lossless */ 0, /* frame_parallel_decoding_mode */ + 0, /* aq_mode */ } } }; @@ -157,6 +159,7 @@ static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx, RANGE_CHECK_HI(cfg, rc_max_quantizer, 0); RANGE_CHECK_HI(cfg, rc_min_quantizer, 0); } + RANGE_CHECK(vp8_cfg, aq_mode, 0, AQ_MODES_COUNT - 1); RANGE_CHECK_HI(cfg, g_threads, 64); RANGE_CHECK_HI(cfg, g_lag_in_frames, MAX_LAG_BUFFERS); @@ -335,6 +338,8 @@ static vpx_codec_err_t set_vp9e_config(VP9_CONFIG *oxcf, oxcf->error_resilient_mode = cfg.g_error_resilient; oxcf->frame_parallel_decoding_mode = vp8_cfg.frame_parallel_decoding_mode; + oxcf->aq_mode = vp8_cfg.aq_mode; + oxcf->ss_number_layers = cfg.ss_number_layers; /* printf("Current VP9 Settings: \n"); @@ -445,6 +450,7 @@ static vpx_codec_err_t set_param(vpx_codec_alg_priv_t *ctx, MAP(VP8E_SET_MAX_INTRA_BITRATE_PCT, xcfg.rc_max_intra_bitrate_pct); MAP(VP9E_SET_LOSSLESS, xcfg.lossless); MAP(VP9E_SET_FRAME_PARALLEL_DECODING, xcfg.frame_parallel_decoding_mode); + MAP(VP9E_SET_AQ_MODE, xcfg.aq_mode); } res = validate_config(ctx, &ctx->cfg, &xcfg); @@ -1071,6 +1077,7 @@ static vpx_codec_ctrl_fn_map_t vp9e_ctf_maps[] = { {VP8E_SET_MAX_INTRA_BITRATE_PCT, set_param}, {VP9E_SET_LOSSLESS, set_param}, {VP9E_SET_FRAME_PARALLEL_DECODING, set_param}, + {VP9E_SET_AQ_MODE, set_param}, {VP9_GET_REFERENCE, get_reference}, {VP9E_SET_SVC, vp9e_set_svc}, {VP9E_SET_SVC_PARAMETERS, vp9e_set_svc_parameters}, diff --git a/vpx/vp8cx.h b/vpx/vp8cx.h index 433cc0d8a..c0424f146 100644 --- a/vpx/vp8cx.h +++ b/vpx/vp8cx.h @@ -193,6 +193,7 @@ enum vp8e_enc_control_id { VP9E_SET_TILE_COLUMNS, VP9E_SET_TILE_ROWS, VP9E_SET_FRAME_PARALLEL_DECODING, + VP9E_SET_AQ_MODE, VP9E_SET_SVC, VP9E_SET_SVC_PARAMETERS @@ -343,6 +344,8 @@ VPX_CTRL_USE_TYPE(VP9E_SET_LOSSLESS, unsigned int) VPX_CTRL_USE_TYPE(VP9E_SET_FRAME_PARALLEL_DECODING, unsigned int) +VPX_CTRL_USE_TYPE(VP9E_SET_AQ_MODE, unsigned int) + /*! @} - end defgroup vp8_encoder */ #ifdef __cplusplus } // extern "C" diff --git a/vpxenc.c b/vpxenc.c index b7897dbf3..674da1490 100644 --- a/vpxenc.c +++ b/vpxenc.c @@ -561,6 +561,9 @@ static const arg_def_t lossless = ARG_DEF(NULL, "lossless", 1, "Lossless mode"); #if CONFIG_VP9_ENCODER static const arg_def_t frame_parallel_decoding = ARG_DEF( NULL, "frame-parallel", 1, "Enable frame parallel decodability features"); +static const arg_def_t aq_mode = ARG_DEF( + NULL, "aq-mode", 1, + "Adaptive quantization mode (0: disabled (by default), 1: variance based)"); #endif #if CONFIG_VP8_ENCODER @@ -585,7 +588,7 @@ static const arg_def_t *vp9_args[] = { &cpu_used, &auto_altref, &noise_sens, &sharpness, &static_thresh, &tile_cols, &tile_rows, &arnr_maxframes, &arnr_strength, &arnr_type, &tune_ssim, &cq_level, &max_intra_rate_pct, &lossless, - &frame_parallel_decoding, + &frame_parallel_decoding, &aq_mode, NULL }; static const int vp9_arg_ctrl_map[] = { @@ -594,7 +597,7 @@ static const int vp9_arg_ctrl_map[] = { VP9E_SET_TILE_COLUMNS, VP9E_SET_TILE_ROWS, VP8E_SET_ARNR_MAXFRAMES, VP8E_SET_ARNR_STRENGTH, VP8E_SET_ARNR_TYPE, VP8E_SET_TUNING, VP8E_SET_CQ_LEVEL, VP8E_SET_MAX_INTRA_BITRATE_PCT, - VP9E_SET_LOSSLESS, VP9E_SET_FRAME_PARALLEL_DECODING, + VP9E_SET_LOSSLESS, VP9E_SET_FRAME_PARALLEL_DECODING, VP9E_SET_AQ_MODE, 0 }; #endif -- 2.40.0