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