Commit 5c06a646 authored by David Barker's avatar David Barker

Fix tile boundary calculation

Fix a rare case in which the tile boundary information was not
set up properly in the decoder when using LOOPFILTERING_ACROSS_TILES

The situation was:
* One frame uses loop filtering across tiles. Then its tile
  boundary information is not needed, so is not calculated.
* The next frame (in decode order) has the same size and the
  same tile layout, but doesn't use loop filtering across tiles.
* Now the tile boundary information *is* needed, but we weren't
  recalculating it. This resulted in the loop filter being
  applied across tile boundaries even though we signalled not to.

Since the conditions on when we can reuse the previous frame's
boundary information are complex, and the overhead of calculating
the tile boundaries is low, we avoid this issue by simply
recalculating the boundary information each frame.

Change-Id: I1f3cbb0537535bf38faaed4c21c07142e747f962
parent eac51a94
......@@ -103,13 +103,10 @@ void av1_setup_frame_boundary_info(const AV1_COMMON *const cm) {
}
}
#if CONFIG_LOOPFILTERING_ACROSS_TILES
void av1_setup_across_tile_boundary_info(const AV1_COMMON *const cm,
const TileInfo *const tile_info) {
int lpf_across_tiles_enabled = 1;
#if CONFIG_LOOPFILTERING_ACROSS_TILES
lpf_across_tiles_enabled = cm->loop_filter_across_tiles_enabled;
#endif
if ((cm->tile_cols * cm->tile_rows > 1) && (!lpf_across_tiles_enabled)) {
if (cm->tile_cols * cm->tile_rows > 1) {
const int mi_row = tile_info->mi_row_start;
const int mi_col = tile_info->mi_col_start;
MODE_INFO *const mi_start = cm->mi + mi_row * cm->mi_stride + mi_col;
......@@ -150,7 +147,6 @@ void av1_setup_across_tile_boundary_info(const AV1_COMMON *const cm,
}
}
#if CONFIG_LOOPFILTERING_ACROSS_TILES
int av1_disable_loopfilter_on_tile_boundary(const struct AV1Common *cm) {
return (!cm->loop_filter_across_tiles_enabled &&
(cm->tile_cols * cm->tile_rows > 1));
......
......@@ -43,10 +43,10 @@ void av1_get_tile_n_bits(int mi_cols, int *min_log2_tile_cols,
int *max_log2_tile_cols);
void av1_setup_frame_boundary_info(const struct AV1Common *const cm);
void av1_setup_across_tile_boundary_info(const struct AV1Common *const cm,
const TileInfo *const tile_info);
#if CONFIG_LOOPFILTERING_ACROSS_TILES
void av1_setup_across_tile_boundary_info(const struct AV1Common *const cm,
const TileInfo *const tile_info);
int av1_disable_loopfilter_on_tile_boundary(const struct AV1Common *cm);
#endif // CONFIG_LOOPFILTERING_ACROSS_TILES
......
......@@ -3569,18 +3569,18 @@ static void daala_dec_init(AV1_COMMON *const cm, daala_dec_ctx *daala_dec,
}
#endif // #if CONFIG_PVQ
#if CONFIG_LOOPFILTERING_ACROSS_TILES
static void dec_setup_across_tile_boundary_info(
const AV1_COMMON *const cm, const TileInfo *const tile_info) {
if (tile_info->mi_row_start >= tile_info->mi_row_end ||
tile_info->mi_col_start >= tile_info->mi_col_end)
return;
if (cm->width != cm->last_width || cm->height != cm->last_height ||
cm->tile_cols != cm->last_tile_cols ||
cm->tile_rows != cm->last_tile_rows) {
if (!cm->loop_filter_across_tiles_enabled) {
av1_setup_across_tile_boundary_info(cm, tile_info);
}
}
#endif // CONFIG_LOOPFILTERING_ACROSS_TILES
static const uint8_t *decode_tiles(AV1Decoder *pbi, const uint8_t *data,
const uint8_t *data_end) {
......@@ -3748,7 +3748,9 @@ static const uint8_t *decode_tiles(AV1Decoder *pbi, const uint8_t *data,
av1_zero_above_context(cm, tile_info.mi_col_start, tile_info.mi_col_end);
#endif
#if CONFIG_LOOPFILTERING_ACROSS_TILES
dec_setup_across_tile_boundary_info(cm, &tile_info);
#endif // CONFIG_LOOPFILTERING_ACROSS_TILES
for (mi_row = tile_info.mi_row_start; mi_row < tile_info.mi_row_end;
mi_row += cm->mib_size) {
......@@ -4070,7 +4072,9 @@ static const uint8_t *decode_tiles_mt(AV1Decoder *pbi, const uint8_t *data,
av1_tile_init(tile_info, cm, tile_row, buf->col);
av1_tile_init(&twd->xd.tile, cm, tile_row, buf->col);
#if CONFIG_LOOPFILTERING_ACROSS_TILES
dec_setup_across_tile_boundary_info(cm, tile_info);
#endif // CONFIG_LOOPFILTERING_ACROSS_TILES
setup_bool_decoder(buf->data, data_end, buf->size, &cm->error,
&twd->bit_reader,
......@@ -5142,9 +5146,15 @@ void superres_post_decode(AV1Decoder *pbi) {
#endif // CONFIG_FRAME_SUPERRES
static void dec_setup_frame_boundary_info(AV1_COMMON *const cm) {
if (cm->width != cm->last_width || cm->height != cm->last_height ||
cm->tile_cols != cm->last_tile_cols ||
cm->tile_rows != cm->last_tile_rows) {
// Note: When LOOPFILTERING_ACROSS_TILES is enabled, we need to clear the
// boundary information every frame, since the tile boundaries may
// change every frame (particularly when dependent-horztiles is also
// enabled); when it is disabled, the only information stored is the frame
// boundaries, which only depend on the frame size.
#if !CONFIG_LOOPFILTERING_ACROSS_TILES
if (cm->width != cm->last_width || cm->height != cm->last_height)
#endif // CONFIG_LOOPFILTERING_ACROSS_TILES
{
int row, col;
for (row = 0; row < cm->mi_rows; ++row) {
MODE_INFO *mi = cm->mi + row * cm->mi_stride;
......
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