shithub: libvpx

Download patch

ref: 9261e1aa6e192ff72cd4ded00898b001c0ead4b9
parent: 0cf0b02c4c9dd7dc1338a7514a1e47588d74e704
author: Yaowu Xu <yaowu@google.com>
date: Thu Jul 24 05:12:46 EDT 2014

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

--- a/vp9/decoder/vp9_decodeframe.c
+++ b/vp9/decoder/vp9_decodeframe.c
@@ -662,6 +662,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 +676,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_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);
--- a/vp9/decoder/vp9_decodemv.c
+++ b/vp9/decoder/vp9_decodemv.c
@@ -435,6 +435,11 @@
 
   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);
   }