| Index: source/libvpx/vp9/decoder/vp9_decodeframe.c
|
| ===================================================================
|
| --- source/libvpx/vp9/decoder/vp9_decodeframe.c (revision 290053)
|
| +++ source/libvpx/vp9/decoder/vp9_decodeframe.c (working copy)
|
| @@ -627,12 +627,14 @@
|
| "Width and height beyond allowed size.");
|
| #endif
|
| if (cm->width != width || cm->height != height) {
|
| - // Change in frame size (assumption: color format does not change).
|
| - if (cm->width == 0 || cm->height == 0 ||
|
| - width * height > cm->width * cm->height) {
|
| + const int new_rows = ALIGN_POWER_OF_TWO(height,
|
| + MI_SIZE_LOG2) >> MI_SIZE_LOG2;
|
| + const int new_cols = ALIGN_POWER_OF_TWO(width,
|
| + MI_SIZE_LOG2) >> MI_SIZE_LOG2;
|
| + if (calc_mi_size(new_rows) * calc_mi_size(new_cols) > cm->mi_alloc_size) {
|
| if (vp9_alloc_context_buffers(cm, width, height))
|
| vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
|
| - "Failed to allocate frame buffers");
|
| + "Failed to allocate context buffers");
|
| } else {
|
| vp9_set_mb_mi(cm, width, height);
|
| }
|
| @@ -662,6 +664,7 @@
|
| struct vp9_read_bit_buffer *rb) {
|
| int width, height;
|
| int found = 0, i;
|
| + int has_valid_ref_frame = 0;
|
| for (i = 0; i < REFS_PER_FRAME; ++i) {
|
| if (vp9_rb_read_bit(rb)) {
|
| YV12_BUFFER_CONFIG *const buf = cm->frame_refs[i].buf;
|
| @@ -675,15 +678,21 @@
|
| if (!found)
|
| vp9_read_frame_size(rb, &width, &height);
|
|
|
| - // Check that each of the frames that this frame references has valid
|
| - // dimensions.
|
| + if (width <=0 || height <= 0)
|
| + vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME,
|
| + "Invalid frame size");
|
| +
|
| + // Check to make sure at least one of frames that this frame references
|
| + // has valid dimensions.
|
| for (i = 0; i < REFS_PER_FRAME; ++i) {
|
| RefBuffer *const ref_frame = &cm->frame_refs[i];
|
| - if (!valid_ref_frame_size(ref_frame->buf->y_width, ref_frame->buf->y_height,
|
| - width, height))
|
| - vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME,
|
| - "Referenced frame has invalid size");
|
| + has_valid_ref_frame |= valid_ref_frame_size(ref_frame->buf->y_crop_width,
|
| + ref_frame->buf->y_crop_height,
|
| + width, height);
|
| }
|
| + if (!has_valid_ref_frame)
|
| + vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME,
|
| + "Referenced frame has invalid size");
|
|
|
| resize_context_buffers(cm, width, height);
|
| setup_display_size(cm, rb);
|
| @@ -1084,6 +1093,40 @@
|
| return (BITSTREAM_PROFILE) profile;
|
| }
|
|
|
| +static void read_bitdepth_colorspace_sampling(
|
| + VP9_COMMON *cm, struct vp9_read_bit_buffer *rb) {
|
| + if (cm->profile >= PROFILE_2)
|
| + cm->bit_depth = vp9_rb_read_bit(rb) ? BITS_12 : BITS_10;
|
| + cm->color_space = (COLOR_SPACE)vp9_rb_read_literal(rb, 3);
|
| + if (cm->color_space != SRGB) {
|
| + vp9_rb_read_bit(rb); // [16,235] (including xvycc) vs [0,255] range
|
| + if (cm->profile == PROFILE_1 || cm->profile == PROFILE_3) {
|
| + cm->subsampling_x = vp9_rb_read_bit(rb);
|
| + cm->subsampling_y = vp9_rb_read_bit(rb);
|
| + if (cm->subsampling_x == 1 && cm->subsampling_y == 1)
|
| + vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
|
| + "4:2:0 color not supported in profile 1 or 3");
|
| + if (vp9_rb_read_bit(rb))
|
| + vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
|
| + "Reserved bit set");
|
| + } else {
|
| + cm->subsampling_y = cm->subsampling_x = 1;
|
| + }
|
| + } else {
|
| + if (cm->profile == PROFILE_1 || cm->profile == PROFILE_3) {
|
| + // Note if colorspace is SRGB then 4:4:4 chroma sampling is assumed.
|
| + // 4:2:2 or 4:4:0 chroma sampling is not allowed.
|
| + cm->subsampling_y = cm->subsampling_x = 0;
|
| + if (vp9_rb_read_bit(rb))
|
| + vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
|
| + "Reserved bit set");
|
| + } else {
|
| + vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
|
| + "4:4:4 color not supported in profile 0 or 2");
|
| + }
|
| + }
|
| +}
|
| +
|
| static size_t read_uncompressed_header(VP9Decoder *pbi,
|
| struct vp9_read_bit_buffer *rb) {
|
| VP9_COMMON *const cm = &pbi->common;
|
| @@ -1126,32 +1169,8 @@
|
| if (!vp9_read_sync_code(rb))
|
| vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
|
| "Invalid frame sync code");
|
| - if (cm->profile > PROFILE_1)
|
| - cm->bit_depth = vp9_rb_read_bit(rb) ? BITS_12 : BITS_10;
|
| - cm->color_space = (COLOR_SPACE)vp9_rb_read_literal(rb, 3);
|
| - if (cm->color_space != SRGB) {
|
| - vp9_rb_read_bit(rb); // [16,235] (including xvycc) vs [0,255] range
|
| - if (cm->profile == PROFILE_1 || cm->profile == PROFILE_3) {
|
| - cm->subsampling_x = vp9_rb_read_bit(rb);
|
| - cm->subsampling_y = vp9_rb_read_bit(rb);
|
| - if (vp9_rb_read_bit(rb))
|
| - vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
|
| - "Reserved bit set");
|
| - } else {
|
| - cm->subsampling_y = cm->subsampling_x = 1;
|
| - }
|
| - } else {
|
| - if (cm->profile == PROFILE_1 || cm->profile == PROFILE_3) {
|
| - cm->subsampling_y = cm->subsampling_x = 0;
|
| - if (vp9_rb_read_bit(rb))
|
| - vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
|
| - "Reserved bit set");
|
| - } else {
|
| - vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
|
| - "4:4:4 color not supported in profile 0");
|
| - }
|
| - }
|
|
|
| + read_bitdepth_colorspace_sampling(cm, rb);
|
| pbi->refresh_frame_flags = (1 << REF_FRAMES) - 1;
|
|
|
| for (i = 0; i < REFS_PER_FRAME; ++i) {
|
| @@ -1170,15 +1189,18 @@
|
| if (!vp9_read_sync_code(rb))
|
| vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
|
| "Invalid frame sync code");
|
| + if (cm->profile > PROFILE_0) {
|
| + read_bitdepth_colorspace_sampling(cm, rb);
|
| + } else {
|
| + // NOTE: The intra-only frame header does not include the specification
|
| + // of either the color format or color sub-sampling in profile 0. VP9
|
| + // specifies that the default color space should be YUV 4:2:0 in this
|
| + // case (normative).
|
| + cm->color_space = BT_601;
|
| + cm->subsampling_y = cm->subsampling_x = 1;
|
| + }
|
|
|
| pbi->refresh_frame_flags = vp9_rb_read_literal(rb, REF_FRAMES);
|
| -
|
| - // NOTE: The intra-only frame header does not include the specification of
|
| - // either the color format or color sub-sampling. VP9 specifies that the
|
| - // default color space should be YUV 4:2:0 in this case (normative).
|
| - cm->color_space = BT_601;
|
| - cm->subsampling_y = cm->subsampling_x = 1;
|
| -
|
| setup_frame_size(cm, rb);
|
| } else {
|
| pbi->refresh_frame_flags = vp9_rb_read_literal(rb, REF_FRAMES);
|
| @@ -1209,11 +1231,9 @@
|
| }
|
|
|
| if (!cm->error_resilient_mode) {
|
| - cm->coding_use_prev_mi = 1;
|
| cm->refresh_frame_context = vp9_rb_read_bit(rb);
|
| cm->frame_parallel_decoding_mode = vp9_rb_read_bit(rb);
|
| } else {
|
| - cm->coding_use_prev_mi = 0;
|
| cm->refresh_frame_context = 0;
|
| cm->frame_parallel_decoding_mode = 1;
|
| }
|
| @@ -1389,7 +1409,7 @@
|
|
|
| init_macroblockd(cm, &pbi->mb);
|
|
|
| - if (cm->coding_use_prev_mi)
|
| + if (!cm->error_resilient_mode)
|
| set_prev_mi(cm);
|
| else
|
| cm->prev_mi = NULL;
|
|
|