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