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