Commit d7c8bd51 authored by David Barker's avatar David Barker Committed by Debargha Mukherjee

Fix global-motion + error-resilient-mode

Patch https://aomedia-review.googlesource.com/c/21783
changed things so that error-resilient frames use the default
global motion parameters as a reference, rather than taking
the reference from the previous frame.

This was implemented by clearing out cm->prev_frame->global_motion
when we have an error-resilient frame. Unfortunately, this causes
an issue: if we have an error resilient frame which isn't stored
into any reference slots, followed by a non-error-resilient frame,
then both frames refer to the same prev_frame. The second frame
then delta-codes against cm->prev_frame->global_motion, but
this was reset to the default values by the intervening
error-resilient frame!

In order to allow the above case to work as intended, expand the
default warp parameter set to a full WarpedMotionParams struct,
and use that as the reference for error-resilient frames.

This also allows us to remove set_default_warp_params, as we
can now just copy directly from default_warp_params.

Change-Id: I9645615db2700c1d3810e6e42f4f1da626fcd5e3
parent 886bfc7b
......@@ -120,14 +120,14 @@ typedef struct {
int16_t alpha, beta, gamma, delta;
} WarpedMotionParams;
static INLINE void set_default_warp_params(WarpedMotionParams *wm) {
static const int32_t default_wm_mat[8] = {
0, 0, (1 << WARPEDMODEL_PREC_BITS), 0, 0, (1 << WARPEDMODEL_PREC_BITS), 0, 0
};
memset(wm, 0, sizeof(*wm));
memcpy(wm->wmmat, default_wm_mat, sizeof(wm->wmmat));
wm->wmtype = IDENTITY;
}
/* clang-format off */
static const WarpedMotionParams default_warp_params = {
IDENTITY,
{ 0, 0, (1 << WARPEDMODEL_PREC_BITS), 0, 0, (1 << WARPEDMODEL_PREC_BITS), 0,
0 },
0, 0, 0, 0
};
/* clang-format on */
#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
#if CONFIG_GLOBAL_MOTION
......
......@@ -43,7 +43,7 @@ static INLINE int allow_warp(const MODE_INFO *const mi,
#endif // CONFIG_MOTION_VAR
WarpedMotionParams *final_warp_params) {
const MB_MODE_INFO *const mbmi = &mi->mbmi;
set_default_warp_params(final_warp_params);
*final_warp_params = default_warp_params;
// Only global motion configured
#if CONFIG_GLOBAL_MOTION && !CONFIG_WARPED_MOTION && !CONFIG_MOTION_VAR
......
......@@ -4480,7 +4480,7 @@ static void check_valid_ref_frames(AV1_COMMON *cm) {
#if CONFIG_GLOBAL_MOTION
static int read_global_motion_params(WarpedMotionParams *params,
WarpedMotionParams *ref_params,
const WarpedMotionParams *ref_params,
struct aom_read_bit_buffer *rb,
int allow_hp) {
TransformationType type = aom_rb_read_bit(rb);
......@@ -4498,7 +4498,7 @@ static int read_global_motion_params(WarpedMotionParams *params,
int trans_bits;
int trans_dec_factor;
int trans_prec_diff;
set_default_warp_params(params);
*params = default_warp_params;
params->wmtype = type;
switch (type) {
case HOMOGRAPHY:
......@@ -4577,11 +4577,11 @@ static int read_global_motion_params(WarpedMotionParams *params,
static void read_global_motion(AV1_COMMON *cm, struct aom_read_bit_buffer *rb) {
int frame;
for (frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame) {
if (cm->error_resilient_mode)
set_default_warp_params(&cm->prev_frame->global_motion[frame]);
const WarpedMotionParams *ref_params =
cm->error_resilient_mode ? &default_warp_params
: &cm->prev_frame->global_motion[frame];
int good_params = read_global_motion_params(
&cm->global_motion[frame], &cm->prev_frame->global_motion[frame], rb,
cm->allow_high_precision_mv);
&cm->global_motion[frame], ref_params, rb, cm->allow_high_precision_mv);
if (!good_params)
aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
"Invalid shear parameters for global motion.");
......@@ -4597,7 +4597,7 @@ static void read_global_motion(AV1_COMMON *cm, struct aom_read_bit_buffer *rb) {
&cm->prev_frame->global_motion[frame], rb,
cm->allow_high_precision_mv);
} else {
set_default_warp_params(&cm->global_motion[frame]);
cm->global_motion[frame] = default_warp_params;
}
*/
/*
......@@ -5456,8 +5456,8 @@ size_t av1_decode_frame_headers_and_setup(AV1Decoder *pbi, const uint8_t *data,
#if CONFIG_GLOBAL_MOTION
int i;
for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
set_default_warp_params(&cm->global_motion[i]);
set_default_warp_params(&cm->cur_frame->global_motion[i]);
cm->global_motion[i] = default_warp_params;
cm->cur_frame->global_motion[i] = default_warp_params;
}
xd->global_motion = cm->global_motion;
#endif // CONFIG_GLOBAL_MOTION
......
......@@ -4396,8 +4396,8 @@ static void write_compound_tools(const AV1_COMMON *cm,
}
#if CONFIG_GLOBAL_MOTION
static void write_global_motion_params(WarpedMotionParams *params,
WarpedMotionParams *ref_params,
static void write_global_motion_params(const WarpedMotionParams *params,
const WarpedMotionParams *ref_params,
struct aom_write_bit_buffer *wb,
int allow_hp) {
TransformationType type = params->wmtype;
......@@ -4480,10 +4480,10 @@ static void write_global_motion(AV1_COMP *cpi,
AV1_COMMON *const cm = &cpi->common;
int frame;
for (frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame) {
if (cm->error_resilient_mode)
set_default_warp_params(&cm->prev_frame->global_motion[frame]);
write_global_motion_params(&cm->global_motion[frame],
&cm->prev_frame->global_motion[frame], wb,
const WarpedMotionParams *ref_params =
cm->error_resilient_mode ? &default_warp_params
: &cm->prev_frame->global_motion[frame];
write_global_motion_params(&cm->global_motion[frame], ref_params, wb,
cm->allow_high_precision_mv);
// TODO(sarahparker, debargha): The logic in the commented out code below
// does not work currently and causes mismatches when resize is on.
......
......@@ -5081,8 +5081,8 @@ static int input_fpmb_stats(FIRSTPASS_MB_STATS *firstpass_mb_stats,
#if CONFIG_GLOBAL_MOTION
#define GLOBAL_TRANS_TYPES_ENC 3 // highest motion model to search
static int gm_get_params_cost(WarpedMotionParams *gm,
WarpedMotionParams *ref_gm, int allow_hp) {
static int gm_get_params_cost(const WarpedMotionParams *gm,
const WarpedMotionParams *ref_gm, int allow_hp) {
assert(gm->wmtype < GLOBAL_TRANS_TYPES);
int params_cost = 0;
int trans_bits, trans_prec_diff;
......@@ -5329,9 +5329,10 @@ static void encode_frame_internal(AV1_COMP *cpi) {
for (frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame) {
ref_buf[frame] = get_ref_frame_buffer(cpi, frame);
int pframe;
set_default_warp_params(&cm->global_motion[frame]);
if (cm->error_resilient_mode)
set_default_warp_params(&cm->prev_frame->global_motion[frame]);
cm->global_motion[frame] = default_warp_params;
const WarpedMotionParams *ref_params =
cm->error_resilient_mode ? &default_warp_params
: &cm->prev_frame->global_motion[frame];
// check for duplicate buffer
for (pframe = LAST_FRAME; pframe < frame; ++pframe) {
if (ref_buf[frame] == ref_buf[pframe]) break;
......@@ -5398,7 +5399,7 @@ static void encode_frame_internal(AV1_COMP *cpi) {
}
if (cm->global_motion[frame].wmtype <= AFFINE)
if (!get_shear_params(&cm->global_motion[frame]))
set_default_warp_params(&cm->global_motion[frame]);
cm->global_motion[frame] = default_warp_params;
if (cm->global_motion[frame].wmtype == TRANSLATION) {
cm->global_motion[frame].wmmat[0] =
......@@ -5415,10 +5416,9 @@ static void encode_frame_internal(AV1_COMP *cpi) {
// this motion type, revert to IDENTITY.
if (!is_enough_erroradvantage(
(double)best_warp_error / ref_frame_error,
gm_get_params_cost(&cm->global_motion[frame],
&cm->prev_frame->global_motion[frame],
gm_get_params_cost(&cm->global_motion[frame], ref_params,
cm->allow_high_precision_mv))) {
set_default_warp_params(&cm->global_motion[frame]);
cm->global_motion[frame] = default_warp_params;
}
if (cm->global_motion[frame].wmtype != IDENTITY) break;
}
......@@ -5426,8 +5426,7 @@ static void encode_frame_internal(AV1_COMP *cpi) {
}
if (cm->global_motion[frame].wmtype != IDENTITY) num_refs_using_gm++;
cpi->gmparams_cost[frame] =
gm_get_params_cost(&cm->global_motion[frame],
&cm->prev_frame->global_motion[frame],
gm_get_params_cost(&cm->global_motion[frame], ref_params,
cm->allow_high_precision_mv) +
cpi->gmtype_cost[cm->global_motion[frame].wmtype] -
cpi->gmtype_cost[IDENTITY];
......
......@@ -3507,7 +3507,7 @@ static int recode_loop_test_global_motion(AV1_COMP *cpi) {
if (cm->global_motion[i].wmtype != IDENTITY &&
rdc->global_motion_used[i] * GM_RECODE_LOOP_NUM4X4_FACTOR <
cpi->gmparams_cost[i]) {
set_default_warp_params(&cm->global_motion[i]);
cm->global_motion[i] = default_warp_params;
assert(cm->global_motion[i].wmtype == IDENTITY);
cpi->gmparams_cost[i] = 0;
recode = 1;
......@@ -4163,7 +4163,7 @@ static void set_size_independent_vars(AV1_COMP *cpi) {
#if CONFIG_GLOBAL_MOTION
int i;
for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
set_default_warp_params(&cpi->common.global_motion[i]);
cpi->common.global_motion[i] = default_warp_params;
}
cpi->global_motion_search_done = 0;
#endif // CONFIG_GLOBAL_MOTION
......
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