Commit 50e9a1eb authored by Debargha Mukherjee's avatar Debargha Mukherjee

Decouple encoder side x0 parameter from dq_type

The x0 parameter can now be chosen on the encoder side
independently of the dq offset.

Change-Id: I4a63bae6ae81d5a7f65c53efe1b1ecd713355b01
parent 8ddc7aed
......@@ -22,111 +22,77 @@
// nominal quantization step. The width is only
// for one side of zero, so the actual width is twice that.
// These are needed only on the encoder side.
static const uint8_t x0_nuq[QUANT_PROFILES][2] = {
static const uint8_t x0_nuq[X0_PROFILES][2] = {
{
// lossless
64, 64, // dc, ac
},
// dq_type = 1
// optimize = 1
{
// Y/intra, dq_type 1, low quality
// Y/intra, optimize 1, low quality
64, 64, // dc, ac
},
{
// Y/intra, dq_type 1, high quality
// Y/intra, optimize 1, high quality
64, 64, // dc, ac
},
{
// UV/intra, dq_type 1, low quality
// UV/intra, optimize 1, low quality
64, 64, // dc, ac
},
{
// UV/intra, dq_type 1, high quality
// UV/intra, optimize 1, high quality
64, 64, // dc, ac
},
{
// Y/inter, dq_type 1, low quality
// Y/inter, optimize 1, low quality
64, 64, // dc, ac
},
{
// Y/inter, dq_type 1, high quality
// Y/inter, optimize 1, high quality
64, 64, // dc, ac
},
{
// UV/inter, dq_type 1, low quality
// UV/inter, optimize 1, low quality
64, 64, // dc, ac
},
{
// UV/inter, dq_type 1, high quality
// UV/inter, optimize 1, high quality
64, 64, // dc, ac
},
// dq_type = 2
{
// Y/intra, dq_type 2, low quality
72, 72, // dc, ac
},
{
// Y/intra, dq_type 2, high quality
72, 72, // dc, ac
},
{
// UV/intra, dq_type 2, low quality
72, 72, // dc, ac
},
{
// UV/intra, dq_type 2, high quality
72, 72, // dc, ac
},
{
// Y/inter, dq_type 2, low quality
72, 72, // dc, ac
},
{
// Y/inter, dq_type 2, high quality
72, 72, // dc, ac
},
{
// UV/inter, dq_type 2, low quality
72, 72, // dc, ac
},
{
// UV/inter, dq_type 2, high quality
72, 72, // dc, ac
},
// dq_type = 3
// optimize = 0
{
// Y/intra, dq_type 3, low quality
// Y/intra, optimize 0, low quality
80, 80, // dc, ac
},
{
// Y/intra, dq_type 3, high quality
// Y/intra, optimize 0, high quality
82, 82, // dc, ac
},
{
// UV/intra, dq_type 3, low quality
// UV/intra, optimize 0, low quality
80, 80, // dc, ac
},
{
// UV/intra, dq_type 3, high quality
// UV/intra, optimize 0, high quality
82, 82, // dc, ac
},
{
// Y/inter, dq_type 3, low quality
// Y/inter, optimize 0, low quality
80, 80, // dc, ac
},
{
// Y/inter, dq_type 3, high quality
// Y/inter, optimize 0, high quality
82, 82, // dc, ac
},
{
// UV/inter, dq_type 3, low quality
// UV/inter, optimize 0, low quality
80, 80, // dc, ac
},
{
// UV/inter, dq_type 3, high quality
// UV/inter, optimize 0, high quality
82, 82, // dc, ac
},
};
......@@ -241,25 +207,20 @@ static const int8_t doff_nuq[QUANT_PROFILES][2] = {
},
};
static INLINE uint8_t get_nuq_zbin(int is_ac_coeff, int q_profile) {
return x0_nuq[q_profile][is_ac_coeff];
// Encoder only
static INLINE uint8_t get_nuq_zbin(int is_ac_coeff, int x0_profile) {
return x0_nuq[x0_profile][is_ac_coeff];
}
static INLINE int8_t quant_to_doff_fixed(int is_ac_coeff, int q_profile) {
return doff_nuq[q_profile][is_ac_coeff];
}
// get zero bin width
static INLINE void get_cuml_bins_nuq(int q, int is_ac_coeff,
tran_low_t *zbin_width, int q_profile) {
const uint8_t zbin = get_nuq_zbin(is_ac_coeff, q_profile);
// Encoder only
void av1_get_cuml_bins_nuq(int q, int is_ac_coeff, tran_low_t *zbin_width,
int x0_profile) {
const uint8_t zbin = get_nuq_zbin(is_ac_coeff, x0_profile);
zbin_width[0] = ROUND_POWER_OF_TWO(zbin * q, 7);
}
void av1_get_cuml_bins_nuq(int q, int is_ac_coeff, tran_low_t *cuml_bins,
int q_profile) {
// Get the quantization boundary for the zero bin
get_cuml_bins_nuq(q, is_ac_coeff, cuml_bins, q_profile);
static INLINE int8_t quant_to_doff_fixed(int is_ac_coeff, int q_profile) {
return doff_nuq[q_profile][is_ac_coeff];
}
void av1_get_dequant_val_nuq(int q, int is_ac_coeff, tran_low_t *dq,
......
......@@ -64,6 +64,9 @@ const qm_val_t *aom_qmatrix(struct AV1Common *cm, int qindex, int comp,
#define QUANT_RANGES 2
#define NUQ_KNOTS 1
// Encoder only
#define X0_PROFILES (2 * 8 + 1)
// dequant_val_type_nuq needs space for the 3 possible shift values
// for different tx sizes
typedef tran_low_t dequant_val_type_nuq[NUQ_KNOTS * 3];
......@@ -107,6 +110,26 @@ static INLINE int get_dq_profile(DqType dqtype, int qindex, int is_inter,
return dq_profile_lookup[dqtype][is_inter][plane_type]
[qindex_to_qrange(qindex)];
}
// Encoder only
static INLINE int get_x0_profile(int optimize, int qindex, int is_inter,
PLANE_TYPE plane_type) {
// intra/inter, Y/UV, ctx, qrange
static const int x0_profile_lookup[2][REF_TYPES][PLANE_TYPES][QUANT_RANGES] =
{
{
{ { 1, 2 }, { 3, 4 } }, // intra: Y, UV
{ { 5, 6 }, { 7, 8 } }, // inter: Y, UV
},
{
{ { 9, 10 }, { 11, 12 } }, // intra: Y, UV
{ { 13, 14 }, { 15, 16 } }, // inter: Y, UV
},
};
if (!qindex) return 0; // lossless
return x0_profile_lookup[!optimize][is_inter][plane_type]
[qindex_to_qrange(qindex)];
}
#endif // CONFIG_NEW_QUANT
#ifdef __cplusplus
......
This diff is collapsed.
......@@ -26,6 +26,7 @@ typedef struct QUANT_PARAM {
TX_SIZE tx_size;
#if CONFIG_NEW_QUANT
int dq;
int x0;
#endif // CONFIG_NEW_QUANT
#if CONFIG_AOM_QM
const qm_val_t *qmatrix;
......
......@@ -52,7 +52,7 @@ typedef struct macroblock_plane {
const int16_t *round_QTX;
const int16_t *dequant_QTX;
#if CONFIG_NEW_QUANT
const cuml_bins_type_nuq *cuml_bins_nuq[QUANT_PROFILES];
const cuml_bins_type_nuq *cuml_bins_nuq[X0_PROFILES];
const dequant_val_type_nuq *dequant_val_nuq_QTX[QUANT_PROFILES];
#endif // CONFIG_NEW_QUANT
} MACROBLOCK_PLANE;
......
......@@ -513,6 +513,7 @@ void av1_xform_quant(const AV1_COMMON *cm, MACROBLOCK *x, int plane, int block,
qparam.tx_size = tx_size;
#if CONFIG_NEW_QUANT
qparam.dq = get_dq_profile(cm->dq_type, x->qindex, is_inter, plane_type);
qparam.x0 = get_x0_profile(x->optimize, x->qindex, is_inter, plane_type);
#endif // CONFIG_NEW_QUANT
#if CONFIG_AOM_QM
qparam.qmatrix = qmatrix;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment