Commit f1783291 authored by Sarah Parker's avatar Sarah Parker Committed by Debargha Mukherjee

Add gm parameter coding based on ref parameters

Change-Id: Ic2344a6475b967fa07f70b3ffad2714de657bb49
parent 9d53302c
......@@ -108,3 +108,12 @@ uint16_t aom_read_primitive_refsubexpfin(aom_reader *r, uint16_t n, uint16_t k,
return inv_recenter_finite_nonneg(n, ref,
aom_read_primitive_subexpfin(r, n, k));
}
// Decode finite subexponential code that for a symbol v in [-(n-1), n-1] with
// parameter k based on a reference ref also in [-(n-1), n-1].
int16_t aom_read_signed_primitive_refsubexpfin(aom_reader *r, uint16_t n,
uint16_t k, int16_t ref) {
ref += n - 1;
const uint16_t scaled_n = (n << 1) - 1;
return aom_read_primitive_refsubexpfin(r, scaled_n, k, ref) - n + 1;
}
......@@ -29,6 +29,8 @@ uint16_t aom_read_primitive_refbilevel(aom_reader *r, uint16_t n, uint16_t p,
uint16_t aom_read_primitive_subexpfin(aom_reader *r, uint16_t n, uint16_t k);
uint16_t aom_read_primitive_refsubexpfin(aom_reader *r, uint16_t n, uint16_t k,
uint16_t ref);
int16_t aom_read_signed_primitive_refsubexpfin(aom_reader *r, uint16_t n,
uint16_t k, int16_t ref);
#ifdef __cplusplus
} // extern "C"
#endif
......
......@@ -184,11 +184,28 @@ int aom_count_primitive_subexpfin(uint16_t n, uint16_t k, uint16_t v) {
// based on a reference ref also in [0, n-1].
// Recenters symbol around r first and then uses a finite subexponential code.
void aom_write_primitive_refsubexpfin(aom_writer *w, uint16_t n, uint16_t k,
uint16_t ref, uint16_t v) {
int16_t ref, int16_t v) {
aom_write_primitive_subexpfin(w, n, k, recenter_finite_nonneg(n, ref, v));
}
void aom_write_signed_primitive_refsubexpfin(aom_writer *w, uint16_t n,
uint16_t k, uint16_t ref,
uint16_t v) {
ref += n - 1;
v += n - 1;
const uint16_t scaled_n = (n << 1) - 1;
aom_write_primitive_refsubexpfin(w, scaled_n, k, ref, v);
}
int aom_count_primitive_refsubexpfin(uint16_t n, uint16_t k, uint16_t ref,
uint16_t v) {
return aom_count_primitive_subexpfin(n, k, recenter_finite_nonneg(n, ref, v));
}
int aom_count_signed_primitive_refsubexpfin(uint16_t n, uint16_t k, int16_t ref,
int16_t v) {
ref += n - 1;
v += n - 1;
const uint16_t scaled_n = (n << 1) - 1;
return aom_count_primitive_refsubexpfin(scaled_n, k, ref, v);
}
......@@ -47,6 +47,12 @@ void aom_write_primitive_subexpfin(aom_writer *w, uint16_t n, uint16_t k,
void aom_write_primitive_refsubexpfin(aom_writer *w, uint16_t n, uint16_t k,
uint16_t ref, uint16_t v);
// Finite subexponential code that codes a symbol v in [-(n-1), n-1] with
// parameter k based on a reference ref also in [-(n-1), n-1].
void aom_write_signed_primitive_refsubexpfin(aom_writer *w, uint16_t n,
uint16_t k, int16_t ref,
int16_t v);
// Functions that counts bits for the above primitives
int aom_count_primitive_symmetric(int16_t v, unsigned int mag_bits);
int aom_count_primitive_quniform(uint16_t n, uint16_t v);
......@@ -55,6 +61,8 @@ int aom_count_primitive_refbilevel(uint16_t n, uint16_t p, uint16_t ref,
int aom_count_primitive_subexpfin(uint16_t n, uint16_t k, uint16_t v);
int aom_count_primitive_refsubexpfin(uint16_t n, uint16_t k, uint16_t ref,
uint16_t v);
int aom_count_signed_primitive_refsubexpfin(uint16_t n, uint16_t k, int16_t ref,
int16_t v);
#ifdef __cplusplus
} // extern "C"
#endif
......
......@@ -121,6 +121,7 @@ typedef struct {
//
// XX_MIN, XX_MAX are also computed to avoid repeated computation
#define SUBEXPFIN_K 3
#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)
......
......@@ -108,6 +108,9 @@ typedef struct {
MV_REF *mvs;
int mi_rows;
int mi_cols;
#if CONFIG_GLOBAL_MOTION
WarpedMotionParams global_motion[TOTAL_REFS_PER_FRAME];
#endif // CONFIG_GLOBAL_MOTION
aom_codec_frame_buffer_t raw_frame_buffer;
YV12_BUFFER_CONFIG buf;
#if CONFIG_TEMPMV_SIGNALING
......
......@@ -4401,12 +4401,14 @@ static void read_supertx_probs(FRAME_CONTEXT *fc, aom_reader *r) {
#if CONFIG_GLOBAL_MOTION
static void read_global_motion_params(WarpedMotionParams *params,
WarpedMotionParams *ref_params,
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;
int trans_prec_diff;
set_default_gmparams(params);
params->wmtype = type;
switch (type) {
......@@ -4415,26 +4417,39 @@ static void read_global_motion_params(WarpedMotionParams *params,
case VERTRAPEZOID:
if (type != HORTRAPEZOID)
params->wmmat[6] =
aom_read_primitive_symmetric(r, GM_ABS_ROW3HOMO_BITS) *
aom_read_signed_primitive_refsubexpfin(
r, GM_ROW3HOMO_MAX + 1, SUBEXPFIN_K,
(ref_params->wmmat[6] >> GM_ROW3HOMO_PREC_DIFF)) *
GM_ROW3HOMO_DECODE_FACTOR;
if (type != VERTRAPEZOID)
params->wmmat[7] =
aom_read_primitive_symmetric(r, GM_ABS_ROW3HOMO_BITS) *
aom_read_signed_primitive_refsubexpfin(
r, GM_ROW3HOMO_MAX + 1, SUBEXPFIN_K,
(ref_params->wmmat[7] >> GM_ROW3HOMO_PREC_DIFF)) *
GM_ROW3HOMO_DECODE_FACTOR;
case AFFINE:
case ROTZOOM:
params->wmmat[2] = aom_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) *
params->wmmat[2] = aom_read_signed_primitive_refsubexpfin(
r, GM_ALPHA_MAX + 1, SUBEXPFIN_K,
(ref_params->wmmat[2] >> GM_ALPHA_PREC_DIFF) -
(1 << GM_ALPHA_PREC_BITS)) *
GM_ALPHA_DECODE_FACTOR +
(1 << WARPEDMODEL_PREC_BITS);
if (type != VERTRAPEZOID)
params->wmmat[3] = aom_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) *
params->wmmat[3] = aom_read_signed_primitive_refsubexpfin(
r, GM_ALPHA_MAX + 1, SUBEXPFIN_K,
(ref_params->wmmat[3] >> GM_ALPHA_PREC_DIFF)) *
GM_ALPHA_DECODE_FACTOR;
if (type >= AFFINE) {
if (type != HORTRAPEZOID)
params->wmmat[4] =
aom_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) *
GM_ALPHA_DECODE_FACTOR;
params->wmmat[5] = aom_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) *
params->wmmat[4] = aom_read_signed_primitive_refsubexpfin(
r, GM_ALPHA_MAX + 1, SUBEXPFIN_K,
(ref_params->wmmat[4] >> GM_ALPHA_PREC_DIFF)) *
GM_ALPHA_DECODE_FACTOR;
params->wmmat[5] = aom_read_signed_primitive_refsubexpfin(
r, GM_ALPHA_MAX + 1, SUBEXPFIN_K,
(ref_params->wmmat[5] >> GM_ALPHA_PREC_DIFF) -
(1 << GM_ALPHA_PREC_BITS)) *
GM_ALPHA_DECODE_FACTOR +
(1 << WARPEDMODEL_PREC_BITS);
} else {
......@@ -4448,11 +4463,17 @@ static void read_global_motion_params(WarpedMotionParams *params,
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;
trans_prec_diff = (type == TRANSLATION)
? GM_TRANS_ONLY_PREC_DIFF + !allow_hp
: GM_TRANS_PREC_DIFF;
params->wmmat[0] = aom_read_signed_primitive_refsubexpfin(
r, (1 << trans_bits) + 1, SUBEXPFIN_K,
(ref_params->wmmat[0] >> trans_prec_diff)) *
trans_dec_factor;
params->wmmat[1] = aom_read_signed_primitive_refsubexpfin(
r, (1 << trans_bits) + 1, SUBEXPFIN_K,
(ref_params->wmmat[1] >> trans_prec_diff)) *
trans_dec_factor;
case IDENTITY: break;
default: assert(0);
}
......@@ -4463,9 +4484,9 @@ static void read_global_motion_params(WarpedMotionParams *params,
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->allow_high_precision_mv);
read_global_motion_params(
&cm->global_motion[frame], &cm->prev_frame->global_motion[frame],
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,
......@@ -4475,6 +4496,8 @@ static void read_global_motion(AV1_COMMON *cm, aom_reader *r) {
cm->global_motion[frame].wmmat[3]);
*/
}
memcpy(cm->cur_frame->global_motion, cm->global_motion,
TOTAL_REFS_PER_FRAME * sizeof(WarpedMotionParams));
}
#endif // CONFIG_GLOBAL_MOTION
......@@ -4824,6 +4847,11 @@ void av1_decode_frame(AV1Decoder *pbi, const uint8_t *data,
new_fb = get_frame_new_buffer(cm);
xd->cur_buf = new_fb;
#if CONFIG_GLOBAL_MOTION
int i;
for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
set_default_gmparams(&cm->global_motion[i]);
set_default_gmparams(&cm->cur_frame->global_motion[i]);
}
xd->global_motion = cm->global_motion;
#endif // CONFIG_GLOBAL_MOTION
......
......@@ -4598,6 +4598,7 @@ static void write_uncompressed_header(AV1_COMP *cpi,
#if CONFIG_GLOBAL_MOTION
static void write_global_motion_params(WarpedMotionParams *params,
WarpedMotionParams *ref_params,
aom_prob *probs, aom_writer *w,
int allow_hp) {
TransformationType type = params->wmtype;
......@@ -4610,31 +4611,40 @@ static void write_global_motion_params(WarpedMotionParams *params,
case HORTRAPEZOID:
case VERTRAPEZOID:
if (type != HORTRAPEZOID)
aom_write_primitive_symmetric(
w, (params->wmmat[6] >> GM_ROW3HOMO_PREC_DIFF),
GM_ABS_ROW3HOMO_BITS);
aom_write_signed_primitive_refsubexpfin(
w, GM_ROW3HOMO_MAX + 1, SUBEXPFIN_K,
(ref_params->wmmat[6] >> GM_ROW3HOMO_PREC_DIFF),
(params->wmmat[6] >> GM_ROW3HOMO_PREC_DIFF));
if (type != VERTRAPEZOID)
aom_write_primitive_symmetric(
w, (params->wmmat[7] >> GM_ROW3HOMO_PREC_DIFF),
GM_ABS_ROW3HOMO_BITS);
aom_write_signed_primitive_refsubexpfin(
w, GM_ROW3HOMO_MAX + 1, SUBEXPFIN_K,
(ref_params->wmmat[7] >> GM_ROW3HOMO_PREC_DIFF),
(params->wmmat[7] >> GM_ROW3HOMO_PREC_DIFF));
// fallthrough intended
case AFFINE:
case ROTZOOM:
aom_write_primitive_symmetric(
w,
(params->wmmat[2] >> GM_ALPHA_PREC_DIFF) - (1 << GM_ALPHA_PREC_BITS),
GM_ABS_ALPHA_BITS);
aom_write_signed_primitive_refsubexpfin(
w, GM_ALPHA_MAX + 1, SUBEXPFIN_K,
(ref_params->wmmat[2] >> GM_ALPHA_PREC_DIFF) -
(1 << GM_ALPHA_PREC_BITS),
(params->wmmat[2] >> GM_ALPHA_PREC_DIFF) - (1 << GM_ALPHA_PREC_BITS));
if (type != VERTRAPEZOID)
aom_write_primitive_symmetric(
w, (params->wmmat[3] >> GM_ALPHA_PREC_DIFF), GM_ABS_ALPHA_BITS);
aom_write_signed_primitive_refsubexpfin(
w, GM_ALPHA_MAX + 1, SUBEXPFIN_K,
(ref_params->wmmat[3] >> GM_ALPHA_PREC_DIFF),
(params->wmmat[3] >> GM_ALPHA_PREC_DIFF));
if (type >= AFFINE) {
if (type != HORTRAPEZOID)
aom_write_primitive_symmetric(
w, (params->wmmat[4] >> GM_ALPHA_PREC_DIFF), GM_ABS_ALPHA_BITS);
aom_write_primitive_symmetric(w,
(params->wmmat[5] >> GM_ALPHA_PREC_DIFF) -
(1 << GM_ALPHA_PREC_BITS),
GM_ABS_ALPHA_BITS);
aom_write_signed_primitive_refsubexpfin(
w, GM_ALPHA_MAX + 1, SUBEXPFIN_K,
(ref_params->wmmat[4] >> GM_ALPHA_PREC_DIFF),
(params->wmmat[4] >> GM_ALPHA_PREC_DIFF));
aom_write_signed_primitive_refsubexpfin(
w, GM_ALPHA_MAX + 1, SUBEXPFIN_K,
(ref_params->wmmat[5] >> GM_ALPHA_PREC_DIFF) -
(1 << GM_ALPHA_PREC_BITS),
(params->wmmat[5] >> GM_ALPHA_PREC_DIFF) -
(1 << GM_ALPHA_PREC_BITS));
}
// fallthrough intended
case TRANSLATION:
......@@ -4643,10 +4653,14 @@ static void write_global_motion_params(WarpedMotionParams *params,
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);
aom_write_signed_primitive_refsubexpfin(
w, (1 << trans_bits) + 1, SUBEXPFIN_K,
(ref_params->wmmat[0] >> trans_prec_diff),
(params->wmmat[0] >> trans_prec_diff));
aom_write_signed_primitive_refsubexpfin(
w, (1 << trans_bits) + 1, SUBEXPFIN_K,
(ref_params->wmmat[1] >> trans_prec_diff),
(params->wmmat[1] >> trans_prec_diff));
break;
case IDENTITY: break;
default: assert(0);
......@@ -4665,9 +4679,9 @@ static void write_global_motion(AV1_COMP *cpi, aom_writer *w) {
set_default_gmparams(&cm->global_motion[frame]);
}
#endif
write_global_motion_params(&cm->global_motion[frame],
cm->fc->global_motion_types_prob, w,
cm->allow_high_precision_mv);
write_global_motion_params(
&cm->global_motion[frame], &cm->prev_frame->global_motion[frame],
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,
......
......@@ -18,6 +18,7 @@
#include "./aom_config.h"
#include "aom_dsp/aom_dsp_common.h"
#include "aom_dsp/binary_codes_writer.h"
#include "aom_ports/mem.h"
#include "aom_ports/aom_timer.h"
#include "aom_ports/system_state.h"
......@@ -5022,36 +5023,65 @@ static int input_fpmb_stats(FIRSTPASS_MB_STATS *firstpass_mb_stats,
#endif
#if CONFIG_GLOBAL_MOTION
static int gm_get_params_cost(WarpedMotionParams *gm) {
static int gm_get_params_cost(WarpedMotionParams *gm,
WarpedMotionParams *ref_gm, int allow_hp) {
assert(gm->wmtype < GLOBAL_TRANS_TYPES);
int params_cost = 0;
int trans_bits, trans_prec_diff;
switch (gm->wmtype) {
case HOMOGRAPHY:
case HORTRAPEZOID:
case VERTRAPEZOID:
if (gm->wmtype != HORTRAPEZOID)
params_cost += gm->wmmat[6] == 0 ? 1 : (GM_ABS_ROW3HOMO_BITS + 2);
params_cost += aom_count_signed_primitive_refsubexpfin(
GM_ROW3HOMO_MAX + 1, SUBEXPFIN_K,
(ref_gm->wmmat[6] >> GM_ROW3HOMO_PREC_DIFF),
(gm->wmmat[6] >> GM_ROW3HOMO_PREC_DIFF));
if (gm->wmtype != VERTRAPEZOID)
params_cost += gm->wmmat[7] == 0 ? 1 : (GM_ABS_ROW3HOMO_BITS + 2);
params_cost += aom_count_signed_primitive_refsubexpfin(
GM_ROW3HOMO_MAX + 1, SUBEXPFIN_K,
(ref_gm->wmmat[7] >> GM_ROW3HOMO_PREC_DIFF),
(gm->wmmat[7] >> GM_ROW3HOMO_PREC_DIFF));
// Fallthrough intended
case AFFINE:
case ROTZOOM:
params_cost += gm->wmmat[2] == (1 << WARPEDMODEL_PREC_BITS)
? 1
: (GM_ABS_ALPHA_BITS + 2);
params_cost += aom_count_signed_primitive_refsubexpfin(
GM_ALPHA_MAX + 1, SUBEXPFIN_K,
(ref_gm->wmmat[2] >> GM_ALPHA_PREC_DIFF) - (1 << GM_ALPHA_PREC_BITS),
(gm->wmmat[2] >> GM_ALPHA_PREC_DIFF) - (1 << GM_ALPHA_PREC_BITS));
if (gm->wmtype != VERTRAPEZOID)
params_cost += gm->wmmat[3] == 0 ? 1 : (GM_ABS_ALPHA_BITS + 2);
params_cost += aom_count_signed_primitive_refsubexpfin(
GM_ALPHA_MAX + 1, SUBEXPFIN_K,
(ref_gm->wmmat[3] >> GM_ALPHA_PREC_DIFF),
(gm->wmmat[3] >> GM_ALPHA_PREC_DIFF));
if (gm->wmtype >= AFFINE) {
if (gm->wmtype != HORTRAPEZOID)
params_cost += gm->wmmat[4] == 0 ? 1 : (GM_ABS_ALPHA_BITS + 2);
params_cost += gm->wmmat[5] == (1 << WARPEDMODEL_PREC_BITS)
? 1
: (GM_ABS_ALPHA_BITS + 2);
params_cost += aom_count_signed_primitive_refsubexpfin(
GM_ALPHA_MAX + 1, SUBEXPFIN_K,
(ref_gm->wmmat[4] >> GM_ALPHA_PREC_DIFF),
(gm->wmmat[4] >> GM_ALPHA_PREC_DIFF));
params_cost += aom_count_signed_primitive_refsubexpfin(
GM_ALPHA_MAX + 1, SUBEXPFIN_K,
(ref_gm->wmmat[5] >> GM_ALPHA_PREC_DIFF) -
(1 << GM_ALPHA_PREC_BITS),
(gm->wmmat[5] >> GM_ALPHA_PREC_DIFF) - (1 << GM_ALPHA_PREC_BITS));
}
// Fallthrough intended
case TRANSLATION:
params_cost += gm->wmmat[0] == 0 ? 1 : (GM_ABS_TRANS_BITS + 2);
params_cost += gm->wmmat[1] == 0 ? 1 : (GM_ABS_TRANS_BITS + 2);
trans_bits = (gm->wmtype == TRANSLATION)
? GM_ABS_TRANS_ONLY_BITS - !allow_hp
: GM_ABS_TRANS_BITS;
trans_prec_diff = (gm->wmtype == TRANSLATION)
? GM_TRANS_ONLY_PREC_DIFF + !allow_hp
: GM_TRANS_PREC_DIFF;
params_cost += aom_count_signed_primitive_refsubexpfin(
(1 << trans_bits) + 1, SUBEXPFIN_K,
(ref_gm->wmmat[0] >> trans_prec_diff),
(gm->wmmat[0] >> trans_prec_diff));
params_cost += aom_count_signed_primitive_refsubexpfin(
(1 << trans_bits) + 1, SUBEXPFIN_K,
(ref_gm->wmmat[1] >> trans_prec_diff),
(gm->wmmat[1] >> trans_prec_diff));
// Fallthrough intended
case IDENTITY: break;
default: assert(0);
......@@ -5170,12 +5200,16 @@ static void encode_frame_internal(AV1_COMP *cpi) {
aom_clear_system_state();
}
cpi->gmparams_cost[frame] =
gm_get_params_cost(&cm->global_motion[frame]) +
gm_get_params_cost(&cm->global_motion[frame],
&cm->prev_frame->global_motion[frame],
cm->allow_high_precision_mv) +
cpi->gmtype_cost[cm->global_motion[frame].wmtype] -
cpi->gmtype_cost[IDENTITY];
}
cpi->global_motion_search_done = 1;
}
memcpy(cm->cur_frame->global_motion, cm->global_motion,
TOTAL_REFS_PER_FRAME * sizeof(WarpedMotionParams));
#endif // CONFIG_GLOBAL_MOTION
for (i = 0; i < MAX_SEGMENTS; ++i) {
......
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