shithub: libvpx

Download patch

ref: fec40f9269bee20171fbd6570caa67203d497284
parent: c29cc89c78dcd5cdf66e879f284de40cb0d85a08
author: James Zern <jzern@google.com>
date: Thu Aug 28 13:11:31 EDT 2014

vp9: fix m/t loop filter invalid free

store the number of allocated rows in VP9LfSync, the calculated values
can not be relied on when dealing with corrupt material.

Change-Id: I13b8bcec9738c299a71df726772ab7ac05511e5b

--- a/test/invalid_file_test.cc
+++ b/test/invalid_file_test.cc
@@ -147,6 +147,7 @@
   {4, "invalid-"
       "vp90-2-08-tile_1x2_frame_parallel.webm.ivf.s47039_r01-05_b6-.ivf"},
   {2, "invalid-vp90-2-09-aq2.webm.ivf.s3984_r01-05_b6-.ivf"},
+  {4, "invalid-vp90-2-09-subpixel-00.ivf.s19552_r01-05_b6-.ivf"},
 };
 
 INSTANTIATE_TEST_CASE_P(
--- a/test/test-data.sha1
+++ b/test/test-data.sha1
@@ -685,3 +685,5 @@
 0a3884edb3fd8f9d9b500223e650f7de257b67d8  invalid-vp90-2-08-tile_1x2_frame_parallel.webm.ivf.s47039_r01-05_b6-.ivf.res
 fac89b5735be8a86b0dc05159f996a5c3208ae32  invalid-vp90-2-09-aq2.webm.ivf.s3984_r01-05_b6-.ivf
 22e0ee8babe574722baf4ef6d7ff5d7cf80d386c  invalid-vp90-2-09-aq2.webm.ivf.s3984_r01-05_b6-.ivf.res
+4506dfdcdf8ee4250924b075a0dcf1f070f72e5a  invalid-vp90-2-09-subpixel-00.ivf.s19552_r01-05_b6-.ivf
+d3ea592c8d7b05d14c7ed48befc0a3aaf7709b7a  invalid-vp90-2-09-subpixel-00.ivf.s19552_r01-05_b6-.ivf.res
--- a/test/test.mk
+++ b/test/test.mk
@@ -807,6 +807,8 @@
 LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm.res
 LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-09-aq2.webm.ivf.s3984_r01-05_b6-.ivf
 LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-09-aq2.webm.ivf.s3984_r01-05_b6-.ivf.res
+LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-09-subpixel-00.ivf.s19552_r01-05_b6-.ivf
+LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-09-subpixel-00.ivf.s19552_r01-05_b6-.ivf.res
 
 ifeq ($(CONFIG_DECODE_PERF_TESTS),yes)
 # BBB VP9 streams
--- a/vp9/decoder/vp9_decoder.c
+++ b/vp9/decoder/vp9_decoder.c
@@ -96,10 +96,8 @@
   }
   vpx_free(pbi->tile_workers);
 
