Change PVQ's skip symbols to use dyadic and ec_adapt adaptation
Change-Id: I4f7d37af84220971a839f4f8f42aafa1adeb04e4
diff --git a/av1/common/generic_code.c b/av1/common/generic_code.c
index e21e81c..d0426f0 100644
--- a/av1/common/generic_code.c
+++ b/av1/common/generic_code.c
@@ -27,6 +27,16 @@
}
}
+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;
+
+#if CONFIG_EC_ADAPT
+ cdf[cdf_size - 1] = 0;
+#endif
+}
+
/** Adapts a Q15 cdf after encoding/decoding a symbol. */
void aom_cdf_adapt_q15(int val, uint16_t *cdf, int n, int *count, int rate) {
int i;
diff --git a/av1/common/generic_code.h b/av1/common/generic_code.h
index 310a62a..2ebe543 100644
--- a/av1/common/generic_code.h
+++ b/av1/common/generic_code.h
@@ -49,8 +49,21 @@
#define OD_SINGLE_CDF_INIT_FIRST(cdf, val, first) aom_cdf_init(cdf, \
1, sizeof(cdf)/sizeof(cdf[0]), val, first)
+// WARNING: DO NOT USE this init function,
+// if the size of cdf is different from what is declared by code.
+#define OD_CDFS_INIT_Q15(cdfs) \
+ { int n_cdfs = sizeof(cdfs)/sizeof(cdfs[0]); \
+ int cdf_size = sizeof(cdfs[0])/sizeof(cdfs[0][0]); \
+ int nsyms = cdf_size - CONFIG_EC_ADAPT; \
+ int i_; \
+ for (i_ = 0; i_ < n_cdfs; i_++) \
+ aom_cdf_init_q15_1D(cdfs[i_], nsyms, cdf_size); \
+ }
+
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);
+
void aom_cdf_adapt_q15(int val, uint16_t *cdf, int n, int *count, int rate);
void aom_encode_cdf_adapt_q15(aom_writer *w, int val, uint16_t *cdf, int n,
diff --git a/av1/common/pvq_state.c b/av1/common/pvq_state.c
index a9567da..b6fcfb2 100644
--- a/av1/common/pvq_state.c
+++ b/av1/common/pvq_state.c
@@ -13,12 +13,11 @@
#include "av1/common/odintrin.h"
void od_adapt_ctx_reset(od_adapt_ctx *adapt, int is_keyframe) {
- int i;
int pli;
od_adapt_pvq_ctx_reset(&adapt->pvq, is_keyframe);
- adapt->skip_increment = 128;
- OD_CDFS_INIT(adapt->skip_cdf, adapt->skip_increment >> 2);
+ OD_CDFS_INIT_Q15(adapt->skip_cdf);
for (pli = 0; pli < OD_NPLANES_MAX; pli++) {
+ int i;
generic_model_init(&adapt->model_dc[pli]);
for (i = 0; i < OD_TXSIZES; i++) {
int j;
diff --git a/av1/common/pvq_state.h b/av1/common/pvq_state.h
index dc8c0fa..e52c313 100644
--- a/av1/common/pvq_state.h
+++ b/av1/common/pvq_state.h
@@ -34,8 +34,7 @@
int ex_g[OD_NPLANES_MAX][OD_TXSIZES];
/* Joint skip flag for DC and AC */
- uint16_t skip_cdf[OD_TXSIZES*2][4];
- int skip_increment;
+ uint16_t skip_cdf[OD_TXSIZES*2][CDF_SIZE(4)];
};
struct od_state {
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index 7006ead..3867e2b 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -425,10 +425,10 @@
// 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(
+ 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_increment, "skip");
+ "skip");
if (ac_dc_coded < 0 || ac_dc_coded > 3) {
aom_internal_error(&cm->error, AOM_CODEC_INVALID_PARAM,
"Invalid PVQ Skip Type");
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index d364cba..e926360 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -1057,9 +1057,8 @@
pvq = get_pvq_block(x->pvq_q);
// encode block skip info
- aom_encode_cdf_adapt(w, pvq->ac_dc_coded,
- adapt->skip_cdf[2 * tx_size + (plane != 0)], 4,
- adapt->skip_increment);
+ aom_write_symbol(w, pvq->ac_dc_coded,
+ adapt->skip_cdf[2 * tx_size + (plane != 0)], 4);
// AC coeffs coded?
if (pvq->ac_dc_coded & AC_CODED) {
@@ -1070,7 +1069,7 @@
pvq_encode_partition(
w, pvq->qg[i], pvq->theta[i], pvq->max_theta[i],
pvq->y + pvq->off[i], pvq->size[i], pvq->k[i], model, adapt,
- exg + i, ext + i, nodesync,
+ exg + i, ext + i, nodesync || is_keyframe,
(plane != 0) * OD_TXSIZES * PVQ_MAX_PARTITIONS +
pvq->bs * PVQ_MAX_PARTITIONS + i,
is_keyframe, i == 0 && (i < pvq->nb_bands - 1), pvq->skip_rest,
diff --git a/av1/encoder/pvq_encoder.c b/av1/encoder/pvq_encoder.c
index d437a38..7820214 100644
--- a/av1/encoder/pvq_encoder.c
+++ b/av1/encoder/pvq_encoder.c
@@ -884,8 +884,7 @@
#error "CONFIG_PVQ currently requires CONFIG_DAALA_EC."
#endif
/* 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);
+ aom_write_symbol(&enc->w, 2 + (out[0] != 0), skip_cdf, 4);
ac_dc_coded = AC_CODED + (out[0] != 0);
cfl_encoded = 0;
skip_rest = 1;
@@ -988,8 +987,7 @@
}
/* We decide to skip, roll back everything as it was before. */
od_encode_rollback(enc, &buf);
- aom_encode_cdf_adapt(&enc->w, out[0] != 0, skip_cdf,
- 4, enc->state.adapt.skip_increment);
+ aom_write_symbol(&enc->w, out[0] != 0, skip_cdf, 4);
ac_dc_coded = (out[0] != 0);
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];