Coverage Report

Created: 2026-07-15 06:19

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libhevc/common/x86/ihevc_deblk_ssse3_intr.c
Line
Count
Source
1
/******************************************************************************
2
*
3
* Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore
4
*
5
* Licensed under the Apache License, Version 2.0 (the "License");
6
* you may not use this file except in compliance with the License.
7
* You may obtain a copy of the License at:
8
*
9
* http://www.apache.org/licenses/LICENSE-2.0
10
*
11
* Unless required by applicable law or agreed to in writing, software
12
* distributed under the License is distributed on an "AS IS" BASIS,
13
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
* See the License for the specific language governing permissions and
15
* limitations under the License.
16
*
17
******************************************************************************/
18
/**
19
*******************************************************************************
20
* @file
21
*  ihevc_deblck_atom_intr.c
22
*
23
* @brief
24
*  Contains function definitions for deblocking filters
25
*
26
* @author
27
*  Rishab
28
*
29
* @par List of Functions:
30
*   - ihevc_deblk_luma_vert_ssse3()
31
*   - ihevc_deblk_luma_horz_ssse3()
32
*   - ihevc_deblk_chroma_vert_ssse3()
33
*   - ihevc_deblk_chroma_horz_ssse3()
34
*
35
* @remarks
36
*  None
37
*
38
*******************************************************************************
39
*/
40
#include <stdlib.h>
41
#include <stdio.h>
42
#include <assert.h>
43
#include "ihevc_typedefs.h"
44
#include "ihevc_platform_macros.h"
45
#include "ihevc_macros.h"
46
#include "ihevc_deblk.h"
47
#include "ihevc_deblk_tables.h"
48
#include "ihevc_debug.h"
49
#include "ihevc_defs.h"
50
51
#include "ihevc_tables_x86_intr.h"
52
53
#include <immintrin.h>
54
/**
55
*******************************************************************************
56
*
57
* @brief
58
*       Decision process and filtering for the luma block vertical edge.
59
*
60
* @par Description:
61
*     The decision process for the luma block vertical edge is  carried out and
62
*     an appropriate filter is applied. The  boundary filter strength, bs should
63
*     be greater than 0.  The pcm flags and the transquant bypass flags should
64
*     be  taken care of by the calling function.
65
*
66
* @param[in] pu1_src
67
*  Pointer to the src sample q(0,0)
68
*
69
* @param[in] src_strd
70
*  Source stride
71
*
72
* @param[in] bs
73
*  Boundary filter strength of q(0,0)
74
*
75
* @param[in] quant_param_p
76
*  quantization parameter of p block
77
*
78
* @param[in] quant_param_q
79
*  quantization parameter of p block
80
*
81
* @param[in] beta_offset_div2
82
*
83
*
84
* @param[in] tc_offset_div2
85
*
86
*
87
* @param[in] filter_flag_p
88
*  flag whether to filter the p block
89
*
90
* @param[in] filter_flag_q
91
*  flag whether to filter the q block
92
*
93
* @returns
94
*
95
* @remarks
96
*  None
97
*
98
*******************************************************************************
99
*/
100
101
void ihevc_deblk_luma_vert_ssse3(UWORD8 *pu1_src,
102
                                 WORD32 src_strd,
103
                                 WORD32 bs,
104
                                 WORD32 quant_param_p,
105
                                 WORD32 quant_param_q,
106
                                 WORD32 beta_offset_div2,
107
                                 WORD32 tc_offset_div2,
108
                                 WORD32 filter_flag_p,
109
                                 WORD32 filter_flag_q)
