| Index: source/libvpx/vp9/decoder/vp9_decodeframe.c
|
| ===================================================================
|
| --- source/libvpx/vp9/decoder/vp9_decodeframe.c (revision 291857)
|
| +++ source/libvpx/vp9/decoder/vp9_decodeframe.c (working copy)
|
| @@ -330,6 +330,9 @@
|
| if (!vp9_is_valid_scale(&ref_buffer->sf))
|
| vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
|
| "Invalid scale factors");
|
| + if (ref_buffer->buf->corrupted)
|
| + vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME,
|
| + "Block reference is corrupt");
|
| vp9_setup_pre_planes(xd, idx, ref_buffer->buf, mi_row, mi_col,
|
| &ref_buffer->sf);
|
| xd->corrupted |= ref_buffer->buf->corrupted;
|
| @@ -627,11 +630,14 @@
|
| "Width and height beyond allowed size.");
|
| #endif
|
| if (cm->width != width || cm->height != 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) {
|
| + const int new_mi_rows =
|
| + ALIGN_POWER_OF_TWO(height, MI_SIZE_LOG2) >> MI_SIZE_LOG2;
|
| + const int new_mi_cols =
|
| + ALIGN_POWER_OF_TWO(width, MI_SIZE_LOG2) >> MI_SIZE_LOG2;
|
| +
|
| + // Allocations in vp9_alloc_context_buffers() depend on individual
|
| + // dimensions as well as the overall size.
|
| + if (new_mi_cols > cm->mi_cols || new_mi_rows > cm->mi_rows) {
|
| if (vp9_alloc_context_buffers(cm, width, height))
|
| vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
|
| "Failed to allocate context buffers");
|
| @@ -652,7 +658,11 @@
|
|
|
| if (vp9_realloc_frame_buffer(
|
| get_frame_new_buffer(cm), cm->width, cm->height,
|
| - cm->subsampling_x, cm->subsampling_y, VP9_DEC_BORDER_IN_PIXELS,
|
| + cm->subsampling_x, cm->subsampling_y,
|
| +#if CONFIG_VP9_HIGHBITDEPTH
|
| + cm->use_highbitdepth,
|
| +#endif
|
| + VP9_DEC_BORDER_IN_PIXELS,
|
| &cm->frame_bufs[cm->new_fb_idx].raw_frame_buffer, cm->get_fb_cb,
|
| cm->cb_priv)) {
|
| vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
|
| @@ -670,6 +680,10 @@
|
| YV12_BUFFER_CONFIG *const buf = cm->frame_refs[i].buf;
|
| width = buf->y_crop_width;
|
| height = buf->y_crop_height;
|
| + if (buf->corrupted) {
|
| + vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME,
|
| + "Frame reference is corrupt");
|
| + }
|
| found = 1;
|
| break;
|
| }
|
| @@ -699,7 +713,11 @@
|
|
|
| if (vp9_realloc_frame_buffer(
|
| get_frame_new_buffer(cm), cm->width, cm->height,
|
| - cm->subsampling_x, cm->subsampling_y, VP9_DEC_BORDER_IN_PIXELS,
|
| + cm->subsampling_x, cm->subsampling_y,
|
| +#if CONFIG_VP9_HIGHBITDEPTH
|
| + cm->use_highbitdepth,
|
| +#endif
|
| + VP9_DEC_BORDER_IN_PIXELS,
|
| &cm->frame_bufs[cm->new_fb_idx].raw_frame_buffer, cm->get_fb_cb,
|
| cm->cb_priv)) {
|
| vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
|
| @@ -812,6 +830,8 @@
|
|
|
| if (cm->lf.filter_level) {
|
| LFWorkerData *const lf_data = (LFWorkerData*)pbi->lf_worker.data1;
|
| + // Be sure to sync as we might be resuming after a failed frame decode.
|
| + winterface->sync(&pbi->lf_worker);
|
| lf_data->frame_buffer = get_frame_new_buffer(cm);
|
| lf_data->cm = cm;
|
| vp9_copy(lf_data->planes, pbi->mb.plane);
|
| @@ -881,7 +901,7 @@
|
| pbi->mb.corrupted |= tile_data->xd.corrupted;
|
| }
|
| // Loopfilter one row.
|
| - if (cm->lf.filter_level) {
|
| + if (cm->lf.filter_level && !pbi->mb.corrupted) {
|
| const int lf_start = mi_row - MI_BLOCK_SIZE;
|
| LFWorkerData *const lf_data = (LFWorkerData*)pbi->lf_worker.data1;
|
|
|
| @@ -904,7 +924,7 @@
|
| }
|
|
|
| // Loopfilter remaining rows in the frame.
|
| - if (cm->lf.filter_level) {
|
| + if (cm->lf.filter_level && !pbi->mb.corrupted) {
|
| LFWorkerData *const lf_data = (LFWorkerData*)pbi->lf_worker.data1;
|
| winterface->sync(&pbi->lf_worker);
|
| lf_data->start = lf_data->stop;
|
| @@ -993,6 +1013,7 @@
|
|
|
| // Reset tile decoding hook
|
| for (n = 0; n < num_workers; ++n) {
|
| + winterface->sync(&pbi->tile_workers[n]);
|
| pbi->tile_workers[n].hook = (VP9WorkerHook)tile_worker_hook;
|
| }
|
|
|
| @@ -1096,7 +1117,7 @@
|
| static void read_bitdepth_colorspace_sampling(
|
| VP9_COMMON *cm, struct vp9_read_bit_buffer *rb) {
|
| if (cm->profile >= PROFILE_2)
|
| - cm->bit_depth = vp9_rb_read_bit(rb) ? BITS_12 : BITS_10;
|
| + cm->bit_depth = vp9_rb_read_bit(rb) ? VPX_BITS_12 : VPX_BITS_10;
|
| cm->color_space = (COLOR_SPACE)vp9_rb_read_literal(rb, 3);
|
| if (cm->color_space != SRGB) {
|
| vp9_rb_read_bit(rb); // [16,235] (including xvycc) vs [0,255] range
|
| @@ -1140,6 +1161,7 @@
|
| "Invalid frame marker");
|
|
|
| cm->profile = vp9_read_profile(rb);
|
| +
|
| if (cm->profile >= MAX_PROFILES)
|
| vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
|
| "Unsupported bitstream profile");
|
| @@ -1398,7 +1420,7 @@
|
|
|
| if (!first_partition_size) {
|
| // showing a frame directly
|
| - *p_data_end = data + 1;
|
| + *p_data_end = data + (cm->profile <= PROFILE_2 ? 1 : 2);
|
| return;
|
| }
|
|
|
| @@ -1429,9 +1451,11 @@
|
| if (pbi->max_threads > 1 && tile_rows == 1 && tile_cols > 1 &&
|
| cm->frame_parallel_decoding_mode) {
|
| *p_data_end = decode_tiles_mt(pbi, data + first_partition_size, data_end);
|
| - // If multiple threads are used to decode tiles, then we use those threads
|
| - // to do parallel loopfiltering.
|
| - vp9_loop_filter_frame_mt(new_fb, pbi, cm, cm->lf.filter_level, 0);
|
| + if (!xd->corrupted) {
|
| + // If multiple threads are used to decode tiles, then we use those threads
|
| + // to do parallel loopfiltering.
|
| + vp9_loop_filter_frame_mt(new_fb, pbi, cm, cm->lf.filter_level, 0);
|
| + }
|
| } else {
|
| *p_data_end = decode_tiles(pbi, data + first_partition_size, data_end);
|
| }
|
|
|