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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 392 - (view) (download)

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

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