110
0
{
111
0
    WORD32 qp_luma, beta_indx, tc_indx;
112
0
    WORD32 beta, tc;
113
0
    WORD32 d, dp, dq, d_sam0, d_sam3;
114
115
0
    WORD32 d3, d0, de_0, de_1, de_2, de_3;
116
0
    WORD32 de, dep, deq;
117
0
    __m128i src_row0_8x16b, src_row1_8x16b, src_row2_8x16b, src_row3_8x16b;
118
119
120
0
    {
121
0
        __m128i src_tmp_8x16b, coef_8x16b, mask_d_result_4x32b, mask_de_result_8x16b;
122
0
        __m128i mask_16x8b, temp_coef0_8x16b, temp_coef1_8x16b;
123
124
125
126
0
        ASSERT((bs > 0) && (bs <= 3));
127
0
        ASSERT(filter_flag_p || filter_flag_q);
128
129
0
        qp_luma = (quant_param_p + quant_param_q + 1) >> 1;
130
0
        beta_indx = CLIP3(qp_luma + (beta_offset_div2 << 1), 0, 51);
131
132
        /* BS based on implementation can take value 3 if it is intra/inter egde          */
133
        /* based on BS, tc index is calcuated by adding 2 * ( bs - 1) to QP and tc_offset */
134
        /* for BS = 1 adding factor is (0*2), BS = 2 or 3 adding factor is (1*2)          */
135
        /* the above desired functionallity is achieved by doing (2*(bs>>1))              */
136
137
0
        tc_indx = CLIP3(qp_luma + (2 * (bs >> 1)) + (tc_offset_div2 << 1), 0, 53);
138
139
0
        beta = gai4_ihevc_beta_table[beta_indx];
140
0
        tc = gai4_ihevc_tc_table[tc_indx];
141
0
        if(0 == tc)
142
0
        {
143
0
            return;
144
0
        }
145
0
        src_row0_8x16b = _mm_loadl_epi64((__m128i *)(pu1_src - 4));
146
0
        src_row3_8x16b = _mm_loadl_epi64((__m128i *)((pu1_src - 4) + 3 * src_strd));
147
148
0
        coef_8x16b = _mm_load_si128((__m128i *)(coef_d));
149
0
        mask_16x8b =  _mm_load_si128((__m128i *)(shuffle_d));
150
151
0
        src_tmp_8x16b = _mm_unpacklo_epi64(src_row0_8x16b, src_row3_8x16b);
152
0
        mask_de_result_8x16b = _mm_shuffle_epi8(src_tmp_8x16b, mask_16x8b);
153
154
0
        mask_d_result_4x32b = _mm_maddubs_epi16(src_tmp_8x16b, coef_8x16b);
155
156
157
        //to get all 1's of 8 bit in (1)
158
0
        temp_coef0_8x16b = _mm_cmpeq_epi16(src_tmp_8x16b, src_tmp_8x16b);
159
0
        temp_coef1_8x16b = _mm_srli_epi16(temp_coef0_8x16b, 15);
160
        //accumulating values foe dp3 dq3 , dp0 dq0 values
161
0
        mask_d_result_4x32b = _mm_madd_epi16(mask_d_result_4x32b, temp_coef1_8x16b);
162
163
0
        temp_coef1_8x16b = _mm_packus_epi16(temp_coef1_8x16b, temp_coef1_8x16b);
164
        // to get all 1,-1 sets of 16 bits in (0)
165
0
        temp_coef0_8x16b = _mm_unpacklo_epi8(temp_coef0_8x16b, temp_coef1_8x16b);
166
        //q33-q30,p33-p30,q03-q00,p03-p00,0,q30-p30,0,q00-p00
167
0
        mask_de_result_8x16b = _mm_maddubs_epi16(mask_de_result_8x16b, temp_coef0_8x16b);
168
        //to get 16 bit 1's
169
0
        temp_coef0_8x16b = _mm_srli_epi16(temp_coef1_8x16b, 8);
170
171
172
        // dq3 dp3 dq0 dp0
173
0
        mask_d_result_4x32b = _mm_abs_epi32(mask_d_result_4x32b);
174
0
        mask_16x8b = _mm_shuffle_epi32(mask_d_result_4x32b, 0xec);
175
0
        mask_d_result_4x32b = _mm_shuffle_epi32(mask_d_result_4x32b, 0x49);
176
        // dq dp d3 d0
177
0
        mask_d_result_4x32b = _mm_add_epi32(mask_d_result_4x32b, mask_16x8b);
178
        //|q33-q30|,|p33-p30|,|q03-q00|,|p03-p00|,0,|q30-p30|,0,|q00-p00|
179
0
        mask_de_result_8x16b = _mm_abs_epi16(mask_de_result_8x16b);
180
        //|q33-q30|+|p33-p30|,|q03-q00|+|p03-p00|,0+|q30-p30|,0+|q00-p00|
181
0
        mask_de_result_8x16b = _mm_madd_epi16(mask_de_result_8x16b, temp_coef0_8x16b);
182
183
        ///store back in a single variable
184
0
        temp_coef0_8x16b = _mm_srli_si128(mask_d_result_4x32b, 4);
185
0
        temp_coef1_8x16b = _mm_srli_si128(mask_d_result_4x32b, 8);
186
0
        mask_16x8b = _mm_srli_si128(mask_d_result_4x32b, 12);
187
188
0
        d0 = _mm_cvtsi128_si32(mask_d_result_4x32b);
189
0
        d3 = _mm_cvtsi128_si32(temp_coef0_8x16b);
190
0
        dp = _mm_cvtsi128_si32(temp_coef1_8x16b);
191
0
        dq = _mm_cvtsi128_si32(mask_16x8b);
192
        //getting d
193
0
        d = d0 + d3;
194
195
        ///store back in a single variable
196
0
        temp_coef0_8x16b = _mm_srli_si128(mask_de_result_8x16b, 4);
197
0
        temp_coef1_8x16b = _mm_srli_si128(mask_de_result_8x16b, 8);
198
0
        mask_16x8b = _mm_srli_si128(mask_de_result_8x16b, 12);
199
200
0
        de_0 = _mm_cvtsi128_si32(mask_de_result_8x16b);
201
0
        de_1 = _mm_cvtsi128_si32(temp_coef0_8x16b);
202
0
        de_2 = _mm_cvtsi128_si32(temp_coef1_8x16b);
203
0
        de_3 = _mm_cvtsi128_si32(mask_16x8b);
204
205
0
        de = 0;
206
0
        dep = 0;
207
0
        deq = 0;
208
0
        if(d < beta)
209
0
        {
210
0
            d_sam0 = 0;
211
0
            if((2 * d0 < (beta >> 2))
212
0
                            && (de_2 < (beta >> 3))
213
0
                            && (de_0 < ((5 * tc + 1) >> 1)))
214
0
            {
215
0
                d_sam0 = 1;
216
0
            }
217
218
0
            d_sam3 = 0;
219
0
            if((2 * d3 < (beta >> 2))
220
0
                            && (de_3 < (beta >> 3))
221
0
                            && de_1 < ((5 * tc + 1) >> 1))
222
0
            {
223
0
                d_sam3 = 1;
224
0
            }
225
226
0
            de = (d_sam0 & d_sam3) + 1;
227
0
            dep = (dp < (beta + (beta >> 1)) >> 3) ? 1 : 0;
228
0
            deq = (dq < (beta + (beta >> 1)) >> 3) ? 1 : 0;
229
0
            if(tc <= 1)
230
0
            {
231
0
                dep = 0;
232
0
                deq = 0;
233
0
            }
234
0
        }
235
236
0
    }
237
238
0
    if(de != 0)
239
0
    {
240
241
242
0
        src_row1_8x16b = _mm_loadl_epi64((__m128i *)((pu1_src - 4) + src_strd));
243
0
        src_row2_8x16b = _mm_loadl_epi64((__m128i *)((pu1_src - 4) + 2 * src_strd));
244
245
0
        if(de == 2)
246
0
        {
247
0
            __m128i temp_pq_str0_16x8b;
248
0
            __m128i temp_pq1_str0_16x8b, temp_pq1_str1_16x8b;
249
0
            __m128i temp_pq2_str0_16x8b;
250
0
            __m128i temp_pq_str1_16x8b;
251
0
            __m128i temp_str0_16x8b, temp_str1_16x8b, temp_str2_16x8b, temp_str3_16x8b;
252
0
            __m128i temp_max0_16x8b, temp_max1_16x8b, temp_min0_16x8b, temp_min1_16x8b;
253
0
            __m128i const2_8x16b, const2tc_8x16b;
254
0
            LWORD64 mask, tc2;
255
0
            tc = tc << 1;
256
0
            mask = (((LWORD64)filter_flag_q) << 63) | (((LWORD64)filter_flag_p) << 31);
257
0
            tc2 = ((LWORD64)tc);
258
259
0
            const2_8x16b = _mm_cmpeq_epi16(src_row0_8x16b, src_row0_8x16b);
260
            //q'0-q'1-2 ,p'0-p'1-2
261
0
            src_row0_8x16b = _mm_unpacklo_epi64(src_row0_8x16b, src_row2_8x16b);
262
0
            src_row1_8x16b = _mm_unpacklo_epi64(src_row1_8x16b, src_row3_8x16b);
263
264
0
            const2_8x16b = _mm_srli_epi16(const2_8x16b, 15);
265
0
            temp_pq_str0_16x8b = _mm_srli_epi64(src_row0_8x16b, 16);
266
0
            temp_pq_str1_16x8b = _mm_srli_epi64(src_row1_8x16b, 16);
267
            //arranged x x x x x x x x q31 q30 q1 q10 p30 p31 p10 p11 , x x x x x x x x q21 q20 q01 q00 p20 p21 p00 p01
268
0
            temp_str0_16x8b = _mm_unpacklo_epi16(temp_pq_str0_16x8b, temp_pq_str1_16x8b);
269
0
            temp_str1_16x8b = _mm_unpackhi_epi16(temp_pq_str0_16x8b, temp_pq_str1_16x8b);
270
271
0
            const2_8x16b = _mm_packus_epi16(const2_8x16b, const2_8x16b);
272
            //arranged q31 q30 q21 q20 q1 q10 q01 q00 p30 p31 p20 p21 p10 p11 p00 p01
273
0
            temp_pq_str0_16x8b = _mm_unpacklo_epi32(temp_str0_16x8b, temp_str1_16x8b);
274
275
0
            temp_pq_str0_16x8b = _mm_maddubs_epi16(temp_pq_str0_16x8b, const2_8x16b);
276
277
            //q'1-2, p'1-2
278
0
            temp_pq1_str0_16x8b = _mm_srli_epi64(src_row0_8x16b, 8);
279
0
            temp_pq1_str1_16x8b = _mm_srli_epi64(src_row1_8x16b, 8);
280
281
0
            temp_str2_16x8b = _mm_unpacklo_epi16(temp_pq1_str0_16x8b, temp_pq1_str1_16x8b);
282
0
            temp_str3_16x8b = _mm_unpackhi_epi16(temp_pq1_str0_16x8b, temp_pq1_str1_16x8b);
283
284
0
            temp_str2_16x8b = _mm_shuffle_epi32(temp_str2_16x8b, 0x58);
285
0
            temp_str3_16x8b = _mm_shuffle_epi32(temp_str3_16x8b, 0x58);
286
            // q30 p30 q20 p20 q10 p10 q01 q00 p30 q20 p20 q10 p10 q01 q00 p00
287
0
            temp_pq1_str0_16x8b = _mm_unpackhi_epi32(temp_str2_16x8b, temp_str3_16x8b);
288
            // q32 q31 q22 q21 q12 q11 q02 q01 p32 p31 p22 p21 p12 p11 p02 p01
289
0
            temp_pq1_str1_16x8b = _mm_unpacklo_epi32(temp_str2_16x8b, temp_str3_16x8b);
290
291
0
            temp_pq1_str0_16x8b = _mm_maddubs_epi16(temp_pq1_str0_16x8b, const2_8x16b);
292
0
            temp_pq1_str1_16x8b = _mm_maddubs_epi16(temp_pq1_str1_16x8b, const2_8x16b);
293
294
            //clipping mask design
295
0
            temp_str1_16x8b = _mm_setzero_si128();
296
0
            temp_str0_16x8b = _mm_loadl_epi64((__m128i *)(&mask));
297
0
            const2tc_8x16b  = _mm_loadl_epi64((__m128i *)(&tc2));
298
0
            temp_str0_16x8b = _mm_shuffle_epi32(temp_str0_16x8b, 0x44);
299
0
            const2tc_8x16b  = _mm_shuffle_epi8(const2tc_8x16b, temp_str1_16x8b);
300
301
            //clipping mask design
302
0
            temp_str0_16x8b = _mm_srai_epi32(temp_str0_16x8b, 31);
303
0
            const2tc_8x16b = _mm_and_si128(const2tc_8x16b, temp_str0_16x8b);
304
            //calculating Clipping MAX for all pixel values.
305
0
            temp_max0_16x8b = _mm_adds_epu8(src_row0_8x16b, const2tc_8x16b);
306
0
            temp_max1_16x8b = _mm_adds_epu8(src_row1_8x16b, const2tc_8x16b);
307
308
309
            //q'2-q'0-2,p'2-p'0-2
310
0
            temp_pq2_str0_16x8b = _mm_unpacklo_epi16(src_row0_8x16b, src_row2_8x16b);
311
0
            temp_str3_16x8b     = _mm_unpacklo_epi16(src_row1_8x16b, src_row3_8x16b);
312
313
0
            temp_pq2_str0_16x8b = _mm_shuffle_epi32(temp_pq2_str0_16x8b, 0x5c);
314
0
            temp_str3_16x8b     = _mm_shuffle_epi32(temp_str3_16x8b, 0x5c);
315
316
0
            const2_8x16b = _mm_slli_epi16(const2_8x16b, 1);
317
            //arranged q33 q32 q23 q22 q13 q12 q03 q02 p33 p32 p23 p22 p13 p12 p03 p02
318
0
            temp_str3_16x8b = _mm_unpacklo_epi16(temp_pq2_str0_16x8b, temp_str3_16x8b);
319
320
0
            temp_pq2_str0_16x8b = _mm_maddubs_epi16(temp_str3_16x8b, const2_8x16b);
321
322
            //calculating Clipping MIN for all pixel values.
323
0
            temp_min0_16x8b = _mm_subs_epu8(src_row0_8x16b, const2tc_8x16b);
324
0
            temp_min1_16x8b = _mm_subs_epu8(src_row1_8x16b, const2tc_8x16b);
325
            //q'0-q'1-2 ,p'0-p'1-2
326
0
            temp_pq_str1_16x8b = _mm_shuffle_epi32(temp_pq_str0_16x8b, 0x4e);
327
0
            temp_pq_str0_16x8b = _mm_add_epi16(temp_pq_str0_16x8b, temp_pq_str1_16x8b);
328
            //q'1-2 p'1-2
329
0
            temp_pq1_str0_16x8b = _mm_add_epi16(temp_pq1_str0_16x8b, temp_pq1_str1_16x8b);
330
            //to get 2 in 16 bit
331
0
            const2_8x16b = _mm_srli_epi16(const2_8x16b, 8);
332
            //to get q33 q23 q13 q03, p33 p23 p13 p03
333
0
            temp_pq1_str1_16x8b = _mm_slli_epi16(temp_str3_16x8b, 8);
334
0
            temp_pq_str1_16x8b = _mm_srli_epi16(temp_str3_16x8b, 8);
335
0
            temp_pq1_str1_16x8b = _mm_srli_epi16(temp_pq1_str1_16x8b, 8);
336
337
            //q'1, p'1 (adding 2)
338
0
            temp_pq1_str0_16x8b = _mm_add_epi16(temp_pq1_str0_16x8b, const2_8x16b);
339
            //q'0-q'1,p'0-p'1
340
0
            temp_pq_str0_16x8b = _mm_add_epi16(temp_pq_str0_16x8b, const2_8x16b);
341
            //q'2-q'1,p'2-p'1
342
0
            temp_pq2_str0_16x8b = _mm_add_epi16(temp_pq2_str0_16x8b, const2_8x16b);
343
            //q'0 = (q'0-q'1)+q'1 ,p'0 = (p'0-p'1)+p'1;
344
0
            temp_pq_str0_16x8b = _mm_add_epi16(temp_pq1_str0_16x8b, temp_pq_str0_16x8b);
345
            //q'2 = (q'2-q'1)+q'1 ,p'2 = (p'2-p'1)+p'1;
346
0
            temp_pq2_str0_16x8b = _mm_add_epi16(temp_pq1_str0_16x8b, temp_pq2_str0_16x8b);
347
348
            //normalisation of all modified pixels
349
0
            temp_pq_str0_16x8b  = _mm_srai_epi16(temp_pq_str0_16x8b, 3);
350
0
            temp_pq1_str0_16x8b = _mm_srai_epi16(temp_pq1_str0_16x8b, 2);
351
0
            temp_pq2_str0_16x8b = _mm_srai_epi16(temp_pq2_str0_16x8b, 3);
352
353
            //getting p0 p1 together and p2 p3 together
354
0
            temp_str0_16x8b = _mm_unpacklo_epi16(temp_pq1_str0_16x8b, temp_pq_str0_16x8b);
355
0
            temp_str2_16x8b = _mm_unpacklo_epi16(temp_pq1_str1_16x8b, temp_pq2_str0_16x8b);
356
            //getting q1 q0 together and  q3 q2 together
357
0
            temp_pq_str0_16x8b = _mm_unpackhi_epi16(temp_pq_str0_16x8b, temp_pq1_str0_16x8b);
358
0
            temp_pq2_str0_16x8b = _mm_unpackhi_epi16(temp_pq2_str0_16x8b, temp_pq_str1_16x8b);
359
            //getting p's of row0 row1 together and of row2 row3 together
360
0
            temp_pq_str1_16x8b = _mm_unpacklo_epi32(temp_str2_16x8b, temp_str0_16x8b);
361
0
            temp_str2_16x8b    = _mm_unpackhi_epi32(temp_str2_16x8b, temp_str0_16x8b);
362
            //getting q's of row0 row1 together and of row2 row3 together
363
0
            temp_str0_16x8b    = _mm_unpacklo_epi32(temp_pq_str0_16x8b, temp_pq2_str0_16x8b);
364
0
            temp_pq_str0_16x8b = _mm_unpackhi_epi32(temp_pq_str0_16x8b, temp_pq2_str0_16x8b);
365
            //getting values for respective rows in 16 bit
366
0
            src_row0_8x16b = _mm_unpacklo_epi64(temp_pq_str1_16x8b, temp_str0_16x8b);
367
0
            src_row1_8x16b = _mm_unpackhi_epi64(temp_pq_str1_16x8b, temp_str0_16x8b);
368
0
            src_row2_8x16b = _mm_unpacklo_epi64(temp_str2_16x8b, temp_pq_str0_16x8b);
369
0
            src_row3_8x16b = _mm_unpackhi_epi64(temp_str2_16x8b, temp_pq_str0_16x8b);
370
            //packing values to 8 bit
371
0
            src_row0_8x16b = _mm_packus_epi16(src_row0_8x16b, src_row2_8x16b);
372
0
            src_row1_8x16b = _mm_packus_epi16(src_row1_8x16b, src_row3_8x16b);
373
            //Clipping MAX
374
0
            src_row0_8x16b = _mm_min_epu8(src_row0_8x16b, temp_max0_16x8b);
375
0
            src_row1_8x16b = _mm_min_epu8(src_row1_8x16b, temp_max1_16x8b);
376
            //Clipping MIN
377
0
            src_row0_8x16b = _mm_max_epu8(src_row0_8x16b, temp_min0_16x8b);
378
0
            src_row1_8x16b = _mm_max_epu8(src_row1_8x16b, temp_min1_16x8b);
379
            //separating row 2 and row 3
380
0
            src_row2_8x16b = _mm_srli_si128(src_row0_8x16b, 8);
381
0
            src_row3_8x16b = _mm_srli_si128(src_row1_8x16b, 8);
382
383
0
        }
384
385
0
        else
386
0
        {
387
388
0
            __m128i tmp_delta0_8x16b, tmp_delta1_8x16b, tmp_delta2_8x16b, tmp_delta3_8x16b;
389
0
            __m128i tmp0_const_8x16b, tmp1_const_8x16b, tmp2_const_8x16b, tmp3_const_8x16b;
390
0
            __m128i coefdelta_0_8x16b, mask_pq_8x16b;
391
0
            __m128i const2_8x16b, consttc_8x16b;
392
393
0
            LWORD64 mask1;
394
0
            mask1 = (((LWORD64)(filter_flag_q & deq)) << 63) | (((LWORD64)filter_flag_q) << 47) | (((LWORD64)filter_flag_p) << 31) | (((LWORD64)(filter_flag_p & dep)) << 15);
395
396
0
            consttc_8x16b = _mm_set1_epi32(tc);
397
398
399
0
            src_row0_8x16b = _mm_unpacklo_epi64(src_row0_8x16b, src_row1_8x16b);
400
0
            src_row2_8x16b = _mm_unpacklo_epi64(src_row2_8x16b, src_row3_8x16b);
401
402
0
            tmp_delta2_8x16b = _mm_srli_epi64(src_row0_8x16b, 16);
403
0
            tmp_delta3_8x16b = _mm_srli_epi64(src_row2_8x16b, 16);
404
405
0
            tmp_delta2_8x16b = _mm_shuffle_epi32(tmp_delta2_8x16b, 0x08);
406
0
            tmp_delta3_8x16b = _mm_shuffle_epi32(tmp_delta3_8x16b, 0x08);
407
            //arranged q31 q30 p30 p31  q21 q20 p20 p21  q1 q10 p10 p11 q01 q00 p00 p01
408
0
            tmp_delta2_8x16b = _mm_unpacklo_epi64(tmp_delta2_8x16b, tmp_delta3_8x16b);
409
410
0
            coefdelta_0_8x16b = _mm_load_si128((__m128i *)coef_de1);
411
            // (-3q1+9q0),(-9p0+3p1)
412
0
            tmp_delta3_8x16b = _mm_maddubs_epi16(tmp_delta2_8x16b, coefdelta_0_8x16b);
413
            //converting to 16 bit
414
0
            consttc_8x16b = _mm_packs_epi32(consttc_8x16b, consttc_8x16b);
415
            //getting -tc store
416
0
            tmp1_const_8x16b = _mm_cmpeq_epi32(consttc_8x16b, consttc_8x16b);
417
            //calc 10 *tc = 2*tc +8*tc ; 2*tc
418
0
            tmp2_const_8x16b = _mm_slli_epi16(consttc_8x16b, 1);
419
            //calc 10 *tc = 2*tc +8*tc ; 8*tc
420
0
            tmp0_const_8x16b = _mm_slli_epi16(consttc_8x16b, 3);
421
            //getting -tc store
422
0
            tmp3_const_8x16b = _mm_sign_epi16(consttc_8x16b, tmp1_const_8x16b);
423
            //calc 10 *tc
424
0
            tmp2_const_8x16b = _mm_add_epi16(tmp2_const_8x16b, tmp0_const_8x16b);
425
            //const 1
426
0
            const2_8x16b = _mm_srli_epi16(tmp1_const_8x16b, 15);
427
0
            tmp_delta0_8x16b = _mm_madd_epi16(tmp_delta3_8x16b, const2_8x16b);
428
0
            const2_8x16b = _mm_srli_epi32(tmp1_const_8x16b, 31);
429
            //getting the mask values
430
0
            mask_pq_8x16b = _mm_loadl_epi64((__m128i *)(&mask1));
431
            //loaded coef for delta1 calculation
432
0
            coefdelta_0_8x16b = _mm_load_si128((__m128i *)coef_dep1);
433
            //(-2q1+q0),(p0-2p1)
434
0
            tmp_delta3_8x16b = _mm_maddubs_epi16(tmp_delta2_8x16b, coefdelta_0_8x16b);
435
            //const 8
436
0
            const2_8x16b = _mm_slli_epi32(const2_8x16b, 3);
437
            //rearranging the mask values
438
0
            mask_pq_8x16b = _mm_unpacklo_epi64(mask_pq_8x16b, mask_pq_8x16b);
439
            //normalisation of the filter
440
0
            tmp_delta0_8x16b = _mm_add_epi32(tmp_delta0_8x16b, const2_8x16b);
441
0
            tmp_delta0_8x16b = _mm_srai_epi32(tmp_delta0_8x16b, 4);
442
443
            //getting deltaq0
444
0
            tmp_delta2_8x16b = _mm_sign_epi32(tmp_delta0_8x16b, tmp1_const_8x16b);
445
            //packing  d3q d2q d1q d0q d3p d2p d1p d0p
446
0
            tmp_delta0_8x16b = _mm_packs_epi32(tmp_delta0_8x16b, tmp_delta2_8x16b);
447
            //absolute delta
448
0
            tmp_delta2_8x16b = _mm_abs_epi16(tmp_delta0_8x16b);
449
            //Clipping of delta0
450
0
            tmp_delta0_8x16b = _mm_min_epi16(tmp_delta0_8x16b, consttc_8x16b);
451
            //mask for |delta| < 10*tc
452
0
            tmp0_const_8x16b = _mm_cmpgt_epi16(tmp2_const_8x16b, tmp_delta2_8x16b);
453
            //Clipping of delta0
454
0
            tmp_delta0_8x16b = _mm_max_epi16(tmp_delta0_8x16b, tmp3_const_8x16b);
455
456
457
            //delta 1 calc starts
458
459
            //getting q32 q22 q12 q02 p32 p12 p22 p02
460
0
            tmp2_const_8x16b = _mm_loadl_epi64((__m128i *)(shuffle0));
461
0
            tmp_delta2_8x16b = _mm_shuffle_epi8(src_row0_8x16b, tmp2_const_8x16b);
462
0
            tmp_delta1_8x16b =  _mm_shuffle_epi8(src_row2_8x16b, tmp2_const_8x16b);
463
0
            tmp_delta1_8x16b = _mm_unpacklo_epi32(tmp_delta2_8x16b, tmp_delta1_8x16b);
464
            //constant 1
465
0
            const2_8x16b = _mm_srli_epi16(tmp1_const_8x16b, 15);
466
            //tc>>1 16 bit
467
0
            consttc_8x16b = _mm_srai_epi16(consttc_8x16b, 1);
468
469
            //getting -tc>>1 store  16 bit
470
0
            tmp1_const_8x16b = _mm_sign_epi16(consttc_8x16b, tmp1_const_8x16b);
471
            //2*delta0
472
0
            tmp2_const_8x16b = _mm_add_epi16(tmp_delta0_8x16b, tmp_delta0_8x16b);
473
474
            //getting  all respective q's and p's together
475
0
            tmp3_const_8x16b = _mm_load_si128((__m128i *)(shuffle1));
476
0
            tmp_delta3_8x16b = _mm_shuffle_epi8(tmp_delta3_8x16b, tmp3_const_8x16b);
477
            //final adds for deltap1 and deltaq1
478
0
            tmp_delta3_8x16b = _mm_add_epi16(tmp_delta3_8x16b, const2_8x16b);
479
0
            tmp_delta1_8x16b = _mm_add_epi16(tmp_delta1_8x16b, tmp2_const_8x16b);
480
0
            tmp_delta1_8x16b = _mm_add_epi16(tmp_delta1_8x16b, tmp_delta3_8x16b);
481
0
            tmp2_const_8x16b = _mm_setzero_si128();
482
0
            tmp_delta1_8x16b = _mm_srai_epi16(tmp_delta1_8x16b, 2);
483
484
            // clipping delta1
485
0
            tmp_delta1_8x16b = _mm_min_epi16(tmp_delta1_8x16b, consttc_8x16b);
486
            // clipping delta1
487
0
            tmp_delta1_8x16b = _mm_max_epi16(tmp_delta1_8x16b, tmp1_const_8x16b);
488
489
            //getting the mask ready
490
0
            mask_pq_8x16b = _mm_srai_epi16(mask_pq_8x16b, 15);
491
            //masking of the delta values |delta|<10*tc
492
0
            tmp_delta1_8x16b = _mm_and_si128(tmp_delta1_8x16b, tmp0_const_8x16b);
493
0
            tmp_delta0_8x16b = _mm_and_si128(tmp_delta0_8x16b, tmp0_const_8x16b);
494
            //packing dq1 dq0 dp0 dp1
495
0
            tmp1_const_8x16b = _mm_unpacklo_epi16(tmp_delta1_8x16b, tmp_delta0_8x16b);
496
0
            tmp_delta0_8x16b = _mm_unpackhi_epi16(tmp_delta0_8x16b, tmp_delta1_8x16b);
497
0
            tmp_delta1_8x16b = _mm_unpackhi_epi32(tmp1_const_8x16b, tmp_delta0_8x16b);
498
0
            tmp_delta0_8x16b = _mm_unpacklo_epi32(tmp1_const_8x16b, tmp_delta0_8x16b);
499
500
            //masking of the delta values dep, deq , filter_p ,filter_q
501
0
            tmp_delta0_8x16b = _mm_and_si128(tmp_delta0_8x16b, mask_pq_8x16b);
502
0
            tmp_delta1_8x16b = _mm_and_si128(tmp_delta1_8x16b, mask_pq_8x16b);
503
            //converting 8bit to 16 bit
504
0
            src_row0_8x16b = _mm_unpacklo_epi8(src_row0_8x16b, tmp2_const_8x16b);
505
0
            src_row1_8x16b = _mm_unpacklo_epi8(src_row1_8x16b, tmp2_const_8x16b);
506
0
            src_row2_8x16b = _mm_unpacklo_epi8(src_row2_8x16b, tmp2_const_8x16b);
507
0
            src_row3_8x16b = _mm_unpacklo_epi8(src_row3_8x16b, tmp2_const_8x16b);
508
            //shuffle values loaded
509
0
            tmp0_const_8x16b = _mm_load_si128((__m128i *)shuffle2);
510
0
            tmp1_const_8x16b = _mm_load_si128((__m128i *)shuffle3);
511
            //arranging each row delta in different registers
512
0
            tmp_delta3_8x16b = _mm_shuffle_epi8(tmp_delta1_8x16b, tmp1_const_8x16b);
513
0
            tmp_delta2_8x16b = _mm_shuffle_epi8(tmp_delta1_8x16b, tmp0_const_8x16b);
514
0
            tmp_delta1_8x16b = _mm_shuffle_epi8(tmp_delta0_8x16b, tmp1_const_8x16b);
515
0
            tmp_delta0_8x16b = _mm_shuffle_epi8(tmp_delta0_8x16b, tmp0_const_8x16b);
516
517
            //adding the respective delta
518
0
            src_row3_8x16b = _mm_add_epi16(tmp_delta3_8x16b, src_row3_8x16b);
519
0
            src_row2_8x16b = _mm_add_epi16(tmp_delta2_8x16b, src_row2_8x16b);
520
0
            src_row1_8x16b = _mm_add_epi16(tmp_delta1_8x16b, src_row1_8x16b);
521
0
            src_row0_8x16b = _mm_add_epi16(tmp_delta0_8x16b, src_row0_8x16b);
522
            //saturating to 8 bit
523
0
            src_row2_8x16b = _mm_packus_epi16(src_row2_8x16b, src_row3_8x16b);
524
0
            src_row0_8x16b = _mm_packus_epi16(src_row0_8x16b, src_row1_8x16b);
525
            //separating different rows
526
0
            src_row1_8x16b = _mm_srli_si128(src_row0_8x16b, 8);
527
0
            src_row3_8x16b = _mm_srli_si128(src_row2_8x16b, 8);
528
0
        }
529
530
0
        _mm_storel_epi64((__m128i *)(pu1_src - 4), src_row0_8x16b);
531
0
        _mm_storel_epi64((__m128i *)((pu1_src - 4) + src_strd), src_row1_8x16b);
532
0
        _mm_storel_epi64((__m128i *)((pu1_src - 4) + 2 * src_strd), src_row2_8x16b);
533
0
        _mm_storel_epi64((__m128i *)((pu1_src - 4) + 3 * src_strd), src_row3_8x16b);
534
0
    }
535
0
}
536
537
void ihevc_deblk_luma_horz_ssse3(UWORD8 *pu1_src,
538
                                 WORD32 src_strd,
539
                                 WORD32 bs,
540
                                 WORD32 quant_param_p,
541
                                 WORD32 quant_param_q,
542
                                 WORD32 beta_offset_div2,
543
                                 WORD32 tc_offset_div2,
544
                                 WORD32 filter_flag_p,
545
                                 WORD32 filter_flag_q)
