Reduce the number of bits sent for global translation model

When a global translation model is found, the only 3 bits
of precision are used for the motion parameters. This case
uses a smaller precision than the translation parameters
in a global model that is rotzoom or greater.
Change-Id: Ic972e9edf46e301f2894cce2b723960d0297c8e8
This commit is contained in:
Sarah Parker 2017-03-10 17:03:28 -08:00
Родитель 4ba27d0162
Коммит 13d0662b9b
5 изменённых файлов: 62 добавлений и 19 удалений

Просмотреть файл

@ -123,8 +123,11 @@ typedef struct {
#define GM_TRANS_PREC_BITS 6
#define GM_ABS_TRANS_BITS 12
#define GM_ABS_TRANS_ONLY_BITS (GM_ABS_TRANS_BITS - GM_TRANS_PREC_BITS + 3)
#define GM_TRANS_PREC_DIFF (WARPEDMODEL_PREC_BITS - GM_TRANS_PREC_BITS)
#define GM_TRANS_ONLY_PREC_DIFF (WARPEDMODEL_PREC_BITS - 3)
#define GM_TRANS_DECODE_FACTOR (1 << GM_TRANS_PREC_DIFF)
#define GM_TRANS_ONLY_DECODE_FACTOR (1 << GM_TRANS_ONLY_PREC_DIFF)
#define GM_ALPHA_PREC_BITS 15
#define GM_ABS_ALPHA_BITS 12
@ -158,6 +161,13 @@ static INLINE int block_center_y(int mi_row, BLOCK_SIZE bs) {
return mi_row * MI_SIZE + bh / 2 - 1;
}
static INLINE int convert_to_trans_prec(int allow_hp, int coor) {
const int shift =
allow_hp ? WARPEDMODEL_PREC_BITS - 3 : WARPEDMODEL_PREC_BITS - 2;
const int scale = allow_hp ? 0 : 1;
return (ROUND_POWER_OF_TWO_SIGNED(coor, shift) << scale);
}
// Convert a global motion translation vector (which may have more bits than a
// regular motion vector) into a motion vector
static INLINE int_mv gm_get_motion_vector(const WarpedMotionParams *gm,
@ -168,6 +178,13 @@ static INLINE int_mv gm_get_motion_vector(const WarpedMotionParams *gm,
int_mv res;
const int32_t *mat = gm->wmmat;
int xc, yc, x, y;
if (gm->wmtype == TRANSLATION) {
res.as_mv.row = gm->wmmat[0] >> GM_TRANS_ONLY_PREC_DIFF;
res.as_mv.col = gm->wmmat[1] >> GM_TRANS_ONLY_PREC_DIFF;
return res;
}
if (bsize >= BLOCK_8X8 || unify_bsize) {
x = block_center_x(mi_col, bsize);
y = block_center_y(mi_row, bsize);
@ -177,8 +194,6 @@ static INLINE int_mv gm_get_motion_vector(const WarpedMotionParams *gm,
x += (block_idx & 1) * MI_SIZE / 2;
y += (block_idx & 2) * MI_SIZE / 4;
}
int shift = allow_hp ? WARPEDMODEL_PREC_BITS - 3 : WARPEDMODEL_PREC_BITS - 2;
int scale = allow_hp ? 0 : 1;
if (gm->wmtype == ROTZOOM) {
assert(gm->wmmat[5] == gm->wmmat[2]);
@ -196,8 +211,8 @@ static INLINE int_mv gm_get_motion_vector(const WarpedMotionParams *gm,
yc = yc > 0 ? (yc + Z / 2) / Z : (yc - Z / 2) / Z;
}
int tx = (ROUND_POWER_OF_TWO_SIGNED(xc, shift) << scale) - (x << 3);
int ty = (ROUND_POWER_OF_TWO_SIGNED(yc, shift) << scale) - (y << 3);
int tx = convert_to_trans_prec(allow_hp, xc) - (x << 3);
int ty = convert_to_trans_prec(allow_hp, yc) - (y << 3);
res.as_mv.row = ty;
res.as_mv.col = tx;

Просмотреть файл

@ -4395,9 +4395,12 @@ static void read_supertx_probs(FRAME_CONTEXT *fc, aom_reader *r) {
#if CONFIG_GLOBAL_MOTION
static void read_global_motion_params(WarpedMotionParams *params,
aom_prob *probs, aom_reader *r) {
aom_prob *probs, aom_reader *r,
int allow_hp) {
TransformationType type =
aom_read_tree(r, av1_global_motion_types_tree, probs, ACCT_STR);
int trans_bits;
int trans_dec_factor;
set_default_gmparams(params);
params->wmtype = type;
switch (type) {
@ -4434,10 +4437,15 @@ static void read_global_motion_params(WarpedMotionParams *params,
}
// fallthrough intended
case TRANSLATION:
params->wmmat[0] = aom_read_primitive_symmetric(r, GM_ABS_TRANS_BITS) *
GM_TRANS_DECODE_FACTOR;
params->wmmat[1] = aom_read_primitive_symmetric(r, GM_ABS_TRANS_BITS) *
GM_TRANS_DECODE_FACTOR;
trans_bits = (type == TRANSLATION) ? GM_ABS_TRANS_ONLY_BITS - !allow_hp
: GM_ABS_TRANS_BITS;
trans_dec_factor = (type == TRANSLATION)
? GM_TRANS_ONLY_DECODE_FACTOR * (1 << !allow_hp)
: GM_TRANS_DECODE_FACTOR;
params->wmmat[0] =
aom_read_primitive_symmetric(r, trans_bits) * trans_dec_factor;
params->wmmat[1] =
aom_read_primitive_symmetric(r, trans_bits) * trans_dec_factor;
break;
case IDENTITY: break;
default: assert(0);
@ -4450,7 +4458,8 @@ static void read_global_motion(AV1_COMMON *cm, aom_reader *r) {
int frame;
for (frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame) {
read_global_motion_params(&cm->global_motion[frame],
cm->fc->global_motion_types_prob, r);
cm->fc->global_motion_types_prob, r,
cm->allow_high_precision_mv);
/*
printf("Dec Ref %d [%d/%d]: %d %d %d %d\n",
frame, cm->current_video_frame, cm->show_frame,

Просмотреть файл

@ -4571,8 +4571,11 @@ static void write_uncompressed_header(AV1_COMP *cpi,
#if CONFIG_GLOBAL_MOTION
static void write_global_motion_params(WarpedMotionParams *params,
aom_prob *probs, aom_writer *w) {
aom_prob *probs, aom_writer *w,
int allow_hp) {
TransformationType type = params->wmtype;
int trans_bits;
int trans_prec_diff;
av1_write_token(w, av1_global_motion_types_tree, probs,
&global_motion_types_encodings[type]);
switch (type) {
@ -4608,10 +4611,15 @@ static void write_global_motion_params(WarpedMotionParams *params,
}
// fallthrough intended
case TRANSLATION:
aom_write_primitive_symmetric(w, (params->wmmat[0] >> GM_TRANS_PREC_DIFF),
GM_ABS_TRANS_BITS);
aom_write_primitive_symmetric(w, (params->wmmat[1] >> GM_TRANS_PREC_DIFF),
GM_ABS_TRANS_BITS);
trans_bits = (type == TRANSLATION) ? GM_ABS_TRANS_ONLY_BITS - !allow_hp
: GM_ABS_TRANS_BITS;
trans_prec_diff = (type == TRANSLATION)
? GM_TRANS_ONLY_PREC_DIFF + !allow_hp
: GM_TRANS_PREC_DIFF;
aom_write_primitive_symmetric(w, (params->wmmat[0] >> trans_prec_diff),
trans_bits);
aom_write_primitive_symmetric(w, (params->wmmat[1] >> trans_prec_diff),
trans_bits);
break;
case IDENTITY: break;
default: assert(0);
@ -4631,7 +4639,8 @@ static void write_global_motion(AV1_COMP *cpi, aom_writer *w) {
}
#endif
write_global_motion_params(&cm->global_motion[frame],
cm->fc->global_motion_types_prob, w);
cm->fc->global_motion_types_prob, w,
cm->allow_high_precision_mv);
/*
printf("Frame %d/%d: Enc Ref %d (used %d): %d %d %d %d\n",
cm->current_video_frame, cm->show_frame, frame,

Просмотреть файл

@ -5153,7 +5153,19 @@ static void encode_frame_internal(AV1_COMP *cpi) {
if (!get_shear_params(&cm->global_motion[frame]))
set_default_gmparams(&cm->global_motion[frame]);
if (cm->global_motion[frame].wmtype != IDENTITY) break;
if (cm->global_motion[frame].wmtype != IDENTITY) {
if (cm->global_motion[frame].wmtype == TRANSLATION) {
cm->global_motion[frame].wmmat[0] =
convert_to_trans_prec(cm->allow_high_precision_mv,
cm->global_motion[frame].wmmat[0]) *
GM_TRANS_ONLY_DECODE_FACTOR;
cm->global_motion[frame].wmmat[1] =
convert_to_trans_prec(cm->allow_high_precision_mv,
cm->global_motion[frame].wmmat[1]) *
GM_TRANS_ONLY_DECODE_FACTOR;
}
break;
}
}
aom_clear_system_state();
}

Просмотреть файл

@ -24,8 +24,6 @@ extern "C" {
extern const double gm_advantage_thresh[TRANS_TYPES];
void convert_to_params(const double *params, int32_t *model);
void convert_model_to_params(const double *params, WarpedMotionParams *model);
// Adds some offset to a global motion parameter and handles