PVQ uses backward updated context in a tile
In the beginning of encoding and bitstream packing, the frame context in common of codec is copied to the frame context in each tile. Initial prob and context is based on flat probability and does not come from table at the moment. The bd-rate change for the test set objective-1-fast on awcy with high delay mode is: PSNR PSNR HVS SSIM CIEDE 2000 PSNR Cb PSNR Cr MS SSIM -0.77 -1.05 -0.74 -0.67 -0.67 -0.77 -0.88 Change-Id: Ic9105ac68aceb7486cb5f6f1c0b19df5853f2cb9
This commit is contained in:
Родитель
b188ea1402
Коммит
c49ef3a15f
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче