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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 434 - (view) (download)

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

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