• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Loongson LASX optimized h264dsp
3  *
4  * Copyright (c) 2021 Loongson Technology Corporation Limited
5  * Contributed by Shiyou Yin <yinshiyou-hf@loongson.cn>
6  *                Xiwei  Gu  <guxiwei-hf@loongson.cn>
7  *
8  * This file is part of FFmpeg.
9  *
10  * FFmpeg is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * FFmpeg is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with FFmpeg; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23  */
24 
25 #include "libavutil/loongarch/loongson_intrinsics.h"
26 #include "h264dsp_lasx.h"
27 #include "libavcodec/bit_depth_template.c"
28 
29 #define AVC_ITRANS_H(in0, in1, in2, in3, out0, out1, out2, out3)     \
30 {                                                                    \
31    __m256i tmp0_m, tmp1_m, tmp2_m, tmp3_m;                           \
32                                                                      \
33     tmp0_m = __lasx_xvadd_h(in0, in2);                               \
34     tmp1_m = __lasx_xvsub_h(in0, in2);                               \
35     tmp2_m = __lasx_xvsrai_h(in1, 1);                                \
36     tmp2_m = __lasx_xvsub_h(tmp2_m, in3);                            \
37     tmp3_m = __lasx_xvsrai_h(in3, 1);                                \
38     tmp3_m = __lasx_xvadd_h(in1, tmp3_m);                            \
39                                                                      \
40     LASX_BUTTERFLY_4_H(tmp0_m, tmp1_m, tmp2_m, tmp3_m,               \
41                        out0, out1, out2, out3);                      \
42 }
43 
ff_h264_idct_add_lasx(uint8_t * dst,int16_t * src,int32_t dst_stride)44 void ff_h264_idct_add_lasx(uint8_t *dst, int16_t *src, int32_t dst_stride)
45 {
46     __m256i src0_m, src1_m, src2_m, src3_m;
47     __m256i dst0_m, dst1_m;
48     __m256i hres0, hres1, hres2, hres3, vres0, vres1, vres2, vres3;
49     __m256i inp0_m, inp1_m, res0_m, src1, src3;
50     __m256i src0 = __lasx_xvld(src, 0);
51     __m256i src2 = __lasx_xvld(src, 16);
52     __m256i zero = __lasx_xvldi(0);
53     int32_t dst_stride_2x = dst_stride << 1;
54     int32_t dst_stride_3x = dst_stride_2x + dst_stride;
55 
56     __lasx_xvst(zero, src, 0);
57     DUP2_ARG2(__lasx_xvilvh_d, src0, src0, src2, src2, src1, src3);
58     AVC_ITRANS_H(src0, src1, src2, src3, hres0, hres1, hres2, hres3);
59     LASX_TRANSPOSE4x4_H(hres0, hres1, hres2, hres3, hres0, hres1, hres2, hres3);
60     AVC_ITRANS_H(hres0, hres1, hres2, hres3, vres0, vres1, vres2, vres3);
61     DUP4_ARG2(__lasx_xvldx, dst, 0, dst, dst_stride, dst, dst_stride_2x,
62               dst, dst_stride_3x, src0_m, src1_m, src2_m, src3_m);
63     DUP4_ARG2(__lasx_xvld, dst, 0, dst + dst_stride, 0, dst + dst_stride_2x,
64               0, dst + dst_stride_3x, 0, src0_m, src1_m, src2_m, src3_m);
65     DUP2_ARG2(__lasx_xvilvl_d, vres1, vres0, vres3, vres2, inp0_m, inp1_m);
66     inp0_m = __lasx_xvpermi_q(inp1_m, inp0_m, 0x20);
67     inp0_m = __lasx_xvsrari_h(inp0_m, 6);
68     DUP2_ARG2(__lasx_xvilvl_w, src1_m, src0_m, src3_m, src2_m, dst0_m, dst1_m);
69     dst0_m = __lasx_xvilvl_d(dst1_m, dst0_m);
70     res0_m = __lasx_vext2xv_hu_bu(dst0_m);
71     res0_m = __lasx_xvadd_h(res0_m, inp0_m);
72     res0_m = __lasx_xvclip255_h(res0_m);
73     dst0_m = __lasx_xvpickev_b(res0_m, res0_m);
74     __lasx_xvstelm_w(dst0_m, dst, 0, 0);
75     __lasx_xvstelm_w(dst0_m, dst + dst_stride, 0, 1);
76     __lasx_xvstelm_w(dst0_m, dst + dst_stride_2x, 0, 4);
77     __lasx_xvstelm_w(dst0_m, dst + dst_stride_3x, 0, 5);
78 }
79 
ff_h264_idct8_addblk_lasx(uint8_t * dst,int16_t * src,int32_t dst_stride)80 void ff_h264_idct8_addblk_lasx(uint8_t *dst, int16_t *src,
81                                int32_t dst_stride)
82 {
83     __m256i src0, src1, src2, src3, src4, src5, src6, src7;
84     __m256i vec0, vec1, vec2, vec3;
85     __m256i tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
86     __m256i res0, res1, res2, res3, res4, res5, res6, res7;
87     __m256i dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7;
88     __m256i zero = __lasx_xvldi(0);
89     int32_t dst_stride_2x = dst_stride << 1;
90     int32_t dst_stride_4x = dst_stride << 2;
91     int32_t dst_stride_3x = dst_stride_2x + dst_stride;
92 
93     src[0] += 32;
94     DUP4_ARG2(__lasx_xvld, src, 0, src, 16, src, 32, src, 48,
95               src0, src1, src2, src3);
96     DUP4_ARG2(__lasx_xvld, src, 64, src, 80, src, 96, src, 112,
97               src4, src5, src6, src7);
98     __lasx_xvst(zero, src, 0);
99     __lasx_xvst(zero, src, 32);
100     __lasx_xvst(zero, src, 64);
101     __lasx_xvst(zero, src, 96);
102 
103     vec0 = __lasx_xvadd_h(src0, src4);
104     vec1 = __lasx_xvsub_h(src0, src4);
105     vec2 = __lasx_xvsrai_h(src2, 1);
106     vec2 = __lasx_xvsub_h(vec2, src6);
107     vec3 = __lasx_xvsrai_h(src6, 1);
108     vec3 = __lasx_xvadd_h(src2, vec3);
109 
110     LASX_BUTTERFLY_4_H(vec0, vec1, vec2, vec3, tmp0, tmp1, tmp2, tmp3);
111 
112     vec0 = __lasx_xvsrai_h(src7, 1);
113     vec0 = __lasx_xvsub_h(src5, vec0);
114     vec0 = __lasx_xvsub_h(vec0, src3);
115     vec0 = __lasx_xvsub_h(vec0, src7);
116 
117     vec1 = __lasx_xvsrai_h(src3, 1);
118     vec1 = __lasx_xvsub_h(src1, vec1);
119     vec1 = __lasx_xvadd_h(vec1, src7);
120     vec1 = __lasx_xvsub_h(vec1, src3);
121 
122     vec2 = __lasx_xvsrai_h(src5, 1);
123     vec2 = __lasx_xvsub_h(vec2, src1);
124     vec2 = __lasx_xvadd_h(vec2, src7);
125     vec2 = __lasx_xvadd_h(vec2, src5);
126 
127     vec3 = __lasx_xvsrai_h(src1, 1);
128     vec3 = __lasx_xvadd_h(src3, vec3);
129     vec3 = __lasx_xvadd_h(vec3, src5);
130     vec3 = __lasx_xvadd_h(vec3, src1);
131 
132     tmp4 = __lasx_xvsrai_h(vec3, 2);
133     tmp4 = __lasx_xvadd_h(tmp4, vec0);
134     tmp5 = __lasx_xvsrai_h(vec2, 2);
135     tmp5 = __lasx_xvadd_h(tmp5, vec1);
136     tmp6 = __lasx_xvsrai_h(vec1, 2);
137     tmp6 = __lasx_xvsub_h(tmp6, vec2);
138     tmp7 = __lasx_xvsrai_h(vec0, 2);
139     tmp7 = __lasx_xvsub_h(vec3, tmp7);
140 
141     LASX_BUTTERFLY_8_H(tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7,
142                        res0, res1, res2, res3, res4, res5, res6, res7);
143     LASX_TRANSPOSE8x8_H(res0, res1, res2, res3, res4, res5, res6, res7,
144                         res0, res1, res2, res3, res4, res5, res6, res7);
145 
146     DUP4_ARG1(__lasx_vext2xv_w_h, res0, res1, res2, res3,
147               tmp0, tmp1, tmp2, tmp3);
148     DUP4_ARG1(__lasx_vext2xv_w_h, res4, res5, res6, res7,
149               tmp4, tmp5, tmp6, tmp7);
150     vec0 = __lasx_xvadd_w(tmp0, tmp4);
151     vec1 = __lasx_xvsub_w(tmp0, tmp4);
152 
153     vec2 = __lasx_xvsrai_w(tmp2, 1);
154     vec2 = __lasx_xvsub_w(vec2, tmp6);
155     vec3 = __lasx_xvsrai_w(tmp6, 1);
156     vec3 = __lasx_xvadd_w(vec3, tmp2);
157 
158     tmp0 = __lasx_xvadd_w(vec0, vec3);
159     tmp2 = __lasx_xvadd_w(vec1, vec2);
160     tmp4 = __lasx_xvsub_w(vec1, vec2);
161     tmp6 = __lasx_xvsub_w(vec0, vec3);
162 
163     vec0 = __lasx_xvsrai_w(tmp7, 1);
164     vec0 = __lasx_xvsub_w(tmp5, vec0);
165     vec0 = __lasx_xvsub_w(vec0, tmp3);
166     vec0 = __lasx_xvsub_w(vec0, tmp7);
167 
168     vec1 = __lasx_xvsrai_w(tmp3, 1);
169     vec1 = __lasx_xvsub_w(tmp1, vec1);
170     vec1 = __lasx_xvadd_w(vec1, tmp7);
171     vec1 = __lasx_xvsub_w(vec1, tmp3);
172 
173     vec2 = __lasx_xvsrai_w(tmp5, 1);
174     vec2 = __lasx_xvsub_w(vec2, tmp1);
175     vec2 = __lasx_xvadd_w(vec2, tmp7);
176     vec2 = __lasx_xvadd_w(vec2, tmp5);
177 
178     vec3 = __lasx_xvsrai_w(tmp1, 1);
179     vec3 = __lasx_xvadd_w(tmp3, vec3);
180     vec3 = __lasx_xvadd_w(vec3, tmp5);
181     vec3 = __lasx_xvadd_w(vec3, tmp1);
182 
183     tmp1 = __lasx_xvsrai_w(vec3, 2);
184     tmp1 = __lasx_xvadd_w(tmp1, vec0);
185     tmp3 = __lasx_xvsrai_w(vec2, 2);
186     tmp3 = __lasx_xvadd_w(tmp3, vec1);
187     tmp5 = __lasx_xvsrai_w(vec1, 2);
188     tmp5 = __lasx_xvsub_w(tmp5, vec2);
189     tmp7 = __lasx_xvsrai_w(vec0, 2);
190     tmp7 = __lasx_xvsub_w(vec3, tmp7);
191 
192     LASX_BUTTERFLY_4_W(tmp0, tmp2, tmp5, tmp7, res0, res1, res6, res7);
193     LASX_BUTTERFLY_4_W(tmp4, tmp6, tmp1, tmp3, res2, res3, res4, res5);
194 
195     DUP4_ARG2(__lasx_xvsrai_w, res0, 6, res1, 6, res2, 6, res3, 6,
196               res0, res1, res2, res3);
197     DUP4_ARG2(__lasx_xvsrai_w, res4, 6, res5, 6, res6, 6, res7, 6,
198               res4, res5, res6, res7);
199     DUP4_ARG2(__lasx_xvpickev_h, res1, res0, res3, res2, res5, res4, res7,
200               res6, res0, res1, res2, res3);
201     DUP4_ARG2(__lasx_xvpermi_d, res0, 0xd8, res1, 0xd8, res2, 0xd8, res3, 0xd8,
202               res0, res1, res2, res3);
203 
204     DUP4_ARG2(__lasx_xvldx, dst, 0, dst, dst_stride, dst, dst_stride_2x,
205               dst, dst_stride_3x, dst0, dst1, dst2, dst3);
206     dst += dst_stride_4x;
207     DUP4_ARG2(__lasx_xvldx, dst, 0, dst, dst_stride, dst, dst_stride_2x,
208               dst, dst_stride_3x, dst4, dst5, dst6, dst7);
209     dst -= dst_stride_4x;
210     DUP4_ARG2(__lasx_xvilvl_b, zero, dst0, zero, dst1, zero, dst2, zero, dst3,
211               dst0, dst1, dst2, dst3);
212     DUP4_ARG2(__lasx_xvilvl_b, zero, dst4, zero, dst5, zero, dst6, zero, dst7,
213               dst4, dst5, dst6, dst7);
214     DUP4_ARG3(__lasx_xvpermi_q, dst1, dst0, 0x20, dst3, dst2, 0x20, dst5,
215               dst4, 0x20, dst7, dst6, 0x20, dst0, dst1, dst2, dst3);
216     res0 = __lasx_xvadd_h(res0, dst0);
217     res1 = __lasx_xvadd_h(res1, dst1);
218     res2 = __lasx_xvadd_h(res2, dst2);
219     res3 = __lasx_xvadd_h(res3, dst3);
220     DUP4_ARG1(__lasx_xvclip255_h, res0, res1, res2, res3, res0, res1,
221               res2, res3);
222     DUP2_ARG2(__lasx_xvpickev_b, res1, res0, res3, res2, res0, res1);
223     __lasx_xvstelm_d(res0, dst, 0, 0);
224     __lasx_xvstelm_d(res0, dst + dst_stride, 0, 2);
225     __lasx_xvstelm_d(res0, dst + dst_stride_2x, 0, 1);
226     __lasx_xvstelm_d(res0, dst + dst_stride_3x, 0, 3);
227     dst += dst_stride_4x;
228     __lasx_xvstelm_d(res1, dst, 0, 0);
229     __lasx_xvstelm_d(res1, dst + dst_stride, 0, 2);
230     __lasx_xvstelm_d(res1, dst + dst_stride_2x, 0, 1);
231     __lasx_xvstelm_d(res1, dst + dst_stride_3x, 0, 3);
232 }
233 
ff_h264_idct4x4_addblk_dc_lasx(uint8_t * dst,int16_t * src,int32_t dst_stride)234 void ff_h264_idct4x4_addblk_dc_lasx(uint8_t *dst, int16_t *src,
235                                     int32_t dst_stride)
236 {
237     const int16_t dc = (src[0] + 32) >> 6;
238     int32_t dst_stride_2x = dst_stride << 1;
239     int32_t dst_stride_3x = dst_stride_2x + dst_stride;
240     __m256i pred, out;
241     __m256i src0, src1, src2, src3;
242     __m256i input_dc = __lasx_xvreplgr2vr_h(dc);
243 
244     src[0] = 0;
245     DUP4_ARG2(__lasx_xvldx, dst, 0, dst, dst_stride, dst, dst_stride_2x,
246               dst, dst_stride_3x, src0, src1, src2, src3);
247     DUP2_ARG2(__lasx_xvilvl_w, src1, src0, src3, src2, src0, src1);
248 
249     pred = __lasx_xvpermi_q(src0, src1, 0x02);
250     pred = __lasx_xvaddw_h_h_bu(input_dc, pred);
251     pred = __lasx_xvclip255_h(pred);
252     out = __lasx_xvpickev_b(pred, pred);
253     __lasx_xvstelm_w(out, dst, 0, 0);
254     __lasx_xvstelm_w(out, dst + dst_stride, 0, 1);
255     __lasx_xvstelm_w(out, dst + dst_stride_2x, 0, 4);
256     __lasx_xvstelm_w(out, dst + dst_stride_3x, 0, 5);
257 }
258 
ff_h264_idct8_dc_addblk_lasx(uint8_t * dst,int16_t * src,int32_t dst_stride)259 void ff_h264_idct8_dc_addblk_lasx(uint8_t *dst, int16_t *src,
260                                   int32_t dst_stride)
261 {
262     int32_t dc_val;
263     int32_t dst_stride_2x = dst_stride << 1;
264     int32_t dst_stride_4x = dst_stride << 2;
265     int32_t dst_stride_3x = dst_stride_2x + dst_stride;
266     __m256i dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7;
267     __m256i dc;
268 
269     dc_val = (src[0] + 32) >> 6;
270     dc = __lasx_xvreplgr2vr_h(dc_val);
271 
272     src[0] = 0;
273 
274     DUP4_ARG2(__lasx_xvldx, dst, 0, dst, dst_stride, dst, dst_stride_2x,
275               dst, dst_stride_3x, dst0, dst1, dst2, dst3);
276     dst += dst_stride_4x;
277     DUP4_ARG2(__lasx_xvldx, dst, 0, dst, dst_stride, dst, dst_stride_2x,
278               dst, dst_stride_3x, dst4, dst5, dst6, dst7);
279     dst -= dst_stride_4x;
280     DUP4_ARG1(__lasx_vext2xv_hu_bu, dst0, dst1, dst2, dst3,
281               dst0, dst1, dst2, dst3);
282     DUP4_ARG1(__lasx_vext2xv_hu_bu, dst4, dst5, dst6, dst7,
283               dst4, dst5, dst6, dst7);
284     DUP4_ARG3(__lasx_xvpermi_q, dst1, dst0, 0x20, dst3, dst2, 0x20, dst5,
285               dst4, 0x20, dst7, dst6, 0x20, dst0, dst1, dst2, dst3);
286     dst0 = __lasx_xvadd_h(dst0, dc);
287     dst1 = __lasx_xvadd_h(dst1, dc);
288     dst2 = __lasx_xvadd_h(dst2, dc);
289     dst3 = __lasx_xvadd_h(dst3, dc);
290     DUP4_ARG1(__lasx_xvclip255_h, dst0, dst1, dst2, dst3,
291               dst0, dst1, dst2, dst3);
292     DUP2_ARG2(__lasx_xvpickev_b, dst1, dst0, dst3, dst2, dst0, dst1);
293     __lasx_xvstelm_d(dst0, dst, 0, 0);
294     __lasx_xvstelm_d(dst0, dst + dst_stride, 0, 2);
295     __lasx_xvstelm_d(dst0, dst + dst_stride_2x, 0, 1);
296     __lasx_xvstelm_d(dst0, dst + dst_stride_3x, 0, 3);
297     dst += dst_stride_4x;
298     __lasx_xvstelm_d(dst1, dst, 0, 0);
299     __lasx_xvstelm_d(dst1, dst + dst_stride, 0, 2);
300     __lasx_xvstelm_d(dst1, dst + dst_stride_2x, 0, 1);
301     __lasx_xvstelm_d(dst1, dst + dst_stride_3x, 0, 3);
302 }
303 
ff_h264_idct_add16_lasx(uint8_t * dst,const int32_t * blk_offset,int16_t * block,int32_t dst_stride,const uint8_t nzc[15* 8])304 void ff_h264_idct_add16_lasx(uint8_t *dst,
305                              const int32_t *blk_offset,
306                              int16_t *block, int32_t dst_stride,
307                              const uint8_t nzc[15 * 8])
308 {
309     int32_t i;
310 
311     for (i = 0; i < 16; i++) {
312         int32_t nnz = nzc[scan8[i]];
313 
314         if (nnz) {
315             if (nnz == 1 && ((dctcoef *) block)[i * 16])
316                 ff_h264_idct4x4_addblk_dc_lasx(dst + blk_offset[i],
317                                                block + i * 16 * sizeof(pixel),
318                                                dst_stride);
319             else
320                 ff_h264_idct_add_lasx(dst + blk_offset[i],
321                                       block + i * 16 * sizeof(pixel),
322                                       dst_stride);
323         }
324     }
325 }
326 
ff_h264_idct8_add4_lasx(uint8_t * dst,const int32_t * blk_offset,int16_t * block,int32_t dst_stride,const uint8_t nzc[15* 8])327 void ff_h264_idct8_add4_lasx(uint8_t *dst, const int32_t *blk_offset,
328                              int16_t *block, int32_t dst_stride,
329                              const uint8_t nzc[15 * 8])
330 {
331     int32_t cnt;
332 
333     for (cnt = 0; cnt < 16; cnt += 4) {
334         int32_t nnz = nzc[scan8[cnt]];
335 
336         if (nnz) {
337             if (nnz == 1 && ((dctcoef *) block)[cnt * 16])
338                 ff_h264_idct8_dc_addblk_lasx(dst + blk_offset[cnt],
339                                              block + cnt * 16 * sizeof(pixel),
340                                              dst_stride);
341             else
342                 ff_h264_idct8_addblk_lasx(dst + blk_offset[cnt],
343                                           block + cnt * 16 * sizeof(pixel),
344                                           dst_stride);
345         }
346     }
347 }
348 
349 
ff_h264_idct_add8_lasx(uint8_t ** dst,const int32_t * blk_offset,int16_t * block,int32_t dst_stride,const uint8_t nzc[15* 8])350 void ff_h264_idct_add8_lasx(uint8_t **dst,
351                             const int32_t *blk_offset,
352                             int16_t *block, int32_t dst_stride,
353                             const uint8_t nzc[15 * 8])
354 {
355     int32_t i;
356 
357     for (i = 16; i < 20; i++) {
358         if (nzc[scan8[i]])
359             ff_h264_idct_add_lasx(dst[0] + blk_offset[i],
360                                   block + i * 16 * sizeof(pixel),
361                                   dst_stride);
362         else if (((dctcoef *) block)[i * 16])
363             ff_h264_idct4x4_addblk_dc_lasx(dst[0] + blk_offset[i],
364                                            block + i * 16 * sizeof(pixel),
365                                            dst_stride);
366     }
367     for (i = 32; i < 36; i++) {
368         if (nzc[scan8[i]])
369             ff_h264_idct_add_lasx(dst[1] + blk_offset[i],
370                                   block + i * 16 * sizeof(pixel),
371                                   dst_stride);
372         else if (((dctcoef *) block)[i * 16])
373             ff_h264_idct4x4_addblk_dc_lasx(dst[1] + blk_offset[i],
374                                            block + i * 16 * sizeof(pixel),
375                                            dst_stride);
376     }
377 }
378 
ff_h264_idct_add8_422_lasx(uint8_t ** dst,const int32_t * blk_offset,int16_t * block,int32_t dst_stride,const uint8_t nzc[15* 8])379 void ff_h264_idct_add8_422_lasx(uint8_t **dst,
380                                 const int32_t *blk_offset,
381                                 int16_t *block, int32_t dst_stride,
382                                 const uint8_t nzc[15 * 8])
383 {
384     int32_t i;
385 
386     for (i = 16; i < 20; i++) {
387         if (nzc[scan8[i]])
388             ff_h264_idct_add_lasx(dst[0] + blk_offset[i],
389                                   block + i * 16 * sizeof(pixel),
390                                   dst_stride);
391         else if (((dctcoef *) block)[i * 16])
392             ff_h264_idct4x4_addblk_dc_lasx(dst[0] + blk_offset[i],
393                                            block + i * 16 * sizeof(pixel),
394                                            dst_stride);
395     }
396     for (i = 32; i < 36; i++) {
397         if (nzc[scan8[i]])
398             ff_h264_idct_add_lasx(dst[1] + blk_offset[i],
399                                   block + i * 16 * sizeof(pixel),
400                                   dst_stride);
401         else if (((dctcoef *) block)[i * 16])
402             ff_h264_idct4x4_addblk_dc_lasx(dst[1] + blk_offset[i],
403                                            block + i * 16 * sizeof(pixel),
404                                            dst_stride);
405     }
406     for (i = 20; i < 24; i++) {
407         if (nzc[scan8[i + 4]])
408             ff_h264_idct_add_lasx(dst[0] + blk_offset[i + 4],
409                                   block + i * 16 * sizeof(pixel),
410                                   dst_stride);
411         else if (((dctcoef *) block)[i * 16])
412             ff_h264_idct4x4_addblk_dc_lasx(dst[0] + blk_offset[i + 4],
413                                            block + i * 16 * sizeof(pixel),
414                                            dst_stride);
415     }
416     for (i = 36; i < 40; i++) {
417         if (nzc[scan8[i + 4]])
418             ff_h264_idct_add_lasx(dst[1] + blk_offset[i + 4],
419                                   block + i * 16 * sizeof(pixel),
420                                   dst_stride);
421         else if (((dctcoef *) block)[i * 16])
422             ff_h264_idct4x4_addblk_dc_lasx(dst[1] + blk_offset[i + 4],
423                                            block + i * 16 * sizeof(pixel),
424                                            dst_stride);
425     }
426 }
427 
ff_h264_idct_add16_intra_lasx(uint8_t * dst,const int32_t * blk_offset,int16_t * block,int32_t dst_stride,const uint8_t nzc[15* 8])428 void ff_h264_idct_add16_intra_lasx(uint8_t *dst,
429                                    const int32_t *blk_offset,
430                                    int16_t *block,
431                                    int32_t dst_stride,
432                                    const uint8_t nzc[15 * 8])
433 {
434     int32_t i;
435 
436     for (i = 0; i < 16; i++) {
437         if (nzc[scan8[i]])
438             ff_h264_idct_add_lasx(dst + blk_offset[i],
439                                   block + i * 16 * sizeof(pixel), dst_stride);
440         else if (((dctcoef *) block)[i * 16])
441             ff_h264_idct4x4_addblk_dc_lasx(dst + blk_offset[i],
442                                            block + i * 16 * sizeof(pixel),
443                                            dst_stride);
444     }
445 }
446 
ff_h264_deq_idct_luma_dc_lasx(int16_t * dst,int16_t * src,int32_t de_qval)447 void ff_h264_deq_idct_luma_dc_lasx(int16_t *dst, int16_t *src,
448                                    int32_t de_qval)
449 {
450 #define DC_DEST_STRIDE 16
451 
452     __m256i src0, src1, src2, src3;
453     __m256i vec0, vec1, vec2, vec3;
454     __m256i tmp0, tmp1, tmp2, tmp3;
455     __m256i hres0, hres1, hres2, hres3;
456     __m256i vres0, vres1, vres2, vres3;
457     __m256i de_q_vec = __lasx_xvreplgr2vr_w(de_qval);
458 
459     DUP4_ARG2(__lasx_xvld, src, 0, src, 8, src, 16, src, 24,
460               src0, src1, src2, src3);
461     LASX_TRANSPOSE4x4_H(src0, src1, src2, src3, tmp0, tmp1, tmp2, tmp3);
462     LASX_BUTTERFLY_4_H(tmp0, tmp2, tmp3, tmp1, vec0, vec3, vec2, vec1);
463     LASX_BUTTERFLY_4_H(vec0, vec1, vec2, vec3, hres0, hres3, hres2, hres1);
464     LASX_TRANSPOSE4x4_H(hres0, hres1, hres2, hres3,
465                         hres0, hres1, hres2, hres3);
466     LASX_BUTTERFLY_4_H(hres0, hres1, hres3, hres2, vec0, vec3, vec2, vec1);
467     LASX_BUTTERFLY_4_H(vec0, vec1, vec2, vec3, vres0, vres1, vres2, vres3);
468     DUP4_ARG1(__lasx_vext2xv_w_h, vres0, vres1, vres2, vres3,
469               vres0, vres1, vres2, vres3);
470     DUP2_ARG3(__lasx_xvpermi_q, vres1, vres0, 0x20, vres3, vres2, 0x20,
471               vres0, vres1);
472 
473     vres0 = __lasx_xvmul_w(vres0, de_q_vec);
474     vres1 = __lasx_xvmul_w(vres1, de_q_vec);
475 
476     vres0 = __lasx_xvsrari_w(vres0, 8);
477     vres1 = __lasx_xvsrari_w(vres1, 8);
478     vec0 = __lasx_xvpickev_h(vres1, vres0);
479     vec0 = __lasx_xvpermi_d(vec0, 0xd8);
480     __lasx_xvstelm_h(vec0, dst + 0  * DC_DEST_STRIDE, 0, 0);
481     __lasx_xvstelm_h(vec0, dst + 2  * DC_DEST_STRIDE, 0, 1);
482     __lasx_xvstelm_h(vec0, dst + 8  * DC_DEST_STRIDE, 0, 2);
483     __lasx_xvstelm_h(vec0, dst + 10 * DC_DEST_STRIDE, 0, 3);
484     __lasx_xvstelm_h(vec0, dst + 1  * DC_DEST_STRIDE, 0, 4);
485     __lasx_xvstelm_h(vec0, dst + 3  * DC_DEST_STRIDE, 0, 5);
486     __lasx_xvstelm_h(vec0, dst + 9  * DC_DEST_STRIDE, 0, 6);
487     __lasx_xvstelm_h(vec0, dst + 11 * DC_DEST_STRIDE, 0, 7);
488     __lasx_xvstelm_h(vec0, dst + 4  * DC_DEST_STRIDE, 0, 8);
489     __lasx_xvstelm_h(vec0, dst + 6  * DC_DEST_STRIDE, 0, 9);
490     __lasx_xvstelm_h(vec0, dst + 12 * DC_DEST_STRIDE, 0, 10);
491     __lasx_xvstelm_h(vec0, dst + 14 * DC_DEST_STRIDE, 0, 11);
492     __lasx_xvstelm_h(vec0, dst + 5  * DC_DEST_STRIDE, 0, 12);
493     __lasx_xvstelm_h(vec0, dst + 7  * DC_DEST_STRIDE, 0, 13);
494     __lasx_xvstelm_h(vec0, dst + 13 * DC_DEST_STRIDE, 0, 14);
495     __lasx_xvstelm_h(vec0, dst + 15 * DC_DEST_STRIDE, 0, 15);
496 
497 #undef DC_DEST_STRIDE
498 }
499