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 AV1_COMMON_TXB_COMMON_H_
13 #define AV1_COMMON_TXB_COMMON_H_
14
15 #define REDUCE_CONTEXT_DEPENDENCY 0
16 #define MIN_SCAN_IDX_REDUCE_CONTEXT_DEPENDENCY 0
17
18 extern const int16_t av1_coeff_band_4x4[16];
19
20 extern const int16_t av1_coeff_band_8x8[64];
21
22 extern const int16_t av1_coeff_band_16x16[256];
23
24 extern const int16_t av1_coeff_band_32x32[1024];
25
26 typedef struct txb_ctx {
27 int txb_skip_ctx;
28 int dc_sign_ctx;
29 } TXB_CTX;
30
get_txsize_context(TX_SIZE tx_size)31 static INLINE TX_SIZE get_txsize_context(TX_SIZE tx_size) {
32 return txsize_sqr_up_map[tx_size];
33 }
34
35 static int base_ref_offset[BASE_CONTEXT_POSITION_NUM][2] = {
36 /* clang-format off*/
37 { -2, 0 }, { -1, -1 }, { -1, 0 }, { -1, 1 }, { 0, -2 }, { 0, -1 }, { 0, 1 },
38 { 0, 2 }, { 1, -1 }, { 1, 0 }, { 1, 1 }, { 2, 0 }
39 /* clang-format on*/
40 };
41
get_level_count(const tran_low_t * tcoeffs,int bwl,int height,int row,int col,int level,int (* nb_offset)[2],int nb_num)42 static INLINE int get_level_count(const tran_low_t *tcoeffs, int bwl,
43 int height, int row, int col, int level,
44 int (*nb_offset)[2], int nb_num) {
45 int count = 0;
46 for (int idx = 0; idx < nb_num; ++idx) {
47 const int ref_row = row + nb_offset[idx][0];
48 const int ref_col = col + nb_offset[idx][1];
49 if (ref_row < 0 || ref_col < 0 || ref_row >= height ||
50 ref_col >= (1 << bwl))
51 continue;
52 const int pos = (ref_row << bwl) + ref_col;
53 tran_low_t abs_coeff = abs(tcoeffs[pos]);
54 count += abs_coeff > level;
55 }
56 return count;
57 }
58
get_mag(int * mag,const tran_low_t * tcoeffs,int bwl,int height,int row,int col,int (* nb_offset)[2],int nb_num)59 static INLINE void get_mag(int *mag, const tran_low_t *tcoeffs, int bwl,
60 int height, int row, int col, int (*nb_offset)[2],
61 int nb_num) {
62 mag[0] = 0;
63 mag[1] = 0;
64 for (int idx = 0; idx < nb_num; ++idx) {
65 const int ref_row = row + nb_offset[idx][0];
66 const int ref_col = col + nb_offset[idx][1];
67 if (ref_row < 0 || ref_col < 0 || ref_row >= height ||
68 ref_col >= (1 << bwl))
69 continue;
70 const int pos = (ref_row << bwl) + ref_col;
71 tran_low_t abs_coeff = abs(tcoeffs[pos]);
72 if (nb_offset[idx][0] >= 0 && nb_offset[idx][1] >= 0) {
73 if (abs_coeff > mag[0]) {
74 mag[0] = abs_coeff;
75 mag[1] = 1;
76 } else if (abs_coeff == mag[0]) {
77 ++mag[1];
78 }
79 }
80 }
81 }
82
get_base_count_mag(int * mag,int * count,const tran_low_t * tcoeffs,int bwl,int height,int row,int col)83 static INLINE void get_base_count_mag(int *mag, int *count,
84 const tran_low_t *tcoeffs, int bwl,
85 int height, int row, int col) {
86 mag[0] = 0;
87 mag[1] = 0;
88 for (int i = 0; i < NUM_BASE_LEVELS; ++i) count[i] = 0;
89 for (int idx = 0; idx < BASE_CONTEXT_POSITION_NUM; ++idx) {
90 const int ref_row = row + base_ref_offset[idx][0];
91 const int ref_col = col + base_ref_offset[idx][1];
92 if (ref_row < 0 || ref_col < 0 || ref_row >= height ||
93 ref_col >= (1 << bwl))
94 continue;
95 const int pos = (ref_row << bwl) + ref_col;
96 tran_low_t abs_coeff = abs(tcoeffs[pos]);
97 // count
98 for (int i = 0; i < NUM_BASE_LEVELS; ++i) {
99 count[i] += abs_coeff > i;
100 }
101 // mag
102 if (base_ref_offset[idx][0] >= 0 && base_ref_offset[idx][1] >= 0) {
103 if (abs_coeff > mag[0]) {
104 mag[0] = abs_coeff;
105 mag[1] = 1;
106 } else if (abs_coeff == mag[0]) {
107 ++mag[1];
108 }
109 }
110 }
111 }
112
get_level_count_mag(int * mag,const tran_low_t * tcoeffs,int bwl,int height,int row,int col,int level,int (* nb_offset)[2],int nb_num)113 static INLINE int get_level_count_mag(int *mag, const tran_low_t *tcoeffs,
114 int bwl, int height, int row, int col,
115 int level, int (*nb_offset)[2],
116 int nb_num) {
117 const int stride = 1 << bwl;
118 int count = 0;
119 *mag = 0;
120 for (int idx = 0; idx < nb_num; ++idx) {
121 const int ref_row = row + nb_offset[idx][0];
122 const int ref_col = col + nb_offset[idx][1];
123 if (ref_row < 0 || ref_col < 0 || ref_row >= height || ref_col >= stride)
124 continue;
125 const int pos = (ref_row << bwl) + ref_col;
126 tran_low_t abs_coeff = abs(tcoeffs[pos]);
127 count += abs_coeff > level;
128 if (nb_offset[idx][0] >= 0 && nb_offset[idx][1] >= 0)
129 *mag = AOMMAX(*mag, abs_coeff);
130 }
131 return count;
132 }
133
get_base_ctx_from_count_mag(int row,int col,int count,int sig_mag)134 static INLINE int get_base_ctx_from_count_mag(int row, int col, int count,
135 int sig_mag) {
136 const int ctx = (count + 1) >> 1;
137 int ctx_idx = -1;
138 if (row == 0 && col == 0) {
139 ctx_idx = (ctx << 1) + sig_mag;
140 // TODO(angiebird): turn this on once the optimization is finalized
141 // assert(ctx_idx < 8);
142 } else if (row == 0) {
143 ctx_idx = 8 + (ctx << 1) + sig_mag;
144 // TODO(angiebird): turn this on once the optimization is finalized
145 // assert(ctx_idx < 18);
146 } else if (col == 0) {
147 ctx_idx = 8 + 10 + (ctx << 1) + sig_mag;
148 // TODO(angiebird): turn this on once the optimization is finalized
149 // assert(ctx_idx < 28);
150 } else {
151 ctx_idx = 8 + 10 + 10 + (ctx << 1) + sig_mag;
152 assert(ctx_idx < COEFF_BASE_CONTEXTS);
153 }
154 return ctx_idx;
155 }
156
get_base_ctx(const tran_low_t * tcoeffs,int c,const int bwl,const int height,const int level)157 static INLINE int get_base_ctx(const tran_low_t *tcoeffs,
158 int c, // raster order
159 const int bwl, const int height,
160 const int level) {
161 const int row = c >> bwl;
162 const int col = c - (row << bwl);
163 const int level_minus_1 = level - 1;
164 int mag;
165 int count =
166 get_level_count_mag(&mag, tcoeffs, bwl, height, row, col, level_minus_1,
167 base_ref_offset, BASE_CONTEXT_POSITION_NUM);
168 int ctx_idx = get_base_ctx_from_count_mag(row, col, count, mag > level);
169 return ctx_idx;
170 }
171
172 #define BR_CONTEXT_POSITION_NUM 8 // Base range coefficient context
173 static int br_ref_offset[BR_CONTEXT_POSITION_NUM][2] = {
174 /* clang-format off*/
175 { -1, -1 }, { -1, 0 }, { -1, 1 }, { 0, -1 },
176 { 0, 1 }, { 1, -1 }, { 1, 0 }, { 1, 1 },
177 /* clang-format on*/
178 };
179
180 static const int br_level_map[9] = {
181 0, 0, 1, 1, 2, 2, 3, 3, 3,
182 };
183
184 static const int coeff_to_br_index[COEFF_BASE_RANGE] = {
185 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2,
186 };
187
188 static const int br_index_to_coeff[BASE_RANGE_SETS] = {
189 0, 2, 6,
190 };
191
192 static const int br_extra_bits[BASE_RANGE_SETS] = {
193 1, 2, 3,
194 };
195
196 #define BR_MAG_OFFSET 1
197 // TODO(angiebird): optimize this function by using a table to map from
198 // count/mag to ctx
199
get_br_count_mag(int * mag,const tran_low_t * tcoeffs,int bwl,int height,int row,int col,int level)200 static INLINE int get_br_count_mag(int *mag, const tran_low_t *tcoeffs, int bwl,
201 int height, int row, int col, int level) {
202 mag[0] = 0;
203 mag[1] = 0;
204 int count = 0;
205 for (int idx = 0; idx < BR_CONTEXT_POSITION_NUM; ++idx) {
206 const int ref_row = row + br_ref_offset[idx][0];
207 const int ref_col = col + br_ref_offset[idx][1];
208 if (ref_row < 0 || ref_col < 0 || ref_row >= height ||
209 ref_col >= (1 << bwl))
210 continue;
211 const int pos = (ref_row << bwl) + ref_col;
212 tran_low_t abs_coeff = abs(tcoeffs[pos]);
213 count += abs_coeff > level;
214 if (br_ref_offset[idx][0] >= 0 && br_ref_offset[idx][1] >= 0) {
215 if (abs_coeff > mag[0]) {
216 mag[0] = abs_coeff;
217 mag[1] = 1;
218 } else if (abs_coeff == mag[0]) {
219 ++mag[1];
220 }
221 }
222 }
223 return count;
224 }
225
get_br_ctx_from_count_mag(int row,int col,int count,int mag)226 static INLINE int get_br_ctx_from_count_mag(int row, int col, int count,
227 int mag) {
228 int offset = 0;
229 if (mag <= BR_MAG_OFFSET)
230 offset = 0;
231 else if (mag <= 3)
232 offset = 1;
233 else if (mag <= 5)
234 offset = 2;
235 else
236 offset = 3;
237
238 int ctx = br_level_map[count];
239 ctx += offset * BR_TMP_OFFSET;
240
241 // DC: 0 - 1
242 if (row == 0 && col == 0) return ctx;
243
244 // Top row: 2 - 4
245 if (row == 0) return 2 + ctx;
246
247 // Left column: 5 - 7
248 if (col == 0) return 5 + ctx;
249
250 // others: 8 - 11
251 return 8 + ctx;
252 }
253
get_br_ctx(const tran_low_t * tcoeffs,const int c,const int bwl,const int height)254 static INLINE int get_br_ctx(const tran_low_t *tcoeffs,
255 const int c, // raster order
256 const int bwl, const int height) {
257 const int row = c >> bwl;
258 const int col = c - (row << bwl);
259 const int level_minus_1 = NUM_BASE_LEVELS;
260 int mag;
261 const int count =
262 get_level_count_mag(&mag, tcoeffs, bwl, height, row, col, level_minus_1,
263 br_ref_offset, BR_CONTEXT_POSITION_NUM);
264 const int ctx = get_br_ctx_from_count_mag(row, col, count, mag);
265 return ctx;
266 }
267
268 #define SIG_REF_OFFSET_NUM 7
269 static int sig_ref_offset[SIG_REF_OFFSET_NUM][2] = {
270 { -2, -1 }, { -2, 0 }, { -1, -2 }, { -1, -1 },
271 { -1, 0 }, { 0, -2 }, { 0, -1 },
272 };
273
274 #if REDUCE_CONTEXT_DEPENDENCY
get_nz_count(const tran_low_t * tcoeffs,int bwl,int height,int row,int col,int prev_row,int prev_col)275 static INLINE int get_nz_count(const tran_low_t *tcoeffs, int bwl, int height,
276 int row, int col, int prev_row, int prev_col) {
277 int count = 0;
278 for (int idx = 0; idx < SIG_REF_OFFSET_NUM; ++idx) {
279 const int ref_row = row + sig_ref_offset[idx][0];
280 const int ref_col = col + sig_ref_offset[idx][1];
281 if (ref_row < 0 || ref_col < 0 || ref_row >= height ||
282 ref_col >= (1 << bwl) || (prev_row == ref_row && prev_col == ref_col))
283 continue;
284 const int nb_pos = (ref_row << bwl) + ref_col;
285 count += (tcoeffs[nb_pos] != 0);
286 }
287 return count;
288 }
289 #else
get_nz_count(const tran_low_t * tcoeffs,int bwl,int height,int row,int col)290 static INLINE int get_nz_count(const tran_low_t *tcoeffs, int bwl, int height,
291 int row, int col) {
292 int count = 0;
293 for (int idx = 0; idx < SIG_REF_OFFSET_NUM; ++idx) {
294 const int ref_row = row + sig_ref_offset[idx][0];
295 const int ref_col = col + sig_ref_offset[idx][1];
296 if (ref_row < 0 || ref_col < 0 || ref_row >= height ||
297 ref_col >= (1 << bwl))
298 continue;
299 const int nb_pos = (ref_row << bwl) + ref_col;
300 count += (tcoeffs[nb_pos] != 0);
301 }
302 return count;
303 }
304 #endif
305
get_tx_class(TX_TYPE tx_type)306 static INLINE TX_CLASS get_tx_class(TX_TYPE tx_type) {
307 switch (tx_type) {
308 #if CONFIG_EXT_TX
309 case V_DCT:
310 case V_ADST:
311 case V_FLIPADST: return TX_CLASS_VERT;
312 case H_DCT:
313 case H_ADST:
314 case H_FLIPADST: return TX_CLASS_HORIZ;
315 #endif
316 default: return TX_CLASS_2D;
317 }
318 }
319
320 // TODO(angiebird): optimize this function by generate a table that maps from
321 // count to ctx
get_nz_map_ctx_from_count(int count,int coeff_idx,int bwl,TX_TYPE tx_type)322 static INLINE int get_nz_map_ctx_from_count(int count,
323 int coeff_idx, // raster order
324 int bwl, TX_TYPE tx_type) {
325 (void)tx_type;
326 const int row = coeff_idx >> bwl;
327 const int col = coeff_idx - (row << bwl);
328 int ctx = 0;
329 #if CONFIG_EXT_TX
330 int tx_class = get_tx_class(tx_type);
331 int offset;
332 if (tx_class == TX_CLASS_2D)
333 offset = 0;
334 else if (tx_class == TX_CLASS_VERT)
335 offset = SIG_COEF_CONTEXTS_2D;
336 else
337 offset = SIG_COEF_CONTEXTS_2D + SIG_COEF_CONTEXTS_1D;
338 #else
339 int offset = 0;
340 #endif
341
342 if (row == 0 && col == 0) return offset + 0;
343
344 if (row == 0 && col == 1) return offset + 1 + count;
345
346 if (row == 1 && col == 0) return offset + 3 + count;
347
348 if (row == 1 && col == 1) {
349 ctx = (count + 1) >> 1;
350
351 assert(5 + ctx <= 7);
352
353 return offset + 5 + ctx;
354 }
355
356 if (row == 0) {
357 ctx = (count + 1) >> 1;
358
359 assert(ctx < 2);
360 return offset + 8 + ctx;
361 }
362
363 if (col == 0) {
364 ctx = (count + 1) >> 1;
365
366 assert(ctx < 2);
367 return offset + 10 + ctx;
368 }
369
370 ctx = count >> 1;
371
372 assert(12 + ctx < 16);
373
374 return offset + 12 + ctx;
375 }
376
get_nz_map_ctx(const tran_low_t * tcoeffs,const int scan_idx,const int16_t * scan,const int bwl,const int height,TX_TYPE tx_type)377 static INLINE int get_nz_map_ctx(const tran_low_t *tcoeffs, const int scan_idx,
378 const int16_t *scan, const int bwl,
379 const int height, TX_TYPE tx_type) {
380 const int coeff_idx = scan[scan_idx];
381 const int row = coeff_idx >> bwl;
382 const int col = coeff_idx - (row << bwl);
383 #if REDUCE_CONTEXT_DEPENDENCY
384 int prev_coeff_idx;
385 int prev_row;
386 int prev_col;
387 if (scan_idx > MIN_SCAN_IDX_REDUCE_CONTEXT_DEPENDENCY) {
388 prev_coeff_idx = scan[scan_idx - 1]; // raster order
389 prev_row = prev_coeff_idx >> bwl;
390 prev_col = prev_coeff_idx - (prev_row << bwl);
391 } else {
392 prev_coeff_idx = -1;
393 prev_row = -1;
394 prev_col = -1;
395 }
396 int count = get_nz_count(tcoeffs, bwl, height, row, col, prev_row, prev_col);
397 #else
398 int count = get_nz_count(tcoeffs, bwl, height, row, col);
399 #endif
400 return get_nz_map_ctx_from_count(count, coeff_idx, bwl, tx_type);
401 }
402
get_eob_ctx(const tran_low_t * tcoeffs,const int coeff_idx,const TX_SIZE txs_ctx,TX_TYPE tx_type)403 static INLINE int get_eob_ctx(const tran_low_t *tcoeffs,
404 const int coeff_idx, // raster order
405 const TX_SIZE txs_ctx, TX_TYPE tx_type) {
406 (void)tcoeffs;
407 int offset = 0;
408 #if CONFIG_CTX1D
409 TX_CLASS tx_class = get_tx_class(tx_type);
410 if (tx_class == TX_CLASS_VERT)
411 offset = EOB_COEF_CONTEXTS_2D;
412 else if (tx_class == TX_CLASS_HORIZ)
413 offset = EOB_COEF_CONTEXTS_2D + EOB_COEF_CONTEXTS_1D;
414 #else
415 (void)tx_type;
416 #endif
417
418 if (txs_ctx == TX_4X4) return offset + av1_coeff_band_4x4[coeff_idx];
419 if (txs_ctx == TX_8X8) return offset + av1_coeff_band_8x8[coeff_idx];
420 if (txs_ctx == TX_16X16) return offset + av1_coeff_band_16x16[coeff_idx];
421 if (txs_ctx == TX_32X32) return offset + av1_coeff_band_32x32[coeff_idx];
422
423 assert(0);
424 return 0;
425 }
426
set_dc_sign(int * cul_level,tran_low_t v)427 static INLINE void set_dc_sign(int *cul_level, tran_low_t v) {
428 if (v < 0)
429 *cul_level |= 1 << COEFF_CONTEXT_BITS;
430 else if (v > 0)
431 *cul_level += 2 << COEFF_CONTEXT_BITS;
432 }
433
get_dc_sign_ctx(int dc_sign)434 static INLINE int get_dc_sign_ctx(int dc_sign) {
435 int dc_sign_ctx = 0;
436 if (dc_sign < 0)
437 dc_sign_ctx = 1;
438 else if (dc_sign > 0)
439 dc_sign_ctx = 2;
440
441 return dc_sign_ctx;
442 }
443
get_txb_ctx(BLOCK_SIZE plane_bsize,TX_SIZE tx_size,int plane,const ENTROPY_CONTEXT * a,const ENTROPY_CONTEXT * l,TXB_CTX * txb_ctx)444 static INLINE void get_txb_ctx(BLOCK_SIZE plane_bsize, TX_SIZE tx_size,
445 int plane, const ENTROPY_CONTEXT *a,
446 const ENTROPY_CONTEXT *l, TXB_CTX *txb_ctx) {
447 const int txb_w_unit = tx_size_wide_unit[tx_size];
448 const int txb_h_unit = tx_size_high_unit[tx_size];
449 int ctx_offset = (plane == 0) ? 0 : 7;
450
451 if (plane_bsize > txsize_to_bsize[tx_size]) ctx_offset += 3;
452
453 int dc_sign = 0;
454 for (int k = 0; k < txb_w_unit; ++k) {
455 int sign = ((uint8_t)a[k]) >> COEFF_CONTEXT_BITS;
456 if (sign == 1)
457 --dc_sign;
458 else if (sign == 2)
459 ++dc_sign;
460 else if (sign != 0)
461 assert(0);
462 }
463
464 for (int k = 0; k < txb_h_unit; ++k) {
465 int sign = ((uint8_t)l[k]) >> COEFF_CONTEXT_BITS;
466 if (sign == 1)
467 --dc_sign;
468 else if (sign == 2)
469 ++dc_sign;
470 else if (sign != 0)
471 assert(0);
472 }
473
474 txb_ctx->dc_sign_ctx = get_dc_sign_ctx(dc_sign);
475
476 if (plane == 0) {
477 int top = 0;
478 int left = 0;
479
480 for (int k = 0; k < txb_w_unit; ++k) {
481 top = AOMMAX(top, ((uint8_t)a[k] & COEFF_CONTEXT_MASK));
482 }
483
484 for (int k = 0; k < txb_h_unit; ++k) {
485 left = AOMMAX(left, ((uint8_t)l[k] & COEFF_CONTEXT_MASK));
486 }
487
488 top = AOMMIN(top, 255);
489 left = AOMMIN(left, 255);
490
491 if (plane_bsize == txsize_to_bsize[tx_size])
492 txb_ctx->txb_skip_ctx = 0;
493 else if (top == 0 && left == 0)
494 txb_ctx->txb_skip_ctx = 1;
495 else if (top == 0 || left == 0)
496 txb_ctx->txb_skip_ctx = 2 + (AOMMAX(top, left) > 3);
497 else if (AOMMAX(top, left) <= 3)
498 txb_ctx->txb_skip_ctx = 4;
499 else if (AOMMIN(top, left) <= 3)
500 txb_ctx->txb_skip_ctx = 5;
501 else
502 txb_ctx->txb_skip_ctx = 6;
503 } else {
504 int ctx_base = get_entropy_context(tx_size, a, l);
505 txb_ctx->txb_skip_ctx = ctx_offset + ctx_base;
506 }
507 }
508
509 #if LV_MAP_PROB
510 void av1_init_txb_probs(FRAME_CONTEXT *fc);
511 #endif // LV_MAP_PROB
512
513 void av1_adapt_txb_probs(AV1_COMMON *cm, unsigned int count_sat,
514 unsigned int update_factor);
515
516 void av1_init_lv_map(AV1_COMMON *cm);
517
518 #if CONFIG_CTX1D
get_eob_vert(int16_t * eob_ls,const tran_low_t * tcoeff,int w,int h)519 static INLINE void get_eob_vert(int16_t *eob_ls, const tran_low_t *tcoeff,
520 int w, int h) {
521 for (int c = 0; c < w; ++c) {
522 eob_ls[c] = 0;
523 for (int r = h - 1; r >= 0; --r) {
524 int coeff_idx = r * w + c;
525 if (tcoeff[coeff_idx] != 0) {
526 eob_ls[c] = r + 1;
527 break;
528 }
529 }
530 }
531 }
532
get_eob_horiz(int16_t * eob_ls,const tran_low_t * tcoeff,int w,int h)533 static INLINE void get_eob_horiz(int16_t *eob_ls, const tran_low_t *tcoeff,
534 int w, int h) {
535 for (int r = 0; r < h; ++r) {
536 eob_ls[r] = 0;
537 for (int c = w - 1; c >= 0; --c) {
538 int coeff_idx = r * w + c;
539 if (tcoeff[coeff_idx] != 0) {
540 eob_ls[r] = c + 1;
541 break;
542 }
543 }
544 }
545 }
546
get_empty_line_ctx(int line_idx,int16_t * eob_ls)547 static INLINE int get_empty_line_ctx(int line_idx, int16_t *eob_ls) {
548 if (line_idx > 0) {
549 int prev_eob = eob_ls[line_idx - 1];
550 if (prev_eob == 0) {
551 return 1;
552 } else if (prev_eob < 3) {
553 return 2;
554 } else if (prev_eob < 6) {
555 return 3;
556 } else {
557 return 4;
558 }
559 } else {
560 return 0;
561 }
562 }
563
564 #define MAX_POS_CTX 8
565 static int pos_ctx[MAX_HVTX_SIZE] = {
566 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5,
567 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7,
568 };
get_hv_eob_ctx(int line_idx,int pos,int16_t * eob_ls)569 static INLINE int get_hv_eob_ctx(int line_idx, int pos, int16_t *eob_ls) {
570 if (line_idx > 0) {
571 int prev_eob = eob_ls[line_idx - 1];
572 int diff = pos + 1 - prev_eob;
573 int abs_diff = abs(diff);
574 int ctx_idx = pos_ctx[abs_diff];
575 assert(ctx_idx < MAX_POS_CTX);
576 if (diff < 0) {
577 ctx_idx += MAX_POS_CTX;
578 assert(ctx_idx >= MAX_POS_CTX);
579 assert(ctx_idx < 2 * MAX_POS_CTX);
580 }
581 return ctx_idx;
582 } else {
583 int ctx_idx = MAX_POS_CTX + MAX_POS_CTX + pos_ctx[pos];
584 assert(ctx_idx < HV_EOB_CONTEXTS);
585 assert(HV_EOB_CONTEXTS == MAX_POS_CTX * 3);
586 return ctx_idx;
587 }
588 }
589 #endif // CONFIG_CTX1D
590
591 #endif // AV1_COMMON_TXB_COMMON_H_
592