Checking scale factors on access.
authorDmitry Kovalev <dkovalev@google.com>
Thu, 22 Aug 2013 22:19:05 +0000 (15:19 -0700)
committerDmitry Kovalev <dkovalev@google.com>
Thu, 22 Aug 2013 22:19:05 +0000 (15:19 -0700)
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

vp9/common/vp9_reconinter.c
vp9/common/vp9_scale.c
vp9/common/vp9_scale.h
vp9/decoder/vp9_decodframe.c
vp9/encoder/vp9_temporal_filter.c

index 1975e2e..89c2aa8 100644 (file)
@@ -253,7 +253,7 @@ void vp9_setup_scale_factors(VP9_COMMON *cm, int i) {
     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);
 
index 12acac1..0b8dc23 100644 (file)
@@ -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 @@ static int check_scale_factors(int other_w, int other_h,
          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
index e3fcae1..827ae9b 100644 (file)
 #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,11 +34,15 @@ struct scale_factors {
   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 ||
          sf->y_scale_fp != VP9_REF_NO_SCALE;
index 70e85f9..58a01e4 100644 (file)
@@ -202,11 +202,15 @@ static void set_ref(VP9D_COMP *pbi, int i, int mi_row, int mi_col) {
   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;
 }
 
index 74fb07e..3052e8f 100644 (file)
@@ -437,7 +437,7 @@ void vp9_temporal_filter_prepare(VP9_COMP *cpi, int distance) {
 #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);