[svn] / branches / dev-api-3 / xvidcore / src / image / x86_asm / yv12_to_yuyv_mmx.asm Repository:
ViewVC logotype

Annotation of /branches/dev-api-3/xvidcore/src/image/x86_asm/yv12_to_yuyv_mmx.asm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 582 - (view) (download)

1 : Isibaar 3 ;/**************************************************************************
2 :     ; *
3 :     ; * XVID MPEG-4 VIDEO CODEC
4 :     ; * mmx yuv planar to yuyv/uyvy
5 :     ; *
6 :     ; * This program is free software; you can redistribute it and/or modify
7 :     ; * it under the terms of the GNU General Public License as published by
8 :     ; * the Free Software Foundation; either version 2 of the License, or
9 :     ; * (at your option) any later version.
10 :     ; *
11 :     ; * This program is distributed in the hope that it will be useful,
12 :     ; * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 :     ; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 :     ; * GNU General Public License for more details.
15 :     ; *
16 :     ; * You should have received a copy of the GNU General Public License
17 :     ; * along with this program; if not, write to the Free Software
18 :     ; * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 :     ; *
20 :     ; *************************************************************************/
21 :    
22 :     ;/**************************************************************************
23 :     ; *
24 :     ; * History:
25 :     ; *
26 :     ; * 05.12.2001 initial version; (c)2001 peter ross <pross@cs.rmit.edu.au>
27 :     ; *
28 :     ; *************************************************************************/
29 :    
30 :    
31 :     bits 32
32 :    
33 :    
34 :     section .data
35 :    
36 :     %macro cglobal 1
37 :     %ifdef PREFIX
38 :     global _%1
39 :     %define %1 _%1
40 :     %else
41 :     global %1
42 :     %endif
43 :     %endmacro
44 :    
45 :     align 16
46 :    
47 :    
48 :     section .text
49 :    
50 :    
51 :     ;===========================================================================
52 :     ;
53 :     ; void yv12_to_uyvy_mmx(
54 :     ; uint8_t * dst,
55 :     ; int dst_stride,
56 :     ; uint8_t * y_src,
57 :     ; uint8_t * u_src,
58 :     ; uint8_t * v_src,
59 :     ; int y_stride,
60 :     ; int uv_stride,
61 :     ; int width,
62 :     ; int height);
63 :     ;
64 :     ; width must be multiple of 8
65 :     ; ~10% faster than plain c
66 :     ;
67 :     ;===========================================================================
68 :    
69 :     align 16
70 :     cglobal yv12_to_yuyv_mmx
71 :     yv12_to_yuyv_mmx
72 :    
73 :     push ebx
74 :     push ecx
75 :     push esi
76 :     push edi
77 :     push ebp ; STACK BASE = 20
78 :    
79 :     ; global constants
80 :    
81 :     mov ebx, [esp + 20 + 32] ; width
82 :     mov eax, [esp + 20 + 8] ; dst_stride
83 :     sub eax, ebx ;
84 : suxen_drol 582 sub eax, ebx ; eax = dst_stride - (2 * width)
85 : Isibaar 3 push eax ; [esp + 4] = dst_dif
86 :     ; STACK BASE = 24
87 :    
88 :     shr ebx, 3 ; ebx = width / 8
89 :     mov edi, [esp + 24 + 4] ; dst
90 :    
91 :    
92 :     ; --------- flip -------------
93 :    
94 :     mov ebp, [esp + 24 + 36]
95 :     test ebp, ebp
96 :     jl .flip
97 :    
98 :     mov esi, [esp + 24 + 12] ; y_src
99 :     mov ecx, [esp + 24 + 16] ; u_src
100 :     mov edx, [esp + 24 + 20] ; v_src
101 :     shr ebp, 1 ; y = height / 2
102 :     jmp short .yloop
103 :    
104 :    
105 :     .flip
106 :     neg ebp ; height = -height
107 :    
108 :     mov eax, [esp + 24 + 24] ; y_stride
109 :     lea edx, [ebp - 1] ; edx = height - 1
110 :     mul edx
111 :     mov esi, [esp + 24 + 12] ; y_src
112 :     add esi, eax ; y_src += (height - 1) * y_stride
113 :    
114 :     shr ebp, 1 ; y = height / 2
115 :     mov eax, [esp + 24 + 28] ; uv_stride
116 :     lea edx, [ebp - 1] ; edx = height/2 - 1
117 :     mul edx
118 :    
119 :     mov ecx, [esp + 24 + 16] ; u_src
120 :     mov edx, [esp + 24 + 20] ; v_src
121 :     add ecx, eax ; u_src += (height/2 - 1) * uv_stride
122 :     add edx, eax ; v_src += (height/2 - 1) * uv_stride
123 :    
124 :     neg dword [esp + 24 + 24] ; y_stride = -y_stride
125 :     neg dword [esp + 24 + 28] ; uv_stride = -uv_stride
126 :    
127 :     .yloop
128 :     xor eax, eax ; x = 0;
129 :    
130 :     .xloop1
131 :     movd mm0, [ecx+4*eax] ; [ |uuuu]
132 :     movd mm1, [edx+4*eax] ; [ |vvvv]
133 :     movq mm2, [esi+8*eax] ; [yyyy|yyyy]
134 :    
135 :     punpcklbw mm0, mm1 ; [vuvu|vuvu]
136 :     movq mm3, mm2
137 :     punpcklbw mm2, mm0 ; [vyuy|vyuy]
138 :     punpckhbw mm3, mm0 ; [vyuy|vyuy]
139 :     movq [edi], mm2
140 :     movq [edi+8], mm3
141 :    
142 :     inc eax
143 :     add edi, 16
144 :    
145 :     cmp eax, ebx
146 :     jb .xloop1
147 :    
148 :     add edi, [esp + 0] ; dst += dst_dif
149 :     add esi, [esp + 24 + 24] ; y_src += y_stride
150 :    
151 :     xor eax, eax
152 :    
153 :     .xloop2
154 :     movd mm0, [ecx+4*eax] ; [ |uuuu]
155 :     movd mm1, [edx+4*eax] ; [ |vvvv]
156 :     movq mm2, [esi+8*eax] ; [yyyy|yyyy]
157 :    
158 :     punpcklbw mm0, mm1 ; [vuvu|vuvu]
159 :     movq mm3, mm2
160 :     punpcklbw mm2, mm0 ; [vyuy|vyuy]
161 :     punpckhbw mm3, mm0 ; [vyuy|vyuy]
162 :     movq [edi], mm2
163 :     movq [edi+8], mm3
164 :    
165 :     inc eax
166 :     add edi, 16
167 :    
168 :     cmp eax, ebx
169 :     jb .xloop2
170 :    
171 :     add edi, [esp + 0] ; dst += dst_dif
172 :     add esi, [esp + 24 + 24] ; y_src += y_stride
173 :     add ecx, [esp + 24 + 28] ; u_src += uv_stride
174 :     add edx, [esp + 24 + 28] ; v_src += uv_stride
175 :    
176 :     dec ebp ; y--
177 :     jnz near .yloop
178 :    
179 :     emms
180 :    
181 :     add esp, 4
182 :     pop ebp
183 :     pop edi
184 :     pop esi
185 :     pop ecx
186 :     pop ebx
187 :    
188 :     ret
189 :    
190 :    
191 :    
192 :    
193 :    
194 :     ;===========================================================================
195 :     ;
196 :     ; void yv12_to_uyvy_mmx(
197 :     ; uint8_t * dst,
198 :     ; int dst_stride,
199 :     ; uint8_t * y_src,
200 :     ; uint8_t * u_src,
201 :     ; uint8_t * v_src,
202 :     ; int y_stride,
203 :     ; int uv_stride,
204 :     ; int width,
205 :     ; int height);
206 :     ;
207 :     ; width must be multiple of 8
208 :     ; ~10% faster than plain c
209 :     ;
210 :     ;===========================================================================
211 :    
212 :     align 16
213 :     cglobal yv12_to_uyvy_mmx
214 :     yv12_to_uyvy_mmx
215 :    
216 :     push ebx
217 :     push ecx
218 :     push esi
219 :     push edi
220 :     push ebp ; STACK BASE = 20
221 :    
222 :     ; global constants
223 :    
224 :     mov ebx, [esp + 20 + 32] ; width
225 :     mov eax, [esp + 20 + 8] ; dst_stride
226 :     sub eax, ebx ;
227 : suxen_drol 582 sub eax, ebx ; eax = dst_stride - (2 * width)
228 : Isibaar 3 push eax ; [esp + 4] = dst_dif
229 :     ; STACK BASE = 24
230 :    
231 :     shr ebx, 3 ; ebx = width / 8
232 :     mov edi, [esp + 24 + 4] ; dst
233 :    
234 :    
235 :     ; --------- flip -------------
236 :    
237 :     mov ebp, [esp + 24 + 36]
238 :     test ebp, ebp
239 :     jl .flip
240 :    
241 :     mov esi, [esp + 24 + 12] ; y_src
242 :     mov ecx, [esp + 24 + 16] ; u_src
243 :     mov edx, [esp + 24 + 20] ; v_src
244 :     shr ebp, 1 ; y = height / 2
245 :     jmp short .yloop
246 :    
247 :    
248 :     .flip
249 :     neg ebp ; height = -height
250 :    
251 :     mov eax, [esp + 24 + 24] ; y_stride
252 :     lea edx, [ebp - 1] ; edx = height - 1
253 :     mul edx
254 :     mov esi, [esp + 24 + 12] ; y_src
255 :     add esi, eax ; y_src += (height - 1) * y_stride
256 :    
257 :     shr ebp, 1 ; y = height / 2
258 :     mov eax, [esp + 24 + 28] ; uv_stride
259 :     lea edx, [ebp - 1] ; edx = height/2 - 1
260 :     mul edx
261 :    
262 :     mov ecx, [esp + 24 + 16] ; u_src
263 :     mov edx, [esp + 24 + 20] ; v_src
264 :     add ecx, eax ; u_src += (height/2 - 1) * uv_stride
265 :     add edx, eax ; v_src += (height/2 - 1) * uv_stride
266 :    
267 :     neg dword [esp + 24 + 24] ; y_stride = -y_stride
268 :     neg dword [esp + 24 + 28] ; uv_stride = -uv_stride
269 :    
270 :     .yloop
271 :     xor eax, eax ; x = 0;
272 :    
273 :     .xloop1
274 :     movd mm0, [ecx+4*eax] ; [ |uuuu]
275 :     movd mm1, [edx+4*eax] ; [ |vvvv]
276 :     movq mm2, [esi+8*eax] ; [yyyy|yyyy]
277 :    
278 :     punpcklbw mm0, mm1 ; [vuvu|vuvu]
279 :     movq mm1, mm0
280 :     punpcklbw mm0, mm2 ; [yvyu|yvyu]
281 :     punpckhbw mm1, mm2 ; [yvyu|yvyu]
282 :     movq [edi], mm0
283 :     movq [edi+8], mm1
284 :    
285 :     inc eax
286 :     add edi, 16
287 :    
288 :     cmp eax, ebx
289 :     jb .xloop1
290 :    
291 :     add edi, [esp + 0] ; dst += dst_dif
292 :     add esi, [esp + 24 + 24] ; y_src += y_stride
293 :    
294 :     xor eax, eax
295 :    
296 :     .xloop2
297 :     movd mm0, [ecx+4*eax] ; [ |uuuu]
298 :     movd mm1, [edx+4*eax] ; [ |vvvv]
299 :     movq mm2, [esi+8*eax] ; [yyyy|yyyy]
300 :    
301 :     punpcklbw mm0, mm1 ; [vuvu|vuvu]
302 :     movq mm1, mm0
303 :     punpcklbw mm0, mm2 ; [yvyu|yvyu]
304 :     punpckhbw mm1, mm2 ; [yvyu|yvyu]
305 :    
306 :     movq [edi], mm0
307 :     movq [edi+8], mm1
308 :    
309 :     inc eax
310 :     add edi, 16
311 :    
312 :     cmp eax, ebx
313 :     jb .xloop2
314 :    
315 :     add edi, [esp + 0] ; dst += dst_dif
316 :     add esi, [esp + 24 + 24] ; y_src += y_stride
317 :     add ecx, [esp + 24 + 28] ; u_src += uv_stride
318 :     add edx, [esp + 24 + 28] ; v_src += uv_stride
319 :    
320 :     dec ebp ; y--
321 :     jnz near .yloop
322 :    
323 :     emms
324 :    
325 :     add esp, 4
326 :     pop ebp
327 :     pop edi
328 :     pop esi
329 :     pop ecx
330 :     pop ebx
331 :    
332 :     ret

No admin address has been configured
ViewVC Help
Powered by ViewVC 1.0.4