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); |