shithub: libvpx

Download patch

ref: f9b93714764ef4dde7f672d5791b2e1c38b12e2c
parent: b0c89c99ce47daf1210e6dd78568cd418c80dc8c
author: Angie Chiang <angiebird@google.com>
date: Fri Aug 16 10:17:18 EDT 2019

Add MotionField and MotionFieldInfo

Also add related buffer alloc/free functions.

Change-Id: I77dde3dd991f6b21b5c2c1ffa72300ce7738fd50

--- a/vp9/encoder/vp9_encoder.h
+++ b/vp9/encoder/vp9_encoder.h
@@ -302,7 +302,6 @@
 } TplDepStats;
 
 #if CONFIG_NON_GREEDY_MV
-#define SQUARE_BLOCK_SIZES 4
 
 #define ZERO_MV_MODE 0
 #define NEW_MV_MODE 1
@@ -329,40 +328,6 @@
 } TplDepFrame;
 
 #if CONFIG_NON_GREEDY_MV
-static INLINE int get_square_block_idx(BLOCK_SIZE bsize) {
-  if (bsize == BLOCK_4X4) {
-    return 0;
-  }
-  if (bsize == BLOCK_8X8) {
-    return 1;
-  }
-  if (bsize == BLOCK_16X16) {
-    return 2;
-  }
-  if (bsize == BLOCK_32X32) {
-    return 3;
-  }
-  assert(0 && "ERROR: non-square block size");
-  return -1;
-}
-
-static INLINE BLOCK_SIZE square_block_idx_to_bsize(int square_block_idx) {
-  if (square_block_idx == 0) {
-    return BLOCK_4X4;
-  }
-  if (square_block_idx == 1) {
-    return BLOCK_8X8;
-  }
-  if (square_block_idx == 2) {
-    return BLOCK_16X16;
-  }
-  if (square_block_idx == 3) {
-    return BLOCK_32X32;
-  }
-  assert(0 && "ERROR: invalid square_block_idx");
-  return BLOCK_INVALID;
-}
-
 static INLINE int_mv *get_pyramid_mv(const TplDepFrame *tpl_frame, int rf_idx,
                                      BLOCK_SIZE bsize, int mi_row, int mi_col) {
   return &tpl_frame->pyramid_mv_arr[rf_idx][get_square_block_idx(bsize)]
--- a/vp9/encoder/vp9_non_greedy_mv.c
+++ b/vp9/encoder/vp9_non_greedy_mv.c
@@ -164,6 +164,72 @@
   10484282,
 };
 
