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

Annotation of /branches/dev-api-4/xvidcore/src/image/x86_asm/yv12_to_rgb24_mmx.asm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 651 - (view) (download)
Original Path: trunk/xvidcore/src/image/x86_asm/yv12_to_rgb24_mmx.asm

1 : chl 434 ;/*****************************************************************************
2 :     ; *
3 :     ; * XVID MPEG-4 VIDEO CODEC
4 :     ; * mmx yv12 to rgb24 conversion
5 :     ; *
6 :     ; * Copyright (C) 2001 - Michael Militzer <isibaar@xvid.org>
7 :     ; *
8 : edgomez 651 ; * This file is part of XviD, a free MPEG-4 video encoder/decoder
9 : chl 434 ; *
10 : edgomez 651 ; * XviD is free software; you can redistribute it and/or modify it
11 :     ; * under the terms of the GNU General Public License as published by
12 : chl 434 ; * the Free Software Foundation; either version 2 of the License, or
13 :     ; * (at your option) any later version.
14 :     ; *
15 :     ; * This program 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
18 :     ; * GNU General Public License for more details.
19 :     ; *
20 :     ; * You should have received a copy of the GNU General Public License
21 :     ; * along with this program; if not, write to the Free Software
22 :     ; * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 :     ; *
24 : edgomez 651 ; * Under section 8 of the GNU General Public License, the copyright
25 :     ; * holders of XVID explicitly forbid distribution in the following
26 :     ; * countries:
27 :     ; *
28 :     ; * - Japan
29 :     ; * - United States of America
30 :     ; *
31 :     ; * Linking XviD statically or dynamically with other modules is making a
32 :     ; * combined work based on XviD. Thus, the terms and conditions of the
33 :     ; * GNU General Public License cover the whole combination.
34 :     ; *
35 :     ; * As a special exception, the copyright holders of XviD give you
36 :     ; * permission to link XviD with independent modules that communicate with
37 :     ; * XviD solely through the VFW1.1 and DShow interfaces, regardless of the
38 :     ; * license terms of these independent modules, and to copy and distribute
39 :     ; * the resulting combined work under terms of your choice, provided that
40 :     ; * every copy of the combined work is accompanied by a complete copy of
41 :     ; * the source code of XviD (the version of XviD used to produce the
42 :     ; * combined work), being distributed under the terms of the GNU General
43 :     ; * Public License plus this exception. An independent module is a module
44 :     ; * which is not derived from or based on XviD.
45 :     ; *
46 :     ; * Note that people who make modified versions of XviD are not obligated
47 :     ; * to grant this special exception for their modified versions; it is
48 :     ; * their choice whether to do so. The GNU General Public License gives
49 :     ; * permission to release a modified version without this exception; this
50 :     ; * exception also makes it possible to release a modified version which
51 :     ; * carries forward this exception.
52 :     ; *
53 :     ; * $Id: yv12_to_rgb24_mmx.asm,v 1.4 2002-11-17 00:20:30 edgomez Exp $
54 :     ; *
55 : chl 434 ; ****************************************************************************/
56 : edgomez 330 ;
57 :     ;------------------------------------------------------------------------------
58 :     ; NB: n contrary to the c implementation this code does the conversion
59 :     ; using direct calculations. Input data width must be a multiple of 8
60 :     ; and height must be even.
61 :     ; This implementation is less precise than the c version but is
62 :     ; more than twice as fast :-)
63 :     ;------------------------------------------------------------------------------
64 :    
65 :     BITS 32
66 :    
67 :    
68 :     %macro cglobal 1
69 :     %ifdef PREFIX
70 :     global _%1
71 :     %define %1 _%1
72 :     %else
73 :     global %1
74 :     %endif
75 :     %endmacro
76 :    
77 :    
78 :     %define SCALEBITS 6
79 :    
80 :    
81 :     ALIGN 16
82 :    
83 :     SECTION .data
84 :    
85 :     Y_SUB dw 16, 16, 16, 16
86 :     U_SUB dw 128, 128, 128, 128
87 :     V_SUB dw 128, 128, 128, 128
88 :    
89 :     Y_MUL dw 74, 74, 74, 74
90 :    
91 :     UG_MUL dw 25, 25, 25, 25
92 :     VG_MUL dw 52, 52, 52, 52
93 :    
94 :     UB_MUL dw 129, 129, 129, 129
95 :     VR_MUL dw 102, 102, 102, 102
96 :    
97 :    
98 :     ALIGN 16
99 :    
100 :     SECTION .text
101 :    
102 :     ;------------------------------------------------------------------------------
103 :     ;
104 :     ; void yv12_to_rgb24_mmx(uint8_t *dst,
105 :     ; int dst_stride,
106 :     ; uint8_t *y_src,
107 :     ; uint8_t *u_src,
108 :     ; uint8_t *v_src,
109 :     ; int y_stride, int uv_stride,
110 :     ; int width, int height);
111 :     ;
112 :     ;------------------------------------------------------------------------------
113 :    
114 :     cglobal yv12_to_rgb24_mmx
115 :     yv12_to_rgb24_mmx:
116 :    
117 :     push ebx
118 :     push esi
119 :     push edi
120 :     push ebp
121 :    
122 :     ; local vars alloc
123 :     %define localsize 72
124 :     %define TEMP_Y1 esp
125 :     %define TEMP_Y2 esp + 8
126 :     %define TEMP_G1 esp + 16
127 :     %define TEMP_G2 esp + 24
128 :     %define TEMP_B1 esp + 32
129 :     %define TEMP_B2 esp + 40
130 :     %define y_dif esp + 48
131 :     %define dst_dif esp + 52
132 :     %define uv_dif esp + 56
133 :     %define height esp + 60
134 :     %define width_8 esp + 64
135 :     %define height_2 esp + 68
136 :     sub esp, localsize
137 :    
138 :    
139 :     mov eax, [esp + 52 + localsize] ; height -> eax
140 :     cmp eax, 0x00
141 :     jge near dont_flip ; flip?
142 :    
143 :     neg eax
144 :     mov [height], eax
145 :    
146 :     mov esi, [esp + 48 + localsize] ; width -> esi
147 :    
148 :     mov ebp, [esp + 40 + localsize] ; y_stride -> ebp
149 :     mov ebx, ebp
150 :     shl ebx, 1 ; 2 * y_stride -> ebx
151 :     neg ebx
152 :     sub ebx, esi ; y_dif -> eax
153 :    
154 :     mov [y_dif], ebx
155 :    
156 :     sub eax, 1 ; height - 1 -> eax
157 :     mul ebp ; (height - 1) * y_stride -> ebp
158 :     mov ecx, eax
159 :     mov eax, [esp + 28 + localsize] ; y_src -> eax
160 :     add eax, ecx ; y_src -> eax
161 :     mov ebx, eax
162 :     sub ebx, ebp ; y_src2 -> ebx
163 :    
164 :     mov ecx, [esp + 24 + localsize] ; dst_stride -> ecx
165 :     mov edx, ecx
166 :     add ecx, edx
167 :     shl edx, 2
168 :     add ecx, edx ; 6 * dst_stride -> ecx
169 :     mov edx, ecx
170 :     sub ecx, esi
171 :     shl esi, 1
172 :     sub ecx, esi ; 6 * dst_stride - 3 * width -> ecx
173 :    
174 :     mov [dst_dif], ecx
175 :    
176 :     mov esi, [esp + 20 + localsize] ; dst -> esi
177 :     mov edi, esi
178 :     shr edx, 1
179 :     add edi, edx ; dst2 -> edi
180 :    
181 :     mov ebp, [esp + 48 + localsize] ; width -> ebp
182 :     mov ecx, ebp ; width -> ecx
183 :     shr ecx, 1
184 :     shr ebp, 3 ; width / 8 -> ebp
185 :     mov [width_8], ebp
186 :    
187 :     mov ebp, [esp + 44 + localsize] ; uv_stride -> ebp
188 :     mov edx, ebp
189 :     neg edx
190 :     sub edx, ecx
191 :     mov [uv_dif], edx
192 :    
193 :     mov edx, ebp
194 :     mov ebp, eax
195 :     mov eax, [height] ; height -> eax
196 :     shr eax, 1 ; height / 2 -> eax
197 :    
198 :     mov ecx, [esp + 32 + localsize] ; u_src -> ecx
199 :     sub eax, 1
200 :     mul edx
201 :     add ecx, eax
202 :    
203 :     mov edx, [esp + 36 + localsize] ; v_src -> edx
204 :     add edx, eax
205 :    
206 :     mov eax, ebp
207 :    
208 :     mov ebp, [height] ; height -> ebp
209 :     shr ebp, 1 ; height / 2 -> ebp
210 :    
211 :     pxor mm7, mm7 ; clear mm7
212 :     jmp y_loop
213 :    
214 :    
215 :     dont_flip:
216 :     mov esi, [esp + 48 + localsize] ; width -> esi
217 :    
218 :     mov ebp, [esp + 40 + localsize] ; y_stride -> ebp
219 :     mov ebx, ebp
220 :     shl ebx, 1 ; 2 * y_stride -> ebx
221 :     sub ebx, esi ; y_dif -> ebx
222 :    
223 :     mov [y_dif], ebx
224 :    
225 :     mov eax, [esp + 28 + localsize] ; y_src -> eax
226 :     mov ebx, eax
227 :     add ebx, ebp ; y_src2 -> ebp
228 :    
229 :     mov ecx, [esp + 24 + localsize] ; dst_stride -> ecx
230 :     mov edx, ecx
231 :     add ecx, edx
232 :     shl edx, 2
233 :     add ecx, edx ; 6 * dst_stride -> ecx
234 :     mov edx, ecx
235 :     sub ecx, esi
236 :     shl esi, 1
237 :     sub ecx, esi ; 6 * dst_stride - 3 * width -> ecx
238 :    
239 :     mov [dst_dif], ecx
240 :    
241 :     mov esi, [esp + 20 + localsize] ; dst -> esi
242 :     mov edi, esi
243 :     shr edx, 1
244 :     add edi, edx ; dst2 -> edi
245 :    
246 :     mov ebp, [esp + 48 + localsize] ; width -> ebp
247 :     mov ecx, ebp ; width -> ecx
248 :     shr ecx, 1
249 :     shr ebp, 3 ; width / 8 -> ebp
250 :     mov [width_8], ebp
251 :    
252 :     mov ebp, [esp + 44 + localsize] ; uv_stride -> ebp
253 :     sub ebp, ecx
254 :     mov [uv_dif], ebp
255 :    
256 :     mov ecx, [esp + 32 + localsize] ; u_src -> ecx
257 :     mov edx, [esp + 36 + localsize] ; v_src -> edx
258 :    
259 :     mov ebp, [esp + 52 + localsize] ; height -> ebp
260 :     shr ebp, 1 ; height / 2 -> ebp
261 :    
262 :     pxor mm7, mm7
263 :    
264 :     y_loop:
265 :     mov [height_2], ebp
266 :     mov ebp, [width_8]
267 :    
268 :     x_loop:
269 :     movd mm2, [ecx]
270 :     movd mm3, [edx]
271 :    
272 :     punpcklbw mm2, mm7 ; u3u2u1u0 -> mm2
273 :     punpcklbw mm3, mm7 ; v3v2v1v0 -> mm3
274 :    
275 :     psubsw mm2, [U_SUB] ; U - 128
276 :     psubsw mm3, [V_SUB] ; V - 128
277 :    
278 :     movq mm4, mm2
279 :     movq mm5, mm3
280 :    
281 :     pmullw mm2, [UG_MUL]
282 :     pmullw mm3, [VG_MUL]
283 :    
284 :     movq mm6, mm2 ; u3u2u1u0 -> mm6
285 :     punpckhwd mm2, mm2 ; u3u3u2u2 -> mm2
286 :     punpcklwd mm6, mm6 ; u1u1u0u0 -> mm6
287 :    
288 :     pmullw mm4, [UB_MUL] ; B_ADD -> mm4
289 :    
290 :     movq mm0, mm3
291 :     punpckhwd mm3, mm3 ; v3v3v2v2 -> mm2
292 :     punpcklwd mm0, mm0 ; v1v1v0v0 -> mm6
293 :    
294 :     paddsw mm2, mm3
295 :     paddsw mm6, mm0
296 :    
297 :     pmullw mm5, [VR_MUL] ; R_ADD -> mm5
298 :    
299 :     movq mm0, [eax] ; y7y6y5y4y3y2y1y0 -> mm0
300 :    
301 :     movq mm1, mm0
302 :     punpckhbw mm1, mm7 ; y7y6y5y4 -> mm1
303 :     punpcklbw mm0, mm7 ; y3y2y1y0 -> mm0
304 :    
305 :     psubsw mm0, [Y_SUB] ; Y - Y_SUB
306 :     psubsw mm1, [Y_SUB] ; Y - Y_SUB
307 :    
308 :     pmullw mm1, [Y_MUL]
309 :     pmullw mm0, [Y_MUL]
310 :    
311 :     movq [TEMP_Y2], mm1 ; y7y6y5y4 -> mm3
312 :     movq [TEMP_Y1], mm0 ; y3y2y1y0 -> mm7
313 :    
314 :     psubsw mm1, mm2 ; g7g6g5g4 -> mm1
315 :     psubsw mm0, mm6 ; g3g2g1g0 -> mm0
316 :    
317 :     psraw mm1, SCALEBITS
318 :     psraw mm0, SCALEBITS
319 :    
320 :     packuswb mm0, mm1 ;g7g6g5g4g3g2g1g0 -> mm0
321 :    
322 :     movq [TEMP_G1], mm0
323 :    
324 :     movq mm0, [ebx] ; y7y6y5y4y3y2y1y0 -> mm0
325 :    
326 :     movq mm1, mm0
327 :    
328 :     punpckhbw mm1, mm7 ; y7y6y5y4 -> mm1
329 :     punpcklbw mm0, mm7 ; y3y2y1y0 -> mm0
330 :    
331 :     psubsw mm0, [Y_SUB] ; Y - Y_SUB
332 :     psubsw mm1, [Y_SUB] ; Y - Y_SUB
333 :    
334 :     pmullw mm1, [Y_MUL]
335 :     pmullw mm0, [Y_MUL]
336 :    
337 :     movq mm3, mm1
338 :     psubsw mm1, mm2 ; g7g6g5g4 -> mm1
339 :    
340 :     movq mm2, mm0
341 :     psubsw mm0, mm6 ; g3g2g1g0 -> mm0
342 :    
343 :     psraw mm1, SCALEBITS
344 :     psraw mm0, SCALEBITS
345 :    
346 :     packuswb mm0, mm1 ; g7g6g5g4g3g2g1g0 -> mm0
347 :    
348 :     movq [TEMP_G2], mm0
349 :    
350 :     movq mm0, mm4
351 :     punpckhwd mm4, mm4 ; u3u3u2u2 -> mm2
352 :     punpcklwd mm0, mm0 ; u1u1u0u0 -> mm6
353 :    
354 :     movq mm1, mm3 ; y7y6y5y4 -> mm1
355 :     paddsw mm3, mm4 ; b7b6b5b4 -> mm3
356 :    
357 :     movq mm7, mm2 ; y3y2y1y0 -> mm7
358 :    
359 :     paddsw mm2, mm0 ; b3b2b1b0 -> mm2
360 :    
361 :     psraw mm3, SCALEBITS
362 :     psraw mm2, SCALEBITS
363 :    
364 :     packuswb mm2, mm3 ; b7b6b5b4b3b2b1b0 -> mm2
365 :    
366 :     movq [TEMP_B2], mm2
367 :    
368 :     movq mm3, [TEMP_Y2]
369 :     movq mm2, [TEMP_Y1]
370 :    
371 :     movq mm6, mm3 ; TEMP_Y2 -> mm6
372 :     paddsw mm3, mm4 ; b7b6b5b4 -> mm3
373 :    
374 :     movq mm4, mm2 ; TEMP_Y1 -> mm4
375 :     paddsw mm2, mm0 ; b3b2b1b0 -> mm2
376 :    
377 :     psraw mm3, SCALEBITS
378 :     psraw mm2, SCALEBITS
379 :    
380 :     packuswb mm2, mm3 ; b7b6b5b4b3b2b1b0 -> mm2
381 :    
382 :     movq [TEMP_B1], mm2
383 :    
384 :     movq mm0, mm5
385 :     punpckhwd mm5, mm5 ; v3v3v2v2 -> mm5
386 :     punpcklwd mm0, mm0 ; v1v1v0v0 -> mm0
387 :    
388 :     paddsw mm1, mm5 ; r7r6r5r4 -> mm1
389 :     paddsw mm7, mm0 ; r3r2r1r0 -> mm7
390 :    
391 :     psraw mm1, SCALEBITS
392 :     psraw mm7, SCALEBITS
393 :    
394 :     packuswb mm7, mm1 ; r7r6r5r4r3r2r1r0 -> mm7 (TEMP_R2)
395 :    
396 :     paddsw mm6, mm5 ; r7r6r5r4 -> mm6
397 :     paddsw mm4, mm0 ; r3r2r1r0 -> mm4
398 :    
399 :     psraw mm6, SCALEBITS
400 :     psraw mm4, SCALEBITS
401 :    
402 :     packuswb mm4, mm6 ; r7r6r5r4r3r2r1r0 -> mm4 (TEMP_R1)
403 :    
404 :     movq mm0, [TEMP_B1]
405 :     movq mm1, [TEMP_G1]
406 :    
407 :     movq mm6, mm7
408 :    
409 :     movq mm2, mm0
410 :     punpcklbw mm2, mm4 ; r3b3r2b2r1b1r0b0 -> mm2
411 :     punpckhbw mm0, mm4 ; r7b7r6b6r5b5r4b4 -> mm0
412 :    
413 :     pxor mm7, mm7
414 :    
415 :     movq mm3, mm1
416 :     punpcklbw mm1, mm7 ; 0g30g20g10g0 -> mm1
417 :     punpckhbw mm3, mm7 ; 0g70g60g50g4 -> mm3
418 :    
419 :     movq mm4, mm2
420 :     punpcklbw mm2, mm1 ; 0r1g1b10r0g0b0 -> mm2
421 :     punpckhbw mm4, mm1 ; 0r3g3b30r2g2b2 -> mm4
422 :    
423 :     movq mm5, mm0
424 :     punpcklbw mm0, mm3 ; 0r5g5b50r4g4b4 -> mm0
425 :     punpckhbw mm5, mm3 ; 0r7g7b70r6g6b6 -> mm5
426 :    
427 :     movd [esi], mm2
428 :     psrlq mm2, 32
429 :    
430 :     movd [esi + 3], mm2
431 :     movd [esi + 6], mm4
432 :    
433 :     psrlq mm4, 32
434 :    
435 :     movd [esi + 9], mm4
436 :     movd [esi + 12], mm0
437 :    
438 :     psrlq mm0, 32
439 :    
440 :     movd [esi + 15], mm0
441 :     movd [esi + 18], mm5
442 :    
443 :     psrlq mm5, 32
444 :    
445 :     movd [esi + 21], mm5
446 :    
447 :     movq mm0, [TEMP_B2]
448 :     movq mm1, [TEMP_G2]
449 :    
450 :     movq mm2, mm0
451 :     punpcklbw mm2, mm6 ; r3b3r2b2r1b1r0b0 -> mm2
452 :     punpckhbw mm0, mm6 ; r7b7r6b6r5b5r4b4 -> mm0
453 :    
454 :     movq mm3, mm1
455 :     punpcklbw mm1, mm7 ; 0g30g20g10g0 -> mm1
456 :     punpckhbw mm3, mm7 ; 0g70g60g50g4 -> mm3
457 :    
458 :     movq mm4, mm2
459 :     punpcklbw mm2, mm1 ; 0r1g1b10r0g0b0 -> mm2
460 :     punpckhbw mm4, mm1 ; 0r3g3b30r2g2b2 -> mm4
461 :    
462 :     movq mm5, mm0
463 :     punpcklbw mm0, mm3 ; 0r5g5b50r4g4b4 -> mm0
464 :     punpckhbw mm5, mm3 ; 0r7g7b70r6g6b6 -> mm5
465 :    
466 :     movd [edi], mm2
467 :     psrlq mm2, 32
468 :    
469 :     movd [edi + 3], mm2
470 :     movd [edi + 6], mm4
471 :    
472 :     psrlq mm4, 32
473 :    
474 :     movd [edi + 9], mm4
475 :     movd [edi + 12], mm0
476 :    
477 :     psrlq mm0, 32
478 :    
479 :     movd [edi + 15], mm0
480 :     movd [edi + 18], mm5
481 :    
482 :     psrlq mm5, 32
483 :    
484 :     movd [edi + 21], mm5
485 :    
486 :     add esi, 24
487 :     add edi, 24
488 :    
489 :     add eax, 8
490 :     add ebx, 8
491 :     add ecx, 4
492 :     add edx, 4
493 :    
494 :     dec ebp
495 :    
496 :     jnz near x_loop
497 :    
498 :     add esi, [dst_dif]
499 :     add edi, [dst_dif]
500 :    
501 :     add eax, [y_dif]
502 :     add ebx, [y_dif]
503 :    
504 :     add ecx, [uv_dif]
505 :     add edx, [uv_dif]
506 :    
507 :     mov ebp, [height_2]
508 :     dec ebp
509 :     jnz near y_loop
510 :    
511 :     emms
512 :    
513 :     ;; Local vars deallocation
514 :     add esp, localsize
515 :     %undef TEMP_Y1
516 :     %undef TEMP_Y2
517 :     %undef TEMP_G1
518 :     %undef TEMP_G2
519 :     %undef TEMP_B1
520 :     %undef TEMP_B2
521 :     %undef y_dif
522 :     %undef dst_dif
523 :     %undef uv_dif
524 :     %undef height
525 :     %undef width_8
526 :     %undef height_2
527 :     %undef localsize
528 :    
529 :     pop ebp
530 :     pop edi
531 :     pop esi
532 :     pop ebx
533 :    
534 :     ret

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