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