disflow.c (32548B)
1 /* 2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved. 3 * 4 * This source code is subject to the terms of the BSD 2 Clause License and 5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License 6 * was not distributed with this source code in the LICENSE file, you can 7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open 8 * Media Patent License 1.0 was not distributed with this source code in the 9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent. 10 */ 11 12 // Dense Inverse Search flow algorithm 13 // Paper: https://arxiv.org/abs/1603.03590 14 15 #include <assert.h> 16 #include <math.h> 17 18 #include "aom_dsp/aom_dsp_common.h" 19 #include "aom_dsp/flow_estimation/corner_detect.h" 20 #include "aom_dsp/flow_estimation/disflow.h" 21 #include "aom_dsp/flow_estimation/ransac.h" 22 #include "aom_dsp/pyramid.h" 23 #include "aom_mem/aom_mem.h" 24 25 #include "config/aom_dsp_rtcd.h" 26 27 // Amount to downsample the flow field by. 28 // e.g., DOWNSAMPLE_SHIFT = 2 (DOWNSAMPLE_FACTOR == 4) means we calculate 29 // one flow point for each 4x4 pixel region of the frame 30 // Must be a power of 2 31 #define DOWNSAMPLE_SHIFT 3 32 #define DOWNSAMPLE_FACTOR (1 << DOWNSAMPLE_SHIFT) 33 34 // Filters used when upscaling the flow field from one pyramid level 35 // to another. See upscale_flow_component for details on kernel selection 36 #define FLOW_UPSCALE_TAPS 4 37 38 // Number of outermost flow field entries (on each edge) which can't be 39 // computed, because the patch they correspond to extends outside of the 40 // frame 41 // The border is (DISFLOW_PATCH_SIZE >> 1) pixels, which is 42 // (DISFLOW_PATCH_SIZE >> 1) >> DOWNSAMPLE_SHIFT many flow field entries 43 #define FLOW_BORDER_INNER ((DISFLOW_PATCH_SIZE >> 1) >> DOWNSAMPLE_SHIFT) 44 45 // Number of extra padding entries on each side of the flow field. 46 // These samples are added so that we do not need to apply clamping when 47 // interpolating or upsampling the flow field 48 #define FLOW_BORDER_OUTER (FLOW_UPSCALE_TAPS / 2) 49 50 // When downsampling the flow field, each flow field entry covers a square 51 // region of pixels in the image pyramid. This value is equal to the position 52 // of the center of that region, as an offset from the top/left edge. 53 // 54 // Note: Using ((DOWNSAMPLE_FACTOR - 1) / 2) is equivalent to the more 55 // natural expression ((DOWNSAMPLE_FACTOR / 2) - 1), 56 // unless DOWNSAMPLE_FACTOR == 1 (ie, no downsampling), in which case 57 // this gives the correct offset of 0 instead of -1. 58 #define UPSAMPLE_CENTER_OFFSET ((DOWNSAMPLE_FACTOR - 1) / 2) 59 60 static double flow_upscale_filter[2][FLOW_UPSCALE_TAPS] = { 61 // Cubic interpolation kernels for phase=0.75 and phase=0.25, respectively 62 { -3 / 128., 29 / 128., 111 / 128., -9 / 128. }, 63 { -9 / 128., 111 / 128., 29 / 128., -3 / 128. } 64 }; 65 66 static inline void get_cubic_kernel_dbl(double x, double kernel[4]) { 67 // Check that the fractional position is in range. 68 // 69 // Note: x is calculated from, e.g., `u_frac = u - floor(u)`. 70 // Mathematically, this implies that 0 <= x < 1. However, in practice it is 71 // possible to have x == 1 due to floating point rounding. This is fine, 72 // and we still interpolate correctly if we allow x = 1. 73 assert(0 <= x && x <= 1); 74 75 double x2 = x * x; 76 double x3 = x2 * x; 77 kernel[0] = -0.5 * x + x2 - 0.5 * x3; 78 kernel[1] = 1.0 - 2.5 * x2 + 1.5 * x3; 79 kernel[2] = 0.5 * x + 2.0 * x2 - 1.5 * x3; 80 kernel[3] = -0.5 * x2 + 0.5 * x3; 81 } 82 83 static inline void get_cubic_kernel_int(double x, int kernel[4]) { 84 double kernel_dbl[4]; 85 get_cubic_kernel_dbl(x, kernel_dbl); 86 87 kernel[0] = (int)rint(kernel_dbl[0] * (1 << DISFLOW_INTERP_BITS)); 88 kernel[1] = (int)rint(kernel_dbl[1] * (1 << DISFLOW_INTERP_BITS)); 89 kernel[2] = (int)rint(kernel_dbl[2] * (1 << DISFLOW_INTERP_BITS)); 90 kernel[3] = (int)rint(kernel_dbl[3] * (1 << DISFLOW_INTERP_BITS)); 91 } 92 93 static inline double get_cubic_value_dbl(const double *p, 94 const double kernel[4]) { 95 return kernel[0] * p[0] + kernel[1] * p[1] + kernel[2] * p[2] + 96 kernel[3] * p[3]; 97 } 98 99 static inline int get_cubic_value_int(const int *p, const int kernel[4]) { 100 return kernel[0] * p[0] + kernel[1] * p[1] + kernel[2] * p[2] + 101 kernel[3] * p[3]; 102 } 103 104 static inline double bicubic_interp_one(const double *arr, int stride, 105 const double h_kernel[4], 106 const double v_kernel[4]) { 107 double tmp[1 * 4]; 108 109 // Horizontal convolution 110 for (int i = -1; i < 3; ++i) { 111 tmp[i + 1] = get_cubic_value_dbl(&arr[i * stride - 1], h_kernel); 112 } 113 114 // Vertical convolution 115 return get_cubic_value_dbl(tmp, v_kernel); 116 } 117 118 static int determine_disflow_correspondence(const ImagePyramid *src_pyr, 119 const ImagePyramid *ref_pyr, 120 CornerList *corners, 121 const FlowField *flow, 122 Correspondence *correspondences) { 123 const int width = flow->width; 124 const int height = flow->height; 125 const int stride = flow->stride; 126 127 int num_correspondences = 0; 128 for (int i = 0; i < corners->num_corners; ++i) { 129 const int x0 = corners->corners[2 * i]; 130 const int y0 = corners->corners[2 * i + 1]; 131 132 // Offset points, to compensate for the fact that (say) a flow field entry 133 // at horizontal index i, is nominally associated with the pixel at 134 // horizontal coordinate (i << DOWNSAMPLE_FACTOR) + UPSAMPLE_CENTER_OFFSET 135 // This offset must be applied before we split the coordinate into integer 136 // and fractional parts, in order for the interpolation to be correct. 137 const int x = x0 - UPSAMPLE_CENTER_OFFSET; 138 const int y = y0 - UPSAMPLE_CENTER_OFFSET; 139 140 // Split the pixel coordinates into integer flow field coordinates and 141 // an offset for interpolation 142 const int flow_x = x >> DOWNSAMPLE_SHIFT; 143 const double flow_sub_x = 144 (x & (DOWNSAMPLE_FACTOR - 1)) / (double)DOWNSAMPLE_FACTOR; 145 const int flow_y = y >> DOWNSAMPLE_SHIFT; 146 const double flow_sub_y = 147 (y & (DOWNSAMPLE_FACTOR - 1)) / (double)DOWNSAMPLE_FACTOR; 148 149 // Exclude points which would sample from the outer border of the flow 150 // field, as this would give lower-quality results. 151 // 152 // Note: As we never read from the border region at pyramid level 0, we 153 // can skip filling it in. If the conditions here are removed, or any 154 // other logic is added which reads from this border region, then 155 // compute_flow_field() will need to be modified to call 156 // fill_flow_field_borders() at pyramid level 0 to set up the correct 157 // border data. 158 if (flow_x < 1 || (flow_x + 2) >= width) continue; 159 if (flow_y < 1 || (flow_y + 2) >= height) continue; 160 161 double h_kernel[4]; 162 double v_kernel[4]; 163 get_cubic_kernel_dbl(flow_sub_x, h_kernel); 164 get_cubic_kernel_dbl(flow_sub_y, v_kernel); 165 166 double flow_u = bicubic_interp_one(&flow->u[flow_y * stride + flow_x], 167 stride, h_kernel, v_kernel); 168 double flow_v = bicubic_interp_one(&flow->v[flow_y * stride + flow_x], 169 stride, h_kernel, v_kernel); 170 171 // Refine the interpolated flow vector one last time 172 const int patch_tl_x = x0 - DISFLOW_PATCH_CENTER; 173 const int patch_tl_y = y0 - DISFLOW_PATCH_CENTER; 174 aom_compute_flow_at_point( 175 src_pyr->layers[0].buffer, ref_pyr->layers[0].buffer, patch_tl_x, 176 patch_tl_y, src_pyr->layers[0].width, src_pyr->layers[0].height, 177 src_pyr->layers[0].stride, &flow_u, &flow_v); 178 179 // Use original points (without offsets) when filling in correspondence 180 // array 181 correspondences[num_correspondences].x = x0; 182 correspondences[num_correspondences].y = y0; 183 correspondences[num_correspondences].rx = x0 + flow_u; 184 correspondences[num_correspondences].ry = y0 + flow_v; 185 num_correspondences++; 186 } 187 return num_correspondences; 188 } 189 190 // Compare two regions of width x height pixels, one rooted at position 191 // (x, y) in src and the other at (x + u, y + v) in ref. 192 // This function returns the sum of squared pixel differences between 193 // the two regions. 194 static inline void compute_flow_vector(const uint8_t *src, const uint8_t *ref, 195 int width, int height, int stride, int x, 196 int y, double u, double v, 197 const int16_t *dx, const int16_t *dy, 198 int *b) { 199 memset(b, 0, 2 * sizeof(*b)); 200 201 // Split offset into integer and fractional parts, and compute cubic 202 // interpolation kernels 203 const int u_int = (int)floor(u); 204 const int v_int = (int)floor(v); 205 const double u_frac = u - floor(u); 206 const double v_frac = v - floor(v); 207 208 int h_kernel[4]; 209 int v_kernel[4]; 210 get_cubic_kernel_int(u_frac, h_kernel); 211 get_cubic_kernel_int(v_frac, v_kernel); 212 213 // Storage for intermediate values between the two convolution directions 214 int tmp_[DISFLOW_PATCH_SIZE * (DISFLOW_PATCH_SIZE + 3)]; 215 int *tmp = tmp_ + DISFLOW_PATCH_SIZE; // Offset by one row 216 217 // Clamp coordinates so that all pixels we fetch will remain within the 218 // allocated border region, but allow them to go far enough out that 219 // the border pixels' values do not change. 220 // Since we are calculating an 8x8 block, the bottom-right pixel 221 // in the block has coordinates (x0 + 7, y0 + 7). Then, the cubic 222 // interpolation has 4 taps, meaning that the output of pixel 223 // (x_w, y_w) depends on the pixels in the range 224 // ([x_w - 1, x_w + 2], [y_w - 1, y_w + 2]). 225 // 226 // Thus the most extreme coordinates which will be fetched are 227 // (x0 - 1, y0 - 1) and (x0 + 9, y0 + 9). 228 const int x0 = clamp(x + u_int, -9, width); 229 const int y0 = clamp(y + v_int, -9, height); 230 231 // Horizontal convolution 232 for (int i = -1; i < DISFLOW_PATCH_SIZE + 2; ++i) { 233 const int y_w = y0 + i; 234 for (int j = 0; j < DISFLOW_PATCH_SIZE; ++j) { 235 const int x_w = x0 + j; 236 int arr[4]; 237 238 arr[0] = (int)ref[y_w * stride + (x_w - 1)]; 239 arr[1] = (int)ref[y_w * stride + (x_w + 0)]; 240 arr[2] = (int)ref[y_w * stride + (x_w + 1)]; 241 arr[3] = (int)ref[y_w * stride + (x_w + 2)]; 242 243 // Apply kernel and round, keeping 6 extra bits of precision. 244 // 245 // 6 is the maximum allowable number of extra bits which will avoid 246 // the intermediate values overflowing an int16_t. The most extreme 247 // intermediate value occurs when: 248 // * The input pixels are [0, 255, 255, 0] 249 // * u_frac = 0.5 250 // In this case, the un-scaled output is 255 * 1.125 = 286.875. 251 // As an integer with 6 fractional bits, that is 18360, which fits 252 // in an int16_t. But with 7 fractional bits it would be 36720, 253 // which is too large. 254 tmp[i * DISFLOW_PATCH_SIZE + j] = ROUND_POWER_OF_TWO( 255 get_cubic_value_int(arr, h_kernel), DISFLOW_INTERP_BITS - 6); 256 } 257 } 258 259 // Vertical convolution 260 for (int i = 0; i < DISFLOW_PATCH_SIZE; ++i) { 261 for (int j = 0; j < DISFLOW_PATCH_SIZE; ++j) { 262 const int *p = &tmp[i * DISFLOW_PATCH_SIZE + j]; 263 const int arr[4] = { p[-DISFLOW_PATCH_SIZE], p[0], p[DISFLOW_PATCH_SIZE], 264 p[2 * DISFLOW_PATCH_SIZE] }; 265 const int result = get_cubic_value_int(arr, v_kernel); 266 267 // Apply kernel and round. 268 // This time, we have to round off the 6 extra bits which were kept 269 // earlier, but we also want to keep DISFLOW_DERIV_SCALE_LOG2 extra bits 270 // of precision to match the scale of the dx and dy arrays. 271 const int round_bits = DISFLOW_INTERP_BITS + 6 - DISFLOW_DERIV_SCALE_LOG2; 272 const int warped = ROUND_POWER_OF_TWO(result, round_bits); 273 const int src_px = src[(x + j) + (y + i) * stride] << 3; 274 const int dt = warped - src_px; 275 b[0] += dx[i * DISFLOW_PATCH_SIZE + j] * dt; 276 b[1] += dy[i * DISFLOW_PATCH_SIZE + j] * dt; 277 } 278 } 279 } 280 281 static inline void sobel_filter(const uint8_t *src, int src_stride, 282 int16_t *dst, int dst_stride, int dir) { 283 int16_t tmp_[DISFLOW_PATCH_SIZE * (DISFLOW_PATCH_SIZE + 2)]; 284 int16_t *tmp = tmp_ + DISFLOW_PATCH_SIZE; 285 286 // Sobel filter kernel 287 // This must have an overall scale factor equal to DISFLOW_DERIV_SCALE, 288 // in order to produce correctly scaled outputs. 289 // To work out the scale factor, we multiply two factors: 290 // 291 // * For the derivative filter (sobel_a), comparing our filter 292 // image[x - 1] - image[x + 1] 293 // to the standard form 294 // d/dx image[x] = image[x+1] - image[x] 295 // tells us that we're actually calculating -2 * d/dx image[2] 296 // 297 // * For the smoothing filter (sobel_b), all coefficients are positive 298 // so the scale factor is just the sum of the coefficients 299 // 300 // Thus we need to make sure that DISFLOW_DERIV_SCALE = 2 * sum(sobel_b) 301 // (and take care of the - sign from sobel_a elsewhere) 302 static const int16_t sobel_a[3] = { 1, 0, -1 }; 303 static const int16_t sobel_b[3] = { 1, 2, 1 }; 304 const int taps = 3; 305 306 // horizontal filter 307 const int16_t *h_kernel = dir ? sobel_a : sobel_b; 308 309 for (int y = -1; y < DISFLOW_PATCH_SIZE + 1; ++y) { 310 for (int x = 0; x < DISFLOW_PATCH_SIZE; ++x) { 311 int sum = 0; 312 for (int k = 0; k < taps; ++k) { 313 sum += h_kernel[k] * src[y * src_stride + (x + k - 1)]; 314 } 315 tmp[y * DISFLOW_PATCH_SIZE + x] = sum; 316 } 317 } 318 319 // vertical filter 320 const int16_t *v_kernel = dir ? sobel_b : sobel_a; 321 322 for (int y = 0; y < DISFLOW_PATCH_SIZE; ++y) { 323 for (int x = 0; x < DISFLOW_PATCH_SIZE; ++x) { 324 int sum = 0; 325 for (int k = 0; k < taps; ++k) { 326 sum += v_kernel[k] * tmp[(y + k - 1) * DISFLOW_PATCH_SIZE + x]; 327 } 328 dst[y * dst_stride + x] = sum; 329 } 330 } 331 } 332 333 // Computes the components of the system of equations used to solve for 334 // a flow vector. 335 // 336 // The flow equations are a least-squares system, derived as follows: 337 // 338 // For each pixel in the patch, we calculate the current error `dt`, 339 // and the x and y gradients `dx` and `dy` of the source patch. 340 // This means that, to first order, the squared error for this pixel is 341 // 342 // (dt + u * dx + v * dy)^2 343 // 344 // where (u, v) are the incremental changes to the flow vector. 345 // 346 // We then want to find the values of u and v which minimize the sum 347 // of the squared error across all pixels. Conveniently, this fits exactly 348 // into the form of a least squares problem, with one equation 349 // 350 // u * dx + v * dy = -dt 351 // 352 // for each pixel. 353 // 354 // Summing across all pixels in a square window of size DISFLOW_PATCH_SIZE, 355 // and absorbing the - sign elsewhere, this results in the least squares system 356 // 357 // M = |sum(dx * dx) sum(dx * dy)| 358 // |sum(dx * dy) sum(dy * dy)| 359 // 360 // b = |sum(dx * dt)| 361 // |sum(dy * dt)| 362 static inline void compute_flow_matrix(const int16_t *dx, int dx_stride, 363 const int16_t *dy, int dy_stride, 364 double *M) { 365 int tmp[4] = { 0 }; 366 367 for (int i = 0; i < DISFLOW_PATCH_SIZE; i++) { 368 for (int j = 0; j < DISFLOW_PATCH_SIZE; j++) { 369 tmp[0] += dx[i * dx_stride + j] * dx[i * dx_stride + j]; 370 tmp[1] += dx[i * dx_stride + j] * dy[i * dy_stride + j]; 371 // Don't compute tmp[2], as it should be equal to tmp[1] 372 tmp[3] += dy[i * dy_stride + j] * dy[i * dy_stride + j]; 373 } 374 } 375 376 // Apply regularization 377 // We follow the standard regularization method of adding `k * I` before 378 // inverting. This ensures that the matrix will be invertible. 379 // 380 // Setting the regularization strength k to 1 seems to work well here, as 381 // typical values coming from the other equations are very large (1e5 to 382 // 1e6, with an upper limit of around 6e7, at the time of writing). 383 // It also preserves the property that all matrix values are whole numbers, 384 // which is convenient for integerized SIMD implementation. 385 tmp[0] += 1; 386 tmp[3] += 1; 387 388 tmp[2] = tmp[1]; 389 390 M[0] = (double)tmp[0]; 391 M[1] = (double)tmp[1]; 392 M[2] = (double)tmp[2]; 393 M[3] = (double)tmp[3]; 394 } 395 396 // Try to invert the matrix M 397 // Note: Due to the nature of how a least-squares matrix is constructed, all of 398 // the eigenvalues will be >= 0, and therefore det M >= 0 as well. 399 // The regularization term `+ k * I` further ensures that det M >= k^2. 400 // As mentioned in compute_flow_matrix(), here we use k = 1, so det M >= 1. 401 // So we don't have to worry about non-invertible matrices here. 402 static inline void invert_2x2(const double *M, double *M_inv) { 403 double det = (M[0] * M[3]) - (M[1] * M[2]); 404 assert(det >= 1); 405 const double det_inv = 1 / det; 406 407 M_inv[0] = M[3] * det_inv; 408 M_inv[1] = -M[1] * det_inv; 409 M_inv[2] = -M[2] * det_inv; 410 M_inv[3] = M[0] * det_inv; 411 } 412 413 void aom_compute_flow_at_point_c(const uint8_t *src, const uint8_t *ref, int x, 414 int y, int width, int height, int stride, 415 double *u, double *v) { 416 double M[4]; 417 double M_inv[4]; 418 int b[2]; 419 int16_t dx[DISFLOW_PATCH_SIZE * DISFLOW_PATCH_SIZE]; 420 int16_t dy[DISFLOW_PATCH_SIZE * DISFLOW_PATCH_SIZE]; 421 422 // Compute gradients within this patch 423 const uint8_t *src_patch = &src[y * stride + x]; 424 sobel_filter(src_patch, stride, dx, DISFLOW_PATCH_SIZE, 1); 425 sobel_filter(src_patch, stride, dy, DISFLOW_PATCH_SIZE, 0); 426 427 compute_flow_matrix(dx, DISFLOW_PATCH_SIZE, dy, DISFLOW_PATCH_SIZE, M); 428 invert_2x2(M, M_inv); 429 430 for (int itr = 0; itr < DISFLOW_MAX_ITR; itr++) { 431 compute_flow_vector(src, ref, width, height, stride, x, y, *u, *v, dx, dy, 432 b); 433 434 // Solve flow equations to find a better estimate for the flow vector 435 // at this point 436 const double step_u = M_inv[0] * b[0] + M_inv[1] * b[1]; 437 const double step_v = M_inv[2] * b[0] + M_inv[3] * b[1]; 438 *u += fclamp(step_u * DISFLOW_STEP_SIZE, -2, 2); 439 *v += fclamp(step_v * DISFLOW_STEP_SIZE, -2, 2); 440 441 if (fabs(step_u) + fabs(step_v) < DISFLOW_STEP_SIZE_THRESOLD) { 442 // Stop iteration when we're close to convergence 443 break; 444 } 445 } 446 } 447 448 static void fill_flow_field_borders(double *flow, int width, int height, 449 int stride) { 450 // Calculate the bounds of the rectangle which was filled in by 451 // compute_flow_field() before calling this function. 452 // These indices are inclusive on both ends. 453 const int left_index = FLOW_BORDER_INNER; 454 const int right_index = (width - FLOW_BORDER_INNER - 1); 455 const int top_index = FLOW_BORDER_INNER; 456 const int bottom_index = (height - FLOW_BORDER_INNER - 1); 457 458 // Left area 459 for (int i = top_index; i <= bottom_index; i += 1) { 460 double *row = flow + i * stride; 461 const double left = row[left_index]; 462 for (int j = -FLOW_BORDER_OUTER; j < left_index; j++) { 463 row[j] = left; 464 } 465 } 466 467 // Right area 468 for (int i = top_index; i <= bottom_index; i += 1) { 469 double *row = flow + i * stride; 470 const double right = row[right_index]; 471 for (int j = right_index + 1; j < width + FLOW_BORDER_OUTER; j++) { 472 row[j] = right; 473 } 474 } 475 476 // Top area 477 const double *top_row = flow + top_index * stride - FLOW_BORDER_OUTER; 478 for (int i = -FLOW_BORDER_OUTER; i < top_index; i++) { 479 double *row = flow + i * stride - FLOW_BORDER_OUTER; 480 size_t length = width + 2 * FLOW_BORDER_OUTER; 481 memcpy(row, top_row, length * sizeof(*row)); 482 } 483 484 // Bottom area 485 const double *bottom_row = flow + bottom_index * stride - FLOW_BORDER_OUTER; 486 for (int i = bottom_index + 1; i < height + FLOW_BORDER_OUTER; i++) { 487 double *row = flow + i * stride - FLOW_BORDER_OUTER; 488 size_t length = width + 2 * FLOW_BORDER_OUTER; 489 memcpy(row, bottom_row, length * sizeof(*row)); 490 } 491 } 492 493 // Upscale one component of the flow field, from a size of 494 // cur_width x cur_height to a size of (2*cur_width) x (2*cur_height), storing 495 // the result back into the same buffer. This function also scales the flow 496 // vector by 2, so that when we move to the next pyramid level down, the implied 497 // motion vector is the same. 498 // 499 // The temporary buffer tmpbuf must be large enough to hold an intermediate 500 // array of size stride * cur_height, *plus* FLOW_BORDER_OUTER rows above and 501 // below. In other words, indices from -FLOW_BORDER_OUTER * stride to 502 // (cur_height + FLOW_BORDER_OUTER) * stride - 1 must be valid. 503 // 504 // Note that the same stride is used for u before and after upscaling 505 // and for the temporary buffer, for simplicity. 506 // 507 // A note on phasing: 508 // 509 // The flow fields at two adjacent pyramid levels are offset from each other, 510 // and we need to account for this in the construction of the interpolation 511 // kernels. 512 // 513 // Consider an 8x8 pixel patch at pyramid level n. This is split into four 514 // patches at pyramid level n-1. Bringing these patches back up to pyramid level 515 // n, each sub-patch covers 4x4 pixels, and between them they cover the same 516 // 8x8 region. 517 // 518 // Therefore, at pyramid level n, two adjacent patches look like this: 519 // 520 // + - - - - - - - + - - - - - - - + 521 // | | | 522 // | x x | x x | 523 // | | | 524 // | # | # | 525 // | | | 526 // | x x | x x | 527 // | | | 528 // + - - - - - - - + - - - - - - - + 529 // 530 // where # marks the center of a patch at pyramid level n (the input to this 531 // function), and x marks the center of a patch at pyramid level n-1 (the output 532 // of this function). 533 // 534 // By counting pixels (marked by +, -, and |), we can see that the flow vectors 535 // at pyramid level n-1 are offset relative to the flow vectors at pyramid 536 // level n, by 1/4 of the larger (input) patch size. Therefore, our 537 // interpolation kernels need to have phases of 0.25 and 0.75. 538 // 539 // In addition, in order to handle the frame edges correctly, we need to 540 // generate one output vector to the left and one to the right of each input 541 // vector, even though these must be interpolated using different source points. 542 static void upscale_flow_component(double *flow, int cur_width, int cur_height, 543 int stride, double *tmpbuf) { 544 const int half_len = FLOW_UPSCALE_TAPS / 2; 545 546 // Check that the outer border is large enough to avoid needing to clamp 547 // the source locations 548 assert(half_len <= FLOW_BORDER_OUTER); 549 550 // Horizontal upscale and multiply by 2 551 for (int i = 0; i < cur_height; i++) { 552 for (int j = 0; j < cur_width; j++) { 553 double left = 0; 554 for (int k = -half_len; k < half_len; k++) { 555 left += 556 flow[i * stride + (j + k)] * flow_upscale_filter[0][k + half_len]; 557 } 558 tmpbuf[i * stride + (2 * j + 0)] = 2.0 * left; 559 560 // Right output pixel is 0.25 units to the right of the input pixel 561 double right = 0; 562 for (int k = -(half_len - 1); k < (half_len + 1); k++) { 563 right += flow[i * stride + (j + k)] * 564 flow_upscale_filter[1][k + (half_len - 1)]; 565 } 566 tmpbuf[i * stride + (2 * j + 1)] = 2.0 * right; 567 } 568 } 569 570 // Fill in top and bottom borders of tmpbuf 571 const double *top_row = &tmpbuf[0]; 572 for (int i = -FLOW_BORDER_OUTER; i < 0; i++) { 573 double *row = &tmpbuf[i * stride]; 574 memcpy(row, top_row, 2 * cur_width * sizeof(*row)); 575 } 576 577 const double *bottom_row = &tmpbuf[(cur_height - 1) * stride]; 578 for (int i = cur_height; i < cur_height + FLOW_BORDER_OUTER; i++) { 579 double *row = &tmpbuf[i * stride]; 580 memcpy(row, bottom_row, 2 * cur_width * sizeof(*row)); 581 } 582 583 // Vertical upscale 584 int upscaled_width = cur_width * 2; 585 for (int i = 0; i < cur_height; i++) { 586 for (int j = 0; j < upscaled_width; j++) { 587 double top = 0; 588 for (int k = -half_len; k < half_len; k++) { 589 top += 590 tmpbuf[(i + k) * stride + j] * flow_upscale_filter[0][k + half_len]; 591 } 592 flow[(2 * i) * stride + j] = top; 593 594 double bottom = 0; 595 for (int k = -(half_len - 1); k < (half_len + 1); k++) { 596 bottom += tmpbuf[(i + k) * stride + j] * 597 flow_upscale_filter[1][k + (half_len - 1)]; 598 } 599 flow[(2 * i + 1) * stride + j] = bottom; 600 } 601 } 602 } 603 604 // make sure flow_u and flow_v start at 0 605 static bool compute_flow_field(const ImagePyramid *src_pyr, 606 const ImagePyramid *ref_pyr, int n_levels, 607 FlowField *flow) { 608 bool mem_status = true; 609 610 double *flow_u = flow->u; 611 double *flow_v = flow->v; 612 613 double *tmpbuf0; 614 double *tmpbuf; 615 616 if (n_levels < 2) { 617 // tmpbuf not needed 618 tmpbuf0 = NULL; 619 tmpbuf = NULL; 620 } else { 621 // This line must match the calculation of cur_flow_height below 622 const int layer1_height = src_pyr->layers[1].height >> DOWNSAMPLE_SHIFT; 623 624 const size_t tmpbuf_size = 625 (layer1_height + 2 * FLOW_BORDER_OUTER) * flow->stride; 626 tmpbuf0 = aom_malloc(tmpbuf_size * sizeof(*tmpbuf0)); 627 if (!tmpbuf0) { 628 mem_status = false; 629 goto free_tmpbuf; 630 } 631 tmpbuf = tmpbuf0 + FLOW_BORDER_OUTER * flow->stride; 632 } 633 634 // Compute flow field from coarsest to finest level of the pyramid 635 // 636 // Note: We stop after refining pyramid level 1 and interpolating it to 637 // generate an initial flow field at level 0. We do *not* refine the dense 638 // flow field at level 0. Instead, we wait until we have generated 639 // correspondences by interpolating this flow field, and then refine the 640 // correspondences themselves. This is both faster and gives better output 641 // compared to refining the flow field at level 0 and then interpolating. 642 for (int level = n_levels - 1; level >= 1; --level) { 643 const PyramidLayer *cur_layer = &src_pyr->layers[level]; 644 const int cur_width = cur_layer->width; 645 const int cur_height = cur_layer->height; 646 const int cur_stride = cur_layer->stride; 647 648 const uint8_t *src_buffer = cur_layer->buffer; 649 const uint8_t *ref_buffer = ref_pyr->layers[level].buffer; 650 651 const int cur_flow_width = cur_width >> DOWNSAMPLE_SHIFT; 652 const int cur_flow_height = cur_height >> DOWNSAMPLE_SHIFT; 653 const int cur_flow_stride = flow->stride; 654 655 for (int i = FLOW_BORDER_INNER; i < cur_flow_height - FLOW_BORDER_INNER; 656 i += 1) { 657 for (int j = FLOW_BORDER_INNER; j < cur_flow_width - FLOW_BORDER_INNER; 658 j += 1) { 659 const int flow_field_idx = i * cur_flow_stride + j; 660 661 // Calculate the position of a patch of size DISFLOW_PATCH_SIZE pixels, 662 // which is centered on the region covered by this flow field entry 663 const int patch_center_x = 664 (j << DOWNSAMPLE_SHIFT) + UPSAMPLE_CENTER_OFFSET; // In pixels 665 const int patch_center_y = 666 (i << DOWNSAMPLE_SHIFT) + UPSAMPLE_CENTER_OFFSET; // In pixels 667 const int patch_tl_x = patch_center_x - DISFLOW_PATCH_CENTER; 668 const int patch_tl_y = patch_center_y - DISFLOW_PATCH_CENTER; 669 assert(patch_tl_x >= 0); 670 assert(patch_tl_y >= 0); 671 672 aom_compute_flow_at_point(src_buffer, ref_buffer, patch_tl_x, 673 patch_tl_y, cur_width, cur_height, cur_stride, 674 &flow_u[flow_field_idx], 675 &flow_v[flow_field_idx]); 676 } 677 } 678 679 // Fill in the areas which we haven't explicitly computed, with copies 680 // of the outermost values which we did compute 681 fill_flow_field_borders(flow_u, cur_flow_width, cur_flow_height, 682 cur_flow_stride); 683 fill_flow_field_borders(flow_v, cur_flow_width, cur_flow_height, 684 cur_flow_stride); 685 686 if (level > 0) { 687 const int upscale_flow_width = cur_flow_width << 1; 688 const int upscale_flow_height = cur_flow_height << 1; 689 const int upscale_stride = flow->stride; 690 691 upscale_flow_component(flow_u, cur_flow_width, cur_flow_height, 692 cur_flow_stride, tmpbuf); 693 upscale_flow_component(flow_v, cur_flow_width, cur_flow_height, 694 cur_flow_stride, tmpbuf); 695 696 // If we didn't fill in the rightmost column or bottommost row during 697 // upsampling (in order to keep the ratio to exactly 2), fill them 698 // in here by copying the next closest column/row 699 const PyramidLayer *next_layer = &src_pyr->layers[level - 1]; 700 const int next_flow_width = next_layer->width >> DOWNSAMPLE_SHIFT; 701 const int next_flow_height = next_layer->height >> DOWNSAMPLE_SHIFT; 702 703 // Rightmost column 704 if (next_flow_width > upscale_flow_width) { 705 assert(next_flow_width == upscale_flow_width + 1); 706 for (int i = 0; i < upscale_flow_height; i++) { 707 const int index = i * upscale_stride + upscale_flow_width; 708 flow_u[index] = flow_u[index - 1]; 709 flow_v[index] = flow_v[index - 1]; 710 } 711 } 712 713 // Bottommost row 714 if (next_flow_height > upscale_flow_height) { 715 assert(next_flow_height == upscale_flow_height + 1); 716 for (int j = 0; j < next_flow_width; j++) { 717 const int index = upscale_flow_height * upscale_stride + j; 718 flow_u[index] = flow_u[index - upscale_stride]; 719 flow_v[index] = flow_v[index - upscale_stride]; 720 } 721 } 722 } 723 } 724 725 free_tmpbuf: 726 aom_free(tmpbuf0); 727 return mem_status; 728 } 729 730 static FlowField *alloc_flow_field(int frame_width, int frame_height) { 731 FlowField *flow = (FlowField *)aom_malloc(sizeof(FlowField)); 732 if (flow == NULL) return NULL; 733 734 // Calculate the size of the bottom (largest) layer of the flow pyramid 735 flow->width = frame_width >> DOWNSAMPLE_SHIFT; 736 flow->height = frame_height >> DOWNSAMPLE_SHIFT; 737 flow->stride = flow->width + 2 * FLOW_BORDER_OUTER; 738 739 const size_t flow_size = 740 flow->stride * (size_t)(flow->height + 2 * FLOW_BORDER_OUTER); 741 742 flow->buf0 = aom_calloc(2 * flow_size, sizeof(*flow->buf0)); 743 if (!flow->buf0) { 744 aom_free(flow); 745 return NULL; 746 } 747 748 flow->u = flow->buf0 + FLOW_BORDER_OUTER * flow->stride + FLOW_BORDER_OUTER; 749 flow->v = flow->u + flow_size; 750 751 return flow; 752 } 753 754 static void free_flow_field(FlowField *flow) { 755 aom_free(flow->buf0); 756 aom_free(flow); 757 } 758 759 // Compute flow field between `src` and `ref`, and then use that flow to 760 // compute a global motion model relating the two frames. 761 // 762 // Following the convention in flow_estimation.h, the flow vectors are computed 763 // at fixed points in `src` and point to the corresponding locations in `ref`, 764 // regardless of the temporal ordering of the frames. 765 bool av1_compute_global_motion_disflow( 766 TransformationType type, YV12_BUFFER_CONFIG *src, YV12_BUFFER_CONFIG *ref, 767 int bit_depth, int downsample_level, MotionModel *motion_models, 768 int num_motion_models, bool *mem_alloc_failed) { 769 // Precompute information we will need about each frame 770 ImagePyramid *src_pyramid = src->y_pyramid; 771 CornerList *src_corners = src->corners; 772 ImagePyramid *ref_pyramid = ref->y_pyramid; 773 774 const int src_layers = 775 aom_compute_pyramid(src, bit_depth, DISFLOW_PYRAMID_LEVELS, src_pyramid); 776 const int ref_layers = 777 aom_compute_pyramid(ref, bit_depth, DISFLOW_PYRAMID_LEVELS, ref_pyramid); 778 779 if (src_layers < 0 || ref_layers < 0) { 780 *mem_alloc_failed = true; 781 return false; 782 } 783 if (!av1_compute_corner_list(src, bit_depth, downsample_level, src_corners)) { 784 *mem_alloc_failed = true; 785 return false; 786 } 787 788 assert(src_layers == ref_layers); 789 790 const int src_width = src_pyramid->layers[0].width; 791 const int src_height = src_pyramid->layers[0].height; 792 assert(ref_pyramid->layers[0].width == src_width); 793 assert(ref_pyramid->layers[0].height == src_height); 794 795 FlowField *flow = alloc_flow_field(src_width, src_height); 796 if (!flow) { 797 *mem_alloc_failed = true; 798 return false; 799 } 800 801 if (!compute_flow_field(src_pyramid, ref_pyramid, src_layers, flow)) { 802 *mem_alloc_failed = true; 803 free_flow_field(flow); 804 return false; 805 } 806 807 // find correspondences between the two images using the flow field 808 Correspondence *correspondences = 809 aom_malloc(src_corners->num_corners * sizeof(*correspondences)); 810 if (!correspondences) { 811 *mem_alloc_failed = true; 812 free_flow_field(flow); 813 return false; 814 } 815 816 const int num_correspondences = determine_disflow_correspondence( 817 src_pyramid, ref_pyramid, src_corners, flow, correspondences); 818 819 bool result = ransac(correspondences, num_correspondences, type, 820 motion_models, num_motion_models, mem_alloc_failed); 821 822 aom_free(correspondences); 823 free_flow_field(flow); 824 return result; 825 }