From 0527894f75079d953ae56f3ec034ac9382d20ae5 Mon Sep 17 00:00:00 2001 From: Thomas Date: Tue, 23 Feb 2016 11:48:02 +0000 Subject: [PATCH] Add encoder option and signaling for quant matrix control. Restore tests speed_test and end_to_end test since quant matrices are not on by default. Change-Id: I0baa649a91e83d62acaca099670671e0406a46ab --- test/cpu_speed_test.cc | 11 ----------- test/end_to_end_test.cc | 4 ---- vp10/common/onyxc_int.h | 1 + vp10/decoder/decodeframe.c | 14 ++++++++++---- vp10/encoder/bitstream.c | 3 +++ vp10/encoder/encoder.c | 4 ++++ vp10/encoder/encoder.h | 1 + vp10/encoder/quantize.c | 3 ++- vp10/vp10_cx_iface.c | 22 ++++++++++++++++++++++ vpx/vp8cx.h | 20 ++++++++++++++++++++ vpxenc.c | 14 +++++++++++++- 11 files changed, 76 insertions(+), 21 deletions(-) diff --git a/test/cpu_speed_test.cc b/test/cpu_speed_test.cc index c20628594..0620f56c8 100644 --- a/test/cpu_speed_test.cc +++ b/test/cpu_speed_test.cc @@ -17,9 +17,6 @@ namespace { const int kMaxPSNR = 100; -#if CONFIG_AOM_QM -const int kMaxPSNR_QM = 35; -#endif class CpuSpeedTest : public ::libvpx_test::EncoderTest, @@ -83,11 +80,7 @@ TEST_P(CpuSpeedTest, TestQ0) { init_flags_ = VPX_CODEC_USE_PSNR; ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -#if CONFIG_AOM_QM - EXPECT_GE(min_psnr_, kMaxPSNR_QM); -#else EXPECT_GE(min_psnr_, kMaxPSNR); -#endif } TEST_P(CpuSpeedTest, TestScreencastQ0) { @@ -102,11 +95,7 @@ TEST_P(CpuSpeedTest, TestScreencastQ0) { init_flags_ = VPX_CODEC_USE_PSNR; ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -#if CONFIG_AOM_QM - EXPECT_GE(min_psnr_, kMaxPSNR_QM); -#else EXPECT_GE(min_psnr_, kMaxPSNR); -#endif } TEST_P(CpuSpeedTest, TestEncodeHighBitrate) { diff --git a/test/end_to_end_test.cc b/test/end_to_end_test.cc index b436e983d..96621dbc2 100644 --- a/test/end_to_end_test.cc +++ b/test/end_to_end_test.cc @@ -132,11 +132,7 @@ class EndToEndTestLarge } double GetPsnrThreshold() { -#if CONFIG_AOM_QM - return kPsnrThreshold[cpu_used_][encoding_mode_] - 3.0; -#else return kPsnrThreshold[cpu_used_][encoding_mode_]; -#endif } TestVideoParam test_video_param_; diff --git a/vp10/common/onyxc_int.h b/vp10/common/onyxc_int.h index 7c126e114..c17de2c60 100644 --- a/vp10/common/onyxc_int.h +++ b/vp10/common/onyxc_int.h @@ -211,6 +211,7 @@ typedef struct VP10Common { qm_val_t *y_qmatrix[MAX_SEGMENTS][2][TX_SIZES]; qm_val_t *uv_qmatrix[MAX_SEGMENTS][2][TX_SIZES]; + int using_qmatrix; #endif /* We allocate a MODE_INFO struct for each macroblock, together with diff --git a/vp10/decoder/decodeframe.c b/vp10/decoder/decodeframe.c index 3f7f098fa..706914ce7 100644 --- a/vp10/decoder/decodeframe.c +++ b/vp10/decoder/decodeframe.c @@ -1116,6 +1116,9 @@ static void setup_quantization(VP10_COMMON *const cm, cm->uv_dc_delta_q = read_delta_q(rb); cm->uv_ac_delta_q = read_delta_q(rb); cm->dequant_bit_depth = cm->bit_depth; +#if CONFIG_AOM_QM + cm->using_qmatrix = vpx_rb_read_bit(rb); +#endif } static void setup_segmentation_dequant(VP10_COMMON *const cm) { @@ -1125,6 +1128,7 @@ static void setup_segmentation_dequant(VP10_COMMON *const cm) { int lossless; int j = 0; int qmindex; + int using_qm = cm->using_qmatrix; #endif if (cm->seg.enabled) { for (i = 0; i < MAX_SEGMENTS; ++i) { @@ -1140,8 +1144,9 @@ static void setup_segmentation_dequant(VP10_COMMON *const cm) { lossless = qindex == 0 && cm->y_dc_delta_q == 0 && cm->uv_dc_delta_q == 0 && cm->uv_ac_delta_q == 0; // NB: depends on base index so there is only 1 set per frame - // No quant weighting when lossless - qmindex = lossless ? QINDEX_RANGE - 1 : cm->base_qindex; + // No quant weighting when lossless or signalled not using QM + qmindex = (lossless || using_qm == 0) ? + QINDEX_RANGE - 1 : cm->base_qindex; for (j = 0; j < TX_SIZES; ++j) { cm->y_iqmatrix[i][1][j] = aom_iqmatrix(cm, qmindex, 0, j, 1); cm->y_iqmatrix[i][0][j] = aom_iqmatrix(cm, qmindex, 0, j, 0); @@ -1164,8 +1169,9 @@ static void setup_segmentation_dequant(VP10_COMMON *const cm) { #if CONFIG_AOM_QM lossless = qindex == 0 && cm->y_dc_delta_q == 0 && cm->uv_dc_delta_q == 0 && cm->uv_ac_delta_q == 0; - // No quant weighting when lossless - qmindex = lossless ? QINDEX_RANGE - 1 : cm->base_qindex; + // No quant weighting when lossless or signalled not using QM + qmindex = (lossless || using_qm == 0) ? + QINDEX_RANGE - 1 : cm->base_qindex; for (j = 0; j < TX_SIZES; ++j) { cm->y_iqmatrix[i][1][j] = aom_iqmatrix(cm, qmindex, 0, j, 1); cm->y_iqmatrix[i][0][j] = aom_iqmatrix(cm, qmindex, 0, j, 0); diff --git a/vp10/encoder/bitstream.c b/vp10/encoder/bitstream.c index 9f7b6b399..d4fd08ca1 100644 --- a/vp10/encoder/bitstream.c +++ b/vp10/encoder/bitstream.c @@ -863,6 +863,9 @@ static void encode_quantization(const VP10_COMMON *const cm, write_delta_q(wb, cm->y_dc_delta_q); write_delta_q(wb, cm->uv_dc_delta_q); write_delta_q(wb, cm->uv_ac_delta_q); +#if CONFIG_AOM_QM + vpx_wb_write_bit(wb, cm->using_qmatrix); +#endif } static void encode_segmentation(VP10_COMMON *cm, MACROBLOCKD *xd, diff --git a/vp10/encoder/encoder.c b/vp10/encoder/encoder.c index b7a18cc76..881ec99d2 100644 --- a/vp10/encoder/encoder.c +++ b/vp10/encoder/encoder.c @@ -3826,6 +3826,10 @@ int vp10_get_compressed_data(VP10_COMP *cpi, unsigned int *frame_flags, for (i = 0; i < MAX_REF_FRAMES; ++i) cpi->scaled_ref_idx[i] = INVALID_IDX; } +#if CONFIG_AOM_QM + cm->using_qmatrix = cpi->oxcf.using_qm; +#endif + if (oxcf->pass == 1) { cpi->td.mb.e_mbd.lossless[0] = is_lossless_requested(oxcf); vp10_first_pass(cpi, source); diff --git a/vp10/encoder/encoder.h b/vp10/encoder/encoder.h index 3547cbae3..697da5116 100644 --- a/vp10/encoder/encoder.h +++ b/vp10/encoder/encoder.h @@ -168,6 +168,7 @@ typedef struct VP10EncoderConfig { int best_allowed_q; int cq_level; AQ_MODE aq_mode; // Adaptive Quantization mode + int using_qm; // Internal frame size scaling. RESIZE_TYPE resize_mode; diff --git a/vp10/encoder/quantize.c b/vp10/encoder/quantize.c index 820dc4a02..ae5c97931 100644 --- a/vp10/encoder/quantize.c +++ b/vp10/encoder/quantize.c @@ -392,7 +392,8 @@ void vp10_init_plane_quantizers(VP10_COMP *cpi, MACROBLOCK *x) { #if CONFIG_AOM_QM const int lossless = xd->lossless[segment_id]; // Quant matrix only depends on the base QP so there is only one set per frame - int qmlevel = lossless ? NUM_QM_LEVELS - 1 : aom_get_qmlevel(cm->base_qindex); + int qmlevel = (lossless || cm->using_qmatrix == 0) ? + NUM_QM_LEVELS - 1 : aom_get_qmlevel(cm->base_qindex); #endif // Y diff --git a/vp10/vp10_cx_iface.c b/vp10/vp10_cx_iface.c index 0e737881e..840c4a7f5 100644 --- a/vp10/vp10_cx_iface.c +++ b/vp10/vp10_cx_iface.c @@ -39,6 +39,9 @@ struct vp10_extracfg { unsigned int rc_max_inter_bitrate_pct; unsigned int gf_cbr_boost_pct; unsigned int lossless; +#if CONFIG_AOM_QM + unsigned int enable_qm; +#endif unsigned int frame_parallel_decoding_mode; AQ_MODE aq_mode; unsigned int frame_periodic_boost; @@ -68,6 +71,9 @@ static struct vp10_extracfg default_extra_cfg = { 0, // rc_max_inter_bitrate_pct 0, // gf_cbr_boost_pct 0, // lossless +#if CONFIG_AOM_QM + 0, // enable_qm +#endif 1, // frame_parallel_decoding_mode NO_AQ, // aq_mode 0, // frame_periodic_delta_q @@ -357,6 +363,10 @@ static vpx_codec_err_t set_encoder_config( oxcf->cq_level = vp10_quantizer_to_qindex(extra_cfg->cq_level); oxcf->fixed_q = -1; +#if CONFIG_AOM_QM + oxcf->using_qm = extra_cfg->enable_qm; +#endif + oxcf->under_shoot_pct = cfg->rc_undershoot_pct; oxcf->over_shoot_pct = cfg->rc_overshoot_pct; @@ -632,6 +642,15 @@ static vpx_codec_err_t ctrl_set_lossless(vpx_codec_alg_priv_t *ctx, return update_extra_cfg(ctx, &extra_cfg); } +#if CONFIG_AOM_QM +static vpx_codec_err_t ctrl_set_enable_qm(vpx_codec_alg_priv_t *ctx, + va_list args) { + struct vp10_extracfg extra_cfg = ctx->extra_cfg; + extra_cfg.enable_qm = CAST(VP9E_SET_ENABLE_QM, args); + return update_extra_cfg(ctx, &extra_cfg); +} +#endif + static vpx_codec_err_t ctrl_set_frame_parallel_decoding_mode( vpx_codec_alg_priv_t *ctx, va_list args) { struct vp10_extracfg extra_cfg = ctx->extra_cfg; @@ -1228,6 +1247,9 @@ static vpx_codec_ctrl_fn_map_t encoder_ctrl_maps[] = { { VP9E_SET_MAX_INTER_BITRATE_PCT, ctrl_set_rc_max_inter_bitrate_pct }, { VP9E_SET_GF_CBR_BOOST_PCT, ctrl_set_rc_gf_cbr_boost_pct }, { VP9E_SET_LOSSLESS, ctrl_set_lossless }, +#if CONFIG_AOM_QM + { VP9E_SET_ENABLE_QM, ctrl_set_enable_qm }, +#endif { VP9E_SET_FRAME_PARALLEL_DECODING, ctrl_set_frame_parallel_decoding_mode }, { VP9E_SET_AQ_MODE, ctrl_set_aq_mode }, { VP9E_SET_FRAME_PERIODIC_BOOST, ctrl_set_frame_periodic_boost }, diff --git a/vpx/vp8cx.h b/vpx/vp8cx.h index 835ea78de..0f033ffb7 100644 --- a/vpx/vp8cx.h +++ b/vpx/vp8cx.h @@ -310,6 +310,21 @@ enum vp8e_enc_control_id { * Supported in codecs: VP9 */ VP9E_SET_LOSSLESS, +#if CONFIG_AOM_QM + /*!\brief Codec control function to encode with quantisation matrices. + * + * AOM can operate with default quantisation matrices dependent on + * quantisation level and block type. + * 0 = do not use quantisation matrices + * 1 = use quantisation matrices + * + * By default, the encoder operates without quantisation matrices. + * + * Supported in codecs: AOM + */ + + VP9E_SET_ENABLE_QM, +#endif /*!\brief Codec control function to set number of tile columns. * @@ -745,6 +760,11 @@ VPX_CTRL_USE_TYPE(VP9E_SET_GF_CBR_BOOST_PCT, unsigned int) VPX_CTRL_USE_TYPE(VP9E_SET_LOSSLESS, unsigned int) #define VPX_CTRL_VP9E_SET_LOSSLESS +#if CONFIG_AOM_QM +VPX_CTRL_USE_TYPE(VP9E_SET_ENABLE_QM, unsigned int) +#define VPX_CTRL_VP9E_SET_ENABLE_QM +#endif + VPX_CTRL_USE_TYPE(VP9E_SET_FRAME_PARALLEL_DECODING, unsigned int) #define VPX_CTRL_VP9E_SET_FRAME_PARALLEL_DECODING diff --git a/vpxenc.c b/vpxenc.c index f9ff31c19..8fbeb3659 100644 --- a/vpxenc.c +++ b/vpxenc.c @@ -365,6 +365,11 @@ static const arg_def_t tile_rows = ARG_DEF(NULL, "tile-rows", 1, "Number of tile rows to use, log2"); static const arg_def_t lossless = ARG_DEF(NULL, "lossless", 1, "Lossless mode (0: false (default), 1: true)"); +#if CONFIG_AOM_QM +static const arg_def_t enable_qm = + ARG_DEF(NULL, "enable_qm", 1, + "Enable quantisation matrices (0: false (default), 1: true)"); +#endif 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( @@ -431,6 +436,9 @@ static const arg_def_t *vp10_args[] = { &tile_cols, &tile_rows, &arnr_maxframes, &arnr_strength, &arnr_type, &tune_ssim, &cq_level, &max_intra_rate_pct, &max_inter_rate_pct, &gf_cbr_boost_pct, &lossless, +#if CONFIG_AOM_QM + &enable_qm, +#endif &frame_parallel_decoding, &aq_mode, &frame_periodic_boost, &noise_sens, &tune_content, &input_color_space, &min_gf_interval, &max_gf_interval, @@ -443,7 +451,11 @@ static const int vp10_arg_ctrl_map[] = { 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_MAX_INTER_BITRATE_PCT, VP9E_SET_GF_CBR_BOOST_PCT, - VP9E_SET_LOSSLESS, VP9E_SET_FRAME_PARALLEL_DECODING, VP9E_SET_AQ_MODE, + VP9E_SET_LOSSLESS, +#if CONFIG_AOM_QM + VP9E_SET_ENABLE_QM, +#endif + VP9E_SET_FRAME_PARALLEL_DECODING, VP9E_SET_AQ_MODE, VP9E_SET_FRAME_PERIODIC_BOOST, VP9E_SET_NOISE_SENSITIVITY, VP9E_SET_TUNE_CONTENT, VP9E_SET_COLOR_SPACE, VP9E_SET_MIN_GF_INTERVAL, VP9E_SET_MAX_GF_INTERVAL,