Commit 9a3640d8 authored by Rupert Swarbrick's avatar Rupert Swarbrick Committed by Debargha Mukherjee

Fix tile height/width calculation

In the bitstream in bug 709, the frame has a width of 13318 mi
units. This rounds up to 13328 mi units (when rounding to a whole
number of max superblocks) but then the shift right by log2_tile_cols
gives floor(13328/32) = floor(416.5) = 416. Of course 32*416 = 13312
which is less than 13318.

This patch moves the <mi_cols, log2_tile_cols> -> tile_width
calculation (and the equivalent calculation for tile_height) into a
common function which gets the rounding right.

BUG=aomedia:709

Change-Id: If5e8e6b7a3c6f3d336cda9edd94a17595eaf5406
parent f9ef4f6b
......@@ -103,6 +103,17 @@ void av1_setup_frame_boundary_info(const AV1_COMMON *const cm) {
}
}
int get_tile_size(int frame_mi_size, int log2_tile_num) {
// Round the frame up to a whole number of max superblocks
frame_mi_size = ALIGN_POWER_OF_TWO(frame_mi_size, MAX_MIB_SIZE_LOG2);
// Divide by the number of tiles, rounding up to the multiple of the max
// superblock size. To do this, shift right (and round up) to get the number
// of super-blocks and then shift left again to convert it to mi units.
const int shift = log2_tile_num + MAX_MIB_SIZE_LOG2;
const int round = (1 << shift) - 1;
return ((frame_mi_size + round) >> shift) << MAX_MIB_SIZE_LOG2;
}
#if CONFIG_LOOPFILTERING_ACROSS_TILES
void av1_setup_across_tile_boundary_info(const AV1_COMMON *const cm,
const TileInfo *const tile_info) {
......
......@@ -44,6 +44,10 @@ void av1_get_tile_n_bits(int mi_cols, int *min_log2_tile_cols,
void av1_setup_frame_boundary_info(const struct AV1Common *const cm);
// Calculate the correct tile size (width or height) for (1 << log2_tile_num)
// tiles horizontally or vertically in the frame.
int get_tile_size(int frame_mi_size, int log2_tile_num);
#if CONFIG_LOOPFILTERING_ACROSS_TILES
void av1_setup_across_tile_boundary_info(const struct AV1Common *const cm,
const TileInfo *const tile_info);
......
......@@ -3207,14 +3207,8 @@ static void read_tile_info(AV1Decoder *const pbi,
cm->loop_filter_across_tiles_enabled = aom_rb_read_bit(rb);
#endif // CONFIG_LOOPFILTERING_ACROSS_TILES
cm->tile_width = ALIGN_POWER_OF_TWO(cm->mi_cols, MAX_MIB_SIZE_LOG2);
cm->tile_width >>= cm->log2_tile_cols;
cm->tile_height = ALIGN_POWER_OF_TWO(cm->mi_rows, MAX_MIB_SIZE_LOG2);
cm->tile_height >>= cm->log2_tile_rows;
// round to integer multiples of superblock size
cm->tile_width = ALIGN_POWER_OF_TWO(cm->tile_width, MAX_MIB_SIZE_LOG2);
cm->tile_height = ALIGN_POWER_OF_TWO(cm->tile_height, MAX_MIB_SIZE_LOG2);
cm->tile_width = get_tile_size(cm->mi_cols, cm->log2_tile_cols);
cm->tile_height = get_tile_size(cm->mi_rows, cm->log2_tile_rows);
const int max_cols = (cm->mi_cols + cm->tile_width - 1) / cm->tile_width;
const int max_rows = (cm->mi_rows + cm->tile_height - 1) / cm->tile_height;
......
......@@ -896,14 +896,8 @@ static void set_tile_info(AV1_COMP *cpi) {
clamp(cpi->oxcf.tile_columns, min_log2_tile_cols, max_log2_tile_cols);
cm->log2_tile_rows = cpi->oxcf.tile_rows;
cm->tile_width = ALIGN_POWER_OF_TWO(cm->mi_cols, MAX_MIB_SIZE_LOG2);
cm->tile_width >>= cm->log2_tile_cols;
cm->tile_height = ALIGN_POWER_OF_TWO(cm->mi_rows, MAX_MIB_SIZE_LOG2);
cm->tile_height >>= cm->log2_tile_rows;
// round to integer multiples of max superblock size
cm->tile_width = ALIGN_POWER_OF_TWO(cm->tile_width, MAX_MIB_SIZE_LOG2);
cm->tile_height = ALIGN_POWER_OF_TWO(cm->tile_height, MAX_MIB_SIZE_LOG2);
cm->tile_width = get_tile_size(cm->mi_cols, cm->log2_tile_cols);
cm->tile_height = get_tile_size(cm->mi_rows, cm->log2_tile_rows);
const int max_cols = (cm->mi_cols + cm->tile_width - 1) / cm->tile_width;
const int max_rows = (cm->mi_rows + cm->tile_height - 1) / cm->tile_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