avcodec/options: leave priv_data in avcodec_copy_context() intact
[ffmpeg.git] / libavcodec / x86 / huffyuvdsp.asm
1 ;******************************************************************************
2 ;* SIMD-optimized HuffYUV functions
3 ;* Copyright (c) 2008 Loren Merritt
4 ;* Copyright (c) 2014 Christophe Gisquet
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 pb_f: times 16 db 15
27 pb_zzzzzzzz77777777: times 8 db -1
28 pb_7: times 8 db 7
29 pb_zzzz3333zzzzbbbb: db -1,-1,-1,-1,3,3,3,3,-1,-1,-1,-1,11,11,11,11
30 pb_zz11zz55zz99zzdd: db -1,-1,1,1,-1,-1,5,5,-1,-1,9,9,-1,-1,13,13
31
32 SECTION_TEXT
33
34 ; void ff_add_hfyu_median_pred_mmxext(uint8_t *dst, const uint8_t *top,
35 ;                                     const uint8_t *diff, int w,
36 ;                                     int *left, int *left_top)
37 %macro LSHIFT 2
38 %if mmsize > 8
39     pslldq  %1, %2
40 %else
41     psllq   %1, 8*(%2)
42 %endif
43 %endmacro
44
45 %macro RSHIFT 2
46 %if mmsize > 8
47     psrldq  %1, %2
48 %else
49     psrlq   %1, 8*(%2)
50 %endif
51 %endmacro
52
53 %macro HFYU_MEDIAN 0
54 cglobal add_hfyu_median_pred, 6,6,8, dst, top, diff, w, left, left_top
55     movu    m0, [topq]
56     mova    m2, m0
57     movd    m4, [left_topq]
58     LSHIFT  m2, 1
59     mova    m1, m0
60     por     m4, m2
61     movd    m3, [leftq]
62     psubb   m0, m4 ; t-tl
63     add    dstq, wq
64     add    topq, wq
65     add   diffq, wq
66     neg      wq
67     jmp .skip
68 .loop:
69     movu    m4, [topq+wq]
70     mova    m0, m4
71     LSHIFT  m4, 1
72     por     m4, m1
73     mova    m1, m0 ; t
74     psubb   m0, m4 ; t-tl
75 .skip:
76     movu    m2, [diffq+wq]
77 %assign i 0
78 %rep mmsize
79     mova    m4, m0
80     paddb   m4, m3 ; t-tl+l
81     mova    m5, m3
82     pmaxub  m3, m1
83     pminub  m5, m1
84     pminub  m3, m4
85     pmaxub  m3, m5 ; median
86     paddb   m3, m2 ; +residual
87 %if i==0
88     mova    m7, m3
89     LSHIFT  m7, mmsize-1
90 %else
91     mova    m6, m3
92     RSHIFT  m7, 1
93     LSHIFT  m6, mmsize-1
94     por     m7, m6
95 %endif
96 %if i<mmsize-1
97     RSHIFT  m0, 1
98     RSHIFT  m1, 1
99     RSHIFT  m2, 1
100 %endif
101 %assign i i+1
102 %endrep
103     movu [dstq+wq], m7
104     add      wq, mmsize
105     jl .loop
106     movzx   r2d, byte [dstq-1]
107     mov [leftq], r2d
108     movzx   r2d, byte [topq-1]
109     mov [left_topq], r2d
110     RET
111 %endmacro
112
113 INIT_MMX mmxext
114 HFYU_MEDIAN
115 INIT_XMM sse2
116 HFYU_MEDIAN
117
118
119 %macro ADD_HFYU_LEFT_LOOP 2 ; %1 = dst_is_aligned, %2 = src_is_aligned
120     add     srcq, wq
121     add     dstq, wq
122     neg     wq
123 %%.loop:
124 %if %2
125     mova    m1, [srcq+wq]
126 %else
127     movu    m1, [srcq+wq]
128 %endif
129     mova    m2, m1
130     psllw   m1, 8
131     paddb   m1, m2
132     mova    m2, m1
133     pshufb  m1, m3
134     paddb   m1, m2
135     pshufb  m0, m5
136     mova    m2, m1
137     pshufb  m1, m4
138     paddb   m1, m2
139 %if mmsize == 16
140     mova    m2, m1
141     pshufb  m1, m6
142     paddb   m1, m2
143 %endif
144     paddb   m0, m1
145 %if %1
146     mova    [dstq+wq], m0
147 %else
148     movq    [dstq+wq], m0
149     movhps  [dstq+wq+8], m0
150 %endif
151     add     wq, mmsize
152     jl %%.loop
153     mov     eax, mmsize-1
154     sub     eax, wd
155     movd    m1, eax
156     pshufb  m0, m1
157     movd    eax, m0
158     RET
159 %endmacro
160
161 ; int ff_add_hfyu_left_pred(uint8_t *dst, const uint8_t *src, int w, int left)
162 INIT_MMX ssse3
163 cglobal add_hfyu_left_pred, 3,3,7, dst, src, w, left
164 .skip_prologue:
165     mova    m5, [pb_7]
166     mova    m4, [pb_zzzz3333zzzzbbbb]
167     mova    m3, [pb_zz11zz55zz99zzdd]
168     movd    m0, leftm
169     psllq   m0, 56
170     ADD_HFYU_LEFT_LOOP 1, 1
171
172 INIT_XMM sse4
173 cglobal add_hfyu_left_pred, 3,3,7, dst, src, w, left
174     mova    m5, [pb_f]
175     mova    m6, [pb_zzzzzzzz77777777]
176     mova    m4, [pb_zzzz3333zzzzbbbb]
177     mova    m3, [pb_zz11zz55zz99zzdd]
178     movd    m0, leftm
179     pslldq  m0, 15
180     test    srcq, 15
181     jnz .src_unaligned
182     test    dstq, 15
183     jnz .dst_unaligned
184     ADD_HFYU_LEFT_LOOP 1, 1
185 .dst_unaligned:
186     ADD_HFYU_LEFT_LOOP 0, 1
187 .src_unaligned:
188     ADD_HFYU_LEFT_LOOP 0, 0
189
190 %macro ADD_BYTES 0
191 cglobal add_bytes, 3,4,2, dst, src, w, size
192     mov  sizeq, wq
193     and  sizeq, -2*mmsize
194     jz  .2
195     add   dstq, sizeq
196     add   srcq, sizeq
197     neg  sizeq
198 .1:
199     mova    m0, [srcq + sizeq]
200     mova    m1, [srcq + sizeq + mmsize]
201     paddb   m0, [dstq + sizeq]
202     paddb   m1, [dstq + sizeq + mmsize]
203     mova   [dstq + sizeq], m0
204     mova   [dstq + sizeq + mmsize], m1
205     add  sizeq, 2*mmsize
206     jl .1
207 .2:
208     and     wq, 2*mmsize-1
209     jz    .end
210     add   dstq, wq
211     add   srcq, wq
212     neg     wq
213 .3
214     mov  sizeb, [srcq + wq]
215     add [dstq + wq], sizeb
216     inc     wq
217     jl .3
218 .end:
219     REP_RET
220 %endmacro
221
222 INIT_MMX mmx
223 ADD_BYTES
224 INIT_XMM sse2
225 ADD_BYTES
226
227 ; void add_hfyu_left_pred_bgr32(uint8_t *dst, const uint8_t *src,
228 ;                               intptr_t w, uint8_t *left)
229 %macro LEFT_BGR32 0
230 cglobal add_hfyu_left_pred_bgr32, 4,4,3, dst, src, w, left
231     shl           wq, 2
232     movd          m0, [leftq]
233     lea         dstq, [dstq + wq]
234     lea         srcq, [srcq + wq]
235     LSHIFT        m0, mmsize-4
236     neg           wq
237 .loop:
238     movu          m1, [srcq+wq]
239     mova          m2, m1
240 %if mmsize == 8
241     punpckhdq     m0, m0
242 %endif
243     LSHIFT        m1, 4
244     paddb         m1, m2
245 %if mmsize == 16
246     pshufd        m0, m0, q3333
247     mova          m2, m1
248     LSHIFT        m1, 8
249     paddb         m1, m2
250 %endif
251     paddb         m0, m1
252     movu   [dstq+wq], m0
253     add           wq, mmsize
254     jl         .loop
255     movd          m0, [dstq-4]
256     movd     [leftq], m0
257     REP_RET
258 %endmacro
259
260 INIT_MMX mmx
261 LEFT_BGR32
262 INIT_XMM sse2
263 LEFT_BGR32