Dynamically allocate memory for level stats

Only allocate memory for level related stats when necessary.

Change-Id: If04aec82480db99f56c86076efcc069606fc1149
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index 99c2a69..f795011 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -597,6 +597,10 @@
     aom_film_grain_table_free(cpi->film_grain_table);
     cpi->film_grain_table = NULL;
   }
+
+  for (int i = 0; i < MAX_NUM_OPERATING_POINTS; ++i) {
+    aom_free(cpi->level_info[i]);
+  }
 }
 
 static void save_coding_context(AV1_COMP *cpi) {
@@ -2412,6 +2416,10 @@
   for (int i = 0; i < MAX_NUM_OPERATING_POINTS; ++i) {
     if (cpi->target_seq_level_idx[i] < SEQ_LEVELS) {
       cpi->keep_level_stats |= 1u << i;
+      if (!cpi->level_info[i]) {
+        CHECK_MEM_ERROR(cm, cpi->level_info[i],
+                        aom_calloc(1, sizeof(*cpi->level_info[i])));
+      }
     }
   }
 
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index 319c652..5273464 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -1010,7 +1010,7 @@
   // Bit mask to indicate whether to keep level stats for corresponding
   // operating points.
   uint32_t keep_level_stats;
-  AV1LevelInfo level_info[MAX_NUM_OPERATING_POINTS];
+  AV1LevelInfo *level_info[MAX_NUM_OPERATING_POINTS];
   // Count the number of OBU_FRAME and OBU_FRAME_HEADER for level calculation.
   int frame_header_count;
   FrameWindowBuffer frame_window_buffer;
diff --git a/av1/encoder/level.c b/av1/encoder/level.c
index 954560a..335e6e1 100644
--- a/av1/encoder/level.c
+++ b/av1/encoder/level.c
@@ -639,12 +639,14 @@
   }
 }
 
-void av1_init_level_info(AV1LevelInfo *level_info) {
-  memset(level_info, 0, MAX_NUM_OPERATING_POINTS * sizeof(*level_info));
+void av1_init_level_info(AV1LevelInfo *level_info[]) {
   for (int i = 0; i < MAX_NUM_OPERATING_POINTS; ++i) {
-    AV1LevelSpec *const level_spec = &level_info[i].level_spec;
+    AV1LevelInfo *this_level_info = level_info[i];
+    if (!this_level_info) continue;
+    memset(this_level_info, 0, sizeof(*this_level_info));
+    AV1LevelSpec *const level_spec = &this_level_info->level_spec;
     level_spec->level = SEQ_LEVEL_MAX;
-    AV1LevelStats *const level_stats = &level_info[i].level_stats;
+    AV1LevelStats *const level_stats = &this_level_info->level_stats;
     level_stats->min_cropped_tile_width = INT_MAX;
     level_stats->min_cropped_tile_height = INT_MAX;
     level_stats->min_frame_width = INT_MAX;
@@ -1003,7 +1005,8 @@
       continue;
     }
 
-    AV1LevelInfo *const level_info = &cpi->level_info[i];
+    AV1LevelInfo *const level_info = cpi->level_info[i];
+    assert(level_info != NULL);
     AV1LevelStats *const level_stats = &level_info->level_stats;
 
     level_stats->max_tile_size =
@@ -1066,7 +1069,8 @@
     seq_level_idx[op] = (int)SEQ_LEVEL_MAX;
     if (!((cpi->keep_level_stats >> op) & 1)) continue;
     const int tier = seq_params->tier[op];
-    const AV1LevelInfo *const level_info = &cpi->level_info[op];
+    const AV1LevelInfo *const level_info = cpi->level_info[op];
+    assert(level_info != NULL);
     const AV1LevelStats *const level_stats = &level_info->level_stats;
     const AV1LevelSpec *const level_spec = &level_info->level_spec;
     for (int level = 0; level < SEQ_LEVELS; ++level) {
diff --git a/av1/encoder/level.h b/av1/encoder/level.h
index fca0cae..142d03b 100644
--- a/av1/encoder/level.h
+++ b/av1/encoder/level.h
@@ -143,7 +143,7 @@
   size_t coded_bits;
 } DECODER_MODEL;
 
-void av1_init_level_info(AV1LevelInfo *level_info);
+void av1_init_level_info(AV1LevelInfo *level_info[]);
 
 void av1_update_level_info(struct AV1_COMP *cpi, size_t size, int64_t ts_start,
                            int64_t ts_end);