| Index: source/libvpx/vp9/decoder/vp9_decodeframe.c
|
| ===================================================================
|
| --- source/libvpx/vp9/decoder/vp9_decodeframe.c (revision 293588)
|
| +++ source/libvpx/vp9/decoder/vp9_decodeframe.c (working copy)
|
| @@ -463,8 +463,8 @@
|
| subsize = get_subsize(bsize, partition);
|
| uv_subsize = ss_size_lookup[subsize][cm->subsampling_x][cm->subsampling_y];
|
| if (subsize >= BLOCK_8X8 && uv_subsize == BLOCK_INVALID)
|
| - vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME,
|
| - "Invalid block size.");
|
| + vpx_internal_error(xd->error_info,
|
| + VPX_CODEC_CORRUPT_FRAME, "Invalid block size.");
|
| if (subsize < BLOCK_8X8) {
|
| decode_block(cm, xd, tile, mi_row, mi_col, r, subsize);
|
| } else {
|
| @@ -719,6 +719,7 @@
|
| cm->use_highbitdepth,
|
| #endif
|
| VP9_DEC_BORDER_IN_PIXELS,
|
| + cm->byte_alignment,
|
| &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,
|
| @@ -747,10 +748,6 @@
|
| 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;
|
| }
|
| @@ -797,6 +794,7 @@
|
| cm->use_highbitdepth,
|
| #endif
|
| VP9_DEC_BORDER_IN_PIXELS,
|
| + cm->byte_alignment,
|
| &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,
|
| @@ -956,7 +954,6 @@
|
| &tile_data->bit_reader, pbi->decrypt_cb,
|
| pbi->decrypt_state);
|
| init_macroblockd(cm, &tile_data->xd);
|
| - vp9_zero(tile_data->xd.dqcoeff);
|
| }
|
| }
|
|
|
| @@ -978,9 +975,12 @@
|
| &tile_data->bit_reader, BLOCK_64X64);
|
| }
|
| pbi->mb.corrupted |= tile_data->xd.corrupted;
|
| + if (pbi->mb.corrupted)
|
| + vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME,
|
| + "Failed to decode tile data");
|
| }
|
| // Loopfilter one row.
|
| - if (cm->lf.filter_level && !pbi->mb.corrupted) {
|
| + if (cm->lf.filter_level) {
|
| const int lf_start = mi_row - MI_BLOCK_SIZE;
|
| LFWorkerData *const lf_data = (LFWorkerData*)pbi->lf_worker.data1;
|
|
|
| @@ -1003,7 +1003,7 @@
|
| }
|
|
|
| // Loopfilter remaining rows in the frame.
|
| - if (cm->lf.filter_level && !pbi->mb.corrupted) {
|
| + if (cm->lf.filter_level) {
|
| LFWorkerData *const lf_data = (LFWorkerData*)pbi->lf_worker.data1;
|
| winterface->sync(&pbi->lf_worker);
|
| lf_data->start = lf_data->stop;
|
| @@ -1021,6 +1021,15 @@
|
| const TileInfo *const tile) {
|
| int mi_row, mi_col;
|
|
|
| + if (setjmp(tile_data->error_info.jmp)) {
|
| + tile_data->error_info.setjmp = 0;
|
| + tile_data->xd.corrupted = 1;
|
| + return 0;
|
| + }
|
| +
|
| + tile_data->error_info.setjmp = 1;
|
| + tile_data->xd.error_info = &tile_data->error_info;
|
| +
|
| for (mi_row = tile->mi_row_start; mi_row < tile->mi_row_end;
|
| mi_row += MI_BLOCK_SIZE) {
|
| vp9_zero(tile_data->xd.left_context);
|
| @@ -1150,7 +1159,6 @@
|
| &tile_data->bit_reader, pbi->decrypt_cb,
|
| pbi->decrypt_state);
|
| init_macroblockd(cm, &tile_data->xd);
|
| - vp9_zero(tile_data->xd.dqcoeff);
|
|
|
| worker->had_error = 0;
|
| if (i == num_workers - 1 || n == tile_cols - 1) {
|
| @@ -1168,6 +1176,10 @@
|
|
|
| for (; i > 0; --i) {
|
| VP9Worker *const worker = &pbi->tile_workers[i - 1];
|
| + // TODO(jzern): The tile may have specific error data associated with
|
| + // its vpx_internal_error_info which could be propagated to the main info
|
| + // in cm. Additionally once the threads have been synced and an error is
|
| + // detected, there's no point in continuing to decode tiles.
|
| pbi->mb.corrupted |= !winterface->sync(worker);
|
| }
|
| if (final_worker > -1) {
|
| @@ -1547,8 +1559,6 @@
|
| vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME,
|
| "Truncated packet or corrupt header length");
|
|
|
| - init_macroblockd(cm, &pbi->mb);
|
| -
|
| cm->use_prev_frame_mvs = !cm->error_resilient_mode &&
|
| cm->width == cm->last_width &&
|
| cm->height == cm->last_height &&
|
| @@ -1559,11 +1569,17 @@
|
| vp9_setup_block_planes(xd, cm->subsampling_x, cm->subsampling_y);
|
|
|
| *cm->fc = cm->frame_contexts[cm->frame_context_idx];
|
| + if (!cm->fc->initialized)
|
| + vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME,
|
| + "Uninitialized entropy context.");
|
| +
|
| vp9_zero(cm->counts);
|
| - vp9_zero(xd->dqcoeff);
|
|
|
| xd->corrupted = 0;
|
| new_fb->corrupted = read_compressed_header(pbi, data, first_partition_size);
|
| + if (new_fb->corrupted)
|
| + vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME,
|
| + "Decode failed. Frame data header is corrupted.");
|
|
|
| // TODO(jzern): remove frame_parallel_decoding_mode restriction for
|
| // single-frame tile decoding.
|
| @@ -1576,6 +1592,10 @@
|
| vp9_loop_filter_frame_mt(&pbi->lf_row_sync, new_fb, pbi->mb.plane, cm,
|
| pbi->tile_workers, pbi->num_tile_workers,
|
| cm->lf.filter_level, 0);
|
| + } else {
|
| + vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME,
|
| + "Decode failed. Frame data is corrupted.");
|
| +
|
| }
|
| } else {
|
| *p_data_end = decode_tiles(pbi, data + first_partition_size, data_end);
|
|
|