From: Sarah Parker Date: Tue, 2 Aug 2016 19:28:41 +0000 (-0700) Subject: Adjust gm parameter computation to avoid mismatch X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=aa810c002cbc12bb26d5b4b63510fdc39ada26dc;p=libvpx Adjust gm parameter computation to avoid mismatch The gm parameters need to have WARPED_PRECISION_BITS precision until they are written to the bitstream because functions in reconinter use these parameters before they are written to the bitstream. Previously, the parameters weren't being converted to WARPED_PRECISION_BITS until they were read from the bitstream which causes an encode/decode mismatch. Change-Id: I31e76e9d6f7d24df21af287a72f8c01f1997304d --- diff --git a/vp10/common/mv.h b/vp10/common/mv.h index f45f2ab49..aee31098e 100644 --- a/vp10/common/mv.h +++ b/vp10/common/mv.h @@ -50,31 +50,34 @@ typedef struct mv32 { // // The ABS parameters are used to create an upper and lower bound // for each parameter. In other words, after a parameter is integerized -// it is clamped between -(1 << ABS_XXX_BITS) and (1 << ABS_XXX_BITS) +// it is clamped between -(1 << ABS_XXX_BITS) and (1 << ABS_XXX_BITS). // -// XXX_PREC_DIFF and XXX_DECODE_FACTOR are computed once here to -// prevent repetetive computation on the decoder side. These are +// XXX_PREC_DIFF, XXX_ENCODE_FACTOR and XXX_DECODE_FACTOR +// are computed once here to prevent repetitive +// computation on the decoder side. These are // to allow the global motion parameters to be encoded in a lower // precision than the warped model precision. This means that they // need to be changed to warped precision when they are decoded. // // XX_MIN, XX_MAX are also computed to avoid repeated computation -#define GM_TRANS_PREC_BITS 3 -#define GM_TRANS_PREC_DIFF (WARPEDMODEL_PREC_BITS - GM_TRANS_PREC_BITS) -#define GM_TRANS_DECODE_FACTOR (1 << GM_TRANS_PREC_DIFF) +#define GM_TRANS_PREC_BITS 5 +#define GM_TRANS_PREC_DIFF (WARPEDMODEL_PREC_BITS - GM_TRANS_PREC_BITS) +#define GM_TRANS_DECODE_FACTOR (1 << GM_TRANS_PREC_DIFF) +#define GM_TRANS_ENCODE_FACTOR (1 / (GM_TRANS_DECODE_FACTOR)) -#define GM_ALPHA_PREC_BITS 5 -#define GM_ALPHA_PREC_DIFF (WARPEDMODEL_PREC_BITS - GM_ALPHA_PREC_BITS) -#define GM_ALPHA_DECODE_FACTOR (1 << GM_ALPHA_PREC_DIFF) +#define GM_ALPHA_PREC_BITS 5 +#define GM_ALPHA_PREC_DIFF (WARPEDMODEL_PREC_BITS - GM_ALPHA_PREC_BITS) +#define GM_ALPHA_DECODE_FACTOR (1 << GM_ALPHA_PREC_DIFF) +#define GM_ALPHA_ENCODE_FACTOR (1 / (GM_ALPHA_DECODE_FACTOR)) -#define GM_ABS_ALPHA_BITS 5 -#define GM_ABS_TRANS_BITS 5 +#define GM_ABS_ALPHA_BITS 8 +#define GM_ABS_TRANS_BITS 8 -#define GM_TRANS_MAX (1 << GM_ABS_TRANS_BITS) -#define GM_ALPHA_MAX (1 << GM_ABS_ALPHA_BITS) -#define GM_TRANS_MIN -GM_TRANS_MAX -#define GM_ALPHA_MIN -GM_ALPHA_MAX +#define GM_TRANS_MAX (1 << GM_ABS_TRANS_BITS) +#define GM_ALPHA_MAX (1 << GM_ABS_ALPHA_BITS) +#define GM_TRANS_MIN -GM_TRANS_MAX +#define GM_ALPHA_MIN -GM_ALPHA_MAX typedef enum { GLOBAL_ZERO = 0, diff --git a/vp10/decoder/decodeframe.c b/vp10/decoder/decodeframe.c index 3a51a48ce..ec04e5677 100644 --- a/vp10/decoder/decodeframe.c +++ b/vp10/decoder/decodeframe.c @@ -3473,6 +3473,7 @@ static void read_global_motion_params(Global_Motion_Params *params, params->motion_params.wmmat[5] = vp10_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) * GM_ALPHA_DECODE_FACTOR; + // fallthrough intended case GLOBAL_ROTZOOM: params->motion_params.wmmat[2] = (vp10_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) * @@ -3480,6 +3481,7 @@ static void read_global_motion_params(Global_Motion_Params *params, params->motion_params.wmmat[3] = vp10_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) * GM_ALPHA_DECODE_FACTOR; + // fallthrough intended case GLOBAL_TRANSLATION: params->motion_params.wmmat[0] = vp10_read_primitive_symmetric(r, GM_ABS_TRANS_BITS) * diff --git a/vp10/encoder/bitstream.c b/vp10/encoder/bitstream.c index 558bafb51..e0427cc94 100644 --- a/vp10/encoder/bitstream.c +++ b/vp10/encoder/bitstream.c @@ -3200,19 +3200,29 @@ static void write_global_motion_params(Global_Motion_Params *params, case GLOBAL_ZERO: break; case GLOBAL_AFFINE: - vp10_write_primitive_symmetric(w, params->motion_params.wmmat[4], + vp10_write_primitive_symmetric(w, (params->motion_params.wmmat[4] * + GM_ALPHA_ENCODE_FACTOR) - + (1 << GM_ALPHA_PREC_BITS), GM_ABS_ALPHA_BITS); - vp10_write_primitive_symmetric(w, params->motion_params.wmmat[5], + vp10_write_primitive_symmetric(w, params->motion_params.wmmat[5] * + GM_ALPHA_ENCODE_FACTOR, GM_ABS_ALPHA_BITS); + // fallthrough intended case GLOBAL_ROTZOOM: - vp10_write_primitive_symmetric(w, params->motion_params.wmmat[2], + vp10_write_primitive_symmetric(w, (params->motion_params.wmmat[2] * + GM_ALPHA_ENCODE_FACTOR) - + (1 << GM_ALPHA_PREC_BITS), GM_ABS_ALPHA_BITS); - vp10_write_primitive_symmetric(w, params->motion_params.wmmat[3], + vp10_write_primitive_symmetric(w, params->motion_params.wmmat[3] * + GM_ALPHA_ENCODE_FACTOR, GM_ABS_ALPHA_BITS); + // fallthrough intended case GLOBAL_TRANSLATION: - vp10_write_primitive_symmetric(w, params->motion_params.wmmat[0], + vp10_write_primitive_symmetric(w, params->motion_params.wmmat[0] * + GM_TRANS_ENCODE_FACTOR, GM_ABS_TRANS_BITS); - vp10_write_primitive_symmetric(w, params->motion_params.wmmat[1], + vp10_write_primitive_symmetric(w, params->motion_params.wmmat[1] * + GM_TRANS_ENCODE_FACTOR, GM_ABS_TRANS_BITS); break; default: diff --git a/vp10/encoder/encodeframe.c b/vp10/encoder/encodeframe.c index ed7e14982..0389dcf27 100644 --- a/vp10/encoder/encodeframe.c +++ b/vp10/encoder/encodeframe.c @@ -4549,18 +4549,20 @@ static void convert_to_params(double *H, TransformationType type, (1 << GM_TRANS_PREC_BITS) + 0.5); model->motion_params.wmmat[0] = clamp(model->motion_params.wmmat[0], - GM_TRANS_MIN, GM_TRANS_MAX); + GM_TRANS_MIN, GM_TRANS_MAX) * + GM_TRANS_DECODE_FACTOR; model->motion_params.wmmat[1] = clamp(model->motion_params.wmmat[1], - GM_TRANS_MIN, GM_TRANS_MAX); + GM_TRANS_MIN, GM_TRANS_MAX) * + GM_TRANS_DECODE_FACTOR; for (i = 2; i < n_params; ++i) { model->motion_params.wmmat[i] = (int) floor(H[i] * - (1 << GM_ALPHA_PREC_BITS) + 0.5) - - (!(i & 1) * (1 << GM_ALPHA_PREC_BITS)); + (1 << GM_ALPHA_PREC_BITS) + 0.5); model->motion_params.wmmat[i] = clamp(model->motion_params.wmmat[i], - GM_ALPHA_MIN, GM_ALPHA_MAX); + GM_ALPHA_MIN, GM_ALPHA_MAX) * + GM_ALPHA_DECODE_FACTOR; alpha_present |= (model->motion_params.wmmat[i] != 0); } @@ -4579,6 +4581,7 @@ static void convert_model_to_params(double *H, TransformationType type, if (type > HOMOGRAPHY) convert_to_params(H, type, model); model->gmtype = get_gmtype(model); + model->motion_params.wmtype = gm_to_trans_type(model->gmtype); } #endif // CONFIG_GLOBAL_MOTION @@ -4610,7 +4613,7 @@ static void encode_frame_internal(VP10_COMP *cpi) { int frame; double H[9] = {0, 0, 0, 0, 0, 0, 0, 0, 1}; for (frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame) - convert_model_to_params(H, ROTZOOM, &cm->global_motion[frame]); + convert_model_to_params(H, AFFINE, &cm->global_motion[frame]); } #endif // CONFIG_GLOBAL_MOTION