Merge "vp9: add per-tile longjmp error handling"
This commit is contained in:
Коммит
4d6838627d
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче