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
This commit is contained in:
@@ -17,23 +17,6 @@
|
|||||||
#include "entropymode.h"
|
#include "entropymode.h"
|
||||||
#include "systemdependent.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)
|
void vp8_de_alloc_frame_buffers(VP8_COMMON *oci)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -49,12 +32,13 @@ void vp8_de_alloc_frame_buffers(VP8_COMMON *oci)
|
|||||||
|
|
||||||
vpx_free(oci->above_context);
|
vpx_free(oci->above_context);
|
||||||
vpx_free(oci->mip);
|
vpx_free(oci->mip);
|
||||||
|
#if CONFIG_ERROR_CONCEALMENT
|
||||||
vpx_free(oci->prev_mip);
|
vpx_free(oci->prev_mip);
|
||||||
|
oci->prev_mip = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
oci->above_context = 0;
|
oci->above_context = NULL;
|
||||||
oci->mip = 0;
|
oci->mip = NULL;
|
||||||
oci->prev_mip = 0;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int vp8_alloc_frame_buffers(VP8_COMMON *oci, int width, int height)
|
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;
|
oci->mi = oci->mip + oci->mode_info_stride + 1;
|
||||||
|
|
||||||
/* allocate memory for last frame MODE_INFO array */
|
/* Allocation of previous mode info will be done in vp8_decode_frame()
|
||||||
#if CONFIG_ERROR_CONCEALMENT
|
* as it is a decoder only data */
|
||||||
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
|
|
||||||
|
|
||||||
oci->above_context = vpx_calloc(sizeof(ENTROPY_CONTEXT_PLANES) * oci->mb_cols, 1);
|
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;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
void vp8_setup_version(VP8_COMMON *cm)
|
void vp8_setup_version(VP8_COMMON *cm)
|
||||||
|
@@ -124,9 +124,10 @@ typedef struct VP8Common
|
|||||||
|
|
||||||
MODE_INFO *mip; /* Base of allocated array */
|
MODE_INFO *mip; /* Base of allocated array */
|
||||||
MODE_INFO *mi; /* Corresponds to upper left visible macroblock */
|
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_mip; /* MODE_INFO array 'mip' from last decoded frame */
|
||||||
MODE_INFO *prev_mi; /* 'mi' from last frame (points into prev_mip) */
|
MODE_INFO *prev_mi; /* 'mi' from last frame (points into prev_mip) */
|
||||||
|
#endif
|
||||||
|
|
||||||
LOOPFILTERTYPE filter_type;
|
LOOPFILTERTYPE filter_type;
|
||||||
|
|
||||||
|
@@ -821,20 +821,40 @@ int vp8_decode_frame(VP8D_COMP *pbi)
|
|||||||
vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR,
|
vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR,
|
||||||
"Failed to allocate frame buffers");
|
"Failed to allocate frame buffers");
|
||||||
|
|
||||||
|
/* allocate memory for last frame MODE_INFO array */
|
||||||
#if CONFIG_ERROR_CONCEALMENT
|
#if CONFIG_ERROR_CONCEALMENT
|
||||||
pbi->overlaps = NULL;
|
|
||||||
if (pbi->ec_enabled)
|
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))
|
if (vp8_alloc_overlap_lists(pbi))
|
||||||
vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR,
|
vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR,
|
||||||
"Failed to allocate overlap lists "
|
"Failed to allocate overlap lists "
|
||||||
"for error concealment");
|
"for error concealment");
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CONFIG_MULTITHREAD
|
#if CONFIG_MULTITHREAD
|
||||||
|
|
||||||
if (pbi->b_multithreaded_rd)
|
if (pbi->b_multithreaded_rd)
|
||||||
vp8mt_alloc_temp_buffers(pbi, pc->Width, prev_mb_rows);
|
vp8mt_alloc_temp_buffers(pbi, pc->Width, prev_mb_rows);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
frame_size_change = 1;
|
frame_size_change = 1;
|
||||||
}
|
}
|
||||||
|
@@ -51,12 +51,13 @@ int vp8_alloc_overlap_lists(VP8D_COMP *pbi)
|
|||||||
vpx_free(pbi->overlaps);
|
vpx_free(pbi->overlaps);
|
||||||
pbi->overlaps = NULL;
|
pbi->overlaps = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pbi->overlaps = vpx_calloc(pbi->common.mb_rows * pbi->common.mb_cols,
|
pbi->overlaps = vpx_calloc(pbi->common.mb_rows * pbi->common.mb_cols,
|
||||||
sizeof(MB_OVERLAP));
|
sizeof(MB_OVERLAP));
|
||||||
|
|
||||||
if (pbi->overlaps == NULL)
|
if (pbi->overlaps == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
vpx_memset(pbi->overlaps, 0,
|
|
||||||
sizeof(MB_OVERLAP) * pbi->common.mb_rows * pbi->common.mb_cols);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -80,6 +80,7 @@ struct VP8D_COMP * vp8dx_create_decompressor(VP8D_CONFIG *oxcf)
|
|||||||
|
|
||||||
#if CONFIG_ERROR_CONCEALMENT
|
#if CONFIG_ERROR_CONCEALMENT
|
||||||
pbi->ec_enabled = oxcf->error_concealment;
|
pbi->ec_enabled = oxcf->error_concealment;
|
||||||
|
pbi->overlaps = NULL;
|
||||||
#else
|
#else
|
||||||
pbi->ec_enabled = 0;
|
pbi->ec_enabled = 0;
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user