Commit 4d683862 authored by James Zern's avatar James Zern Committed by Gerrit Code Review

Merge "vp9: add per-tile longjmp error handling"

parents 44b55dad 953dd189
......@@ -232,6 +232,8 @@ typedef struct macroblockd {
int lossless;
int corrupted;
struct vpx_internal_error_info *error_info;
} MACROBLOCKD;
static INLINE BLOCK_SIZE get_subsize(BLOCK_SIZE bsize,
......
......@@ -272,6 +272,7 @@ static INLINE void init_macroblockd(VP9_COMMON *cm, MACROBLOCKD *xd) {
xd->above_seg_context = cm->above_seg_context;
xd->mi_stride = cm->mi_stride;
xd->error_info = &cm->error;
}
static INLINE int frame_is_intra_only(const VP9_COMMON *const cm) {
......
......@@ -463,8 +463,8 @@ static void decode_partition(VP9_COMMON *const cm, MACROBLOCKD *const xd,
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 {
......@@ -1021,6 +1021,15 @@ static int tile_worker_hook(TileWorkerData *const tile_data,
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);
......@@ -1167,6 +1176,10 @@ static const uint8_t *decode_tiles_mt(VP9Decoder *pbi,
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) {
......
......@@ -438,7 +438,7 @@ static void read_inter_block_mode_info(VP9_COMMON *const cm,
RefBuffer *ref_buf = &cm->frame_refs[frame - LAST_FRAME];
xd->block_refs[ref] = ref_buf;
if ((!vp9_is_valid_scale(&ref_buf->sf)))
vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
vpx_internal_error(xd->error_info, VPX_CODEC_UNSUP_BITSTREAM,
"Reference frame has invalid dimensions");
vp9_setup_pre_planes(xd, ref, ref_buf->buf, mi_row, mi_col,
&ref_buf->sf);
......@@ -451,7 +451,7 @@ static void read_inter_block_mode_info(VP9_COMMON *const cm,
if (vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
mbmi->mode = ZEROMV;
if (bsize < BLOCK_8X8) {
vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
vpx_internal_error(xd->error_info, VPX_CODEC_UNSUP_BITSTREAM,
"Invalid usage of segement feature on small blocks");
return;
}
......
......@@ -14,6 +14,7 @@
#include "./vpx_config.h"
#include "vp9/common/vp9_thread.h"
#include "vp9/decoder/vp9_reader.h"
#include "vpx/internal/vpx_codec_internal.h"
struct VP9Common;
struct VP9Decoder;
......@@ -22,6 +23,7 @@ typedef struct TileWorkerData {
struct VP9Common *cm;
vp9_reader bit_reader;
DECLARE_ALIGNED(16, struct macroblockd, xd);
struct vpx_internal_error_info error_info;
} TileWorkerData;
// Loopfilter row synchronization
......
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