|  | @@ -45,7 +45,6 @@ | 
														
													
														
															
																|  |  | * the use of this software, even if advised of the possibility of such damage. |  |  | * the use of this software, even if advised of the possibility of such damage. | 
														
													
														
															
																|  |  | */ |  |  | */ | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | #include <stdbool.h> |  |  |  | 
														
													
														
															
																|  |  | #include <float.h> |  |  | #include <float.h> | 
														
													
														
															
																|  |  | #include <libavutil/lfg.h> |  |  | #include <libavutil/lfg.h> | 
														
													
														
															
																|  |  | #include "libavutil/opt.h" |  |  | #include "libavutil/opt.h" | 
														
													
												
													
														
															
																|  | @@ -205,7 +204,7 @@ typedef struct DeshakeOpenCLContext { | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | // These variables are used in the activate callback |  |  | // These variables are used in the activate callback | 
														
													
														
															
																|  |  | int64_t duration; |  |  | int64_t duration; | 
														
													
														
															
																|  |  | bool eof; |  |  |  | 
														
													
														
															
																|  |  |  |  |  | int eof; | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | // State for random number generation |  |  | // State for random number generation | 
														
													
														
															
																|  |  | AVLFG alfg; |  |  | AVLFG alfg; | 
														
													
												
													
														
															
																|  | @@ -233,7 +232,7 @@ typedef struct DeshakeOpenCLContext { | 
														
													
														
															
																|  |  | CropInfo crop_uv; |  |  | CropInfo crop_uv; | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | // Whether or not we are processing YUV input (as oppposed to RGB) |  |  | // Whether or not we are processing YUV input (as oppposed to RGB) | 
														
													
														
															
																|  |  | bool is_yuv; |  |  |  | 
														
													
														
															
																|  |  |  |  |  | int is_yuv; | 
														
													
														
															
																|  |  | // The underlying format of the hardware surfaces |  |  | // The underlying format of the hardware surfaces | 
														
													
														
															
																|  |  | int sw_format; |  |  | int sw_format; | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
												
													
														
															
																|  | @@ -357,7 +356,7 @@ static void run_estimate_kernel(const MotionVector *point_pairs, double *model) | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | // Checks that the 3 points in the given array are not collinear |  |  | // Checks that the 3 points in the given array are not collinear | 
														
													
														
															
																|  |  | static bool points_not_collinear(const cl_float2 **points) |  |  |  | 
														
													
														
															
																|  |  |  |  |  | static int points_not_collinear(const cl_float2 **points) | 
														
													
														
															
																|  |  | { |  |  | { | 
														
													
														
															
																|  |  | int j, k, i = 2; |  |  | int j, k, i = 2; | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
												
													
														
															
																|  | @@ -373,17 +372,17 @@ static bool points_not_collinear(const cl_float2 **points) | 
														
													
														
															
																|  |  | // (3839, 2159), this prevents a third point from being within roughly |  |  | // (3839, 2159), this prevents a third point from being within roughly | 
														
													
														
															
																|  |  | // 0.5 of a pixel of the line connecting the two on both axes |  |  | // 0.5 of a pixel of the line connecting the two on both axes | 
														
													
														
															
																|  |  | if (fabs(dx2*dy1 - dy2*dx1) <= 1.0) { |  |  | if (fabs(dx2*dy1 - dy2*dx1) <= 1.0) { | 
														
													
														
															
																|  |  | return false; |  |  |  | 
														
													
														
															
																|  |  |  |  |  | return 0; | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | return true; |  |  |  | 
														
													
														
															
																|  |  |  |  |  | return 1; | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | // Checks a subset of 3 point pairs to make sure that the points are not collinear |  |  | // Checks a subset of 3 point pairs to make sure that the points are not collinear | 
														
													
														
															
																|  |  | // and not too close to each other |  |  | // and not too close to each other | 
														
													
														
															
																|  |  | static bool check_subset(const MotionVector *pairs_subset) |  |  |  | 
														
													
														
															
																|  |  |  |  |  | static int check_subset(const MotionVector *pairs_subset) | 
														
													
														
															
																|  |  | { |  |  | { | 
														
													
														
															
																|  |  | const cl_float2 *prev_points[] = { |  |  | const cl_float2 *prev_points[] = { | 
														
													
														
															
																|  |  | &pairs_subset[0].p.p1, |  |  | &pairs_subset[0].p.p1, | 
														
													
												
													
														
															
																|  | @@ -401,7 +400,7 @@ static bool check_subset(const MotionVector *pairs_subset) | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | // Selects a random subset of 3 points from point_pairs and places them in pairs_subset |  |  | // Selects a random subset of 3 points from point_pairs and places them in pairs_subset | 
														
													
														
															
																|  |  | static bool get_subset( |  |  |  | 
														
													
														
															
																|  |  |  |  |  | static int get_subset( | 
														
													
														
															
																|  |  | AVLFG *alfg, |  |  | AVLFG *alfg, | 
														
													
														
															
																|  |  | const MotionVector *point_pairs, |  |  | const MotionVector *point_pairs, | 
														
													
														
															
																|  |  | const int num_point_pairs, |  |  | const int num_point_pairs, | 
														
													
												
													
														
															
																|  | @@ -482,10 +481,10 @@ static int find_inliers( | 
														
													
														
															
																|  |  | for (i = 0; i < n; i++) { |  |  | for (i = 0; i < n; i++) { | 
														
													
														
															
																|  |  | if (err[i] <= t) { |  |  | if (err[i] <= t) { | 
														
													
														
															
																|  |  | // This is an inlier |  |  | // This is an inlier | 
														
													
														
															
																|  |  | point_pairs[i].should_consider = true; |  |  |  | 
														
													
														
															
																|  |  |  |  |  | point_pairs[i].should_consider = 1; | 
														
													
														
															
																|  |  | num_inliers += 1; |  |  | num_inliers += 1; | 
														
													
														
															
																|  |  | } else { |  |  | } else { | 
														
													
														
															
																|  |  | point_pairs[i].should_consider = false; |  |  |  | 
														
													
														
															
																|  |  |  |  |  | point_pairs[i].should_consider = 0; | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
												
													
														
															
																|  | @@ -525,7 +524,7 @@ static int ransac_update_num_iters(double confidence, double num_outliers, int m | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | // Estimates an affine transform between the given pairs of points using RANdom |  |  | // Estimates an affine transform between the given pairs of points using RANdom | 
														
													
														
															
																|  |  | // SAmple Consensus |  |  | // SAmple Consensus | 
														
													
														
															
																|  |  | static bool estimate_affine_2d( |  |  |  | 
														
													
														
															
																|  |  |  |  |  | static int estimate_affine_2d( | 
														
													
														
															
																|  |  | DeshakeOpenCLContext *deshake_ctx, |  |  | DeshakeOpenCLContext *deshake_ctx, | 
														
													
														
															
																|  |  | MotionVector *point_pairs, |  |  | MotionVector *point_pairs, | 
														
													
														
															
																|  |  | DebugMatches *debug_matches, |  |  | DebugMatches *debug_matches, | 
														
													
												
													
														
															
																|  | @@ -535,7 +534,7 @@ static bool estimate_affine_2d( | 
														
													
														
															
																|  |  | const int max_iters, |  |  | const int max_iters, | 
														
													
														
															
																|  |  | const double confidence |  |  | const double confidence | 
														
													
														
															
																|  |  | ) { |  |  | ) { | 
														
													
														
															
																|  |  | bool result = false; |  |  |  | 
														
													
														
															
																|  |  |  |  |  | int result = 0; | 
														
													
														
															
																|  |  | double best_model[6], model[6]; |  |  | double best_model[6], model[6]; | 
														
													
														
															
																|  |  | MotionVector pairs_subset[3], best_pairs[3]; |  |  | MotionVector pairs_subset[3], best_pairs[3]; | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
												
													
														
															
																|  | @@ -544,24 +543,24 @@ static bool estimate_affine_2d( | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | // We need at least 3 points to build a model from |  |  | // We need at least 3 points to build a model from | 
														
													
														
															
																|  |  | if (num_point_pairs < 3) { |  |  | if (num_point_pairs < 3) { | 
														
													
														
															
																|  |  | return false; |  |  |  | 
														
													
														
															
																|  |  |  |  |  | return 0; | 
														
													
														
															
																|  |  | } else if (num_point_pairs == 3) { |  |  | } else if (num_point_pairs == 3) { | 
														
													
														
															
																|  |  | // There are only 3 points, so RANSAC doesn't apply here |  |  | // There are only 3 points, so RANSAC doesn't apply here | 
														
													
														
															
																|  |  | run_estimate_kernel(point_pairs, model_out); |  |  | run_estimate_kernel(point_pairs, model_out); | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | for (int i = 0; i < 3; ++i) { |  |  | for (int i = 0; i < 3; ++i) { | 
														
													
														
															
																|  |  | point_pairs[i].should_consider = true; |  |  |  | 
														
													
														
															
																|  |  |  |  |  | point_pairs[i].should_consider = 1; | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | return true; |  |  |  | 
														
													
														
															
																|  |  |  |  |  | return 1; | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | for (iter = 0; iter < niters; ++iter) { |  |  | for (iter = 0; iter < niters; ++iter) { | 
														
													
														
															
																|  |  | bool found = get_subset(&deshake_ctx->alfg, point_pairs, num_point_pairs, pairs_subset, 10000); |  |  |  | 
														
													
														
															
																|  |  |  |  |  | int found = get_subset(&deshake_ctx->alfg, point_pairs, num_point_pairs, pairs_subset, 10000); | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | if (!found) { |  |  | if (!found) { | 
														
													
														
															
																|  |  | if (iter == 0) { |  |  | if (iter == 0) { | 
														
													
														
															
																|  |  | return false; |  |  |  | 
														
													
														
															
																|  |  |  |  |  | return 0; | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | break; |  |  | break; | 
														
													
												
													
														
															
																|  | @@ -600,7 +599,7 @@ static bool estimate_affine_2d( | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | // Find the inliers again for the best model for debugging |  |  | // Find the inliers again for the best model for debugging | 
														
													
														
															
																|  |  | find_inliers(point_pairs, num_point_pairs, best_model, deshake_ctx->ransac_err, threshold); |  |  | find_inliers(point_pairs, num_point_pairs, best_model, deshake_ctx->ransac_err, threshold); | 
														
													
														
															
																|  |  | result = true; |  |  |  | 
														
													
														
															
																|  |  |  |  |  | result = 1; | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | return result; |  |  | return result; | 
														
													
												
													
														
															
																|  | @@ -618,7 +617,7 @@ static void optimize_model( | 
														
													
														
															
																|  |  | ) { |  |  | ) { | 
														
													
														
															
																|  |  | float move_x_val = 0.01; |  |  | float move_x_val = 0.01; | 
														
													
														
															
																|  |  | float move_y_val = 0.01; |  |  | float move_y_val = 0.01; | 
														
													
														
															
																|  |  | bool move_x = true; |  |  |  | 
														
													
														
															
																|  |  |  |  |  | int move_x = 1; | 
														
													
														
															
																|  |  | float old_move_x_val = 0; |  |  | float old_move_x_val = 0; | 
														
													
														
															
																|  |  | double model[6]; |  |  | double model[6]; | 
														
													
														
															
																|  |  | int last_changed = 0; |  |  | int last_changed = 0; | 
														
													
												
													
														
															
																|  | @@ -668,9 +667,9 @@ static void optimize_model( | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | if (old_move_x_val < 0) { |  |  | if (old_move_x_val < 0) { | 
														
													
														
															
																|  |  | move_x = false; |  |  |  | 
														
													
														
															
																|  |  |  |  |  | move_x = 0; | 
														
													
														
															
																|  |  | } else { |  |  | } else { | 
														
													
														
															
																|  |  | move_x = true; |  |  |  | 
														
													
														
															
																|  |  |  |  |  | move_x = 1; | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
												
													
														
															
																|  | @@ -681,7 +680,7 @@ static void optimize_model( | 
														
													
														
															
																|  |  | // |  |  | // | 
														
													
														
															
																|  |  | // (Pick random subsets, compute model, find total error, iterate until error |  |  | // (Pick random subsets, compute model, find total error, iterate until error | 
														
													
														
															
																|  |  | // is minimized.) |  |  | // is minimized.) | 
														
													
														
															
																|  |  | static bool minimize_error( |  |  |  | 
														
													
														
															
																|  |  |  |  |  | static int minimize_error( | 
														
													
														
															
																|  |  | DeshakeOpenCLContext *deshake_ctx, |  |  | DeshakeOpenCLContext *deshake_ctx, | 
														
													
														
															
																|  |  | MotionVector *inliers, |  |  | MotionVector *inliers, | 
														
													
														
															
																|  |  | DebugMatches *debug_matches, |  |  | DebugMatches *debug_matches, | 
														
													
												
													
														
															
																|  | @@ -689,18 +688,18 @@ static bool minimize_error( | 
														
													
														
															
																|  |  | double *model_out, |  |  | double *model_out, | 
														
													
														
															
																|  |  | const int max_iters |  |  | const int max_iters | 
														
													
														
															
																|  |  | ) { |  |  | ) { | 
														
													
														
															
																|  |  | bool result = false; |  |  |  | 
														
													
														
															
																|  |  |  |  |  | int result = 0; | 
														
													
														
															
																|  |  | float best_err = FLT_MAX; |  |  | float best_err = FLT_MAX; | 
														
													
														
															
																|  |  | double best_model[6], model[6]; |  |  | double best_model[6], model[6]; | 
														
													
														
															
																|  |  | MotionVector pairs_subset[3], best_pairs[3]; |  |  | MotionVector pairs_subset[3], best_pairs[3]; | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | for (int i = 0; i < max_iters; i++) { |  |  | for (int i = 0; i < max_iters; i++) { | 
														
													
														
															
																|  |  | float total_err = 0; |  |  | float total_err = 0; | 
														
													
														
															
																|  |  | bool found = get_subset(&deshake_ctx->alfg, inliers, num_inliers, pairs_subset, 10000); |  |  |  | 
														
													
														
															
																|  |  |  |  |  | int found = get_subset(&deshake_ctx->alfg, inliers, num_inliers, pairs_subset, 10000); | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | if (!found) { |  |  | if (!found) { | 
														
													
														
															
																|  |  | if (i == 0) { |  |  | if (i == 0) { | 
														
													
														
															
																|  |  | return false; |  |  |  | 
														
													
														
															
																|  |  |  |  |  | return 0; | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | break; |  |  | break; | 
														
													
												
													
														
															
																|  | @@ -734,7 +733,7 @@ static bool minimize_error( | 
														
													
														
															
																|  |  | debug_matches->model_matches[pi] = best_pairs[pi]; |  |  | debug_matches->model_matches[pi] = best_pairs[pi]; | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | debug_matches->num_model_matches = 3; |  |  | debug_matches->num_model_matches = 3; | 
														
													
														
															
																|  |  | result = true; |  |  |  | 
														
													
														
															
																|  |  |  |  |  | result = 1; | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | optimize_model(deshake_ctx, best_pairs, inliers, num_inliers, best_err, model_out); |  |  | optimize_model(deshake_ctx, best_pairs, inliers, num_inliers, best_err, model_out); | 
														
													
														
															
																|  |  | return result; |  |  | return result; | 
														
													
												
													
														
															
																|  | @@ -1170,7 +1169,7 @@ static int deshake_opencl_init(AVFilterContext *avctx) | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | ff_framequeue_global_init(&fqg); |  |  | ff_framequeue_global_init(&fqg); | 
														
													
														
															
																|  |  | ff_framequeue_init(&ctx->fq, &fqg); |  |  | ff_framequeue_init(&ctx->fq, &fqg); | 
														
													
														
															
																|  |  | ctx->eof = false; |  |  |  | 
														
													
														
															
																|  |  |  |  |  | ctx->eof = 0; | 
														
													
														
															
																|  |  | ctx->smooth_window = (int)(av_q2d(avctx->inputs[0]->frame_rate) * ctx->smooth_window_multiplier); |  |  | ctx->smooth_window = (int)(av_q2d(avctx->inputs[0]->frame_rate) * ctx->smooth_window_multiplier); | 
														
													
														
															
																|  |  | ctx->curr_frame = 0; |  |  | ctx->curr_frame = 0; | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
												
													
														
															
																|  | @@ -1262,9 +1261,9 @@ static int deshake_opencl_init(AVFilterContext *avctx) | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | if (desc->flags & AV_PIX_FMT_FLAG_RGB) { |  |  | if (desc->flags & AV_PIX_FMT_FLAG_RGB) { | 
														
													
														
															
																|  |  | ctx->is_yuv = false; |  |  |  | 
														
													
														
															
																|  |  |  |  |  | ctx->is_yuv = 0; | 
														
													
														
															
																|  |  | } else { |  |  | } else { | 
														
													
														
															
																|  |  | ctx->is_yuv = true; |  |  |  | 
														
													
														
															
																|  |  |  |  |  | ctx->is_yuv = 1; | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | ctx->sw_format = hw_frames_ctx->sw_format; |  |  | ctx->sw_format = hw_frames_ctx->sw_format; | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
												
													
														
															
																|  | @@ -1971,7 +1970,7 @@ no_motion_data: | 
														
													
														
															
																|  |  | new_vals[RingbufScaleY] = 1.0f; |  |  | new_vals[RingbufScaleY] = 1.0f; | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | for (int i = 0; i < num_vectors; i++) { |  |  | for (int i = 0; i < num_vectors; i++) { | 
														
													
														
															
																|  |  | deshake_ctx->matches_contig_host[i].should_consider = false; |  |  |  | 
														
													
														
															
																|  |  |  |  |  | deshake_ctx->matches_contig_host[i].should_consider = 0; | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | debug_matches.num_model_matches = 0; |  |  | debug_matches.num_model_matches = 0; | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
												
													
														
															
																|  | @@ -2085,7 +2084,7 @@ static int activate(AVFilterContext *ctx) | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | if (!deshake_ctx->eof && ff_inlink_acknowledge_status(inlink, &status, &pts)) { |  |  | if (!deshake_ctx->eof && ff_inlink_acknowledge_status(inlink, &status, &pts)) { | 
														
													
														
															
																|  |  | if (status == AVERROR_EOF) { |  |  | if (status == AVERROR_EOF) { | 
														
													
														
															
																|  |  | deshake_ctx->eof = true; |  |  |  | 
														
													
														
															
																|  |  |  |  |  | deshake_ctx->eof = 1; | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
												
													
														
															
																|  | 
 |