Index: source/libvpx/vp9/decoder/vp9_decodeframe.c |
=================================================================== |
--- source/libvpx/vp9/decoder/vp9_decodeframe.c (revision 281795) |
+++ source/libvpx/vp9/decoder/vp9_decodeframe.c (working copy) |
@@ -410,13 +410,17 @@ |
vp9_reader* r, BLOCK_SIZE bsize) { |
const int hbs = num_8x8_blocks_wide_lookup[bsize] / 2; |
PARTITION_TYPE partition; |
- BLOCK_SIZE subsize; |
+ BLOCK_SIZE subsize, uv_subsize; |
if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) |
return; |
partition = read_partition(cm, xd, hbs, mi_row, mi_col, bsize, r); |
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."); |
if (subsize < BLOCK_8X8) { |
decode_block(cm, xd, tile, mi_row, mi_col, r, subsize); |
} else { |
@@ -667,10 +671,18 @@ |
if (!found) |
read_frame_size(rb, &width, &height); |
- if (width <= 0 || height <= 0) |
- vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, |
- "Referenced frame with invalid size"); |
+ // Check that each of the frames that this frame references has valid |
+ // dimensions. |
+ for (i = 0; i < REFS_PER_FRAME; ++i) { |
+ RefBuffer *const ref_frame = &cm->frame_refs[i]; |
+ const int ref_width = ref_frame->buf->y_width; |
+ const int ref_height = ref_frame->buf->y_height; |
+ if (!valid_ref_frame_size(ref_width, ref_height, width, height)) |
+ vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, |
+ "Referenced frame has invalid size"); |
+ } |
+ |
apply_frame_size(cm, width, height); |
setup_display_size(cm, rb); |
} |
@@ -685,6 +697,10 @@ |
while (max_ones-- && vp9_rb_read_bit(rb)) |
cm->log2_tile_cols++; |
+ if (cm->log2_tile_cols > 6) |
+ vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, |
+ "Invalid number of tile columns"); |
+ |
// rows |
cm->log2_tile_rows = vp9_rb_read_bit(rb); |
if (cm->log2_tile_rows) |
@@ -755,6 +771,7 @@ |
const uint8_t *data, |
const uint8_t *data_end) { |
VP9_COMMON *const cm = &pbi->common; |
+ const VP9WorkerInterface *const winterface = vp9_get_worker_interface(); |
const int aligned_cols = mi_cols_aligned_to_sb(cm->mi_cols); |
const int tile_cols = 1 << cm->log2_tile_cols; |
const int tile_rows = 1 << cm->log2_tile_rows; |
@@ -767,7 +784,7 @@ |
CHECK_MEM_ERROR(cm, pbi->lf_worker.data1, |
vpx_memalign(32, sizeof(LFWorkerData))); |
pbi->lf_worker.hook = (VP9WorkerHook)vp9_loop_filter_worker; |
- if (pbi->max_threads > 1 && !vp9_worker_reset(&pbi->lf_worker)) { |
+ if (pbi->max_threads > 1 && !winterface->reset(&pbi->lf_worker)) { |
vpx_internal_error(&cm->error, VPX_CODEC_ERROR, |
"Loop filter thread creation failed"); |
} |
@@ -853,13 +870,13 @@ |
// decoding has completed: finish up the loop filter in this thread. |
if (mi_row + MI_BLOCK_SIZE >= cm->mi_rows) continue; |
- vp9_worker_sync(&pbi->lf_worker); |
+ winterface->sync(&pbi->lf_worker); |
lf_data->start = lf_start; |
lf_data->stop = mi_row; |
if (pbi->max_threads > 1) { |
- vp9_worker_launch(&pbi->lf_worker); |
+ winterface->launch(&pbi->lf_worker); |
} else { |
- vp9_worker_execute(&pbi->lf_worker); |
+ winterface->execute(&pbi->lf_worker); |
} |
} |
} |
@@ -868,10 +885,10 @@ |
// Loopfilter remaining rows in the frame. |
if (cm->lf.filter_level) { |
LFWorkerData *const lf_data = (LFWorkerData*)pbi->lf_worker.data1; |
- vp9_worker_sync(&pbi->lf_worker); |
+ winterface->sync(&pbi->lf_worker); |
lf_data->start = lf_data->stop; |
lf_data->stop = cm->mi_rows; |
- vp9_worker_execute(&pbi->lf_worker); |
+ winterface->execute(&pbi->lf_worker); |
} |
// Get last tile data. |
@@ -915,6 +932,7 @@ |
const uint8_t *data, |
const uint8_t *data_end) { |
VP9_COMMON *const cm = &pbi->common; |
+ const VP9WorkerInterface *const winterface = vp9_get_worker_interface(); |
const uint8_t *bit_reader_end = NULL; |
const int aligned_mi_cols = mi_cols_aligned_to_sb(cm->mi_cols); |
const int tile_cols = 1 << cm->log2_tile_cols; |
@@ -941,11 +959,11 @@ |
VP9Worker *const worker = &pbi->tile_workers[i]; |
++pbi->num_tile_workers; |
- vp9_worker_init(worker); |
+ winterface->init(worker); |
CHECK_MEM_ERROR(cm, worker->data1, |
vpx_memalign(32, sizeof(TileWorkerData))); |
CHECK_MEM_ERROR(cm, worker->data2, vpx_malloc(sizeof(TileInfo))); |
- if (i < num_threads - 1 && !vp9_worker_reset(worker)) { |
+ if (i < num_threads - 1 && !winterface->reset(worker)) { |
vpx_internal_error(&cm->error, VPX_CODEC_ERROR, |
"Tile decoder thread creation failed"); |
} |
@@ -1008,9 +1026,9 @@ |
worker->had_error = 0; |
if (i == num_workers - 1 || n == tile_cols - 1) { |
- vp9_worker_execute(worker); |
+ winterface->execute(worker); |
} else { |
- vp9_worker_launch(worker); |
+ winterface->launch(worker); |
} |
if (buf->col == tile_cols - 1) { |
@@ -1022,7 +1040,7 @@ |
for (; i > 0; --i) { |
VP9Worker *const worker = &pbi->tile_workers[i - 1]; |
- pbi->mb.corrupted |= !vp9_worker_sync(worker); |
+ pbi->mb.corrupted |= !winterface->sync(worker); |
} |
if (final_worker > -1) { |
TileWorkerData *const tile_data = |
@@ -1138,12 +1156,12 @@ |
setup_frame_size(cm, rb); |
} else { |
pbi->refresh_frame_flags = vp9_rb_read_literal(rb, REF_FRAMES); |
- |
for (i = 0; i < REFS_PER_FRAME; ++i) { |
const int ref = vp9_rb_read_literal(rb, REF_FRAMES_LOG2); |
const int idx = cm->ref_frame_map[ref]; |
- cm->frame_refs[i].idx = idx; |
- cm->frame_refs[i].buf = &cm->frame_bufs[idx].buf; |
+ RefBuffer *const ref_frame = &cm->frame_refs[i]; |
+ ref_frame->idx = idx; |
+ ref_frame->buf = &cm->frame_bufs[idx].buf; |
cm->ref_frame_sign_bias[LAST_FRAME + i] = vp9_rb_read_bit(rb); |
} |
@@ -1322,7 +1340,8 @@ |
const uint8_t **p_data_end) { |
VP9_COMMON *const cm = &pbi->common; |
MACROBLOCKD *const xd = &pbi->mb; |
- struct vp9_read_bit_buffer rb = { 0 }; |
+ struct vp9_read_bit_buffer rb = { NULL, NULL, 0, NULL, 0}; |
+ |
uint8_t clear_data[MAX_VP9_HEADER_SIZE]; |
const size_t first_partition_size = read_uncompressed_header(pbi, |
init_read_bit_buffer(pbi, &rb, data, data_end, clear_data)); |