diff options
author | Cédric Schieli <cschieli@gmail.com> | 2009-02-21 14:51:01 +0000 |
---|---|---|
committer | Carl Eugen Hoyos <cehoyos@rainbow.studorg.tuwien.ac.at> | 2009-02-21 14:51:01 +0000 |
commit | 431ac290461df62b0e982e88163377080e5bf290 (patch) | |
tree | d193c5567bfad08644ca5c408570150e915acf5e | |
parent | d541a7d2d1d42f669de1716d6bbbc2e57335e837 (diff) | |
download | ffmpeg-431ac290461df62b0e982e88163377080e5bf290.tar.gz |
Factorize some code in yuv2rgb_template.c to ease further yuva2rgb patch.
Patch by Cédric Schieli, cschieli gmail
Originally committed as revision 28690 to svn://svn.mplayerhq.hu/mplayer/trunk/libswscale
-rw-r--r-- | libswscale/yuv2rgb_template.c | 231 |
1 files changed, 73 insertions, 158 deletions
diff --git a/libswscale/yuv2rgb_template.c b/libswscale/yuv2rgb_template.c index 216ddd2803..bd3a40f611 100644 --- a/libswscale/yuv2rgb_template.c +++ b/libswscale/yuv2rgb_template.c @@ -121,47 +121,68 @@ "punpcklbw %%mm5, %%mm2;" /* G7 G6 G5 G4 G3 G2 G1 G0 */\ +#define YUV422_UNSHIFT \ + if(c->srcFormat == PIX_FMT_YUV422P){ \ + srcStride[1] *= 2; \ + srcStride[2] *= 2; \ + } \ + +#define YUV2RGB_LOOP(depth) \ + h_size= (c->dstW+7)&~7; \ + if(h_size*depth > FFABS(dstStride[0])) h_size-=8; \ +\ + __asm__ volatile ("pxor %mm4, %mm4;" /* zero mm4 */ ); \ + for (y= 0; y<srcSliceH; y++ ) { \ + uint8_t *image = dst[0] + (y+srcSliceY)*dstStride[0]; \ + uint8_t *py = src[0] + y*srcStride[0]; \ + uint8_t *pu = src[1] + (y>>1)*srcStride[1]; \ + uint8_t *pv = src[2] + (y>>1)*srcStride[2]; \ + long index= -h_size/2; \ + +#define YUV2RGB_INIT \ + /* This MMX assembly code deals with a SINGLE scan line at a time, \ + * it converts 8 pixels in each iteration. */ \ + __asm__ volatile ( \ + /* load data for start of next scan line */ \ + "movd (%2, %0), %%mm0;" /* Load 4 Cb 00 00 00 00 u3 u2 u1 u0 */ \ + "movd (%3, %0), %%mm1;" /* Load 4 Cr 00 00 00 00 v3 v2 v1 v0 */ \ + "movq (%5, %0, 2), %%mm6;" /* Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */ \ + /* \ + ".balign 16 \n\t" \ + */ \ + "1: \n\t" \ + /* No speed difference on my p3@500 with prefetch, \ + * if it is faster for anyone with -benchmark then tell me. \ + PREFETCH" 64(%0) \n\t" \ + PREFETCH" 64(%1) \n\t" \ + PREFETCH" 64(%2) \n\t" \ + */ \ + +#define YUV2RGB_ENDLOOP(depth) \ + "add $"AV_STRINGIFY(depth*8)", %1 \n\t" \ + "add $4, %0 \n\t" \ + " js 1b \n\t" \ +\ + : "+r" (index), "+r" (image) \ + : "r" (pu - index), "r" (pv - index), "r"(&c->redDither), "r" (py - 2*index) \ + ); \ + } \ + __asm__ volatile (EMMS); \ + return srcSliceH; \ + static inline int RENAME(yuv420_rgb16)(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t* dst[], int dstStride[]){ int y, h_size; - if(c->srcFormat == PIX_FMT_YUV422P){ - srcStride[1] *= 2; - srcStride[2] *= 2; - } - - h_size= (c->dstW+7)&~7; - if(h_size*2 > FFABS(dstStride[0])) h_size-=8; - - __asm__ volatile ("pxor %mm4, %mm4;" /* zero mm4 */ ); - //printf("%X %X %X %X %X %X %X %X %X %X\n", (int)&c->redDither, (int)&c->blueDither, (int)src[0], (int)src[1], (int)src[2], (int)dst[0], - //srcStride[0],srcStride[1],srcStride[2],dstStride[0]); - for (y= 0; y<srcSliceH; y++ ) { - uint8_t *image = dst[0] + (y+srcSliceY)*dstStride[0]; - uint8_t *py = src[0] + y*srcStride[0]; - uint8_t *pu = src[1] + (y>>1)*srcStride[1]; - uint8_t *pv = src[2] + (y>>1)*srcStride[2]; - long index= -h_size/2; + YUV422_UNSHIFT + YUV2RGB_LOOP(2) c->blueDither= ff_dither8[y&1]; c->greenDither= ff_dither4[y&1]; c->redDither= ff_dither8[(y+1)&1]; - /* This MMX assembly code deals with a SINGLE scan line at a time, - * it converts 8 pixels in each iteration. */ - __asm__ volatile ( - /* load data for start of next scan line */ - "movd (%2, %0), %%mm0;" /* Load 4 Cb 00 00 00 00 u3 u2 u1 u0 */ - "movd (%3, %0), %%mm1;" /* Load 4 Cr 00 00 00 00 v3 v2 v1 v0 */ - "movq (%5, %0, 2), %%mm6;" /* Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */ - //".balign 16 \n\t" - "1: \n\t" - /* No speed difference on my p3@500 with prefetch, - * if it is faster for anyone with -benchmark then tell me. - PREFETCH" 64(%0) \n\t" - PREFETCH" 64(%1) \n\t" - PREFETCH" 64(%2) \n\t" - */ -YUV2RGB + + YUV2RGB_INIT + YUV2RGB #ifdef DITHER1XBPP "paddusb "BLUE_DITHER"(%4), %%mm0;" @@ -201,55 +222,22 @@ YUV2RGB MOVNTQ " %%mm5, 8 (%1);" /* store pixel 4-7 */ - "add $16, %1 \n\t" - "add $4, %0 \n\t" - " js 1b \n\t" - - : "+r" (index), "+r" (image) - : "r" (pu - index), "r" (pv - index), "r"(&c->redDither), "r" (py - 2*index) - ); - } - - __asm__ volatile (EMMS); - - return srcSliceH; + YUV2RGB_ENDLOOP(2) } static inline int RENAME(yuv420_rgb15)(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t* dst[], int dstStride[]){ int y, h_size; - if(c->srcFormat == PIX_FMT_YUV422P){ - srcStride[1] *= 2; - srcStride[2] *= 2; - } - - h_size= (c->dstW+7)&~7; - if(h_size*2 > FFABS(dstStride[0])) h_size-=8; - - __asm__ volatile ("pxor %mm4, %mm4;" /* zero mm4 */ ); - //printf("%X %X %X %X %X %X %X %X %X %X\n", (int)&c->redDither, (int)&c->blueDither, (int)src[0], (int)src[1], (int)src[2], (int)dst[0], - //srcStride[0],srcStride[1],srcStride[2],dstStride[0]); - for (y= 0; y<srcSliceH; y++ ) { - uint8_t *image = dst[0] + (y+srcSliceY)*dstStride[0]; - uint8_t *py = src[0] + y*srcStride[0]; - uint8_t *pu = src[1] + (y>>1)*srcStride[1]; - uint8_t *pv = src[2] + (y>>1)*srcStride[2]; - long index= -h_size/2; + YUV422_UNSHIFT + YUV2RGB_LOOP(2) c->blueDither= ff_dither8[y&1]; c->greenDither= ff_dither8[y&1]; c->redDither= ff_dither8[(y+1)&1]; - /* This MMX assembly code deals with a SINGLE scan line at a time, - * it converts 8 pixels in each iteration. */ - __asm__ volatile ( - /* load data for start of next scan line */ - "movd (%2, %0), %%mm0;" /* Load 4 Cb 00 00 00 00 u3 u2 u1 u0 */ - "movd (%3, %0), %%mm1;" /* Load 4 Cr 00 00 00 00 v3 v2 v1 v0 */ - "movq (%5, %0, 2), %%mm6;" /* Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */ - //".balign 16 \n\t" - "1: \n\t" -YUV2RGB + + YUV2RGB_INIT + YUV2RGB #ifdef DITHER1XBPP "paddusb "BLUE_DITHER"(%4), %%mm0 \n\t" @@ -291,49 +279,18 @@ YUV2RGB MOVNTQ " %%mm5, 8 (%1);" /* store pixel 4-7 */ - "add $16, %1 \n\t" - "add $4, %0 \n\t" - " js 1b \n\t" - : "+r" (index), "+r" (image) - : "r" (pu - index), "r" (pv - index), "r"(&c->redDither), "r" (py - 2*index) - ); - } - - __asm__ volatile (EMMS); - return srcSliceH; + YUV2RGB_ENDLOOP(2) } static inline int RENAME(yuv420_rgb24)(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t* dst[], int dstStride[]){ int y, h_size; - if(c->srcFormat == PIX_FMT_YUV422P){ - srcStride[1] *= 2; - srcStride[2] *= 2; - } - - h_size= (c->dstW+7)&~7; - if(h_size*3 > FFABS(dstStride[0])) h_size-=8; - - __asm__ volatile ("pxor %mm4, %mm4;" /* zero mm4 */ ); - - for (y= 0; y<srcSliceH; y++ ) { - uint8_t *image = dst[0] + (y+srcSliceY)*dstStride[0]; - uint8_t *py = src[0] + y*srcStride[0]; - uint8_t *pu = src[1] + (y>>1)*srcStride[1]; - uint8_t *pv = src[2] + (y>>1)*srcStride[2]; - long index= -h_size/2; - - /* This MMX assembly code deals with a SINGLE scan line at a time, - * it converts 8 pixels in each iteration. */ - __asm__ volatile ( - /* load data for start of next scan line */ - "movd (%2, %0), %%mm0;" /* Load 4 Cb 00 00 00 00 u3 u2 u1 u0 */ - "movd (%3, %0), %%mm1;" /* Load 4 Cr 00 00 00 00 v3 v2 v1 v0 */ - "movq (%5, %0, 2), %%mm6;" /* Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */ - //".balign 16 \n\t" - "1: \n\t" -YUV2RGB + YUV422_UNSHIFT + YUV2RGB_LOOP(3) + + YUV2RGB_INIT + YUV2RGB /* mm0=B, %%mm2=G, %%mm1=R */ #if HAVE_MMX2 "movq "MANGLE(ff_M24A)", %%mm4 \n\t" @@ -436,50 +393,18 @@ YUV2RGB "pxor %%mm4, %%mm4 \n\t" #endif - "add $24, %1 \n\t" - "add $4, %0 \n\t" - " js 1b \n\t" - - : "+r" (index), "+r" (image) - : "r" (pu - index), "r" (pv - index), "r"(&c->redDither), "r" (py - 2*index) - ); - } - - __asm__ volatile (EMMS); - return srcSliceH; + YUV2RGB_ENDLOOP(3) } static inline int RENAME(yuv420_rgb32)(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t* dst[], int dstStride[]){ int y, h_size; - if(c->srcFormat == PIX_FMT_YUV422P){ - srcStride[1] *= 2; - srcStride[2] *= 2; - } - - h_size= (c->dstW+7)&~7; - if(h_size*4 > FFABS(dstStride[0])) h_size-=8; - - __asm__ volatile ("pxor %mm4, %mm4;" /* zero mm4 */ ); - - for (y= 0; y<srcSliceH; y++ ) { - uint8_t *image = dst[0] + (y+srcSliceY)*dstStride[0]; - uint8_t *py = src[0] + y*srcStride[0]; - uint8_t *pu = src[1] + (y>>1)*srcStride[1]; - uint8_t *pv = src[2] + (y>>1)*srcStride[2]; - long index= -h_size/2; - - /* This MMX assembly code deals with a SINGLE scan line at a time, - * it converts 8 pixels in each iteration. */ - __asm__ volatile ( - /* load data for start of next scan line */ - "movd (%2, %0), %%mm0;" /* Load 4 Cb 00 00 00 00 u3 u2 u1 u0 */ - "movd (%3, %0), %%mm1;" /* Load 4 Cr 00 00 00 00 v3 v2 v1 v0 */ - "movq (%5, %0, 2), %%mm6;" /* Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */ - //".balign 16 \n\t" - "1: \n\t" -YUV2RGB + YUV422_UNSHIFT + YUV2RGB_LOOP(4) + + YUV2RGB_INIT + YUV2RGB /* convert RGB plane to RGB packed format, mm0 -> B, mm1 -> R, mm2 -> G, mm3 -> 0, mm4 -> GB, mm5 -> AR pixel 4-7, @@ -522,15 +447,5 @@ YUV2RGB "pxor %%mm4, %%mm4;" /* zero mm4 */ "movq 8 (%5, %0, 2), %%mm6;" /* Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */ - "add $32, %1 \n\t" - "add $4, %0 \n\t" - " js 1b \n\t" - - : "+r" (index), "+r" (image) - : "r" (pu - index), "r" (pv - index), "r"(&c->redDither), "r" (py - 2*index) - ); - } - - __asm__ volatile (EMMS); - return srcSliceH; + YUV2RGB_ENDLOOP(4) } |