Commit 94b876f4 authored by David Barker's avatar David Barker

Fix an edge case with global motion / warped motion

There is a rare edge case in ransac(), causing the tests
AV1/DatarateTestLarge.ChangingDropFrameThresh/{4,5,6}
to fail when global motion is enabled. The sequence of events is:

* Since GLOBAL_MOTION_TYPES = 3, we try to generate a ROTZOOM model
* A model is generated at ransac.c:215, and its first 4 components
  are copied to best_params. The last four components of best_params
  are left as {0, 1, 0, 0}.
* We then finish the trial_count loop, and call find_transformation
  one final time to generate a refined model. But this fails, and
  best_params is not overwritten.
* get_wmtype decides that this is an AFFINE model, since
  wmmat[4] != -wmmat[3] and wmmat[5] != wmmat[2].
* We try to encode this global motion model. But the entropy coder
  cannot encode an AFFINE model, and crashes at daalaboolwriter.h:74
  (with OD_ASSERT(symb != -1))

The fix is to copy 8 entries to best_params regardless of the
model type we are generating, in line with the changes in
https://aomedia-review.googlesource.com/#/c/5589/

Change-Id: I6dbdfb997924f8ddf7ea3a1d557463264ea63cbe
parent 949097c3
......@@ -118,7 +118,7 @@ static int get_rand_indices(int npoints, int minpts, int *indices,
static int ransac(double *matched_points, int npoints, int *number_of_inliers,
int *best_inlier_mask, double *best_params, const int minpts,
const int paramdim, IsDegenerateFunc is_degenerate,
IsDegenerateFunc is_degenerate,
FindTransformationFunc find_transformation,
ProjectPointsDoubleFunc projectpoints) {
static const double inlier_threshold = 1.0;
......@@ -248,7 +248,9 @@ static int ransac(double *matched_points, int npoints, int *number_of_inliers,
(num_inliers == max_inliers && variance < best_variance)) {
best_variance = variance;
max_inliers = num_inliers;
memcpy(best_params, params, paramdim * sizeof(*best_params));
// Save parameters, excluding the implicit '1' in the bottom-right
// entry of the parameter matrix
memcpy(best_params, params, (MAX_PARAMDIM - 1) * sizeof(*best_params));
memcpy(best_inlier_set1, inlier_set1,
num_inliers * 2 * sizeof(*best_inlier_set1));
memcpy(best_inlier_set2, inlier_set2,
......@@ -308,21 +310,21 @@ int ransac_translation(double *matched_points, int npoints,
int *number_of_inliers, int *best_inlier_mask,
double *best_params) {
return ransac(matched_points, npoints, number_of_inliers, best_inlier_mask,
best_params, 3, 2, is_degenerate_translation, find_translation,
best_params, 3, is_degenerate_translation, find_translation,
project_points_double_translation);
}
int ransac_rotzoom(double *matched_points, int npoints, int *number_of_inliers,
int *best_inlier_mask, double *best_params) {
return ransac(matched_points, npoints, number_of_inliers, best_inlier_mask,
best_params, 3, 4, is_degenerate_affine, find_rotzoom,
best_params, 3, is_degenerate_affine, find_rotzoom,
project_points_double_rotzoom);
}
int ransac_affine(double *matched_points, int npoints, int *number_of_inliers,
int *best_inlier_mask, double *best_params) {
return ransac(matched_points, npoints, number_of_inliers, best_inlier_mask,
best_params, 3, 6, is_degenerate_affine, find_affine,
best_params, 3, is_degenerate_affine, find_affine,
project_points_double_affine);
}
......@@ -330,6 +332,6 @@ int ransac_homography(double *matched_points, int npoints,
int *number_of_inliers, int *best_inlier_mask,
double *best_params) {
return ransac(matched_points, npoints, number_of_inliers, best_inlier_mask,
best_params, 4, 8, is_degenerate_homography, find_homography,
best_params, 4, is_degenerate_homography, find_homography,
project_points_double_homography);
}
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