diff options
Diffstat (limited to 'libswscale/swscale.c')
-rw-r--r-- | libswscale/swscale.c | 377 |
1 files changed, 300 insertions, 77 deletions
diff --git a/libswscale/swscale.c b/libswscale/swscale.c index c6012c15b7..316f4517e4 100644 --- a/libswscale/swscale.c +++ b/libswscale/swscale.c @@ -68,6 +68,10 @@ untested special converters #define MAP_ANONYMOUS MAP_ANON #endif #endif +#if HAVE_VIRTUALALLOC +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#endif #include "swscale.h" #include "swscale_internal.h" #include "rgb2rgb.h" @@ -133,6 +137,7 @@ unsigned swscale_version(void) ) #define isSupportedOut(x) ( \ (x)==PIX_FMT_YUV420P \ + || (x)==PIX_FMT_YUVA420P \ || (x)==PIX_FMT_YUYV422 \ || (x)==PIX_FMT_UYVY422 \ || (x)==PIX_FMT_YUV444P \ @@ -469,7 +474,7 @@ const char *sws_format_name(enum PixelFormat format) static inline void yuv2yuvXinC(int16_t *lumFilter, int16_t **lumSrc, int lumFilterSize, int16_t *chrFilter, int16_t **chrSrc, int chrFilterSize, - uint8_t *dest, uint8_t *uDest, uint8_t *vDest, int dstW, int chrDstW) + int16_t **alpSrc, uint8_t *dest, uint8_t *uDest, uint8_t *vDest, uint8_t *aDest, int dstW, int chrDstW) { //FIXME Optimize (just quickly written not optimized..) int i; @@ -498,6 +503,17 @@ static inline void yuv2yuvXinC(int16_t *lumFilter, int16_t **lumSrc, int lumFilt uDest[i]= av_clip_uint8(u>>19); vDest[i]= av_clip_uint8(v>>19); } + + if (CONFIG_SWSCALE_ALPHA && aDest) + for (i=0; i<dstW; i++){ + int val=1<<18; + int j; + for (j=0; j<lumFilterSize; j++) + val += alpSrc[j][i] * lumFilter[j]; + + aDest[i]= av_clip_uint8(val>>19); + } + } static inline void yuv2nv12XinC(int16_t *lumFilter, int16_t **lumSrc, int lumFilterSize, @@ -551,13 +567,14 @@ static inline void yuv2nv12XinC(int16_t *lumFilter, int16_t **lumSrc, int lumFil } } -#define YSCALE_YUV_2_PACKEDX_NOCLIP_C(type) \ +#define YSCALE_YUV_2_PACKEDX_NOCLIP_C(type,alpha) \ for (i=0; i<(dstW>>1); i++){\ int j;\ int Y1 = 1<<18;\ int Y2 = 1<<18;\ int U = 1<<18;\ int V = 1<<18;\ + int av_unused A1, A2;\ type av_unused *r, *b, *g;\ const int i2= 2*i;\ \ @@ -575,9 +592,19 @@ static inline void yuv2nv12XinC(int16_t *lumFilter, int16_t **lumSrc, int lumFil Y2>>=19;\ U >>=19;\ V >>=19;\ + if (alpha){\ + A1 = 1<<18;\ + A2 = 1<<18;\ + for (j=0; j<lumFilterSize; j++){\ + A1 += alpSrc[j][i2 ] * lumFilter[j];\ + A2 += alpSrc[j][i2+1] * lumFilter[j];\ + }\ + A1>>=19;\ + A2>>=19;\ + }\ -#define YSCALE_YUV_2_PACKEDX_C(type) \ - YSCALE_YUV_2_PACKEDX_NOCLIP_C(type)\ +#define YSCALE_YUV_2_PACKEDX_C(type,alpha) \ + YSCALE_YUV_2_PACKEDX_NOCLIP_C(type,alpha)\ if ((Y1|Y2|U|V)&256)\ {\ if (Y1>255) Y1=255; \ @@ -588,14 +615,19 @@ static inline void yuv2nv12XinC(int16_t *lumFilter, int16_t **lumSrc, int lumFil else if (U<0) U=0; \ if (V>255) V=255; \ else if (V<0) V=0; \ + }\ + if (alpha && ((A1|A2)&256)){\ + A1=av_clip_uint8(A1);\ + A2=av_clip_uint8(A2);\ } -#define YSCALE_YUV_2_PACKEDX_FULL_C \ +#define YSCALE_YUV_2_PACKEDX_FULL_C(rnd,alpha) \ for (i=0; i<dstW; i++){\ int j;\ int Y = 0;\ int U = -128<<19;\ int V = -128<<19;\ + int av_unused A;\ int R,G,B;\ \ for (j=0; j<lumFilterSize; j++){\ @@ -608,9 +640,17 @@ static inline void yuv2nv12XinC(int16_t *lumFilter, int16_t **lumSrc, int lumFil Y >>=10;\ U >>=10;\ V >>=10;\ + if (alpha){\ + A = rnd;\ + for (j=0; j<lumFilterSize; j++)\ + A += alpSrc[j][i ] * lumFilter[j];\ + A >>=19;\ + if (A&256)\ + A = av_clip_uint8(A);\ + }\ -#define YSCALE_YUV_2_RGBX_FULL_C(rnd) \ - YSCALE_YUV_2_PACKEDX_FULL_C\ +#define YSCALE_YUV_2_RGBX_FULL_C(rnd,alpha) \ + YSCALE_YUV_2_PACKEDX_FULL_C(rnd>>3,alpha)\ Y-= c->yuv2rgb_y_offset;\ Y*= c->yuv2rgb_y_coeff;\ Y+= rnd;\ @@ -652,19 +692,25 @@ static inline void yuv2nv12XinC(int16_t *lumFilter, int16_t **lumSrc, int lumFil else if (Y2<0)Y2=0; \ } -#define YSCALE_YUV_2_RGBX_C(type) \ - YSCALE_YUV_2_PACKEDX_C(type) /* FIXME fix tables so that clipping is not needed and then use _NOCLIP*/\ +#define YSCALE_YUV_2_RGBX_C(type,alpha) \ + YSCALE_YUV_2_PACKEDX_C(type,alpha) /* FIXME fix tables so that clipping is not needed and then use _NOCLIP*/\ r = (type *)c->table_rV[V]; \ g = (type *)(c->table_gU[U] + c->table_gV[V]); \ b = (type *)c->table_bU[U]; \ -#define YSCALE_YUV_2_PACKED2_C \ +#define YSCALE_YUV_2_PACKED2_C(type,alpha) \ for (i=0; i<(dstW>>1); i++){ \ const int i2= 2*i; \ int Y1= (buf0[i2 ]*yalpha1+buf1[i2 ]*yalpha)>>19; \ int Y2= (buf0[i2+1]*yalpha1+buf1[i2+1]*yalpha)>>19; \ int U= (uvbuf0[i ]*uvalpha1+uvbuf1[i ]*uvalpha)>>19; \ int V= (uvbuf0[i+VOFW]*uvalpha1+uvbuf1[i+VOFW]*uvalpha)>>19; \ + type av_unused *r, *b, *g; \ + int av_unused A1, A2; \ + if (alpha){\ + A1= (abuf0[i2 ]*yalpha1+abuf1[i2 ]*yalpha)>>19; \ + A2= (abuf0[i2+1]*yalpha1+abuf1[i2+1]*yalpha)>>19; \ + }\ #define YSCALE_YUV_2_GRAY16_2_C \ for (i=0; i<(dstW>>1); i++){ \ @@ -672,20 +718,25 @@ static inline void yuv2nv12XinC(int16_t *lumFilter, int16_t **lumSrc, int lumFil int Y1= (buf0[i2 ]*yalpha1+buf1[i2 ]*yalpha)>>11; \ int Y2= (buf0[i2+1]*yalpha1+buf1[i2+1]*yalpha)>>11; \ -#define YSCALE_YUV_2_RGB2_C(type) \ - YSCALE_YUV_2_PACKED2_C\ - type *r, *b, *g;\ +#define YSCALE_YUV_2_RGB2_C(type,alpha) \ + YSCALE_YUV_2_PACKED2_C(type,alpha)\ r = (type *)c->table_rV[V];\ g = (type *)(c->table_gU[U] + c->table_gV[V]);\ b = (type *)c->table_bU[U];\ -#define YSCALE_YUV_2_PACKED1_C \ +#define YSCALE_YUV_2_PACKED1_C(type,alpha) \ for (i=0; i<(dstW>>1); i++){\ const int i2= 2*i;\ int Y1= buf0[i2 ]>>7;\ int Y2= buf0[i2+1]>>7;\ int U= (uvbuf1[i ])>>7;\ int V= (uvbuf1[i+VOFW])>>7;\ + type av_unused *r, *b, *g;\ + int av_unused A1, A2;\ + if (alpha){\ + A1= abuf0[i2 ]>>7;\ + A2= abuf0[i2+1]>>7;\ + }\ #define YSCALE_YUV_2_GRAY16_1_C \ for (i=0; i<(dstW>>1); i++){\ @@ -693,24 +744,28 @@ static inline void yuv2nv12XinC(int16_t *lumFilter, int16_t **lumSrc, int lumFil int Y1= buf0[i2 ]<<1;\ int Y2= buf0[i2+1]<<1;\ -#define YSCALE_YUV_2_RGB1_C(type) \ - YSCALE_YUV_2_PACKED1_C\ - type *r, *b, *g;\ +#define YSCALE_YUV_2_RGB1_C(type,alpha) \ + YSCALE_YUV_2_PACKED1_C(type,alpha)\ r = (type *)c->table_rV[V];\ g = (type *)(c->table_gU[U] + c->table_gV[V]);\ b = (type *)c->table_bU[U];\ -#define YSCALE_YUV_2_PACKED1B_C \ +#define YSCALE_YUV_2_PACKED1B_C(type,alpha) \ for (i=0; i<(dstW>>1); i++){\ const int i2= 2*i;\ int Y1= buf0[i2 ]>>7;\ int Y2= buf0[i2+1]>>7;\ int U= (uvbuf0[i ] + uvbuf1[i ])>>8;\ int V= (uvbuf0[i+VOFW] + uvbuf1[i+VOFW])>>8;\ + type av_unused *r, *b, *g;\ + int av_unused A1, A2;\ + if (alpha){\ + A1= abuf0[i2 ]>>7;\ + A2= abuf0[i2+1]>>7;\ + }\ -#define YSCALE_YUV_2_RGB1B_C(type) \ - YSCALE_YUV_2_PACKED1B_C\ - type *r, *b, *g;\ +#define YSCALE_YUV_2_RGB1B_C(type,alpha) \ + YSCALE_YUV_2_PACKED1B_C(type,alpha)\ r = (type *)c->table_rV[V];\ g = (type *)(c->table_gU[U] + c->table_gV[V]);\ b = (type *)c->table_bU[U];\ @@ -768,17 +823,52 @@ static inline void yuv2nv12XinC(int16_t *lumFilter, int16_t **lumSrc, int lumFil #define YSCALE_YUV_2_ANYRGB_C(func, func2, func_g16, func_monoblack)\ switch(c->dstFormat)\ {\ - case PIX_FMT_RGB32:\ - case PIX_FMT_BGR32:\ - case PIX_FMT_RGB32_1:\ - case PIX_FMT_BGR32_1:\ - func(uint32_t)\ - ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1];\ - ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2];\ + case PIX_FMT_RGBA:\ + case PIX_FMT_BGRA:\ + if (CONFIG_SMALL){\ + int needAlpha = CONFIG_SWSCALE_ALPHA && c->alpPixBuf;\ + func(uint32_t,needAlpha)\ + ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1] + (needAlpha ? (A1<<24) : 0);\ + ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2] + (needAlpha ? (A2<<24) : 0);\ + }\ + }else{\ + if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf){\ + func(uint32_t,1)\ + ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1] + (A1<<24);\ + ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2] + (A2<<24);\ + }\ + }else{\ + func(uint32_t,0)\ + ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1];\ + ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2];\ + }\ + }\ + }\ + break;\ + case PIX_FMT_ARGB:\ + case PIX_FMT_ABGR:\ + if (CONFIG_SMALL){\ + int needAlpha = CONFIG_SWSCALE_ALPHA && c->alpPixBuf;\ + func(uint32_t,needAlpha)\ + ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1] + (needAlpha ? A1 : 0);\ + ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2] + (needAlpha ? A2 : 0);\ + }\ + }else{\ + if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf){\ + func(uint32_t,1)\ + ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1] + A1;\ + ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2] + A2;\ + }\ + }else{\ + func(uint32_t,0)\ + ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1];\ + ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2];\ + }\ + }\ } \ break;\ case PIX_FMT_RGB24:\ - func(uint8_t)\ + func(uint8_t,0)\ ((uint8_t*)dest)[0]= r[Y1];\ ((uint8_t*)dest)[1]= g[Y1];\ ((uint8_t*)dest)[2]= b[Y1];\ @@ -789,7 +879,7 @@ static inline void yuv2nv12XinC(int16_t *lumFilter, int16_t **lumSrc, int lumFil }\ break;\ case PIX_FMT_BGR24:\ - func(uint8_t)\ + func(uint8_t,0)\ ((uint8_t*)dest)[0]= b[Y1];\ ((uint8_t*)dest)[1]= g[Y1];\ ((uint8_t*)dest)[2]= r[Y1];\ @@ -808,7 +898,7 @@ static inline void yuv2nv12XinC(int16_t *lumFilter, int16_t **lumSrc, int lumFil const int dr2= dither_2x2_8[y&1 ][1];\ const int dg2= dither_2x2_4[y&1 ][1];\ const int db2= dither_2x2_8[(y&1)^1][1];\ - func(uint16_t)\ + func(uint16_t,0)\ ((uint16_t*)dest)[i2+0]= r[Y1+dr1] + g[Y1+dg1] + b[Y1+db1];\ ((uint16_t*)dest)[i2+1]= r[Y2+dr2] + g[Y2+dg2] + b[Y2+db2];\ }\ @@ -823,7 +913,7 @@ static inline void yuv2nv12XinC(int16_t *lumFilter, int16_t **lumSrc, int lumFil const int dr2= dither_2x2_8[y&1 ][1];\ const int dg2= dither_2x2_8[y&1 ][0];\ const int db2= dither_2x2_8[(y&1)^1][1];\ - func(uint16_t)\ + func(uint16_t,0)\ ((uint16_t*)dest)[i2+0]= r[Y1+dr1] + g[Y1+dg1] + b[Y1+db1];\ ((uint16_t*)dest)[i2+1]= r[Y2+dr2] + g[Y2+dg2] + b[Y2+db2];\ }\ @@ -834,7 +924,7 @@ static inline void yuv2nv12XinC(int16_t *lumFilter, int16_t **lumSrc, int lumFil {\ const uint8_t * const d64= dither_8x8_73[y&7];\ const uint8_t * const d32= dither_8x8_32[y&7];\ - func(uint8_t)\ + func(uint8_t,0)\ ((uint8_t*)dest)[i2+0]= r[Y1+d32[(i2+0)&7]] + g[Y1+d32[(i2+0)&7]] + b[Y1+d64[(i2+0)&7]];\ ((uint8_t*)dest)[i2+1]= r[Y2+d32[(i2+1)&7]] + g[Y2+d32[(i2+1)&7]] + b[Y2+d64[(i2+1)&7]];\ }\ @@ -845,7 +935,7 @@ static inline void yuv2nv12XinC(int16_t *lumFilter, int16_t **lumSrc, int lumFil {\ const uint8_t * const d64= dither_8x8_73 [y&7];\ const uint8_t * const d128=dither_8x8_220[y&7];\ - func(uint8_t)\ + func(uint8_t,0)\ ((uint8_t*)dest)[i]= r[Y1+d128[(i2+0)&7]] + g[Y1+d64[(i2+0)&7]] + b[Y1+d128[(i2+0)&7]]\ + ((r[Y2+d128[(i2+1)&7]] + g[Y2+d64[(i2+1)&7]] + b[Y2+d128[(i2+1)&7]])<<4);\ }\ @@ -856,7 +946,7 @@ static inline void yuv2nv12XinC(int16_t *lumFilter, int16_t **lumSrc, int lumFil {\ const uint8_t * const d64= dither_8x8_73 [y&7];\ const uint8_t * const d128=dither_8x8_220[y&7];\ - func(uint8_t)\ + func(uint8_t,0)\ ((uint8_t*)dest)[i2+0]= r[Y1+d128[(i2+0)&7]] + g[Y1+d64[(i2+0)&7]] + b[Y1+d128[(i2+0)&7]];\ ((uint8_t*)dest)[i2+1]= r[Y2+d128[(i2+1)&7]] + g[Y2+d64[(i2+1)&7]] + b[Y2+d128[(i2+1)&7]];\ }\ @@ -905,15 +995,15 @@ static inline void yuv2nv12XinC(int16_t *lumFilter, int16_t **lumSrc, int lumFil static inline void yuv2packedXinC(SwsContext *c, int16_t *lumFilter, int16_t **lumSrc, int lumFilterSize, int16_t *chrFilter, int16_t **chrSrc, int chrFilterSize, - uint8_t *dest, int dstW, int y) + int16_t **alpSrc, uint8_t *dest, int dstW, int y) { int i; - YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGBX_C, YSCALE_YUV_2_PACKEDX_C(void), YSCALE_YUV_2_GRAY16_C, YSCALE_YUV_2_MONOX_C) + YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGBX_C, YSCALE_YUV_2_PACKEDX_C(void,0), YSCALE_YUV_2_GRAY16_C, YSCALE_YUV_2_MONOX_C) } static inline void yuv2rgbXinC_full(SwsContext *c, int16_t *lumFilter, int16_t **lumSrc, int lumFilterSize, int16_t *chrFilter, int16_t **chrSrc, int chrFilterSize, - uint8_t *dest, int dstW, int y) + int16_t **alpSrc, uint8_t *dest, int dstW, int y) { int i; int step= fmt_depth(c->dstFormat)/8; @@ -926,12 +1016,33 @@ static inline void yuv2rgbXinC_full(SwsContext *c, int16_t *lumFilter, int16_t * case PIX_FMT_RGB24: aidx--; case PIX_FMT_RGBA: - YSCALE_YUV_2_RGBX_FULL_C(1<<21) - dest[aidx]= 255; - dest[0]= R>>22; - dest[1]= G>>22; - dest[2]= B>>22; - dest+= step; + if (CONFIG_SMALL){ + int needAlpha = CONFIG_SWSCALE_ALPHA && c->alpPixBuf; + YSCALE_YUV_2_RGBX_FULL_C(1<<21, needAlpha) + dest[aidx]= needAlpha ? A : 255; + dest[0]= R>>22; + dest[1]= G>>22; + dest[2]= B>>22; + dest+= step; + } + }else{ + if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf){ + YSCALE_YUV_2_RGBX_FULL_C(1<<21, 1) + dest[aidx]= A; + dest[0]= R>>22; + dest[1]= G>>22; + dest[2]= B>>22; + dest+= step; + } + }else{ + YSCALE_YUV_2_RGBX_FULL_C(1<<21, 0) + dest[aidx]= 255; + dest[0]= R>>22; + dest[1]= G>>22; + dest[2]= B>>22; + dest+= step; + } + } } break; case PIX_FMT_ABGR: @@ -940,12 +1051,33 @@ static inline void yuv2rgbXinC_full(SwsContext *c, int16_t *lumFilter, int16_t * case PIX_FMT_BGR24: aidx--; case PIX_FMT_BGRA: - YSCALE_YUV_2_RGBX_FULL_C(1<<21) - dest[aidx]= 255; - dest[0]= B>>22; - dest[1]= G>>22; - dest[2]= R>>22; - dest+= step; + if (CONFIG_SMALL){ + int needAlpha = CONFIG_SWSCALE_ALPHA && c->alpPixBuf; + YSCALE_YUV_2_RGBX_FULL_C(1<<21, needAlpha) + dest[aidx]= needAlpha ? A : 255; + dest[0]= B>>22; + dest[1]= G>>22; + dest[2]= R>>22; + dest+= step; + } + }else{ + if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf){ + YSCALE_YUV_2_RGBX_FULL_C(1<<21, 1) + dest[aidx]= A; + dest[0]= B>>22; + dest[1]= G>>22; + dest[2]= R>>22; + dest+= step; + } + }else{ + YSCALE_YUV_2_RGBX_FULL_C(1<<21, 0) + dest[aidx]= 255; + dest[0]= B>>22; + dest[1]= G>>22; + dest[2]= R>>22; + dest+= step; + } + } } break; default: @@ -953,6 +1085,15 @@ static inline void yuv2rgbXinC_full(SwsContext *c, int16_t *lumFilter, int16_t * } } +static void fillPlane(uint8_t* plane, int stride, int width, int height, int y, uint8_t val){ + int i; + uint8_t *ptr = plane + stride*y; + for (i=0; i<height; i++){ + memset(ptr, val, width); + ptr += stride; + } +} + //Note: we have C, X86, MMX, MMX2, 3DNOW versions, there is no 3DNOW+MMX2 one //Plain C versions #if !HAVE_MMX || defined (RUNTIME_CPUDETECT) || !CONFIG_GPL @@ -1457,13 +1598,13 @@ error: static void initMMX2HScaler(int dstW, int xInc, uint8_t *funnyCode, int16_t *filter, int32_t *filterPos, int numSplits) { uint8_t *fragmentA; - long imm8OfPShufW1A; - long imm8OfPShufW2A; - long fragmentLengthA; + x86_reg imm8OfPShufW1A; + x86_reg imm8OfPShufW2A; + x86_reg fragmentLengthA; uint8_t *fragmentB; - long imm8OfPShufW1B; - long imm8OfPShufW2B; - long fragmentLengthB; + x86_reg imm8OfPShufW1B; + x86_reg imm8OfPShufW2B; + x86_reg fragmentLengthB; int fragmentPos; int xpos, i; @@ -1736,6 +1877,56 @@ static int YUV422PToUyvyWrapper(SwsContext *c, uint8_t* src[], int srcStride[], return srcSliceH; } +static int YUYV2YUV420Wrapper(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY, + int srcSliceH, uint8_t* dstParam[], int dstStride[]){ + uint8_t *ydst=dstParam[0] + dstStride[0]*srcSliceY; + uint8_t *udst=dstParam[1] + dstStride[1]*srcSliceY/2; + uint8_t *vdst=dstParam[2] + dstStride[2]*srcSliceY/2; + + yuyvtoyuv420(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0], dstStride[1], srcStride[0]); + + if (dstParam[3]) + fillPlane(dstParam[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255); + + return srcSliceH; +} + +static int YUYV2YUV422Wrapper(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY, + int srcSliceH, uint8_t* dstParam[], int dstStride[]){ + uint8_t *ydst=dstParam[0] + dstStride[0]*srcSliceY; + uint8_t *udst=dstParam[1] + dstStride[1]*srcSliceY; + uint8_t *vdst=dstParam[2] + dstStride[2]*srcSliceY; + + yuyvtoyuv422(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0], dstStride[1], srcStride[0]); + + return srcSliceH; +} + +static int UYVY2YUV420Wrapper(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY, + int srcSliceH, uint8_t* dstParam[], int dstStride[]){ + uint8_t *ydst=dstParam[0] + dstStride[0]*srcSliceY; + uint8_t *udst=dstParam[1] + dstStride[1]*srcSliceY/2; + uint8_t *vdst=dstParam[2] + dstStride[2]*srcSliceY/2; + + uyvytoyuv420(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0], dstStride[1], srcStride[0]); + + if (dstParam[3]) + fillPlane(dstParam[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255); + + return srcSliceH; +} + +static int UYVY2YUV422Wrapper(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY, + int srcSliceH, uint8_t* dstParam[], int dstStride[]){ + uint8_t *ydst=dstParam[0] + dstStride[0]*srcSliceY; + uint8_t *udst=dstParam[1] + dstStride[1]*srcSliceY; + uint8_t *vdst=dstParam[2] + dstStride[2]*srcSliceY; + + uyvytoyuv422(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0], dstStride[1], srcStride[0]); + + return srcSliceH; +} + static int pal2rgbWrapper(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t* dst[], int dstStride[]){ const enum PixelFormat srcFormat= c->srcFormat; @@ -1862,6 +2053,8 @@ static int bgr24toyv12Wrapper(SwsContext *c, uint8_t* src[], int srcStride[], in dst[2]+(srcSliceY>>1)*dstStride[2], c->srcW, srcSliceH, dstStride[0], dstStride[1], srcStride[0]); + if (dst[3]) + fillPlane(dst[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255); return srcSliceH; } @@ -1884,13 +2077,15 @@ static int yvu9toyv12Wrapper(SwsContext *c, uint8_t* src[], int srcStride[], int } } - if (c->dstFormat==PIX_FMT_YUV420P){ + if (c->dstFormat==PIX_FMT_YUV420P || c->dstFormat==PIX_FMT_YUVA420P){ planar2x(src[1], dst[1], c->chrSrcW, c->chrSrcH, srcStride[1], dstStride[1]); planar2x(src[2], dst[2], c->chrSrcW, c->chrSrcH, srcStride[2], dstStride[2]); }else{ planar2x(src[1], dst[2], c->chrSrcW, c->chrSrcH, srcStride[1], dstStride[2]); planar2x(src[2], dst[1], c->chrSrcW, c->chrSrcH, srcStride[2], dstStride[1]); } + if (dst[3]) + fillPlane(dst[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255); return srcSliceH; } @@ -1926,17 +2121,17 @@ static int planarCopy(SwsContext *c, uint8_t* src[], int srcStride[], int srcSli int srcSliceH, uint8_t* dst[], int dstStride[]) { int plane; - for (plane=0; plane<3; plane++) + for (plane=0; plane<4; plane++) { - int length= plane==0 ? c->srcW : -((-c->srcW )>>c->chrDstHSubSample); - int y= plane==0 ? srcSliceY: -((-srcSliceY)>>c->chrDstVSubSample); - int height= plane==0 ? srcSliceH: -((-srcSliceH)>>c->chrDstVSubSample); - - if ((isGray(c->srcFormat) || isGray(c->dstFormat)) && plane>0) - { - if (!isGray(c->dstFormat)) - memset(dst[plane], 128, dstStride[plane]*height); - } + int length= (plane==0 || plane==3) ? c->srcW : -((-c->srcW )>>c->chrDstHSubSample); + int y= (plane==0 || plane==3) ? srcSliceY: -((-srcSliceY)>>c->chrDstVSubSample); + int height= (plane==0 || plane==3) ? srcSliceH: -((-srcSliceH)>>c->chrDstVSubSample); + + if (!dst[plane]) continue; + // ignore palette for GRAY8 + if (plane == 1 && !dst[2]) continue; + if (!src[plane] || (plane == 1 && !src[2])) + fillPlane(dst[plane], dstStride[plane], length, height, y, (plane==3) ? 255 : 128); else { if (dstStride[plane]==srcStride[plane] && srcStride[plane] > 0) @@ -1980,6 +2175,8 @@ static int gray16togray(SwsContext *c, uint8_t* src[], int srcStride[], int srcS srcPtr+= srcStride[0]; dstPtr+= dstStride[0]; } + if (dst[3]) + fillPlane(dst[3], dstStride[3], length, height, y, 255); return srcSliceH; } @@ -2133,12 +2330,12 @@ int sws_setColorspaceDetails(SwsContext *c, const int inv_table[4], int srcRange c->yuv2rgb_u2g_coeff= (int16_t)roundToInt16(cgu<<13); c->yuv2rgb_u2b_coeff= (int16_t)roundToInt16(cbu<<13); - sws_yuv2rgb_c_init_tables(c, inv_table, srcRange, brightness, contrast, saturation); + ff_yuv2rgb_c_init_tables(c, inv_table, srcRange, brightness, contrast, saturation); //FIXME factorize #ifdef COMPILE_ALTIVEC if (c->flags & SWS_CPU_CAPS_ALTIVEC) - sws_yuv2rgb_altivec_init_tables (c, inv_table, brightness, contrast, saturation); + ff_yuv2rgb_init_tables_altivec(c, inv_table, brightness, contrast, saturation); #endif return 0; } @@ -2335,16 +2532,16 @@ SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat, int d if ((srcFormat==PIX_FMT_YUV420P || srcFormat==PIX_FMT_YUV422P || srcFormat==PIX_FMT_YUVA420P) && (isBGR(dstFormat) || isRGB(dstFormat)) && !(flags & SWS_ACCURATE_RND) && !(dstH&1)) { - c->swScale= sws_yuv2rgb_get_func_ptr(c); + c->swScale= ff_yuv2rgb_get_func_ptr(c); } - if (srcFormat==PIX_FMT_YUV410P && dstFormat==PIX_FMT_YUV420P && !(flags & SWS_BITEXACT)) + if (srcFormat==PIX_FMT_YUV410P && (dstFormat==PIX_FMT_YUV420P || dstFormat==PIX_FMT_YUVA420P) && !(flags & SWS_BITEXACT)) { c->swScale= yvu9toyv12Wrapper; } /* bgr24toYV12 */ - if (srcFormat==PIX_FMT_BGR24 && dstFormat==PIX_FMT_YUV420P && !(flags & SWS_ACCURATE_RND)) + if (srcFormat==PIX_FMT_BGR24 && (dstFormat==PIX_FMT_YUV420P || dstFormat==PIX_FMT_YUVA420P) && !(flags & SWS_ACCURATE_RND)) c->swScale= bgr24toyv12Wrapper; /* RGB/BGR -> RGB/BGR (no dither needed forms) */ @@ -2391,6 +2588,14 @@ SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat, int d c->swScale= PlanarToUyvyWrapper; } } + if(srcFormat == PIX_FMT_YUYV422 && (dstFormat == PIX_FMT_YUV420P || dstFormat == PIX_FMT_YUVA420P)) + c->swScale= YUYV2YUV420Wrapper; + if(srcFormat == PIX_FMT_UYVY422 && (dstFormat == PIX_FMT_YUV420P || dstFormat == PIX_FMT_YUVA420P)) + c->swScale= UYVY2YUV420Wrapper; + if(srcFormat == PIX_FMT_YUYV422 && dstFormat == PIX_FMT_YUV422P) + c->swScale= YUYV2YUV422Wrapper; + if(srcFormat == PIX_FMT_UYVY422 && dstFormat == PIX_FMT_YUV422P) + c->swScale= UYVY2YUV422Wrapper; #ifdef COMPILE_ALTIVEC if ((c->flags & SWS_CPU_CAPS_ALTIVEC) && @@ -2407,6 +2612,7 @@ SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat, int d /* simple copy */ if ( srcFormat == dstFormat || (srcFormat == PIX_FMT_YUVA420P && dstFormat == PIX_FMT_YUV420P) + || (srcFormat == PIX_FMT_YUV420P && dstFormat == PIX_FMT_YUVA420P) || (isPlanarYUV(srcFormat) && isGray(dstFormat)) || (isPlanarYUV(dstFormat) && isGray(srcFormat))) { @@ -2502,10 +2708,13 @@ SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat, int d if (c->canMMX2BeUsed && (flags & SWS_FAST_BILINEAR)) { #ifdef MAP_ANONYMOUS - c->funnyYCode = (uint8_t*)mmap(NULL, MAX_FUNNY_CODE_SIZE, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); - c->funnyUVCode = (uint8_t*)mmap(NULL, MAX_FUNNY_CODE_SIZE, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); + c->funnyYCode = mmap(NULL, MAX_FUNNY_CODE_SIZE, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); + c->funnyUVCode = mmap(NULL, MAX_FUNNY_CODE_SIZE, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); +#elif HAVE_VIRTUALALLOC + c->funnyYCode = VirtualAlloc(NULL, MAX_FUNNY_CODE_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE); + c->funnyUVCode = VirtualAlloc(NULL, MAX_FUNNY_CODE_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE); #else - c->funnyYCode = av_malloc(MAX_FUNNY_CODE_SIZE); + c->funnyYCode = av_malloc(MAX_FUNNY_CODE_SIZE); c->funnyUVCode = av_malloc(MAX_FUNNY_CODE_SIZE); #endif @@ -2578,12 +2787,17 @@ SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat, int d // allocate pixbufs (we use dynamic allocation because otherwise we would need to c->lumPixBuf= av_malloc(c->vLumBufSize*2*sizeof(int16_t*)); c->chrPixBuf= av_malloc(c->vChrBufSize*2*sizeof(int16_t*)); + if (CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat) && isALPHA(c->dstFormat)) + c->alpPixBuf= av_malloc(c->vLumBufSize*2*sizeof(int16_t*)); //Note we need at least one pixel more at the end because of the MMX code (just in case someone wanna replace the 4000/8000) /* align at 16 bytes for AltiVec */ for (i=0; i<c->vLumBufSize; i++) c->lumPixBuf[i]= c->lumPixBuf[i+c->vLumBufSize]= av_mallocz(VOF+1); for (i=0; i<c->vChrBufSize; i++) c->chrPixBuf[i]= c->chrPixBuf[i+c->vChrBufSize]= av_malloc((VOF+1)*2); + if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf) + for (i=0; i<c->vLumBufSize; i++) + c->alpPixBuf[i]= c->alpPixBuf[i+c->vLumBufSize]= av_mallocz(VOF+1); //try to avoid drawing green stuff between the right end and the stride end for (i=0; i<c->vChrBufSize; i++) memset(c->chrPixBuf[i], 64, (VOF+1)*2); @@ -3134,6 +3348,12 @@ void sws_freeContext(SwsContext *c){ av_freep(&c->chrPixBuf); } + if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf){ + for (i=0; i<c->vLumBufSize; i++) + av_freep(&c->alpPixBuf[i]); + av_freep(&c->alpPixBuf); + } + av_freep(&c->vLumFilter); av_freep(&c->vChrFilter); av_freep(&c->hLumFilter); @@ -3150,10 +3370,13 @@ void sws_freeContext(SwsContext *c){ #if ARCH_X86 && CONFIG_GPL #ifdef MAP_ANONYMOUS - if (c->funnyYCode) munmap(c->funnyYCode, MAX_FUNNY_CODE_SIZE); + if (c->funnyYCode ) munmap(c->funnyYCode , MAX_FUNNY_CODE_SIZE); if (c->funnyUVCode) munmap(c->funnyUVCode, MAX_FUNNY_CODE_SIZE); +#elif HAVE_VIRTUALALLOC + if (c->funnyYCode ) VirtualFree(c->funnyYCode , MAX_FUNNY_CODE_SIZE, MEM_RELEASE); + if (c->funnyUVCode) VirtualFree(c->funnyUVCode, MAX_FUNNY_CODE_SIZE, MEM_RELEASE); #else - av_free(c->funnyYCode); + av_free(c->funnyYCode ); av_free(c->funnyUVCode); #endif c->funnyYCode=NULL; |