From 9261e1aa6e192ff72cd4ded00898b001c0ead4b9 Mon Sep 17 00:00:00 2001 From: Yaowu Xu Date: Thu, 24 Jul 2014 09:12:46 -0700 Subject: [PATCH] Changed validation of reference frame size A previous change, https://gerrit.chromium.org/gerrit/#/c/70632, introduced a size validation for reference frames to insuare the input stream is a valid VP9 stream. However, the logic requiring all reference frames have valid size turned out to be too strict. In this commit, we modify the validation to require one of the reference frame has valid dimension. In addition, the decoder reports error whenever it detects the use of reference frame with invalid scalig ratio. Change-Id: If8efc312244087556cfe00f1fcbdff811268ebad --- vp9/decoder/vp9_decodeframe.c | 19 +++++++++++++------ vp9/decoder/vp9_decodemv.c | 5 +++++ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/vp9/decoder/vp9_decodeframe.c b/vp9/decoder/vp9_decodeframe.c index 28c674a38..932b89152 100644 --- a/vp9/decoder/vp9_decodeframe.c +++ b/vp9/decoder/vp9_decodeframe.c @@ -662,6 +662,7 @@ static void setup_frame_size_with_refs(VP9_COMMON *cm, 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 +676,21 @@ static void setup_frame_size_with_refs(VP9_COMMON *cm, 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_width, + ref_frame->buf->y_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); diff --git a/vp9/decoder/vp9_decodemv.c b/vp9/decoder/vp9_decodemv.c index 1afaee1e3..32e80f93b 100644 --- a/vp9/decoder/vp9_decodemv.c +++ b/vp9/decoder/vp9_decodemv.c @@ -435,6 +435,11 @@ static void read_inter_block_mode_info(VP9_COMMON *const cm, for (ref = 0; ref < 1 + is_compound; ++ref) { const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref]; + const int ref_idx = frame - LAST_FRAME; + if (cm->frame_refs[ref_idx].sf.x_scale_fp == REF_INVALID_SCALE || + cm->frame_refs[ref_idx].sf.y_scale_fp == REF_INVALID_SCALE ) + vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM, + "Reference frame has invalid dimensions"); vp9_find_mv_refs(cm, xd, tile, mi, frame, mbmi->ref_mvs[frame], mi_row, mi_col); }