shithub: libvpx

Download patch

ref: f40c00b206ee6b405ce44a46f6e2adf6906bd41b
parent: c5f298b71fa5e0a1e7be4d2ddb0b2cb8e81f3836
parent: efd02817da3d38140278cc92668547ada662c2e6
author: Angie Chiang <angiebird@google.com>
date: Wed Aug 28 16:38:20 EDT 2019

Merge changes I0fad9437,I79fcb1fd,I93660044

* changes:
  Add MACRO MAX_INTER_REF_FRAMES
  Add motion_filed_info in VP9_COMP
  Add free_tpl_buffer

--- a/vp9/common/vp9_blockd.h
+++ b/vp9/common/vp9_blockd.h
@@ -60,6 +60,7 @@
 #define GOLDEN_FRAME 2
 #define ALTREF_FRAME 3
 #define MAX_REF_FRAMES 4
+#define MAX_INTER_REF_FRAMES 3
 
 typedef int8_t MV_REFERENCE_FRAME;
 
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -2538,9 +2538,11 @@
   snprintf((H) + strlen(H), sizeof(H) - strlen(H), (T), (V))
 #endif  // CONFIG_INTERNAL_STATS
 
+static void free_tpl_buffer(VP9_COMP *cpi);
+
 void vp9_remove_compressor(VP9_COMP *cpi) {
   VP9_COMMON *cm;
-  unsigned int i, frame;
+  unsigned int i;
   int t;
 
   if (!cpi) return;
@@ -2652,27 +2654,7 @@
     vpx_free(cpi->kmeans_data_arr);
   }
 
