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:
Родитель
4ba27d0162
Коммит
13d0662b9b
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче