[svn] / trunk / xvidcore / src / image / x86_asm / rgb_to_yv12_mmx.asm Repository:
ViewVC logotype

Annotation of /trunk/xvidcore/src/image/x86_asm/rgb_to_yv12_mmx.asm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3 - (view) (download)

1 : Isibaar 3 ;/**************************************************************************
2 :     ; *
3 :     ; * XVID MPEG-4 VIDEO CODEC
4 :     ; * mmx colorspace conversions
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 :     ; * 24.11.2001 added cglobal macro (Isibaar)
27 :     ; * 23.11.2001 initial version; (c)2001 peter ross <pross@cs.rmit.edu.au>
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 :     ;===========================================================================
49 :     ; yuv constants
50 :     ;===========================================================================
51 :    
52 :     %define Y_R 0.257
53 :     %define Y_G 0.504
54 :     %define Y_B 0.098
55 :     %define Y_ADD 16
56 :    
57 :     %define U_R 0.148
58 :     %define U_G 0.291
59 :     %define U_B 0.439
60 :     %define U_ADD 128
61 :    
62 :     %define V_R 0.439
63 :     %define V_G 0.368
64 :     %define V_B 0.071
65 :     %define V_ADD 128
66 :    
67 :    
68 :     ;===========================================================================
69 :     ; multiplication matrices
70 :     ;===========================================================================
71 :    
72 :     ; %define SCALEBITS 8
73 :    
74 :     y_mul dw 25 ; FIX(Y_B)
75 :     dw 129 ; FIX(Y_G)
76 :     dw 66 ; FIX(Y_R)
77 :     dw 0
78 :    
79 :     u_mul dw 112 ; FIX(U_B)
80 :     dw -74 ; FIX(U_G)
81 :     dw -38 ; FIX(U_R)
82 :     dw 0
83 :    
84 :     v_mul dw -18 ; FIX(V_B)
85 :     dw -94 ; FIX(V_G)
86 :     dw 112 ; FIX(V_R)
87 :     dw 0
88 :    
89 :    
90 :    
91 :     section .text
92 :    
93 :     ;===========================================================================
94 :     ;
95 :     ; void rgb24_to_yv12_mmx(uint8_t * const y_out,
96 :     ; uint8_t * const u_out,
97 :     ; uint8_t * const v_out,
98 :     ; const uint8_t * const src,
99 :     ; const uint32_t width,
100 :     ; const uint32_t height,
101 :     ; const uint32_t stride)
102 :     ;
103 :     ; always flips
104 :     ;
105 :     ;===========================================================================
106 :    
107 :     align 16
108 :     cglobal rgb24_to_yv12_mmx
109 :     rgb24_to_yv12_mmx
110 :    
111 :     push ebx
112 :     push ecx
113 :     push esi
114 :     push edi
115 :     push ebp ; STACK BASE = 20
116 :    
117 :     ; global consants
118 :    
119 :     mov eax, [esp + 20 + 28] ; stride
120 :     mov ecx, [esp + 20 + 20] ; width
121 :     mov ebx, eax
122 :     sub ebx, ecx
123 :     shr ebx, 1 ; ebx = (stride-width) / 2;
124 :     push ebx ; [esp + 20] = uv_dif
125 :     ; STACK BASE = 24
126 :    
127 :     add eax, eax
128 :     sub eax, ecx ; eax = 2*stride - width
129 :     push eax ; [esp + 16] = y_dif
130 :     ; STACK BASE = 28
131 :    
132 :     mov ebx, ecx ;
133 :     shr ebx, 1 ;
134 :     push ebx ; [esp + 12] = width/2
135 :     ; STACK BASE = 32
136 :    
137 :     mov edx, ecx
138 :     add ecx, edx
139 :     add ecx, edx ; ecx = 3*width (use 4 for rgb32)
140 :     push ecx ; [esp + 8] = width3
141 :     ; STACK BASE = 36
142 :    
143 :     mov edx, ecx
144 :     add edx, ecx
145 :     add edx, ecx ; edx = 3*width3
146 :     push edx ; [esp + 4] = src_dif
147 :     ; STACK BASE = 40
148 :    
149 :     mov esi, [esp + 40 + 16] ; src
150 :     mov ebp, [esp + 40 + 24] ; eax = height
151 :     mov eax, ebp
152 :     sub eax, 2
153 :     mul ecx
154 :     add esi, eax ; src += (height-2) * width3
155 :    
156 :     mov edi, [esp + 40 + 4] ; y_out
157 :     mov ecx, [esp + 40 + 8] ; u_out
158 :     mov edx, [esp + 40 + 12] ; v_out
159 :     movq mm7, [y_mul]
160 :    
161 :     shr ebp, 1 ; ebp = height / 2
162 :     push ebp ; [esp+0] = tmp
163 :     ; STACK BASE = 44
164 :    
165 :     .yloop
166 :     mov ebp, [esp + 12] ; ebp = width /2
167 :    
168 :     .xloop
169 :     ; y_out
170 :    
171 :     mov ebx, [esp + 8] ; ebx = width3
172 :    
173 :     pxor mm4, mm4
174 :     pxor mm5, mm5
175 :     movd mm0, [esi] ; src[0...]
176 :     movd mm2, [esi+ebx] ; src[width3...]
177 :     punpcklbw mm0, mm4 ; [ |b |g |r ]
178 :     punpcklbw mm2, mm5 ; [ |b |g |r ]
179 :     movq mm6, mm0 ; = [ |b4|g4|r4]
180 :     paddw mm6, mm2 ; +[ |b4|g4|r4]
181 :     pmaddwd mm0, mm7 ; *= Y_MUL
182 :     pmaddwd mm2, mm7 ; *= Y_MUL
183 :     movq mm4, mm0 ; [r]
184 :     movq mm5, mm2 ; [r]
185 :     psrlq mm4, 32 ; +[g]
186 :     psrlq mm5, 32 ; +[g]
187 :     paddd mm0, mm4 ; +[b]
188 :     paddd mm2, mm5 ; +[b]
189 :    
190 :     pxor mm4, mm4
191 :     pxor mm5, mm5
192 :     movd mm1, [esi+3] ; src[4...]
193 :     movd mm3, [esi+ebx+3] ; src[width3+4...]
194 :     punpcklbw mm1, mm4 ; [ |b |g |r ]
195 :     punpcklbw mm3, mm5 ; [ |b |g |r ]
196 :     paddw mm6, mm1 ; +[ |b4|g4|r4]
197 :     paddw mm6, mm3 ; +[ |b4|g4|r4]
198 :     pmaddwd mm1, mm7 ; *= Y_MUL
199 :     pmaddwd mm3, mm7 ; *= Y_MUL
200 :     movq mm4, mm1 ; [r]
201 :     movq mm5, mm3 ; [r]
202 :     psrlq mm4, 32 ; +[g]
203 :     psrlq mm5, 32 ; +[g]
204 :     paddd mm1, mm4 ; +[b]
205 :     paddd mm3, mm5 ; +[b]
206 :    
207 :     mov ebx, [esp + 44 + 28] ; stride
208 :    
209 :     movd eax, mm0
210 :     shr eax, 8
211 :     add eax, Y_ADD
212 :     mov [edi + ebx], al
213 :    
214 :     movd eax, mm1
215 :     shr eax, 8
216 :     add eax, Y_ADD
217 :     mov [edi + ebx + 1], al
218 :    
219 :     movd eax, mm2
220 :     shr eax, 8
221 :     add eax, Y_ADD
222 :     mov [edi], al
223 :    
224 :     movd eax, mm3
225 :     shr eax, 8
226 :     add eax, Y_ADD
227 :     mov [edi + 1], al
228 :    
229 :     ; u_out, v_out
230 :    
231 :     movq mm0, mm6 ; = [ |b4|g4|r4]
232 :     pmaddwd mm6, [v_mul] ; *= V_MUL
233 :     pmaddwd mm0, [u_mul] ; *= U_MUL
234 :     movq mm1, mm0
235 :     movq mm2, mm6
236 :     psrlq mm1, 32
237 :     psrlq mm2, 32
238 :     paddd mm0, mm1
239 :     paddd mm2, mm6
240 :    
241 :     movd eax, mm0
242 :     shr eax, 10
243 :     add eax, U_ADD
244 :     mov [ecx], al
245 :    
246 :     movd eax, mm2
247 :     shr eax, 10
248 :     add eax, V_ADD
249 :     mov [edx], al
250 :    
251 :     add esi, 2 * 3 ; (use 4 for rgb32)
252 :     add edi, 2
253 :     inc ecx
254 :     inc edx
255 :    
256 :     dec ebp
257 :     jnz near .xloop
258 :    
259 :     sub esi, [esp + 4] ; src -= src_dif
260 :     add edi, [esp + 16] ; y_out += y_dif
261 :     add ecx, [esp + 20] ; u_out += uv_dif
262 :     add edx, [esp + 20] ; v_out += uv_dif
263 :    
264 :     dec dword [esp+0]
265 :     jnz near .yloop
266 :    
267 :     emms
268 :    
269 :     add esp, 24
270 :     pop ebp
271 :     pop edi
272 :     pop esi
273 :     pop ecx
274 :     pop ebx
275 :    
276 :     ret
277 :    
278 :    
279 :    
280 :     ;===========================================================================
281 :     ;
282 :     ; void rgb32_to_yv12mmx(uint8_t * const y_out,
283 :     ; uint8_t * const u_out,
284 :     ; uint8_t * const v_out,
285 :     ; const uint8_t * const src,
286 :     ; const uint32_t width,
287 :     ; const uint32_t height,
288 :     ; const uint32_t stride)
289 :     ;
290 :     ; always flips
291 :     ;
292 :     ;===========================================================================
293 :    
294 :     align 16
295 :     cglobal rgb32_to_yv12_mmx
296 :     rgb32_to_yv12_mmx
297 :    
298 :     push ebx
299 :     push ecx
300 :     push esi
301 :     push edi
302 :     push ebp ; STACK BASE = 20
303 :    
304 :     ; global consants
305 :    
306 :     mov eax, [esp + 20 + 28] ; stride
307 :     mov ecx, [esp + 20 + 20] ; width
308 :     mov ebx, eax
309 :     sub ebx, ecx
310 :     shr ebx, 1 ; ebx = (stride-width) / 2;
311 :     push ebx ; [esp + 20] = uv_dif
312 :     ; STACK BASE = 24
313 :    
314 :     add eax, eax
315 :     sub eax, ecx ; eax = 2*stride - width
316 :     push eax ; [esp + 16] = y_dif
317 :     ; STACK BASE = 28
318 :    
319 :     mov ebx, ecx ;
320 :     shr ebx, 1 ;
321 :     push ebx ; [esp + 12] = width/2
322 :     ; STACK BASE = 32
323 :    
324 :     mov edx, ecx
325 :     shl ecx, 2 ; ecx = 4*width (use 4 for rgb32)
326 :     push ecx ; [esp + 8] = width4
327 :     ; STACK BASE = 36
328 :    
329 :     mov edx, ecx
330 :     add edx, ecx
331 :     add edx, ecx ; edx = 3*width4
332 :     push edx ; [esp + 4] = src_dif
333 :     ; STACK BASE = 40
334 :    
335 :     mov esi, [esp + 40 + 16] ; src
336 :     mov ebp, [esp + 40 + 24] ; eax = height
337 :     mov eax, ebp
338 :     sub eax, 2
339 :     mul ecx
340 :     add esi, eax ; src += (height-2) * width4
341 :    
342 :     mov edi, [esp + 40 + 4] ; y_out
343 :     mov ecx, [esp + 40 + 8] ; u_out
344 :     mov edx, [esp + 40 + 12] ; v_out
345 :     movq mm7, [y_mul]
346 :    
347 :     shr ebp, 1 ; ebp = height / 2
348 :     push ebp ; [esp+0] = tmp
349 :     ; STACK BASE = 44
350 :    
351 :     .yloop
352 :     mov ebp, [esp + 12] ; ebp = width /2
353 :    
354 :     .xloop
355 :     ; y_out
356 :    
357 :     mov ebx, [esp + 8] ; ebx = width4
358 :    
359 :     pxor mm4, mm4
360 :     movq mm0, [esi] ; src[4... |0... ]
361 :     movq mm2, [esi+ebx] ; src[width4+4...|width4...]
362 :     movq mm1, mm0
363 :     movq mm3, mm2
364 :     punpcklbw mm0, mm4 ; [ |b |g |r ]
365 :     punpcklbw mm2, mm4 ; [ |b |g |r ]
366 :     punpckhbw mm1, mm4 ; [ |b |g |r ]
367 :     punpckhbw mm3, mm4 ; [ |b |g |r ]
368 :    
369 :     movq mm6, mm0 ; = [ |b4|g4|r4]
370 :     paddw mm6, mm2 ; +[ |b4|g4|r4]
371 :     pmaddwd mm0, mm7 ; *= Y_MUL
372 :     pmaddwd mm2, mm7 ; *= Y_MUL
373 :     movq mm4, mm0 ; [r]
374 :     movq mm5, mm2 ; [r]
375 :     psrlq mm4, 32 ; +[g]
376 :     psrlq mm5, 32 ; +[g]
377 :     paddd mm0, mm4 ; +[b]
378 :     paddd mm2, mm5 ; +[b]
379 :    
380 :     paddw mm6, mm1 ; +[ |b4|g4|r4]
381 :     paddw mm6, mm3 ; +[ |b4|g4|r4]
382 :     pmaddwd mm1, mm7 ; *= Y_MUL
383 :     pmaddwd mm3, mm7 ; *= Y_MUL
384 :     movq mm4, mm1 ; [r]
385 :     movq mm5, mm3 ; [r]
386 :     psrlq mm4, 32 ; +[g]
387 :     psrlq mm5, 32 ; +[g]
388 :     paddd mm1, mm4 ; +[b]
389 :     paddd mm3, mm5 ; +[b]
390 :    
391 :     mov ebx, [esp + 44 + 28] ; stride
392 :    
393 :     movd eax, mm0
394 :     shr eax, 8
395 :     add eax, Y_ADD
396 :     mov [edi + ebx], al
397 :    
398 :     movd eax, mm1
399 :     shr eax, 8
400 :     add eax, Y_ADD
401 :     mov [edi + ebx + 1], al
402 :    
403 :     movd eax, mm2
404 :     shr eax, 8
405 :     add eax, Y_ADD
406 :     mov [edi], al
407 :    
408 :     movd eax, mm3
409 :     shr eax, 8
410 :     add eax, Y_ADD
411 :     mov [edi + 1], al
412 :    
413 :     ; u_out, v_out
414 :    
415 :     movq mm0, mm6 ; = [ |b4|g4|r4]
416 :     pmaddwd mm6, [v_mul] ; *= V_MUL
417 :     pmaddwd mm0, [u_mul] ; *= U_MUL
418 :     movq mm1, mm0
419 :     movq mm2, mm6
420 :     psrlq mm1, 32
421 :     psrlq mm2, 32
422 :     paddd mm0, mm1
423 :     paddd mm2, mm6
424 :    
425 :     movd eax, mm0
426 :     shr eax, 10
427 :     add eax, U_ADD
428 :     mov [ecx], al
429 :    
430 :     movd eax, mm2
431 :     shr eax, 10
432 :     add eax, V_ADD
433 :     mov [edx], al
434 :    
435 :     add esi, 2 * 4 ; (use 4 for rgb32)
436 :     add edi, 2
437 :     inc ecx
438 :     inc edx
439 :    
440 :     dec ebp
441 :     jnz near .xloop
442 :    
443 :     sub esi, [esp + 4] ; src -= src_dif
444 :     add edi, [esp + 16] ; y_out += y_dif
445 :     add ecx, [esp + 20] ; u_out += uv_dif
446 :     add edx, [esp + 20] ; v_out += uv_dif
447 :    
448 :     dec dword [esp+0]
449 :     jnz near .yloop
450 :    
451 :     emms
452 :    
453 :     add esp, 24
454 :     pop ebp
455 :     pop edi
456 :     pop esi
457 :     pop ecx
458 :     pop ebx
459 :    
460 :     ret

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