Commit e1c0929f authored by ltrudeau's avatar ltrudeau Committed by Luc Trudeau

Convert PVQ skip variable to enum

Creates the PVQ_SKIP_TYPE enum to encapsulate the different types of
skipping that can be signaled by PVQ (i.e. skip: AC, DC or both).

There is no impact on the bitstream. However, the decoder will now emit
an internal error if the decoded skip flag is out of range. The
block_skip variable is also renamed to ac_dc_coded as it stores the same
information.

Change-Id: Ib2aadaf99dc1736ea392ae5ed8948c3cdc12da9b
parent 25d9a140
......@@ -97,10 +97,10 @@ typedef struct PVQ_INFO {
int size[PVQ_MAX_PARTITIONS];
int skip_rest;
int skip_dir;
int bs; // log of the block size minus two,
// i.e. equivalent to aom's TX_SIZE
int ac_dc_coded; // block skip info, indicating whether DC/AC is coded.
// bit0: DC coded, bit1 : AC coded (1 means coded)
int bs; // log of the block size minus two,
// i.e. equivalent to aom's TX_SIZE
// Block skip info, indicating whether DC/AC, is coded.
PVQ_SKIP_TYPE ac_dc_coded; // bit0: DC coded, bit1 : AC coded (1 means coded)
tran_low_t dq_dc_residue;
} PVQ_INFO;
......
......@@ -109,6 +109,13 @@ extern const uint16_t LAPLACE_OFFSET[];
# define OD_ADAPT_NO_VALUE (-2147483647-1)
typedef enum {
PVQ_SKIP = 0x0,
DC_CODED = 0x1,
AC_CODED = 0x2,
AC_DC_CODED = 0x3,
} PVQ_SKIP_TYPE;
typedef struct od_pvq_adapt_ctx od_pvq_adapt_ctx;
typedef struct od_pvq_codeword_ctx od_pvq_codeword_ctx;
......
......@@ -341,7 +341,7 @@ static void inverse_transform_block(MACROBLOCKD *xd, int plane,
static int av1_pvq_decode_helper(od_dec_ctx *dec, int16_t *ref_coeff,
int16_t *dqcoeff, int16_t *quant, int pli,
int bs, TX_TYPE tx_type, int xdec,
int ac_dc_coded) {
PVQ_SKIP_TYPE ac_dc_coded) {
unsigned int flags; // used for daala's stream analyzer.
int off;
const int is_keyframe = 0;
......@@ -405,7 +405,24 @@ static int av1_pvq_decode_helper(od_dec_ctx *dec, int16_t *ref_coeff,
return eob;
}
static int av1_pvq_decode_helper2(MACROBLOCKD *const xd,
static PVQ_SKIP_TYPE read_pvq_skip(AV1_COMMON *cm, MACROBLOCKD *const xd,
int plane, TX_SIZE tx_size) {
// decode ac/dc coded flag. bit0: DC coded, bit1 : AC coded
// NOTE : we don't use 5 symbols for luma here in aom codebase,
// since block partition is taken care of by aom.
// So, only AC/DC skip info is coded
const int ac_dc_coded = aom_decode_cdf_adapt(
xd->daala_dec.r,
xd->daala_dec.state.adapt.skip_cdf[2 * tx_size + (plane != 0)], 4,
xd->daala_dec.state.adapt.skip_increment, "skip");
if (ac_dc_coded < 0 || ac_dc_coded > 3) {
aom_internal_error(&cm->error, AOM_CODEC_INVALID_PARAM,
"Invalid PVQ Skip Type");
}
return ac_dc_coded;
}
static int av1_pvq_decode_helper2(AV1_COMMON *cm, MACROBLOCKD *const xd,
MB_MODE_INFO *const mbmi, int plane, int row,
int col, TX_SIZE tx_size, TX_TYPE tx_type) {
struct macroblockd_plane *const pd = &xd->plane[plane];
......@@ -416,21 +433,13 @@ static int av1_pvq_decode_helper2(MACROBLOCKD *const xd,
const int diff_stride = tx_blk_size;
int16_t *pred = pd->pred;
tran_low_t *const dqcoeff = pd->dqcoeff;
int ac_dc_coded; // bit0: DC coded, bit1 : AC coded
uint8_t *dst;
int eob;
const PVQ_SKIP_TYPE ac_dc_coded = read_pvq_skip(cm, xd, plane, tx_size);
eob = 0;
dst = &pd->dst.buf[4 * row * pd->dst.stride + 4 * col];
// decode ac/dc coded flag. bit0: DC coded, bit1 : AC coded
// NOTE : we don't use 5 symbols for luma here in aom codebase,
// since block partition is taken care of by aom.
// So, only AC/DC skip info is coded
ac_dc_coded = aom_decode_cdf_adapt(
xd->daala_dec.r,
xd->daala_dec.state.adapt.skip_cdf[2 * tx_size + (plane != 0)], 4,
xd->daala_dec.state.adapt.skip_increment, "skip");
if (ac_dc_coded) {
int xdec = pd->subsampling_x;
int seg_id = mbmi->segment_id;
......@@ -485,7 +494,6 @@ static void predict_and_reconstruct_intra_block(AV1_COMMON *cm,
uint8_t *dst;
const int block_idx = (row << 1) + col;
#if CONFIG_PVQ
(void)cm;
(void)r;
#endif
dst = &pd->dst.buf[(row * pd->dst.stride + col) << tx_size_wide_log2[0]];
......@@ -514,7 +522,7 @@ static void predict_and_reconstruct_intra_block(AV1_COMMON *cm,
inverse_transform_block(xd, plane, tx_type, tx_size, dst, pd->dst.stride,
max_scan_line, eob);
#else
av1_pvq_decode_helper2(xd, mbmi, plane, row, col, tx_size, tx_type);
av1_pvq_decode_helper2(cm, xd, mbmi, plane, row, col, tx_size, tx_type);
#endif
}
}
......@@ -590,7 +598,6 @@ static int reconstruct_inter_block(AV1_COMMON *cm, MACROBLOCKD *const xd,
TX_TYPE tx_type = get_tx_type(plane_type, xd, block_idx, tx_size);
#if CONFIG_PVQ
int eob;
(void)cm;
(void)r;
(void)segment_id;
#else
......@@ -612,8 +619,8 @@ static int reconstruct_inter_block(AV1_COMMON *cm, MACROBLOCKD *const xd,
inverse_transform_block(xd, plane, tx_type, tx_size, dst, pd->dst.stride,
max_scan_line, eob);
#else
eob = av1_pvq_decode_helper2(xd, &xd->mi[0]->mbmi, plane, row, col, tx_size,
tx_type);
eob = av1_pvq_decode_helper2(cm, xd, &xd->mi[0]->mbmi, plane, row, col,
tx_size, tx_type);
#endif
return eob;
}
......
......@@ -287,7 +287,7 @@ static void pvq_decode_partition(aom_reader *r,
* @param [in] robust stream is robust to error in the reference
* @param [in] is_keyframe whether we're encoding a keyframe
* @param [out] flags bitmask of the per band skip and noref flags
* @param [in] block_skip skip flag for the block (range 0-3)
* @param [in] ac_dc_coded skip flag for the block (range 0-3)
* @param [in] qm QM with magnitude compensation
* @param [in] qm_inv Inverse of QM with magnitude compensation
*/
......@@ -301,7 +301,7 @@ void od_pvq_decode(daala_dec_ctx *dec,
int robust,
int is_keyframe,
unsigned int *flags,
int block_skip,
PVQ_SKIP_TYPE ac_dc_coded,
const int16_t *qm,
const int16_t *qm_inv){
......@@ -337,9 +337,8 @@ void od_pvq_decode(daala_dec_ctx *dec,
model = dec->state.adapt.pvq.pvq_param_model;
nb_bands = OD_BAND_OFFSETS[bs][0];
off = &OD_BAND_OFFSETS[bs][1];
OD_ASSERT(block_skip < 4);
out[0] = block_skip & 1;
if (!(block_skip >> 1)) {
out[0] = ac_dc_coded & DC_CODED;
if (ac_dc_coded < AC_CODED) {
if (is_keyframe) for (i = 1; i < 1 << (2*bs + 4); i++) out[i] = 0;
else for (i = 1; i < 1 << (2*bs + 4); i++) out[i] = ref[i];
}
......
......@@ -28,8 +28,8 @@ int aom_laplace_decode_special_(aom_reader *r, unsigned decay,
int max ACCT_STR_PARAM);
void od_pvq_decode(daala_dec_ctx *dec, od_coeff *ref, od_coeff *out, int q0,
int pli, int bs, const od_val16 *beta, int robust, int is_keyframe,
unsigned int *flags, int block_skip, const int16_t *qm,
const int16_t *qm_inv);
int pli, int bs, const od_val16 *beta, int robust, int is_keyframe,
unsigned int *flags, PVQ_SKIP_TYPE ac_dc_coded, const int16_t *qm,
const int16_t *qm_inv);
#endif
......@@ -2163,7 +2163,7 @@ static void write_tokens_b(AV1_COMP *cpi, const TileInfo *const tile,
adapt->skip_increment);
// AC coeffs coded?
if (pvq->ac_dc_coded & 0x02) {
if (pvq->ac_dc_coded & AC_CODED) {
assert(pvq->bs <= tx_size);
for (i = 0; i < pvq->nb_bands; i++) {
if (i == 0 || (!pvq->skip_rest &&
......@@ -2187,12 +2187,12 @@ static void write_tokens_b(AV1_COMP *cpi, const TileInfo *const tile,
}
}
// Encode residue of DC coeff, if exist.
if (!has_dc_skip || (pvq->ac_dc_coded & 1)) { // DC coded?
if (!has_dc_skip || (pvq->ac_dc_coded & DC_CODED)) {
generic_encode(w, &adapt->model_dc[plane],
abs(pvq->dq_dc_residue) - has_dc_skip, -1,
&adapt->ex_dc[plane][pvq->bs][0], 2);
}
if ((pvq->ac_dc_coded & 1)) { // DC coded?
if ((pvq->ac_dc_coded & DC_CODED)) {
aom_write_bit(w, pvq->dq_dc_residue < 0);
}
block += step_xy;
......
......@@ -611,19 +611,20 @@ void av1_xform_quant(const AV1_COMMON *cm, MACROBLOCK *x, int plane, int block,
// PVQ for inter mode block
if (!x->skip_block) {
int ac_dc_coded = av1_pvq_encode_helper(&x->daala_enc,
coeff, // target original vector
ref_coeff, // reference vector
dqcoeff, // de-quantized vector
eob, // End of Block marker
pd->dequant, // aom's quantizers
plane, // image plane
tx_size, // block size in log_2 - 2
tx_type,
&x->rate, // rate measured
x->pvq_speed,
pvq_info); // PVQ info for a block
skip = ac_dc_coded == 0;
PVQ_SKIP_TYPE ac_dc_coded =
av1_pvq_encode_helper(&x->daala_enc,
coeff, // target original vector
ref_coeff, // reference vector
dqcoeff, // de-quantized vector
eob, // End of Block marker
pd->dequant, // aom's quantizers
plane, // image plane
tx_size, // block size in log_2 - 2
tx_type,
&x->rate, // rate measured
x->pvq_speed,
pvq_info); // PVQ info for a block
skip = ac_dc_coded == PVQ_SKIP;
}
x->pvq_skip[plane] = skip;
......@@ -1122,13 +1123,12 @@ void av1_encode_intra_block_plane(AV1_COMMON *cm, MACROBLOCK *x,
}
#if CONFIG_PVQ
int av1_pvq_encode_helper(daala_enc_ctx *daala_enc, tran_low_t *const coeff,
tran_low_t *ref_coeff, tran_low_t *const dqcoeff,
uint16_t *eob, const int16_t *quant, int plane,
int tx_size, TX_TYPE tx_type, int *rate, int speed,
PVQ_INFO *pvq_info) {
PVQ_SKIP_TYPE av1_pvq_encode_helper(
daala_enc_ctx *daala_enc, tran_low_t *const coeff, tran_low_t *ref_coeff,
tran_low_t *const dqcoeff, uint16_t *eob, const int16_t *quant, int plane,
int tx_size, TX_TYPE tx_type, int *rate, int speed, PVQ_INFO *pvq_info) {
const int tx_blk_size = tx_size_wide[tx_size];
int ac_dc_coded;
PVQ_SKIP_TYPE ac_dc_coded;
int quant_shift = get_tx_scale(tx_size);
int pvq_dc_quant;
int use_activity_masking = daala_enc->use_activity_masking;
......
......@@ -70,11 +70,10 @@ void av1_encode_intra_block_plane(AV1_COMMON *cm, MACROBLOCK *x,
int enable_optimize_b);
#if CONFIG_PVQ
int av1_pvq_encode_helper(daala_enc_ctx *daala_enc, tran_low_t *const coeff,
tran_low_t *ref_coeff, tran_low_t *const dqcoeff,
uint16_t *eob, const int16_t *quant, int plane,
int tx_size, TX_TYPE tx_type, int *rate, int speed,
PVQ_INFO *pvq_info);
PVQ_SKIP_TYPE av1_pvq_encode_helper(
daala_enc_ctx *daala_enc, tran_low_t *const coeff, tran_low_t *ref_coeff,
tran_low_t *const dqcoeff, uint16_t *eob, const int16_t *quant, int plane,
int tx_size, TX_TYPE tx_type, int *rate, int speed, PVQ_INFO *pvq_info);
void av1_store_pvq_enc_info(PVQ_INFO *pvq_info, int *qg, int *theta,
int *max_theta, int *k, od_coeff *y, int nb_bands,
......
......@@ -775,7 +775,7 @@ void od_encode_quantizer_scaling(daala_enc_ctx *enc, int q_scaling,
* bit0: DC is coded, bit1: AC is coded (1 means coded)
*
*/
int od_pvq_encode(daala_enc_ctx *enc,
PVQ_SKIP_TYPE od_pvq_encode(daala_enc_ctx *enc,
od_coeff *ref,
const od_coeff *in,
od_coeff *out,
......@@ -818,7 +818,7 @@ int od_pvq_encode(daala_enc_ctx *enc,
const unsigned char *pvq_qm;
double dc_rate;
int use_masking;
int ac_dc_coded;
PVQ_SKIP_TYPE ac_dc_coded;
#if !OD_SIGNAL_Q_SCALING
OD_UNUSED(q_scaling);
OD_UNUSED(bx);
......@@ -932,7 +932,7 @@ int od_pvq_encode(daala_enc_ctx *enc,
/* Code as if we're not skipping. */
aom_encode_cdf_adapt(&enc->w, 2 + (out[0] != 0), skip_cdf,
4, enc->state.adapt.skip_increment);
ac_dc_coded = 2 + (out[0] != 0);
ac_dc_coded = AC_CODED + (out[0] != 0);
#if OD_SIGNAL_Q_SCALING
if (bs == OD_TXSIZES - 1 && pli == 0) {
od_encode_quantizer_scaling(enc, q_scaling, bx >> (OD_TXSIZES - 1),
......
......@@ -50,9 +50,10 @@ void pvq_encode_partition(aom_writer *w,
int encode_flip,
int flip);
int od_pvq_encode(daala_enc_ctx *enc, od_coeff *ref, const od_coeff *in,
od_coeff *out, int q_dc, int q_ac, int pli, int bs, const od_val16 *beta, int robust,
int is_keyframe, int q_scaling, int bx, int by, const int16_t *qm,
const int16_t *qm_inv, int speed, PVQ_INFO *pvq_info);
PVQ_SKIP_TYPE od_pvq_encode(daala_enc_ctx *enc, od_coeff *ref,
const od_coeff *in, od_coeff *out, int q_dc, int q_ac, int pli, int bs,
const od_val16 *beta, int robust, int is_keyframe, int q_scaling, int bx,
int by, const int16_t *qm, const int16_t *qm_inv, int speed,
PVQ_INFO *pvq_info);
#endif
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