Commit 1e3cdc1d authored by Dmitry Kovalev's avatar Dmitry Kovalev Committed by Gerrit Code Review
Browse files

Merge "Combining integer and fractional parts of mvs for entropy coding." into experimental

parents e3869e9c 18375238
......@@ -181,77 +181,38 @@ static void kfread_modes(VP9D_COMP *pbi, MODE_INFO *m,
}
}
static int read_mv_component(vp9_reader *r,
const nmv_component *mvcomp, int usehp) {
static int read_nmv_component(vp9_reader *r,
int rv,
const nmv_component *mvcomp) {
int mag, d;
int mag, d, fr, hp;
const int sign = vp9_read(r, mvcomp->sign);
const int mv_class = treed_read(r, vp9_mv_class_tree, mvcomp->classes);
// Integer part
if (mv_class == MV_CLASS_0) {
d = treed_read(r, vp9_mv_class0_tree, mvcomp->class0);
} else {
int i;
int n = mv_class + CLASS0_BITS - 1; // number of bits
const int n = mv_class + CLASS0_BITS - 1; // number of bits
d = 0;
for (i = 0; i < n; ++i)
d |= vp9_read(r, mvcomp->bits[i]) << i;
}
mag = vp9_get_mv_mag(mv_class, d << 3);
return sign ? -(mag + 8) : (mag + 8);
}
static int read_nmv_component_fp(vp9_reader *r,
int v,
int rv,
const nmv_component *mvcomp,
int usehp) {
const int sign = v < 0;
int mag = ((sign ? -v : v) - 1) & ~7; // magnitude - 1
int offset;
const int mv_class = vp9_get_mv_class(mag, &offset);
const int f = mv_class == MV_CLASS_0 ?
treed_read(r, vp9_mv_fp_tree, mvcomp->class0_fp[offset >> 3]):
treed_read(r, vp9_mv_fp_tree, mvcomp->fp);
offset += f << 1;
// Fractional part
fr = treed_read(r, vp9_mv_fp_tree,
mv_class == MV_CLASS_0 ? mvcomp->class0_fp[d] : mvcomp->fp);
if (usehp) {
const vp9_prob p = mv_class == MV_CLASS_0 ? mvcomp->class0_hp : mvcomp->hp;
offset += vp9_read(r, p);
} else {
offset += 1; // If hp is not used, the default value of the hp bit is 1
}
mag = vp9_get_mv_mag(mv_class, offset);
return sign ? -(mag + 1) : (mag + 1);
}
static void read_nmv(vp9_reader *r, MV *mv, const MV *ref,
const nmv_context *mvctx) {
const MV_JOINT_TYPE j = treed_read(r, vp9_mv_joint_tree, mvctx->joints);
mv->row = mv->col = 0;
if (mv_joint_vertical(j))
mv->row = read_nmv_component(r, ref->row, &mvctx->comps[0]);
if (mv_joint_horizontal(j))
mv->col = read_nmv_component(r, ref->col, &mvctx->comps[1]);
}
static void read_nmv_fp(vp9_reader *r, MV *mv, const MV *ref,
const nmv_context *mvctx, int usehp) {
const MV_JOINT_TYPE j = vp9_get_mv_joint(mv);
usehp = usehp && vp9_use_nmv_hp(ref);
if (mv_joint_vertical(j))
mv->row = read_nmv_component_fp(r, mv->row, ref->row, &mvctx->comps[0],
usehp);
// High precision part (if hp is not used, the default value of the hp is 1)
hp = usehp ? vp9_read(r,
mv_class == MV_CLASS_0 ? mvcomp->class0_hp : mvcomp->hp)
: 1;
if (mv_joint_horizontal(j))
mv->col = read_nmv_component_fp(r, mv->col, ref->col, &mvctx->comps[1],
usehp);
// result
mag = vp9_get_mv_mag(mv_class, (d << 3) | (fr << 1) | hp) + 1;
return sign ? -mag : mag;
}
static void update_nmv(vp9_reader *r, vp9_prob *const p,
......@@ -540,15 +501,24 @@ static INLINE void assign_and_clamp_mv(int_mv *dst, const int_mv *src,
mb_to_bottom_edge);
}
static INLINE void process_mv(vp9_reader *r, MV *mv, const MV *ref,
const nmv_context *nmvc,
nmv_context_counts *mvctx,
int usehp) {
read_nmv(r, mv, ref, nmvc);
read_nmv_fp(r, mv, ref, nmvc, usehp);
vp9_increment_nmv(mv, ref, mvctx, usehp);
mv->row += ref->row;
mv->col += ref->col;
static INLINE void decode_mv(vp9_reader *r, MV *mv, const MV *ref,
const nmv_context *ctx,
nmv_context_counts *counts,
int usehp) {
const MV_JOINT_TYPE j = treed_read(r, vp9_mv_joint_tree, ctx->joints);
MV diff = {0, 0};
usehp = usehp && vp9_use_nmv_hp(ref);
if (mv_joint_vertical(j))
diff.row = read_mv_component(r, &ctx->comps[0], usehp);
if (mv_joint_horizontal(j))
diff.col = read_mv_component(r, &ctx->comps[1], usehp);
vp9_increment_nmv(&diff, ref, counts, usehp);
mv->row = diff.row + ref->row;
mv->col = diff.col + ref->col;
}
static INLINE INTERPOLATIONFILTERTYPE read_switchable_filter_type(
......@@ -741,12 +711,12 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
switch (blockmode) {
case NEW4X4:
process_mv(r, &blockmv.as_mv, &best_mv.as_mv, nmvc,
&cm->fc.NMVcount, xd->allow_high_precision_mv);
decode_mv(r, &blockmv.as_mv, &best_mv.as_mv, nmvc,
&cm->fc.NMVcount, xd->allow_high_precision_mv);
if (mbmi->second_ref_frame > 0)
process_mv(r, &secondmv.as_mv, &best_mv_second.as_mv, nmvc,
&cm->fc.NMVcount, xd->allow_high_precision_mv);
decode_mv(r, &secondmv.as_mv, &best_mv_second.as_mv, nmvc,
&cm->fc.NMVcount, xd->allow_high_precision_mv);
#ifdef VPX_MODE_COUNT
vp9_mv_cont_count[mv_contz][3]++;
......@@ -823,8 +793,8 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
break;
case NEWMV:
process_mv(r, &mv0->as_mv, &best_mv.as_mv, nmvc, &cm->fc.NMVcount,
xd->allow_high_precision_mv);
decode_mv(r, &mv0->as_mv, &best_mv.as_mv, nmvc, &cm->fc.NMVcount,
xd->allow_high_precision_mv);
mbmi->need_to_clamp_mvs = check_mv_bounds(mv0,
mb_to_left_edge,
mb_to_right_edge,
......@@ -832,8 +802,8 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
mb_to_bottom_edge);
if (mbmi->second_ref_frame > 0) {
process_mv(r, &mv1->as_mv, &best_mv_second.as_mv, nmvc,
&cm->fc.NMVcount, xd->allow_high_precision_mv);
decode_mv(r, &mv1->as_mv, &best_mv_second.as_mv, nmvc,
&cm->fc.NMVcount, xd->allow_high_precision_mv);
mbmi->need_to_clamp_secondmv = check_mv_bounds(mv1,
mb_to_left_edge,
mb_to_right_edge,
......
......@@ -455,16 +455,6 @@ static void write_sub_mv_ref(vp9_writer *bc, B_PREDICTION_MODE m,
vp9_sub_mv_ref_encoding_array - LEFT4X4 + m);
}
static void write_nmv(VP9_COMP *cpi, vp9_writer *bc,
const MV *mv, const int_mv *ref,
const nmv_context *nmvc, int usehp) {
MV e;
e.row = mv->row - ref->as_mv.row;
e.col = mv->col - ref->as_mv.col;
vp9_encode_nmv(bc, &e, &ref->as_mv, nmvc);
vp9_encode_nmv_fp(bc, &e, &ref->as_mv, nmvc, usehp);
}
// This function writes the current macro block's segnment id to the bitstream
// It should only be called if a segment map update is indicated.
......@@ -700,15 +690,14 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m,
#ifdef ENTROPY_STATS
active_section = 5;
#endif
write_nmv(cpi, bc, &mi->mv[0].as_mv, &mi->best_mv,
(const nmv_context*) nmvc,
xd->allow_high_precision_mv);
if (mi->second_ref_frame > 0) {
write_nmv(cpi, bc, &mi->mv[1].as_mv, &mi->best_second_mv,
(const nmv_context*) nmvc,
xd->allow_high_precision_mv);
}
vp9_encode_mv(bc,
&mi->mv[0].as_mv, &mi->best_mv.as_mv,
nmvc, xd->allow_high_precision_mv);
if (mi->second_ref_frame > 0)
vp9_encode_mv(bc,
&mi->mv[1].as_mv, &mi->best_second_mv.as_mv,
nmvc, xd->allow_high_precision_mv);
break;
case SPLITMV: {
int j = 0;
......@@ -738,17 +727,14 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m,
#ifdef ENTROPY_STATS
active_section = 11;
#endif
write_nmv(cpi, bc, &blockmv.as_mv, &mi->best_mv,
(const nmv_context*) nmvc,
xd->allow_high_precision_mv);
if (mi->second_ref_frame > 0) {
write_nmv(cpi, bc,
&cpi->mb.partition_info->bmi[j].second_mv.as_mv,
&mi->best_second_mv,
(const nmv_context*) nmvc,
xd->allow_high_precision_mv);
}
vp9_encode_mv(bc, &blockmv.as_mv, &mi->best_mv.as_mv,
nmvc, xd->allow_high_precision_mv);
if (mi->second_ref_frame > 0)
vp9_encode_mv(bc,
&cpi->mb.partition_info->bmi[j].second_mv.as_mv,
&mi->best_second_mv.as_mv,
nmvc, xd->allow_high_precision_mv);
}
} while (++j < cpi->mb.partition_info->count);
break;
......
......@@ -24,68 +24,48 @@ extern unsigned int active_section;
nmv_context_counts tnmvcounts;
#endif
static void encode_nmv_component(vp9_writer* const bc,
int v,
int r,
const nmv_component* const mvcomp) {
int s, z, c, o, d;
assert (v != 0); /* should not be zero */
s = v < 0;
vp9_write(bc, s, mvcomp->sign);
z = (s ? -v : v) - 1; /* magnitude - 1 */
c = vp9_get_mv_class(z, &o);
write_token(bc, vp9_mv_class_tree, mvcomp->classes,
vp9_mv_class_encodings + c);
d = (o >> 3); /* int mv data */
if (c == MV_CLASS_0) {
write_token(bc, vp9_mv_class0_tree, mvcomp->class0,
vp9_mv_class0_encodings + d);
static void encode_mv_component(vp9_writer* w, int comp,
const nmv_component* mvcomp, int usehp) {
int offset;
const int sign = comp < 0;
const int mag = sign ? -comp : comp;
const int mv_class = vp9_get_mv_class(mag - 1, &offset);
const int d = offset >> 3; // int mv data
const int fr = (offset >> 1) & 3; // fractional mv data
const int hp = offset & 1; // high precision mv data
assert(comp != 0);
// Sign
vp9_write(w, sign, mvcomp->sign);
// Class
write_token(w, vp9_mv_class_tree, mvcomp->classes,
&vp9_mv_class_encodings[mv_class]);
// Integer bits
if (mv_class == MV_CLASS_0) {
write_token(w, vp9_mv_class0_tree, mvcomp->class0,
&vp9_mv_class0_encodings[d]);
} else {
int i, b;
b = c + CLASS0_BITS - 1; /* number of bits */
for (i = 0; i < b; ++i)
vp9_write(bc, ((d >> i) & 1), mvcomp->bits[i]);
int i;
const int n = mv_class + CLASS0_BITS - 1; // number of bits
for (i = 0; i < n; ++i)
vp9_write(w, (d >> i) & 1, mvcomp->bits[i]);
}
}
static void encode_nmv_component_fp(vp9_writer *bc,
int v,
int r,
const nmv_component* const mvcomp,
int usehp) {
int s, z, c, o, d, f, e;
assert (v != 0); /* should not be zero */
s = v < 0;
z = (s ? -v : v) - 1; /* magnitude - 1 */
c = vp9_get_mv_class(z, &o);
d = (o >> 3); /* int mv data */
f = (o >> 1) & 3; /* fractional pel mv data */
e = (o & 1); /* high precision mv data */
/* Code the fractional pel bits */
if (c == MV_CLASS_0) {
write_token(bc, vp9_mv_fp_tree, mvcomp->class0_fp[d],
vp9_mv_fp_encodings + f);
} else {
write_token(bc, vp9_mv_fp_tree, mvcomp->fp,
vp9_mv_fp_encodings + f);
}
/* Code the high precision bit */
if (usehp) {
if (c == MV_CLASS_0) {
vp9_write(bc, e, mvcomp->class0_hp);
} else {
vp9_write(bc, e, mvcomp->hp);
}
}
// Fractional bits
write_token(w, vp9_mv_fp_tree,
mv_class == MV_CLASS_0 ? mvcomp->class0_fp[d] : mvcomp->fp,
&vp9_mv_fp_encodings[fr]);
// High precision bit
if (usehp)
vp9_write(w, hp,
mv_class == MV_CLASS_0 ? mvcomp->class0_hp : mvcomp->hp);
}
static void build_nmv_component_cost_table(int *mvcost,
const nmv_component* const mvcomp,
int usehp) {
......@@ -556,27 +536,19 @@ void vp9_write_nmv_probs(VP9_COMP* const cpi, int usehp, vp9_writer* const bc) {
}
}
void vp9_encode_nmv(vp9_writer* w, const MV* const mv,
const MV* const ref, const nmv_context* const mvctx) {
const MV_JOINT_TYPE j = vp9_get_mv_joint(mv);
write_token(w, vp9_mv_joint_tree, mvctx->joints, vp9_mv_joint_encodings + j);
if (mv_joint_vertical(j))
encode_nmv_component(w, mv->row, ref->col, &mvctx->comps[0]);
if (mv_joint_horizontal(j))
encode_nmv_component(w, mv->col, ref->col, &mvctx->comps[1]);
}
void vp9_encode_nmv_fp(vp9_writer* const bc, const MV* const mv,
const MV* const ref, const nmv_context* const mvctx,
int usehp) {
const MV_JOINT_TYPE j = vp9_get_mv_joint(mv);
void vp9_encode_mv(vp9_writer* w, const MV* mv, const MV* ref,
const nmv_context* mvctx, int usehp) {
const MV diff = {mv->row - ref->row,
mv->col - ref->col};
const MV_JOINT_TYPE j = vp9_get_mv_joint(&diff);
usehp = usehp && vp9_use_nmv_hp(ref);
write_token(w, vp9_mv_joint_tree, mvctx->joints, &vp9_mv_joint_encodings[j]);
if (mv_joint_vertical(j))
encode_nmv_component_fp(bc, mv->row, ref->row, &mvctx->comps[0], usehp);
encode_mv_component(w, diff.row, &mvctx->comps[0], usehp);
if (mv_joint_horizontal(j))
encode_nmv_component_fp(bc, mv->col, ref->col, &mvctx->comps[1], usehp);
encode_mv_component(w, diff.col, &mvctx->comps[1], usehp);
}
void vp9_build_nmv_cost_table(int *mvjoint,
......
......@@ -15,11 +15,10 @@
#include "vp9/encoder/vp9_onyx_int.h"
void vp9_write_nmv_probs(VP9_COMP* const, int usehp, vp9_writer* const);
void vp9_encode_nmv(vp9_writer* const w, const MV* const mv,
const MV* const ref, const nmv_context* const mvctx);
void vp9_encode_nmv_fp(vp9_writer* const w, const MV* const mv,
const MV* const ref, const nmv_context* const mvctx,
int usehp);
void vp9_encode_mv(vp9_writer* w, const MV* mv, const MV* ref,
const nmv_context* mvctx, int usehp);
void vp9_build_nmv_cost_table(int *mvjoint,
int *mvcost[2],
const nmv_context* const mvctx,
......
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