| Index: source/libvpx/vp9/decoder/vp9_decodeframe.c
|
| ===================================================================
|
| --- source/libvpx/vp9/decoder/vp9_decodeframe.c (revision 284462)
|
| +++ source/libvpx/vp9/decoder/vp9_decodeframe.c (working copy)
|
| @@ -620,23 +620,34 @@
|
| vp9_read_frame_size(rb, &cm->display_width, &cm->display_height);
|
| }
|
|
|
| -static void apply_frame_size(VP9_COMMON *cm, int width, int height) {
|
| +static void resize_context_buffers(VP9_COMMON *cm, int width, int height) {
|
| +#if CONFIG_SIZE_LIMIT
|
| + if (width > DECODE_WIDTH_LIMIT || height > DECODE_HEIGHT_LIMIT)
|
| + vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME,
|
| + "Width and height beyond allowed size.");
|
| +#endif
|
| if (cm->width != width || cm->height != height) {
|
| - // Change in frame size.
|
| - // TODO(agrange) Don't test width/height, check overall size.
|
| - if (width > cm->width || height > cm->height) {
|
| - // Rescale frame buffers only if they're not big enough already.
|
| - if (vp9_resize_frame_buffers(cm, width, height))
|
| + // Change in frame size (assumption: color format does not change).
|
| + if (cm->width == 0 || cm->height == 0 ||
|
| + width * height > cm->width * cm->height) {
|
| + if (vp9_alloc_context_buffers(cm, width, height))
|
| vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
|
| "Failed to allocate frame buffers");
|
| + } else {
|
| + vp9_set_mb_mi(cm, width, height);
|
| }
|
| -
|
| + vp9_init_context_buffers(cm);
|
| cm->width = width;
|
| cm->height = height;
|
| -
|
| - vp9_update_frame_size(cm);
|
| }
|
| +}
|
|
|
| +static void setup_frame_size(VP9_COMMON *cm, struct vp9_read_bit_buffer *rb) {
|
| + int width, height;
|
| + vp9_read_frame_size(rb, &width, &height);
|
| + resize_context_buffers(cm, width, height);
|
| + setup_display_size(cm, rb);
|
| +
|
| if (vp9_realloc_frame_buffer(
|
| get_frame_new_buffer(cm), cm->width, cm->height,
|
| cm->subsampling_x, cm->subsampling_y, VP9_DEC_BORDER_IN_PIXELS,
|
| @@ -647,13 +658,6 @@
|
| }
|
| }
|
|
|
| -static void setup_frame_size(VP9_COMMON *cm, struct vp9_read_bit_buffer *rb) {
|
| - int width, height;
|
| - vp9_read_frame_size(rb, &width, &height);
|
| - apply_frame_size(cm, width, height);
|
| - setup_display_size(cm, rb);
|
| -}
|
| -
|
| static void setup_frame_size_with_refs(VP9_COMMON *cm,
|
| struct vp9_read_bit_buffer *rb) {
|
| int width, height;
|
| @@ -675,16 +679,23 @@
|
| // 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))
|
| + 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");
|
| }
|
|
|
| - apply_frame_size(cm, width, height);
|
| + resize_context_buffers(cm, width, height);
|
| setup_display_size(cm, rb);
|
| +
|
| + if (vp9_realloc_frame_buffer(
|
| + get_frame_new_buffer(cm), cm->width, cm->height,
|
| + cm->subsampling_x, cm->subsampling_y, VP9_DEC_BORDER_IN_PIXELS,
|
| + &cm->frame_bufs[cm->new_fb_idx].raw_frame_buffer, cm->get_fb_cb,
|
| + cm->cb_priv)) {
|
| + vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
|
| + "Failed to allocate frame buffer");
|
| + }
|
| }
|
|
|
| static void setup_tile_info(VP9_COMMON *cm, struct vp9_read_bit_buffer *rb) {
|
| @@ -1065,9 +1076,11 @@
|
| vp9_rb_read_literal(rb, 8) == VP9_SYNC_CODE_2;
|
| }
|
|
|
| -static BITSTREAM_PROFILE read_profile(struct vp9_read_bit_buffer *rb) {
|
| +BITSTREAM_PROFILE vp9_read_profile(struct vp9_read_bit_buffer *rb) {
|
| int profile = vp9_rb_read_bit(rb);
|
| profile |= vp9_rb_read_bit(rb) << 1;
|
| + if (profile > 2)
|
| + profile += vp9_rb_read_bit(rb);
|
| return (BITSTREAM_PROFILE) profile;
|
| }
|
|
|
| @@ -1083,7 +1096,7 @@
|
| vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
|
| "Invalid frame marker");
|
|
|
| - cm->profile = read_profile(rb);
|
| + cm->profile = vp9_read_profile(rb);
|
| if (cm->profile >= MAX_PROFILES)
|
| vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
|
| "Unsupported bitstream profile");
|
| @@ -1118,7 +1131,7 @@
|
| 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) {
|
| + 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);
|
| vp9_rb_read_bit(rb); // has extra plane
|
| @@ -1126,20 +1139,20 @@
|
| cm->subsampling_y = cm->subsampling_x = 1;
|
| }
|
| } else {
|
| - if (cm->profile >= PROFILE_1) {
|
| + if (cm->profile == PROFILE_1 || cm->profile == PROFILE_3) {
|
| cm->subsampling_y = cm->subsampling_x = 0;
|
| vp9_rb_read_bit(rb); // has extra plane
|
| } else {
|
| vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
|
| - "RGB not supported in profile 0");
|
| + "4:4:4 color not supported in profile 0");
|
| }
|
| }
|
|
|
| pbi->refresh_frame_flags = (1 << REF_FRAMES) - 1;
|
|
|
| for (i = 0; i < REFS_PER_FRAME; ++i) {
|
| - cm->frame_refs[i].idx = cm->new_fb_idx;
|
| - cm->frame_refs[i].buf = get_frame_new_buffer(cm);
|
| + cm->frame_refs[i].idx = -1;
|
| + cm->frame_refs[i].buf = NULL;
|
| }
|
|
|
| setup_frame_size(cm, rb);
|
|
|