]> git.sesse.net Git - ffmpeg/blob - libavcodec/x86/lossless_videodsp.asm
Merge commit 'b90fdb2c7199cc8b0e8d994fafba1fb4dc181d88'
[ffmpeg] / libavcodec / x86 / lossless_videodsp.asm
1 ;******************************************************************************
2 ;* SIMD lossless video DSP utils
3 ;* Copyright (c) 2008 Loren Merritt
4 ;* Copyright (c) 2014 Michael Niedermayer
5 ;*
6 ;* This file is part of FFmpeg.
7 ;*
8 ;* FFmpeg is free software; you can redistribute it and/or
9 ;* modify it under the terms of the GNU Lesser General Public
10 ;* License as published by the Free Software Foundation; either
11 ;* version 2.1 of the License, or (at your option) any later version.
12 ;*
13 ;* FFmpeg is distributed in the hope that it will be useful,
14 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 ;* Lesser General Public License for more details.
17 ;*
18 ;* You should have received a copy of the GNU Lesser General Public
19 ;* License along with FFmpeg; if not, write to the Free Software
20 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 ;******************************************************************************
22
23 %include "libavutil/x86/x86util.asm"
24
25 SECTION_RODATA
26
27 cextern pb_15
28 pb_zzzzzzzz77777777: times 8 db -1
29 pb_7: times 8 db 7
30 pb_ef: times 8 db 14,15
31 pb_67: times 8 db  6, 7
32 pb_zzzz3333zzzzbbbb: db -1,-1,-1,-1,3,3,3,3,-1,-1,-1,-1,11,11,11,11
33 pb_zz11zz55zz99zzdd: db -1,-1,1,1,-1,-1,5,5,-1,-1,9,9,-1,-1,13,13
34 pb_zzzz2323zzzzabab: db -1,-1,-1,-1, 2, 3, 2, 3,-1,-1,-1,-1,10,11,10,11
35 pb_zzzzzzzz67676767: db -1,-1,-1,-1,-1,-1,-1,-1, 6, 7, 6, 7, 6, 7, 6, 7
36
37 SECTION .text
38
39 ;------------------------------------------------------------------------------
40 ; void ff_add_median_pred_mmxext(uint8_t *dst, const uint8_t *top,
41 ;                                const uint8_t *diff, int w,
42 ;                                int *left, int *left_top)
43 ;------------------------------------------------------------------------------
44 %macro MEDIAN_PRED 0
45 cglobal add_median_pred, 6,6,8, dst, top, diff, w, left, left_top
46     movu    m0, [topq]
47     mova    m2, m0
48     movd    m4, [left_topq]
49     LSHIFT  m2, 1
50     mova    m1, m0
51     por     m4, m2
52     movd    m3, [leftq]
53     psubb   m0, m4 ; t-tl
54     add    dstq, wq
55     add    topq, wq
56     add   diffq, wq
57     neg      wq
58     jmp .skip
59 .loop:
60     movu    m4, [topq+wq]
61     mova    m0, m4
62     LSHIFT  m4, 1
63     por     m4, m1
64     mova    m1, m0 ; t
65     psubb   m0, m4 ; t-tl
66 .skip:
67     movu    m2, [diffq+wq]
68 %assign i 0
69 %rep mmsize
70     mova    m4, m0
71     paddb   m4, m3 ; t-tl+l
72     mova    m5, m3
73     pmaxub  m3, m1
74     pminub  m5, m1
75     pminub  m3, m4
76     pmaxub  m3, m5 ; median
77     paddb   m3, m2 ; +residual
78 %if i==0
79     mova    m7, m3
80     LSHIFT  m7, mmsize-1
81 %else
82     mova    m6, m3
83     RSHIFT  m7, 1
84     LSHIFT  m6, mmsize-1
85     por     m7, m6
86 %endif
87 %if i<mmsize-1
88     RSHIFT  m0, 1
89     RSHIFT  m1, 1
90     RSHIFT  m2, 1
91 %endif
92 %assign i i+1
93 %endrep
94     movu [dstq+wq], m7
95     add      wq, mmsize
96     jl .loop
97     movzx   r2d, byte [dstq-1]
98     mov [leftq], r2d
99     movzx   r2d, byte [topq-1]
100     mov [left_topq], r2d
101     RET
102 %endmacro
103
104 %if ARCH_X86_32
105 INIT_MMX mmxext
106 MEDIAN_PRED
107 %endif
108 INIT_XMM sse2
109 MEDIAN_PRED
110
111
112 %macro ADD_LEFT_LOOP 2 ; %1 = dst_is_aligned, %2 = src_is_aligned
113     add     srcq, wq
114     add     dstq, wq
115     neg     wq
116 %%.loop:
117 %if %2
118     mova    m1, [srcq+wq]
119 %else
120     movu    m1, [srcq+wq]
121 %endif
122     mova    m2, m1
123     psllw   m1, 8
124     paddb   m1, m2
125     mova    m2, m1
126     pshufb  m1, m3
127     paddb   m1, m2
128     pshufb  m0, m5
129     mova    m2, m1
130     pshufb  m1, m4
131     paddb   m1, m2
132 %if mmsize == 16
133     mova    m2, m1
134     pshufb  m1, m6
135     paddb   m1, m2
136 %endif
137     paddb   m0, m1
138 %if %1
139     mova    [dstq+wq], m0
140 %else
141     movq    [dstq+wq], m0
142     movhps  [dstq+wq+8], m0
143 %endif
144     add     wq, mmsize
145     jl %%.loop
146     mov     eax, mmsize-1
147     sub     eax, wd
148     movd    m1, eax
149     pshufb  m0, m1
150     movd    eax, m0
151     RET
152 %endmacro
153
154 ;------------------------------------------------------------------------------
155 ; int ff_add_left_pred(uint8_t *dst, const uint8_t *src, int w, int left)
156 ;------------------------------------------------------------------------------
157 INIT_MMX ssse3
158 cglobal add_left_pred, 3,3,7, dst, src, w, left
159 .skip_prologue:
160     mova    m5, [pb_7]
161     mova    m4, [pb_zzzz3333zzzzbbbb]
162     mova    m3, [pb_zz11zz55zz99zzdd]
163     movd    m0, leftm
164     psllq   m0, 56
165     ADD_LEFT_LOOP 1, 1
166
167 INIT_XMM ssse3
168 cglobal add_left_pred_unaligned, 3,3,7, dst, src, w, left
169     mova    m5, [pb_15]
170     mova    m6, [pb_zzzzzzzz77777777]
171     mova    m4, [pb_zzzz3333zzzzbbbb]
172     mova    m3, [pb_zz11zz55zz99zzdd]
173     movd    m0, leftm
174     pslldq  m0, 15
175     test    srcq, 15
176     jnz .src_unaligned
177     test    dstq, 15
178     jnz .dst_unaligned
179     ADD_LEFT_LOOP 1, 1
180 .dst_unaligned:
181     ADD_LEFT_LOOP 0, 1
182 .src_unaligned:
183     ADD_LEFT_LOOP 0, 0
184
185 ;------------------------------------------------------------------------------
186 ; void ff_add_bytes(uint8_t *dst, uint8_t *src, ptrdiff_t w);
187 ;------------------------------------------------------------------------------
188 %macro ADD_BYTES 0
189 cglobal add_bytes, 3,4,2, dst, src, w, size
190     mov  sizeq, wq
191     and  sizeq, -2*mmsize
192     jz  .2
193     add   dstq, sizeq
194     add   srcq, sizeq
195     neg  sizeq
196 .1:
197     mova    m0, [srcq + sizeq]
198     mova    m1, [srcq + sizeq + mmsize]
199     paddb   m0, [dstq + sizeq]
200     paddb   m1, [dstq + sizeq + mmsize]
201     mova   [dstq + sizeq], m0
202     mova   [dstq + sizeq + mmsize], m1
203     add  sizeq, 2*mmsize
204     jl .1
205 .2:
206     and     wq, 2*mmsize-1
207     jz    .end
208     add   dstq, wq
209     add   srcq, wq
210     neg     wq
211 .3:
212     mov  sizeb, [srcq + wq]
213     add [dstq + wq], sizeb
214     inc     wq
215     jl .3
216 .end:
217     REP_RET
218 %endmacro
219
220 %if ARCH_X86_32
221 INIT_MMX mmx
222 ADD_BYTES
223 %endif
224 INIT_XMM sse2
225 ADD_BYTES
226
227 %if HAVE_AVX2_EXTERNAL
228 INIT_YMM avx2
229 ADD_BYTES
230 %endif
231
232 %macro ADD_HFYU_LEFT_LOOP_INT16 2 ; %1 = dst alignment (a/u), %2 = src alignment (a/u)
233     add     wd, wd
234     add     srcq, wq
235     add     dstq, wq
236     neg     wq
237 %%.loop:
238     mov%2   m1, [srcq+wq]
239     mova    m2, m1
240     pslld   m1, 16
241     paddw   m1, m2
242     mova    m2, m1
243
244     pshufb  m1, m3
245     paddw   m1, m2
246     pshufb  m0, m5
247 %if mmsize == 16
248     mova    m2, m1
249     pshufb  m1, m4
250     paddw   m1, m2
251 %endif
252     paddw   m0, m1
253     pand    m0, m7
254 %ifidn %1, a
255     mova    [dstq+wq], m0
256 %else
257     movq    [dstq+wq], m0
258     movhps  [dstq+wq+8], m0
259 %endif
260     add     wq, mmsize
261     jl %%.loop
262     mov     eax, mmsize-1
263     sub     eax, wd
264     mov     wd, eax
265     shl     wd, 8
266     lea     eax, [wd+eax-1]
267     movd    m1, eax
268     pshufb  m0, m1
269     movd    eax, m0
270     RET
271 %endmacro
272
273 ;---------------------------------------------------------------------------------------------
274 ; int add_left_pred_int16(uint16_t *dst, const uint16_t *src, unsigned mask, int w, int left)
275 ;---------------------------------------------------------------------------------------------
276 INIT_MMX ssse3
277 cglobal add_left_pred_int16, 4,4,8, dst, src, mask, w, left
278 .skip_prologue:
279     mova    m5, [pb_67]
280     mova    m3, [pb_zzzz2323zzzzabab]
281     movd    m0, leftm
282     psllq   m0, 48
283     movd    m7, maskm
284     SPLATW  m7 ,m7
285     ADD_HFYU_LEFT_LOOP_INT16 a, a
286
287 INIT_XMM sse4
288 cglobal add_left_pred_int16, 4,4,8, dst, src, mask, w, left
289     mova    m5, [pb_ef]
290     mova    m4, [pb_zzzzzzzz67676767]
291     mova    m3, [pb_zzzz2323zzzzabab]
292     movd    m0, leftm
293     pslldq  m0, 14
294     movd    m7, maskm
295     SPLATW  m7 ,m7
296     test    srcq, 15
297     jnz .src_unaligned
298     test    dstq, 15
299     jnz .dst_unaligned
300     ADD_HFYU_LEFT_LOOP_INT16 a, a
301 .dst_unaligned:
302     ADD_HFYU_LEFT_LOOP_INT16 u, a
303 .src_unaligned:
304     ADD_HFYU_LEFT_LOOP_INT16 u, u