Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1 | /* |
Yaowu Xu | 2ab7ff0 | 2016-09-02 12:04:54 -0700 | [diff] [blame] | 2 | * Copyright (c) 2016, Alliance for Open Media. All rights reserved |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 3 | * |
Yaowu Xu | 2ab7ff0 | 2016-09-02 12:04:54 -0700 | [diff] [blame] | 4 | * This source code is subject to the terms of the BSD 2 Clause License and |
| 5 | * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License |
| 6 | * was not distributed with this source code in the LICENSE file, you can |
| 7 | * obtain it at www.aomedia.org/license/software. If the Alliance for Open |
| 8 | * Media Patent License 1.0 was not distributed with this source code in the |
| 9 | * PATENTS file, you can obtain it at www.aomedia.org/license/patent. |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 10 | */ |
| 11 | |
| 12 | #include "av1/common/tile_common.h" |
| 13 | #include "av1/common/onyxc_int.h" |
Rupert Swarbrick | 33ed9e6 | 2017-10-23 13:32:37 +0100 | [diff] [blame] | 14 | #include "av1/common/resize.h" |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 15 | #include "aom_dsp/aom_dsp_common.h" |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 16 | |
Thomas Davies | b25ba50 | 2017-07-18 10:18:24 +0100 | [diff] [blame] | 17 | #if CONFIG_DEPENDENT_HORZTILES |
Fangwen Fu | 73126c0 | 2017-02-08 22:37:47 -0800 | [diff] [blame] | 18 | void av1_tile_set_tg_boundary(TileInfo *tile, const AV1_COMMON *const cm, |
| 19 | int row, int col) { |
Peter de Rivaz | e33fcbd | 2017-12-15 10:28:35 +0000 | [diff] [blame] | 20 | #if CONFIG_DEPENDENT_HORZTILEGROUPS |
| 21 | (void)cm; |
| 22 | (void)col; |
| 23 | #if !CONFIG_MAX_TILE |
| 24 | (void)row; |
| 25 | #endif |
David Barker | 1302519 | 2018-01-19 16:57:13 +0000 | [diff] [blame] | 26 | tile->tg_horz_boundary = (row == 0); |
Peter de Rivaz | e33fcbd | 2017-12-15 10:28:35 +0000 | [diff] [blame] | 27 | #else |
David Barker | 8643843 | 2017-08-21 12:40:37 +0100 | [diff] [blame] | 28 | const int tg_start_row = cm->tile_group_start_row[row][col]; |
| 29 | const int tg_start_col = cm->tile_group_start_col[row][col]; |
| 30 | tile->tg_horz_boundary = ((row == tg_start_row && col >= tg_start_col) || |
| 31 | (row == tg_start_row + 1 && col < tg_start_col)); |
Peter de Rivaz | e33fcbd | 2017-12-15 10:28:35 +0000 | [diff] [blame] | 32 | #endif |
Dominic Symes | f58f111 | 2017-09-25 12:47:40 +0200 | [diff] [blame] | 33 | #if CONFIG_MAX_TILE |
| 34 | if (cm->tile_row_independent[row]) { |
| 35 | tile->tg_horz_boundary = 1; // this tile row is independent |
| 36 | } |
| 37 | #endif |
Fangwen Fu | 73126c0 | 2017-02-08 22:37:47 -0800 | [diff] [blame] | 38 | } |
| 39 | #endif |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 40 | void av1_tile_init(TileInfo *tile, const AV1_COMMON *cm, int row, int col) { |
| 41 | av1_tile_set_row(tile, cm, row); |
| 42 | av1_tile_set_col(tile, cm, col); |
Thomas Davies | b25ba50 | 2017-07-18 10:18:24 +0100 | [diff] [blame] | 43 | #if CONFIG_DEPENDENT_HORZTILES |
Fangwen Fu | 73126c0 | 2017-02-08 22:37:47 -0800 | [diff] [blame] | 44 | av1_tile_set_tg_boundary(tile, cm, row, col); |
| 45 | #endif |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 46 | } |
| 47 | |
Dominic Symes | db5d66f | 2017-08-18 18:11:34 +0200 | [diff] [blame] | 48 | #if CONFIG_MAX_TILE |
| 49 | |
| 50 | // Find smallest k>=0 such that (blk_size << k) >= target |
| 51 | static int tile_log2(int blk_size, int target) { |
| 52 | int k; |
| 53 | for (k = 0; (blk_size << k) < target; k++) { |
| 54 | } |
| 55 | return k; |
| 56 | } |
| 57 | |
| 58 | void av1_get_tile_limits(AV1_COMMON *const cm) { |
Imdad Sardharwalla | 4ec84ab | 2018-02-06 12:20:18 +0000 | [diff] [blame] | 59 | int mi_cols = ALIGN_POWER_OF_TWO(cm->mi_cols, cm->seq_params.mib_size_log2); |
| 60 | int mi_rows = ALIGN_POWER_OF_TWO(cm->mi_rows, cm->seq_params.mib_size_log2); |
| 61 | int sb_cols = mi_cols >> cm->seq_params.mib_size_log2; |
| 62 | int sb_rows = mi_rows >> cm->seq_params.mib_size_log2; |
Dominic Symes | db5d66f | 2017-08-18 18:11:34 +0200 | [diff] [blame] | 63 | |
| 64 | cm->min_log2_tile_cols = tile_log2(MAX_TILE_WIDTH_SB, sb_cols); |
Dominic Symes | f58f111 | 2017-09-25 12:47:40 +0200 | [diff] [blame] | 65 | cm->max_log2_tile_cols = tile_log2(1, AOMMIN(sb_cols, MAX_TILE_COLS)); |
| 66 | cm->max_log2_tile_rows = tile_log2(1, AOMMIN(sb_rows, MAX_TILE_ROWS)); |
Dominic Symes | db5d66f | 2017-08-18 18:11:34 +0200 | [diff] [blame] | 67 | cm->min_log2_tiles = tile_log2(MAX_TILE_AREA_SB, sb_cols * sb_rows); |
| 68 | cm->min_log2_tiles = AOMMAX(cm->min_log2_tiles, cm->min_log2_tile_cols); |
| 69 | // TODO(dominic.symes@arm.com): |
| 70 | // Add in levelMinLog2Tiles as a lower limit when levels are defined |
| 71 | } |
| 72 | |
| 73 | void av1_calculate_tile_cols(AV1_COMMON *const cm) { |
Imdad Sardharwalla | 4ec84ab | 2018-02-06 12:20:18 +0000 | [diff] [blame] | 74 | int mi_cols = ALIGN_POWER_OF_TWO(cm->mi_cols, cm->seq_params.mib_size_log2); |
| 75 | int mi_rows = ALIGN_POWER_OF_TWO(cm->mi_rows, cm->seq_params.mib_size_log2); |
| 76 | int sb_cols = mi_cols >> cm->seq_params.mib_size_log2; |
| 77 | int sb_rows = mi_rows >> cm->seq_params.mib_size_log2; |
Dominic Symes | db5d66f | 2017-08-18 18:11:34 +0200 | [diff] [blame] | 78 | int i; |
| 79 | |
| 80 | if (cm->uniform_tile_spacing_flag) { |
| 81 | int start_sb; |
| 82 | int size_sb = ALIGN_POWER_OF_TWO(sb_cols, cm->log2_tile_cols); |
| 83 | size_sb >>= cm->log2_tile_cols; |
| 84 | assert(size_sb > 0); |
| 85 | for (i = 0, start_sb = 0; start_sb < sb_cols; i++) { |
| 86 | cm->tile_col_start_sb[i] = start_sb; |
| 87 | start_sb += size_sb; |
| 88 | } |
| 89 | cm->tile_cols = i; |
Dominic Symes | f58f111 | 2017-09-25 12:47:40 +0200 | [diff] [blame] | 90 | cm->tile_col_start_sb[i] = sb_cols; |
Dominic Symes | db5d66f | 2017-08-18 18:11:34 +0200 | [diff] [blame] | 91 | cm->min_log2_tile_rows = AOMMAX(cm->min_log2_tiles - cm->log2_tile_cols, 0); |
Dominic Symes | f58f111 | 2017-09-25 12:47:40 +0200 | [diff] [blame] | 92 | cm->max_tile_height_sb = sb_rows >> cm->min_log2_tile_rows; |
Dominic Symes | db5d66f | 2017-08-18 18:11:34 +0200 | [diff] [blame] | 93 | } else { |
| 94 | int max_tile_area_sb = (sb_rows * sb_cols); |
Dominic Symes | 917d6c0 | 2017-10-11 18:00:52 +0200 | [diff] [blame] | 95 | int max_tile_width_sb = 1; |
Dominic Symes | f58f111 | 2017-09-25 12:47:40 +0200 | [diff] [blame] | 96 | cm->log2_tile_cols = tile_log2(1, cm->tile_cols); |
Dominic Symes | db5d66f | 2017-08-18 18:11:34 +0200 | [diff] [blame] | 97 | for (i = 0; i < cm->tile_cols; i++) { |
| 98 | int size_sb = cm->tile_col_start_sb[i + 1] - cm->tile_col_start_sb[i]; |
| 99 | max_tile_width_sb = AOMMAX(max_tile_width_sb, size_sb); |
| 100 | } |
| 101 | if (cm->min_log2_tiles) { |
| 102 | max_tile_area_sb >>= (cm->min_log2_tiles + 1); |
| 103 | } |
| 104 | cm->max_tile_height_sb = AOMMAX(max_tile_area_sb / max_tile_width_sb, 1); |
| 105 | } |
| 106 | } |
| 107 | |
| 108 | void av1_calculate_tile_rows(AV1_COMMON *const cm) { |
Imdad Sardharwalla | 4ec84ab | 2018-02-06 12:20:18 +0000 | [diff] [blame] | 109 | int mi_rows = ALIGN_POWER_OF_TWO(cm->mi_rows, cm->seq_params.mib_size_log2); |
| 110 | int sb_rows = mi_rows >> cm->seq_params.mib_size_log2; |
Dominic Symes | db5d66f | 2017-08-18 18:11:34 +0200 | [diff] [blame] | 111 | int start_sb, size_sb, i; |
| 112 | |
| 113 | if (cm->uniform_tile_spacing_flag) { |
| 114 | size_sb = ALIGN_POWER_OF_TWO(sb_rows, cm->log2_tile_rows); |
| 115 | size_sb >>= cm->log2_tile_rows; |
| 116 | assert(size_sb > 0); |
| 117 | for (i = 0, start_sb = 0; start_sb < sb_rows; i++) { |
| 118 | cm->tile_row_start_sb[i] = start_sb; |
| 119 | start_sb += size_sb; |
| 120 | } |
| 121 | cm->tile_rows = i; |
Dominic Symes | f58f111 | 2017-09-25 12:47:40 +0200 | [diff] [blame] | 122 | cm->tile_row_start_sb[i] = sb_rows; |
Dominic Symes | db5d66f | 2017-08-18 18:11:34 +0200 | [diff] [blame] | 123 | } else { |
Dominic Symes | f58f111 | 2017-09-25 12:47:40 +0200 | [diff] [blame] | 124 | cm->log2_tile_rows = tile_log2(1, cm->tile_rows); |
Dominic Symes | db5d66f | 2017-08-18 18:11:34 +0200 | [diff] [blame] | 125 | } |
Dominic Symes | f58f111 | 2017-09-25 12:47:40 +0200 | [diff] [blame] | 126 | |
| 127 | #if CONFIG_DEPENDENT_HORZTILES |
| 128 | // Record which tile rows must be indpendent for parallelism |
| 129 | for (i = 0, start_sb = 0; i < cm->tile_rows; i++) { |
| 130 | cm->tile_row_independent[i] = 0; |
| 131 | if (cm->tile_row_start_sb[i + 1] - start_sb > cm->max_tile_height_sb) { |
| 132 | cm->tile_row_independent[i] = 1; |
| 133 | start_sb = cm->tile_row_start_sb[i]; |
| 134 | } |
| 135 | } |
| 136 | #endif |
Dominic Symes | db5d66f | 2017-08-18 18:11:34 +0200 | [diff] [blame] | 137 | } |
| 138 | |
| 139 | void av1_tile_set_row(TileInfo *tile, const AV1_COMMON *cm, int row) { |
| 140 | assert(row < cm->tile_rows); |
Imdad Sardharwalla | 4ec84ab | 2018-02-06 12:20:18 +0000 | [diff] [blame] | 141 | int mi_row_start = cm->tile_row_start_sb[row] << cm->seq_params.mib_size_log2; |
| 142 | int mi_row_end = cm->tile_row_start_sb[row + 1] |
| 143 | << cm->seq_params.mib_size_log2; |
Dominic Symes | db5d66f | 2017-08-18 18:11:34 +0200 | [diff] [blame] | 144 | tile->mi_row_start = mi_row_start; |
| 145 | tile->mi_row_end = AOMMIN(mi_row_end, cm->mi_rows); |
Dominic Symes | 917d6c0 | 2017-10-11 18:00:52 +0200 | [diff] [blame] | 146 | assert(tile->mi_row_end > tile->mi_row_start); |
Dominic Symes | db5d66f | 2017-08-18 18:11:34 +0200 | [diff] [blame] | 147 | } |
| 148 | |
| 149 | void av1_tile_set_col(TileInfo *tile, const AV1_COMMON *cm, int col) { |
| 150 | assert(col < cm->tile_cols); |
Imdad Sardharwalla | 4ec84ab | 2018-02-06 12:20:18 +0000 | [diff] [blame] | 151 | int mi_col_start = cm->tile_col_start_sb[col] << cm->seq_params.mib_size_log2; |
| 152 | int mi_col_end = cm->tile_col_start_sb[col + 1] |
| 153 | << cm->seq_params.mib_size_log2; |
Dominic Symes | db5d66f | 2017-08-18 18:11:34 +0200 | [diff] [blame] | 154 | tile->mi_col_start = mi_col_start; |
| 155 | tile->mi_col_end = AOMMIN(mi_col_end, cm->mi_cols); |
Dominic Symes | 917d6c0 | 2017-10-11 18:00:52 +0200 | [diff] [blame] | 156 | assert(tile->mi_col_end > tile->mi_col_start); |
Dominic Symes | db5d66f | 2017-08-18 18:11:34 +0200 | [diff] [blame] | 157 | } |
| 158 | |
| 159 | #else |
| 160 | |
| 161 | void av1_tile_set_row(TileInfo *tile, const AV1_COMMON *cm, int row) { |
| 162 | tile->mi_row_start = row * cm->tile_height; |
| 163 | tile->mi_row_end = AOMMIN(tile->mi_row_start + cm->tile_height, cm->mi_rows); |
| 164 | } |
| 165 | |
| 166 | void av1_tile_set_col(TileInfo *tile, const AV1_COMMON *cm, int col) { |
| 167 | tile->mi_col_start = col * cm->tile_width; |
| 168 | tile->mi_col_end = AOMMIN(tile->mi_col_start + cm->tile_width, cm->mi_cols); |
| 169 | } |
| 170 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 171 | #define MIN_TILE_WIDTH_MAX_SB 2 |
| 172 | #define MAX_TILE_WIDTH_MAX_SB 32 |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 173 | |
Yaowu Xu | 4ff59b5 | 2017-04-24 12:41:56 -0700 | [diff] [blame] | 174 | static int get_min_log2_tile_cols(int max_sb_cols) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 175 | int min_log2 = 0; |
| 176 | while ((MAX_TILE_WIDTH_MAX_SB << min_log2) < max_sb_cols) ++min_log2; |
| 177 | return min_log2; |
| 178 | } |
| 179 | |
Yaowu Xu | 4ff59b5 | 2017-04-24 12:41:56 -0700 | [diff] [blame] | 180 | static int get_max_log2_tile_cols(int max_sb_cols) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 181 | int max_log2 = 1; |
| 182 | while ((max_sb_cols >> max_log2) >= MIN_TILE_WIDTH_MAX_SB) ++max_log2; |
| 183 | return max_log2 - 1; |
| 184 | } |
| 185 | |
Yaowu Xu | 4ff59b5 | 2017-04-24 12:41:56 -0700 | [diff] [blame] | 186 | void av1_get_tile_n_bits(int mi_cols, int *min_log2_tile_cols, |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 187 | int *max_log2_tile_cols) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 188 | const int max_sb_cols = |
| 189 | ALIGN_POWER_OF_TWO(mi_cols, MAX_MIB_SIZE_LOG2) >> MAX_MIB_SIZE_LOG2; |
| 190 | *min_log2_tile_cols = get_min_log2_tile_cols(max_sb_cols); |
| 191 | *max_log2_tile_cols = get_max_log2_tile_cols(max_sb_cols); |
| 192 | assert(*min_log2_tile_cols <= *max_log2_tile_cols); |
| 193 | } |
Dominic Symes | db5d66f | 2017-08-18 18:11:34 +0200 | [diff] [blame] | 194 | #endif // CONFIG_MAX_TILE |
Ryan Lei | 7386eda | 2016-12-08 21:08:31 -0800 | [diff] [blame] | 195 | |
Yi Luo | f190a16 | 2017-07-13 16:16:56 -0700 | [diff] [blame] | 196 | void av1_setup_frame_boundary_info(const AV1_COMMON *const cm) { |
Frank Bossen | 768d660 | 2018-01-16 08:48:52 -0500 | [diff] [blame] | 197 | BOUNDARY_TYPE *bi = cm->boundary_info; |
Yi Luo | f190a16 | 2017-07-13 16:16:56 -0700 | [diff] [blame] | 198 | int col; |
| 199 | for (col = 0; col < cm->mi_cols; ++col) { |
Frank Bossen | 768d660 | 2018-01-16 08:48:52 -0500 | [diff] [blame] | 200 | *bi |= FRAME_ABOVE_BOUNDARY | TILE_ABOVE_BOUNDARY; |
| 201 | bi += 1; |
Yi Luo | f190a16 | 2017-07-13 16:16:56 -0700 | [diff] [blame] | 202 | } |
Ryan Lei | 3ab0df7 | 2017-05-19 22:04:01 -0700 | [diff] [blame] | 203 | |
Frank Bossen | 768d660 | 2018-01-16 08:48:52 -0500 | [diff] [blame] | 204 | bi = cm->boundary_info; |
Yi Luo | f190a16 | 2017-07-13 16:16:56 -0700 | [diff] [blame] | 205 | int row; |
| 206 | for (row = 0; row < cm->mi_rows; ++row) { |
Frank Bossen | 768d660 | 2018-01-16 08:48:52 -0500 | [diff] [blame] | 207 | *bi |= FRAME_LEFT_BOUNDARY | TILE_LEFT_BOUNDARY; |
| 208 | bi += cm->mi_stride; |
Yi Luo | f190a16 | 2017-07-13 16:16:56 -0700 | [diff] [blame] | 209 | } |
Ryan Lei | 3ab0df7 | 2017-05-19 22:04:01 -0700 | [diff] [blame] | 210 | |
Frank Bossen | 768d660 | 2018-01-16 08:48:52 -0500 | [diff] [blame] | 211 | bi = cm->boundary_info + (cm->mi_rows - 1) * cm->mi_stride; |
Yi Luo | f190a16 | 2017-07-13 16:16:56 -0700 | [diff] [blame] | 212 | for (col = 0; col < cm->mi_cols; ++col) { |
Frank Bossen | 768d660 | 2018-01-16 08:48:52 -0500 | [diff] [blame] | 213 | *bi |= FRAME_BOTTOM_BOUNDARY | TILE_BOTTOM_BOUNDARY; |
| 214 | bi += 1; |
Yi Luo | f190a16 | 2017-07-13 16:16:56 -0700 | [diff] [blame] | 215 | } |
U-AMR\zlei3 | af7846e | 2017-06-30 13:43:05 -0700 | [diff] [blame] | 216 | |
Frank Bossen | 768d660 | 2018-01-16 08:48:52 -0500 | [diff] [blame] | 217 | bi = cm->boundary_info + cm->mi_cols - 1; |
Yi Luo | f190a16 | 2017-07-13 16:16:56 -0700 | [diff] [blame] | 218 | for (row = 0; row < cm->mi_rows; ++row) { |
Frank Bossen | 768d660 | 2018-01-16 08:48:52 -0500 | [diff] [blame] | 219 | *bi |= FRAME_RIGHT_BOUNDARY | TILE_RIGHT_BOUNDARY; |
| 220 | bi += cm->mi_stride; |
Yi Luo | f190a16 | 2017-07-13 16:16:56 -0700 | [diff] [blame] | 221 | } |
| 222 | } |
| 223 | |
Rupert Swarbrick | 5a010aa | 2017-09-26 16:16:48 +0100 | [diff] [blame] | 224 | int get_tile_size(int mi_frame_size, int log2_tile_num, int *ntiles) { |
Rupert Swarbrick | 9a3640d | 2017-09-01 13:54:41 +0100 | [diff] [blame] | 225 | // Round the frame up to a whole number of max superblocks |
Rupert Swarbrick | 5a010aa | 2017-09-26 16:16:48 +0100 | [diff] [blame] | 226 | mi_frame_size = ALIGN_POWER_OF_TWO(mi_frame_size, MAX_MIB_SIZE_LOG2); |
| 227 | |
| 228 | // Divide by the signalled number of tiles, rounding up to the multiple of |
| 229 | // the max superblock size. To do this, shift right (and round up) to get the |
| 230 | // tile size in max super-blocks and then shift left again to convert it to |
| 231 | // mi units. |
Pavel Frolov | a1cdb53 | 2017-10-01 20:03:20 +0300 | [diff] [blame] | 232 | const int shift = log2_tile_num + MAX_MIB_SIZE_LOG2; |
Rupert Swarbrick | 5a010aa | 2017-09-26 16:16:48 +0100 | [diff] [blame] | 233 | const int max_sb_tile_size = |
Pavel Frolov | a1cdb53 | 2017-10-01 20:03:20 +0300 | [diff] [blame] | 234 | ALIGN_POWER_OF_TWO(mi_frame_size, shift) >> shift; |
Rupert Swarbrick | 5a010aa | 2017-09-26 16:16:48 +0100 | [diff] [blame] | 235 | const int mi_tile_size = max_sb_tile_size << MAX_MIB_SIZE_LOG2; |
| 236 | |
| 237 | // The actual number of tiles is the ceiling of the frame size in mi units |
| 238 | // divided by mi_size. This is at most 1 << log2_tile_num but might be |
| 239 | // strictly less if max_sb_tile_size got rounded up significantly. |
| 240 | if (ntiles) { |
| 241 | *ntiles = (mi_frame_size + mi_tile_size - 1) / mi_tile_size; |
| 242 | assert(*ntiles <= (1 << log2_tile_num)); |
| 243 | } |
| 244 | |
| 245 | return mi_tile_size; |
Rupert Swarbrick | 9a3640d | 2017-09-01 13:54:41 +0100 | [diff] [blame] | 246 | } |
| 247 | |
Rupert Swarbrick | 33ed9e6 | 2017-10-23 13:32:37 +0100 | [diff] [blame] | 248 | AV1PixelRect av1_get_tile_rect(const TileInfo *tile_info, const AV1_COMMON *cm, |
| 249 | int is_uv) { |
| 250 | AV1PixelRect r; |
Rupert Swarbrick | 33ed9e6 | 2017-10-23 13:32:37 +0100 | [diff] [blame] | 251 | |
David Barker | 21f4307 | 2017-12-14 14:21:45 +0000 | [diff] [blame] | 252 | // Calculate position in the Y plane |
| 253 | r.left = tile_info->mi_col_start * MI_SIZE; |
| 254 | r.right = tile_info->mi_col_end * MI_SIZE; |
| 255 | r.top = tile_info->mi_row_start * MI_SIZE; |
| 256 | r.bottom = tile_info->mi_row_end * MI_SIZE; |
Rupert Swarbrick | 33ed9e6 | 2017-10-23 13:32:37 +0100 | [diff] [blame] | 257 | |
Rupert Swarbrick | 33ed9e6 | 2017-10-23 13:32:37 +0100 | [diff] [blame] | 258 | // If upscaling is enabled, the tile limits need scaling to match the |
| 259 | // upscaled frame where the restoration tiles live. To do this, scale up the |
| 260 | // top-left and bottom-right of the tile. |
| 261 | if (!av1_superres_unscaled(cm)) { |
| 262 | av1_calculate_unscaled_superres_size(&r.left, &r.top, |
| 263 | cm->superres_scale_denominator); |
| 264 | av1_calculate_unscaled_superres_size(&r.right, &r.bottom, |
| 265 | cm->superres_scale_denominator); |
Rupert Swarbrick | 33ed9e6 | 2017-10-23 13:32:37 +0100 | [diff] [blame] | 266 | } |
Rupert Swarbrick | 509934a | 2017-11-10 11:19:10 +0000 | [diff] [blame] | 267 | |
| 268 | const int frame_w = cm->superres_upscaled_width; |
| 269 | const int frame_h = cm->superres_upscaled_height; |
Rupert Swarbrick | 33ed9e6 | 2017-10-23 13:32:37 +0100 | [diff] [blame] | 270 | |
Rupert Swarbrick | 509934a | 2017-11-10 11:19:10 +0000 | [diff] [blame] | 271 | // Make sure we don't fall off the bottom-right of the frame. |
David Barker | 21f4307 | 2017-12-14 14:21:45 +0000 | [diff] [blame] | 272 | r.right = AOMMIN(r.right, frame_w); |
| 273 | r.bottom = AOMMIN(r.bottom, frame_h); |
| 274 | |
| 275 | // Convert to coordinates in the appropriate plane |
| 276 | const int ss_x = is_uv && cm->subsampling_x; |
| 277 | const int ss_y = is_uv && cm->subsampling_y; |
| 278 | |
| 279 | r.left = ROUND_POWER_OF_TWO(r.left, ss_x); |
| 280 | r.right = ROUND_POWER_OF_TWO(r.right, ss_x); |
| 281 | r.top = ROUND_POWER_OF_TWO(r.top, ss_y); |
| 282 | r.bottom = ROUND_POWER_OF_TWO(r.bottom, ss_y); |
| 283 | |
Rupert Swarbrick | 33ed9e6 | 2017-10-23 13:32:37 +0100 | [diff] [blame] | 284 | return r; |
| 285 | } |
| 286 | |
Lei | 7bb501d | 2017-12-13 15:10:34 -0800 | [diff] [blame] | 287 | #if CONFIG_LOOPFILTERING_ACROSS_TILES || CONFIG_LOOPFILTERING_ACROSS_TILES_EXT |
| 288 | // this function should only be called when loop_filter_across_tile flag is |
| 289 | // set to 0 |
Yi Luo | f190a16 | 2017-07-13 16:16:56 -0700 | [diff] [blame] | 290 | void av1_setup_across_tile_boundary_info(const AV1_COMMON *const cm, |
| 291 | const TileInfo *const tile_info) { |
David Barker | 5c06a64 | 2017-08-18 13:18:16 +0100 | [diff] [blame] | 292 | if (cm->tile_cols * cm->tile_rows > 1) { |
Yi Luo | f190a16 | 2017-07-13 16:16:56 -0700 | [diff] [blame] | 293 | const int mi_row = tile_info->mi_row_start; |
| 294 | const int mi_col = tile_info->mi_col_start; |
Frank Bossen | 768d660 | 2018-01-16 08:48:52 -0500 | [diff] [blame] | 295 | BOUNDARY_TYPE *const bi_start = |
| 296 | cm->boundary_info + mi_row * cm->mi_stride + mi_col; |
| 297 | // assert(mi_start < cm->mip + cm->mi_alloc_size); |
| 298 | BOUNDARY_TYPE *bi = 0; |
Yi Luo | f190a16 | 2017-07-13 16:16:56 -0700 | [diff] [blame] | 299 | const int row_diff = tile_info->mi_row_end - tile_info->mi_row_start; |
| 300 | const int col_diff = tile_info->mi_col_end - tile_info->mi_col_start; |
| 301 | int row, col; |
U-AMR\zlei3 | af7846e | 2017-06-30 13:43:05 -0700 | [diff] [blame] | 302 | |
Lei | 7bb501d | 2017-12-13 15:10:34 -0800 | [diff] [blame] | 303 | // when CONFIG_LOOPFILTERING_ACROSS_TILES_EXT is enabled, whether tile |
| 304 | // is dependent horizontal tile or not is ignored. tile boundary is always |
| 305 | // initialized based on the actual tile boundary. |
| 306 | #if CONFIG_DEPENDENT_HORZTILES && !CONFIG_LOOPFILTERING_ACROSS_TILES_EXT |
Yi Luo | f190a16 | 2017-07-13 16:16:56 -0700 | [diff] [blame] | 307 | if (!cm->dependent_horz_tiles || tile_info->tg_horz_boundary) |
Lei | 7bb501d | 2017-12-13 15:10:34 -0800 | [diff] [blame] | 308 | #elif CONFIG_LOOPFILTERING_ACROSS_TILES_EXT |
| 309 | if (cm->loop_filter_across_tiles_h_enabled == 0) |
| 310 | #endif // CONFIG_LOOPFILTERING_ACROSS_TILES_EXT |
Yi Luo | f190a16 | 2017-07-13 16:16:56 -0700 | [diff] [blame] | 311 | { |
Frank Bossen | 768d660 | 2018-01-16 08:48:52 -0500 | [diff] [blame] | 312 | bi = bi_start; |
Yi Luo | f190a16 | 2017-07-13 16:16:56 -0700 | [diff] [blame] | 313 | for (col = 0; col < col_diff; ++col) { |
Frank Bossen | 768d660 | 2018-01-16 08:48:52 -0500 | [diff] [blame] | 314 | *bi |= TILE_ABOVE_BOUNDARY; |
| 315 | bi += 1; |
Ryan Lei | 9b02b0e | 2017-01-30 15:52:20 -0800 | [diff] [blame] | 316 | } |
Ryan Lei | 7386eda | 2016-12-08 21:08:31 -0800 | [diff] [blame] | 317 | } |
Yi Luo | f190a16 | 2017-07-13 16:16:56 -0700 | [diff] [blame] | 318 | |
Lei | 7bb501d | 2017-12-13 15:10:34 -0800 | [diff] [blame] | 319 | #if CONFIG_LOOPFILTERING_ACROSS_TILES_EXT |
| 320 | if (cm->loop_filter_across_tiles_v_enabled == 0) |
| 321 | #endif // CONFIG_LOOPFILTERING_ACROSS_TILES_EXT |
| 322 | { |
Frank Bossen | 768d660 | 2018-01-16 08:48:52 -0500 | [diff] [blame] | 323 | bi = bi_start; |
Lei | 7bb501d | 2017-12-13 15:10:34 -0800 | [diff] [blame] | 324 | for (row = 0; row < row_diff; ++row) { |
Frank Bossen | 768d660 | 2018-01-16 08:48:52 -0500 | [diff] [blame] | 325 | *bi |= TILE_LEFT_BOUNDARY; |
| 326 | bi += cm->mi_stride; |
Lei | 7bb501d | 2017-12-13 15:10:34 -0800 | [diff] [blame] | 327 | } |
Yi Luo | f190a16 | 2017-07-13 16:16:56 -0700 | [diff] [blame] | 328 | } |
| 329 | |
Lei | 7bb501d | 2017-12-13 15:10:34 -0800 | [diff] [blame] | 330 | #if CONFIG_LOOPFILTERING_ACROSS_TILES_EXT |
| 331 | if (cm->loop_filter_across_tiles_h_enabled == 0) |
| 332 | #endif // CONFIG_LOOPFILTERING_ACROSS_TILES_EXT |
| 333 | { |
Frank Bossen | 768d660 | 2018-01-16 08:48:52 -0500 | [diff] [blame] | 334 | bi = bi_start + (row_diff - 1) * cm->mi_stride; |
Lei | 7bb501d | 2017-12-13 15:10:34 -0800 | [diff] [blame] | 335 | // explicit bounds checking |
Frank Bossen | 768d660 | 2018-01-16 08:48:52 -0500 | [diff] [blame] | 336 | // assert(mi + col_diff <= cm->mip + cm->mi_alloc_size); |
Lei | 7bb501d | 2017-12-13 15:10:34 -0800 | [diff] [blame] | 337 | for (col = 0; col < col_diff; ++col) { |
Frank Bossen | 768d660 | 2018-01-16 08:48:52 -0500 | [diff] [blame] | 338 | *bi |= TILE_BOTTOM_BOUNDARY; |
| 339 | bi += 1; |
Lei | 7bb501d | 2017-12-13 15:10:34 -0800 | [diff] [blame] | 340 | } |
Yi Luo | f190a16 | 2017-07-13 16:16:56 -0700 | [diff] [blame] | 341 | } |
| 342 | |
Lei | 7bb501d | 2017-12-13 15:10:34 -0800 | [diff] [blame] | 343 | #if CONFIG_LOOPFILTERING_ACROSS_TILES_EXT |
| 344 | if (cm->loop_filter_across_tiles_v_enabled == 0) |
| 345 | #endif // CONFIG_LOOPFILTERING_ACROSS_TILES_EXT |
| 346 | { |
Frank Bossen | 768d660 | 2018-01-16 08:48:52 -0500 | [diff] [blame] | 347 | bi = bi_start + col_diff - 1; |
Lei | 7bb501d | 2017-12-13 15:10:34 -0800 | [diff] [blame] | 348 | for (row = 0; row < row_diff; ++row) { |
Frank Bossen | 768d660 | 2018-01-16 08:48:52 -0500 | [diff] [blame] | 349 | *bi |= TILE_RIGHT_BOUNDARY; |
| 350 | bi += cm->mi_stride; |
Lei | 7bb501d | 2017-12-13 15:10:34 -0800 | [diff] [blame] | 351 | } |
Yi Luo | f190a16 | 2017-07-13 16:16:56 -0700 | [diff] [blame] | 352 | } |
Lei | 7bb501d | 2017-12-13 15:10:34 -0800 | [diff] [blame] | 353 | } // end of cm->tile_cols * cm->tile_rows > 1 |
Ryan Lei | 7386eda | 2016-12-08 21:08:31 -0800 | [diff] [blame] | 354 | } |
| 355 | |
| 356 | int av1_disable_loopfilter_on_tile_boundary(const struct AV1Common *cm) { |
Lei | 7bb501d | 2017-12-13 15:10:34 -0800 | [diff] [blame] | 357 | #if CONFIG_LOOPFILTERING_ACROSS_TILES_EXT |
| 358 | return ((!cm->loop_filter_across_tiles_v_enabled || |
| 359 | !cm->loop_filter_across_tiles_h_enabled) && |
| 360 | #else |
Ryan Lei | 7386eda | 2016-12-08 21:08:31 -0800 | [diff] [blame] | 361 | return (!cm->loop_filter_across_tiles_enabled && |
Lei | 7bb501d | 2017-12-13 15:10:34 -0800 | [diff] [blame] | 362 | #endif // CONFIG_LOOPFILTERING_ACROSS_TILES_EXT |
Ryan Lei | 7386eda | 2016-12-08 21:08:31 -0800 | [diff] [blame] | 363 | (cm->tile_cols * cm->tile_rows > 1)); |
| 364 | } |
Ryan Lei | 9b02b0e | 2017-01-30 15:52:20 -0800 | [diff] [blame] | 365 | #endif // CONFIG_LOOPFILTERING_ACROSS_TILES |