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