Moves error concealment allocations from common parts to decoder
authorAttila Nagy <attilanagy@google.com>
Tue, 24 Apr 2012 12:33:44 +0000 (15:33 +0300)
committerAttila Nagy <attilanagy@google.com>
Thu, 26 Apr 2012 08:49:15 +0000 (11:49 +0300)
The backup MODE_INFO buffer used in the error concealment was
allocated in the codec common parts allocation even though this is a
decoder only resource. Moved the allocation to the decoder side.
No need to update_mode_info_border as mode_info buffers are zero
allocated.

This fixes also a potential memory leak as the EC overlaps buffer was not
properly released before reallocation after a frame size change.

Change-Id: I12803d3e012308d95669069980b1c95973fb775f

vp8/common/alloccommon.c
vp8/common/onyxc_int.h
vp8/decoder/decodframe.c
vp8/decoder/error_concealment.c
vp8/decoder/onyxd_if.c

index d58e49c..86485ac 100644 (file)
 #include "entropymode.h"
 #include "systemdependent.h"
 
-
-extern  void vp8_init_scan_order_mask();
-
-static void update_mode_info_border(MODE_INFO *mi, int rows, int cols)
-{
-    int i;
-    vpx_memset(mi - cols - 2, 0, sizeof(MODE_INFO) * (cols + 1));
-
-    for (i = 0; i < rows; i++)
-    {
-        /* TODO(holmer): Bug? This updates the last element of each row
-         * rather than the border element!
-         */
-        vpx_memset(&mi[i*cols-1], 0, sizeof(MODE_INFO));
-    }
-}
-
 void vp8_de_alloc_frame_buffers(VP8_COMMON *oci)
 {
     int i;
@@ -49,12 +32,13 @@ void vp8_de_alloc_frame_buffers(VP8_COMMON *oci)
 
     vpx_free(oci->above_context);
     vpx_free(oci->mip);
+#if CONFIG_ERROR_CONCEALMENT
     vpx_free(oci->prev_mip);
+    oci->prev_mip = NULL;
+#endif
 
-    oci->above_context = 0;
-    oci->mip = 0;
-    oci->prev_mip = 0;
-
+    oci->above_context = NULL;
+    oci->mip = NULL;
 }
 
 int vp8_alloc_frame_buffers(VP8_COMMON *oci, int width, int height)
@@ -124,21 +108,8 @@ int vp8_alloc_frame_buffers(VP8_COMMON *oci, int width, int height)
 
     oci->mi = oci->mip + oci->mode_info_stride + 1;
 
-    /* allocate memory for last frame MODE_INFO array */
-#if CONFIG_ERROR_CONCEALMENT
-    oci->prev_mip = vpx_calloc((oci->mb_cols + 1) * (oci->mb_rows + 1), sizeof(MODE_INFO));
-
-    if (!oci->prev_mip)
-    {
-        vp8_de_alloc_frame_buffers(oci);
-        return 1;
-    }
-
-    oci->prev_mi = oci->prev_mip + oci->mode_info_stride + 1;
-#else
-    oci->prev_mip = NULL;
-    oci->prev_mi = NULL;
-#endif
+    /* Allocation of previous mode info will be done in vp8_decode_frame()
+     * as it is a decoder only data */
 
     oci->above_context = vpx_calloc(sizeof(ENTROPY_CONTEXT_PLANES) * oci->mb_cols, 1);
 
@@ -148,11 +119,6 @@ int vp8_alloc_frame_buffers(VP8_COMMON *oci, int width, int height)
         return 1;
     }
 
-    update_mode_info_border(oci->mi, oci->mb_rows, oci->mb_cols);
-#if CONFIG_ERROR_CONCEALMENT
-    update_mode_info_border(oci->prev_mi, oci->mb_rows, oci->mb_cols);
-#endif
-
     return 0;
 }
 void vp8_setup_version(VP8_COMMON *cm)
index 0e4c9be..d7d02c2 100644 (file)
@@ -124,9 +124,10 @@ typedef struct VP8Common
 
     MODE_INFO *mip; /* Base of allocated array */
     MODE_INFO *mi;  /* Corresponds to upper left visible macroblock */
+#if CONFIG_ERROR_CONCEALMENT
     MODE_INFO *prev_mip; /* MODE_INFO array 'mip' from last decoded frame */
     MODE_INFO *prev_mi;  /* 'mi' from last frame (points into prev_mip) */
-
+#endif
 
     LOOPFILTERTYPE filter_type;
 
index 3332f67..d11933e 100644 (file)
@@ -821,20 +821,40 @@ int vp8_decode_frame(VP8D_COMP *pbi)
                     vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR,
                                        "Failed to allocate frame buffers");
 
+                /* allocate memory for last frame MODE_INFO array */
 #if CONFIG_ERROR_CONCEALMENT
-                pbi->overlaps = NULL;
+
                 if (pbi->ec_enabled)
                 {
+                    /* old prev_mip was released by vp8_de_alloc_frame_buffers()
+                     * called in vp8_alloc_frame_buffers() */
+                    pc->prev_mip = vpx_calloc(
+                                       (pc->mb_cols + 1) * (pc->mb_rows + 1),
+                                       sizeof(MODE_INFO));
+
+                    if (!pc->prev_mip)
+                    {
+                        vp8_de_alloc_frame_buffers(pc);
+                        vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR,
+                                           "Failed to allocate"
+                                           "last frame MODE_INFO array");
+                    }
+
+                    pc->prev_mi = pc->prev_mip + pc->mode_info_stride + 1;
+
                     if (vp8_alloc_overlap_lists(pbi))
                         vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR,
                                            "Failed to allocate overlap lists "
                                            "for error concealment");
                 }
+
 #endif
 
 #if CONFIG_MULTITHREAD
+
                 if (pbi->b_multithreaded_rd)
                     vp8mt_alloc_temp_buffers(pbi, pc->Width, prev_mb_rows);
+
 #endif
                 frame_size_change = 1;
             }
index 7750728..8b2e32b 100644 (file)
@@ -51,12 +51,13 @@ int vp8_alloc_overlap_lists(VP8D_COMP *pbi)
         vpx_free(pbi->overlaps);
         pbi->overlaps = NULL;
     }
+
     pbi->overlaps = vpx_calloc(pbi->common.mb_rows * pbi->common.mb_cols,
                                sizeof(MB_OVERLAP));
+
     if (pbi->overlaps == NULL)
         return -1;
-    vpx_memset(pbi->overlaps, 0,
-               sizeof(MB_OVERLAP) * pbi->common.mb_rows * pbi->common.mb_cols);
+
     return 0;
 }
 
index d835953..8d9cca3 100644 (file)
@@ -80,6 +80,7 @@ struct VP8D_COMP * vp8dx_create_decompressor(VP8D_CONFIG *oxcf)
 
 #if CONFIG_ERROR_CONCEALMENT
     pbi->ec_enabled = oxcf->error_concealment;
+    pbi->overlaps = NULL;
 #else
     pbi->ec_enabled = 0;
 #endif