1 | // Copyright (c) 2017-2020, The rav1e contributors. All rights reserved |
2 | // |
3 | // This source code is subject to the terms of the BSD 2 Clause License and |
4 | // the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License |
5 | // was not distributed with this source code in the LICENSE file, you can |
6 | // obtain it at www.aomedia.org/license/software. If the Alliance for Open |
7 | // Media Patent License 1.0 was not distributed with this source code in the |
8 | // PATENTS file, you can obtain it at www.aomedia.org/license/patent. |
9 | |
10 | #![allow (non_upper_case_globals)] |
11 | #![allow (non_camel_case_types)] |
12 | #![allow (dead_code)] |
13 | |
14 | use crate::context::*; |
15 | use crate::partition::BlockSize::*; |
16 | use crate::partition::*; |
17 | use crate::transform::*; |
18 | |
19 | static has_null: &[u8] = &[]; |
20 | |
21 | // Tables to store if the top-right reference pixels are available. The flags |
22 | // are represented with bits, packed into 8-bit integers. E.g., for the 32x32 |
23 | // blocks in a 128x128 superblock, the index of the "o" block is 10 (in raster |
24 | // order), so its flag is stored at the 3rd bit of the 2nd entry in the table, |
25 | // i.e. (table[10 / 8] >> (10 % 8)) & 1. |
26 | // . . . . |
27 | // . . . . |
28 | // . . o . |
29 | // . . . . |
30 | #[rustfmt::skip] |
31 | static has_tr_4x4: &[u8] = &[ |
32 | 255, 255, 255, 255, 85, 85, 85, 85, 119, 119, 119, 119, 85, 85, 85, 85, |
33 | 127, 127, 127, 127, 85, 85, 85, 85, 119, 119, 119, 119, 85, 85, 85, 85, |
34 | 255, 127, 255, 127, 85, 85, 85, 85, 119, 119, 119, 119, 85, 85, 85, 85, |
35 | 127, 127, 127, 127, 85, 85, 85, 85, 119, 119, 119, 119, 85, 85, 85, 85, |
36 | 255, 255, 255, 127, 85, 85, 85, 85, 119, 119, 119, 119, 85, 85, 85, 85, |
37 | 127, 127, 127, 127, 85, 85, 85, 85, 119, 119, 119, 119, 85, 85, 85, 85, |
38 | 255, 127, 255, 127, 85, 85, 85, 85, 119, 119, 119, 119, 85, 85, 85, 85, |
39 | 127, 127, 127, 127, 85, 85, 85, 85, 119, 119, 119, 119, 85, 85, 85, 85, |
40 | ]; |
41 | |
42 | static has_tr_4x8: &[u8] = &[ |
43 | 255, 255, 255, 255, 119, 119, 119, 119, 127, 127, 127, 127, 119, 119, 119, |
44 | 119, 255, 127, 255, 127, 119, 119, 119, 119, 127, 127, 127, 127, 119, 119, |
45 | 119, 119, 255, 255, 255, 127, 119, 119, 119, 119, 127, 127, 127, 127, 119, |
46 | 119, 119, 119, 255, 127, 255, 127, 119, 119, 119, 119, 127, 127, 127, 127, |
47 | 119, 119, 119, 119, |
48 | ]; |
49 | |
50 | #[rustfmt::skip] |
51 | static has_tr_8x4: &[u8] = &[ |
52 | 255, 255, 0, 0, 85, 85, 0, 0, 119, 119, 0, 0, 85, 85, 0, 0, |
53 | 127, 127, 0, 0, 85, 85, 0, 0, 119, 119, 0, 0, 85, 85, 0, 0, |
54 | 255, 127, 0, 0, 85, 85, 0, 0, 119, 119, 0, 0, 85, 85, 0, 0, |
55 | 127, 127, 0, 0, 85, 85, 0, 0, 119, 119, 0, 0, 85, 85, 0, 0, |
56 | ]; |
57 | |
58 | #[rustfmt::skip] |
59 | static has_tr_8x8: &[u8] = &[ |
60 | 255, 255, 85, 85, 119, 119, 85, 85, 127, 127, 85, 85, 119, 119, 85, 85, |
61 | 255, 127, 85, 85, 119, 119, 85, 85, 127, 127, 85, 85, 119, 119, 85, 85, |
62 | ]; |
63 | static has_tr_8x16: &[u8] = &[ |
64 | 255, 255, 119, 119, 127, 127, 119, 119, 255, 127, 119, 119, 127, 127, 119, |
65 | 119, |
66 | ]; |
67 | static has_tr_16x8: &[u8] = |
68 | &[255, 0, 85, 0, 119, 0, 85, 0, 127, 0, 85, 0, 119, 0, 85, 0]; |
69 | static has_tr_16x16: &[u8] = &[255, 85, 119, 85, 127, 85, 119, 85]; |
70 | static has_tr_16x32: &[u8] = &[255, 119, 127, 119]; |
71 | static has_tr_32x16: &[u8] = &[15, 5, 7, 5]; |
72 | static has_tr_32x32: &[u8] = &[95, 87]; |
73 | static has_tr_32x64: &[u8] = &[127]; |
74 | static has_tr_64x32: &[u8] = &[19]; |
75 | static has_tr_64x64: &[u8] = &[7]; |
76 | static has_tr_64x128: &[u8] = &[3]; |
77 | static has_tr_128x64: &[u8] = &[1]; |
78 | static has_tr_128x128: &[u8] = &[1]; |
79 | static has_tr_4x16: &[u8] = &[ |
80 | 255, 255, 255, 255, 127, 127, 127, 127, 255, 127, 255, 127, 127, 127, 127, |
81 | 127, 255, 255, 255, 127, 127, 127, 127, 127, 255, 127, 255, 127, 127, 127, |
82 | 127, 127, |
83 | ]; |
84 | static has_tr_16x4: &[u8] = &[ |
85 | 255, 0, 0, 0, 85, 0, 0, 0, 119, 0, 0, 0, 85, 0, 0, 0, 127, 0, 0, 0, 85, 0, |
86 | 0, 0, 119, 0, 0, 0, 85, 0, 0, 0, |
87 | ]; |
88 | static has_tr_8x32: &[u8] = &[255, 255, 127, 127, 255, 127, 127, 127]; |
89 | static has_tr_32x8: &[u8] = &[15, 0, 5, 0, 7, 0, 5, 0]; |
90 | static has_tr_16x64: &[u8] = &[255, 127]; |
91 | static has_tr_64x16: &[u8] = &[3, 1]; |
92 | |
93 | static has_tr_tables: &[&[u8]] = &[ |
94 | has_tr_4x4, // 4x4 |
95 | has_tr_4x8, // 4x8 |
96 | has_tr_8x4, // 8x4 |
97 | has_tr_8x8, // 8x8 |
98 | has_tr_8x16, // 8x16 |
99 | has_tr_16x8, // 16x8 |
100 | has_tr_16x16, // 16x16 |
101 | has_tr_16x32, // 16x32 |
102 | has_tr_32x16, // 32x16 |
103 | has_tr_32x32, // 32x32 |
104 | has_tr_32x64, // 32x64 |
105 | has_tr_64x32, // 64x32 |
106 | has_tr_64x64, // 64x64 |
107 | has_tr_64x128, // 64x128 |
108 | has_tr_128x64, // 128x64 |
109 | has_tr_128x128, // 128x128 |
110 | has_tr_4x16, // 4x16 |
111 | has_tr_16x4, // 16x4 |
112 | has_tr_8x32, // 8x32 |
113 | has_tr_32x8, // 32x8 |
114 | has_tr_16x64, // 16x64 |
115 | has_tr_64x16, // 64x16 |
116 | ]; |
117 | |
118 | #[rustfmt::skip] |
119 | static has_tr_vert_8x8: &[u8] = &[ |
120 | 255, 255, 0, 0, 119, 119, 0, 0, 127, 127, 0, 0, 119, 119, 0, 0, |
121 | 255, 127, 0, 0, 119, 119, 0, 0, 127, 127, 0, 0, 119, 119, 0, 0, |
122 | ]; |
123 | static has_tr_vert_16x16: &[u8] = &[255, 0, 119, 0, 127, 0, 119, 0]; |
124 | static has_tr_vert_32x32: &[u8] = &[15, 7]; |
125 | static has_tr_vert_64x64: &[u8] = &[3]; |
126 | |
127 | // The _vert_* tables are like the ordinary tables above, but describe the |
128 | // order we visit square blocks when doing a PARTITION_VERT_A or |
129 | // PARTITION_VERT_B. This is the same order as normal except for on the last |
130 | // split where we go vertically (TL, BL, TR, BR). We treat the rectangular block |
131 | // as a pair of squares, which means that these tables work correctly for both |
132 | // mixed vertical partition types. |
133 | // |
134 | // There are tables for each of the square sizes. Vertical rectangles (like |
135 | // BLOCK_16X32) use their respective "non-vert" table |
136 | static has_tr_vert_tables: &[&[u8]] = &[ |
137 | has_null, // 4X4 |
138 | has_tr_4x8, // 4X8 |
139 | has_null, // 8X4 |
140 | has_tr_vert_8x8, // 8X8 |
141 | has_tr_8x16, // 8X16 |
142 | has_null, // 16X8 |
143 | has_tr_vert_16x16, // 16X16 |
144 | has_tr_16x32, // 16X32 |
145 | has_null, // 32X16 |
146 | has_tr_vert_32x32, // 32X32 |
147 | has_tr_32x64, // 32X64 |
148 | has_null, // 64X32 |
149 | has_tr_vert_64x64, // 64X64 |
150 | has_tr_64x128, // 64x128 |
151 | has_null, // 128x64 |
152 | has_tr_128x128, // 128x128 |
153 | ]; |
154 | |
155 | // TODO: Enable the case for PARTITION_VERT_A/B once they can be encoded by rav1e. |
156 | pub fn get_has_tr_table( |
157 | /*partition: PartitionType, */ bsize: BlockSize, |
158 | ) -> &'static [u8] { |
159 | let ret: &[u8]; |
160 | // If this is a mixed vertical partition, look up bsize in orders_vert. |
161 | /*if partition == PartitionType::PARTITION_VERT_A || partition == PartitionType::PARTITION_VERT_B { |
162 | debug_assert!(bsize < BlockSize::BLOCK_SIZES); |
163 | ret = has_tr_vert_tables[bsize as usize]; |
164 | } else */ |
165 | { |
166 | ret = has_tr_tables[bsize as usize]; |
167 | } |
168 | |
169 | //debug_assert!(ret != ptr::has_null()); |
170 | |
171 | ret |
172 | } |
173 | |
174 | pub fn has_top_right( |
175 | bsize: BlockSize, partition_bo: TileBlockOffset, top_available: bool, |
176 | right_available: bool, tx_size: TxSize, row_off: usize, col_off: usize, |
177 | ss_x: usize, _ss_y: usize, |
178 | ) -> bool { |
179 | if !top_available || !right_available { |
180 | return false; |
181 | }; |
182 | |
183 | let bw_unit = bsize.width_mi(); |
184 | let plane_bw_unit = (bw_unit >> ss_x).max(1); |
185 | let top_right_count_unit = tx_size.width_mi(); |
186 | |
187 | let mi_col = partition_bo.0.x; |
188 | let mi_row = partition_bo.0.y; |
189 | |
190 | if row_off > 0 { |
191 | // Just need to check if enough pixels on the right. |
192 | // 128x128 SB is not supported yet by rav1e |
193 | if bsize.width() > BLOCK_64X64.width() { |
194 | // Special case: For 128x128 blocks, the transform unit whose |
195 | // top-right corner is at the center of the block does in fact have |
196 | // pixels available at its top-right corner. |
197 | if row_off == BLOCK_64X64.height_mi() >> _ss_y |
198 | && col_off + top_right_count_unit == BLOCK_64X64.width_mi() >> ss_x |
199 | { |
200 | return false; |
201 | } |
202 | let plane_bw_unit_64 = BLOCK_64X64.width_mi() >> ss_x; |
203 | let col_off_64 = col_off % plane_bw_unit_64; |
204 | return col_off_64 + top_right_count_unit < plane_bw_unit_64; |
205 | } |
206 | col_off + top_right_count_unit < plane_bw_unit |
207 | } else { |
208 | // All top-right pixels are in the block above, which is already available. |
209 | if col_off + top_right_count_unit < plane_bw_unit { |
210 | return true; |
211 | }; |
212 | |
213 | let bw_in_mi_log2 = bsize.width_log2() - MI_SIZE_LOG2; |
214 | let bh_in_mi_log2 = bsize.height_log2() - MI_SIZE_LOG2; |
215 | let sb_mi_size: usize = 16; // 64x64 |
216 | let blk_row_in_sb = (mi_row & (sb_mi_size - 1)) >> bh_in_mi_log2; |
217 | let blk_col_in_sb = (mi_col & (sb_mi_size - 1)) >> bw_in_mi_log2; |
218 | |
219 | // Top row of superblock: so top-right pixels are in the top and/or |
220 | // top-right superblocks, both of which are already available. |
221 | if blk_row_in_sb == 0 { |
222 | return true; |
223 | }; |
224 | |
225 | // Rightmost column of superblock (and not the top row): so top-right pixels |
226 | // fall in the right superblock, which is not available yet. |
227 | if ((blk_col_in_sb + 1) << bw_in_mi_log2) >= sb_mi_size { |
228 | return false; |
229 | }; |
230 | |
231 | // General case (neither top row nor rightmost column): check if the |
232 | // top-right block is coded before the current block. |
233 | let this_blk_index = |
234 | (blk_row_in_sb << (MAX_MIB_SIZE_LOG2 - bw_in_mi_log2)) + blk_col_in_sb; |
235 | let idx1 = this_blk_index / 8; |
236 | let idx2 = this_blk_index % 8; |
237 | let has_tr_table: &[u8] = get_has_tr_table(/*partition,*/ bsize); |
238 | |
239 | ((has_tr_table[idx1] >> idx2) & 1) != 0 |
240 | } |
241 | } |
242 | |
243 | // Similar to the has_tr_* tables, but store if the bottom-left reference |
244 | // pixels are available. |
245 | static has_bl_4x4: &[u8] = &[ |
246 | 84, 85, 85, 85, 16, 17, 17, 17, 84, 85, 85, 85, 0, 1, 1, 1, 84, 85, 85, 85, |
247 | 16, 17, 17, 17, 84, 85, 85, 85, 0, 0, 1, 0, 84, 85, 85, 85, 16, 17, 17, 17, |
248 | 84, 85, 85, 85, 0, 1, 1, 1, 84, 85, 85, 85, 16, 17, 17, 17, 84, 85, 85, 85, |
249 | 0, 0, 0, 0, 84, 85, 85, 85, 16, 17, 17, 17, 84, 85, 85, 85, 0, 1, 1, 1, 84, |
250 | 85, 85, 85, 16, 17, 17, 17, 84, 85, 85, 85, 0, 0, 1, 0, 84, 85, 85, 85, 16, |
251 | 17, 17, 17, 84, 85, 85, 85, 0, 1, 1, 1, 84, 85, 85, 85, 16, 17, 17, 17, 84, |
252 | 85, 85, 85, 0, 0, 0, 0, |
253 | ]; |
254 | static has_bl_4x8: &[u8] = &[ |
255 | 16, 17, 17, 17, 0, 1, 1, 1, 16, 17, 17, 17, 0, 0, 1, 0, 16, 17, 17, 17, 0, |
256 | 1, 1, 1, 16, 17, 17, 17, 0, 0, 0, 0, 16, 17, 17, 17, 0, 1, 1, 1, 16, 17, 17, |
257 | 17, 0, 0, 1, 0, 16, 17, 17, 17, 0, 1, 1, 1, 16, 17, 17, 17, 0, 0, 0, 0, |
258 | ]; |
259 | static has_bl_8x4: &[u8] = &[ |
260 | 254, 255, 84, 85, 254, 255, 16, 17, 254, 255, 84, 85, 254, 255, 0, 1, 254, |
261 | 255, 84, 85, 254, 255, 16, 17, 254, 255, 84, 85, 254, 255, 0, 0, 254, 255, |
262 | 84, 85, 254, 255, 16, 17, 254, 255, 84, 85, 254, 255, 0, 1, 254, 255, 84, |
263 | 85, 254, 255, 16, 17, 254, 255, 84, 85, 254, 255, 0, 0, |
264 | ]; |
265 | static has_bl_8x8: &[u8] = &[ |
266 | 84, 85, 16, 17, 84, 85, 0, 1, 84, 85, 16, 17, 84, 85, 0, 0, 84, 85, 16, 17, |
267 | 84, 85, 0, 1, 84, 85, 16, 17, 84, 85, 0, 0, |
268 | ]; |
269 | static has_bl_8x16: &[u8] = |
270 | &[16, 17, 0, 1, 16, 17, 0, 0, 16, 17, 0, 1, 16, 17, 0, 0]; |
271 | static has_bl_16x8: &[u8] = |
272 | &[254, 84, 254, 16, 254, 84, 254, 0, 254, 84, 254, 16, 254, 84, 254, 0]; |
273 | static has_bl_16x16: &[u8] = &[84, 16, 84, 0, 84, 16, 84, 0]; |
274 | static has_bl_16x32: &[u8] = &[16, 0, 16, 0]; |
275 | static has_bl_32x16: &[u8] = &[78, 14, 78, 14]; |
276 | static has_bl_32x32: &[u8] = &[4, 4]; |
277 | static has_bl_32x64: &[u8] = &[0]; |
278 | static has_bl_64x32: &[u8] = &[34]; |
279 | static has_bl_64x64: &[u8] = &[0]; |
280 | static has_bl_64x128: &[u8] = &[0]; |
281 | static has_bl_128x64: &[u8] = &[0]; |
282 | static has_bl_128x128: &[u8] = &[0]; |
283 | static has_bl_4x16: &[u8] = &[ |
284 | 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, |
285 | 1, 1, 1, 0, 0, 0, 0, |
286 | ]; |
287 | static has_bl_16x4: &[u8] = &[ |
288 | 254, 254, 254, 84, 254, 254, 254, 16, 254, 254, 254, 84, 254, 254, 254, 0, |
289 | 254, 254, 254, 84, 254, 254, 254, 16, 254, 254, 254, 84, 254, 254, 254, 0, |
290 | ]; |
291 | static has_bl_8x32: &[u8] = &[0, 1, 0, 0, 0, 1, 0, 0]; |
292 | static has_bl_32x8: &[u8] = &[238, 78, 238, 14, 238, 78, 238, 14]; |
293 | static has_bl_16x64: &[u8] = &[0, 0]; |
294 | static has_bl_64x16: &[u8] = &[42, 42]; |
295 | |
296 | static has_bl_tables: &[&[u8]] = &[ |
297 | has_bl_4x4, // 4x4 |
298 | has_bl_4x8, // 4x8 |
299 | has_bl_8x4, // 8x4 |
300 | has_bl_8x8, // 8x8 |
301 | has_bl_8x16, // 8x16 |
302 | has_bl_16x8, // 16x8 |
303 | has_bl_16x16, // 16x16 |
304 | has_bl_16x32, // 16x32 |
305 | has_bl_32x16, // 32x16 |
306 | has_bl_32x32, // 32x32 |
307 | has_bl_32x64, // 32x64 |
308 | has_bl_64x32, // 64x32 |
309 | has_bl_64x64, // 64x64 |
310 | has_bl_64x128, // 64x128 |
311 | has_bl_128x64, // 128x64 |
312 | has_bl_128x128, // 128x128 |
313 | has_bl_4x16, // 4x16 |
314 | has_bl_16x4, // 16x4 |
315 | has_bl_8x32, // 8x32 |
316 | has_bl_32x8, // 32x8 |
317 | has_bl_16x64, // 16x64 |
318 | has_bl_64x16, // 64x16 |
319 | ]; |
320 | |
321 | #[rustfmt::skip] |
322 | static has_bl_vert_8x8: &[u8] = &[ |
323 | 254, 255, 16, 17, 254, 255, 0, 1, 254, 255, 16, 17, 254, 255, 0, 0, |
324 | 254, 255, 16, 17, 254, 255, 0, 1, 254, 255, 16, 17, 254, 255, 0, 0, |
325 | ]; |
326 | static has_bl_vert_16x16: &[u8] = &[254, 16, 254, 0, 254, 16, 254, 0]; |
327 | static has_bl_vert_32x32: &[u8] = &[14, 14]; |
328 | static has_bl_vert_64x64: &[u8] = &[2]; |
329 | |
330 | // The _vert_* tables are like the ordinary tables above, but describe the |
331 | // order we visit square blocks when doing a PARTITION_VERT_A or |
332 | // PARTITION_VERT_B. This is the same order as normal except for on the last |
333 | // split where we go vertically (TL, BL, TR, BR). We treat the rectangular block |
334 | // as a pair of squares, which means that these tables work correctly for both |
335 | // mixed vertical partition types. |
336 | // |
337 | // There are tables for each of the square sizes. Vertical rectangles (like |
338 | // BLOCK_16X32) use their respective "non-vert" table |
339 | static has_bl_vert_tables: &[&[u8]] = &[ |
340 | has_null, // 4x4 |
341 | has_bl_4x8, // 4x8 |
342 | has_null, // 8x4 |
343 | has_bl_vert_8x8, // 8x8 |
344 | has_bl_8x16, // 8x16 |
345 | has_null, // 16x8 |
346 | has_bl_vert_16x16, // 16x16 |
347 | has_bl_16x32, // 16x32 |
348 | has_null, // 32x16 |
349 | has_bl_vert_32x32, // 32x32 |
350 | has_bl_32x64, // 32x64 |
351 | has_null, // 64x32 |
352 | has_bl_vert_64x64, // 64x64 |
353 | has_bl_64x128, // 64x128 |
354 | has_null, // 128x64 |
355 | has_bl_128x128, // 128x128 |
356 | ]; |
357 | |
358 | pub fn get_has_bl_table( |
359 | /*partition: PartitionType, */ bsize: BlockSize, |
360 | ) -> &'static [u8] { |
361 | let ret: &[u8]; |
362 | // If this is a mixed vertical partition, look up bsize in orders_vert. |
363 | /*if (partition == PARTITION_VERT_A || partition == PARTITION_VERT_B) { |
364 | //assert(bsize < BLOCK_SIZES); |
365 | ret = has_bl_vert_tables[bsize as usize]; |
366 | } else*/ |
367 | { |
368 | ret = has_bl_tables[bsize as usize]; |
369 | } |
370 | //debug_assert!(ret != ptr::has_null()); |
371 | ret |
372 | } |
373 | |
374 | pub fn has_bottom_left( |
375 | bsize: BlockSize, partition_bo: TileBlockOffset, bottom_available: bool, |
376 | left_available: bool, tx_size: TxSize, row_off: usize, col_off: usize, |
377 | _ss_x: usize, ss_y: usize, |
378 | ) -> bool { |
379 | if !bottom_available || !left_available { |
380 | return false; |
381 | }; |
382 | |
383 | // Special case for 128x* blocks, when col_off is half the block width. |
384 | // This is needed because 128x* superblocks are divided into 64x* blocks in |
385 | // raster order |
386 | // 128x128 SB is not supported yet by rav1e |
387 | if bsize.width() > BLOCK_64X64.width() && col_off > 0 { |
388 | let plane_bw_unit_64 = BLOCK_64X64.width_mi() >> _ss_x; |
389 | let col_off_64 = col_off % plane_bw_unit_64; |
390 | if col_off_64 == 0 { |
391 | // We are at the left edge of top-right or bottom-right 64x* block. |
392 | let plane_bh_unit_64 = BLOCK_64X64.height_mi() >> ss_y; |
393 | let row_off_64 = row_off % plane_bh_unit_64; |
394 | let plane_bh_unit = (bsize.height_mi() >> ss_y).min(plane_bh_unit_64); |
395 | // Check if all bottom-left pixels are in the left 64x* block (which is |
396 | // already coded). |
397 | return row_off_64 + tx_size.height_mi() < plane_bh_unit; |
398 | } |
399 | } |
400 | |
401 | if col_off > 0 { |
402 | // Bottom-left pixels are in the bottom-left block, which is not available. |
403 | false |
404 | } else { |
405 | let bh_unit = bsize.height_mi(); |
406 | let plane_bh_unit = (bh_unit >> ss_y).max(1); |
407 | let bottom_left_count_unit = tx_size.height_mi(); |
408 | |
409 | let mi_col = partition_bo.0.x; |
410 | let mi_row = partition_bo.0.y; |
411 | |
412 | // All bottom-left pixels are in the left block, which is already available. |
413 | if row_off + bottom_left_count_unit < plane_bh_unit { |
414 | return true; |
415 | }; |
416 | |
417 | let bw_in_mi_log2 = bsize.width_log2() - MI_SIZE_LOG2; |
418 | let bh_in_mi_log2 = bsize.height_log2() - MI_SIZE_LOG2; |
419 | let sb_mi_size: usize = 16; // 64x64 |
420 | let blk_row_in_sb = (mi_row & (sb_mi_size - 1)) >> bh_in_mi_log2; |
421 | let blk_col_in_sb = (mi_col & (sb_mi_size - 1)) >> bw_in_mi_log2; |
422 | |
423 | // Leftmost column of superblock: so bottom-left pixels maybe in the left |
424 | // and/or bottom-left superblocks. But only the left superblock is |
425 | // available, so check if all required pixels fall in that superblock. |
426 | if blk_col_in_sb == 0 { |
427 | let blk_start_row_off = blk_row_in_sb << bh_in_mi_log2 >> ss_y; |
428 | let row_off_in_sb = blk_start_row_off + row_off; |
429 | let sb_height_unit = sb_mi_size >> ss_y; |
430 | return row_off_in_sb + bottom_left_count_unit < sb_height_unit; |
431 | //return row_off_in_sb + (bottom_left_count_unit << 1) < sb_height_unit; // Don't it need tx height? again? |
432 | } |
433 | |
434 | // Bottom row of superblock (and not the leftmost column): so bottom-left |
435 | // pixels fall in the bottom superblock, which is not available yet. |
436 | if ((blk_row_in_sb + 1) << bh_in_mi_log2) >= sb_mi_size { |
437 | return false; |
438 | }; |
439 | |
440 | // General case (neither leftmost column nor bottom row): check if the |
441 | // bottom-left block is coded before the current block. |
442 | let this_blk_index = |
443 | (blk_row_in_sb << (MAX_MIB_SIZE_LOG2 - bw_in_mi_log2)) + blk_col_in_sb; |
444 | let idx1 = this_blk_index / 8; |
445 | let idx2 = this_blk_index % 8; |
446 | let has_bl_table: &[u8] = get_has_bl_table(/*partition,*/ bsize); |
447 | |
448 | ((has_bl_table[idx1] >> idx2) & 1) != 0 |
449 | } |
450 | } |
451 | |