diff --git a/av1/common/generic_code.c b/av1/common/generic_code.c index bb5d4a6fd..aae929430 100644 --- a/av1/common/generic_code.c +++ b/av1/common/generic_code.c @@ -30,7 +30,7 @@ void aom_cdf_init(uint16_t *cdf, int ncdfs, int nsyms, int val, int first) { void aom_cdf_init_q15_1D(uint16_t *cdf, int nsyms, int cdf_size) { int i; for (i = 0; i < nsyms; i++) - cdf[i] = (i + 1)*32768/nsyms; + cdf[i] = (i + 1)*CDF_PROB_TOP/nsyms; #if CONFIG_EC_ADAPT cdf[cdf_size - 1] = 0; diff --git a/av1/common/pvq_state.h b/av1/common/pvq_state.h index e52c313b5..84d454e70 100644 --- a/av1/common/pvq_state.h +++ b/av1/common/pvq_state.h @@ -38,7 +38,7 @@ struct od_adapt_ctx { }; struct od_state { - od_adapt_ctx adapt; + od_adapt_ctx *adapt; unsigned char pvq_qm_q4[OD_NPLANES_MAX][OD_QM_SIZE]; /* Quantization matrices and their inverses. */ int16_t qm[OD_QM_BUFFER_SIZE]; diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c index 35de101b3..c72648315 100644 --- a/av1/decoder/decodeframe.c +++ b/av1/decoder/decodeframe.c @@ -396,9 +396,9 @@ static int av1_pvq_decode_helper(MACROBLOCKD *xd, tran_low_t *ref_coeff, if (!has_dc_skip || out_int32[0]) { out_int32[0] = - has_dc_skip + generic_decode(dec->r, &dec->state.adapt.model_dc[pli], - -1, &dec->state.adapt.ex_dc[pli][bs][0], 2, - "dc:mag"); + has_dc_skip + generic_decode(dec->r, &dec->state.adapt->model_dc[pli], + -1, &dec->state.adapt->ex_dc[pli][bs][0], + 2, "dc:mag"); if (out_int32[0]) out_int32[0] *= aom_read_bit(dec->r, "dc:sign") ? -1 : 1; } out_int32[0] = out_int32[0] * pvq_dc_quant + ref_int32[0]; @@ -427,7 +427,7 @@ static PVQ_SKIP_TYPE read_pvq_skip(AV1_COMMON *cm, MACROBLOCKD *const xd, // So, only AC/DC skip info is coded const int ac_dc_coded = aom_read_symbol( xd->daala_dec.r, - xd->daala_dec.state.adapt.skip_cdf[2 * tx_size + (plane != 0)], 4, + xd->daala_dec.state.adapt->skip_cdf[2 * tx_size + (plane != 0)], 4, "skip"); if (ac_dc_coded < 0 || ac_dc_coded > 3) { aom_internal_error(&cm->error, AOM_CODEC_INVALID_PARAM, @@ -3297,7 +3297,6 @@ static void get_tile_buffers( static void daala_dec_init(AV1_COMMON *const cm, daala_dec_ctx *daala_dec, aom_reader *r) { daala_dec->r = r; - od_adapt_ctx_reset(&daala_dec->state.adapt, 0); // TODO(yushin) : activity masking info needs be signaled by a bitstream daala_dec->use_activity_masking = AV1_PVQ_ENABLE_ACTIVITY_MASKING; @@ -3448,14 +3447,18 @@ static const uint8_t *decode_tiles(AV1Decoder *pbi, const uint8_t *data, td->pvq_ref_coeff, #endif td->dqcoeff); -#if CONFIG_PVQ - daala_dec_init(cm, &td->xd.daala_dec, &td->bit_reader); -#endif + #if CONFIG_EC_ADAPT // Initialise the tile context from the frame context td->tctx = *cm->fc; td->xd.tile_ctx = &td->tctx; #endif + +#if CONFIG_PVQ + daala_dec_init(cm, &td->xd.daala_dec, &td->bit_reader); + td->xd.daala_dec.state.adapt = &td->tctx.pvq_context; +#endif + #if CONFIG_PALETTE td->xd.plane[0].color_index_map = td->color_index_map[0]; td->xd.plane[1].color_index_map = td->color_index_map[1]; @@ -3816,6 +3819,7 @@ static const uint8_t *decode_tiles_mt(AV1Decoder *pbi, const uint8_t *data, twd->dqcoeff); #if CONFIG_PVQ daala_dec_init(cm, &twd->xd.daala_dec, &twd->bit_reader); + twd->xd.daala_dec.state.adapt = &twd->tctx.pvq_context; #endif #if CONFIG_EC_ADAPT // Initialise the tile context from the frame context diff --git a/av1/decoder/pvq_decoder.c b/av1/decoder/pvq_decoder.c index d264bf8e4..28b2e683f 100644 --- a/av1/decoder/pvq_decoder.c +++ b/av1/decoder/pvq_decoder.c @@ -337,9 +337,9 @@ void od_pvq_decode(daala_dec_ctx *dec, else pvq_qm = 0; - exg = &dec->state.adapt.pvq.pvq_exg[pli][bs][0]; - ext = dec->state.adapt.pvq.pvq_ext + bs*PVQ_MAX_PARTITIONS; - model = dec->state.adapt.pvq.pvq_param_model; + exg = &dec->state.adapt->pvq.pvq_exg[pli][bs][0]; + ext = dec->state.adapt->pvq.pvq_ext + bs*PVQ_MAX_PARTITIONS; + model = dec->state.adapt->pvq.pvq_param_model; nb_bands = OD_BAND_OFFSETS[bs][0]; off = &OD_BAND_OFFSETS[bs][1]; out[0] = ac_dc_coded & DC_CODED; @@ -361,7 +361,7 @@ void od_pvq_decode(daala_dec_ctx *dec, q = OD_MAXI(1, q0); pvq_decode_partition(dec->r, q, size[i], - model, &dec->state.adapt, exg + i, ext + i, ref + off[i], out + off[i], + model, dec->state.adapt, exg + i, ext + i, ref + off[i], out + off[i], &noref[i], beta[i], nodesync, is_keyframe, pli, (pli != 0)*OD_TXSIZES*PVQ_MAX_PARTITIONS + bs*PVQ_MAX_PARTITIONS + i, &cfl, i == 0 && (i < nb_bands - 1), skip_rest, i, &skip[i], @@ -370,7 +370,7 @@ void od_pvq_decode(daala_dec_ctx *dec, int skip_dir; int j; skip_dir = aom_read_symbol(dec->r, - &dec->state.adapt.pvq.pvq_skip_dir_cdf[(pli != 0) + 2*(bs - 1)][0], 7, + &dec->state.adapt->pvq.pvq_skip_dir_cdf[(pli != 0) + 2*(bs - 1)][0], 7, "pvq:skiprest"); for (j = 0; j < 3; j++) skip_rest[j] = !!(skip_dir & (1 << j)); } diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c index f8026620e..5c5599f70 100644 --- a/av1/encoder/bitstream.c +++ b/av1/encoder/bitstream.c @@ -1037,7 +1037,7 @@ static void pack_pvq_tokens(aom_writer *w, MACROBLOCK *const x, const BLOCK_SIZE plane_bsize = get_plane_block_size(AOMMAX(bsize, BLOCK_8X8), pd); - adapt = &x->daala_enc.state.adapt; + adapt = x->daala_enc.state.adapt; max_blocks_wide = max_block_wide(xd, plane_bsize, plane); max_blocks_high = max_block_high(xd, plane_bsize, plane); @@ -4121,6 +4121,10 @@ static uint32_t write_tiles(AV1_COMP *const cpi, uint8_t *const dst, this_tile->tctx = *cm->fc; cpi->td.mb.e_mbd.tile_ctx = &this_tile->tctx; #endif +#if CONFIG_PVQ + cpi->td.mb.pvq_q = &this_tile->pvq_q; + cpi->td.mb.daala_enc.state.adapt = &this_tile->tctx.pvq_context; +#endif // CONFIG_PVQ #if CONFIG_ANS buf_ans_write_init(buf_ans, dst + total_size); write_modes(cpi, &tile_info, buf_ans, &tok, tok_end); @@ -4129,11 +4133,6 @@ static uint32_t write_tiles(AV1_COMP *const cpi, uint8_t *const dst, tile_size = buf_ans_write_end(buf_ans); #else aom_start_encode(&mode_bc, dst + total_size); -#if CONFIG_PVQ - // NOTE: This will not work with CONFIG_ANS turned on. - od_adapt_ctx_reset(&cpi->td.mb.daala_enc.state.adapt, 0); - cpi->td.mb.pvq_q = &this_tile->pvq_q; -#endif write_modes(cpi, &tile_info, &mode_bc, &tok, tok_end); #if !CONFIG_LV_MAP assert(tok == tok_end); diff --git a/av1/encoder/daala_compat_enc.c b/av1/encoder/daala_compat_enc.c index 1933d5c55..3df424cac 100644 --- a/av1/encoder/daala_compat_enc.c +++ b/av1/encoder/daala_compat_enc.c @@ -17,7 +17,7 @@ void od_encode_checkpoint(const daala_enc_ctx *enc, od_rollback_buffer *rbuf) { #else #error "CONFIG_PVQ currently requires CONFIG_DAALA_EC." #endif - OD_COPY(&rbuf->adapt, &enc->state.adapt, 1); + OD_COPY(&rbuf->adapt, enc->state.adapt, 1); } void od_encode_rollback(daala_enc_ctx *enc, const od_rollback_buffer *rbuf) { @@ -26,5 +26,5 @@ void od_encode_rollback(daala_enc_ctx *enc, const od_rollback_buffer *rbuf) { #else #error "CONFIG_PVQ currently requires CONFIG_DAALA_EC." #endif - OD_COPY(&enc->state.adapt, &rbuf->adapt, 1); + OD_COPY(enc->state.adapt, &rbuf->adapt, 1); } diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c index d101f02d2..fa65bb9a6 100644 --- a/av1/encoder/encodeframe.c +++ b/av1/encoder/encodeframe.c @@ -4866,9 +4866,7 @@ void av1_encode_tile(AV1_COMP *cpi, ThreadData *td, int tile_row, const TileInfo *const tile_info = &this_tile->tile_info; TOKENEXTRA *tok = cpi->tile_tok[tile_row][tile_col]; int mi_row; -#if CONFIG_PVQ - od_adapt_ctx *adapt; -#endif + #if CONFIG_DEPENDENT_HORZTILES #if CONFIG_TILE_GROUPS if ((!cm->dependent_horz_tiles) || (tile_row == 0) || @@ -4957,14 +4955,11 @@ void av1_encode_tile(AV1_COMP *cpi, ThreadData *td, int tile_row, #error "CONFIG_PVQ currently requires CONFIG_DAALA_EC." #endif - adapt = &td->mb.daala_enc.state.adapt; - #if CONFIG_DAALA_EC od_ec_enc_reset(&td->mb.daala_enc.w.ec); #else #error "CONFIG_PVQ currently requires CONFIG_DAALA_EC." #endif - od_adapt_ctx_reset(adapt, 0); #endif // #if CONFIG_PVQ #if CONFIG_EC_ADAPT @@ -4972,6 +4967,10 @@ void av1_encode_tile(AV1_COMP *cpi, ThreadData *td, int tile_row, td->mb.e_mbd.tile_ctx = &this_tile->tctx; #endif // #if CONFIG_EC_ADAPT +#if CONFIG_PVQ + td->mb.daala_enc.state.adapt = &this_tile->tctx.pvq_context; +#endif // CONFIG_PVQ + for (mi_row = tile_info->mi_row_start; mi_row < tile_info->mi_row_end; mi_row += cm->mib_size) { encode_rd_sb_row(cpi, td, this_tile, mi_row, &tok); diff --git a/av1/encoder/encodemb.c b/av1/encoder/encodemb.c index ceeac845b..03ec98149 100644 --- a/av1/encoder/encodemb.c +++ b/av1/encoder/encodemb.c @@ -1257,9 +1257,9 @@ PVQ_SKIP_TYPE av1_pvq_encode_helper(MACROBLOCK *x, tran_low_t *const coeff, // Encode residue of DC coeff, if required. if (!has_dc_skip || out_int32[0]) { - generic_encode(&daala_enc->w, &daala_enc->state.adapt.model_dc[plane], + generic_encode(&daala_enc->w, &daala_enc->state.adapt->model_dc[plane], abs(out_int32[0]) - has_dc_skip, -1, - &daala_enc->state.adapt.ex_dc[plane][tx_size][0], 2); + &daala_enc->state.adapt->ex_dc[plane][tx_size][0], 2); } if (out_int32[0]) { aom_write_bit(&daala_enc->w, out_int32[0] < 0); diff --git a/av1/encoder/firstpass.c b/av1/encoder/firstpass.c index 74c84914b..03b3b491f 100644 --- a/av1/encoder/firstpass.c +++ b/av1/encoder/firstpass.c @@ -503,6 +503,7 @@ void av1_first_pass(AV1_COMP *cpi, const struct lookahead_entry *source) { const int mb_scale = mi_size_wide[BLOCK_16X16]; #if CONFIG_PVQ PVQ_QUEUE pvq_q; + od_adapt_ctx pvq_context; #endif // First pass code requires valid last and new frame buffers. @@ -541,8 +542,6 @@ void av1_first_pass(AV1_COMP *cpi, const struct lookahead_entry *source) { #if CONFIG_PVQ // For pass 1 of 2-pass encoding, init here for PVQ for now. { - od_adapt_ctx *adapt; - pvq_q.buf_len = 5000; CHECK_MEM_ERROR(cm, pvq_q.buf, aom_malloc(pvq_q.buf_len * sizeof(PVQ_INFO))); @@ -567,13 +566,11 @@ void av1_first_pass(AV1_COMP *cpi, const struct lookahead_entry *source) { #error "CONFIG_PVQ currently requires CONFIG_DAALA_EC." #endif - adapt = &x->daala_enc.state.adapt; #if CONFIG_DAALA_EC od_ec_enc_reset(&x->daala_enc.w.ec); #else #error "CONFIG_PVQ currently requires CONFIG_DAALA_EC." #endif - od_adapt_ctx_reset(adapt, 0); } #endif @@ -595,6 +592,10 @@ void av1_first_pass(AV1_COMP *cpi, const struct lookahead_entry *source) { av1_init_scan_order(cm); #endif av1_convolve_init(cm); +#if CONFIG_PVQ + od_adapt_ctx_reset(&pvq_context, 0); + x->daala_enc.state.adapt = &pvq_context; +#endif // CONFIG_PVQ av1_initialize_rd_consts(cpi); // Tiling is ignored in the first pass. diff --git a/av1/encoder/pvq_encoder.c b/av1/encoder/pvq_encoder.c index 48115445c..945ecf833 100644 --- a/av1/encoder/pvq_encoder.c +++ b/av1/encoder/pvq_encoder.c @@ -797,10 +797,10 @@ PVQ_SKIP_TYPE od_pvq_encode(daala_enc_ctx *enc, else pvq_qm = 0; - exg = &enc->state.adapt.pvq.pvq_exg[pli][bs][0]; - ext = enc->state.adapt.pvq.pvq_ext + bs*PVQ_MAX_PARTITIONS; - skip_cdf = enc->state.adapt.skip_cdf[2*bs + (pli != 0)]; - model = enc->state.adapt.pvq.pvq_param_model; + exg = &enc->state.adapt->pvq.pvq_exg[pli][bs][0]; + ext = enc->state.adapt->pvq.pvq_ext + bs*PVQ_MAX_PARTITIONS; + skip_cdf = enc->state.adapt->skip_cdf[2*bs + (pli != 0)]; + model = enc->state.adapt->pvq.pvq_param_model; nb_bands = OD_BAND_OFFSETS[bs][0]; off = &OD_BAND_OFFSETS[bs][1]; @@ -847,7 +847,7 @@ PVQ_SKIP_TYPE od_pvq_encode(daala_enc_ctx *enc, qg[i] = pvq_theta(out + off[i], in + off[i], ref + off[i], size[i], q, y + off[i], &theta[i], &max_theta[i], - &k[i], beta[i], &skip_diff, nodesync, is_keyframe, pli, &enc->state.adapt, + &k[i], beta[i], &skip_diff, nodesync, is_keyframe, pli, enc->state.adapt, qm + off[i], qm_inv + off[i], enc->pvq_norm_lambda, speed); } od_encode_checkpoint(enc, &buf); @@ -871,8 +871,8 @@ PVQ_SKIP_TYPE od_pvq_encode(daala_enc_ctx *enc, #error "CONFIG_PVQ currently requires CONFIG_DAALA_EC." #endif od_encode_checkpoint(enc, &dc_buf); - generic_encode(&enc->w, &enc->state.adapt.model_dc[pli], - n - 1, -1, &enc->state.adapt.ex_dc[pli][bs][0], 2); + generic_encode(&enc->w, &enc->state.adapt->model_dc[pli], + n - 1, -1, &enc->state.adapt->ex_dc[pli][bs][0], 2); #if CONFIG_DAALA_EC tell2 = od_ec_enc_tell_frac(&enc->w.ec) - tell2; #else @@ -926,14 +926,14 @@ PVQ_SKIP_TYPE od_pvq_encode(daala_enc_ctx *enc, encode_flip = pli != 0 && is_keyframe && theta[i] != -1 && !cfl_encoded; if (i == 0 || (!skip_rest && !(skip_dir & (1 << ((i - 1)%3))))) { pvq_encode_partition(&enc->w, qg[i], theta[i], max_theta[i], y + off[i], - size[i], k[i], model, &enc->state.adapt, exg + i, ext + i, + size[i], k[i], model, enc->state.adapt, exg + i, ext + i, nodesync, (pli != 0)*OD_TXSIZES*PVQ_MAX_PARTITIONS + bs*PVQ_MAX_PARTITIONS + i, is_keyframe, i == 0 && (i < nb_bands - 1), skip_rest, encode_flip, flip); } if (i == 0 && !skip_rest && bs > 0) { aom_write_symbol(&enc->w, skip_dir, - &enc->state.adapt.pvq.pvq_skip_dir_cdf[(pli != 0) + 2*(bs - 1)][0], 7); + &enc->state.adapt->pvq.pvq_skip_dir_cdf[(pli != 0) + 2*(bs - 1)][0], 7); } if (encode_flip) cfl_encoded = 1; } @@ -977,8 +977,8 @@ PVQ_SKIP_TYPE od_pvq_encode(daala_enc_ctx *enc, #error "CONFIG_PVQ currently requires CONFIG_DAALA_EC." #endif od_encode_checkpoint(enc, &dc_buf); - generic_encode(&enc->w, &enc->state.adapt.model_dc[pli], - n - 1, -1, &enc->state.adapt.ex_dc[pli][bs][0], 2); + generic_encode(&enc->w, &enc->state.adapt->model_dc[pli], + n - 1, -1, &enc->state.adapt->ex_dc[pli][bs][0], 2); #if CONFIG_DAALA_EC tell2 = od_ec_enc_tell_frac(&enc->w.ec) - tell2; #else