Fix interaction of WARP_DELTA and EXT_WARP_FILTER Change WARP_DELTA logic so that it handles the edges of the model range allowed by av1_reduce_warp_model(). No change of output when CONFIG_EXT_WARP_FILTER == 0; fixes some rare mismatches when CONFIG_EXT_WARP_FILTER == 1
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c index a07a261..d861e7a 100644 --- a/av1/encoder/bitstream.c +++ b/av1/encoder/bitstream.c
@@ -448,6 +448,9 @@ int coded_value = (value / WARP_DELTA_STEP) + WARP_DELTA_CODED_MAX; assert(0 <= coded_value && coded_value < WARP_DELTA_NUM_SYMBOLS); + // Check that the decoder will receive the correct value + assert((coded_value - WARP_DELTA_CODED_MAX) * WARP_DELTA_STEP == value); + aom_write_symbol(w, coded_value, xd->tile_ctx->warp_delta_param_cdf[index_type], WARP_DELTA_NUM_SYMBOLS);
diff --git a/av1/encoder/mcomp.c b/av1/encoder/mcomp.c index 601e6b5..4687d81 100644 --- a/av1/encoder/mcomp.c +++ b/av1/encoder/mcomp.c
@@ -5559,16 +5559,36 @@ } for (int param_index = 2; param_index < 4; param_index++) { + // Calculate the same range as av1_reduce_warp_model(), as we should + // reject any model which lies outside the clamping range. + int offset = (param_index == 2 || param_index == 5) + ? (1 << WARPEDMODEL_PREC_BITS) + : 0; +#if CONFIG_EXT_WARP_FILTER + const int max_value = + (1 << (WARPEDMODEL_PREC_BITS - 1)) - (1 << WARP_PARAM_REDUCE_BITS); + const int min_value = -max_value; +#else + const int min_value = -(1 << (WARPEDMODEL_PREC_BITS - 1)); + const int max_value = + (1 << (WARPEDMODEL_PREC_BITS - 1)) - (1 << WARP_PARAM_REDUCE_BITS); +#endif // CONFIG_EXT_WARP_FILTER + // Try increasing the parameter *params = best_wm_params; params->wmmat[param_index] += step_size; + assert(params->wmmat[param_index] - offset >= min_value); delta = params->wmmat[param_index] - base_params.wmmat[param_index]; if (abs(delta) > WARP_DELTA_MAX) { + // Reject values we can't encode + inc_rd = UINT64_MAX; + } else if (params->wmmat[param_index] - offset > max_value) { + // Reject models which are outside the range allowed by + // av1_reduce_warp_model() inc_rd = UINT64_MAX; } else { params->wmmat[4] = -params->wmmat[3]; params->wmmat[5] = params->wmmat[2]; - av1_reduce_warp_model(params); valid = av1_get_shear_params(params); params->invalid = !valid; if (valid) { @@ -5589,13 +5609,18 @@ // Try decreasing the parameter *params = best_wm_params; params->wmmat[param_index] -= step_size; + assert(params->wmmat[param_index] - offset <= max_value); delta = params->wmmat[param_index] - base_params.wmmat[param_index]; if (abs(delta) > WARP_DELTA_MAX) { + // Reject values we can't encode + dec_rd = UINT64_MAX; + } else if (params->wmmat[param_index] - offset < min_value) { + // Reject models which are outside the range allowed by + // av1_reduce_warp_model() dec_rd = UINT64_MAX; } else { params->wmmat[4] = -params->wmmat[3]; params->wmmat[5] = params->wmmat[2]; - av1_reduce_warp_model(params); valid = av1_get_shear_params(params); params->invalid = !valid; if (valid) {