546
0
{
547
0
    WORD32 qp_luma, beta_indx, tc_indx;
548
0
    WORD32 beta, tc;
549
550
0
    WORD32 d0, d3, dp, dq, d;
551
0
    WORD32 de_0, de_1, de_2, de_3;
552
0
    WORD32 d_sam0, d_sam3;
553
0
    WORD32 de, dep, deq;
554
555
0
    __m128i src_q0_8x16b, src_q1_8x16b, src_p0_8x16b, src_p1_8x16b, src_q2_8x16b;
556
0
    __m128i tmp_pq_str1_8x16b, src_p2_8x16b, tmp_pq_str0_8x16b;
557
558
559
560
561
0
    {
562
0
        __m128i src_tmp_p_0_8x16b, src_tmp_p_1_8x16b, src_tmp_q_0_8x16b, src_tmp_q_1_8x16b;
563
0
        __m128i coef_8x16b, mask_d_result_4x32b, mask_de_result_8x16b;
564
0
        __m128i mask_16x8b, temp_coef0_8x16b, temp_coef1_8x16b;
565
566
0
        ASSERT((bs > 0));
567
0
        ASSERT(filter_flag_p || filter_flag_q);
568
569
0
        qp_luma = (quant_param_p + quant_param_q + 1) >> 1;
570
0
        beta_indx = CLIP3(qp_luma + (beta_offset_div2 << 1), 0, 51);
571
572
        /* BS based on implementation can take value 3 if it is intra/inter egde          */
573
        /* based on BS, tc index is calcuated by adding 2 * ( bs - 1) to QP and tc_offset */
574
        /* for BS = 1 adding factor is (0*2), BS = 2 or 3 adding factor is (1*2)          */
575
        /* the above desired functionallity is achieved by doing (2*(bs>>1))              */
576
577
0
        tc_indx = CLIP3(qp_luma + 2 * (bs >> 1) + (tc_offset_div2 << 1), 0, 53);
578
579
0
        beta = gai4_ihevc_beta_table[beta_indx];
580
0
        tc = gai4_ihevc_tc_table[tc_indx];
581
0
        if(0 == tc)
582
0
        {
583
0
            return;
584
0
        }
585
0
        src_q0_8x16b = _mm_loadl_epi64((__m128i *)(pu1_src));
586
0
        src_q1_8x16b = _mm_loadl_epi64((__m128i *)(pu1_src + src_strd));
587
0
        src_p0_8x16b = _mm_loadl_epi64((__m128i *)(pu1_src - src_strd));
588
0
        src_p1_8x16b = _mm_loadl_epi64((__m128i *)(pu1_src - 2 * src_strd));
589
0
        src_q2_8x16b = _mm_loadl_epi64((__m128i *)(pu1_src + 2 * src_strd));
590
0
        tmp_pq_str1_8x16b = _mm_loadl_epi64((__m128i *)(pu1_src + 3 * src_strd));
591
0
        src_p2_8x16b = _mm_loadl_epi64((__m128i *)(pu1_src - 3 * src_strd));
592
0
        tmp_pq_str0_8x16b = _mm_loadl_epi64((__m128i *)(pu1_src - 4 * src_strd));
593
594
595
0
        src_tmp_p_0_8x16b = _mm_unpacklo_epi8(src_p1_8x16b, src_p0_8x16b);
596
0
        src_tmp_p_1_8x16b = _mm_unpacklo_epi8(tmp_pq_str0_8x16b, src_p2_8x16b);
597
598
0
        src_tmp_q_0_8x16b = _mm_unpacklo_epi8(src_q0_8x16b, src_q1_8x16b);
599
0
        src_tmp_q_1_8x16b = _mm_unpacklo_epi8(src_q2_8x16b, tmp_pq_str1_8x16b);
600
601
0
        src_tmp_p_0_8x16b = _mm_unpacklo_epi16(src_tmp_p_1_8x16b, src_tmp_p_0_8x16b);
602
0
        src_tmp_q_0_8x16b = _mm_unpacklo_epi16(src_tmp_q_0_8x16b, src_tmp_q_1_8x16b);
603
604
0
        src_tmp_p_0_8x16b = _mm_shuffle_epi32(src_tmp_p_0_8x16b, 0x6c);
605
0
        src_tmp_q_0_8x16b = _mm_shuffle_epi32(src_tmp_q_0_8x16b, 0x6c);
606
607
0
        coef_8x16b = _mm_load_si128((__m128i *)(coef_d));
608
0
        mask_16x8b =  _mm_load_si128((__m128i *)(shuffle_d));
609
610
0
        src_tmp_p_0_8x16b = _mm_unpacklo_epi32(src_tmp_p_0_8x16b, src_tmp_q_0_8x16b);
611
        //WORD32 shuffle_d[4]={0x80800403,0x80800c0b,0x03000704,0x0b080f0c};
612
0
        mask_de_result_8x16b = _mm_shuffle_epi8(src_tmp_p_0_8x16b, mask_16x8b);
613
614
0
        mask_d_result_4x32b = _mm_maddubs_epi16(src_tmp_p_0_8x16b, coef_8x16b);
615
616
617
        //to get all 1's of 8 bit in (1)
618
0
        temp_coef0_8x16b = _mm_cmpeq_epi16(src_tmp_p_0_8x16b, src_tmp_p_0_8x16b);
619
0
        temp_coef1_8x16b = _mm_srli_epi16(temp_coef0_8x16b, 15);
620
        //accumulating values foe dp3 dq3 , dp0 dq0 values
621
0
        mask_d_result_4x32b = _mm_madd_epi16(mask_d_result_4x32b, temp_coef1_8x16b);
622
623
0
        temp_coef1_8x16b = _mm_packus_epi16(temp_coef1_8x16b, temp_coef1_8x16b);
624
        // to get all 1,-1 sets of 16 bits in (0)
625
0
        temp_coef0_8x16b = _mm_unpacklo_epi8(temp_coef0_8x16b, temp_coef1_8x16b);
626
        //q33-q30,p33-p30,q03-q00,p03-p00,0,q30-p30,0,q00-p00
627
0
        mask_de_result_8x16b = _mm_maddubs_epi16(mask_de_result_8x16b, temp_coef0_8x16b);
628
        //to get 16 bit 1's
629
0
        temp_coef0_8x16b = _mm_srli_epi16(temp_coef1_8x16b, 8);
630
631
632
        // dq3 dp3 dq0 dp0
633
0
        mask_d_result_4x32b = _mm_abs_epi32(mask_d_result_4x32b);
634
0
        mask_16x8b = _mm_shuffle_epi32(mask_d_result_4x32b, 0xec);
635
0
        mask_d_result_4x32b = _mm_shuffle_epi32(mask_d_result_4x32b, 0x49);
636
        // dq dp d3 d0
637
0
        mask_d_result_4x32b = _mm_add_epi32(mask_d_result_4x32b, mask_16x8b);
638
        //|q33-q30|,|p33-p30|,|q03-q00|,|p03-p00|,0,|q30-p30|,0,|q00-p00|
639
0
        mask_de_result_8x16b = _mm_abs_epi16(mask_de_result_8x16b);
640
        //|q33-q30|+|p33-p30|,|q03-q00|+|p03-p00|,0+|q30-p30|,0+|q00-p00|
641
0
        mask_de_result_8x16b = _mm_madd_epi16(mask_de_result_8x16b, temp_coef0_8x16b);
642
643
        ///store back in a single variable
644
0
        temp_coef0_8x16b = _mm_srli_si128(mask_d_result_4x32b, 4);
645
0
        temp_coef1_8x16b = _mm_srli_si128(mask_d_result_4x32b, 8);
646
0
        mask_16x8b = _mm_srli_si128(mask_d_result_4x32b, 12);
647
648
0
        d0 = _mm_cvtsi128_si32(mask_d_result_4x32b);
649
0
        d3 = _mm_cvtsi128_si32(temp_coef0_8x16b);
650
0
        dp = _mm_cvtsi128_si32(temp_coef1_8x16b);
651
0
        dq = _mm_cvtsi128_si32(mask_16x8b);
652
        //getting d
653
0
        d = d0 + d3;
654
655
        ///store back in a single variable
656
0
        temp_coef0_8x16b = _mm_srli_si128(mask_de_result_8x16b, 4);
657
0
        temp_coef1_8x16b = _mm_srli_si128(mask_de_result_8x16b, 8);
658
0
        mask_16x8b = _mm_srli_si128(mask_de_result_8x16b, 12);
659
660
0
        de_0 = _mm_cvtsi128_si32(mask_de_result_8x16b);
661
0
        de_1 = _mm_cvtsi128_si32(temp_coef0_8x16b);
662
0
        de_2 = _mm_cvtsi128_si32(temp_coef1_8x16b);
663
0
        de_3 = _mm_cvtsi128_si32(mask_16x8b);
664
665
0
        de = 0;
666
0
        dep = 0;
667
0
        deq = 0;
668
0
        if(d < beta)
669
0
        {
670
0
            d_sam0 = 0;
671
0
            if((2 * d0 < (beta >> 2))
672
0
                            && (de_2 < (beta >> 3))
673
0
                            && (de_0 < ((5 * tc + 1) >> 1)))
674
0
            {
675
0
                d_sam0 = 1;
676
0
            }
677
678
0
            d_sam3 = 0;
679
0
            if((2 * d3 < (beta >> 2))
680
0
                            && (de_3 < (beta >> 3))
681
0
                            && de_1 < ((5 * tc + 1) >> 1))
682
0
            {
683
0
                d_sam3 = 1;
684
0
            }
685
686
0
            de = (d_sam0 & d_sam3) + 1;
687
0
            dep = (dp < (beta + (beta >> 1)) >> 3) ? 1 : 0;
688
0
            deq = (dq < (beta + (beta >> 1)) >> 3) ? 1 : 0;
689
0
            if(tc <= 1)
690
0
            {
691
0
                dep = 0;
692
0
                deq = 0;
693
0
            }
694
0
        }
695
696
0
    }
697
698
0
    if(de != 0)
699
0
    {
700
701
0
        if(2 == de)
702
0
        {
703
704
0
            __m128i temp_pq0_str0_16x8b;
705
0
            __m128i temp_pq1_str0_16x8b, temp_pq1_str1_16x8b;
706
0
            __m128i temp_pq2_str0_16x8b;
707
0
            __m128i temp_str0_16x8b, temp_str1_16x8b;
708
0
            __m128i const2_8x16b, const2tc_8x16b;
709
710
0
            LWORD64 mask, tc2;
711
0
            tc = tc << 1;
712
0
            mask = (((LWORD64)filter_flag_q) << 63) | (((LWORD64)filter_flag_p) << 31);
713
0
            tc2 = ((LWORD64)tc);
714
715
0
            const2_8x16b = _mm_cmpeq_epi16(src_p1_8x16b, src_p1_8x16b);
716
            //q'0-q'1-2 ,p'0-p'1-2
717
0
            temp_pq0_str0_16x8b = _mm_unpacklo_epi8(src_p1_8x16b, src_p0_8x16b);
718
0
            temp_str0_16x8b   = _mm_unpacklo_epi8(src_q0_8x16b, src_q1_8x16b);
719
0
            const2_8x16b = _mm_srli_epi16(const2_8x16b, 15);
720
            //arranged q31 q30 q21 q20 q1 q10 q01 q00 p30 p31 p20 p21 p10 p11 p00 p01
721
0
            temp_pq0_str0_16x8b = _mm_unpacklo_epi64(temp_pq0_str0_16x8b, temp_str0_16x8b);
722
723
0
            const2_8x16b = _mm_packus_epi16(const2_8x16b, const2_8x16b);
724
0
            temp_pq0_str0_16x8b = _mm_maddubs_epi16(temp_pq0_str0_16x8b, const2_8x16b);
725
726
            //q'1-2, p'1-2
727
0
            temp_pq1_str0_16x8b = _mm_unpacklo_epi8(src_p0_8x16b, src_q0_8x16b);
728
0
            temp_pq1_str1_16x8b = _mm_unpacklo_epi8(src_q1_8x16b, src_q2_8x16b);
729
0
            temp_str1_16x8b = _mm_unpacklo_epi8(src_p1_8x16b, src_p2_8x16b);
730
            // q30 p30 q20 p20 q10 p10 q01 q00 p30 q20 p20 q10 p10 q01 q00 p00
731
0
            temp_pq1_str0_16x8b = _mm_unpacklo_epi64(temp_pq1_str0_16x8b, temp_pq1_str0_16x8b);
732
            // q32 q31 q22 q21 q12 q11 q02 q01 p32 p31 p22 p21 p12 p11 p02 p01
733
0
            temp_pq1_str1_16x8b = _mm_unpacklo_epi64(temp_str1_16x8b, temp_pq1_str1_16x8b);
734
735
0
            temp_pq1_str0_16x8b = _mm_maddubs_epi16(temp_pq1_str0_16x8b, const2_8x16b);
736
0
            temp_pq1_str1_16x8b = _mm_maddubs_epi16(temp_pq1_str1_16x8b, const2_8x16b);
737
738
            //clipping mask design
739
0
            temp_str1_16x8b = _mm_setzero_si128();
740
0
            temp_str0_16x8b = _mm_loadl_epi64((__m128i *)(&mask));
741
0
            const2tc_8x16b  = _mm_loadl_epi64((__m128i *)(&tc2));
742
0
            temp_str0_16x8b = _mm_shuffle_epi32(temp_str0_16x8b, 0x44);
743
0
            const2tc_8x16b  = _mm_shuffle_epi8(const2tc_8x16b, temp_str1_16x8b);
744
745
            //clipping mask design
746
0
            temp_str0_16x8b = _mm_srai_epi32(temp_str0_16x8b, 31);
747
0
            const2tc_8x16b = _mm_and_si128(const2tc_8x16b, temp_str0_16x8b);
748
            //calculating Clipping MAX for all pixel values.
749
0
            src_p0_8x16b = _mm_unpacklo_epi32(src_p0_8x16b, src_q0_8x16b);
750
0
            src_q0_8x16b = _mm_unpacklo_epi32(src_p1_8x16b, src_q1_8x16b);
751
            //for clipping calc
752
0
            src_p1_8x16b = _mm_unpacklo_epi64(src_p0_8x16b, src_q0_8x16b);
753
            //saving the unmodified data of q1 p1 q0 p0
754
0
            src_q1_8x16b = _mm_unpackhi_epi64(src_p0_8x16b, src_q0_8x16b);
755
            //CLIpping MAX and MIN for q1 p1 q0 p0
756
0
            src_p0_8x16b = _mm_adds_epu8(src_p1_8x16b, const2tc_8x16b);
757
0
            src_p1_8x16b = _mm_subs_epu8(src_p1_8x16b, const2tc_8x16b);
758
759
760
            //q'2-q'0-2,p'2-p'0-2
761
0
            tmp_pq_str0_8x16b = _mm_unpacklo_epi8(src_p2_8x16b, tmp_pq_str0_8x16b);
762
0
            temp_pq2_str0_16x8b = _mm_unpacklo_epi8(src_q2_8x16b, tmp_pq_str1_8x16b);
763
0
            const2_8x16b = _mm_slli_epi16(const2_8x16b, 1);
764
            //arranged q33 q32 q23 q22 q13 q12 q03 q02 p32 p33 p22 p23 p12 p13 p02 p03
765
0
            temp_pq2_str0_16x8b = _mm_unpacklo_epi64(tmp_pq_str0_8x16b, temp_pq2_str0_16x8b);
766
0
            src_p2_8x16b = _mm_unpacklo_epi32(src_p2_8x16b, src_q2_8x16b);
767
0
            temp_pq2_str0_16x8b = _mm_maddubs_epi16(temp_pq2_str0_16x8b, const2_8x16b);
768
769
            //calculating Clipping MAX and MIN for p2 and q2 .
770
0
            tmp_pq_str0_8x16b = _mm_adds_epu8(src_p2_8x16b, const2tc_8x16b);
771
0
            tmp_pq_str1_8x16b = _mm_subs_epu8(src_p2_8x16b, const2tc_8x16b);
772
            //q'0-q'1-2 ,p'0-p'1-2
773
0
            temp_str0_16x8b = _mm_shuffle_epi32(temp_pq0_str0_16x8b, 0x4e);
774
0
            temp_pq0_str0_16x8b = _mm_add_epi16(temp_pq0_str0_16x8b, temp_str0_16x8b);
775
            //q'1-2 p'1-2
776
0
            temp_pq1_str0_16x8b = _mm_add_epi16(temp_pq1_str0_16x8b, temp_pq1_str1_16x8b);
777
            //to get 2 in 16 bit
778
0
            const2_8x16b = _mm_srli_epi16(const2_8x16b, 8);
779
780
781
            //q'1, p'1 (adding 2)
782
0
            temp_pq1_str0_16x8b = _mm_add_epi16(temp_pq1_str0_16x8b, const2_8x16b);
783
            //q'0-q'1,p'0-p'1
784
0
            temp_pq0_str0_16x8b = _mm_add_epi16(temp_pq0_str0_16x8b, const2_8x16b);
785
            //q'2-q'1,p'2-p'1
786
0
            temp_pq2_str0_16x8b = _mm_add_epi16(temp_pq2_str0_16x8b, const2_8x16b);
787
            //q'0 = (q'0-q'1)+q'1 ,p'0 = (p'0-p'1)+p'1;
788
0
            temp_pq0_str0_16x8b = _mm_add_epi16(temp_pq1_str0_16x8b, temp_pq0_str0_16x8b);
789
            //q'2 = (q'2-q'1)+q'1 ,p'2 = (p'2-p'1)+p'1;
790
0
            temp_pq2_str0_16x8b = _mm_add_epi16(temp_pq1_str0_16x8b, temp_pq2_str0_16x8b);
791
792
            //normalisation of all modified pixels
793
0
            temp_pq0_str0_16x8b = _mm_srai_epi16(temp_pq0_str0_16x8b, 3);
794
0
            temp_pq1_str0_16x8b = _mm_srai_epi16(temp_pq1_str0_16x8b, 2);
795
0
            temp_pq2_str0_16x8b = _mm_srai_epi16(temp_pq2_str0_16x8b, 3);
796
            //q'1 p'1 q'0 p'0
797
0
            temp_pq0_str0_16x8b = _mm_packus_epi16(temp_pq0_str0_16x8b, temp_pq1_str0_16x8b);
798
0
            temp_pq2_str0_16x8b = _mm_packus_epi16(temp_pq2_str0_16x8b, temp_pq2_str0_16x8b);
799
            //pack with the unmodified data of q2 and p2
800
0
            src_p2_8x16b = _mm_unpackhi_epi64(temp_pq2_str0_16x8b, src_p2_8x16b);
801
            //Clipping MAX and MIN for q'1 p'1 q'0 p'0 and q'2  p'2
802
0
            temp_pq0_str0_16x8b = _mm_min_epu8(temp_pq0_str0_16x8b, src_p0_8x16b);
803
0
            src_p2_8x16b = _mm_min_epu8(src_p2_8x16b, tmp_pq_str0_8x16b);
804
0
            temp_pq0_str0_16x8b = _mm_max_epu8(temp_pq0_str0_16x8b, src_p1_8x16b);
805
0
            src_p2_8x16b = _mm_max_epu8(src_p2_8x16b, tmp_pq_str1_8x16b);
806
            //Reshuffling q'1 p'1 q'0 p'0 along with unmodified data
807
0
            src_p0_8x16b = _mm_unpacklo_epi32(temp_pq0_str0_16x8b, src_q1_8x16b);
808
0
            src_p1_8x16b = _mm_unpackhi_epi32(temp_pq0_str0_16x8b, src_q1_8x16b);
809
0
            src_p2_8x16b = _mm_shuffle_epi32(src_p2_8x16b, 0xd8);
810
0
            src_q0_8x16b = _mm_srli_si128(src_p0_8x16b, 8);
811
0
            src_q1_8x16b = _mm_srli_si128(src_p1_8x16b, 8);
812
0
            src_q2_8x16b = _mm_srli_si128(src_p2_8x16b, 8);
813
814
0
            _mm_storel_epi64((__m128i *)(pu1_src - 3 * src_strd), src_p2_8x16b);
815
0
            _mm_storel_epi64((__m128i *)(pu1_src - 2 * src_strd), src_p1_8x16b);
816
0
            _mm_storel_epi64((__m128i *)(pu1_src - src_strd), src_p0_8x16b);
817
0
            _mm_storel_epi64((__m128i *)(pu1_src), src_q0_8x16b);
818
0
            _mm_storel_epi64((__m128i *)(pu1_src + src_strd), src_q1_8x16b);
819
0
            _mm_storel_epi64((__m128i *)(pu1_src + 2 * src_strd), src_q2_8x16b);
820
821
822
0
        }
823
824
0
        else
825
0
        {
826
827
0
            __m128i tmp_delta0_8x16b, tmp_delta1_8x16b;
828
0
            __m128i tmp0_const_8x16b, tmp1_const_8x16b, tmp2_const_8x16b;
829
0
            __m128i coefdelta_0_8x16b;
830
0
            __m128i const2_8x16b, consttc_8x16b;
831
832
0
            LWORD64 maskp0, maskp1, maskq0, maskq1;
833
0
            maskp0 = (LWORD64)filter_flag_p;
834
0
            maskq0 = (LWORD64)filter_flag_q;
835
0
            maskp1 = (LWORD64)dep;
836
0
            maskq1 = (LWORD64)deq;
837
0
            consttc_8x16b = _mm_set1_epi32(tc);
838
839
0
            tmp_delta0_8x16b = _mm_unpacklo_epi8(src_p1_8x16b, src_p0_8x16b);
840
0
            tmp_delta1_8x16b = _mm_unpacklo_epi8(src_q0_8x16b, src_q1_8x16b);
841
            //arranged q31 q30 p30 p31  q21 q20 p20 p21  q1 q10 p10 p11 q01 q00 p00 p01
842
0
            tmp_delta1_8x16b = _mm_unpacklo_epi16(tmp_delta0_8x16b, tmp_delta1_8x16b);
843
844
0
            coefdelta_0_8x16b = _mm_load_si128((__m128i *)coef_de1);
845
            // (-3q1+9q0),(-9p0+3p1)
846
0
            tmp_delta0_8x16b = _mm_maddubs_epi16(tmp_delta1_8x16b, coefdelta_0_8x16b);
847
848
            //getting -tc store
849
0
            tmp2_const_8x16b = _mm_cmpeq_epi32(consttc_8x16b, consttc_8x16b);
850
851
            //getting tc in 16 bit
852
0
            consttc_8x16b = _mm_packs_epi32(consttc_8x16b, consttc_8x16b);
853
            //calc 10 *tc = 2*tc +8*tc ; 2*tc
854
0
            tmp_pq_str0_8x16b = _mm_slli_epi16(consttc_8x16b, 1);
855
            //calc 10 *tc = 2*tc +8*tc ; 8*tc
856
0
            tmp_pq_str1_8x16b = _mm_slli_epi16(consttc_8x16b, 3);
857
858
            //const 1
859
0
            const2_8x16b = _mm_srli_epi16(tmp2_const_8x16b, 15);
860
            //calc 10 *tc
861
0
            tmp_pq_str0_8x16b = _mm_add_epi16(tmp_pq_str0_8x16b, tmp_pq_str1_8x16b);
862
            //delta0 without normalisation and clipping
863
0
            tmp_delta0_8x16b = _mm_madd_epi16(tmp_delta0_8x16b, const2_8x16b);
864
865
0
            const2_8x16b = _mm_srli_epi32(tmp2_const_8x16b, 31);
866
867
            //loaded coef for delta1 calculation
868
0
            coefdelta_0_8x16b = _mm_load_si128((__m128i *)coef_dep1);
869
            //(-2q1+q0),(p0-2p1)
870
0
            tmp_delta1_8x16b = _mm_maddubs_epi16(tmp_delta1_8x16b, coefdelta_0_8x16b);
871
            //const 8
872
0
            const2_8x16b = _mm_slli_epi32(const2_8x16b, 3);
873
874
            //normalisation of the filter
875
0
            tmp_delta0_8x16b = _mm_add_epi32(tmp_delta0_8x16b, const2_8x16b);
876
0
            tmp_delta0_8x16b = _mm_srai_epi32(tmp_delta0_8x16b, 4);
877
878
            //getting deltaq0
879
0
            tmp_pq_str1_8x16b = _mm_sign_epi32(tmp_delta0_8x16b, tmp2_const_8x16b);
880
            //getting -tc
881
0
            tmp1_const_8x16b = _mm_sign_epi16(consttc_8x16b, tmp2_const_8x16b);
882
            //packing  d03q d02q d01q d0q d03p d02p d01p d00p
883
0
            tmp_delta0_8x16b = _mm_packs_epi32(tmp_delta0_8x16b, tmp_pq_str1_8x16b);
884
            //absolute delta
885
0
            tmp_pq_str1_8x16b = _mm_abs_epi16(tmp_delta0_8x16b);
886
887
            //Clipping of delta0
888
0
            tmp_delta0_8x16b = _mm_min_epi16(tmp_delta0_8x16b, consttc_8x16b);
889
            //tc>>1 16 bit
890
0
            consttc_8x16b = _mm_srai_epi16(consttc_8x16b, 1);
891
            //Clipping of delta0
892
0
            tmp_delta0_8x16b = _mm_max_epi16(tmp_delta0_8x16b, tmp1_const_8x16b);
893
894
            //(-tc)>>1 16 bit
895
0
            tmp1_const_8x16b = _mm_sign_epi16(consttc_8x16b, tmp2_const_8x16b);
896
            //mask for |delta| < 10*tc
897
0
            tmp_pq_str0_8x16b = _mm_cmpgt_epi16(tmp_pq_str0_8x16b, tmp_pq_str1_8x16b);
898
            //delta 1 calc starts
899
900
            //getting q32 q22 q12 q02 p32 p12 p22 p02
901
0
            tmp0_const_8x16b = _mm_setzero_si128();
902
0
            src_q2_8x16b = _mm_unpacklo_epi8(src_q2_8x16b, tmp0_const_8x16b);
903
0
            src_p2_8x16b = _mm_unpacklo_epi8(src_p2_8x16b, tmp0_const_8x16b);
904
0
            src_p2_8x16b = _mm_unpacklo_epi64(src_p2_8x16b, src_q2_8x16b);
905
            //constant 1
906
0
            const2_8x16b = _mm_srli_epi16(tmp2_const_8x16b, 15);
907
            //2*delta0
908
0
            tmp2_const_8x16b = _mm_add_epi16(tmp_delta0_8x16b, tmp_delta0_8x16b);
909
            //getting  all respective q's and p's together
910
0
            coefdelta_0_8x16b = _mm_load_si128((__m128i *)(shuffle1));
911
0
            tmp_delta1_8x16b = _mm_shuffle_epi8(tmp_delta1_8x16b, coefdelta_0_8x16b);
912
            //final adds for deltap1 and deltaq1
913
0
            tmp_delta1_8x16b = _mm_add_epi16(tmp_delta1_8x16b, const2_8x16b);
914
0
            src_p2_8x16b = _mm_add_epi16(src_p2_8x16b, tmp2_const_8x16b);
915
0
            tmp_delta1_8x16b = _mm_add_epi16(tmp_delta1_8x16b, src_p2_8x16b);
916
0
            tmp_delta1_8x16b = _mm_srai_epi16(tmp_delta1_8x16b, 2);
917
918
            //mask0= (((LWORD64)filter_flag_q)<<63)| (((LWORD64)filter_flag_p)<<31);
919
0
            tmp_pq_str1_8x16b = _mm_loadl_epi64((__m128i *)(&(maskq0)));
920
0
            src_p2_8x16b = _mm_loadl_epi64((__m128i *)(&(maskp0)));
921
922
            //   src_p2_8x16b = _mm_set_epi32(filter_flag_q,filter_flag_p,filter_flag_q,filter_flag_p);
923
            //mask1= (((LWORD64)(filter_flag_q&deq))<<63)|(((LWORD64)(filter_flag_p & dep))<<31);
924
0
            src_q2_8x16b = _mm_loadl_epi64((__m128i *)(&(maskq1)));
925
0
            coefdelta_0_8x16b = _mm_loadl_epi64((__m128i *)(&(maskp1)));
926
927
0
            src_p2_8x16b = _mm_unpacklo_epi32(src_p2_8x16b, tmp_pq_str1_8x16b);
928
0
            src_q2_8x16b = _mm_unpacklo_epi32(coefdelta_0_8x16b, src_q2_8x16b);
929
            //src_q2_8x16b = _mm_set_epi32(deq,dep,deq,dep);
930
0
            src_q2_8x16b = _mm_and_si128(src_q2_8x16b, src_p2_8x16b);
931
932
            //rearranging the mask values
933
0
            src_q2_8x16b = _mm_shuffle_epi32(src_q2_8x16b, 0x50);
934
0
            src_p2_8x16b = _mm_shuffle_epi32(src_p2_8x16b, 0x50);
935
936
0
            src_q2_8x16b = _mm_slli_epi32(src_q2_8x16b, 31);
937
0
            src_p2_8x16b = _mm_slli_epi32(src_p2_8x16b, 31);
938
0
            src_q2_8x16b = _mm_srai_epi32(src_q2_8x16b, 31);
939
0
            src_p2_8x16b = _mm_srai_epi32(src_p2_8x16b, 31);
940
941
            //combining mask delta1
942
0
            tmp_pq_str1_8x16b = _mm_and_si128(tmp_pq_str0_8x16b, src_q2_8x16b);
943
            // clipping delta1
944
0
            tmp_delta1_8x16b = _mm_min_epi16(tmp_delta1_8x16b, consttc_8x16b);
945
            //combining mask delat0
946
0
            tmp_pq_str0_8x16b = _mm_and_si128(tmp_pq_str0_8x16b, src_p2_8x16b);
947
            // clipping delta1
948
0
            tmp_delta1_8x16b = _mm_max_epi16(tmp_delta1_8x16b, tmp1_const_8x16b);
949
950
951
            //masking of the delta values |delta|<10*tc
952
0
            tmp_delta1_8x16b = _mm_and_si128(tmp_delta1_8x16b, tmp_pq_str1_8x16b);
953
0
            tmp_delta0_8x16b = _mm_and_si128(tmp_delta0_8x16b, tmp_pq_str0_8x16b);
954
            //separating p and q delta 0 and addinq p0 and q0
955
0
            tmp_pq_str0_8x16b = _mm_unpacklo_epi64(tmp_delta0_8x16b, tmp0_const_8x16b);
956
0
            tmp_pq_str1_8x16b = _mm_unpackhi_epi64(tmp_delta0_8x16b, tmp0_const_8x16b);
957
0
            src_p0_8x16b = _mm_unpacklo_epi8(src_p0_8x16b, tmp0_const_8x16b);
958
0
            src_q0_8x16b = _mm_unpacklo_epi8(src_q0_8x16b, tmp0_const_8x16b);
959
0
            src_p0_8x16b = _mm_add_epi16(src_p0_8x16b, tmp_pq_str0_8x16b);
960
0
            src_q0_8x16b = _mm_add_epi16(src_q0_8x16b, tmp_pq_str1_8x16b);
961
            //separating p and q delta 0 and addinq p0 and q0
962
0
            tmp_pq_str0_8x16b = _mm_unpacklo_epi64(tmp_delta1_8x16b, tmp0_const_8x16b);
963
0
            tmp_pq_str1_8x16b = _mm_unpackhi_epi64(tmp_delta1_8x16b, tmp0_const_8x16b);
964
0
            src_p1_8x16b = _mm_unpacklo_epi8(src_p1_8x16b, tmp0_const_8x16b);
965
0
            src_q1_8x16b = _mm_unpacklo_epi8(src_q1_8x16b, tmp0_const_8x16b);
966
0
            src_p1_8x16b = _mm_add_epi16(src_p1_8x16b, tmp_pq_str0_8x16b);
967
0
            src_q1_8x16b = _mm_add_epi16(src_q1_8x16b, tmp_pq_str1_8x16b);
968
            //packing p1 q1 and p0 q0 to 8 bit
969
0
            src_p1_8x16b = _mm_packus_epi16(src_p1_8x16b, src_q1_8x16b);
970
0
            src_p0_8x16b = _mm_packus_epi16(src_p0_8x16b, src_q0_8x16b);
971
972
0
            src_q1_8x16b = _mm_srli_si128(src_p1_8x16b, 8);
973
0
            src_q0_8x16b = _mm_srli_si128(src_p0_8x16b, 8);
974
975
0
            _mm_storel_epi64((__m128i *)(pu1_src - 2 * src_strd), src_p1_8x16b);
976
0
            _mm_storel_epi64((__m128i *)(pu1_src - src_strd), src_p0_8x16b);
977
0
            _mm_storel_epi64((__m128i *)(pu1_src), src_q0_8x16b);
978
0
            _mm_storel_epi64((__m128i *)(pu1_src + src_strd), src_q1_8x16b);
979
980
981
0
        }
982
983
984
985
0
    }
986
987
0
}
988
989
void ihevc_deblk_chroma_vert_ssse3(UWORD8 *pu1_src,
990
                                   WORD32 src_strd,
991
                                   WORD32 quant_param_p,
992
                                   WORD32 quant_param_q,
993
                                   WORD32 qp_offset_u,
994
                                   WORD32 qp_offset_v,
995
                                   WORD32 tc_offset_div2,
996
                                   WORD32 filter_flag_p,
997
                                   WORD32 filter_flag_q,
998
                                   WORD8 chroma_fmt_idc)
