Merge "Combining integer and fractional parts of mvs for entropy coding." into experimental
This commit is contained in:
Коммит
1e3cdc1dd2
|
@ -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);
|
||||
}
|
||||
// Fractional part
|
||||
fr = treed_read(r, vp9_mv_fp_tree,
|
||||
mv_class == MV_CLASS_0 ? mvcomp->class0_fp[d] : mvcomp->fp);
|
||||
|
||||
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;
|
||||
// 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 (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);
|
||||
|
||||
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);
|
||||
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) {
|
||||
write_nmv(cpi, bc, &mi->mv[1].as_mv, &mi->best_second_mv,
|
||||
(const nmv_context*) 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);
|
||||
vp9_encode_mv(bc, &blockmv.as_mv, &mi->best_mv.as_mv,
|
||||
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);
|
||||
}
|
||||
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,67 +24,47 @@ 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 */
|
||||
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
|
||||
|
||||
c = vp9_get_mv_class(z, &o);
|
||||
assert(comp != 0);
|
||||
|
||||
write_token(bc, vp9_mv_class_tree, mvcomp->classes,
|
||||
vp9_mv_class_encodings + c);
|
||||
// Sign
|
||||
vp9_write(w, sign, mvcomp->sign);
|
||||
|
||||
d = (o >> 3); /* int mv data */
|
||||
// Class
|
||||
write_token(w, vp9_mv_class_tree, mvcomp->classes,
|
||||
&vp9_mv_class_encodings[mv_class]);
|
||||
|
||||
if (c == MV_CLASS_0) {
|
||||
write_token(bc, vp9_mv_class0_tree, mvcomp->class0,
|
||||
vp9_mv_class0_encodings + d);
|
||||
// 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]);
|
||||
}
|
||||
|
||||
// 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 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void build_nmv_component_cost_table(int *mvcost,
|
||||
const nmv_component* const mvcomp,
|
||||
|
@ -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,
|
||||
|
|
Загрузка…
Ссылка в новой задаче