Commit 3c426572 authored by Dmitry Kovalev's avatar Dmitry Kovalev
Browse files

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
parent 13eed79c
......@@ -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);
......
......@@ -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
......
......@@ -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;
......
......@@ -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;
}
......
......@@ -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);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment