Commit b3b5304f authored by David Barker's avatar David Barker Committed by Debargha Mukherjee

scaling: Fix border clamping for subsampled planes

When forming a scaled prediction, we need to clamp against
the extended frame border which was set up when the relevant
reference frame was decoded. The width of this border actually
depends on the subsampling mode (for UV planes), but before this
patch we were always using the Y plane's border width.

This resulted in bad predictions when signalling a motion vector
which points far outside the reference frame. This patch fixes
the clamping, and restores the intended behaviour for out-of-frame
motion vectors.

Change-Id: I2cf575ce339a3e22a3c8444de0d0c3be031007c9
parent e65e12f5
......@@ -1106,8 +1106,8 @@ static INLINE void build_inter_predictors(const AV1_COMMON *cm, MACROBLOCKD *xd,
pos_x += SCALE_EXTRA_OFF;
pos_y += SCALE_EXTRA_OFF;
const int top = -AOM_LEFT_TOP_MARGIN_SCALED;
const int left = -AOM_LEFT_TOP_MARGIN_SCALED;
const int top = -AOM_LEFT_TOP_MARGIN_SCALED(ssy);
const int left = -AOM_LEFT_TOP_MARGIN_SCALED(ssx);
const int bottom = (pre_buf->height + AOM_INTERP_EXTEND)
<< SCALE_SUBPEL_BITS;
const int right = (pre_buf->width + AOM_INTERP_EXTEND)
......@@ -1220,8 +1220,8 @@ static INLINE void build_inter_predictors(const AV1_COMMON *cm, MACROBLOCKD *xd,
// Clamp against the reference frame borders, with enough extension
// that we don't force the reference block to be partially onscreen.
const int top = -AOM_LEFT_TOP_MARGIN_SCALED;
const int left = -AOM_LEFT_TOP_MARGIN_SCALED;
const int top = -AOM_LEFT_TOP_MARGIN_SCALED(ssy);
const int left = -AOM_LEFT_TOP_MARGIN_SCALED(ssx);
const int bottom = (pre_buf->height + AOM_INTERP_EXTEND)
<< SCALE_SUBPEL_BITS;
const int right = (pre_buf->width + AOM_INTERP_EXTEND)
......@@ -2550,8 +2550,8 @@ static void build_inter_predictors_single_buf(MACROBLOCKD *xd, int plane,
pos_x += SCALE_EXTRA_OFF;
pos_y += SCALE_EXTRA_OFF;
const int top = -AOM_LEFT_TOP_MARGIN_SCALED;
const int left = -AOM_LEFT_TOP_MARGIN_SCALED;
const int top = -AOM_LEFT_TOP_MARGIN_SCALED(ssy);
const int left = -AOM_LEFT_TOP_MARGIN_SCALED(ssx);
const int bottom = (pre_buf->height + AOM_INTERP_EXTEND)
<< SCALE_SUBPEL_BITS;
const int right = (pre_buf->width + AOM_INTERP_EXTEND) << SCALE_SUBPEL_BITS;
......
......@@ -22,8 +22,18 @@
#define WARP_GM_NEIGHBORS_WITH_OBMC 0
#define AOM_LEFT_TOP_MARGIN_SCALED \
((AOM_BORDER_IN_PIXELS - AOM_INTERP_EXTEND) << SCALE_SUBPEL_BITS)
// Work out how many pixels off the edge of a reference frame we're allowed
// to go when forming an inter prediction.
// The outermost row/col of each referernce frame is extended by
// (AOM_BORDER_IN_PIXELS >> subsampling) pixels, but we need to keep
// at least AOM_INTERP_EXTEND pixels within that to account for filtering.
//
// We have to break this up into two macros to keep both clang-format and
// tools/lint-hunks.py happy.
#define AOM_LEFT_TOP_MARGIN_PX(subsampling) \
((AOM_BORDER_IN_PIXELS >> subsampling) - AOM_INTERP_EXTEND)
#define AOM_LEFT_TOP_MARGIN_SCALED(subsampling) \
(AOM_LEFT_TOP_MARGIN_PX(subsampling) << SCALE_SUBPEL_BITS)
#ifdef __cplusplus
extern "C" {
......
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