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 #include <assert.h>
13*77c1e3ccSAndroid Build Coastguard Worker #include <emmintrin.h> // SSE2
14*77c1e3ccSAndroid Build Coastguard Worker
15*77c1e3ccSAndroid Build Coastguard Worker #include "aom/aom_integer.h"
16*77c1e3ccSAndroid Build Coastguard Worker #include "aom_dsp/x86/mem_sse2.h"
17*77c1e3ccSAndroid Build Coastguard Worker #include "av1/common/av1_common_int.h"
18*77c1e3ccSAndroid Build Coastguard Worker #include "av1/common/txb_common.h"
19*77c1e3ccSAndroid Build Coastguard Worker
load_levels_4x4x5_sse2(const uint8_t * const src,const int stride,const ptrdiff_t * const offsets,__m128i * const level)20*77c1e3ccSAndroid Build Coastguard Worker static inline void load_levels_4x4x5_sse2(const uint8_t *const src,
21*77c1e3ccSAndroid Build Coastguard Worker const int stride,
22*77c1e3ccSAndroid Build Coastguard Worker const ptrdiff_t *const offsets,
23*77c1e3ccSAndroid Build Coastguard Worker __m128i *const level) {
24*77c1e3ccSAndroid Build Coastguard Worker level[0] = load_8bit_4x4_to_1_reg_sse2(src + 1, stride);
25*77c1e3ccSAndroid Build Coastguard Worker level[1] = load_8bit_4x4_to_1_reg_sse2(src + stride, stride);
26*77c1e3ccSAndroid Build Coastguard Worker level[2] = load_8bit_4x4_to_1_reg_sse2(src + offsets[0], stride);
27*77c1e3ccSAndroid Build Coastguard Worker level[3] = load_8bit_4x4_to_1_reg_sse2(src + offsets[1], stride);
28*77c1e3ccSAndroid Build Coastguard Worker level[4] = load_8bit_4x4_to_1_reg_sse2(src + offsets[2], stride);
29*77c1e3ccSAndroid Build Coastguard Worker }
30*77c1e3ccSAndroid Build Coastguard Worker
load_levels_8x2x5_sse2(const uint8_t * const src,const int stride,const ptrdiff_t * const offsets,__m128i * const level)31*77c1e3ccSAndroid Build Coastguard Worker static inline void load_levels_8x2x5_sse2(const uint8_t *const src,
32*77c1e3ccSAndroid Build Coastguard Worker const int stride,
33*77c1e3ccSAndroid Build Coastguard Worker const ptrdiff_t *const offsets,
34*77c1e3ccSAndroid Build Coastguard Worker __m128i *const level) {
35*77c1e3ccSAndroid Build Coastguard Worker level[0] = load_8bit_8x2_to_1_reg_sse2(src + 1, stride);
36*77c1e3ccSAndroid Build Coastguard Worker level[1] = load_8bit_8x2_to_1_reg_sse2(src + stride, stride);
37*77c1e3ccSAndroid Build Coastguard Worker level[2] = load_8bit_8x2_to_1_reg_sse2(src + offsets[0], stride);
38*77c1e3ccSAndroid Build Coastguard Worker level[3] = load_8bit_8x2_to_1_reg_sse2(src + offsets[1], stride);
39*77c1e3ccSAndroid Build Coastguard Worker level[4] = load_8bit_8x2_to_1_reg_sse2(src + offsets[2], stride);
40*77c1e3ccSAndroid Build Coastguard Worker }
41*77c1e3ccSAndroid Build Coastguard Worker
load_levels_16x1x5_sse2(const uint8_t * const src,const int stride,const ptrdiff_t * const offsets,__m128i * const level)42*77c1e3ccSAndroid Build Coastguard Worker static inline void load_levels_16x1x5_sse2(const uint8_t *const src,
43*77c1e3ccSAndroid Build Coastguard Worker const int stride,
44*77c1e3ccSAndroid Build Coastguard Worker const ptrdiff_t *const offsets,
45*77c1e3ccSAndroid Build Coastguard Worker __m128i *const level) {
46*77c1e3ccSAndroid Build Coastguard Worker level[0] = _mm_loadu_si128((__m128i *)(src + 1));
47*77c1e3ccSAndroid Build Coastguard Worker level[1] = _mm_loadu_si128((__m128i *)(src + stride));
48*77c1e3ccSAndroid Build Coastguard Worker level[2] = _mm_loadu_si128((__m128i *)(src + offsets[0]));
49*77c1e3ccSAndroid Build Coastguard Worker level[3] = _mm_loadu_si128((__m128i *)(src + offsets[1]));
50*77c1e3ccSAndroid Build Coastguard Worker level[4] = _mm_loadu_si128((__m128i *)(src + offsets[2]));
51*77c1e3ccSAndroid Build Coastguard Worker }
52*77c1e3ccSAndroid Build Coastguard Worker
get_coeff_contexts_kernel_sse2(__m128i * const level)53*77c1e3ccSAndroid Build Coastguard Worker static inline __m128i get_coeff_contexts_kernel_sse2(__m128i *const level) {
54*77c1e3ccSAndroid Build Coastguard Worker const __m128i const_3 = _mm_set1_epi8(3);
55*77c1e3ccSAndroid Build Coastguard Worker const __m128i const_4 = _mm_set1_epi8(4);
56*77c1e3ccSAndroid Build Coastguard Worker __m128i count;
57*77c1e3ccSAndroid Build Coastguard Worker
58*77c1e3ccSAndroid Build Coastguard Worker count = _mm_min_epu8(level[0], const_3);
59*77c1e3ccSAndroid Build Coastguard Worker level[1] = _mm_min_epu8(level[1], const_3);
60*77c1e3ccSAndroid Build Coastguard Worker level[2] = _mm_min_epu8(level[2], const_3);
61*77c1e3ccSAndroid Build Coastguard Worker level[3] = _mm_min_epu8(level[3], const_3);
62*77c1e3ccSAndroid Build Coastguard Worker level[4] = _mm_min_epu8(level[4], const_3);
63*77c1e3ccSAndroid Build Coastguard Worker count = _mm_add_epi8(count, level[1]);
64*77c1e3ccSAndroid Build Coastguard Worker count = _mm_add_epi8(count, level[2]);
65*77c1e3ccSAndroid Build Coastguard Worker count = _mm_add_epi8(count, level[3]);
66*77c1e3ccSAndroid Build Coastguard Worker count = _mm_add_epi8(count, level[4]);
67*77c1e3ccSAndroid Build Coastguard Worker count = _mm_avg_epu8(count, _mm_setzero_si128());
68*77c1e3ccSAndroid Build Coastguard Worker count = _mm_min_epu8(count, const_4);
69*77c1e3ccSAndroid Build Coastguard Worker return count;
70*77c1e3ccSAndroid Build Coastguard Worker }
71*77c1e3ccSAndroid Build Coastguard Worker
get_4_nz_map_contexts_2d(const uint8_t * levels,const int width,const ptrdiff_t * const offsets,int8_t * const coeff_contexts)72*77c1e3ccSAndroid Build Coastguard Worker static inline void get_4_nz_map_contexts_2d(const uint8_t *levels,
73*77c1e3ccSAndroid Build Coastguard Worker const int width,
74*77c1e3ccSAndroid Build Coastguard Worker const ptrdiff_t *const offsets,
75*77c1e3ccSAndroid Build Coastguard Worker int8_t *const coeff_contexts) {
76*77c1e3ccSAndroid Build Coastguard Worker const int stride = 4 + TX_PAD_HOR;
77*77c1e3ccSAndroid Build Coastguard Worker const __m128i pos_to_offset_large = _mm_set1_epi8(21);
78*77c1e3ccSAndroid Build Coastguard Worker __m128i pos_to_offset =
79*77c1e3ccSAndroid Build Coastguard Worker (width == 4)
80*77c1e3ccSAndroid Build Coastguard Worker ? _mm_setr_epi8(0, 1, 6, 6, 1, 6, 6, 21, 6, 6, 21, 21, 6, 21, 21, 21)
81*77c1e3ccSAndroid Build Coastguard Worker : _mm_setr_epi8(0, 16, 16, 16, 16, 16, 16, 16, 6, 6, 21, 21, 6, 21,
82*77c1e3ccSAndroid Build Coastguard Worker 21, 21);
83*77c1e3ccSAndroid Build Coastguard Worker __m128i count;
84*77c1e3ccSAndroid Build Coastguard Worker __m128i level[5];
85*77c1e3ccSAndroid Build Coastguard Worker int8_t *cc = coeff_contexts;
86*77c1e3ccSAndroid Build Coastguard Worker int col = width;
87*77c1e3ccSAndroid Build Coastguard Worker
88*77c1e3ccSAndroid Build Coastguard Worker assert(!(width % 4));
89*77c1e3ccSAndroid Build Coastguard Worker
90*77c1e3ccSAndroid Build Coastguard Worker do {
91*77c1e3ccSAndroid Build Coastguard Worker load_levels_4x4x5_sse2(levels, stride, offsets, level);
92*77c1e3ccSAndroid Build Coastguard Worker count = get_coeff_contexts_kernel_sse2(level);
93*77c1e3ccSAndroid Build Coastguard Worker count = _mm_add_epi8(count, pos_to_offset);
94*77c1e3ccSAndroid Build Coastguard Worker _mm_store_si128((__m128i *)cc, count);
95*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset = pos_to_offset_large;
96*77c1e3ccSAndroid Build Coastguard Worker levels += 4 * stride;
97*77c1e3ccSAndroid Build Coastguard Worker cc += 16;
98*77c1e3ccSAndroid Build Coastguard Worker col -= 4;
99*77c1e3ccSAndroid Build Coastguard Worker } while (col);
100*77c1e3ccSAndroid Build Coastguard Worker
101*77c1e3ccSAndroid Build Coastguard Worker coeff_contexts[0] = 0;
102*77c1e3ccSAndroid Build Coastguard Worker }
103*77c1e3ccSAndroid Build Coastguard Worker
get_4_nz_map_contexts_ver(const uint8_t * levels,const int width,const ptrdiff_t * const offsets,int8_t * coeff_contexts)104*77c1e3ccSAndroid Build Coastguard Worker static inline void get_4_nz_map_contexts_ver(const uint8_t *levels,
105*77c1e3ccSAndroid Build Coastguard Worker const int width,
106*77c1e3ccSAndroid Build Coastguard Worker const ptrdiff_t *const offsets,
107*77c1e3ccSAndroid Build Coastguard Worker int8_t *coeff_contexts) {
108*77c1e3ccSAndroid Build Coastguard Worker const int stride = 4 + TX_PAD_HOR;
109*77c1e3ccSAndroid Build Coastguard Worker const __m128i pos_to_offset =
110*77c1e3ccSAndroid Build Coastguard Worker _mm_setr_epi8(SIG_COEF_CONTEXTS_2D + 0, SIG_COEF_CONTEXTS_2D + 5,
111*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 10, SIG_COEF_CONTEXTS_2D + 10,
112*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 0, SIG_COEF_CONTEXTS_2D + 5,
113*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 10, SIG_COEF_CONTEXTS_2D + 10,
114*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 0, SIG_COEF_CONTEXTS_2D + 5,
115*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 10, SIG_COEF_CONTEXTS_2D + 10,
116*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 0, SIG_COEF_CONTEXTS_2D + 5,
117*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 10, SIG_COEF_CONTEXTS_2D + 10);
118*77c1e3ccSAndroid Build Coastguard Worker __m128i count;
119*77c1e3ccSAndroid Build Coastguard Worker __m128i level[5];
120*77c1e3ccSAndroid Build Coastguard Worker int col = width;
121*77c1e3ccSAndroid Build Coastguard Worker
122*77c1e3ccSAndroid Build Coastguard Worker assert(!(width % 4));
123*77c1e3ccSAndroid Build Coastguard Worker
124*77c1e3ccSAndroid Build Coastguard Worker do {
125*77c1e3ccSAndroid Build Coastguard Worker load_levels_4x4x5_sse2(levels, stride, offsets, level);
126*77c1e3ccSAndroid Build Coastguard Worker count = get_coeff_contexts_kernel_sse2(level);
127*77c1e3ccSAndroid Build Coastguard Worker count = _mm_add_epi8(count, pos_to_offset);
128*77c1e3ccSAndroid Build Coastguard Worker _mm_store_si128((__m128i *)coeff_contexts, count);
129*77c1e3ccSAndroid Build Coastguard Worker levels += 4 * stride;
130*77c1e3ccSAndroid Build Coastguard Worker coeff_contexts += 16;
131*77c1e3ccSAndroid Build Coastguard Worker col -= 4;
132*77c1e3ccSAndroid Build Coastguard Worker } while (col);
133*77c1e3ccSAndroid Build Coastguard Worker }
134*77c1e3ccSAndroid Build Coastguard Worker
get_4_nz_map_contexts_hor(const uint8_t * levels,const int width,const ptrdiff_t * const offsets,int8_t * coeff_contexts)135*77c1e3ccSAndroid Build Coastguard Worker static inline void get_4_nz_map_contexts_hor(const uint8_t *levels,
136*77c1e3ccSAndroid Build Coastguard Worker const int width,
137*77c1e3ccSAndroid Build Coastguard Worker const ptrdiff_t *const offsets,
138*77c1e3ccSAndroid Build Coastguard Worker int8_t *coeff_contexts) {
139*77c1e3ccSAndroid Build Coastguard Worker const int stride = 4 + TX_PAD_HOR;
140*77c1e3ccSAndroid Build Coastguard Worker const __m128i pos_to_offset_large = _mm_set1_epi8(SIG_COEF_CONTEXTS_2D + 10);
141*77c1e3ccSAndroid Build Coastguard Worker __m128i pos_to_offset =
142*77c1e3ccSAndroid Build Coastguard Worker _mm_setr_epi8(SIG_COEF_CONTEXTS_2D + 0, SIG_COEF_CONTEXTS_2D + 0,
143*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 0, SIG_COEF_CONTEXTS_2D + 0,
144*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 5, SIG_COEF_CONTEXTS_2D + 5,
145*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 5, SIG_COEF_CONTEXTS_2D + 5,
146*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 10, SIG_COEF_CONTEXTS_2D + 10,
147*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 10, SIG_COEF_CONTEXTS_2D + 10,
148*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 10, SIG_COEF_CONTEXTS_2D + 10,
149*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 10, SIG_COEF_CONTEXTS_2D + 10);
150*77c1e3ccSAndroid Build Coastguard Worker __m128i count;
151*77c1e3ccSAndroid Build Coastguard Worker __m128i level[5];
152*77c1e3ccSAndroid Build Coastguard Worker int col = width;
153*77c1e3ccSAndroid Build Coastguard Worker
154*77c1e3ccSAndroid Build Coastguard Worker assert(!(width % 4));
155*77c1e3ccSAndroid Build Coastguard Worker
156*77c1e3ccSAndroid Build Coastguard Worker do {
157*77c1e3ccSAndroid Build Coastguard Worker load_levels_4x4x5_sse2(levels, stride, offsets, level);
158*77c1e3ccSAndroid Build Coastguard Worker count = get_coeff_contexts_kernel_sse2(level);
159*77c1e3ccSAndroid Build Coastguard Worker count = _mm_add_epi8(count, pos_to_offset);
160*77c1e3ccSAndroid Build Coastguard Worker _mm_store_si128((__m128i *)coeff_contexts, count);
161*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset = pos_to_offset_large;
162*77c1e3ccSAndroid Build Coastguard Worker levels += 4 * stride;
163*77c1e3ccSAndroid Build Coastguard Worker coeff_contexts += 16;
164*77c1e3ccSAndroid Build Coastguard Worker col -= 4;
165*77c1e3ccSAndroid Build Coastguard Worker } while (col);
166*77c1e3ccSAndroid Build Coastguard Worker }
167*77c1e3ccSAndroid Build Coastguard Worker
get_8_coeff_contexts_2d(const uint8_t * levels,const int width,const ptrdiff_t * const offsets,int8_t * coeff_contexts)168*77c1e3ccSAndroid Build Coastguard Worker static inline void get_8_coeff_contexts_2d(const uint8_t *levels,
169*77c1e3ccSAndroid Build Coastguard Worker const int width,
170*77c1e3ccSAndroid Build Coastguard Worker const ptrdiff_t *const offsets,
171*77c1e3ccSAndroid Build Coastguard Worker int8_t *coeff_contexts) {
172*77c1e3ccSAndroid Build Coastguard Worker const int stride = 8 + TX_PAD_HOR;
173*77c1e3ccSAndroid Build Coastguard Worker int8_t *cc = coeff_contexts;
174*77c1e3ccSAndroid Build Coastguard Worker int col = width;
175*77c1e3ccSAndroid Build Coastguard Worker __m128i count;
176*77c1e3ccSAndroid Build Coastguard Worker __m128i level[5];
177*77c1e3ccSAndroid Build Coastguard Worker __m128i pos_to_offset[3];
178*77c1e3ccSAndroid Build Coastguard Worker
179*77c1e3ccSAndroid Build Coastguard Worker assert(!(width % 2));
180*77c1e3ccSAndroid Build Coastguard Worker
181*77c1e3ccSAndroid Build Coastguard Worker if (width == 8) {
182*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset[0] =
183*77c1e3ccSAndroid Build Coastguard Worker _mm_setr_epi8(0, 1, 6, 6, 21, 21, 21, 21, 1, 6, 6, 21, 21, 21, 21, 21);
184*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset[1] = _mm_setr_epi8(6, 6, 21, 21, 21, 21, 21, 21, 6, 21, 21,
185*77c1e3ccSAndroid Build Coastguard Worker 21, 21, 21, 21, 21);
186*77c1e3ccSAndroid Build Coastguard Worker } else if (width < 8) {
187*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset[0] = _mm_setr_epi8(0, 11, 6, 6, 21, 21, 21, 21, 11, 11, 6, 21,
188*77c1e3ccSAndroid Build Coastguard Worker 21, 21, 21, 21);
189*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset[1] = _mm_setr_epi8(11, 11, 21, 21, 21, 21, 21, 21, 11, 11, 21,
190*77c1e3ccSAndroid Build Coastguard Worker 21, 21, 21, 21, 21);
191*77c1e3ccSAndroid Build Coastguard Worker } else {
192*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset[0] = _mm_setr_epi8(0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
193*77c1e3ccSAndroid Build Coastguard Worker 16, 16, 16, 16, 16);
194*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset[1] = _mm_setr_epi8(6, 6, 21, 21, 21, 21, 21, 21, 6, 21, 21,
195*77c1e3ccSAndroid Build Coastguard Worker 21, 21, 21, 21, 21);
196*77c1e3ccSAndroid Build Coastguard Worker }
197*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset[2] = _mm_set1_epi8(21);
198*77c1e3ccSAndroid Build Coastguard Worker
199*77c1e3ccSAndroid Build Coastguard Worker do {
200*77c1e3ccSAndroid Build Coastguard Worker load_levels_8x2x5_sse2(levels, stride, offsets, level);
201*77c1e3ccSAndroid Build Coastguard Worker count = get_coeff_contexts_kernel_sse2(level);
202*77c1e3ccSAndroid Build Coastguard Worker count = _mm_add_epi8(count, pos_to_offset[0]);
203*77c1e3ccSAndroid Build Coastguard Worker _mm_store_si128((__m128i *)cc, count);
204*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset[0] = pos_to_offset[1];
205*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset[1] = pos_to_offset[2];
206*77c1e3ccSAndroid Build Coastguard Worker levels += 2 * stride;
207*77c1e3ccSAndroid Build Coastguard Worker cc += 16;
208*77c1e3ccSAndroid Build Coastguard Worker col -= 2;
209*77c1e3ccSAndroid Build Coastguard Worker } while (col);
210*77c1e3ccSAndroid Build Coastguard Worker
211*77c1e3ccSAndroid Build Coastguard Worker coeff_contexts[0] = 0;
212*77c1e3ccSAndroid Build Coastguard Worker }
213*77c1e3ccSAndroid Build Coastguard Worker
get_8_coeff_contexts_ver(const uint8_t * levels,const int width,const ptrdiff_t * const offsets,int8_t * coeff_contexts)214*77c1e3ccSAndroid Build Coastguard Worker static inline void get_8_coeff_contexts_ver(const uint8_t *levels,
215*77c1e3ccSAndroid Build Coastguard Worker const int width,
216*77c1e3ccSAndroid Build Coastguard Worker const ptrdiff_t *const offsets,
217*77c1e3ccSAndroid Build Coastguard Worker int8_t *coeff_contexts) {
218*77c1e3ccSAndroid Build Coastguard Worker const int stride = 8 + TX_PAD_HOR;
219*77c1e3ccSAndroid Build Coastguard Worker const __m128i pos_to_offset =
220*77c1e3ccSAndroid Build Coastguard Worker _mm_setr_epi8(SIG_COEF_CONTEXTS_2D + 0, SIG_COEF_CONTEXTS_2D + 5,
221*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 10, SIG_COEF_CONTEXTS_2D + 10,
222*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 10, SIG_COEF_CONTEXTS_2D + 10,
223*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 10, SIG_COEF_CONTEXTS_2D + 10,
224*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 0, SIG_COEF_CONTEXTS_2D + 5,
225*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 10, SIG_COEF_CONTEXTS_2D + 10,
226*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 10, SIG_COEF_CONTEXTS_2D + 10,
227*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 10, SIG_COEF_CONTEXTS_2D + 10);
228*77c1e3ccSAndroid Build Coastguard Worker int col = width;
229*77c1e3ccSAndroid Build Coastguard Worker __m128i count;
230*77c1e3ccSAndroid Build Coastguard Worker __m128i level[5];
231*77c1e3ccSAndroid Build Coastguard Worker
232*77c1e3ccSAndroid Build Coastguard Worker assert(!(width % 2));
233*77c1e3ccSAndroid Build Coastguard Worker
234*77c1e3ccSAndroid Build Coastguard Worker do {
235*77c1e3ccSAndroid Build Coastguard Worker load_levels_8x2x5_sse2(levels, stride, offsets, level);
236*77c1e3ccSAndroid Build Coastguard Worker count = get_coeff_contexts_kernel_sse2(level);
237*77c1e3ccSAndroid Build Coastguard Worker count = _mm_add_epi8(count, pos_to_offset);
238*77c1e3ccSAndroid Build Coastguard Worker _mm_store_si128((__m128i *)coeff_contexts, count);
239*77c1e3ccSAndroid Build Coastguard Worker levels += 2 * stride;
240*77c1e3ccSAndroid Build Coastguard Worker coeff_contexts += 16;
241*77c1e3ccSAndroid Build Coastguard Worker col -= 2;
242*77c1e3ccSAndroid Build Coastguard Worker } while (col);
243*77c1e3ccSAndroid Build Coastguard Worker }
244*77c1e3ccSAndroid Build Coastguard Worker
get_8_coeff_contexts_hor(const uint8_t * levels,const int width,const ptrdiff_t * const offsets,int8_t * coeff_contexts)245*77c1e3ccSAndroid Build Coastguard Worker static inline void get_8_coeff_contexts_hor(const uint8_t *levels,
246*77c1e3ccSAndroid Build Coastguard Worker const int width,
247*77c1e3ccSAndroid Build Coastguard Worker const ptrdiff_t *const offsets,
248*77c1e3ccSAndroid Build Coastguard Worker int8_t *coeff_contexts) {
249*77c1e3ccSAndroid Build Coastguard Worker const int stride = 8 + TX_PAD_HOR;
250*77c1e3ccSAndroid Build Coastguard Worker const __m128i pos_to_offset_large = _mm_set1_epi8(SIG_COEF_CONTEXTS_2D + 10);
251*77c1e3ccSAndroid Build Coastguard Worker __m128i pos_to_offset =
252*77c1e3ccSAndroid Build Coastguard Worker _mm_setr_epi8(SIG_COEF_CONTEXTS_2D + 0, SIG_COEF_CONTEXTS_2D + 0,
253*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 0, SIG_COEF_CONTEXTS_2D + 0,
254*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 0, SIG_COEF_CONTEXTS_2D + 0,
255*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 0, SIG_COEF_CONTEXTS_2D + 0,
256*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 5, SIG_COEF_CONTEXTS_2D + 5,
257*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 5, SIG_COEF_CONTEXTS_2D + 5,
258*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 5, SIG_COEF_CONTEXTS_2D + 5,
259*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 5, SIG_COEF_CONTEXTS_2D + 5);
260*77c1e3ccSAndroid Build Coastguard Worker int col = width;
261*77c1e3ccSAndroid Build Coastguard Worker __m128i count;
262*77c1e3ccSAndroid Build Coastguard Worker __m128i level[5];
263*77c1e3ccSAndroid Build Coastguard Worker
264*77c1e3ccSAndroid Build Coastguard Worker assert(!(width % 2));
265*77c1e3ccSAndroid Build Coastguard Worker
266*77c1e3ccSAndroid Build Coastguard Worker do {
267*77c1e3ccSAndroid Build Coastguard Worker load_levels_8x2x5_sse2(levels, stride, offsets, level);
268*77c1e3ccSAndroid Build Coastguard Worker count = get_coeff_contexts_kernel_sse2(level);
269*77c1e3ccSAndroid Build Coastguard Worker count = _mm_add_epi8(count, pos_to_offset);
270*77c1e3ccSAndroid Build Coastguard Worker _mm_store_si128((__m128i *)coeff_contexts, count);
271*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset = pos_to_offset_large;
272*77c1e3ccSAndroid Build Coastguard Worker levels += 2 * stride;
273*77c1e3ccSAndroid Build Coastguard Worker coeff_contexts += 16;
274*77c1e3ccSAndroid Build Coastguard Worker col -= 2;
275*77c1e3ccSAndroid Build Coastguard Worker } while (col);
276*77c1e3ccSAndroid Build Coastguard Worker }
277*77c1e3ccSAndroid Build Coastguard Worker
get_16n_coeff_contexts_2d(const uint8_t * levels,const int real_width,const int real_height,const int width,const int height,const ptrdiff_t * const offsets,int8_t * coeff_contexts)278*77c1e3ccSAndroid Build Coastguard Worker static inline void get_16n_coeff_contexts_2d(const uint8_t *levels,
279*77c1e3ccSAndroid Build Coastguard Worker const int real_width,
280*77c1e3ccSAndroid Build Coastguard Worker const int real_height,
281*77c1e3ccSAndroid Build Coastguard Worker const int width, const int height,
282*77c1e3ccSAndroid Build Coastguard Worker const ptrdiff_t *const offsets,
283*77c1e3ccSAndroid Build Coastguard Worker int8_t *coeff_contexts) {
284*77c1e3ccSAndroid Build Coastguard Worker const int stride = height + TX_PAD_HOR;
285*77c1e3ccSAndroid Build Coastguard Worker int8_t *cc = coeff_contexts;
286*77c1e3ccSAndroid Build Coastguard Worker int col = width;
287*77c1e3ccSAndroid Build Coastguard Worker __m128i pos_to_offset[5];
288*77c1e3ccSAndroid Build Coastguard Worker __m128i pos_to_offset_large[3];
289*77c1e3ccSAndroid Build Coastguard Worker __m128i count;
290*77c1e3ccSAndroid Build Coastguard Worker __m128i level[5];
291*77c1e3ccSAndroid Build Coastguard Worker
292*77c1e3ccSAndroid Build Coastguard Worker assert(!(height % 16));
293*77c1e3ccSAndroid Build Coastguard Worker
294*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset_large[2] = _mm_set1_epi8(21);
295*77c1e3ccSAndroid Build Coastguard Worker if (real_width == real_height) {
296*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset[0] = _mm_setr_epi8(0, 1, 6, 6, 21, 21, 21, 21, 21, 21, 21, 21,
297*77c1e3ccSAndroid Build Coastguard Worker 21, 21, 21, 21);
298*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset[1] = _mm_setr_epi8(1, 6, 6, 21, 21, 21, 21, 21, 21, 21, 21,
299*77c1e3ccSAndroid Build Coastguard Worker 21, 21, 21, 21, 21);
300*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset[2] = _mm_setr_epi8(6, 6, 21, 21, 21, 21, 21, 21, 21, 21, 21,
301*77c1e3ccSAndroid Build Coastguard Worker 21, 21, 21, 21, 21);
302*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset[3] = _mm_setr_epi8(6, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
303*77c1e3ccSAndroid Build Coastguard Worker 21, 21, 21, 21, 21);
304*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset[4] = pos_to_offset_large[0] = pos_to_offset_large[1] =
305*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset_large[2];
306*77c1e3ccSAndroid Build Coastguard Worker } else if (real_width < real_height) {
307*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset[0] = _mm_setr_epi8(0, 11, 6, 6, 21, 21, 21, 21, 21, 21, 21,
308*77c1e3ccSAndroid Build Coastguard Worker 21, 21, 21, 21, 21);
309*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset[1] = _mm_setr_epi8(11, 11, 6, 21, 21, 21, 21, 21, 21, 21, 21,
310*77c1e3ccSAndroid Build Coastguard Worker 21, 21, 21, 21, 21);
311*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset[2] = pos_to_offset[3] = pos_to_offset[4] = _mm_setr_epi8(
312*77c1e3ccSAndroid Build Coastguard Worker 11, 11, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21);
313*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset_large[0] = pos_to_offset_large[1] = pos_to_offset_large[2];
314*77c1e3ccSAndroid Build Coastguard Worker } else { // real_width > real_height
315*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset[0] = pos_to_offset[1] = _mm_setr_epi8(
316*77c1e3ccSAndroid Build Coastguard Worker 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16);
317*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset[2] = _mm_setr_epi8(6, 6, 21, 21, 21, 21, 21, 21, 21, 21, 21,
318*77c1e3ccSAndroid Build Coastguard Worker 21, 21, 21, 21, 21);
319*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset[3] = _mm_setr_epi8(6, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
320*77c1e3ccSAndroid Build Coastguard Worker 21, 21, 21, 21, 21);
321*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset[4] = pos_to_offset_large[2];
322*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset_large[0] = pos_to_offset_large[1] = _mm_set1_epi8(16);
323*77c1e3ccSAndroid Build Coastguard Worker }
324*77c1e3ccSAndroid Build Coastguard Worker
325*77c1e3ccSAndroid Build Coastguard Worker do {
326*77c1e3ccSAndroid Build Coastguard Worker int h = height;
327*77c1e3ccSAndroid Build Coastguard Worker
328*77c1e3ccSAndroid Build Coastguard Worker do {
329*77c1e3ccSAndroid Build Coastguard Worker load_levels_16x1x5_sse2(levels, stride, offsets, level);
330*77c1e3ccSAndroid Build Coastguard Worker count = get_coeff_contexts_kernel_sse2(level);
331*77c1e3ccSAndroid Build Coastguard Worker count = _mm_add_epi8(count, pos_to_offset[0]);
332*77c1e3ccSAndroid Build Coastguard Worker _mm_store_si128((__m128i *)cc, count);
333*77c1e3ccSAndroid Build Coastguard Worker levels += 16;
334*77c1e3ccSAndroid Build Coastguard Worker cc += 16;
335*77c1e3ccSAndroid Build Coastguard Worker h -= 16;
336*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset[0] = pos_to_offset_large[0];
337*77c1e3ccSAndroid Build Coastguard Worker } while (h);
338*77c1e3ccSAndroid Build Coastguard Worker
339*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset[0] = pos_to_offset[1];
340*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset[1] = pos_to_offset[2];
341*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset[2] = pos_to_offset[3];
342*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset[3] = pos_to_offset[4];
343*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset_large[0] = pos_to_offset_large[1];
344*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset_large[1] = pos_to_offset_large[2];
345*77c1e3ccSAndroid Build Coastguard Worker levels += TX_PAD_HOR;
346*77c1e3ccSAndroid Build Coastguard Worker } while (--col);
347*77c1e3ccSAndroid Build Coastguard Worker
348*77c1e3ccSAndroid Build Coastguard Worker coeff_contexts[0] = 0;
349*77c1e3ccSAndroid Build Coastguard Worker }
350*77c1e3ccSAndroid Build Coastguard Worker
get_16n_coeff_contexts_ver(const uint8_t * levels,const int width,const int height,const ptrdiff_t * const offsets,int8_t * coeff_contexts)351*77c1e3ccSAndroid Build Coastguard Worker static inline void get_16n_coeff_contexts_ver(const uint8_t *levels,
352*77c1e3ccSAndroid Build Coastguard Worker const int width, const int height,
353*77c1e3ccSAndroid Build Coastguard Worker const ptrdiff_t *const offsets,
354*77c1e3ccSAndroid Build Coastguard Worker int8_t *coeff_contexts) {
355*77c1e3ccSAndroid Build Coastguard Worker const int stride = height + TX_PAD_HOR;
356*77c1e3ccSAndroid Build Coastguard Worker const __m128i pos_to_offset_large =
357*77c1e3ccSAndroid Build Coastguard Worker _mm_setr_epi8(SIG_COEF_CONTEXTS_2D + 10, SIG_COEF_CONTEXTS_2D + 10,
358*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 10, SIG_COEF_CONTEXTS_2D + 10,
359*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 10, SIG_COEF_CONTEXTS_2D + 10,
360*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 10, SIG_COEF_CONTEXTS_2D + 10,
361*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 10, SIG_COEF_CONTEXTS_2D + 10,
362*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 10, SIG_COEF_CONTEXTS_2D + 10,
363*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 10, SIG_COEF_CONTEXTS_2D + 10,
364*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 10, SIG_COEF_CONTEXTS_2D + 10);
365*77c1e3ccSAndroid Build Coastguard Worker __m128i count;
366*77c1e3ccSAndroid Build Coastguard Worker __m128i level[5];
367*77c1e3ccSAndroid Build Coastguard Worker int col = width;
368*77c1e3ccSAndroid Build Coastguard Worker
369*77c1e3ccSAndroid Build Coastguard Worker assert(!(height % 16));
370*77c1e3ccSAndroid Build Coastguard Worker
371*77c1e3ccSAndroid Build Coastguard Worker do {
372*77c1e3ccSAndroid Build Coastguard Worker __m128i pos_to_offset =
373*77c1e3ccSAndroid Build Coastguard Worker _mm_setr_epi8(SIG_COEF_CONTEXTS_2D + 0, SIG_COEF_CONTEXTS_2D + 5,
374*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 10, SIG_COEF_CONTEXTS_2D + 10,
375*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 10, SIG_COEF_CONTEXTS_2D + 10,
376*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 10, SIG_COEF_CONTEXTS_2D + 10,
377*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 10, SIG_COEF_CONTEXTS_2D + 10,
378*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 10, SIG_COEF_CONTEXTS_2D + 10,
379*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 10, SIG_COEF_CONTEXTS_2D + 10,
380*77c1e3ccSAndroid Build Coastguard Worker SIG_COEF_CONTEXTS_2D + 10, SIG_COEF_CONTEXTS_2D + 10);
381*77c1e3ccSAndroid Build Coastguard Worker int h = height;
382*77c1e3ccSAndroid Build Coastguard Worker
383*77c1e3ccSAndroid Build Coastguard Worker do {
384*77c1e3ccSAndroid Build Coastguard Worker load_levels_16x1x5_sse2(levels, stride, offsets, level);
385*77c1e3ccSAndroid Build Coastguard Worker count = get_coeff_contexts_kernel_sse2(level);
386*77c1e3ccSAndroid Build Coastguard Worker count = _mm_add_epi8(count, pos_to_offset);
387*77c1e3ccSAndroid Build Coastguard Worker _mm_store_si128((__m128i *)coeff_contexts, count);
388*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset = pos_to_offset_large;
389*77c1e3ccSAndroid Build Coastguard Worker levels += 16;
390*77c1e3ccSAndroid Build Coastguard Worker coeff_contexts += 16;
391*77c1e3ccSAndroid Build Coastguard Worker h -= 16;
392*77c1e3ccSAndroid Build Coastguard Worker } while (h);
393*77c1e3ccSAndroid Build Coastguard Worker
394*77c1e3ccSAndroid Build Coastguard Worker levels += TX_PAD_HOR;
395*77c1e3ccSAndroid Build Coastguard Worker } while (--col);
396*77c1e3ccSAndroid Build Coastguard Worker }
397*77c1e3ccSAndroid Build Coastguard Worker
get_16n_coeff_contexts_hor(const uint8_t * levels,const int width,const int height,const ptrdiff_t * const offsets,int8_t * coeff_contexts)398*77c1e3ccSAndroid Build Coastguard Worker static inline void get_16n_coeff_contexts_hor(const uint8_t *levels,
399*77c1e3ccSAndroid Build Coastguard Worker const int width, const int height,
400*77c1e3ccSAndroid Build Coastguard Worker const ptrdiff_t *const offsets,
401*77c1e3ccSAndroid Build Coastguard Worker int8_t *coeff_contexts) {
402*77c1e3ccSAndroid Build Coastguard Worker const int stride = height + TX_PAD_HOR;
403*77c1e3ccSAndroid Build Coastguard Worker __m128i pos_to_offset[3];
404*77c1e3ccSAndroid Build Coastguard Worker __m128i count;
405*77c1e3ccSAndroid Build Coastguard Worker __m128i level[5];
406*77c1e3ccSAndroid Build Coastguard Worker int col = width;
407*77c1e3ccSAndroid Build Coastguard Worker
408*77c1e3ccSAndroid Build Coastguard Worker assert(!(height % 16));
409*77c1e3ccSAndroid Build Coastguard Worker
410*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset[0] = _mm_set1_epi8(SIG_COEF_CONTEXTS_2D + 0);
411*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset[1] = _mm_set1_epi8(SIG_COEF_CONTEXTS_2D + 5);
412*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset[2] = _mm_set1_epi8(SIG_COEF_CONTEXTS_2D + 10);
413*77c1e3ccSAndroid Build Coastguard Worker
414*77c1e3ccSAndroid Build Coastguard Worker do {
415*77c1e3ccSAndroid Build Coastguard Worker int h = height;
416*77c1e3ccSAndroid Build Coastguard Worker
417*77c1e3ccSAndroid Build Coastguard Worker do {
418*77c1e3ccSAndroid Build Coastguard Worker load_levels_16x1x5_sse2(levels, stride, offsets, level);
419*77c1e3ccSAndroid Build Coastguard Worker count = get_coeff_contexts_kernel_sse2(level);
420*77c1e3ccSAndroid Build Coastguard Worker count = _mm_add_epi8(count, pos_to_offset[0]);
421*77c1e3ccSAndroid Build Coastguard Worker _mm_store_si128((__m128i *)coeff_contexts, count);
422*77c1e3ccSAndroid Build Coastguard Worker levels += 16;
423*77c1e3ccSAndroid Build Coastguard Worker coeff_contexts += 16;
424*77c1e3ccSAndroid Build Coastguard Worker h -= 16;
425*77c1e3ccSAndroid Build Coastguard Worker } while (h);
426*77c1e3ccSAndroid Build Coastguard Worker
427*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset[0] = pos_to_offset[1];
428*77c1e3ccSAndroid Build Coastguard Worker pos_to_offset[1] = pos_to_offset[2];
429*77c1e3ccSAndroid Build Coastguard Worker levels += TX_PAD_HOR;
430*77c1e3ccSAndroid Build Coastguard Worker } while (--col);
431*77c1e3ccSAndroid Build Coastguard Worker }
432*77c1e3ccSAndroid Build Coastguard Worker
433*77c1e3ccSAndroid Build Coastguard Worker // Note: levels[] must be in the range [0, 127], inclusive.
av1_get_nz_map_contexts_sse2(const uint8_t * const levels,const int16_t * const scan,const uint16_t eob,const TX_SIZE tx_size,const TX_CLASS tx_class,int8_t * const coeff_contexts)434*77c1e3ccSAndroid Build Coastguard Worker void av1_get_nz_map_contexts_sse2(const uint8_t *const levels,
435*77c1e3ccSAndroid Build Coastguard Worker const int16_t *const scan, const uint16_t eob,
436*77c1e3ccSAndroid Build Coastguard Worker const TX_SIZE tx_size,
437*77c1e3ccSAndroid Build Coastguard Worker const TX_CLASS tx_class,
438*77c1e3ccSAndroid Build Coastguard Worker int8_t *const coeff_contexts) {
439*77c1e3ccSAndroid Build Coastguard Worker const int last_idx = eob - 1;
440*77c1e3ccSAndroid Build Coastguard Worker if (!last_idx) {
441*77c1e3ccSAndroid Build Coastguard Worker coeff_contexts[0] = 0;
442*77c1e3ccSAndroid Build Coastguard Worker return;
443*77c1e3ccSAndroid Build Coastguard Worker }
444*77c1e3ccSAndroid Build Coastguard Worker
445*77c1e3ccSAndroid Build Coastguard Worker const int real_width = tx_size_wide[tx_size];
446*77c1e3ccSAndroid Build Coastguard Worker const int real_height = tx_size_high[tx_size];
447*77c1e3ccSAndroid Build Coastguard Worker const int width = get_txb_wide(tx_size);
448*77c1e3ccSAndroid Build Coastguard Worker const int height = get_txb_high(tx_size);
449*77c1e3ccSAndroid Build Coastguard Worker const int stride = height + TX_PAD_HOR;
450*77c1e3ccSAndroid Build Coastguard Worker ptrdiff_t offsets[3];
451*77c1e3ccSAndroid Build Coastguard Worker
452*77c1e3ccSAndroid Build Coastguard Worker /* coeff_contexts must be 16 byte aligned. */
453*77c1e3ccSAndroid Build Coastguard Worker assert(!((intptr_t)coeff_contexts & 0xf));
454*77c1e3ccSAndroid Build Coastguard Worker
455*77c1e3ccSAndroid Build Coastguard Worker if (tx_class == TX_CLASS_2D) {
456*77c1e3ccSAndroid Build Coastguard Worker offsets[0] = 0 * stride + 2;
457*77c1e3ccSAndroid Build Coastguard Worker offsets[1] = 1 * stride + 1;
458*77c1e3ccSAndroid Build Coastguard Worker offsets[2] = 2 * stride + 0;
459*77c1e3ccSAndroid Build Coastguard Worker
460*77c1e3ccSAndroid Build Coastguard Worker if (height == 4) {
461*77c1e3ccSAndroid Build Coastguard Worker get_4_nz_map_contexts_2d(levels, width, offsets, coeff_contexts);
462*77c1e3ccSAndroid Build Coastguard Worker } else if (height == 8) {
463*77c1e3ccSAndroid Build Coastguard Worker get_8_coeff_contexts_2d(levels, width, offsets, coeff_contexts);
464*77c1e3ccSAndroid Build Coastguard Worker } else if (height == 16) {
465*77c1e3ccSAndroid Build Coastguard Worker get_16n_coeff_contexts_2d(levels, real_width, real_height, width, height,
466*77c1e3ccSAndroid Build Coastguard Worker offsets, coeff_contexts);
467*77c1e3ccSAndroid Build Coastguard Worker } else {
468*77c1e3ccSAndroid Build Coastguard Worker get_16n_coeff_contexts_2d(levels, real_width, real_height, width, height,
469*77c1e3ccSAndroid Build Coastguard Worker offsets, coeff_contexts);
470*77c1e3ccSAndroid Build Coastguard Worker }
471*77c1e3ccSAndroid Build Coastguard Worker } else if (tx_class == TX_CLASS_HORIZ) {
472*77c1e3ccSAndroid Build Coastguard Worker offsets[0] = 2 * stride;
473*77c1e3ccSAndroid Build Coastguard Worker offsets[1] = 3 * stride;
474*77c1e3ccSAndroid Build Coastguard Worker offsets[2] = 4 * stride;
475*77c1e3ccSAndroid Build Coastguard Worker if (height == 4) {
476*77c1e3ccSAndroid Build Coastguard Worker get_4_nz_map_contexts_hor(levels, width, offsets, coeff_contexts);
477*77c1e3ccSAndroid Build Coastguard Worker } else if (height == 8) {
478*77c1e3ccSAndroid Build Coastguard Worker get_8_coeff_contexts_hor(levels, width, offsets, coeff_contexts);
479*77c1e3ccSAndroid Build Coastguard Worker } else {
480*77c1e3ccSAndroid Build Coastguard Worker get_16n_coeff_contexts_hor(levels, width, height, offsets,
481*77c1e3ccSAndroid Build Coastguard Worker coeff_contexts);
482*77c1e3ccSAndroid Build Coastguard Worker }
483*77c1e3ccSAndroid Build Coastguard Worker } else { // TX_CLASS_VERT
484*77c1e3ccSAndroid Build Coastguard Worker offsets[0] = 2;
485*77c1e3ccSAndroid Build Coastguard Worker offsets[1] = 3;
486*77c1e3ccSAndroid Build Coastguard Worker offsets[2] = 4;
487*77c1e3ccSAndroid Build Coastguard Worker if (height == 4) {
488*77c1e3ccSAndroid Build Coastguard Worker get_4_nz_map_contexts_ver(levels, width, offsets, coeff_contexts);
489*77c1e3ccSAndroid Build Coastguard Worker } else if (height == 8) {
490*77c1e3ccSAndroid Build Coastguard Worker get_8_coeff_contexts_ver(levels, width, offsets, coeff_contexts);
491*77c1e3ccSAndroid Build Coastguard Worker } else {
492*77c1e3ccSAndroid Build Coastguard Worker get_16n_coeff_contexts_ver(levels, width, height, offsets,
493*77c1e3ccSAndroid Build Coastguard Worker coeff_contexts);
494*77c1e3ccSAndroid Build Coastguard Worker }
495*77c1e3ccSAndroid Build Coastguard Worker }
496*77c1e3ccSAndroid Build Coastguard Worker
497*77c1e3ccSAndroid Build Coastguard Worker const int bhl = get_txb_bhl(tx_size);
498*77c1e3ccSAndroid Build Coastguard Worker const int pos = scan[last_idx];
499*77c1e3ccSAndroid Build Coastguard Worker if (last_idx <= (width << bhl) / 8)
500*77c1e3ccSAndroid Build Coastguard Worker coeff_contexts[pos] = 1;
501*77c1e3ccSAndroid Build Coastguard Worker else if (last_idx <= (width << bhl) / 4)
502*77c1e3ccSAndroid Build Coastguard Worker coeff_contexts[pos] = 2;
503*77c1e3ccSAndroid Build Coastguard Worker else
504*77c1e3ccSAndroid Build Coastguard Worker coeff_contexts[pos] = 3;
505*77c1e3ccSAndroid Build Coastguard Worker }
506