Fix heap corruption in case of resizing with row-mt=1

When the number of superblock columns change, entropy
context memory is not reallocated resulting in heap
corruption. This patch reallocates row-mt related
memory whenever there is a change in the number of
superblock columns.

BUG=aomedia:2710

Change-Id: Ifed5b1ed27acfa6fde37b2a00e01e5ea767d6eb3
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index d8f5a0a..e88b0e0 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -1128,6 +1128,11 @@
    * per tile.
    */
   int allocated_sb_rows;
+  /*!
+   * Number of superblock columns for which entropy context memory is allocated
+   * per tile.
+   */
+  int allocated_sb_cols;
 
   /*!
    * thread_id_to_tile_id[i] indicates the tile id assigned to the ith thread.
diff --git a/av1/encoder/ethread.c b/av1/encoder/ethread.c
index d8ade05..63f7b87 100644
--- a/av1/encoder/ethread.c
+++ b/av1/encoder/ethread.c
@@ -217,7 +217,8 @@
   }
 }
 
-static void row_mt_mem_alloc(AV1_COMP *cpi, int max_sb_rows) {
+static void row_mt_mem_alloc(AV1_COMP *cpi, int max_sb_rows, int max_sb_cols,
+                             int alloc_row_ctx) {
   struct AV1Common *cm = &cpi->common;
   AV1EncRowMultiThreadInfo *const enc_row_mt = &cpi->mt_info.enc_row_mt;
   const int tile_cols = cm->tiles.cols;
@@ -232,10 +233,10 @@
 
       row_mt_sync_mem_alloc(&this_tile->row_mt_sync, cm, max_sb_rows);
 
-      if (cpi->oxcf.cdf_update_mode) {
-        const int sb_cols_in_tile =
-            av1_get_sb_cols_in_tile(cm, this_tile->tile_info);
-        const int num_row_ctx = AOMMAX(1, (sb_cols_in_tile - 1));
+      this_tile->row_ctx = NULL;
+      if (alloc_row_ctx) {
+        assert(max_sb_cols > 0);
+        const int num_row_ctx = AOMMAX(1, (max_sb_cols - 1));
         CHECK_MEM_ERROR(cm, this_tile->row_ctx,
                         (FRAME_CONTEXT *)aom_memalign(
                             16, num_row_ctx * sizeof(*this_tile->row_ctx)));
@@ -245,6 +246,7 @@
   enc_row_mt->allocated_tile_cols = tile_cols;
   enc_row_mt->allocated_tile_rows = tile_rows;
   enc_row_mt->allocated_sb_rows = max_sb_rows;
+  enc_row_mt->allocated_sb_cols = max_sb_cols - 1;
 }
 
 void av1_row_mt_mem_dealloc(AV1_COMP *cpi) {
@@ -901,20 +903,21 @@
 
 // Computes the maximum number of sb_rows for row multi-threading of encoding
 // stage
-static AOM_INLINE int compute_max_sb_rows(AV1_COMP *cpi) {
+static AOM_INLINE void compute_max_sb_rows_cols(AV1_COMP *cpi, int *max_sb_rows,
+                                                int *max_sb_cols) {
   AV1_COMMON *const cm = &cpi->common;
   const int tile_cols = cm->tiles.cols;
   const int tile_rows = cm->tiles.rows;
-  int max_sb_rows = 0;
   for (int row = 0; row < tile_rows; row++) {
     for (int col = 0; col < tile_cols; col++) {
       const int tile_index = row * cm->tiles.cols + col;
       TileInfo tile_info = cpi->tile_data[tile_index].tile_info;
       const int num_sb_rows_in_tile = av1_get_sb_rows_in_tile(cm, tile_info);
-      max_sb_rows = AOMMAX(max_sb_rows, num_sb_rows_in_tile);
+      const int num_sb_cols_in_tile = av1_get_sb_cols_in_tile(cm, tile_info);
+      *max_sb_rows = AOMMAX(*max_sb_rows, num_sb_rows_in_tile);
+      *max_sb_cols = AOMMAX(*max_sb_cols, num_sb_cols_in_tile);
     }
   }
-  return max_sb_rows;
 }
 
 #if !CONFIG_REALTIME_ONLY
@@ -966,7 +969,7 @@
   const int tile_cols = cm->tiles.cols;
   const int tile_rows = cm->tiles.rows;
   int *thread_id_to_tile_id = enc_row_mt->thread_id_to_tile_id;
-  int max_sb_rows = 0;
+  int max_sb_rows = 0, max_sb_cols = 0;
 
   // TODO(ravi.chaudhary@ittiam.com): Currently the percentage of
   // post-processing stages in encoder is quiet low, so limiting the number of
@@ -984,13 +987,14 @@
 
   av1_init_tile_data(cpi);
 
-  max_sb_rows = compute_max_sb_rows(cpi);
+  compute_max_sb_rows_cols(cpi, &max_sb_rows, &max_sb_cols);
 
   if (enc_row_mt->allocated_tile_cols != tile_cols ||
       enc_row_mt->allocated_tile_rows != tile_rows ||
-      enc_row_mt->allocated_sb_rows != max_sb_rows) {
+      enc_row_mt->allocated_sb_rows != max_sb_rows ||
+      enc_row_mt->allocated_sb_cols != (max_sb_cols - 1)) {
     av1_row_mt_mem_dealloc(cpi);
-    row_mt_mem_alloc(cpi, max_sb_rows);
+    row_mt_mem_alloc(cpi, max_sb_rows, max_sb_cols, cpi->oxcf.cdf_update_mode);
   }
 
   memset(thread_id_to_tile_id, -1,
@@ -1063,7 +1067,7 @@
       enc_row_mt->allocated_tile_rows != tile_rows ||
       enc_row_mt->allocated_sb_rows != max_mb_rows) {
     av1_row_mt_mem_dealloc(cpi);
-    row_mt_mem_alloc(cpi, max_mb_rows);
+    row_mt_mem_alloc(cpi, max_mb_rows, -1, 0);
   }
 
   memset(thread_id_to_tile_id, -1,