]> git.sesse.net Git - vlc/blob - src/video_output/video_yuv_mmx.S
1b03d86138049d84e12ffda18ac35558689bce45
[vlc] / src / video_output / video_yuv_mmx.S
1 /*****************************************************************************
2  * video_yuv_mmx.S: YUV transformation, optimized for MMX processors
3  * (c)1999 VideoLAN
4  *****************************************************************************
5  * Following functions are defined:
6  * vout_YUV420_16_MMX
7  *            This function performs YUV12-to-RGB16 color conversion for H26x.
8  *            It handles any format in which there are three fields, the low
9  *            order field being B and fully contained in the low order byte, the
10  *            second field being G and being somewhere in bits 4 through 11,
11  *            and the high order field being R and fully contained in the high
12  *            order byte.
13  *
14  *            The YUV12 input is planar, 8 bits per pel.  The Y plane may have
15  *            a pitch of up to 768.  It may have a width less than or equal
16  *            to the pitch.  It must be DWORD aligned, and preferably QWORD
17  *            aligned.  Pitch and Width must be a multiple of four.  For best
18  *            performance, Pitch should not be 4 more than a multiple of 32.
19  *            Height may be any amount, but must be a multiple of two.  The U
20  *            and V planes may have a different pitch than the Y plane, subject
21  *            to the same limitations.
22  *****************************************************************************/
23
24 //.include iammx.inc
25 //.include locals.inc
26
27 .data
28     .align 16
29
30 RGB_formats:
31     .long  RGB565
32     .long  RGB555
33     .long  RGB664
34     .long  RGB655
35
36 Minusg:             .long 0x00800080, 0x00800080
37 Yadd:               .long 0x10101010, 0x10101010
38 VtR:                .long 0x00660066, 0x00660066
39 VtG:                .long 0x00340034, 0x00340034
40 UtG:                .long 0x00190019, 0x00190019
41 UtB:                .long 0x00810081, 0x00810081
42 Ymul:               .long 0x004a004a, 0x004a004a
43 UVtG:               .long 0x00340019, 0x00340019
44 VtRUtB:             .long 0x01990205, 0x01990205
45 fourbitu:           .quad 0xf0f0f0f0f0f0f0f0
46 fivebitu:           .quad 0xe0e0e0e0e0e0e0e0
47 sixbitu:            .quad 0xc0c0c0c0c0c0c0c0
48
49 .text
50
51 #define LocalFrameSize  156
52 #define RegisterStorageSize  16
53
54 //#define DOUBLE /*double le nombre de colonnes */
55
56 /* Arguments: */
57 #define YPlane                    LocalFrameSize + RegisterStorageSize +  4
58 #define UPlane                    LocalFrameSize + RegisterStorageSize +  8
59 #define VPlane                    LocalFrameSize + RegisterStorageSize + 12
60 #define FrameWidth                LocalFrameSize + RegisterStorageSize + 16
61 #define FrameHeight               LocalFrameSize + RegisterStorageSize + 20
62 #define YPitch                    LocalFrameSize + RegisterStorageSize + 24
63 #define ChromaPitch               LocalFrameSize + RegisterStorageSize + 28
64 #define AspectAdjustmentCount     LocalFrameSize + RegisterStorageSize + 32
65 #define ColorConvertedFrame       LocalFrameSize + RegisterStorageSize + 36
66 #define DCIOffset                 LocalFrameSize + RegisterStorageSize + 40
67 #define CCOffsetToLine0           LocalFrameSize + RegisterStorageSize + 44
68 #define CCOPitch                  LocalFrameSize + RegisterStorageSize + 48
69 #define CCType                    LocalFrameSize + RegisterStorageSize + 52
70 #define EndOfArgList              LocalFrameSize + RegisterStorageSize + 56
71
72 /* Locals (on local stack frame) */
73 #define CCOCursor        0
74 #define CCOSkipDistance  4
75 #define ChromaLineLen    8
76 #define YCursor          12
77 #define DistanceFromVToU 16
78 #define EndOfChromaLine  20
79 #define AspectCount      24
80 #define AspectBaseCount  28
81 #define tmpYCursorEven   32
82 #define tmpYCursorOdd    36
83 #define tmpCCOPitch      40
84 #define temp_mmx         44
85 #define RLeftShift       92
86 #define GLeftShift       100
87 #define RRightShift      108
88 #define GRightShift      116
89 #define BRightShift      124
90 #define RUpperLimit      132
91 #define GUpperLimit      140
92 #define BUpperLimit      148
93
94 /*
95  * extern void C ConvertYUV420RGB16MMX (
96  *                                     U8* YPlane,
97  *                                     U8* UPlane,
98  *                                     U8* VPlane,
99  *                                     UN  FrameWidth,
100  *                                     UN  FrameHeight,
101  *                                     UN  YPitch,
102  *                                     UN  VPitch,
103  *                                     UN  AspectAdjustmentCount,
104  *                                     U8* ColorConvertedFrame,
105  *                                     U32 DCIOffset,
106  *                                     U32 CCOffsetToLine0,
107  *                                     IN  CCOPitch,
108  *                                     IN  CCType)
109  *
110  *  The local variables are on the stack,
111  *  The tables are in the one and only data segment.
112  *
113  *  CCOffsetToLine0 is relative to ColorConvertedFrame.
114  *  CCType  used by RGB color convertors to determine the exact conversion type.
115  *    RGB565 = 0
116  *    RGB555 = 1
117  *    RGB664 = 2
118  *    RGB655 = 3
119  */
120
121 .globl ConvertYUV420RGB16MMX
122 ConvertYUV420RGB16MMX:
123   pushl      %esi
124   pushl      %edi
125
126   pushl      %ebp
127   pushl      %ebx
128
129   subl       $LocalFrameSize,%esp
130   movl       CCType(%esp),%eax
131   cmpl       $4,%eax
132   jae        finish
133
134   jmp        *RGB_formats(,%eax,4)
135
136 RGB555:
137   xorl       %eax,%eax
138   movl       $2,%ebx                 /* 10-8 for byte shift */
139   movl       %ebx,RLeftShift(%esp)
140   movl       %eax,RLeftShift+4(%esp)
141   movl       $5,%ebx
142   movl       %ebx,GLeftShift(%esp)
143   movl       %eax,GLeftShift+4(%esp)
144   movl       $9,%ebx
145   movl       %ebx,RRightShift(%esp)
146   movl       %eax,RRightShift+4(%esp)
147   movl       %ebx,GRightShift(%esp)
148   movl       %eax,GRightShift+4(%esp)
149   movl       %ebx,BRightShift(%esp)
150   movl       %eax,BRightShift+4(%esp)
151   movq       fivebitu,%mm0
152   movq       %mm0,RUpperLimit(%esp)
153   movq       %mm0,GUpperLimit(%esp)
154   movq       %mm0,BUpperLimit(%esp)
155   jmp        RGBEND
156
157 RGB664:
158   xorl       %eax,%eax
159   movl       $2,%ebx                 /* 8-6 */
160   movl       %ebx,RLeftShift(%esp)
161   movl       %eax,RLeftShift+4(%esp)
162   movl       $4,%ebx
163   movl       %ebx,GLeftShift(%esp)
164   movl       %eax,GLeftShift+4(%esp)
165   movl       $8,%ebx
166   movl       %ebx,RRightShift(%esp)
167   movl       %eax,RRightShift+4(%esp)
168   movl       %ebx,GRightShift(%esp)
169   movl       %eax,GRightShift+4(%esp)
170   movl       $10,%ebx
171   movl       %ebx,BRightShift(%esp)
172   movl       %eax,BRightShift+4(%esp)
173   movq       sixbitu,%mm0
174   movq       %mm0,RUpperLimit(%esp)
175   movq       %mm0,GUpperLimit(%esp)
176   movq       fourbitu,%mm0
177   movq       %mm0,BUpperLimit(%esp)
178   jmp        RGBEND
179
180 RGB655:
181   xorl       %eax,%eax
182   movl       $2,%ebx                 /* 8-6 */
183   movl       %ebx,RLeftShift(%esp)
184   movl       %eax,RLeftShift+4(%esp)
185   movl       $5,%ebx
186   movl       %ebx,GLeftShift(%esp)
187   movl       %eax,GLeftShift+4(%esp)
188   movl       $8,%ebx
189   movl       %ebx,RRightShift(%esp)
190   movl       %eax,RRightShift+4(%esp)
191   movl       $9,%ebx
192   movl       %ebx,GRightShift(%esp)
193   movl       %eax,GRightShift+4(%esp)
194   movl       %ebx,BRightShift(%esp)
195   movl       %eax,BRightShift+4(%esp)
196   movq       sixbitu,%mm0
197   movq       %mm0,RUpperLimit(%esp)
198   movq       fivebitu,%mm0
199   movq       %mm0,GUpperLimit(%esp)
200   movq       %mm0,BUpperLimit(%esp)
201   jmp        RGBEND
202
203 RGB565:
204   xorl       %eax,%eax
205   movl       $3,%ebx                 /* 8-5 */
206   movl       %ebx,RLeftShift(%esp)
207   movl       %eax,RLeftShift+4(%esp)
208   movl       $5,%ebx
209   movl       %ebx,GLeftShift(%esp)
210   movl       %eax,GLeftShift+4(%esp)
211   movl       $9,%ebx
212   movl       %ebx,RRightShift(%esp)
213   movl       %eax,RRightShift+4(%esp)
214   movl       %ebx,BRightShift(%esp)
215   movl       %eax,BRightShift+4(%esp)
216   movl       $8,%ebx
217   movl       %ebx,GRightShift(%esp)
218   movl       %eax,GRightShift+4(%esp)
219   movq       fivebitu,%mm0
220   movq       %mm0,RUpperLimit(%esp)
221   movq       %mm0,BUpperLimit(%esp)
222   movq       sixbitu,%mm0
223   movq       %mm0,GUpperLimit(%esp)
224 //  jmp        RGBEND
225
226 RGBEND:
227   movl       VPlane(%esp),%ebx
228   movl       UPlane(%esp),%ecx
229   subl       %ebx,%ecx
230   movl       %ecx,DistanceFromVToU(%esp)
231
232   movl       ColorConvertedFrame(%esp),%eax
233   addl       DCIOffset(%esp),%eax
234   addl       CCOffsetToLine0(%esp),%eax
235   movl       %eax,CCOCursor(%esp)
236
237
238   movl       YPitch(%esp),%ecx
239   movl       FrameWidth(%esp),%ebx
240   movl       CCOPitch(%esp),%eax
241   subl       %ebx,%eax                   /* CCOPitch-FrameWidth */
242   subl       %ebx,%eax                   /* CCOPitch-2*FrameWidth */
243   sarl       %ebx                        /* FrameWidth/2 */
244   movl       YPlane(%esp),%esi           /* Fetch cursor over luma plane. */
245   movl       %ebx,ChromaLineLen(%esp)    /* FrameWidth/2 */
246   movl       %eax,CCOSkipDistance(%esp)  /* CCOPitch-3*FrameWidth */
247   movl       %esi,YCursor(%esp)
248   movl       AspectAdjustmentCount(%esp),%edx
249   movl       VPlane(%esp),%esi
250
251   cmpl       $1,%edx
252   je         finish
253   movl       %edx,AspectCount(%esp)
254   movl       %edx,AspectBaseCount(%esp)
255   xorl       %eax,%eax
256
257   movl       ChromaLineLen(%esp),%edi
258   movl       %edi,EndOfChromaLine(%esp)
259   movl       CCOCursor(%esp),%edi
260
261   movl       DistanceFromVToU(%esp),%edx
262   movl       YCursor(%esp),%ebp         /* Fetch Y Pitch. */
263   movl       FrameWidth(%esp),%ebx
264
265   addl       %ebx,%ebp
266   movl       %ebp,tmpYCursorEven(%esp)
267   movl       YPitch(%esp),%eax
268   addl       %eax,%ebp
269   movl       %ebp,tmpYCursorOdd(%esp)
270
271   sarl       %ebx
272   addl       %ebx,%esi
273   addl       %esi,%edx
274   negl       %ebx
275   movl       %ebx,FrameWidth(%esp)
276
277 /*
278  *  Register Usage:
279  */
280
281 PrepareChromaLine:
282   movl       AspectCount(%esp),%ebp
283   movl       FrameWidth(%esp),%ebx
284   subl       $2,%ebp
285   movl       CCOPitch(%esp),%eax
286   movl       %eax,tmpCCOPitch(%esp)
287   ja         continue
288
289   xorl       %eax,%eax
290   addl       AspectAdjustmentCount(%esp),%ebp
291   movl       %eax,tmpCCOPitch(%esp)
292 continue:
293   movl       %ebp,AspectCount(%esp)
294
295 do_next_8x2_block:
296   movl       tmpYCursorEven(%esp),%ebp
297 /* here is even line */
298   movd       (%edx,%ebx,),%mm1       /* 4 u values */
299   pxor       %mm0,%mm0               /* mm0=0 */
300   movd       (%esi,%ebx,),%mm2       /* 4 v values */
301   punpcklbw  %mm0,%mm1               /* get 4 unsign u */
302   psubw      Minusg,%mm1             /* get 4 unsign u-128 */
303   punpcklbw  %mm0,%mm2               /* get unsign v */
304   psubw      Minusg,%mm2             /* get unsign v-128 */
305   movq       %mm1,%mm3               /* save the u-128 unsign */
306   movq       %mm1,%mm5               /* save u-128 unsign */
307   punpcklwd  %mm2,%mm1               /* get 2 low u, v unsign pairs */
308   pmaddwd    UVtG,%mm1
309   punpckhwd  %mm2,%mm3               /* create high 2 unsign uv pairs */
310   pmaddwd    UVtG,%mm3
311   movq       %mm2,temp_mmx(%esp)       /* save v-128 */
312   movq       (%ebp,%ebx,2),%mm6      /* mm6 has 8 y pixels */
313   psubusb    Yadd,%mm6               /* mm6 has 8 y-16 pixels */
314   packssdw   %mm3,%mm1               /* packed the results to signed words */
315   movq       %mm6,%mm7               /* save the 8 y-16 pixels */
316   punpcklbw  %mm0,%mm6               /* mm6 has 4 low y-16 unsign */
317   pmullw     Ymul,%mm6
318   punpckhbw  %mm0,%mm7               /* mm7 has 4 high y-16 unsign */
319   pmullw     Ymul,%mm7
320   movq       %mm1,%mm4
321   movq       %mm1,temp_mmx+8(%esp)     /* save 4 chroma G values */
322   punpcklwd  %mm1,%mm1               /* chroma G replicate low 2 */
323   movq       %mm6,%mm0               /* low  y */
324   punpckhwd  %mm4,%mm4               /* chroma G replicate high 2 */
325   movq       %mm7,%mm3               /* high y */
326   psubw      %mm1,%mm6               /* 4 low G */
327   psraw      GRightShift(%esp),%mm6
328   psubw      %mm4,%mm7               /* 4 high G values in signed 16 bit */
329   movq       %mm5,%mm2
330   punpcklwd  %mm5,%mm5               /* replicate the 2 low u pixels */
331   pmullw     UtB,%mm5
332   punpckhwd  %mm2,%mm2
333   psraw      GRightShift(%esp),%mm7
334   pmullw     UtB,%mm2
335   packuswb   %mm7,%mm6               /* mm6: G7 G6 G5 G4 G3 G2 G1 G0 */
336   movq       %mm5,temp_mmx+16(%esp)    /* low chroma B */
337   paddw      %mm0,%mm5               /* 4 low B values in signed 16 bit */
338   movq       %mm2,temp_mmx+40(%esp)    /* high chroma B */
339   paddw      %mm3,%mm2               /* 4 high B values in signed 16 bit */
340   psraw      BRightShift(%esp),%mm5  /* low B scaled down by 6+(8-5) */
341   psraw      BRightShift(%esp),%mm2  /* high B scaled down by 6+(8-5) */
342   packuswb   %mm2,%mm5               /* mm5: B7 B6 B5 B4 B3 B2 B1 B0 */
343
344   movq       temp_mmx(%esp),%mm2       /* 4 v values */
345   movq       %mm5,%mm1               /* save B */
346   movq       %mm2,%mm7
347   punpcklwd  %mm2,%mm2               /* replicate the 2 low v pixels */
348   pmullw     VtR,%mm2
349   punpckhwd  %mm7,%mm7
350   pmullw     VtR,%mm7
351   paddusb    BUpperLimit(%esp),%mm1  /* mm1: saturate B+0FF-15 */
352   movq       %mm2,temp_mmx+24(%esp)    /* low chroma R */
353   paddw      %mm0,%mm2               /* 4 low R values in signed 16 bit */
354   psraw      RRightShift(%esp),%mm2  /* low R scaled down by 6+(8-5) */
355   pxor       %mm4,%mm4               /* mm4=0 for 8->16 conversion */
356   movq       %mm7,temp_mmx+32(%esp)    /* high chroma R */
357   paddw      %mm3,%mm7               /* 4 high R values in signed 16 bit */
358   psraw      RRightShift(%esp),%mm7  /* high R scaled down by 6+(8-5) */
359   psubusb    BUpperLimit(%esp),%mm1
360   packuswb   %mm7,%mm2               /* mm2: R7 R6 R5 R4 R3 R2 R1 R0 */
361   paddusb    GUpperLimit(%esp),%mm6  /* G fast patch ih */
362   psubusb    GUpperLimit(%esp),%mm6  /* fast patch ih */
363   paddusb    RUpperLimit(%esp),%mm2  /* R */
364   psubusb    RUpperLimit(%esp),%mm2
365
366 /*
367  * here we are packing from RGB24 to RGB16
368  * input:
369  *         mm6: G7 G6 G5 G4 G3 G2 G1 G0
370  *         mm1: B7 B6 B5 B4 B3 B2 B1 B0
371  *         mm2: R7 R6 R5 R4 R3 R2 R1 R0
372  * assuming 8 original pixels in 0-H representation on mm6, mm5, mm2
373  * when  H=2**xBITS-1 (x is for R G B)
374  * output:
375  *        mm1- result: 4 low RGB16
376  *        mm7- result: 4 high RGB16
377  * using: mm0- zero register
378  *        mm3- temporary results
379  * algorithm:
380  *   for (i=0; i<8; i++) {
381  *     RGB[i]=256*(R[i]<<(8-5))+(G[i]<<5)+B[i];
382  *   }
383  */
384
385   psllq      RLeftShift(%esp),%mm2   /* position R in the most significant
386                                         part of the byte */
387   movq       %mm1,%mm7               /* mm1: Save B */
388
389 /*
390  * note: no need for shift to place B on the least significant part of the byte
391  *   R in left position, B in the right position so they can be combined
392  */
393
394   punpcklbw  %mm2,%mm1               /* mm1: 4 low 16 bit RB */
395   pxor       %mm0,%mm0               /* mm0: 0 */
396   punpckhbw  %mm2,%mm7               /* mm5: 4 high 16 bit RB */
397   movq       %mm6,%mm3               /* mm3: G */
398   punpcklbw  %mm0,%mm6               /* mm6: low 4 G 16 bit */
399   psllw      GLeftShift(%esp),%mm6   /* shift low G 5 positions */
400   punpckhbw  %mm0,%mm3               /* mm3: high 4 G 16 bit */
401   por        %mm6,%mm1               /* mm1: low RBG16 */
402   psllw      GLeftShift(%esp),%mm3   /* shift high G 5 positions */
403   por        %mm3,%mm7               /* mm5: high RBG16 */
404
405   movl       tmpYCursorOdd(%esp),%ebp  /* moved to here to save cycles
406                                            before odd line */
407   movq       %mm1,(%edi)             /* !! aligned */
408
409 /*- start odd line */
410   movq       (%ebp,%ebx,2),%mm1      /* mm1 has 8 y pixels */
411   pxor       %mm2,%mm2
412   psubusb    Yadd,%mm1               /* mm1 has 8 pixels y-16 */
413   movq       %mm1,%mm5
414   punpcklbw  %mm2,%mm1               /* get 4 low y-16 unsign pixels word */
415   pmullw     Ymul,%mm1               /* low 4 luminance contribution */
416   punpckhbw  %mm2,%mm5               /* 4 high y-16 */
417   pmullw     Ymul,%mm5               /* high 4 luminance contribution */
418   movq       %mm7,8(%edi)            /* !! aligned */
419   movq       %mm1,%mm0
420   paddw      temp_mmx+24(%esp),%mm0    /* low 4 R */
421   movq       %mm5,%mm6
422   psraw      RRightShift(%esp),%mm0  /* low R scaled down by 6+(8-5) */
423   paddw      temp_mmx+32(%esp),%mm5    /* high 4 R */
424   movq       %mm1,%mm2
425   psraw      RRightShift(%esp),%mm5  /* high R scaled down by 6+(8-5) */
426   paddw      temp_mmx+16(%esp),%mm2    /* low 4 B */
427   packuswb   %mm5,%mm0               /* mm0: R7 R6 R5 R4 R3 R2 R1 R0 */
428   psraw      BRightShift(%esp),%mm2  /* low B scaled down by 6+(8-5) */
429   movq       %mm6,%mm5
430   paddw      temp_mmx+40(%esp),%mm6    /* high 4 B */
431   psraw      BRightShift(%esp),%mm6  /* high B scaled down by 6+(8-5) */
432   movq       temp_mmx+8(%esp),%mm3     /* chroma G  low 4 */
433   packuswb   %mm6,%mm2               /* mm2: B7 B6 B5 B4 B3 B2 B1 B0 */
434   movq       %mm3,%mm4
435   punpcklwd  %mm3,%mm3               /* replicate low 2 */
436   punpckhwd  %mm4,%mm4               /* replicate high 2 */
437   psubw      %mm3,%mm1               /* 4 low G */
438   psraw      GRightShift(%esp),%mm1  /* low G scaled down by 6+(8-5) */
439   psubw      %mm4,%mm5               /* 4 high G values in signed 16 bit */
440   psraw      GRightShift(%esp),%mm5  /* high G scaled down by 6+(8-5) */
441   paddusb    BUpperLimit(%esp),%mm2  /* mm1: saturate B+0FF-15 */
442   packuswb   %mm5,%mm1               /*mm1: G7 G6 G5 G4 G3 G2 G1 G0 */
443   psubusb    BUpperLimit(%esp),%mm2
444   paddusb    GUpperLimit(%esp),%mm1  /* G */
445   psubusb    GUpperLimit(%esp),%mm1
446   paddusb    RUpperLimit(%esp),%mm0  /* R */
447   movl       tmpCCOPitch(%esp),%eax
448   psubusb    RUpperLimit(%esp),%mm0
449
450 /*
451  * here we are packing from RGB24 to RGB16
452  *        mm1: G7 G6 G5 G4 G3 G2 G1 G0
453  *        mm2: B7 B6 B5 B4 B3 B2 B1 B0
454  *        mm0: R7 R6 R5 R4 R3 R2 R1 R0
455  * output:
456  *        mm2- result: 4 low RGB16
457  *        mm7- result: 4 high RGB16
458  * using: mm4- zero register
459  *        mm3- temporary results
460  */
461
462   psllq      RLeftShift(%esp),%mm0   /* position R in the most significant
463                                         part of the byte */
464   movq       %mm2,%mm7               /* mm7: Save B */
465
466 /*
467  * note: no need for shift to place B on the least significant part of the byte
468  *   R in left position, B in the right position so they can be combined
469  */
470
471   punpcklbw  %mm0,%mm2               /* mm1: 4 low 16 bit RB */
472   pxor       %mm4,%mm4               /* mm4: 0 */
473   movq       %mm1,%mm3               /* mm3: G */
474   punpckhbw  %mm0,%mm7               /* mm7: 4 high 16 bit RB */
475   punpcklbw  %mm4,%mm1               /* mm1: low 4 G 16 bit */
476   punpckhbw  %mm4,%mm3               /* mm3: high 4 G 16 bit */
477   psllw      GLeftShift(%esp),%mm1   /* shift low G 5 positions */
478   por        %mm1,%mm2               /* mm2: low RBG16 */
479   psllw      GLeftShift(%esp),%mm3   /* shift high G 5 positions */
480   por        %mm3,%mm7               /* mm7: high RBG16 */
481 #ifdef DOUBLE
482   movq       %mm2,%mm1
483   movq       %mm7,%mm5
484   movq       %mm2,%mm0
485   movq       %mm7,%mm3
486   punpckhwd  %mm2,%mm1
487   punpckhwd  %mm7,%mm5
488   punpcklwd  %mm2,%mm0
489   punpcklwd  %mm7,%mm3
490   movq       %mm0,(%edi,%eax,)
491   movq       %mm1,8(%edi,%eax,)
492   movq       %mm3,16(%edi,%eax,)
493   movq       %mm5,24(%edi,%eax,)
494   addl       $32,%edi
495   addl       $4,%ebx
496 #endif
497 #ifndef DOUBLE
498   movq       %mm2,(%edi,%eax,)
499   movq       %mm7,8(%edi,%eax,)      /* aligned */
500   addl       $16,%edi                /* ih take 16 bytes (8 pixels-16 bit) */
501   addl       $4,%ebx                 /* ? to take 4 pixels together
502                                         instead of 2 */
503 #endif
504   jl         do_next_8x2_block
505
506   addl       CCOSkipDistance(%esp),%edi /* go to begin of next line */
507   addl       tmpCCOPitch(%esp),%edi     /* skip odd line (if it is needed) */
508 // Leax       AspectCount
509 // Lebp       CCOPitch               ; skip odd line
510
511 // sub        eax, 2
512 // jg         @f
513
514 // Addeax     AspectBaseCount
515 // xor        ebp, ebp
516
517 //@@:
518 //  Seax       AspectCount
519 //  add        edi, ebp
520
521   movl       YPitch(%esp),%eax
522   movl       tmpYCursorOdd(%esp),%ebp
523   addl       %eax,%ebp               /* skip one line */
524 //  lea        ebp, [ebp+2*eax]        /* skip two lines */
525   movl       %ebp,tmpYCursorEven(%esp)
526 //  Sebp       tmpYCursorOdd
527
528   addl       %eax,%ebp               /* skip one line */
529   movl       %ebp,tmpYCursorOdd(%esp)
530 //  Lebp       tmpYCursorEven
531 //  lea        ebp, [ebp+2*eax]
532 //  Sebp       tmpYCursorEven
533
534
535   addl       ChromaPitch(%esp),%esi
536   addl       ChromaPitch(%esp),%edx
537
538
539 //  Leax       YLimit                  /* Done with last line? */
540 //  cmp        ebp, eax
541 //  jbe        PrepareChromaLine
542   subw       $2,FrameHeight(%esp)
543   ja         PrepareChromaLine
544
545 /******************************************************************************/
546
547 finish:
548   emms
549   addl       $LocalFrameSize,%esp
550
551   popl       %ebx
552   popl       %ebp
553   popl       %edi
554   popl       %esi
555   ret
556