From 3c426572074ee10bf28832ea33e5dbef0a86a7fb Mon Sep 17 00:00:00 2001 From: Dmitry Kovalev Date: Thu, 22 Aug 2013 15:19:05 -0700 Subject: [PATCH] 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 --- vp9/common/vp9_reconinter.c | 2 +- vp9/common/vp9_scale.c | 32 +++++++++++++++---------------- vp9/common/vp9_scale.h | 11 +++++++---- vp9/decoder/vp9_decodframe.c | 12 ++++++++---- vp9/encoder/vp9_temporal_filter.c | 2 +- 5 files changed, 32 insertions(+), 27 deletions(-) diff --git a/vp9/common/vp9_reconinter.c b/vp9/common/vp9_reconinter.c index 1975e2e76..89c2aa820 100644 --- a/vp9/common/vp9_reconinter.c +++ b/vp9/common/vp9_reconinter.c @@ -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); diff --git a/vp9/common/vp9_scale.c b/vp9/common/vp9_scale.c index 12acac1c9..0b8dc23ea 100644 --- 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 @@ 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 diff --git a/vp9/common/vp9_scale.h b/vp9/common/vp9_scale.h index e3fcae1fc..827ae9bce 100644 --- 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,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; diff --git a/vp9/decoder/vp9_decodframe.c b/vp9/decoder/vp9_decodframe.c index 70e85f95a..58a01e488 100644 --- a/vp9/decoder/vp9_decodframe.c +++ b/vp9/decoder/vp9_decodframe.c @@ -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; } diff --git a/vp9/encoder/vp9_temporal_filter.c b/vp9/encoder/vp9_temporal_filter.c index 74fb07ee3..3052e8f70 100644 --- a/vp9/encoder/vp9_temporal_filter.c +++ b/vp9/encoder/vp9_temporal_filter.c @@ -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); -- 2.40.0