Only compute image gradients for source image
Spatial gradients are only needed from one image to compute the
optical flow field.
Change-Id: I87861547cb2996c1a61900423ef2a0008c3aa536
diff --git a/av1/encoder/global_motion.c b/av1/encoder/global_motion.c
index 41bda29..b947bad 100644
--- a/av1/encoder/global_motion.c
+++ b/av1/encoder/global_motion.c
@@ -46,6 +46,7 @@
typedef struct {
int n_levels;
int pad_size;
+ int has_gradient;
int widths[N_LEVELS];
int heights[N_LEVELS];
int strides[N_LEVELS];
@@ -508,27 +509,35 @@
}
}
-static ImagePyramid *alloc_pyramid(int width, int height, int pad_size) {
+static ImagePyramid *alloc_pyramid(int width, int height, int pad_size,
+ int compute_gradient) {
ImagePyramid *pyr = aom_malloc(sizeof(*pyr));
+ pyr->has_gradient = compute_gradient;
// 2 * width * height is the upper bound for a buffer that fits
// all pyramid levels + padding for each level
const int buffer_size = sizeof(*pyr->level_buffer) * 2 * width * height +
(width + 2 * pad_size) * 2 * pad_size * N_LEVELS;
- const int gradient_size = sizeof(*pyr->level_dx_buffer) * 2 * width * height +
- (width + 2 * pad_size) * 2 * pad_size * N_LEVELS;
pyr->level_buffer = aom_malloc(buffer_size);
- pyr->level_dx_buffer = aom_malloc(gradient_size);
- pyr->level_dy_buffer = aom_malloc(gradient_size);
memset(pyr->level_buffer, 0, buffer_size);
- memset(pyr->level_dx_buffer, 0, gradient_size);
- memset(pyr->level_dy_buffer, 0, gradient_size);
+
+ if (compute_gradient) {
+ const int gradient_size =
+ sizeof(*pyr->level_dx_buffer) * 2 * width * height +
+ (width + 2 * pad_size) * 2 * pad_size * N_LEVELS;
+ pyr->level_dx_buffer = aom_malloc(gradient_size);
+ pyr->level_dy_buffer = aom_malloc(gradient_size);
+ memset(pyr->level_dx_buffer, 0, gradient_size);
+ memset(pyr->level_dy_buffer, 0, gradient_size);
+ }
return pyr;
}
static void free_pyramid(ImagePyramid *pyr) {
aom_free(pyr->level_buffer);
- aom_free(pyr->level_dx_buffer);
- aom_free(pyr->level_dy_buffer);
+ if (pyr->has_gradient) {
+ aom_free(pyr->level_dx_buffer);
+ aom_free(pyr->level_dy_buffer);
+ }
aom_free(pyr);
}
@@ -547,7 +556,7 @@
// Compute coarse to fine pyramids for a frame
static void compute_flow_pyramids(unsigned char *frm, const int frm_width,
const int frm_height, const int frm_stride,
- int n_levels, int pad_size,
+ int n_levels, int pad_size, int compute_grad,
ImagePyramid *frm_pyr) {
int cur_width, cur_height, cur_stride, cur_loc;
assert((frm_width >> n_levels) > 0);
@@ -584,15 +593,19 @@
frm_pyr->level_buffer + cur_loc, cur_height, cur_width,
cur_stride);
- // Computation x gradient
- sobel_xy_image_gradient(frm_pyr->level_buffer + cur_loc, cur_stride,
- frm_pyr->level_dx_buffer + cur_loc, cur_stride,
- cur_height, cur_width, 1);
+ if (compute_grad) {
+ assert(frm_pyr->has_gradient && frm_pyr->level_dx_buffer != NULL &&
+ frm_pyr->level_dy_buffer != NULL);
+ // Computation x gradient
+ sobel_xy_image_gradient(frm_pyr->level_buffer + cur_loc, cur_stride,
+ frm_pyr->level_dx_buffer + cur_loc, cur_stride,
+ cur_height, cur_width, 1);
- // Computation y gradient
- sobel_xy_image_gradient(frm_pyr->level_buffer + cur_loc, cur_stride,
- frm_pyr->level_dy_buffer + cur_loc, cur_stride,
- cur_height, cur_width, 0);
+ // Computation y gradient
+ sobel_xy_image_gradient(frm_pyr->level_buffer + cur_loc, cur_stride,
+ frm_pyr->level_dy_buffer + cur_loc, cur_stride,
+ cur_height, cur_width, 0);
+ }
}
}
@@ -631,13 +644,17 @@
// flow field is computed and upscaled. I'll add these optimizations
// once the full implementation is working.
// Allocate frm image pyramids
- ImagePyramid *frm_pyr = alloc_pyramid(frm_width, frm_height, pad_size);
+ int compute_gradient = 1;
+ ImagePyramid *frm_pyr =
+ alloc_pyramid(frm_width, frm_height, pad_size, compute_gradient);
compute_flow_pyramids(frm_buffer, frm_width, frm_height, frm->y_stride,
- n_levels, pad_size, frm_pyr);
+ n_levels, pad_size, compute_gradient, frm_pyr);
// Allocate ref image pyramids
- ImagePyramid *ref_pyr = alloc_pyramid(ref_width, ref_height, pad_size);
+ compute_gradient = 0;
+ ImagePyramid *ref_pyr =
+ alloc_pyramid(ref_width, ref_height, pad_size, compute_gradient);
compute_flow_pyramids(ref_buffer, ref_width, ref_height, ref->y_stride,
- n_levels, pad_size, ref_pyr);
+ n_levels, pad_size, compute_gradient, ref_pyr);
// TODO(sarahparker) Implement the rest of DISFlow, currently only the image
// pyramid is implemented.