+static int mi_size_to_block_size(int mi_bsize, int mi_num) {
+  return (mi_num % mi_bsize) ? mi_num / mi_bsize + 1 : mi_num / mi_bsize;
+}
+
+void vp9_alloc_motion_field_info(MotionFieldInfo *motion_field_info,
+                                 int frame_num, int mi_rows, int mi_cols) {
+  int frame_idx, rf_idx, square_block_idx;
+  motion_field_info->frame_num = frame_num;
+  motion_field_info->motion_field_array =
+      vpx_calloc(frame_num, sizeof(*motion_field_info->motion_field_array));
+  for (frame_idx = 0; frame_idx < frame_num; ++frame_idx) {
+    for (rf_idx = 0; rf_idx < 3; ++rf_idx) {
+      for (square_block_idx = 0; square_block_idx < SQUARE_BLOCK_SIZES;
+           ++square_block_idx) {
+        BLOCK_SIZE bsize = square_block_idx_to_bsize(square_block_idx);
+        const int mi_height = num_8x8_blocks_high_lookup[bsize];
+        const int mi_width = num_8x8_blocks_wide_lookup[bsize];
+        const int block_rows = mi_size_to_block_size(mi_height, mi_rows);
+        const int block_cols = mi_size_to_block_size(mi_width, mi_cols);
+        MotionField *motion_field =
+            &motion_field_info
+                 ->motion_field_array[frame_idx][rf_idx][square_block_idx];
+        vp9_alloc_motion_field(motion_field, bsize, block_rows, block_cols);
+      }
+    }
+  }
+}
+
+void vp9_alloc_motion_field(MotionField *motion_field, BLOCK_SIZE bsize,
+                            int block_rows, int block_cols) {
+  motion_field->ready = 0;
+  motion_field->bsize = bsize;
+  motion_field->block_rows = block_rows;
+  motion_field->block_cols = block_cols;
+  motion_field->mf =
+      vpx_calloc(block_rows * block_cols, sizeof(*motion_field->mf));
+  assert(motion_field->mf != NULL);
+  motion_field->local_structure = vpx_calloc(
+      block_rows * block_cols, sizeof(*motion_field->local_structure));
+  assert(motion_field->local_structure != NULL);
+}
+
+void vp9_free_motion_field(MotionField *motion_field) {
+  vpx_free(motion_field->mf);
+  vpx_free(motion_field->local_structure);
+  vp9_zero(*motion_field);
+}
+
+void vp9_free_motion_field_info(MotionFieldInfo *motion_field_info) {
+  int frame_idx, rf_idx, square_block_idx;
+  for (frame_idx = 0; frame_idx < motion_field_info->frame_num; ++frame_idx) {
+    for (rf_idx = 0; rf_idx < 3; ++rf_idx) {
+      for (square_block_idx = 0; square_block_idx < SQUARE_BLOCK_SIZES;
+           ++square_block_idx) {
+        MotionField *motion_field =
+            &motion_field_info
+                 ->motion_field_array[frame_idx][rf_idx][square_block_idx];
+        vp9_free_motion_field(motion_field);
+      }
+    }
+  }
+  vpx_free(motion_field_info->motion_field_array);
+  motion_field_info->motion_field_array = NULL;
+  motion_field_info->frame_num = 0;
+}
+
 static int64_t log2_approximation(int64_t v) {
   assert(v > 0);
   if (v < LOG2_TABLE_SIZE) {
@@ -206,8 +272,9 @@
 }
 
 static MV get_smooth_motion_vector(const MV search_mv, const MV *tmp_mf,
-                                   const int (*M)[4], int rows, int cols,
-                                   int row, int col, float alpha) {
+                                   const int (*M)[MF_LOCAL_STRUCTURE_SIZE],
+                                   int rows, int cols, int row, int col,
+                                   float alpha) {
   const MV tmp_mv = tmp_mf[row * cols + col];
   int idx_row, idx_col;
   float avg_nb_mv[2] = { 0.0f, 0.0f };
@@ -260,7 +327,8 @@
   return mv;
 }
 
-void vp9_get_smooth_motion_field(const MV *scaled_search_mf, const int (*M)[4],
+void vp9_get_smooth_motion_field(const MV *scaled_search_mf,
+                                 const int (*M)[MF_LOCAL_STRUCTURE_SIZE],
                                  int rows, int cols, float alpha, int num_iters,
                                  MV *smooth_mf) {
   // note: the scaled_search_mf and smooth_mf are all scaled by macroblock size
@@ -298,11 +366,12 @@
 
 void vp9_get_local_structure(const YV12_BUFFER_CONFIG *ref_frame,
                              const vp9_variance_fn_ptr_t *fn_ptr, int mi_rows,
-                             int mi_cols, BLOCK_SIZE bsize, int (*M)[4]) {
+                             int mi_cols, BLOCK_SIZE bsize,
+                             int (*M)[MF_LOCAL_STRUCTURE_SIZE]) {
   int stride = ref_frame->y_stride;
   const int mi_height = num_8x8_blocks_high_lookup[bsize];
   const int mi_width = num_8x8_blocks_wide_lookup[bsize];
-  int cols = mi_cols / mi_width;
+  int cols = mi_size_to_block_size(mi_width, mi_cols);
   int mi_row, mi_col;
   for (mi_row = 0; mi_row < mi_rows; mi_row += mi_height) {
     for (mi_col = 0; mi_col < mi_cols; mi_col += mi_width) {
--- a/vp9/encoder/vp9_non_greedy_mv.h
+++ b/vp9/encoder/vp9_non_greedy_mv.h
@@ -21,17 +21,80 @@
 #endif
 #define NB_MVS_NUM 4
 #define LOG2_PRECISION 20
+#define MF_LOCAL_STRUCTURE_SIZE 4
+#define SQUARE_BLOCK_SIZES 4
 
+typedef struct MotionField {
+  int ready;
+  BLOCK_SIZE bsize;
+  int block_rows;
+  int block_cols;
+  int (*local_structure)[MF_LOCAL_STRUCTURE_SIZE];
+  MV *mf;
+  int mv_log_scale;
+} MotionField;
+
+typedef struct MotionFieldInfo {
+  int frame_num;
+  MotionField (*motion_field_array)[3][SQUARE_BLOCK_SIZES];
+} MotionFieldInfo;
+
+static INLINE int get_square_block_idx(BLOCK_SIZE bsize) {
+  if (bsize == BLOCK_4X4) {
+    return 0;
+  }
+  if (bsize == BLOCK_8X8) {
+    return 1;
+  }
+  if (bsize == BLOCK_16X16) {
+    return 2;
+  }
+  if (bsize == BLOCK_32X32) {
+    return 3;
+  }
+  assert(0 && "ERROR: non-square block size");
+  return -1;
+}
+
+static INLINE BLOCK_SIZE square_block_idx_to_bsize(int square_block_idx) {
+  if (square_block_idx == 0) {
+    return BLOCK_4X4;
+  }
+  if (square_block_idx == 1) {
+    return BLOCK_8X8;
+  }
+  if (square_block_idx == 2) {
+    return BLOCK_16X16;
+  }
+  if (square_block_idx == 3) {
+    return BLOCK_32X32;
+  }
+  assert(0 && "ERROR: invalid square_block_idx");
+  return BLOCK_INVALID;
+}
+
+void vp9_alloc_motion_field_info(MotionFieldInfo *motion_field_info,
+                                 int gop_size, int block_rows, int block_cols);
+
+void vp9_alloc_motion_field(MotionField *motion_field, BLOCK_SIZE bsize,
+                            int block_rows, int block_cols);
+
+void vp9_free_motion_field(MotionField *motion_field);
+
+void vp9_free_motion_field_info(MotionFieldInfo *motion_field_info);
+
 int64_t vp9_nb_mvs_inconsistency(const MV *mv, const int_mv *nb_full_mvs,
                                  int mv_num);
 
-void vp9_get_smooth_motion_field(const MV *search_mf, const int (*M)[4],
+void vp9_get_smooth_motion_field(const MV *search_mf,
+                                 const int (*M)[MF_LOCAL_STRUCTURE_SIZE],
                                  int rows, int cols, float alpha, int num_iters,
                                  MV *smooth_mf);
 
 void vp9_get_local_structure(const YV12_BUFFER_CONFIG *ref_frame,
                              const vp9_variance_fn_ptr_t *fn_ptr, int mi_rows,
-                             int mi_cols, BLOCK_SIZE bsize, int (*M)[4]);
+                             int mi_cols, BLOCK_SIZE bsize,
+                             int (*M)[MF_LOCAL_STRUCTURE_SIZE]);
 
 #ifdef __cplusplus
 }  // extern "C"