-#if CONFIG_NON_GREEDY_MV
-  vpx_free(cpi->feature_score_loc_arr);
-  vpx_free(cpi->feature_score_loc_sort);
-  vpx_free(cpi->feature_score_loc_heap);
-  vpx_free(cpi->select_mv_arr);
-#endif
-  for (frame = 0; frame < MAX_ARF_GOP_SIZE; ++frame) {
-#if CONFIG_NON_GREEDY_MV
-    int rf_idx;
-    for (rf_idx = 0; rf_idx < 3; ++rf_idx) {
-      int sqr_bsize;
-      for (sqr_bsize = 0; sqr_bsize < SQUARE_BLOCK_SIZES; ++sqr_bsize) {
-        vpx_free(cpi->tpl_stats[frame].pyramid_mv_arr[rf_idx][sqr_bsize]);
-      }
-      vpx_free(cpi->tpl_stats[frame].mv_mode_arr[rf_idx]);
-      vpx_free(cpi->tpl_stats[frame].rd_diff_arr[rf_idx]);
-    }
-#endif
-    vpx_free(cpi->tpl_stats[frame].tpl_stats_ptr);
-    cpi->tpl_stats[frame].is_valid = 0;
-  }
+  free_tpl_buffer(cpi);
 
   for (t = 0; t < cpi->num_workers; ++t) {
     VPxWorker *const worker = &cpi->workers[t];
@@ -6301,7 +6283,7 @@
 
   set_mv_limits(cm, x, mi_row, mi_col);
 
-  for (rf_idx = 0; rf_idx < 3; ++rf_idx) {
+  for (rf_idx = 0; rf_idx < MAX_INTER_REF_FRAMES; ++rf_idx) {
     int_mv mv;
     if (ref_frame[rf_idx] == NULL) continue;
 
@@ -6854,9 +6836,9 @@
 #endif  // USE_PQSORT
 #endif  // CHANGE_MV_SEARCH_ORDER
 
-static void build_motion_field(VP9_COMP *cpi, MACROBLOCKD *xd, int frame_idx,
-                               YV12_BUFFER_CONFIG *ref_frame[3],
-                               BLOCK_SIZE bsize) {
+static void build_motion_field(
+    VP9_COMP *cpi, MACROBLOCKD *xd, int frame_idx,
+    YV12_BUFFER_CONFIG *ref_frame[MAX_INTER_REF_FRAMES], BLOCK_SIZE bsize) {
   VP9_COMMON *cm = &cpi->common;
   ThreadData *td = &cpi->td;
   TplDepFrame *tpl_frame = &cpi->tpl_stats[frame_idx];
@@ -6897,7 +6879,7 @@
   qsort(cpi->feature_score_loc_sort, fs_loc_sort_size,
         sizeof(*cpi->feature_score_loc_sort), compare_feature_score);
 
-  for (rf_idx = 0; rf_idx < 3; ++rf_idx) {
+  for (rf_idx = 0; rf_idx < MAX_INTER_REF_FRAMES; ++rf_idx) {
     for (mi_row = 0; mi_row < cm->mi_rows; mi_row += mi_height) {
       for (mi_col = 0; mi_col < cm->mi_cols; mi_col += mi_width) {
         TplDepStats *tpl_stats =
@@ -6908,7 +6890,7 @@
   }
 
   // TODO(angiebird): Clean up this part.
-  for (rf_idx = 0; rf_idx < 3; ++rf_idx) {
+  for (rf_idx = 0; rf_idx < MAX_INTER_REF_FRAMES; ++rf_idx) {
     int i;
     if (ref_frame[rf_idx] == NULL) {
       continue;
@@ -6956,7 +6938,7 @@
                               int frame_idx, BLOCK_SIZE bsize) {
   TplDepFrame *tpl_frame = &cpi->tpl_stats[frame_idx];
   YV12_BUFFER_CONFIG *this_frame = gf_picture[frame_idx].frame;
-  YV12_BUFFER_CONFIG *ref_frame[3] = { NULL, NULL, NULL };
+  YV12_BUFFER_CONFIG *ref_frame[MAX_INTER_REF_FRAMES] = { NULL, NULL, NULL };
 
   VP9_COMMON *cm = &cpi->common;
   struct scale_factors sf;
@@ -7006,7 +6988,7 @@
 
   // Prepare reference frame pointers. If any reference frame slot is
   // unavailable, the pointer will be set to Null.
-  for (idx = 0; idx < 3; ++idx) {
+  for (idx = 0; idx < MAX_INTER_REF_FRAMES; ++idx) {
     int rf_idx = gf_picture[frame_idx].ref_frame[idx];
     if (rf_idx != -1) ref_frame[idx] = gf_picture[rf_idx].frame;
   }
@@ -7031,7 +7013,7 @@
     BLOCK_SIZE square_bsize = square_block_idx_to_bsize(square_block_idx);
     build_motion_field(cpi, xd, frame_idx, ref_frame, square_bsize);
   }
-  for (rf_idx = 0; rf_idx < 3; ++rf_idx) {
+  for (rf_idx = 0; rf_idx < MAX_INTER_REF_FRAMES; ++rf_idx) {
     int ref_frame_idx = gf_picture[frame_idx].ref_frame[rf_idx];
     if (ref_frame_idx != -1) {
       predict_mv_mode_arr(cpi, x, gf_picture, frame_idx, tpl_frame, rf_idx,
@@ -7085,7 +7067,7 @@
   const VP9_COMMON *cm = &cpi->common;
   int rf_idx;
   for (frame_idx = 1; frame_idx < tpl_group_frames; ++frame_idx) {
-    for (rf_idx = 0; rf_idx < 3; ++rf_idx) {
+    for (rf_idx = 0; rf_idx < MAX_INTER_REF_FRAMES; ++rf_idx) {
       const TplDepFrame *tpl_frame = &cpi->tpl_stats[frame_idx];
       int mi_row, mi_col;
       int ref_frame_idx;
@@ -7156,6 +7138,8 @@
 
   // TODO(angiebird): This probably needs further modifications to support
   // frame scaling later on.
+  vp9_alloc_motion_field_info(&cpi->motion_field_info, MAX_ARF_GOP_SIZE,
+                              mi_rows, mi_cols);
   if (cpi->feature_score_loc_alloc == 0) {
     // The smallest block size of motion field is 4x4, but the mi_unit is 8x8,
     // therefore the number of units is "mi_rows * mi_cols * 4" here.
@@ -7185,7 +7169,7 @@
       continue;
 
 #if CONFIG_NON_GREEDY_MV
-    for (rf_idx = 0; rf_idx < 3; ++rf_idx) {
+    for (rf_idx = 0; rf_idx < MAX_INTER_REF_FRAMES; ++rf_idx) {
       for (sqr_bsize = 0; sqr_bsize < SQUARE_BLOCK_SIZES; ++sqr_bsize) {
         vpx_free(cpi->tpl_stats[frame].pyramid_mv_arr[rf_idx][sqr_bsize]);
         CHECK_MEM_ERROR(
@@ -7222,6 +7206,32 @@
   for (frame = 0; frame < REF_FRAMES; ++frame) {
     cpi->enc_frame_buf[frame].mem_valid = 0;
     cpi->enc_frame_buf[frame].released = 1;
+  }
+}
+
+static void free_tpl_buffer(VP9_COMP *cpi) {
+  int frame;
+#if CONFIG_NON_GREEDY_MV
+  vp9_free_motion_field_info(&cpi->motion_field_info);
+  vpx_free(cpi->feature_score_loc_arr);
+  vpx_free(cpi->feature_score_loc_sort);
+  vpx_free(cpi->feature_score_loc_heap);
+  vpx_free(cpi->select_mv_arr);
+#endif
+  for (frame = 0; frame < MAX_ARF_GOP_SIZE; ++frame) {
+#if CONFIG_NON_GREEDY_MV
+    int rf_idx;
+    for (rf_idx = 0; rf_idx < MAX_INTER_REF_FRAMES; ++rf_idx) {
+      int sqr_bsize;
+      for (sqr_bsize = 0; sqr_bsize < SQUARE_BLOCK_SIZES; ++sqr_bsize) {
+        vpx_free(cpi->tpl_stats[frame].pyramid_mv_arr[rf_idx][sqr_bsize]);
+      }
+      vpx_free(cpi->tpl_stats[frame].mv_mode_arr[rf_idx]);
+      vpx_free(cpi->tpl_stats[frame].rd_diff_arr[rf_idx]);
+    }
+#endif
+    vpx_free(cpi->tpl_stats[frame].tpl_stats_ptr);
+    cpi->tpl_stats[frame].is_valid = 0;
   }
 }
 
--- a/vp9/encoder/vp9_encoder.h
+++ b/vp9/encoder/vp9_encoder.h
@@ -576,6 +576,7 @@
   int kmeans_count_ls[MAX_KMEANS_GROUPS];
   int kmeans_ctr_num;
 #if CONFIG_NON_GREEDY_MV
+  MotionFieldInfo motion_field_info;
   int tpl_ready;
   int feature_score_loc_alloc;
   FEATURE_SCORE_LOC *feature_score_loc_arr;
--- a/vp9/encoder/vp9_non_greedy_mv.c
+++ b/vp9/encoder/vp9_non_greedy_mv.c
@@ -168,14 +168,18 @@
   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) {
+Status 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;
+  if (motion_field_info->allocated == 1) {
+    // TODO(angiebird): Avoid re-allocate buffer if possible
+    vp9_free_motion_field_info(motion_field_info);
+  }
   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 (rf_idx = 0; rf_idx < MAX_INTER_REF_FRAMES; ++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);
@@ -186,14 +190,22 @@
         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);
+        Status status =
+            vp9_alloc_motion_field(motion_field, bsize, block_rows, block_cols);
+        if (status == STATUS_FAILED) {
+          assert(0);
+          return STATUS_FAILED;
+        }
       }
     }
   }
+  motion_field_info->allocated = 1;
+  return STATUS_OK;
 }
 
-void vp9_alloc_motion_field(MotionField *motion_field, BLOCK_SIZE bsize,
-                            int block_rows, int block_cols) {
+Status vp9_alloc_motion_field(MotionField *motion_field, BLOCK_SIZE bsize,
+                              int block_rows, int block_cols) {
+  Status status = STATUS_OK;
   motion_field->ready = 0;
   motion_field->bsize = bsize;
   motion_field->block_rows = block_rows;
@@ -200,10 +212,17 @@
   motion_field->block_cols = block_cols;
   motion_field->mf =
       vpx_calloc(block_rows * block_cols, sizeof(*motion_field->mf));
-  assert(motion_field->mf != NULL);
+  if (motion_field->mf == NULL) {
+    assert(0);
+    status = STATUS_FAILED;
+  }
   motion_field->local_structure = vpx_calloc(
       block_rows * block_cols, sizeof(*motion_field->local_structure));
-  assert(motion_field->local_structure != NULL);
+  if (motion_field->local_structure == NULL) {
+    assert(0);
+    status = STATUS_FAILED;
+  }
+  return status;
 }
 
 void vp9_free_motion_field(MotionField *motion_field) {
@@ -213,21 +232,24 @@
 }
 
 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);
+  if (motion_field_info->allocated) {
+    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 < MAX_INTER_REF_FRAMES; ++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;
+    motion_field_info->allocated = 0;
   }
-  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) {
--- a/vp9/encoder/vp9_non_greedy_mv.h
+++ b/vp9/encoder/vp9_non_greedy_mv.h
@@ -24,6 +24,8 @@
 #define MF_LOCAL_STRUCTURE_SIZE 4
 #define SQUARE_BLOCK_SIZES 4
 
+typedef enum Status { STATUS_OK = 0, STATUS_FAILED = 1 } Status;
+
 typedef struct MotionField {
   int ready;
   BLOCK_SIZE bsize;
@@ -36,7 +38,8 @@
 
 typedef struct MotionFieldInfo {
   int frame_num;
-  MotionField (*motion_field_array)[3][SQUARE_BLOCK_SIZES];
+  int allocated;
+  MotionField (*motion_field_array)[MAX_INTER_REF_FRAMES][SQUARE_BLOCK_SIZES];
 } MotionFieldInfo;
 
 typedef struct {
@@ -77,11 +80,11 @@
   return BLOCK_INVALID;
 }
 
-void vp9_alloc_motion_field_info(MotionFieldInfo *motion_field_info,
-                                 int frame_num, int mi_rows, int mi_cols);
+Status vp9_alloc_motion_field_info(MotionFieldInfo *motion_field_info,
+                                   int frame_num, int mi_rows, int mi_cols);
 
-void vp9_alloc_motion_field(MotionField *motion_field, BLOCK_SIZE bsize,
-                            int block_rows, int block_cols);
+Status vp9_alloc_motion_field(MotionField *motion_field, BLOCK_SIZE bsize,
+                              int block_rows, int block_cols);
 
 void vp9_free_motion_field(MotionField *motion_field);