From: Attila Nagy Date: Tue, 24 Apr 2012 12:33:44 +0000 (+0300) Subject: Moves error concealment allocations from common parts to decoder X-Git-Tag: 1.0_branch~34 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=24e7b1b90d802dacea4daeeb03984184c7b74d2a;hp=0c483d6b683fa4313cf7dadf448a707fe32714a4;p=profile%2Fivi%2Flibvpx.git Moves error concealment allocations from common parts to decoder 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 --- diff --git a/vp8/common/alloccommon.c b/vp8/common/alloccommon.c index d58e49c..86485ac 100644 --- a/vp8/common/alloccommon.c +++ b/vp8/common/alloccommon.c @@ -17,23 +17,6 @@ #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) diff --git a/vp8/common/onyxc_int.h b/vp8/common/onyxc_int.h index 0e4c9be..d7d02c2 100644 --- a/vp8/common/onyxc_int.h +++ b/vp8/common/onyxc_int.h @@ -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; diff --git a/vp8/decoder/decodframe.c b/vp8/decoder/decodframe.c index 3332f67..d11933e 100644 --- a/vp8/decoder/decodframe.c +++ b/vp8/decoder/decodframe.c @@ -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; } diff --git a/vp8/decoder/error_concealment.c b/vp8/decoder/error_concealment.c index 7750728..8b2e32b 100644 --- a/vp8/decoder/error_concealment.c +++ b/vp8/decoder/error_concealment.c @@ -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; } diff --git a/vp8/decoder/onyxd_if.c b/vp8/decoder/onyxd_if.c index d835953..8d9cca3 100644 --- a/vp8/decoder/onyxd_if.c +++ b/vp8/decoder/onyxd_if.c @@ -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