Mercurial > mplayer.hg
changeset 28655:9fcf23aaf13c
Factorize some code in yuv2rgb_template.c to ease further yuva2rgb patch.
Patch by C¸«±dric Schieli, cschieli gmail
author | cehoyos |
---|---|
date | Sat, 21 Feb 2009 14:51:01 +0000 |
parents | aa7af4c30429 |
children | 5a0e7cec3f9f |
files | libswscale/yuv2rgb_template.c |
diffstat | 1 files changed, 71 insertions(+), 156 deletions(-) [+] |
line wrap: on
line diff
--- a/libswscale/yuv2rgb_template.c Sat Feb 21 13:37:47 2009 +0000 +++ b/libswscale/yuv2rgb_template.c Sat Feb 21 14:51:01 2009 +0000 @@ -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 @@ 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 @@ 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 */ ); + YUV422_UNSHIFT + YUV2RGB_LOOP(3) - 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 + YUV2RGB_INIT + YUV2RGB /* mm0=B, %%mm2=G, %%mm1=R */ #if HAVE_MMX2 "movq "MANGLE(ff_M24A)", %%mm4 \n\t" @@ -436,50 +393,18 @@ "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 */ ); + YUV422_UNSHIFT + YUV2RGB_LOOP(4) - 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 + 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 @@ "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) }