Single out the quantize function not using qmatrix Add a unit test to clarify how it function. BUG=aomedia:3018 Change-Id: If9ff38e90267268ab50ff2421314300876e2c238
diff --git a/av1/encoder/av1_quantize.c b/av1/encoder/av1_quantize.c index 6e9b79e..2b07e4c 100644 --- a/av1/encoder/av1_quantize.c +++ b/av1/encoder/av1_quantize.c
@@ -33,6 +33,40 @@ *eob_ptr = 0; } +int av1_quantize_fp_no_qmatrix(const int16_t quant_ptr[2], + const int16_t dequant_ptr[2], + const int16_t round_ptr[2], int log_scale, + const int16_t *scan, int coeff_count, + const tran_low_t *coeff_ptr, + tran_low_t *qcoeff_ptr, + tran_low_t *dqcoeff_ptr) { + memset(qcoeff_ptr, 0, coeff_count * sizeof(*qcoeff_ptr)); + memset(dqcoeff_ptr, 0, coeff_count * sizeof(*dqcoeff_ptr)); + const int rounding[2] = { ROUND_POWER_OF_TWO(round_ptr[0], log_scale), + ROUND_POWER_OF_TWO(round_ptr[1], log_scale) }; + int eob = 0; + for (int i = 0; i < coeff_count; i++) { + const int rc = scan[i]; + const int32_t thresh = (int32_t)(dequant_ptr[rc != 0]); + const int coeff = coeff_ptr[rc]; + const int coeff_sign = AOMSIGN(coeff); + int64_t abs_coeff = (coeff ^ coeff_sign) - coeff_sign; + int tmp32 = 0; + if ((abs_coeff << (1 + log_scale)) >= thresh) { + abs_coeff = clamp64(abs_coeff + rounding[rc != 0], INT16_MIN, INT16_MAX); + tmp32 = (int)((abs_coeff * quant_ptr[rc != 0]) >> (16 - log_scale)); + if (tmp32) { + qcoeff_ptr[rc] = (tmp32 ^ coeff_sign) - coeff_sign; + const tran_low_t abs_dqcoeff = + (tmp32 * dequant_ptr[rc != 0]) >> log_scale; + dqcoeff_ptr[rc] = (abs_dqcoeff ^ coeff_sign) - coeff_sign; + } + } + if (tmp32) eob = i + 1; + } + return eob; +} + static void quantize_fp_helper_c( const tran_low_t *coeff_ptr, intptr_t n_coeffs, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, @@ -53,26 +87,9 @@ memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr)); if (qm_ptr == NULL && iqm_ptr == NULL) { - for (i = 0; i < n_coeffs; i++) { - const int rc = scan[i]; - const int32_t thresh = (int32_t)(dequant_ptr[rc != 0]); - const int coeff = coeff_ptr[rc]; - const int coeff_sign = AOMSIGN(coeff); - int64_t abs_coeff = (coeff ^ coeff_sign) - coeff_sign; - int tmp32 = 0; - if ((abs_coeff << (1 + log_scale)) >= thresh) { - abs_coeff = - clamp64(abs_coeff + rounding[rc != 0], INT16_MIN, INT16_MAX); - tmp32 = (int)((abs_coeff * quant_ptr[rc != 0]) >> (16 - log_scale)); - if (tmp32) { - qcoeff_ptr[rc] = (tmp32 ^ coeff_sign) - coeff_sign; - const tran_low_t abs_dqcoeff = - (tmp32 * dequant_ptr[rc != 0]) >> log_scale; - dqcoeff_ptr[rc] = (abs_dqcoeff ^ coeff_sign) - coeff_sign; - } - } - if (tmp32) eob = i; - } + *eob_ptr = av1_quantize_fp_no_qmatrix(quant_ptr, dequant_ptr, round_ptr, + log_scale, scan, (int)n_coeffs, + coeff_ptr, qcoeff_ptr, dqcoeff_ptr); } else { // Quantization pass: All coefficients with index >= zero_flag are // skippable. Note: zero_flag can be zero. @@ -100,8 +117,8 @@ if (tmp32) eob = i; } + *eob_ptr = eob + 1; } - *eob_ptr = eob + 1; } #if CONFIG_AV1_HIGHBITDEPTH
diff --git a/av1/encoder/av1_quantize.h b/av1/encoder/av1_quantize.h index ad96197..215feb0 100644 --- a/av1/encoder/av1_quantize.h +++ b/av1/encoder/av1_quantize.h
@@ -118,6 +118,32 @@ void av1_quantize_skip(intptr_t n_coeffs, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr); +/*!\brief Quantize transform coefficients without using qmatrix + * + * quant_ptr, dequant_ptr and round_ptr are size 2 arrays, + * where index 0 corresponds to dc coeff and index 1 corresponds to ac coeffs. + * + * \param[in] quant_ptr 16-bit fixed point representation of inverse + * quantize step size, i.e. 2^16/dequant + * \param[in] dequant_ptr quantize step size + * \param[in] round_ptr rounding + * \param[in] log_scale the relative log scale of the transform + * coefficients + * \param[in] scan scan[i] indicates the position of ith to-be-coded + * coefficient + * \param[in] coeff_count number of coefficients + * \param[out] qcoeff_ptr quantized coefficients + * \param[out] dqcoeff_ptr dequantized coefficients + * + * \return The last non-zero coefficient's scan index plus 1 + */ +int av1_quantize_fp_no_qmatrix(const int16_t quant_ptr[2], + const int16_t dequant_ptr[2], + const int16_t round_ptr[2], int log_scale, + const int16_t *scan, int coeff_count, + const tran_low_t *coeff_ptr, + tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr); + void av1_quantize_fp_facade(const tran_low_t *coeff_ptr, intptr_t n_coeffs, const MACROBLOCK_PLANE *p, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
diff --git a/test/av1_quantize_test.cc b/test/av1_quantize_test.cc index f0882c7..bfb684e 100644 --- a/test/av1_quantize_test.cc +++ b/test/av1_quantize_test.cc
@@ -19,6 +19,7 @@ #include "test/clear_system_state.h" #include "test/register_state_check.h" #include "av1/common/scan.h" +#include "av1/encoder/av1_quantize.h" namespace { @@ -207,6 +208,32 @@ TEST_P(AV1QuantizeTest, BitExactCheck) { RunQuantizeTest(); } TEST_P(AV1QuantizeTest, EobVerify) { RunEobTest(); } +TEST(AV1QuantizeTest, QuantizeFpNoQmatrix) { + // Here we use a uniform quantizer as an example + const int16_t dequant_ptr[2] = { 78, 93 }; // quantize step + const int16_t round_ptr[2] = { 39, 46 }; // round ~= dequant / 2 + + // quant ~= 2^16 / dequant. This is a 16-bit fixed point representation of the + // inverse of quantize step. + const int16_t quant_ptr[2] = { 840, 704 }; + int log_scale = 0; + int coeff_count = 4; + const tran_low_t coeff_ptr[4] = { -449, 624, -14, 24 }; + const tran_low_t ref_qcoeff_ptr[4] = { -6, 7, 0, 0 }; + const tran_low_t ref_dqcoeff_ptr[4] = { -468, 651, 0, 0 }; + const int16_t scan[4] = { 0, 1, 2, 3 }; + tran_low_t qcoeff_ptr[4]; + tran_low_t dqcoeff_ptr[4]; + int eob = av1_quantize_fp_no_qmatrix(quant_ptr, dequant_ptr, round_ptr, + log_scale, scan, coeff_count, coeff_ptr, + qcoeff_ptr, dqcoeff_ptr); + EXPECT_EQ(eob, 2); + for (int i = 0; i < coeff_count; ++i) { + EXPECT_EQ(qcoeff_ptr[i], ref_qcoeff_ptr[i]); + EXPECT_EQ(dqcoeff_ptr[i], ref_dqcoeff_ptr[i]); + } +} + #if HAVE_SSE4_1 const QuantizeFuncParams qfps[4] = { QuantizeFuncParams(&av1_highbd_quantize_fp_sse4_1, &av1_highbd_quantize_fp_c,
diff --git a/test/quantize_func_test.cc b/test/quantize_func_test.cc index 3d79cf8..3523050 100644 --- a/test/quantize_func_test.cc +++ b/test/quantize_func_test.cc
@@ -589,4 +589,5 @@ static_cast<TX_SIZE>(TX_32X32), TYPE_B, AOM_BITS_8))); #endif // HAVE_AVX + } // namespace