shithub: libvpx

Download patch

ref: 3c426572074ee10bf28832ea33e5dbef0a86a7fb
parent: 13eed79c776477f0bc3ed5e70c2fce69165cb77e
author: Dmitry Kovalev <dkovalev@google.com>
date: Thu Aug 22 11:19:05 EDT 2013

Checking scale factors on access.

It is possible to have invalid scale factors and not access them
during decoding. Error is reported if we really try to use invalid scale
factors.

Change-Id: Ie532d3ea7325ee0c7a6ada08269f804350c80fdf

--- a/vp9/common/vp9_reconinter.c
+++ b/vp9/common/vp9_reconinter.c
@@ -253,7 +253,7 @@
     vp9_zero(*sf);
   } else {
     YV12_BUFFER_CONFIG *const fb = &cm->yv12_fb[ref];
-    vp9_setup_scale_factors_for_frame(cm, sf,
+    vp9_setup_scale_factors_for_frame(sf,
                                       fb->y_crop_width, fb->y_crop_height,
                                       cm->width, cm->height);
 
--- a/vp9/common/vp9_scale.c
+++ b/vp9/common/vp9_scale.c
@@ -10,7 +10,6 @@
 
 #include "./vp9_rtcd.h"
 #include "vp9/common/vp9_filter.h"
-#include "vp9/common/vp9_onyxc_int.h"
 #include "vp9/common/vp9_scale.h"
 
 static INLINE int scaled_x(int val, const struct scale_factors *scale) {
@@ -70,33 +69,32 @@
          this_h <= 16 * other_h;
 }
 
-void vp9_setup_scale_factors_for_frame(struct VP9Common *cm,
-                                       struct scale_factors *scale,
+void vp9_setup_scale_factors_for_frame(struct scale_factors *scale,
                                        int other_w, int other_h,
                                        int this_w, int this_h) {
-  if (!check_scale_factors(other_w, other_h, this_w, this_h))
-    vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
-                       "Invalid scale factors");
+  if (!check_scale_factors(other_w, other_h, this_w, this_h)) {
+    scale->x_scale_fp = VP9_REF_INVALID_SCALE;
+    scale->y_scale_fp = VP9_REF_INVALID_SCALE;
+    return;
+  }
 
-
   scale->x_scale_fp = get_fixed_point_scale_factor(other_w, this_w);
-  scale->x_offset_q4 = 0;  // calculated per block
-  scale->x_step_q4 = scaled_x(16, scale);
-
   scale->y_scale_fp = get_fixed_point_scale_factor(other_h, this_h);
-  scale->y_offset_q4 = 0;  // calculated per block
+  scale->x_step_q4 = scaled_x(16, scale);
   scale->y_step_q4 = scaled_y(16, scale);
+  scale->x_offset_q4 = 0;  // calculated per block
+  scale->y_offset_q4 = 0;  // calculated per block
 
-  if (other_w == this_w && other_h == this_h) {
-    scale->scale_value_x = unscaled_value;
-    scale->scale_value_y = unscaled_value;
-    scale->set_scaled_offsets = set_offsets_without_scaling;
-    scale->scale_mv = unscaled_mv;
-  } else {
+  if (vp9_is_scaled(scale)) {
     scale->scale_value_x = scaled_x;
     scale->scale_value_y = scaled_y;
     scale->set_scaled_offsets = set_offsets_with_scaling;
     scale->scale_mv = scaled_mv;
+  } else {
+    scale->scale_value_x = unscaled_value;
+    scale->scale_value_y = unscaled_value;
+    scale->set_scaled_offsets = set_offsets_without_scaling;
+    scale->scale_mv = unscaled_mv;
   }
 
   // TODO(agrange): Investigate the best choice of functions to use here
--- a/vp9/common/vp9_scale.h
+++ b/vp9/common/vp9_scale.h
@@ -14,10 +14,9 @@
 #include "vp9/common/vp9_mv.h"
 #include "vp9/common/vp9_convolve.h"
 
-struct VP9Common;
-
 #define VP9_REF_SCALE_SHIFT 14
 #define VP9_REF_NO_SCALE (1 << VP9_REF_SCALE_SHIFT)
+#define VP9_REF_INVALID_SCALE -1
 
 struct scale_factors {
   int x_scale_fp;   // horizontal fixed point scale factor
@@ -35,10 +34,14 @@
   convolve_fn_t predict[2][2][2];  // horiz, vert, avg
 };
 
-void vp9_setup_scale_factors_for_frame(struct VP9Common *cm,
-                                       struct scale_factors *scale,
+void vp9_setup_scale_factors_for_frame(struct scale_factors *scale,
                                        int other_w, int other_h,
                                        int this_w, int this_h);
+
+static int vp9_is_valid_scale(const struct scale_factors *sf) {
+  return sf->x_scale_fp != VP9_REF_INVALID_SCALE &&
+         sf->y_scale_fp != VP9_REF_INVALID_SCALE;
+}
 
 static int vp9_is_scaled(const struct scale_factors *sf) {
   return sf->x_scale_fp != VP9_REF_NO_SCALE ||
--- a/vp9/decoder/vp9_decodframe.c
+++ b/vp9/decoder/vp9_decodframe.c
@@ -202,11 +202,15 @@
   VP9_COMMON *const cm = &pbi->common;
   MACROBLOCKD *const xd = &pbi->mb;
   MB_MODE_INFO *const mbmi = &xd->mode_info_context->mbmi;
-  const int ref = mbmi->ref_frame[i] - 1;
-
+  const int ref = mbmi->ref_frame[i] - LAST_FRAME;
   const YV12_BUFFER_CONFIG *cfg = &cm->yv12_fb[cm->active_ref_idx[ref]];
-  xd->scale_factor[i] = cm->active_ref_scale[ref];
-  setup_pre_planes(xd, i, cfg, mi_row, mi_col, &xd->scale_factor[i]);
+  const struct scale_factors *sf = &cm->active_ref_scale[ref];
+  if (!vp9_is_valid_scale(sf))
+    vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
+                       "Invalid scale factors");
+
+  xd->scale_factor[i] = *sf;
+  setup_pre_planes(xd, i, cfg, mi_row, mi_col, sf);
   xd->corrupted |= cfg->corrupted;
 }
 
--- a/vp9/encoder/vp9_temporal_filter.c
+++ b/vp9/encoder/vp9_temporal_filter.c
@@ -437,7 +437,7 @@
 #endif
 
   // Setup scaling factors. Scaling on each of the arnr frames is not supported
-  vp9_setup_scale_factors_for_frame(cm, &cpi->mb.e_mbd.scale_factor[0],
+  vp9_setup_scale_factors_for_frame(&cpi->mb.e_mbd.scale_factor[0],
       cm->yv12_fb[cm->new_fb_idx].y_crop_width,
       cm->yv12_fb[cm->new_fb_idx].y_crop_height,
       cm->width, cm->height);