Commit 6b2584c6 authored by Alex Converse's avatar Alex Converse
Browse files

intrabc: Elide subpel bits

objective-1-fast 1st KF: -0.04 BDRATE-PSNR
twitch-1 1st KF: -0.04 BDRATE-PSNR

Change-Id: I74e8e43278a3d228f9b0a9af014e69f80aa90a0f
parent 746a7853
......@@ -180,7 +180,7 @@ MV_CLASS_TYPE av1_get_mv_class(int z, int *offset) {
}
static void inc_mv_component(int v, nmv_component_counts *comp_counts, int incr,
int usehp) {
MvSubpelPrecision precision) {
int s, z, c, o, d, e, f;
assert(v != 0); /* should not be zero */
s = v < 0;
......@@ -196,27 +196,34 @@ static void inc_mv_component(int v, nmv_component_counts *comp_counts, int incr,
if (c == MV_CLASS_0) {
comp_counts->class0[d] += incr;
comp_counts->class0_fp[d][f] += incr;
if (usehp) comp_counts->class0_hp[e] += incr;
#if CONFIG_INTRABC
if (precision > MV_SUBPEL_NONE)
#endif
comp_counts->class0_fp[d][f] += incr;
if (precision > MV_SUBPEL_LOW_PRECISION) comp_counts->class0_hp[e] += incr;
} else {
int i;
int b = c + CLASS0_BITS - 1; // number of bits
for (i = 0; i < b; ++i) comp_counts->bits[i][((d >> i) & 1)] += incr;
comp_counts->fp[f] += incr;
if (usehp) comp_counts->hp[e] += incr;
#if CONFIG_INTRABC
if (precision > MV_SUBPEL_NONE)
#endif
comp_counts->fp[f] += incr;
if (precision > MV_SUBPEL_LOW_PRECISION) comp_counts->hp[e] += incr;
}
}
void av1_inc_mv(const MV *mv, nmv_context_counts *counts, const int usehp) {
void av1_inc_mv(const MV *mv, nmv_context_counts *counts,
MvSubpelPrecision precision) {
if (counts != NULL) {
const MV_JOINT_TYPE j = av1_get_mv_joint(mv);
++counts->joints[j];
if (mv_joint_vertical(j))
inc_mv_component(mv->row, &counts->comps[0], 1, usehp);
inc_mv_component(mv->row, &counts->comps[0], 1, precision);
if (mv_joint_horizontal(j))
inc_mv_component(mv->col, &counts->comps[1], 1, usehp);
inc_mv_component(mv->col, &counts->comps[1], 1, precision);
}
}
......
......@@ -127,7 +127,16 @@ typedef struct {
nmv_component_counts comps[2];
} nmv_context_counts;
void av1_inc_mv(const MV *mv, nmv_context_counts *mvctx, const int usehp);
typedef enum {
#if CONFIG_INTRABC
MV_SUBPEL_NONE = -1,
#endif
MV_SUBPEL_LOW_PRECISION = 0,
MV_SUBPEL_HIGH_PRECISION,
} MvSubpelPrecision;
void av1_inc_mv(const MV *mv, nmv_context_counts *mvctx,
MvSubpelPrecision precision);
#if CONFIG_GLOBAL_MOTION
extern const aom_tree_index
av1_global_motion_types_tree[TREE_SIZE(GLOBAL_TRANS_TYPES)];
......
......@@ -944,7 +944,7 @@ void av1_read_tx_type(const AV1_COMMON *const cm, MACROBLOCKD *xd,
#if CONFIG_INTRABC
static INLINE void read_mv(aom_reader *r, MV *mv, const MV *ref,
nmv_context *ctx, nmv_context_counts *counts,
int allow_hp);
MvSubpelPrecision precision);
static INLINE int is_mv_valid(const MV *mv);
......@@ -959,7 +959,8 @@ static INLINE int assign_dv(AV1_COMMON *cm, MACROBLOCKD *xd, int_mv *mv,
#endif
FRAME_COUNTS *counts = xd->counts;
nmv_context_counts *const dv_counts = counts ? &counts->dv : NULL;
read_mv(r, &mv->as_mv, &ref_mv->as_mv, &ec_ctx->ndvc, dv_counts, 0);
read_mv(r, &mv->as_mv, &ref_mv->as_mv, &ec_ctx->ndvc, dv_counts,
MV_SUBPEL_NONE);
int valid = is_mv_valid(&mv->as_mv) &&
is_dv_valid(mv->as_mv, &xd->tile, mi_row, mi_col, bsize);
return valid;
......@@ -1141,7 +1142,11 @@ static void read_intra_frame_mode_info(AV1_COMMON *const cm,
#endif // !CONFIG_TXK_SEL
}
static int read_mv_component(aom_reader *r, nmv_component *mvcomp, int usehp) {
static int read_mv_component(aom_reader *r, nmv_component *mvcomp,
#if CONFIG_INTRABC
int use_subpel,
#endif // CONFIG_INTRABC
int usehp) {
int mag, d, fr, hp;
const int sign = aom_read(r, mvcomp->sign, ACCT_STR);
const int mv_class =
......@@ -1161,13 +1166,22 @@ static int read_mv_component(aom_reader *r, nmv_component *mvcomp, int usehp) {
mag = CLASS0_SIZE << (mv_class + 2);
}
// Fractional part
fr = aom_read_symbol(r, class0 ? mvcomp->class0_fp_cdf[d] : mvcomp->fp_cdf,
MV_FP_SIZE, ACCT_STR);
#if CONFIG_INTRABC
if (use_subpel) {
#endif // CONFIG_INTRABC
// Fractional part
fr = aom_read_symbol(r, class0 ? mvcomp->class0_fp_cdf[d] : mvcomp->fp_cdf,
MV_FP_SIZE, ACCT_STR);
// High precision part (if hp is not used, the default value of the hp is 1)
hp = usehp ? aom_read(r, class0 ? mvcomp->class0_hp : mvcomp->hp, ACCT_STR)
: 1;
// High precision part (if hp is not used, the default value of the hp is 1)
hp = usehp ? aom_read(r, class0 ? mvcomp->class0_hp : mvcomp->hp, ACCT_STR)
: 1;
#if CONFIG_INTRABC
} else {
fr = 3;
hp = 1;
}
#endif // CONFIG_INTRABC
// Result
mag += ((d << 3) | (fr << 1) | hp) + 1;
......@@ -1176,19 +1190,27 @@ static int read_mv_component(aom_reader *r, nmv_component *mvcomp, int usehp) {
static INLINE void read_mv(aom_reader *r, MV *mv, const MV *ref,
nmv_context *ctx, nmv_context_counts *counts,
int allow_hp) {
MvSubpelPrecision precision) {
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);
if (mv_joint_vertical(joint_type))
diff.row = read_mv_component(r, &ctx->comps[0], allow_hp);
diff.row = read_mv_component(r, &ctx->comps[0],
#if CONFIG_INTRABC
precision > MV_SUBPEL_NONE,
#endif // CONFIG_INTRABC
precision > MV_SUBPEL_LOW_PRECISION);
if (mv_joint_horizontal(joint_type))
diff.col = read_mv_component(r, &ctx->comps[1], allow_hp);
diff.col = read_mv_component(r, &ctx->comps[1],
#if CONFIG_INTRABC
precision > MV_SUBPEL_NONE,
#endif // CONFIG_INTRABC
precision > MV_SUBPEL_LOW_PRECISION);
av1_inc_mv(&diff, counts, allow_hp);
av1_inc_mv(&diff, counts, precision);
mv->row = ref->row + diff.row;
mv->col = ref->col + diff.col;
......
......@@ -31,7 +31,7 @@ void av1_entropy_mv_init(void) {
}
static void encode_mv_component(aom_writer *w, int comp, nmv_component *mvcomp,
int usehp) {
MvSubpelPrecision precision) {
int offset;
const int sign = comp < 0;
const int mag = sign ? -comp : comp;
......@@ -57,13 +57,18 @@ static void encode_mv_component(aom_writer *w, int comp, nmv_component *mvcomp,
for (i = 0; i < n; ++i) aom_write(w, (d >> i) & 1, mvcomp->bits[i]);
}
// Fractional bits
aom_write_symbol(
w, fr, mv_class == MV_CLASS_0 ? mvcomp->class0_fp_cdf[d] : mvcomp->fp_cdf,
MV_FP_SIZE);
// Fractional bits
#if CONFIG_INTRABC
if (precision > MV_SUBPEL_NONE)
#endif // CONFIG_INTRABC
{
aom_write_symbol(w, fr, mv_class == MV_CLASS_0 ? mvcomp->class0_fp_cdf[d]
: mvcomp->fp_cdf,
MV_FP_SIZE);
}
// High precision bit
if (usehp)
if (precision > MV_SUBPEL_LOW_PRECISION)
aom_write(w, hp, mv_class == MV_CLASS_0 ? mvcomp->class0_hp : mvcomp->hp);
}
......@@ -230,10 +235,10 @@ void av1_encode_dv(aom_writer *w, const MV *mv, const MV *ref,
aom_write_symbol(w, j, mvctx->joint_cdf, MV_JOINTS);
if (mv_joint_vertical(j))
encode_mv_component(w, diff.row, &mvctx->comps[0], 0);
encode_mv_component(w, diff.row, &mvctx->comps[0], MV_SUBPEL_NONE);
if (mv_joint_horizontal(j))
encode_mv_component(w, diff.col, &mvctx->comps[1], 0);
encode_mv_component(w, diff.col, &mvctx->comps[1], MV_SUBPEL_NONE);
}
#endif // CONFIG_INTRABC
......
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