Commit 4e30565a authored by Adrian Grange's avatar Adrian Grange
Browse files

Fix bug 837: realloc mode info buffers on resize

The test to determine if the mode info buffers need
to be resized when the frame size changes was
incorrect, as per bug 837.

By storing the size of the allocated data structure,
a simple test determines whether to allocate more
memory when the frame size changes.

Change-Id: I1544698f2882cf958fc672485614f2f46e9719bd
parent 82481405
......@@ -34,7 +34,7 @@ void vp9_set_mb_mi(VP9_COMMON *cm, int width, int height) {
cm->mi_cols = aligned_width >> MI_SIZE_LOG2;
cm->mi_rows = aligned_height >> MI_SIZE_LOG2;
cm->mi_stride = cm->mi_cols + MI_BLOCK_SIZE;
cm->mi_stride = calc_mi_size(cm->mi_cols);
cm->mb_cols = (cm->mi_cols + 1) >> 1;
cm->mb_rows = (cm->mi_rows + 1) >> 1;
......@@ -60,16 +60,18 @@ static int alloc_mi(VP9_COMMON *cm, int mi_size) {
for (i = 0; i < 2; ++i) {
cm->mip_array[i] =
(MODE_INFO *)vpx_calloc(mi_size, sizeof(*cm->mip));
(MODE_INFO *)vpx_calloc(mi_size, sizeof(MODE_INFO));
if (cm->mip_array[i] == NULL)
return 1;
cm->mi_grid_base_array[i] =
(MODE_INFO **)vpx_calloc(mi_size, sizeof(*cm->mi_grid_base));
(MODE_INFO **)vpx_calloc(mi_size, sizeof(MODE_INFO*));
if (cm->mi_grid_base_array[i] == NULL)
return 1;
}
cm->mi_alloc_size = mi_size;
// Init the index.
cm->mi_idx = 0;
cm->prev_mi_idx = 1;
......@@ -131,7 +133,8 @@ int vp9_alloc_context_buffers(VP9_COMMON *cm, int width, int height) {
vp9_free_context_buffers(cm);
vp9_set_mb_mi(cm, width, height);
if (alloc_mi(cm, cm->mi_stride * (cm->mi_rows + MI_BLOCK_SIZE))) goto fail;
if (alloc_mi(cm, cm->mi_stride * calc_mi_size(cm->mi_rows)))
goto fail;
cm->last_frame_seg_map = (uint8_t *)vpx_calloc(cm->mi_rows * cm->mi_cols, 1);
if (!cm->last_frame_seg_map) goto fail;
......
......@@ -137,6 +137,7 @@ typedef struct VP9Common {
int mi_idx;
int prev_mi_idx;
int mi_alloc_size;
MODE_INFO *mip_array[2];
MODE_INFO **mi_grid_base_array[2];
......@@ -272,6 +273,11 @@ static INLINE void set_skip_context(MACROBLOCKD *xd, int mi_row, int mi_col) {
}
}
static INLINE int calc_mi_size(int len) {
// len is in mi units.
return len + MI_BLOCK_SIZE;
}
static INLINE void set_mi_row_col(MACROBLOCKD *xd, const TileInfo *const tile,
int mi_row, int bh,
int mi_col, int bw,
......
......@@ -627,16 +627,14 @@ static void resize_context_buffers(VP9_COMMON *cm, int width, int height) {
"Width and height beyond allowed size.");
#endif
if (cm->width != width || cm->height != height) {
const int aligned_width = ALIGN_POWER_OF_TWO(width, MI_SIZE_LOG2);
const int aligned_height = ALIGN_POWER_OF_TWO(height, MI_SIZE_LOG2);
// Change in frame size (assumption: color format does not change).
if (cm->width == 0 || cm->height == 0 ||
aligned_width > cm->width ||
aligned_width * aligned_height > cm->width * cm->height) {
const int new_rows = ALIGN_POWER_OF_TWO(height,
MI_SIZE_LOG2) >> MI_SIZE_LOG2;
const int new_cols = ALIGN_POWER_OF_TWO(width,
MI_SIZE_LOG2) >> MI_SIZE_LOG2;
if (calc_mi_size(new_rows) * calc_mi_size(new_cols) > cm->mi_alloc_size) {
if (vp9_alloc_context_buffers(cm, width, height))
vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
"Failed to allocate frame buffers");
"Failed to allocate context buffers");
} else {
vp9_set_mb_mi(cm, width, height);
}
......
......@@ -421,11 +421,13 @@ static void write_modes_sb(VP9_COMP *cpi,
const int bs = (1 << bsl) / 4;
PARTITION_TYPE partition;
BLOCK_SIZE subsize;
const MODE_INFO *m = cm->mi_grid_visible[mi_row * cm->mi_stride + mi_col];
const MODE_INFO *m = NULL;
if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
return;
m = cm->mi_grid_visible[mi_row * cm->mi_stride + mi_col];
partition = partition_lookup[bsl][m->mbmi.sb_type];
write_partition(cm, xd, bs, mi_row, mi_col, partition, bsize, w);
subsize = get_subsize(bsize, partition);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment