diff --git a/vp8/decoder/decodframe.c b/vp8/decoder/decodframe.c index 877eb7738..dbd450542 100644 --- a/vp8/decoder/decodframe.c +++ b/vp8/decoder/decodframe.c @@ -515,37 +515,36 @@ static void decode_mb_rows(VP8D_COMP *pbi) int recon_yoffset, recon_uvoffset; int mb_row, mb_col; int mb_idx = 0; - int dst_fb_idx = pc->new_fb_idx; - int recon_y_stride = pc->yv12_fb[dst_fb_idx].y_stride; - int recon_uv_stride = pc->yv12_fb[dst_fb_idx].uv_stride; + + YV12_BUFFER_CONFIG *yv12_fb_new = pbi->dec_fb_ref[INTRA_FRAME]; + + int recon_y_stride = yv12_fb_new->y_stride; + int recon_uv_stride = yv12_fb_new->uv_stride; unsigned char *ref_buffer[MAX_REF_FRAMES][3]; unsigned char *dst_buffer[3]; unsigned char *lf_dst[3]; unsigned char *eb_dst[3]; int i; - int ref_fb_index[MAX_REF_FRAMES]; int ref_fb_corrupted[MAX_REF_FRAMES]; ref_fb_corrupted[INTRA_FRAME] = 0; - ref_fb_index[LAST_FRAME] = pc->lst_fb_idx; - ref_fb_index[GOLDEN_FRAME] = pc->gld_fb_idx; - ref_fb_index[ALTREF_FRAME] = pc->alt_fb_idx; - for(i = 1; i < MAX_REF_FRAMES; i++) { - ref_buffer[i][0] = pc->yv12_fb[ref_fb_index[i]].y_buffer; - ref_buffer[i][1] = pc->yv12_fb[ref_fb_index[i]].u_buffer; - ref_buffer[i][2] = pc->yv12_fb[ref_fb_index[i]].v_buffer; + YV12_BUFFER_CONFIG *this_fb = pbi->dec_fb_ref[i]; - ref_fb_corrupted[i] = pc->yv12_fb[ref_fb_index[i]].corrupted; + ref_buffer[i][0] = this_fb->y_buffer; + ref_buffer[i][1] = this_fb->u_buffer; + ref_buffer[i][2] = this_fb->v_buffer; + + ref_fb_corrupted[i] = this_fb->corrupted; } /* Set up the buffer pointers */ - eb_dst[0] = lf_dst[0] = dst_buffer[0] = pc->yv12_fb[dst_fb_idx].y_buffer; - eb_dst[1] = lf_dst[1] = dst_buffer[1] = pc->yv12_fb[dst_fb_idx].u_buffer; - eb_dst[2] = lf_dst[2] = dst_buffer[2] = pc->yv12_fb[dst_fb_idx].v_buffer; + eb_dst[0] = lf_dst[0] = dst_buffer[0] = yv12_fb_new->y_buffer; + eb_dst[1] = lf_dst[1] = dst_buffer[1] = yv12_fb_new->u_buffer; + eb_dst[2] = lf_dst[2] = dst_buffer[2] = yv12_fb_new->v_buffer; xd->up_available = 0; @@ -553,7 +552,7 @@ static void decode_mb_rows(VP8D_COMP *pbi) if(pc->filter_level) vp8_loop_filter_frame_init(pc, xd, pc->filter_level); - vp8_setup_intra_recon_top_line(&pc->yv12_fb[dst_fb_idx]); + vp8_setup_intra_recon_top_line(yv12_fb_new); /* Decode the individual macro block */ for (mb_row = 0; mb_row < pc->mb_rows; mb_row++) @@ -669,7 +668,7 @@ static void decode_mb_rows(VP8D_COMP *pbi) } /* adjust to the next row of mbs */ - vp8_extend_mb_row(&pc->yv12_fb[dst_fb_idx], xd->dst.y_buffer + 16, + vp8_extend_mb_row(yv12_fb_new, xd->dst.y_buffer + 16, xd->dst.u_buffer + 8, xd->dst.v_buffer + 8); ++xd->mode_info_context; /* skip prediction column */ @@ -690,7 +689,7 @@ static void decode_mb_rows(VP8D_COMP *pbi) if(mb_row > 1) { - yv12_extend_frame_left_right_c(&pc->yv12_fb[dst_fb_idx], + yv12_extend_frame_left_right_c(yv12_fb_new, eb_dst[0], eb_dst[1], eb_dst[2]); @@ -700,7 +699,7 @@ static void decode_mb_rows(VP8D_COMP *pbi) eb_dst[2] += recon_uv_stride * 8; if(mb_row == 2) - yv12_extend_frame_top_c(&pc->yv12_fb[dst_fb_idx]); + yv12_extend_frame_top_c(yv12_fb_new); } @@ -716,7 +715,7 @@ static void decode_mb_rows(VP8D_COMP *pbi) if(mb_row > 0) { /**/ - yv12_extend_frame_left_right_c(&pc->yv12_fb[dst_fb_idx], + yv12_extend_frame_left_right_c(yv12_fb_new, eb_dst[0], eb_dst[1], eb_dst[2]); @@ -726,7 +725,7 @@ static void decode_mb_rows(VP8D_COMP *pbi) eb_dst[2] += recon_uv_stride * 8; if(mb_row == 1) - yv12_extend_frame_top_c(&pc->yv12_fb[dst_fb_idx]); + yv12_extend_frame_top_c(yv12_fb_new); } } } @@ -742,7 +741,7 @@ static void decode_mb_rows(VP8D_COMP *pbi) recon_uv_stride, lf_dst[0], lf_dst[1], lf_dst[2]); - yv12_extend_frame_left_right_c(&pc->yv12_fb[dst_fb_idx], + yv12_extend_frame_left_right_c(yv12_fb_new, eb_dst[0], eb_dst[1], eb_dst[2]); @@ -750,12 +749,13 @@ static void decode_mb_rows(VP8D_COMP *pbi) eb_dst[1] += recon_uv_stride * 8; eb_dst[2] += recon_uv_stride * 8; } - yv12_extend_frame_left_right_c(&pc->yv12_fb[dst_fb_idx], + yv12_extend_frame_left_right_c(yv12_fb_new, eb_dst[0], eb_dst[1], eb_dst[2]); - yv12_extend_frame_bottom_c(&pc->yv12_fb[dst_fb_idx]); + yv12_extend_frame_bottom_c(yv12_fb_new); + } static unsigned int read_partition_size(const unsigned char *cx_size) @@ -995,9 +995,11 @@ int vp8_decode_frame(VP8D_COMP *pbi) int corrupt_tokens = 0; int prev_independent_partitions = pbi->independent_partitions; + YV12_BUFFER_CONFIG *yv12_fb_new = pbi->dec_fb_ref[INTRA_FRAME]; + /* start with no corruption of current frame */ xd->corrupted = 0; - pc->yv12_fb[pc->new_fb_idx].corrupted = 0; + yv12_fb_new->corrupted = 0; if (data_end - data < 3) { @@ -1035,9 +1037,6 @@ int vp8_decode_frame(VP8D_COMP *pbi) if (pc->frame_type == KEY_FRAME) { - const int Width = pc->Width; - const int Height = pc->Height; - /* vet via sync code */ /* When error concealment is enabled we should only check the sync * code if we have enough bits available @@ -1062,85 +1061,14 @@ int vp8_decode_frame(VP8D_COMP *pbi) } data += 7; - if (Width != pc->Width || Height != pc->Height) - { - int prev_mb_rows = pc->mb_rows; - - if (pc->Width <= 0) - { - pc->Width = Width; - vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME, - "Invalid frame width"); - } - - if (pc->Height <= 0) - { - pc->Height = Height; - vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME, - "Invalid frame height"); - } - - if (vp8_alloc_frame_buffers(pc, pc->Width, pc->Height)) - vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR, - "Failed to allocate frame buffers"); - - vpx_memcpy(&xd->pre, &pc->yv12_fb[pc->lst_fb_idx], sizeof(YV12_BUFFER_CONFIG)); - vpx_memcpy(&xd->dst, &pc->yv12_fb[pc->new_fb_idx], sizeof(YV12_BUFFER_CONFIG)); - -#if CONFIG_MULTITHREAD - for (i = 0; i < pbi->allocated_decoding_thread_count; i++) - { - pbi->mb_row_di[i].mbd.dst = pc->yv12_fb[pc->new_fb_idx]; - vp8_build_block_doffsets(&pbi->mb_row_di[i].mbd); - } -#endif - vp8_build_block_doffsets(&pbi->mb); - - /* allocate memory for last frame MODE_INFO array */ -#if CONFIG_ERROR_CONCEALMENT - - 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); -#else - (void)prev_mb_rows; -#endif - } } else { - vpx_memcpy(&xd->pre, &pc->yv12_fb[pc->lst_fb_idx], sizeof(YV12_BUFFER_CONFIG)); - vpx_memcpy(&xd->dst, &pc->yv12_fb[pc->new_fb_idx], sizeof(YV12_BUFFER_CONFIG)); + vpx_memcpy(&xd->pre, yv12_fb_new, sizeof(YV12_BUFFER_CONFIG)); + vpx_memcpy(&xd->dst, yv12_fb_new, sizeof(YV12_BUFFER_CONFIG)); } } - if ((!pbi->decoded_key_frame && pc->frame_type != KEY_FRAME) || - pc->Width == 0 || pc->Height == 0) + if ((!pbi->decoded_key_frame && pc->frame_type != KEY_FRAME)) { return -1; } @@ -1412,7 +1340,7 @@ int vp8_decode_frame(VP8D_COMP *pbi) { unsigned int i; vp8mt_decode_mb_rows(pbi, xd); - vp8_yv12_extend_frame_borders(&pc->yv12_fb[pc->new_fb_idx]); /*cm->frame_to_show);*/ + vp8_yv12_extend_frame_borders(yv12_fb_new); for (i = 0; i < pbi->decoding_thread_count; ++i) corrupt_tokens |= pbi->mb_row_di[i].mbd.corrupted; } @@ -1425,14 +1353,14 @@ int vp8_decode_frame(VP8D_COMP *pbi) /* Collect information about decoder corruption. */ /* 1. Check first boolean decoder for errors. */ - pc->yv12_fb[pc->new_fb_idx].corrupted = vp8dx_bool_error(bc); + yv12_fb_new->corrupted = vp8dx_bool_error(bc); /* 2. Check the macroblock information */ - pc->yv12_fb[pc->new_fb_idx].corrupted |= corrupt_tokens; + yv12_fb_new->corrupted |= corrupt_tokens; if (!pbi->decoded_key_frame) { if (pc->frame_type == KEY_FRAME && - !pc->yv12_fb[pc->new_fb_idx].corrupted) + !yv12_fb_new->corrupted) pbi->decoded_key_frame = 1; else vpx_internal_error(&pbi->common.error, VPX_CODEC_CORRUPT_FRAME, diff --git a/vp8/decoder/onyxd_if.c b/vp8/decoder/onyxd_if.c index 95293f421..2985d7603 100644 --- a/vp8/decoder/onyxd_if.c +++ b/vp8/decoder/onyxd_if.c @@ -289,14 +289,6 @@ int vp8dx_receive_compressed_data(VP8D_COMP *pbi, unsigned long size, const unsi VP8_COMMON *cm = &pbi->common; int retcode = 0; - /*if(pbi->ready_for_new_data == 0) - return -1;*/ - - if (pbi == 0) - { - return -1; - } - pbi->common.error.error_code = VPX_CODEC_OK; if (pbi->num_fragments == 0) @@ -383,6 +375,12 @@ int vp8dx_receive_compressed_data(VP8D_COMP *pbi, unsigned long size, const unsi cm->new_fb_idx = get_free_fb (cm); + /* setup reference frames for vp8_decode_frame */ + pbi->dec_fb_ref[INTRA_FRAME] = &cm->yv12_fb[cm->new_fb_idx]; + pbi->dec_fb_ref[LAST_FRAME] = &cm->yv12_fb[cm->lst_fb_idx]; + pbi->dec_fb_ref[GOLDEN_FRAME] = &cm->yv12_fb[cm->gld_fb_idx]; + pbi->dec_fb_ref[ALTREF_FRAME] = &cm->yv12_fb[cm->alt_fb_idx]; + if (setjmp(pbi->common.error.jmp)) { #if HAVE_NEON diff --git a/vp8/decoder/onyxd_int.h b/vp8/decoder/onyxd_int.h index e6c814acc..022c6985b 100644 --- a/vp8/decoder/onyxd_int.h +++ b/vp8/decoder/onyxd_int.h @@ -37,6 +37,8 @@ typedef struct VP8D_COMP { DECLARE_ALIGNED(16, MACROBLOCKD, mb); + YV12_BUFFER_CONFIG *dec_fb_ref[NUM_YV12_BUFFERS]; + DECLARE_ALIGNED(16, VP8_COMMON, common); vp8_reader bc, bc2; diff --git a/vp8/decoder/threading.c b/vp8/decoder/threading.c index de14789cb..a91281b4c 100644 --- a/vp8/decoder/threading.c +++ b/vp8/decoder/threading.c @@ -48,8 +48,8 @@ static void setup_decoding_thread_data(VP8D_COMP *pbi, MACROBLOCKD *xd, MB_ROW_D mbd->mode_info_stride = pc->mode_info_stride; mbd->frame_type = pc->frame_type; - mbd->pre = pc->yv12_fb[pc->lst_fb_idx]; - mbd->dst = pc->yv12_fb[pc->new_fb_idx]; + mbd->pre = xd->pre; + mbd->dst = xd->dst; mbd->segmentation_enabled = xd->segmentation_enabled; mbd->mb_segement_abs_delta = xd->mb_segement_abs_delta; @@ -304,31 +304,33 @@ static void mt_decode_mb_rows(VP8D_COMP *pbi, MACROBLOCKD *xd, int start_mb_row) int num_part = 1 << pbi->common.multi_token_partition; int last_mb_row = start_mb_row; - int dst_fb_idx = pc->new_fb_idx; + YV12_BUFFER_CONFIG *yv12_fb_new = pbi->dec_fb_ref[INTRA_FRAME]; + YV12_BUFFER_CONFIG *yv12_fb_lst = pbi->dec_fb_ref[LAST_FRAME]; + + int recon_y_stride = yv12_fb_new->y_stride; + int recon_uv_stride = yv12_fb_new->uv_stride; + unsigned char *ref_buffer[MAX_REF_FRAMES][3]; unsigned char *dst_buffer[3]; int i; - int ref_fb_index[MAX_REF_FRAMES]; int ref_fb_corrupted[MAX_REF_FRAMES]; ref_fb_corrupted[INTRA_FRAME] = 0; - ref_fb_index[LAST_FRAME] = pc->lst_fb_idx; - ref_fb_index[GOLDEN_FRAME] = pc->gld_fb_idx; - ref_fb_index[ALTREF_FRAME] = pc->alt_fb_idx; - for(i = 1; i < MAX_REF_FRAMES; i++) { - ref_buffer[i][0] = pc->yv12_fb[ref_fb_index[i]].y_buffer; - ref_buffer[i][1] = pc->yv12_fb[ref_fb_index[i]].u_buffer; - ref_buffer[i][2] = pc->yv12_fb[ref_fb_index[i]].v_buffer; + YV12_BUFFER_CONFIG *this_fb = pbi->dec_fb_ref[i]; - ref_fb_corrupted[i] = pc->yv12_fb[ref_fb_index[i]].corrupted; + ref_buffer[i][0] = this_fb->y_buffer; + ref_buffer[i][1] = this_fb->u_buffer; + ref_buffer[i][2] = this_fb->v_buffer; + + ref_fb_corrupted[i] = this_fb->corrupted; } - dst_buffer[0] = pc->yv12_fb[dst_fb_idx].y_buffer; - dst_buffer[1] = pc->yv12_fb[dst_fb_idx].u_buffer; - dst_buffer[2] = pc->yv12_fb[dst_fb_idx].v_buffer; + dst_buffer[0] = yv12_fb_new->y_buffer; + dst_buffer[1] = yv12_fb_new->u_buffer; + dst_buffer[2] = yv12_fb_new->v_buffer; xd->up_available = (start_mb_row != 0); @@ -337,11 +339,6 @@ static void mt_decode_mb_rows(VP8D_COMP *pbi, MACROBLOCKD *xd, int start_mb_row) int i; int recon_yoffset, recon_uvoffset; int mb_col; - int ref_fb_idx = pc->lst_fb_idx; - int dst_fb_idx = pc->new_fb_idx; - int recon_y_stride = pc->yv12_fb[ref_fb_idx].y_stride; - int recon_uv_stride = pc->yv12_fb[ref_fb_idx].uv_stride; - int filter_level; loop_filter_info_n *lfi_n = &pc->lf_info; @@ -589,8 +586,8 @@ static void mt_decode_mb_rows(VP8D_COMP *pbi, MACROBLOCKD *xd, int start_mb_row) { if(mb_row != pc->mb_rows-1) { - int lasty = pc->yv12_fb[ref_fb_idx].y_width + VP8BORDERINPIXELS; - int lastuv = (pc->yv12_fb[ref_fb_idx].y_width>>1) + (VP8BORDERINPIXELS>>1); + int lasty = yv12_fb_lst->y_width + VP8BORDERINPIXELS; + int lastuv = (yv12_fb_lst->y_width>>1) + (VP8BORDERINPIXELS>>1); for (i = 0; i < 4; i++) { @@ -601,7 +598,7 @@ static void mt_decode_mb_rows(VP8D_COMP *pbi, MACROBLOCKD *xd, int start_mb_row) } } else - vp8_extend_mb_row(&pc->yv12_fb[dst_fb_idx], xd->dst.y_buffer + 16, + vp8_extend_mb_row(yv12_fb_new, xd->dst.y_buffer + 16, xd->dst.u_buffer + 8, xd->dst.v_buffer + 8); /* last MB of row is ready just after extension is done */ @@ -874,13 +871,14 @@ void vp8mt_decode_mb_rows( VP8D_COMP *pbi, MACROBLOCKD *xd) int j; int filter_level = pc->filter_level; + YV12_BUFFER_CONFIG *yv12_fb_new = pbi->dec_fb_ref[INTRA_FRAME]; if (filter_level) { /* Set above_row buffer to 127 for decoding first MB row */ - vpx_memset(pbi->mt_yabove_row[0] + VP8BORDERINPIXELS-1, 127, pc->yv12_fb[pc->new_fb_idx].y_width + 5); - vpx_memset(pbi->mt_uabove_row[0] + (VP8BORDERINPIXELS>>1)-1, 127, (pc->yv12_fb[pc->new_fb_idx].y_width>>1) +5); - vpx_memset(pbi->mt_vabove_row[0] + (VP8BORDERINPIXELS>>1)-1, 127, (pc->yv12_fb[pc->new_fb_idx].y_width>>1) +5); + vpx_memset(pbi->mt_yabove_row[0] + VP8BORDERINPIXELS-1, 127, yv12_fb_new->y_width + 5); + vpx_memset(pbi->mt_uabove_row[0] + (VP8BORDERINPIXELS>>1)-1, 127, (yv12_fb_new->y_width>>1) +5); + vpx_memset(pbi->mt_vabove_row[0] + (VP8BORDERINPIXELS>>1)-1, 127, (yv12_fb_new->y_width>>1) +5); for (j=1; jmb_rows; j++) { @@ -901,7 +899,7 @@ void vp8mt_decode_mb_rows( VP8D_COMP *pbi, MACROBLOCKD *xd) vp8_loop_filter_frame_init(pc, &pbi->mb, filter_level); } else - vp8_setup_intra_recon_top_line(&pc->yv12_fb[pc->new_fb_idx]); + vp8_setup_intra_recon_top_line(yv12_fb_new); setup_decoding_thread_data(pbi, xd, pbi->mb_row_di, pbi->decoding_thread_count); diff --git a/vp8/vp8_dx_iface.c b/vp8/vp8_dx_iface.c index 3290de9fa..c13d69783 100644 --- a/vp8/vp8_dx_iface.c +++ b/vp8/vp8_dx_iface.c @@ -18,6 +18,12 @@ #include "vpx_version.h" #include "common/onyxd.h" #include "decoder/onyxd_int.h" +#include "common/alloccommon.h" +#include "vpx_mem/vpx_mem.h" +#if CONFIG_ERROR_CONCEALMENT +#include "decoder/error_concealment.h" +#endif +#include "decoder/decoderthreading.h" #define VP8_CAP_POSTPROC (CONFIG_POSTPROC ? VPX_CODEC_CAP_POSTPROC : 0) #define VP8_CAP_ERROR_CONCEALMENT (CONFIG_ERROR_CONCEALMENT ? \ @@ -344,14 +350,30 @@ static vpx_codec_err_t vp8_decode(vpx_codec_alg_priv_t *ctx, long deadline) { vpx_codec_err_t res = VPX_CODEC_OK; + unsigned int resolution_change = 0; + unsigned int w, h; /* Determine the stream parameters. Note that we rely on peek_si to * validate that we have a buffer that does not wrap around the top * of the heap. */ - if (!ctx->si.h) - res = ctx->base.iface->dec.peek_si(data, data_sz, &ctx->si); + w = ctx->si.w; + h = ctx->si.h; + res = ctx->base.iface->dec.peek_si(data, data_sz, &ctx->si); + + if((res == VPX_CODEC_UNSUP_BITSTREAM) && !ctx->si.is_kf) + { + /* the peek function returns an error for non keyframes, however for + * this case, it is not an error */ + res = VPX_CODEC_OK; + } + + if(!ctx->decoder_init && !ctx->si.is_kf) + res = VPX_CODEC_UNSUP_BITSTREAM; + + if ((ctx->si.h != h) || (ctx->si.w != w)) + resolution_change = 1; /* Perform deferred allocations, if required */ if (!res && ctx->defer_alloc) @@ -427,6 +449,101 @@ static vpx_codec_err_t vp8_decode(vpx_codec_alg_priv_t *ctx, if (!res && ctx->pbi) { + if(resolution_change) + { + VP8D_COMP *pbi = ctx->pbi; + VP8_COMMON *const pc = & pbi->common; + MACROBLOCKD *const xd = & pbi->mb; +#if CONFIG_MULTITHREAD + int i; +#endif + pc->Width = ctx->si.w; + pc->Height = ctx->si.h; + { + int prev_mb_rows = pc->mb_rows; + + if (setjmp(pbi->common.error.jmp)) + { + pbi->common.error.setjmp = 0; + /* same return value as used in vp8dx_receive_compressed_data */ + return -1; + } + + pbi->common.error.setjmp = 1; + + if (pc->Width <= 0) + { + pc->Width = w; + vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME, + "Invalid frame width"); + } + + if (pc->Height <= 0) + { + pc->Height = h; + vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME, + "Invalid frame height"); + } + + if (vp8_alloc_frame_buffers(pc, pc->Width, pc->Height)) + vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR, + "Failed to allocate frame buffers"); + + xd->pre = pc->yv12_fb[pc->lst_fb_idx]; + xd->dst = pc->yv12_fb[pc->new_fb_idx]; + +#if CONFIG_MULTITHREAD + for (i = 0; i < pbi->allocated_decoding_thread_count; i++) + { + pbi->mb_row_di[i].mbd.dst = pc->yv12_fb[pc->new_fb_idx]; + vp8_build_block_doffsets(&pbi->mb_row_di[i].mbd); + } +#endif + vp8_build_block_doffsets(&pbi->mb); + + /* allocate memory for last frame MODE_INFO array */ +#if CONFIG_ERROR_CONCEALMENT + + 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); +#else + (void)prev_mb_rows; +#endif + } + + pbi->common.error.setjmp = 0; + + /* required to get past the first get_free_fb() call */ + ctx->pbi->common.fb_idx_ref_cnt[0] = 0; + } + ctx->user_priv = user_priv; if (vp8dx_receive_compressed_data(ctx->pbi, data_sz, data, deadline)) {