-  if (pbi->num_tile_workers) {
-    const int sb_rows =
-        mi_cols_aligned_to_sb(cm->mi_rows) >> MI_BLOCK_SIZE_LOG2;
-    vp9_loop_filter_dealloc(&pbi->lf_row_sync, sb_rows);
+  if (pbi->num_tile_workers > 0) {
+    vp9_loop_filter_dealloc(&pbi->lf_row_sync);
   }
 
   vp9_remove_common(cm);
--- a/vp9/decoder/vp9_dthread.c
+++ b/vp9/decoder/vp9_dthread.c
@@ -148,16 +148,7 @@
   // Allocate memory used in thread synchronization.
   // This always needs to be done even if frame_filter_level is 0.
   if (!lf_sync->sync_range || cm->last_height != cm->height) {
-    if (cm->last_height != cm->height) {
-      const int aligned_last_height =
-          ALIGN_POWER_OF_TWO(cm->last_height, MI_SIZE_LOG2);
-      const int last_sb_rows =
-          mi_cols_aligned_to_sb(aligned_last_height >> MI_SIZE_LOG2) >>
-          MI_BLOCK_SIZE_LOG2;
-
-      vp9_loop_filter_dealloc(lf_sync, last_sb_rows);
-    }
-
+    vp9_loop_filter_dealloc(lf_sync);
     vp9_loop_filter_alloc(cm, lf_sync, sb_rows, cm->width);
   }
 
@@ -227,19 +218,22 @@
 // Allocate memory for lf row synchronization
 void vp9_loop_filter_alloc(VP9_COMMON *cm, VP9LfSync *lf_sync, int rows,
                            int width) {
+  lf_sync->rows = rows;
 #if CONFIG_MULTITHREAD
-  int i;
+  {
+    int i;
 
-  CHECK_MEM_ERROR(cm, lf_sync->mutex_,
-                  vpx_malloc(sizeof(*lf_sync->mutex_) * rows));
-  for (i = 0; i < rows; ++i) {
-    pthread_mutex_init(&lf_sync->mutex_[i], NULL);
-  }
+    CHECK_MEM_ERROR(cm, lf_sync->mutex_,
+                    vpx_malloc(sizeof(*lf_sync->mutex_) * rows));
+    for (i = 0; i < rows; ++i) {
+      pthread_mutex_init(&lf_sync->mutex_[i], NULL);
+    }
 
-  CHECK_MEM_ERROR(cm, lf_sync->cond_,
-                  vpx_malloc(sizeof(*lf_sync->cond_) * rows));
-  for (i = 0; i < rows; ++i) {
-    pthread_cond_init(&lf_sync->cond_[i], NULL);
+    CHECK_MEM_ERROR(cm, lf_sync->cond_,
+                    vpx_malloc(sizeof(*lf_sync->cond_) * rows));
+    for (i = 0; i < rows; ++i) {
+      pthread_cond_init(&lf_sync->cond_[i], NULL);
+    }
   }
 #endif  // CONFIG_MULTITHREAD
 
@@ -251,23 +245,19 @@
 }
 
 // Deallocate lf synchronization related mutex and data
-void vp9_loop_filter_dealloc(VP9LfSync *lf_sync, int rows) {
-#if !CONFIG_MULTITHREAD
-  (void)rows;
-#endif  // !CONFIG_MULTITHREAD
-
+void vp9_loop_filter_dealloc(VP9LfSync *lf_sync) {
   if (lf_sync != NULL) {
 #if CONFIG_MULTITHREAD
     int i;
 
     if (lf_sync->mutex_ != NULL) {
-      for (i = 0; i < rows; ++i) {
+      for (i = 0; i < lf_sync->rows; ++i) {
         pthread_mutex_destroy(&lf_sync->mutex_[i]);
       }
       vpx_free(lf_sync->mutex_);
     }
     if (lf_sync->cond_ != NULL) {
-      for (i = 0; i < rows; ++i) {
+      for (i = 0; i < lf_sync->rows; ++i) {
         pthread_cond_destroy(&lf_sync->cond_[i]);
       }
       vpx_free(lf_sync->cond_);
--- a/vp9/decoder/vp9_dthread.h
+++ b/vp9/decoder/vp9_dthread.h
@@ -38,6 +38,7 @@
   // The optimal sync_range for different resolution and platform should be
   // determined by testing. Currently, it is chosen to be a power-of-2 number.
   int sync_range;
+  int rows;
 } VP9LfSync;
 
 // Allocate memory for loopfilter row synchronization.
@@ -45,7 +46,7 @@
                            int rows, int width);
 
 // Deallocate loopfilter synchronization related mutex and data.
-void vp9_loop_filter_dealloc(VP9LfSync *lf_sync, int rows);
+void vp9_loop_filter_dealloc(VP9LfSync *lf_sync);
 
 // Multi-threaded loopfilter that uses the tile threads.
 void vp9_loop_filter_frame_mt(YV12_BUFFER_CONFIG *frame,