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

Fix encode/decode mismatch when enabling frame resizing

There was a bug caused by the following sequence of events:
* A frame was coded full-size, filling out the
  cm->above_context array as normal.
* The next frame was coded at a reduced size
* Due to changes between VP9 and AV1, we now clear the
  context arrays per-tile on the decoder side. The amount
  cleared is the span of the tile, rounded up to the next
  mi unit. Since this frame is at a reduced size, this
  leaves some entries "off the edge of the frame" set to 1.
* get_entropy_context() reads a full transform block's worth
  of data from cm->above_context. This could read the off-frame
  1s, even when all the in-frame values were 0 (eg, because
  we're working on the topmost block of the frame).
* This leads to the decoder getting the wrong context, causing
  an encode/decode mismatch.

We fix this by rounding up to the next superblock, rather than
the next mi unit, when clearing the context arrays per-tile.
This is safe because all tiles other than the rightmost column
must be an integer number of superblocks wide.

BUG=aomedia:481

Change-Id: I8283c69957900572d44eb8d7f633cb59e352da3c
parent f9d77bd5
......@@ -862,9 +862,10 @@ static INLINE int max_block_high(const MACROBLOCKD *xd, BLOCK_SIZE bsize,
static INLINE void av1_zero_above_context(AV1_COMMON *const cm,
int mi_col_start, int mi_col_end) {
const int width = mi_col_end - mi_col_start;
const int aligned_width = ALIGN_POWER_OF_TWO(width, cm->mib_size_log2);
const int offset_y = 2 * mi_col_start;
const int width_y = 2 * width;
const int width_y = 2 * aligned_width;
const int offset_uv = offset_y >> cm->subsampling_x;
const int width_uv = width_y >> cm->subsampling_x;
......@@ -872,10 +873,10 @@ static INLINE void av1_zero_above_context(AV1_COMMON *const cm,
av1_zero_array(cm->above_context[1] + offset_uv, width_uv);
av1_zero_array(cm->above_context[2] + offset_uv, width_uv);
av1_zero_array(cm->above_seg_context + mi_col_start, width);
av1_zero_array(cm->above_seg_context + mi_col_start, aligned_width);
#if CONFIG_VAR_TX
av1_zero_array(cm->above_txfm_context + mi_col_start, width);
av1_zero_array(cm->above_txfm_context + mi_col_start, aligned_width);
#endif // CONFIG_VAR_TX
}
......
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