999
0
{
1000
0
    WORD32 qp_indx_u, qp_chroma_u;
1001
0
    WORD32 qp_indx_v, qp_chroma_v;
1002
0
    WORD32 tc_indx_u, tc_u;
1003
0
    WORD32 tc_indx_v, tc_v;
1004
1005
0
    __m128i src_row_0_16x8b, tmp_pxl_0_16x8b, src_row_2_16x8b, tmp_pxl_1_16x8b;
1006
0
    ASSERT(filter_flag_p || filter_flag_q);
1007
1008
    /* chroma processing is done only if BS is 2             */
1009
    /* this function is assumed to be called only if BS is 2 */
1010
0
    qp_indx_u = qp_offset_u + ((quant_param_p + quant_param_q + 1) >> 1);
1011
0
    qp_indx_v = qp_offset_v + ((quant_param_p + quant_param_q + 1) >> 1);
1012
1013
    /* 8.7.2.5.5 Filtering process for chroma block edges */
1014
0
    if(chroma_fmt_idc == CHROMA_FMT_IDC_YUV444 || chroma_fmt_idc == CHROMA_FMT_IDC_YUV422)
1015
0
    {
1016
0
        qp_chroma_u = MIN(qp_indx_u, 51);
1017
0
        qp_chroma_v = MIN(qp_indx_v, 51);
1018
0
    }
1019
0
    else
1020
0
    {
1021
0
        qp_chroma_u = qp_indx_u < 0 ? qp_indx_u : (qp_indx_u > 57 ? qp_indx_u - 6 : gai4_ihevc_qp_table[qp_indx_u]);
1022
0
        qp_chroma_v = qp_indx_v < 0 ? qp_indx_v : (qp_indx_v > 57 ? qp_indx_v - 6 : gai4_ihevc_qp_table[qp_indx_v]);
1023
0
    }
1024
1025
0
    tc_indx_u = CLIP3(qp_chroma_u + 2 + (tc_offset_div2 << 1), 0, 53);
1026
0
    tc_u = gai4_ihevc_tc_table[tc_indx_u];
1027
1028
0
    tc_indx_v = CLIP3(qp_chroma_v + 2 + (tc_offset_div2 << 1), 0, 53);
1029
0
    tc_v = gai4_ihevc_tc_table[tc_indx_v];
1030
1031
0
    if(0 == tc_u && 0 == tc_v)
1032
0
    {
1033
0
        return;
1034
0
    }
1035
0
    src_row_0_16x8b = _mm_loadl_epi64((__m128i *)(pu1_src - 4));
1036
0
    tmp_pxl_0_16x8b = _mm_loadl_epi64((__m128i *)(pu1_src + src_strd - 4));
1037
0
    src_row_2_16x8b = _mm_loadl_epi64((__m128i *)(pu1_src + 2 * src_strd - 4));
1038
0
    tmp_pxl_1_16x8b = _mm_loadl_epi64((__m128i *)(pu1_src + 3 * src_strd - 4));
1039
1040
0
    {
1041
0
        LWORD64 mask_tc, mask_flag, mask;
1042
0
        __m128i delta_vu0_16x8b, delta_vu1_16x8b;
1043
0
        __m128i mask_tc_16x8, mask_16x8b, mask_flag_p_16x8b, mask_flag_q_16x8b;
1044
0
        __m128i min_0_16x8b;
1045
0
        __m128i const_16x8b;
1046
0
        mask_flag = (((LWORD64)filter_flag_p) << 31) | (((LWORD64)filter_flag_q) << 63);
1047
0
        mask_tc = (((LWORD64)tc_v) << 16) | ((LWORD64)tc_u);
1048
0
        mask = 0xffff00000000ffffLL;
1049
1050
0
        src_row_0_16x8b = _mm_unpacklo_epi64(src_row_0_16x8b, tmp_pxl_0_16x8b);
1051
0
        src_row_2_16x8b = _mm_unpacklo_epi64(src_row_2_16x8b, tmp_pxl_1_16x8b);
1052
1053
0
        mask_16x8b = _mm_load_si128((__m128i *)(shuffle_uv));
1054
        // qv11 qu11 qv10 qu10 qv01 qu01 qv00 qu00 pv10 pu10 pv11 pu11 pv00 pu00 pv01 pu01
1055
        // qv31 qu31 qv30 qu30 qv21 qu21 qv20 qu20 pv30 pu30 pv31 pu31 pv20 pu20 pv21 pu21
1056
0
        delta_vu0_16x8b = _mm_shuffle_epi8(src_row_0_16x8b, mask_16x8b);
1057
0
        delta_vu1_16x8b = _mm_shuffle_epi8(src_row_2_16x8b, mask_16x8b);
1058
1059
0
        tmp_pxl_0_16x8b = _mm_unpacklo_epi64(delta_vu0_16x8b, delta_vu1_16x8b);
1060
0
        tmp_pxl_1_16x8b = _mm_unpackhi_epi64(delta_vu0_16x8b, delta_vu1_16x8b);
1061
        // pv30 pv31 pu30 pu31 pv20 pv21 pu20 pu21 pv10 pv11 pu10 pu11 pv00 pv01 pu00 pu01
1062
        // qv31 qv30 qu31 qu30 qv21 qv20 qu21 qu20 qv11 qv10 qu11 qu10 qv01 qv00 qu01 qu00
1063
0
        delta_vu0_16x8b = _mm_load_si128((__m128i *)delta0);
1064
0
        delta_vu1_16x8b = _mm_load_si128((__m128i *)delta1);
1065
1066
0
        delta_vu0_16x8b = _mm_maddubs_epi16(tmp_pxl_0_16x8b, delta_vu0_16x8b);
1067
0
        delta_vu1_16x8b = _mm_maddubs_epi16(tmp_pxl_1_16x8b, delta_vu1_16x8b);
1068
1069
        //generating offset 4
1070
0
        const_16x8b = _mm_cmpeq_epi16(tmp_pxl_0_16x8b, tmp_pxl_0_16x8b);
1071
        // filter flag mask and tc mask
1072
0
        mask_tc_16x8 = _mm_loadl_epi64((__m128i *)(&mask_tc));
1073
0
        mask_flag_q_16x8b = _mm_loadl_epi64((__m128i *)(&mask_flag));
1074
1075
0
        mask_tc_16x8 = _mm_shuffle_epi32(mask_tc_16x8, 0x00);
1076
0
        mask_flag_q_16x8b = _mm_srai_epi32(mask_flag_q_16x8b, 31);
1077
        //-tc
1078
0
        min_0_16x8b = _mm_sign_epi16(mask_tc_16x8, const_16x8b);
1079
        //converting const 1
1080
0
        const_16x8b = _mm_srli_epi16(const_16x8b, 15);
1081
1082
        //filterp and filterq flag
1083
0
        mask_flag_p_16x8b = _mm_shuffle_epi32(mask_flag_q_16x8b, 0x00);
1084
0
        mask_flag_q_16x8b = _mm_shuffle_epi32(mask_flag_q_16x8b, 0x55);
1085
1086
        //modified delta with a filter (1 -4 4 -1) available in 16 bit
1087
0
        delta_vu0_16x8b = _mm_add_epi16(delta_vu0_16x8b, delta_vu1_16x8b);
1088
        //converting const 4
1089
0
        const_16x8b = _mm_slli_epi16(const_16x8b, 2);
1090
1091
0
        mask_16x8b = _mm_loadl_epi64((__m128i *)(&mask));
1092
        //offset addition
1093
0
        delta_vu0_16x8b = _mm_add_epi16(delta_vu0_16x8b, const_16x8b);
1094
        //eliminating q1
1095
0
        tmp_pxl_1_16x8b = _mm_slli_epi16(tmp_pxl_1_16x8b, 8);
1096
1097
0
        const_16x8b = _mm_setzero_si128();
1098
        //filter after normalisation
1099
0
        delta_vu0_16x8b = _mm_srai_epi16(delta_vu0_16x8b, 3);
1100
0
        mask_16x8b = _mm_shuffle_epi32(mask_16x8b, 0x44);
1101
1102
        //clipping MAX
1103
0
        delta_vu0_16x8b = _mm_min_epi16(delta_vu0_16x8b, mask_tc_16x8);
1104
        //getting p0 and eliminating p1
1105
0
        tmp_pxl_0_16x8b = _mm_srli_epi16(tmp_pxl_0_16x8b, 8);
1106
        //clipping MIN
1107
0
        delta_vu0_16x8b = _mm_max_epi16(delta_vu0_16x8b, min_0_16x8b);
1108
        //getting q0
1109
0
        tmp_pxl_1_16x8b = _mm_srli_epi16(tmp_pxl_1_16x8b, 8);
1110
        //masking filter flag
1111
0
        delta_vu1_16x8b = _mm_and_si128(delta_vu0_16x8b, mask_flag_q_16x8b);
1112
0
        delta_vu0_16x8b = _mm_and_si128(delta_vu0_16x8b, mask_flag_p_16x8b);
1113
1114
        // q-delta ,p+delta
1115
0
        tmp_pxl_1_16x8b = _mm_sub_epi16(tmp_pxl_1_16x8b, delta_vu1_16x8b);
1116
0
        tmp_pxl_0_16x8b = _mm_add_epi16(tmp_pxl_0_16x8b, delta_vu0_16x8b);
1117
        //merging q0 and p0 of respective rows
1118
0
        delta_vu1_16x8b = _mm_unpackhi_epi32(tmp_pxl_0_16x8b, tmp_pxl_1_16x8b);
1119
0
        delta_vu0_16x8b = _mm_unpacklo_epi32(tmp_pxl_0_16x8b, tmp_pxl_1_16x8b);
1120
        // row 0 and row 1 packed , row2 and row3 packed
1121
0
        delta_vu0_16x8b = _mm_packus_epi16(delta_vu0_16x8b, const_16x8b);
1122
0
        delta_vu1_16x8b = _mm_packus_epi16(delta_vu1_16x8b, const_16x8b);
1123
        //removing older pixel values
1124
0
        src_row_0_16x8b = _mm_and_si128(src_row_0_16x8b, mask_16x8b);
1125
0
        src_row_2_16x8b = _mm_and_si128(src_row_2_16x8b, mask_16x8b);
1126
        //arranging modified pixels
1127
0
        delta_vu0_16x8b = _mm_shuffle_epi32(delta_vu0_16x8b, 0xd8);
1128
0
        delta_vu1_16x8b = _mm_shuffle_epi32(delta_vu1_16x8b, 0xd8);
1129
0
        delta_vu0_16x8b = _mm_slli_epi64(delta_vu0_16x8b, 16);
1130
0
        delta_vu1_16x8b = _mm_slli_epi64(delta_vu1_16x8b, 16);
1131
        //plugging the modified values
1132
0
        src_row_0_16x8b = _mm_or_si128(src_row_0_16x8b, delta_vu0_16x8b);
1133
0
        src_row_2_16x8b = _mm_or_si128(src_row_2_16x8b, delta_vu1_16x8b);
1134
1135
1136
        //geting values for row1 and row 3
1137
0
        tmp_pxl_0_16x8b = _mm_srli_si128(src_row_0_16x8b, 8);
1138
0
        tmp_pxl_1_16x8b = _mm_srli_si128(src_row_2_16x8b, 8);
1139
1140
0
        _mm_storel_epi64((__m128i *)(pu1_src - 4), src_row_0_16x8b);
1141
0
        _mm_storel_epi64((__m128i *)((pu1_src - 4) + src_strd), tmp_pxl_0_16x8b);
1142
0
        _mm_storel_epi64((__m128i *)((pu1_src - 4) + 2 * src_strd), src_row_2_16x8b);
1143
0
        _mm_storel_epi64((__m128i *)((pu1_src - 4) + 3 * src_strd), tmp_pxl_1_16x8b);
1144
0
    }
1145
1146
1147
1148
0
}
1149
1150
void ihevc_deblk_chroma_horz_ssse3(UWORD8 *pu1_src,
1151
                                   WORD32 src_strd,
1152
                                   WORD32 quant_param_p,
1153
                                   WORD32 quant_param_q,
1154
                                   WORD32 qp_offset_u,
1155
                                   WORD32 qp_offset_v,
1156
                                   WORD32 tc_offset_div2,
1157
                                   WORD32 filter_flag_p,
1158
                                   WORD32 filter_flag_q,
1159
                                   WORD8 chroma_fmt_idc)
