[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 434 - (view) (download)

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

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