2 Yadif C-plugin for Avisynth 2.5 - Yet Another DeInterlacing Filter
3 Copyright (C)2007 Alexander G. Balakhnin aka Fizick http://avisynth.org.ru
4 Port of YADIF filter from MPlayer
5 Copyright (C) 2006 Michael Niedermayer <michaelni@gmx.at>
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 Assembler optimized for GNU C compiler
28 #define MIN(a,b) ((a) > (b) ? (b) : (a))
29 #define MAX(a,b) ((a) < (b) ? (b) : (a))
30 #define ABS(a) ((a) > 0 ? (a) : (-(a)))
32 #define MIN3(a,b,c) MIN(MIN(a,b),c)
33 #define MAX3(a,b,c) MAX(MAX(a,b),c)
35 static void (*filter_line)(int mode, uint8_t *dst, const uint8_t *prev, const uint8_t *cur, const uint8_t *next, int w, int refs, int parity);
37 #if defined(__GNUC__) && defined(USE_SSE)
39 #define LOAD4(mem,dst) \
40 "movd "mem", "#dst" \n\t"\
41 "punpcklbw %%mm7, "#dst" \n\t"
43 #define PABS(tmp,dst) \
44 "pxor "#tmp", "#tmp" \n\t"\
45 "psubw "#dst", "#tmp" \n\t"\
46 "pmaxsw "#tmp", "#dst" \n\t"
48 #define CHECK(pj,mj) \
49 "movq "#pj"(%[cur],%[mrefs]), %%mm2 \n\t" /* cur[x-refs-1+j] */\
50 "movq "#mj"(%[cur],%[prefs]), %%mm3 \n\t" /* cur[x+refs-1-j] */\
51 "movq %%mm2, %%mm4 \n\t"\
52 "movq %%mm2, %%mm5 \n\t"\
53 "pxor %%mm3, %%mm4 \n\t"\
54 "pavgb %%mm3, %%mm5 \n\t"\
55 "pand %[pb1], %%mm4 \n\t"\
56 "psubusb %%mm4, %%mm5 \n\t"\
57 "psrlq $8, %%mm5 \n\t"\
58 "punpcklbw %%mm7, %%mm5 \n\t" /* (cur[x-refs+j] + cur[x+refs-j])>>1 */\
59 "movq %%mm2, %%mm4 \n\t"\
60 "psubusb %%mm3, %%mm2 \n\t"\
61 "psubusb %%mm4, %%mm3 \n\t"\
62 "pmaxub %%mm3, %%mm2 \n\t"\
63 "movq %%mm2, %%mm3 \n\t"\
64 "movq %%mm2, %%mm4 \n\t" /* ABS(cur[x-refs-1+j] - cur[x+refs-1-j]) */\
65 "psrlq $8, %%mm3 \n\t" /* ABS(cur[x-refs +j] - cur[x+refs -j]) */\
66 "psrlq $16, %%mm4 \n\t" /* ABS(cur[x-refs+1+j] - cur[x+refs+1-j]) */\
67 "punpcklbw %%mm7, %%mm2 \n\t"\
68 "punpcklbw %%mm7, %%mm3 \n\t"\
69 "punpcklbw %%mm7, %%mm4 \n\t"\
70 "paddw %%mm3, %%mm2 \n\t"\
71 "paddw %%mm4, %%mm2 \n\t" /* score */
74 "movq %%mm0, %%mm3 \n\t"\
75 "pcmpgtw %%mm2, %%mm3 \n\t" /* if(score < spatial_score) */\
76 "pminsw %%mm2, %%mm0 \n\t" /* spatial_score= score; */\
77 "movq %%mm3, %%mm6 \n\t"\
78 "pand %%mm3, %%mm5 \n\t"\
79 "pandn %%mm1, %%mm3 \n\t"\
80 "por %%mm5, %%mm3 \n\t"\
81 "movq %%mm3, %%mm1 \n\t" /* spatial_pred= (cur[x-refs+j] + cur[x+refs-j])>>1; */
83 #define CHECK2 /* pretend not to have checked dir=2 if dir=1 was bad.\
84 hurts both quality and speed, but matches the C version. */\
85 "paddw %[pw1], %%mm6 \n\t"\
86 "psllw $14, %%mm6 \n\t"\
87 "paddsw %%mm6, %%mm2 \n\t"\
88 "movq %%mm0, %%mm3 \n\t"\
89 "pcmpgtw %%mm2, %%mm3 \n\t"\
90 "pminsw %%mm2, %%mm0 \n\t"\
91 "pand %%mm3, %%mm5 \n\t"\
92 "pandn %%mm1, %%mm3 \n\t"\
93 "por %%mm5, %%mm3 \n\t"\
94 "movq %%mm3, %%mm1 \n\t"
96 static void filter_line_mmx2(int mode, uint8_t *dst, const uint8_t *prev, const uint8_t *cur, const uint8_t *next, int w, int refs, int parity){
97 static const uint64_t pw_1 = 0x0001000100010001ULL;
98 static const uint64_t pb_1 = 0x0101010101010101ULL;
99 // const int mode = p->mode;
100 uint64_t tmp0, tmp1, tmp2, tmp3;
104 for(x=0; x<w; x+=4){\
106 "pxor %%mm7, %%mm7 \n\t"\
107 LOAD4("(%[cur],%[mrefs])", %%mm0) /* c = cur[x-refs] */\
108 LOAD4("(%[cur],%[prefs])", %%mm1) /* e = cur[x+refs] */\
109 LOAD4("(%["prev2"])", %%mm2) /* prev2[x] */\
110 LOAD4("(%["next2"])", %%mm3) /* next2[x] */\
111 "movq %%mm3, %%mm4 \n\t"\
112 "paddw %%mm2, %%mm3 \n\t"\
113 "psraw $1, %%mm3 \n\t" /* d = (prev2[x] + next2[x])>>1 */\
114 "movq %%mm0, %[tmp0] \n\t" /* c */\
115 "movq %%mm3, %[tmp1] \n\t" /* d */\
116 "movq %%mm1, %[tmp2] \n\t" /* e */\
117 "psubw %%mm4, %%mm2 \n\t"\
118 PABS( %%mm4, %%mm2) /* temporal_diff0 */\
119 LOAD4("(%[prev],%[mrefs])", %%mm3) /* prev[x-refs] */\
120 LOAD4("(%[prev],%[prefs])", %%mm4) /* prev[x+refs] */\
121 "psubw %%mm0, %%mm3 \n\t"\
122 "psubw %%mm1, %%mm4 \n\t"\
125 "paddw %%mm4, %%mm3 \n\t" /* temporal_diff1 */\
126 "psrlw $1, %%mm2 \n\t"\
127 "psrlw $1, %%mm3 \n\t"\
128 "pmaxsw %%mm3, %%mm2 \n\t"\
129 LOAD4("(%[next],%[mrefs])", %%mm3) /* next[x-refs] */\
130 LOAD4("(%[next],%[prefs])", %%mm4) /* next[x+refs] */\
131 "psubw %%mm0, %%mm3 \n\t"\
132 "psubw %%mm1, %%mm4 \n\t"\
135 "paddw %%mm4, %%mm3 \n\t" /* temporal_diff2 */\
136 "psrlw $1, %%mm3 \n\t"\
137 "pmaxsw %%mm3, %%mm2 \n\t"\
138 "movq %%mm2, %[tmp3] \n\t" /* diff */\
140 "paddw %%mm0, %%mm1 \n\t"\
141 "paddw %%mm0, %%mm0 \n\t"\
142 "psubw %%mm1, %%mm0 \n\t"\
143 "psrlw $1, %%mm1 \n\t" /* spatial_pred */\
144 PABS( %%mm2, %%mm0) /* ABS(c-e) */\
146 "movq -1(%[cur],%[mrefs]), %%mm2 \n\t" /* cur[x-refs-1] */\
147 "movq -1(%[cur],%[prefs]), %%mm3 \n\t" /* cur[x+refs-1] */\
148 "movq %%mm2, %%mm4 \n\t"\
149 "psubusb %%mm3, %%mm2 \n\t"\
150 "psubusb %%mm4, %%mm3 \n\t"\
151 "pmaxub %%mm3, %%mm2 \n\t"\
152 /*"pshufw $9,%%mm2, %%mm3 \n\t"*/\
153 "movq %%mm2, %%mm3 \n\t" /* replace for "pshufw $9,%%mm2, %%mm3" - Fizick */\
154 "psrlq $16, %%mm3 \n\t"/* replace for "pshufw $9,%%mm2, %%mm3" - Fizick*/\
155 "punpcklbw %%mm7, %%mm2 \n\t" /* ABS(cur[x-refs-1] - cur[x+refs-1]) */\
156 "punpcklbw %%mm7, %%mm3 \n\t" /* ABS(cur[x-refs+1] - cur[x+refs+1]) */\
157 "paddw %%mm2, %%mm0 \n\t"\
158 "paddw %%mm3, %%mm0 \n\t"\
159 "psubw %[pw1], %%mm0 \n\t" /* spatial_score */\
170 /* if(p->mode<2) ... */\
171 "movq %[tmp3], %%mm6 \n\t" /* diff */\
172 "cmp $2, %[mode] \n\t"\
174 LOAD4("(%["prev2"],%[mrefs],2)", %%mm2) /* prev2[x-2*refs] */\
175 LOAD4("(%["next2"],%[mrefs],2)", %%mm4) /* next2[x-2*refs] */\
176 LOAD4("(%["prev2"],%[prefs],2)", %%mm3) /* prev2[x+2*refs] */\
177 LOAD4("(%["next2"],%[prefs],2)", %%mm5) /* next2[x+2*refs] */\
178 "paddw %%mm4, %%mm2 \n\t"\
179 "paddw %%mm5, %%mm3 \n\t"\
180 "psrlw $1, %%mm2 \n\t" /* b */\
181 "psrlw $1, %%mm3 \n\t" /* f */\
182 "movq %[tmp0], %%mm4 \n\t" /* c */\
183 "movq %[tmp1], %%mm5 \n\t" /* d */\
184 "movq %[tmp2], %%mm7 \n\t" /* e */\
185 "psubw %%mm4, %%mm2 \n\t" /* b-c */\
186 "psubw %%mm7, %%mm3 \n\t" /* f-e */\
187 "movq %%mm5, %%mm0 \n\t"\
188 "psubw %%mm4, %%mm5 \n\t" /* d-c */\
189 "psubw %%mm7, %%mm0 \n\t" /* d-e */\
190 "movq %%mm2, %%mm4 \n\t"\
191 "pminsw %%mm3, %%mm2 \n\t"\
192 "pmaxsw %%mm4, %%mm3 \n\t"\
193 "pmaxsw %%mm5, %%mm2 \n\t"\
194 "pminsw %%mm5, %%mm3 \n\t"\
195 "pmaxsw %%mm0, %%mm2 \n\t" /* max */\
196 "pminsw %%mm0, %%mm3 \n\t" /* min */\
197 "pxor %%mm4, %%mm4 \n\t"\
198 "pmaxsw %%mm3, %%mm6 \n\t"\
199 "psubw %%mm2, %%mm4 \n\t" /* -max */\
200 "pmaxsw %%mm4, %%mm6 \n\t" /* diff= MAX3(diff, min, -max); */\
203 "movq %[tmp1], %%mm2 \n\t" /* d */\
204 "movq %%mm2, %%mm3 \n\t"\
205 "psubw %%mm6, %%mm2 \n\t" /* d-diff */\
206 "paddw %%mm6, %%mm3 \n\t" /* d+diff */\
207 "pmaxsw %%mm2, %%mm1 \n\t"\
208 "pminsw %%mm3, %%mm1 \n\t" /* d = clip(spatial_pred, d-diff, d+diff); */\
209 "packuswb %%mm1, %%mm1 \n\t"\
218 [prefs]"r"((long)refs),\
219 [mrefs]"r"((long)-refs),\
224 asm volatile("movd %%mm1, %0" :"=m"(*dst));\
252 #ifndef attribute_align_arg
253 #if defined(__GNUC__) && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__>1)
254 # define attribute_align_arg __attribute__((force_align_arg_pointer))
256 # define attribute_align_arg
260 // for proper alignment SSE2 we need in GCC 4.2 and above
261 #if (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__>1)
263 #ifndef DECLARE_ALIGNED
264 #define DECLARE_ALIGNED(n,t,v) t v __attribute__ ((aligned (n)))
267 // ================= SSE2 =================
268 #if defined(USE_SSE2) && defined(ARCH_X86_64)
269 #define PABS(tmp,dst) \
270 "pxor "#tmp", "#tmp" \n\t"\
271 "psubw "#dst", "#tmp" \n\t"\
272 "pmaxsw "#tmp", "#dst" \n\t"
274 #define FILTER_LINE_FUNC_NAME filter_line_sse2
275 #include "vf_yadif_template.h"
278 // ================ SSSE3 =================
280 #define PABS(tmp,dst) \
281 "pabsw "#dst", "#dst" \n\t"
283 #define FILTER_LINE_FUNC_NAME filter_line_ssse3
284 #include "vf_yadif_template.h"
288 #endif // GNUC, USE_SSE
290 static void filter_line_c(int mode, uint8_t *dst, const uint8_t *prev, const uint8_t *cur, const uint8_t *next, int w, int refs, int parity){
292 const uint8_t *prev2= parity ? prev : cur ;
293 const uint8_t *next2= parity ? cur : next;
296 int d= (prev2[0] + next2[0])>>1;
298 int temporal_diff0= ABS(prev2[0] - next2[0]);
299 int temporal_diff1=( ABS(prev[-refs] - c) + ABS(prev[+refs] - e) )>>1;
300 int temporal_diff2=( ABS(next[-refs] - c) + ABS(next[+refs] - e) )>>1;
301 int diff= MAX3(temporal_diff0>>1, temporal_diff1, temporal_diff2);
302 int spatial_pred= (c+e)>>1;
303 int spatial_score= ABS(cur[-refs-1] - cur[+refs-1]) + ABS(c-e)
304 + ABS(cur[-refs+1] - cur[+refs+1]) - 1;
307 { int score= ABS(cur[-refs-1+ j] - cur[+refs-1- j])\
308 + ABS(cur[-refs + j] - cur[+refs - j])\
309 + ABS(cur[-refs+1+ j] - cur[+refs+1- j]);\
310 if(score < spatial_score){\
311 spatial_score= score;\
312 spatial_pred= (cur[-refs + j] + cur[+refs - j])>>1;\
314 CHECK(-1) CHECK(-2) }} }}
315 CHECK( 1) CHECK( 2) }} }}
318 int b= (prev2[-2*refs] + next2[-2*refs])>>1;
319 int f= (prev2[+2*refs] + next2[+2*refs])>>1;
323 int max= MAX3(d-e, d-c, MIN3(MAX(b-c,f-e),MAX(b-c,b-a),MAX(f-g,f-e)) );
324 int min= MIN3(d-e, d-c, MAX3(MIN(b-c,f-e),MIN(b-c,b-a),MIN(f-g,f-e)) );
326 int max= MAX3(d-e, d-c, MIN(b-c, f-e));
327 int min= MIN3(d-e, d-c, MAX(b-c, f-e));
330 diff= MAX3(diff, min, -max);
333 if(spatial_pred > d + diff)
334 spatial_pred = d + diff;
335 else if(spatial_pred < d - diff)
336 spatial_pred = d - diff;
338 dst[0] = spatial_pred;
349 static void interpolate(uint8_t *dst, const uint8_t *cur0, const uint8_t *cur2, int w)
352 for (x=0; x<w; x++) {
353 dst[x] = (cur0[x] + cur2[x] + 1)>>1; // simple average
357 void filter_plane(int mode, uint8_t *dst, int dst_stride, const uint8_t *prev0, const uint8_t *cur0, const uint8_t *next0, int refs, int w, int h, int parity, int tff, int cpu){
360 filter_line = filter_line_c;
362 #if (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__>1)
364 if (cpu & AVS_CPU_SSSE3)
365 filter_line = filter_line_ssse3;
368 #if defined(USE_SSE2) && defined(ARCH_X86_64)
369 if (cpu & AVS_CPU_SSE2)
370 filter_line = filter_line_sse2;
375 if (cpu & AVS_CPU_INTEGER_SSE)
376 filter_line = filter_line_mmx2;
380 if(((y ^ parity) & 1)){
381 memcpy(dst, cur0 + refs, w);// duplicate 1
383 memcpy(dst, cur0, w);
386 if(((y ^ parity) & 1)){
387 interpolate(dst + dst_stride, cur0, cur0 + refs*2, w); // interpolate 0 and 2
389 memcpy(dst + dst_stride, cur0 + refs, w); // copy original
391 for(y=2; y<h-2; y++){
392 if(((y ^ parity) & 1)){
393 const uint8_t *prev= prev0 + y*refs;
394 const uint8_t *cur = cur0 + y*refs;
395 const uint8_t *next= next0 + y*refs;
396 uint8_t *dst2= dst + y*dst_stride;
397 filter_line(mode, dst2, prev, cur, next, w, refs, (parity ^ tff));
399 memcpy(dst + y*dst_stride, cur0 + y*refs, w); // copy original
403 if(((y ^ parity) & 1)){
404 interpolate(dst + (h-2)*dst_stride, cur0 + (h-3)*refs, cur0 + (h-1)*refs, w); // interpolate h-3 and h-1
406 memcpy(dst + (h-2)*dst_stride, cur0 + (h-2)*refs, w); // copy original
409 if(((y ^ parity) & 1)){
410 memcpy(dst + (h-1)*dst_stride, cur0 + (h-2)*refs, w); // duplicate h-2
412 memcpy(dst + (h-1)*dst_stride, cur0 + (h-1)*refs, w); // copy original
415 #if defined(__GNUC__) && defined(USE_SSE)
416 if (cpu >= AVS_CPU_INTEGER_SSE)
417 asm volatile("emms");
421 #if defined(__GNUC__) && defined(USE_SSE) && !defined(PIC)
422 static attribute_align_arg void YUY2ToPlanes_mmx(const unsigned char *srcYUY2, int pitch_yuy2, int width, int height,
423 unsigned char *py, int pitch_y,
424 unsigned char *pu, unsigned char *pv, int pitch_uv)
425 { /* process by 16 bytes (8 pixels), so width is assumed mod 8 */
426 int widthdiv2 = width>>1;
427 // static unsigned __int64 Ymask = 0x00FF00FF00FF00FFULL;
429 for (h=0; h<height; h++)
432 "pcmpeqb %%mm5, %%mm5 \n\t" /* prepare Ymask FFFFFFFFFFFFFFFF */\
433 "psrlw $8, %%mm5 \n\t" /* Ymask = 00FF00FF00FF00FF */\
434 "xor %%eax, %%eax \n\t"\
436 "prefetchnta 0xc0(%%edi,%%eax,4) \n\t"\
437 "movq (%%edi,%%eax,4), %%mm0 \n\t" /* src VYUYVYUY - 1 */\
438 "movq 8(%%edi,%%eax,4), %%mm1 \n\t" /* src VYUYVYUY - 2 */\
439 "movq %%mm0, %%mm2 \n\t" /* VYUYVYUY - 1 */\
440 "movq %%mm1, %%mm3 \n\t" /* VYUYVYUY - 2 */\
441 "pand %%mm5, %%mm0 \n\t" /* 0Y0Y0Y0Y - 1 */\
442 "psrlw $8, %%mm2 \n\t" /* 0V0U0V0U - 1 */\
443 "pand %%mm5, %%mm1 \n\t" /* 0Y0Y0Y0Y - 2 */\
444 "psrlw $8, %%mm3 \n\t" /* 0V0U0V0U - 2 */\
445 "packuswb %%mm1, %%mm0 \n\t" /* YYYYYYYY */\
446 "packuswb %%mm3, %%mm2 \n\t" /* VUVUVUVU */\
447 "movntq %%mm0, (%%ebx,%%eax,2) \n\t" /* store y */\
448 "movq %%mm2, %%mm4 \n\t" /* VUVUVUVU */\
449 "pand %%mm5, %%mm2 \n\t" /* 0U0U0U0U */\
450 "psrlw $8, %%mm4 \n\t" /* 0V0V0V0V */\
451 "packuswb %%mm2, %%mm2 \n\t" /* xxxxUUUU */\
452 "packuswb %%mm4, %%mm4 \n\t" /* xxxxVVVV */\
453 "movd %%mm2, (%%edx,%%eax) \n\t" /* store u */\
454 "add $4, %%eax \n\t" \
455 "cmp %%ecx, %%eax \n\t" \
456 "movd %%mm4, -4(%%esi,%%eax) \n\t" /* store v */\
458 : : "D"(srcYUY2), "b"(py), "d"(pu), "S"(pv), "c"(widthdiv2) : "%eax");
460 srcYUY2 += pitch_yuy2;
465 asm ("sfence \n\t emms");
468 static attribute_align_arg void YUY2FromPlanes_mmx(unsigned char *dstYUY2, int pitch_yuy2, int width, int height,
469 const unsigned char *py, int pitch_y,
470 const unsigned char *pu, const unsigned char *pv, int pitch_uv)
472 int widthdiv2 = width >> 1;
474 for (h=0; h<height; h++)
477 "xor %%eax, %%eax \n\t"\
479 "movd (%%edx,%%eax), %%mm1 \n\t" /* 0000UUUU */\
480 "movd (%%esi,%%eax), %%mm2 \n\t" /* 0000VVVV */\
481 "movq (%%ebx,%%eax,2), %%mm0 \n\t" /* YYYYYYYY */\
482 "punpcklbw %%mm2,%%mm1 \n\t" /* VUVUVUVU */\
483 "movq %%mm0, %%mm3 \n\t" /* YYYYYYYY */\
484 "punpcklbw %%mm1, %%mm0 \n\t" /* VYUYVYUY */\
485 "add $4, %%eax \n\t"\
486 "punpckhbw %%mm1, %%mm3 \n\t" /* VYUYVYUY */\
487 "movntq %%mm0, -16(%%edi,%%eax,4) \n\t" /*store */\
488 "movntq %%mm3, -8(%%edi,%%eax,4) \n\t" /* store */\
489 "cmp %%ecx, %%eax \n\t"\
491 : : "b"(py), "d"(pu), "S"(pv), "D"(dstYUY2), "c"(widthdiv2) : "%eax");
495 dstYUY2 += pitch_yuy2;
497 asm ("sfence \n\t emms");
499 #endif // GNUC, USE_SSE, !PIC
501 //----------------------------------------------------------------------------------------------
503 void YUY2ToPlanes(const unsigned char *pSrcYUY2, int nSrcPitchYUY2, int nWidth, int nHeight,
504 unsigned char * pSrcY, int srcPitchY,
505 unsigned char * pSrcU, unsigned char * pSrcV, int srcPitchUV, int cpu)
510 #if defined(__GNUC__) && defined(USE_SSE) && !defined(PIC)
511 if (cpu & AVS_CPU_INTEGER_SSE) {
513 YUY2ToPlanes_mmx(pSrcYUY2, nSrcPitchYUY2, w0, nHeight, pSrcY, srcPitchY, pSrcU, pSrcV, srcPitchUV);
516 for (h=0; h<nHeight; h++)
518 for (w=w0; w<nWidth; w+=2)
521 pSrcY[w] = pSrcYUY2[w2];
522 pSrcY[w+1] = pSrcYUY2[w2+2];
523 pSrcU[(w>>1)] = pSrcYUY2[w2+1];
524 pSrcV[(w>>1)] = pSrcYUY2[w2+3];
529 pSrcYUY2 += nSrcPitchYUY2;
533 //----------------------------------------------------------------------------------------------
535 void YUY2FromPlanes(unsigned char *pSrcYUY2, int nSrcPitchYUY2, int nWidth, int nHeight,
536 const unsigned char * pSrcY, int srcPitchY,
537 const unsigned char * pSrcU, const unsigned char * pSrcV, int srcPitchUV, int cpu)
541 #if defined(__GNUC__) && defined(USE_SSE) && !defined(PIC)
542 if (cpu & AVS_CPU_INTEGER_SSE) {
544 YUY2FromPlanes_mmx(pSrcYUY2, nSrcPitchYUY2, w0, nHeight, pSrcY, srcPitchY, pSrcU, pSrcV, srcPitchUV);
547 for (h=0; h<nHeight; h++)
549 for (w=w0; w<nWidth; w+=2)
552 pSrcYUY2[w2] = pSrcY[w];
553 pSrcYUY2[w2+1] = pSrcU[(w>>1)];
554 pSrcYUY2[w2+2] = pSrcY[w+1];
555 pSrcYUY2[w2+3] = pSrcV[(w>>1)];
560 pSrcYUY2 += nSrcPitchYUY2;