1160
0
{
1161
0
    WORD32 qp_indx_u, qp_chroma_u;
1162
0
    WORD32 qp_indx_v, qp_chroma_v;
1163
0
    WORD32 tc_indx_u, tc_u;
1164
0
    WORD32 tc_indx_v, tc_v;
1165
1166
1167
0
    __m128i tmp_p0_16x8b, src_p0_16x8b, src_q0_16x8b, tmp_q0_16x8b;
1168
1169
0
    ASSERT(filter_flag_p || filter_flag_q);
1170
1171
    /* chroma processing is done only if BS is 2             */
1172
    /* this function is assumed to be called only if BS is 2 */
1173
0
    qp_indx_u = qp_offset_u + ((quant_param_p + quant_param_q + 1) >> 1);
1174
0
    qp_indx_v = qp_offset_v + ((quant_param_p + quant_param_q + 1) >> 1);
1175
1176
    /* 8.7.2.5.5 Filtering process for chroma block edges */
1177
0
    if(chroma_fmt_idc == CHROMA_FMT_IDC_YUV444 || chroma_fmt_idc == CHROMA_FMT_IDC_YUV422)
1178
0
    {
1179
0
        qp_chroma_u = MIN(qp_indx_u, 51);
1180
0
        qp_chroma_v = MIN(qp_indx_v, 51);
1181
0
    }
1182
0
    else
1183
0
    {
1184
0
        qp_chroma_u = qp_indx_u < 0 ? qp_indx_u : (qp_indx_u > 57 ? qp_indx_u - 6 : gai4_ihevc_qp_table[qp_indx_u]);
1185
0
        qp_chroma_v = qp_indx_v < 0 ? qp_indx_v : (qp_indx_v > 57 ? qp_indx_v - 6 : gai4_ihevc_qp_table[qp_indx_v]);
1186
0
    }
1187
1188
0
    tc_indx_u = CLIP3(qp_chroma_u + 2 + (tc_offset_div2 << 1), 0, 53);
1189
0
    tc_u = gai4_ihevc_tc_table[tc_indx_u];
1190
1191
0
    tc_indx_v = CLIP3(qp_chroma_v + 2 + (tc_offset_div2 << 1), 0, 53);
1192
0
    tc_v = gai4_ihevc_tc_table[tc_indx_v];
1193
1194
0
    if(0 == tc_u && 0 == tc_v)
1195
0
    {
1196
0
        return;
1197
0
    }
1198
0
    tmp_p0_16x8b = _mm_loadl_epi64((__m128i *)(pu1_src - 2 * src_strd));
1199
0
    src_p0_16x8b = _mm_loadl_epi64((__m128i *)(pu1_src - src_strd));
1200
0
    src_q0_16x8b = _mm_loadl_epi64((__m128i *)(pu1_src));
1201
0
    tmp_q0_16x8b = _mm_loadl_epi64((__m128i *)(pu1_src + src_strd));
1202
1203
0
    {
1204
0
        LWORD64 mask_tc, mask_flag;
1205
0
        __m128i delta_vu0_16x8b, delta_vu1_16x8b;
1206
0
        __m128i mask_tc_16x8, mask_16x8b, mask_flag_p_16x8b, mask_flag_q_16x8b;
1207
0
        __m128i min_0_16x8b;
1208
0
        __m128i const_16x8b;
1209
0
        mask_flag = (((LWORD64)filter_flag_p) << 31) | (((LWORD64)filter_flag_q) << 63);
1210
0
        mask_tc = (((LWORD64)tc_v) << 16) | ((LWORD64)tc_u);
1211
1212
0
        tmp_p0_16x8b = _mm_unpacklo_epi8(tmp_p0_16x8b, src_p0_16x8b);
1213
0
        tmp_q0_16x8b = _mm_unpacklo_epi8(src_q0_16x8b, tmp_q0_16x8b);
1214
1215
        // pv30 pv31 pu30 pu31 pv20 pv21 pu20 pu21 pv10 pv11 pu10 pu11 pv00 pv01 pu00 pu01
1216
        // qv31 qv30 qu31 qu30 qv21 qv20 qu21 qu20 qv11 qv10 qu11 qu10 qv01 qv00 qu01 qu00
1217
0
        delta_vu0_16x8b = _mm_load_si128((__m128i *)delta0);
1218
0
        delta_vu1_16x8b = _mm_load_si128((__m128i *)delta1);
1219
1220
0
        delta_vu0_16x8b = _mm_maddubs_epi16(tmp_p0_16x8b, delta_vu0_16x8b);
1221
0
        delta_vu1_16x8b = _mm_maddubs_epi16(tmp_q0_16x8b, delta_vu1_16x8b);
1222
1223
1224
        // filter flag mask and tc mask
1225
0
        mask_tc_16x8 = _mm_loadl_epi64((__m128i *)(&mask_tc));
1226
0
        mask_flag_q_16x8b = _mm_loadl_epi64((__m128i *)(&mask_flag));
1227
1228
        //generating offset 4
1229
0
        const_16x8b = _mm_cmpeq_epi16(tmp_p0_16x8b, tmp_p0_16x8b);
1230
        // filter flag mask and tc mask
1231
0
        mask_tc_16x8 = _mm_shuffle_epi32(mask_tc_16x8, 0x00);
1232
0
        mask_flag_q_16x8b = _mm_srai_epi32(mask_flag_q_16x8b, 31);
1233
        //-tc
1234
0
        min_0_16x8b = _mm_sign_epi16(mask_tc_16x8, const_16x8b);
1235
        //converting const 1
1236
0
        const_16x8b = _mm_srli_epi16(const_16x8b, 15);
1237
1238
        //filterp
1239
0
        mask_flag_p_16x8b = _mm_shuffle_epi32(mask_flag_q_16x8b, 0x00);
1240
1241
1242
        //converting const 4
1243
0
        const_16x8b = _mm_slli_epi16(const_16x8b, 2);
1244
        //modified delta with a filter (1 -4 4 -1) available in 16 bit
1245
0
        delta_vu0_16x8b = _mm_add_epi16(delta_vu0_16x8b, delta_vu1_16x8b);
1246
1247
        //filterq flag
1248
0
        mask_flag_q_16x8b = _mm_shuffle_epi32(mask_flag_q_16x8b, 0x55);
1249
        //offset addition
1250
0
        delta_vu0_16x8b = _mm_add_epi16(delta_vu0_16x8b, const_16x8b);
1251
0
        mask_16x8b = _mm_setzero_si128();
1252
        //filter after normalisation
1253
0
        delta_vu0_16x8b = _mm_srai_epi16(delta_vu0_16x8b, 3);
1254
1255
        //converting p0 to 16bit
1256
0
        src_p0_16x8b = _mm_unpacklo_epi8(src_p0_16x8b, mask_16x8b);
1257
        //clipping MAX
1258
0
        delta_vu0_16x8b = _mm_min_epi16(delta_vu0_16x8b, mask_tc_16x8);
1259
        //converting q0 to 16bit
1260
0
        src_q0_16x8b = _mm_unpacklo_epi8(src_q0_16x8b, mask_16x8b);
1261
        //clipping MIN
1262
0
        delta_vu0_16x8b = _mm_max_epi16(delta_vu0_16x8b, min_0_16x8b);
1263
1264
        //masking filter flag
1265
0
        delta_vu1_16x8b = _mm_and_si128(delta_vu0_16x8b, mask_flag_q_16x8b);
1266
0
        delta_vu0_16x8b = _mm_and_si128(delta_vu0_16x8b, mask_flag_p_16x8b);
1267
1268
        // q-delta ,p+delta
1269
0
        src_q0_16x8b = _mm_sub_epi16(src_q0_16x8b, delta_vu1_16x8b);
1270
0
        src_p0_16x8b = _mm_add_epi16(src_p0_16x8b, delta_vu0_16x8b);
1271
1272
        // p0 and q0 packed
1273
0
        src_q0_16x8b = _mm_packus_epi16(src_q0_16x8b, mask_16x8b);
1274
0
        src_p0_16x8b = _mm_packus_epi16(src_p0_16x8b, mask_16x8b);
1275
1276
1277
1278
0
        _mm_storel_epi64((__m128i *)(pu1_src - src_strd), src_p0_16x8b);
1279
0
        _mm_storel_epi64((__m128i *)(pu1_src), src_q0_16x8b);
1280
1281
0
    }
1282
1283
1284
0
}