Commit 62fcfab0 authored by Debargha Mukherjee's avatar Debargha Mukherjee

MV entropy coding fixes and clean ups.

Consistently uses cdfs for all mv symbols, and resolves
some inconsistencies.

All the legacy code dealing with probabilities and counts
can now be removed.

BDRATE (lowres 30 frames): -0.04% (a slight improvement).

Change-Id: Ie27c8e3594e60080e4d155a3ea11c320caa1d85d
parent ab9d37a3
......@@ -1649,13 +1649,14 @@ void av1_average_tile_mv_cdfs(FRAME_CONTEXT *fc, FRAME_CONTEXT *ec_ctxs[],
int j;
for (j = 0; j < NMV_CONTEXTS; ++j) {
AVERAGE_TILE_CDFS(nmvc[j].joint_cdf)
AVERAGE_TILE_CDFS(nmvc[j].joints_cdf)
for (k = 0; k < 2; ++k) {
AVERAGE_TILE_CDFS(nmvc[j].comps[k].class_cdf)
AVERAGE_TILE_CDFS(nmvc[j].comps[k].classes_cdf)
AVERAGE_TILE_CDFS(nmvc[j].comps[k].class0_fp_cdf)
AVERAGE_TILE_CDFS(nmvc[j].comps[k].fp_cdf)
#if CONFIG_NEW_MULTISYMBOL
AVERAGE_TILE_CDFS(nmvc[j].comps[k].sign_cdf)
AVERAGE_TILE_CDFS(nmvc[j].comps[k].hp_cdf)
AVERAGE_TILE_CDFS(nmvc[j].comps[k].class0_hp_cdf)
AVERAGE_TILE_CDFS(nmvc[j].comps[k].class0_cdf)
......
......@@ -43,7 +43,7 @@ const aom_tree_index av1_mv_fp_tree[TREE_SIZE(MV_FP_SIZE)] = { -0, 2, -1,
static const nmv_context default_nmv_context = {
{ 32, 64, 96 }, // joints
{ AOM_CDF4(4096, 11264, 19328) }, // joint_cdf
{ AOM_CDF4(4096, 11264, 19328) }, // joints_cdf
{ {
// Vertical component
128, // sign
......@@ -60,14 +60,19 @@ static const nmv_context default_nmv_context = {
160, // class0_hp bit
128, // hp
#if CONFIG_NEW_MULTISYMBOL
{ AOM_CDF2(128 * 128) },
{ AOM_CDF2(160 * 128) },
{ AOM_CDF2(128 * 128) },
{ AOM_CDF2(216 * 128) },
{ { AOM_CDF2(128 * 196) },
{ AOM_CDF2(128 * 198) },
{ AOM_CDF2(128 * 208) },
{ { AOM_CDF2(128 * 136) },
{ AOM_CDF2(128 * 140) },
{ AOM_CDF2(128 * 148) },
{ AOM_CDF2(128 * 160) },
{ AOM_CDF2(128 * 176) },
{ AOM_CDF2(128 * 192) },
{ AOM_CDF2(128 * 224) },
{ AOM_CDF2(128 * 245) },
{ AOM_CDF2(128 * 234) },
{ AOM_CDF2(128 * 234) },
{ AOM_CDF2(128 * 240) } }, // bits_cdf
#endif
},
......@@ -87,14 +92,19 @@ static const nmv_context default_nmv_context = {
160, // class0_hp bit
128, // hp
#if CONFIG_NEW_MULTISYMBOL
{ AOM_CDF2(128 * 128) },
{ AOM_CDF2(160 * 128) },
{ AOM_CDF2(128 * 128) },
{ AOM_CDF2(216 * 128) },
{ { AOM_CDF2(128 * 196) },
{ AOM_CDF2(128 * 198) },
{ AOM_CDF2(128 * 208) },
{ { AOM_CDF2(128 * 136) },
{ AOM_CDF2(128 * 140) },
{ AOM_CDF2(128 * 148) },
{ AOM_CDF2(128 * 160) },
{ AOM_CDF2(128 * 176) },
{ AOM_CDF2(128 * 192) },
{ AOM_CDF2(128 * 224) },
{ AOM_CDF2(128 * 245) },
{ AOM_CDF2(128 * 234) },
{ AOM_CDF2(128 * 234) },
{ AOM_CDF2(128 * 240) } }, // bits_cdf
#endif
} },
......
......@@ -87,7 +87,7 @@ extern const aom_tree_index av1_mv_fp_tree[];
typedef struct {
aom_prob sign;
aom_prob classes[MV_CLASSES - 1];
aom_cdf_prob class_cdf[CDF_SIZE(MV_CLASSES)];
aom_cdf_prob classes_cdf[CDF_SIZE(MV_CLASSES)];
aom_prob class0[CLASS0_SIZE - 1];
aom_prob bits[MV_OFFSET_BITS];
aom_prob class0_fp[CLASS0_SIZE][MV_FP_SIZE - 1];
......@@ -97,16 +97,17 @@ typedef struct {
aom_prob class0_hp;
aom_prob hp;
#if CONFIG_NEW_MULTISYMBOL
aom_cdf_prob sign_cdf[CDF_SIZE(2)];
aom_cdf_prob class0_hp_cdf[CDF_SIZE(2)];
aom_cdf_prob hp_cdf[CDF_SIZE(2)];
aom_cdf_prob class0_cdf[CDF_SIZE(CLASS0_SIZE)];
aom_cdf_prob bits_cdf[MV_BITS_CONTEXTS][CDF_SIZE(2)];
aom_cdf_prob bits_cdf[MV_OFFSET_BITS][CDF_SIZE(2)];
#endif
} nmv_component;
typedef struct {
aom_prob joints[MV_JOINTS - 1];
aom_cdf_prob joint_cdf[CDF_SIZE(MV_JOINTS)];
aom_cdf_prob joints_cdf[CDF_SIZE(MV_JOINTS)];
nmv_component comps[2];
} nmv_context;
......
......@@ -1285,12 +1285,12 @@ static int read_mv_component(aom_reader *r, nmv_component *mvcomp,
int usehp) {
int mag, d, fr, hp;
#if CONFIG_NEW_MULTISYMBOL
const int sign = aom_read_bit(r, ACCT_STR);
const int sign = aom_read_symbol(r, mvcomp->sign_cdf, 2, ACCT_STR);
#else
const int sign = aom_read(r, mvcomp->sign, ACCT_STR);
#endif
const int mv_class =
aom_read_symbol(r, mvcomp->class_cdf, MV_CLASSES, ACCT_STR);
aom_read_symbol(r, mvcomp->classes_cdf, MV_CLASSES, ACCT_STR);
const int class0 = mv_class == MV_CLASS_0;
// Integer part
......@@ -1307,7 +1307,7 @@ static int read_mv_component(aom_reader *r, nmv_component *mvcomp,
d = 0;
#if CONFIG_NEW_MULTISYMBOL
for (i = 0; i < n; ++i)
d |= aom_read_symbol(r, mvcomp->bits_cdf[(i + 1) / 2], 2, ACCT_STR) << i;
d |= aom_read_symbol(r, mvcomp->bits_cdf[i], 2, ACCT_STR) << i;
#else
for (i = 0; i < n; ++i) d |= aom_read(r, mvcomp->bits[i], ACCT_STR) << i;
#endif
......@@ -1349,7 +1349,7 @@ static INLINE void read_mv(aom_reader *r, MV *mv, const MV *ref,
MV_JOINT_TYPE joint_type;
MV diff = { 0, 0 };
joint_type =
(MV_JOINT_TYPE)aom_read_symbol(r, ctx->joint_cdf, MV_JOINTS, ACCT_STR);
(MV_JOINT_TYPE)aom_read_symbol(r, ctx->joints_cdf, MV_JOINTS, ACCT_STR);
if (mv_joint_vertical(joint_type))
diff.row = read_mv_component(r, &ctx->comps[0],
......
......@@ -44,13 +44,13 @@ static void encode_mv_component(aom_writer *w, int comp, nmv_component *mvcomp,
// Sign
#if CONFIG_NEW_MULTISYMBOL
aom_write_bit(w, sign);
aom_write_symbol(w, sign, mvcomp->sign_cdf, 2);
#else
aom_write(w, sign, mvcomp->sign);
#endif
// Class
aom_write_symbol(w, mv_class, mvcomp->class_cdf, MV_CLASSES);
aom_write_symbol(w, mv_class, mvcomp->classes_cdf, MV_CLASSES);
// Integer bits
if (mv_class == MV_CLASS_0) {
......@@ -64,7 +64,7 @@ static void encode_mv_component(aom_writer *w, int comp, nmv_component *mvcomp,
const int n = mv_class + CLASS0_BITS - 1; // number of bits
#if CONFIG_NEW_MULTISYMBOL
for (i = 0; i < n; ++i)
aom_write_symbol(w, (d >> i) & 1, mvcomp->bits_cdf[(i + 1) / 2], 2);
aom_write_symbol(w, (d >> i) & 1, mvcomp->bits_cdf[i], 2);
#else
for (i = 0; i < n; ++i) aom_write(w, (d >> i) & 1, mvcomp->bits[i]);
#endif
......@@ -100,24 +100,41 @@ static void build_nmv_component_cost_table(int *mvcost,
int class0_fp_cost[CLASS0_SIZE][MV_FP_SIZE], fp_cost[MV_FP_SIZE];
int class0_hp_cost[2], hp_cost[2];
#if CONFIG_NEW_MULTISYMBOL
av1_cost_tokens_from_cdf(sign_cost, mvcomp->sign_cdf, NULL);
#else
sign_cost[0] = av1_cost_zero(mvcomp->sign);
sign_cost[1] = av1_cost_one(mvcomp->sign);
av1_cost_tokens(class_cost, mvcomp->classes, av1_mv_class_tree);
#endif // CONFIG_NEW_MULTISYMBOL
av1_cost_tokens_from_cdf(class_cost, mvcomp->classes_cdf, NULL);
#if CONFIG_NEW_MULTISYMBOL
av1_cost_tokens_from_cdf(class0_cost, mvcomp->class0_cdf, NULL);
#else
av1_cost_tokens(class0_cost, mvcomp->class0, av1_mv_class0_tree);
#endif // CONFIG_NEW_MULTISYMBOL
for (i = 0; i < MV_OFFSET_BITS; ++i) {
#if CONFIG_NEW_MULTISYMBOL
av1_cost_tokens_from_cdf(bits_cost[i], mvcomp->bits_cdf[i], NULL);
#else
bits_cost[i][0] = av1_cost_zero(mvcomp->bits[i]);
bits_cost[i][1] = av1_cost_one(mvcomp->bits[i]);
#endif // CONFIG_NEW_MULTISYMBOL
}
for (i = 0; i < CLASS0_SIZE; ++i)
av1_cost_tokens(class0_fp_cost[i], mvcomp->class0_fp[i], av1_mv_fp_tree);
av1_cost_tokens(fp_cost, mvcomp->fp, av1_mv_fp_tree);
av1_cost_tokens_from_cdf(class0_fp_cost[i], mvcomp->class0_fp_cdf[i], NULL);
av1_cost_tokens_from_cdf(fp_cost, mvcomp->fp_cdf, NULL);
if (precision > MV_SUBPEL_LOW_PRECISION) {
#if CONFIG_NEW_MULTISYMBOL
av1_cost_tokens_from_cdf(class0_hp_cost, mvcomp->class0_hp_cdf, NULL);
av1_cost_tokens_from_cdf(hp_cost, mvcomp->hp_cdf, NULL);
#else
class0_hp_cost[0] = av1_cost_zero(mvcomp->class0_hp);
class0_hp_cost[1] = av1_cost_one(mvcomp->class0_hp);
hp_cost[0] = av1_cost_zero(mvcomp->hp);
hp_cost[1] = av1_cost_one(mvcomp->hp);
#endif // CONFIG_NEW_MULTISYMBOL
}
mvcost[0] = 0;
for (v = 1; v <= MV_MAX; ++v) {
......@@ -199,7 +216,7 @@ void av1_encode_mv(AV1_COMP *cpi, aom_writer *w, const MV *mv, const MV *ref,
usehp = MV_SUBPEL_NONE;
}
#endif
aom_write_symbol(w, j, mvctx->joint_cdf, MV_JOINTS);
aom_write_symbol(w, j, mvctx->joints_cdf, MV_JOINTS);
if (mv_joint_vertical(j))
encode_mv_component(w, diff.row, &mvctx->comps[0], usehp);
......@@ -225,7 +242,7 @@ void av1_encode_dv(aom_writer *w, const MV *mv, const MV *ref,
const MV diff = { mv->row - ref->row, mv->col - ref->col };
const MV_JOINT_TYPE j = av1_get_mv_joint(&diff);
aom_write_symbol(w, j, mvctx->joint_cdf, MV_JOINTS);
aom_write_symbol(w, j, mvctx->joints_cdf, MV_JOINTS);
if (mv_joint_vertical(j))
encode_mv_component(w, diff.row, &mvctx->comps[0], MV_SUBPEL_NONE);
......@@ -237,7 +254,7 @@ void av1_encode_dv(aom_writer *w, const MV *mv, const MV *ref,
void av1_build_nmv_cost_table(int *mvjoint, int *mvcost[2],
const nmv_context *ctx,
MvSubpelPrecision precision) {
av1_cost_tokens(mvjoint, ctx->joints, av1_mv_joint_tree);
av1_cost_tokens_from_cdf(mvjoint, ctx->joints_cdf, NULL);
build_nmv_component_cost_table(mvcost[0], &ctx->comps[0], precision);
build_nmv_component_cost_table(mvcost[1], &ctx->comps[1], precision);
}
......
......@@ -5703,7 +5703,9 @@ static void encode_frame_to_data_rate(AV1_COMP *cpi, size_t *size,
if (!frame_is_intra_only(cm)) {
if (cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD) {
av1_adapt_inter_frame_probs(cm);
#if !CONFIG_NEW_MULTISYMBOL
av1_adapt_mv_probs(cm, cm->allow_high_precision_mv);
#endif // !CONFIG_NEW_MULTISYMBOL
av1_average_tile_inter_cdfs(&cpi->common, cpi->common.fc, tile_ctxs,
cdf_ptrs, num_bwd_ctxs);
av1_average_tile_mv_cdfs(cpi->common.fc, tile_ctxs, cdf_ptrs,
......
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