1 /*
2 * Copyright (c) 2017, Alliance for Open Media. All rights reserved
3 *
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.
10 */
11
12 #ifndef AOM_AV1_COMMON_TXB_COMMON_H_
13 #define AOM_AV1_COMMON_TXB_COMMON_H_
14
15 #include "av1/common/av1_common_int.h"
16
17 extern const int16_t av1_eob_group_start[12];
18 extern const int16_t av1_eob_offset_bits[12];
19
20 extern const int8_t av1_coeff_band_4x4[16];
21
22 extern const int8_t av1_coeff_band_8x8[64];
23
24 extern const int8_t av1_coeff_band_16x16[256];
25
26 extern const int8_t av1_coeff_band_32x32[1024];
27
28 extern const int8_t *av1_nz_map_ctx_offset[TX_SIZES_ALL];
29
30 typedef struct txb_ctx {
31 int txb_skip_ctx;
32 int dc_sign_ctx;
33 } TXB_CTX;
34
35 static const int base_level_count_to_index[13] = {
36 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
37 };
38
39 static const TX_CLASS tx_type_to_class[TX_TYPES] = {
40 TX_CLASS_2D, // DCT_DCT
41 TX_CLASS_2D, // ADST_DCT
42 TX_CLASS_2D, // DCT_ADST
43 TX_CLASS_2D, // ADST_ADST
44 TX_CLASS_2D, // FLIPADST_DCT
45 TX_CLASS_2D, // DCT_FLIPADST
46 TX_CLASS_2D, // FLIPADST_FLIPADST
47 TX_CLASS_2D, // ADST_FLIPADST
48 TX_CLASS_2D, // FLIPADST_ADST
49 TX_CLASS_2D, // IDTX
50 TX_CLASS_VERT, // V_DCT
51 TX_CLASS_HORIZ, // H_DCT
52 TX_CLASS_VERT, // V_ADST
53 TX_CLASS_HORIZ, // H_ADST
54 TX_CLASS_VERT, // V_FLIPADST
55 TX_CLASS_HORIZ, // H_FLIPADST
56 };
57
get_txb_bwl(TX_SIZE tx_size)58 static INLINE int get_txb_bwl(TX_SIZE tx_size) {
59 tx_size = av1_get_adjusted_tx_size(tx_size);
60 return tx_size_wide_log2[tx_size];
61 }
62
get_txb_wide(TX_SIZE tx_size)63 static INLINE int get_txb_wide(TX_SIZE tx_size) {
64 tx_size = av1_get_adjusted_tx_size(tx_size);
65 return tx_size_wide[tx_size];
66 }
67
get_txb_high(TX_SIZE tx_size)68 static INLINE int get_txb_high(TX_SIZE tx_size) {
69 tx_size = av1_get_adjusted_tx_size(tx_size);
70 return tx_size_high[tx_size];
71 }
72
set_levels(uint8_t * const levels_buf,const int width)73 static INLINE uint8_t *set_levels(uint8_t *const levels_buf, const int width) {
74 return levels_buf + TX_PAD_TOP * (width + TX_PAD_HOR);
75 }
76
get_padded_idx(const int idx,const int bwl)77 static INLINE int get_padded_idx(const int idx, const int bwl) {
78 return idx + ((idx >> bwl) << TX_PAD_HOR_LOG2);
79 }
80
get_br_ctx_2d(const uint8_t * const levels,const int c,const int bwl)81 static INLINE int get_br_ctx_2d(const uint8_t *const levels,
82 const int c, // raster order
83 const int bwl) {
84 assert(c > 0);
85 const int row = c >> bwl;
86 const int col = c - (row << bwl);
87 const int stride = (1 << bwl) + TX_PAD_HOR;
88 const int pos = row * stride + col;
89 int mag = AOMMIN(levels[pos + 1], MAX_BASE_BR_RANGE) +
90 AOMMIN(levels[pos + stride], MAX_BASE_BR_RANGE) +
91 AOMMIN(levels[pos + 1 + stride], MAX_BASE_BR_RANGE);
92 mag = AOMMIN((mag + 1) >> 1, 6);
93 //((row | col) < 2) is equivalent to ((row < 2) && (col < 2))
94 if ((row | col) < 2) return mag + 7;
95 return mag + 14;
96 }
97
get_br_ctx_eob(const int c,const int bwl,const TX_CLASS tx_class)98 static AOM_FORCE_INLINE int get_br_ctx_eob(const int c, // raster order
99 const int bwl,
100 const TX_CLASS tx_class) {
101 const int row = c >> bwl;
102 const int col = c - (row << bwl);
103 if (c == 0) return 0;
104 if ((tx_class == TX_CLASS_2D && row < 2 && col < 2) ||
105 (tx_class == TX_CLASS_HORIZ && col == 0) ||
106 (tx_class == TX_CLASS_VERT && row == 0))
107 return 7;
108 return 14;
109 }
110
get_br_ctx(const uint8_t * const levels,const int c,const int bwl,const TX_CLASS tx_class)111 static AOM_FORCE_INLINE int get_br_ctx(const uint8_t *const levels,
112 const int c, // raster order
113 const int bwl, const TX_CLASS tx_class) {
114 const int row = c >> bwl;
115 const int col = c - (row << bwl);
116 const int stride = (1 << bwl) + TX_PAD_HOR;
117 const int pos = row * stride + col;
118 int mag = levels[pos + 1];
119 mag += levels[pos + stride];
120 switch (tx_class) {
121 case TX_CLASS_2D:
122 mag += levels[pos + stride + 1];
123 mag = AOMMIN((mag + 1) >> 1, 6);
124 if (c == 0) return mag;
125 if ((row < 2) && (col < 2)) return mag + 7;
126 break;
127 case TX_CLASS_HORIZ:
128 mag += levels[pos + 2];
129 mag = AOMMIN((mag + 1) >> 1, 6);
130 if (c == 0) return mag;
131 if (col == 0) return mag + 7;
132 break;
133 case TX_CLASS_VERT:
134 mag += levels[pos + (stride << 1)];
135 mag = AOMMIN((mag + 1) >> 1, 6);
136 if (c == 0) return mag;
137 if (row == 0) return mag + 7;
138 break;
139 default: break;
140 }
141
142 return mag + 14;
143 }
144
145 static const uint8_t clip_max3[256] = {
146 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
147 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
148 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
149 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
150 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
151 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
152 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
153 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
154 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
155 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
156 };
157
get_nz_mag(const uint8_t * const levels,const int bwl,const TX_CLASS tx_class)158 static AOM_FORCE_INLINE int get_nz_mag(const uint8_t *const levels,
159 const int bwl, const TX_CLASS tx_class) {
160 int mag;
161
162 // Note: AOMMIN(level, 3) is useless for decoder since level < 3.
163 mag = clip_max3[levels[1]]; // { 0, 1 }
164 mag += clip_max3[levels[(1 << bwl) + TX_PAD_HOR]]; // { 1, 0 }
165
166 if (tx_class == TX_CLASS_2D) {
167 mag += clip_max3[levels[(1 << bwl) + TX_PAD_HOR + 1]]; // { 1, 1 }
168 mag += clip_max3[levels[2]]; // { 0, 2 }
169 mag += clip_max3[levels[(2 << bwl) + (2 << TX_PAD_HOR_LOG2)]]; // { 2, 0 }
170 } else if (tx_class == TX_CLASS_VERT) {
171 mag += clip_max3[levels[(2 << bwl) + (2 << TX_PAD_HOR_LOG2)]]; // { 2, 0 }
172 mag += clip_max3[levels[(3 << bwl) + (3 << TX_PAD_HOR_LOG2)]]; // { 3, 0 }
173 mag += clip_max3[levels[(4 << bwl) + (4 << TX_PAD_HOR_LOG2)]]; // { 4, 0 }
174 } else {
175 mag += clip_max3[levels[2]]; // { 0, 2 }
176 mag += clip_max3[levels[3]]; // { 0, 3 }
177 mag += clip_max3[levels[4]]; // { 0, 4 }
178 }
179
180 return mag;
181 }
182
183 #define NZ_MAP_CTX_0 SIG_COEF_CONTEXTS_2D
184 #define NZ_MAP_CTX_5 (NZ_MAP_CTX_0 + 5)
185 #define NZ_MAP_CTX_10 (NZ_MAP_CTX_0 + 10)
186
187 static const int nz_map_ctx_offset_1d[32] = {
188 NZ_MAP_CTX_0, NZ_MAP_CTX_5, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10,
189 NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10,
190 NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10,
191 NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10,
192 NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10,
193 NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10,
194 NZ_MAP_CTX_10, NZ_MAP_CTX_10,
195 };
196
get_nz_map_ctx_from_stats(const int stats,const int coeff_idx,const int bwl,const TX_SIZE tx_size,const TX_CLASS tx_class)197 static AOM_FORCE_INLINE int get_nz_map_ctx_from_stats(
198 const int stats,
199 const int coeff_idx, // raster order
200 const int bwl, const TX_SIZE tx_size, const TX_CLASS tx_class) {
201 // tx_class == 0(TX_CLASS_2D)
202 if ((tx_class | coeff_idx) == 0) return 0;
203 int ctx = (stats + 1) >> 1;
204 ctx = AOMMIN(ctx, 4);
205 switch (tx_class) {
206 case TX_CLASS_2D: {
207 // This is the algorithm to generate av1_nz_map_ctx_offset[][]
208 // const int width = tx_size_wide[tx_size];
209 // const int height = tx_size_high[tx_size];
210 // if (width < height) {
211 // if (row < 2) return 11 + ctx;
212 // } else if (width > height) {
213 // if (col < 2) return 16 + ctx;
214 // }
215 // if (row + col < 2) return ctx + 1;
216 // if (row + col < 4) return 5 + ctx + 1;
217 // return 21 + ctx;
218 return ctx + av1_nz_map_ctx_offset[tx_size][coeff_idx];
219 }
220 case TX_CLASS_HORIZ: {
221 const int row = coeff_idx >> bwl;
222 const int col = coeff_idx - (row << bwl);
223 return ctx + nz_map_ctx_offset_1d[col];
224 }
225 case TX_CLASS_VERT: {
226 const int row = coeff_idx >> bwl;
227 return ctx + nz_map_ctx_offset_1d[row];
228 }
229 default: break;
230 }
231 return 0;
232 }
233
234 typedef aom_cdf_prob (*base_cdf_arr)[CDF_SIZE(4)];
235 typedef aom_cdf_prob (*br_cdf_arr)[CDF_SIZE(BR_CDF_SIZE)];
236
get_lower_levels_ctx_eob(int bwl,int height,int scan_idx)237 static INLINE int get_lower_levels_ctx_eob(int bwl, int height, int scan_idx) {
238 if (scan_idx == 0) return 0;
239 if (scan_idx <= (height << bwl) / 8) return 1;
240 if (scan_idx <= (height << bwl) / 4) return 2;
241 return 3;
242 }
243
get_lower_levels_ctx_2d(const uint8_t * levels,int coeff_idx,int bwl,TX_SIZE tx_size)244 static INLINE int get_lower_levels_ctx_2d(const uint8_t *levels, int coeff_idx,
245 int bwl, TX_SIZE tx_size) {
246 assert(coeff_idx > 0);
247 int mag;
248 // Note: AOMMIN(level, 3) is useless for decoder since level < 3.
249 levels = levels + get_padded_idx(coeff_idx, bwl);
250 mag = AOMMIN(levels[1], 3); // { 0, 1 }
251 mag += AOMMIN(levels[(1 << bwl) + TX_PAD_HOR], 3); // { 1, 0 }
252 mag += AOMMIN(levels[(1 << bwl) + TX_PAD_HOR + 1], 3); // { 1, 1 }
253 mag += AOMMIN(levels[2], 3); // { 0, 2 }
254 mag += AOMMIN(levels[(2 << bwl) + (2 << TX_PAD_HOR_LOG2)], 3); // { 2, 0 }
255
256 const int ctx = AOMMIN((mag + 1) >> 1, 4);
257 return ctx + av1_nz_map_ctx_offset[tx_size][coeff_idx];
258 }
get_lower_levels_ctx(const uint8_t * levels,int coeff_idx,int bwl,TX_SIZE tx_size,TX_CLASS tx_class)259 static AOM_FORCE_INLINE int get_lower_levels_ctx(const uint8_t *levels,
260 int coeff_idx, int bwl,
261 TX_SIZE tx_size,
262 TX_CLASS tx_class) {
263 const int stats =
264 get_nz_mag(levels + get_padded_idx(coeff_idx, bwl), bwl, tx_class);
265 return get_nz_map_ctx_from_stats(stats, coeff_idx, bwl, tx_size, tx_class);
266 }
267
get_lower_levels_ctx_general(int is_last,int scan_idx,int bwl,int height,const uint8_t * levels,int coeff_idx,TX_SIZE tx_size,TX_CLASS tx_class)268 static INLINE int get_lower_levels_ctx_general(int is_last, int scan_idx,
269 int bwl, int height,
270 const uint8_t *levels,
271 int coeff_idx, TX_SIZE tx_size,
272 TX_CLASS tx_class) {
273 if (is_last) {
274 if (scan_idx == 0) return 0;
275 if (scan_idx <= (height << bwl) >> 3) return 1;
276 if (scan_idx <= (height << bwl) >> 2) return 2;
277 return 3;
278 }
279 return get_lower_levels_ctx(levels, coeff_idx, bwl, tx_size, tx_class);
280 }
281
set_dc_sign(int * cul_level,int dc_val)282 static INLINE void set_dc_sign(int *cul_level, int dc_val) {
283 if (dc_val < 0)
284 *cul_level |= 1 << COEFF_CONTEXT_BITS;
285 else if (dc_val > 0)
286 *cul_level += 2 << COEFF_CONTEXT_BITS;
287 }
288
get_txb_ctx_general(const BLOCK_SIZE plane_bsize,const TX_SIZE tx_size,const int plane,const ENTROPY_CONTEXT * const a,const ENTROPY_CONTEXT * const l,TXB_CTX * const txb_ctx)289 static void get_txb_ctx_general(const BLOCK_SIZE plane_bsize,
290 const TX_SIZE tx_size, const int plane,
291 const ENTROPY_CONTEXT *const a,
292 const ENTROPY_CONTEXT *const l,
293 TXB_CTX *const txb_ctx) {
294 #define MAX_TX_SIZE_UNIT 16
295 static const int8_t signs[3] = { 0, -1, 1 };
296 static const int8_t dc_sign_contexts[4 * MAX_TX_SIZE_UNIT + 1] = {
297 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
298 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
299 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
300 };
301 const int txb_w_unit = tx_size_wide_unit[tx_size];
302 const int txb_h_unit = tx_size_high_unit[tx_size];
303 int dc_sign = 0;
304 int k = 0;
305
306 do {
307 const unsigned int sign = ((uint8_t)a[k]) >> COEFF_CONTEXT_BITS;
308 assert(sign <= 2);
309 dc_sign += signs[sign];
310 } while (++k < txb_w_unit);
311
312 k = 0;
313 do {
314 const unsigned int sign = ((uint8_t)l[k]) >> COEFF_CONTEXT_BITS;
315 assert(sign <= 2);
316 dc_sign += signs[sign];
317 } while (++k < txb_h_unit);
318
319 txb_ctx->dc_sign_ctx = dc_sign_contexts[dc_sign + 2 * MAX_TX_SIZE_UNIT];
320
321 if (plane == 0) {
322 if (plane_bsize == txsize_to_bsize[tx_size]) {
323 txb_ctx->txb_skip_ctx = 0;
324 } else {
325 // This is the algorithm to generate table skip_contexts[top][left].
326 // const int max = AOMMIN(top | left, 4);
327 // const int min = AOMMIN(AOMMIN(top, left), 4);
328 // if (!max)
329 // txb_skip_ctx = 1;
330 // else if (!min)
331 // txb_skip_ctx = 2 + (max > 3);
332 // else if (max <= 3)
333 // txb_skip_ctx = 4;
334 // else if (min <= 3)
335 // txb_skip_ctx = 5;
336 // else
337 // txb_skip_ctx = 6;
338 static const uint8_t skip_contexts[5][5] = { { 1, 2, 2, 2, 3 },
339 { 2, 4, 4, 4, 5 },
340 { 2, 4, 4, 4, 5 },
341 { 2, 4, 4, 4, 5 },
342 { 3, 5, 5, 5, 6 } };
343 // For top and left, we only care about which of the following three
344 // categories they belong to: { 0 }, { 1, 2, 3 }, or { 4, 5, ... }. The
345 // spec calculates top and left with the Max() function. We can calculate
346 // an approximate max with bitwise OR because the real max and the
347 // approximate max belong to the same category.
348 int top = 0;
349 int left = 0;
350
351 k = 0;
352 do {
353 top |= a[k];
354 } while (++k < txb_w_unit);
355 top &= COEFF_CONTEXT_MASK;
356 top = AOMMIN(top, 4);
357
358 k = 0;
359 do {
360 left |= l[k];
361 } while (++k < txb_h_unit);
362 left &= COEFF_CONTEXT_MASK;
363 left = AOMMIN(left, 4);
364
365 txb_ctx->txb_skip_ctx = skip_contexts[top][left];
366 }
367 } else {
368 const int ctx_base = get_entropy_context(tx_size, a, l);
369 const int ctx_offset = (num_pels_log2_lookup[plane_bsize] >
370 num_pels_log2_lookup[txsize_to_bsize[tx_size]])
371 ? 10
372 : 7;
373 txb_ctx->txb_skip_ctx = ctx_base + ctx_offset;
374 }
375 }
376
377 #define SPECIALIZE_GET_TXB_CTX(w, h) \
378 static void get_txb_ctx_##w##x##h( \
379 const BLOCK_SIZE plane_bsize, const int plane, \
380 const ENTROPY_CONTEXT *const a, const ENTROPY_CONTEXT *const l, \
381 TXB_CTX *const txb_ctx) { \
382 static const int8_t signs[3] = { 0, -1, 1 }; \
383 static const int8_t dc_sign_contexts[4 * MAX_TX_SIZE_UNIT + 1] = { \
384 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
385 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \
386 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 \
387 }; \
388 const TX_SIZE tx_size = TX_##w##X##h; \
389 const int txb_w_unit = tx_size_wide_unit[tx_size]; \
390 const int txb_h_unit = tx_size_high_unit[tx_size]; \
391 int dc_sign = 0; \
392 int k = 0; \
393 \
394 do { \
395 const unsigned int sign = ((uint8_t)a[k]) >> COEFF_CONTEXT_BITS; \
396 assert(sign <= 2); \
397 dc_sign += signs[sign]; \
398 } while (++k < txb_w_unit); \
399 \
400 k = 0; \
401 do { \
402 const unsigned int sign = ((uint8_t)l[k]) >> COEFF_CONTEXT_BITS; \
403 assert(sign <= 2); \
404 dc_sign += signs[sign]; \
405 } while (++k < txb_h_unit); \
406 \
407 txb_ctx->dc_sign_ctx = dc_sign_contexts[dc_sign + 2 * MAX_TX_SIZE_UNIT]; \
408 \
409 if (plane == 0) { \
410 if (plane_bsize == txsize_to_bsize[tx_size]) { \
411 txb_ctx->txb_skip_ctx = 0; \
412 } else { \
413 static const uint8_t skip_contexts[5][5] = { { 1, 2, 2, 2, 3 }, \
414 { 2, 4, 4, 4, 5 }, \
415 { 2, 4, 4, 4, 5 }, \
416 { 2, 4, 4, 4, 5 }, \
417 { 3, 5, 5, 5, 6 } }; \
418 int top = 0; \
419 int left = 0; \
420 \
421 k = 0; \
422 do { \
423 top |= a[k]; \
424 } while (++k < txb_w_unit); \
425 top &= COEFF_CONTEXT_MASK; \
426 top = AOMMIN(top, 4); \
427 \
428 k = 0; \
429 do { \
430 left |= l[k]; \
431 } while (++k < txb_h_unit); \
432 left &= COEFF_CONTEXT_MASK; \
433 left = AOMMIN(left, 4); \
434 \
435 txb_ctx->txb_skip_ctx = skip_contexts[top][left]; \
436 } \
437 } else { \
438 const int ctx_base = get_entropy_context(tx_size, a, l); \
439 const int ctx_offset = (num_pels_log2_lookup[plane_bsize] > \
440 num_pels_log2_lookup[txsize_to_bsize[tx_size]]) \
441 ? 10 \
442 : 7; \
443 txb_ctx->txb_skip_ctx = ctx_base + ctx_offset; \
444 } \
445 }
446
447 SPECIALIZE_GET_TXB_CTX(4, 4)
448 SPECIALIZE_GET_TXB_CTX(8, 8)
449 SPECIALIZE_GET_TXB_CTX(16, 16)
450 SPECIALIZE_GET_TXB_CTX(32, 32)
451
452 // Wrapper for get_txb_ctx that calls the specialized version of get_txb_ctc_*
453 // so that the compiler can compile away the while loops.
get_txb_ctx(const BLOCK_SIZE plane_bsize,const TX_SIZE tx_size,const int plane,const ENTROPY_CONTEXT * const a,const ENTROPY_CONTEXT * const l,TXB_CTX * const txb_ctx)454 static INLINE void get_txb_ctx(const BLOCK_SIZE plane_bsize,
455 const TX_SIZE tx_size, const int plane,
456 const ENTROPY_CONTEXT *const a,
457 const ENTROPY_CONTEXT *const l,
458 TXB_CTX *const txb_ctx) {
459 switch (tx_size) {
460 case TX_4X4: get_txb_ctx_4x4(plane_bsize, plane, a, l, txb_ctx); break;
461 case TX_8X8: get_txb_ctx_8x8(plane_bsize, plane, a, l, txb_ctx); break;
462 case TX_16X16: get_txb_ctx_16x16(plane_bsize, plane, a, l, txb_ctx); break;
463 case TX_32X32: get_txb_ctx_32x32(plane_bsize, plane, a, l, txb_ctx); break;
464 default:
465 get_txb_ctx_general(plane_bsize, tx_size, plane, a, l, txb_ctx);
466 break;
467 }
468 }
469 #undef MAX_TX_SIZE_UNIT
470
471 #endif // AOM_AV1_COMMON_TXB_COMMON_H_
472