diff --git a/postproc/swscale.c b/postproc/swscale.c index d804591c17..5cb3a80785 100644 --- a/postproc/swscale.c +++ b/postproc/swscale.c @@ -253,6 +253,8 @@ void (*swScale)(SwsContext *context, uint8_t* src[], int srcStride[], int srcSli int srcSliceH, uint8_t* dst[], int dstStride[])=NULL; static SwsVector *getConvVec(SwsVector *a, SwsVector *b); +static inline void orderYUV(int format, uint8_t * sortedP[], int sortedStride[], uint8_t * p[], int stride[]); + #ifdef CAN_COMPILE_X86_ASM void in_asm_used_var_warning_killer() @@ -383,13 +385,13 @@ static void selfTest(uint8_t *src[3], int stride[3], int w, int h){ } } -static inline void yuv2yuvXinC(SwsContext *c, int16_t *lumFilter, int16_t **lumSrc, int lumFilterSize, +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) + uint8_t *dest, uint8_t *uDest, uint8_t *vDest, int dstW, int chrDstW) { //FIXME Optimize (just quickly writen not opti..) int i; - for(i=0; idstW; i++) + for(i=0; ichrDstW; i++) + for(i=0; iswScale(context, src, srcStride, srcSliceY, srcSliceH, dst, dstStride3); } -// will use sws_flags & src_filter (from cmd line) -SwsContext *getSwsContextFromCmdLine(int srcW, int srcH, int srcFormat, int dstW, int dstH, int dstFormat) +void swsGetFlagsAndFilterFromCmdLine(int *flags, SwsFilter **srcFilterParam, SwsFilter **dstFilterParam) { - int flags=0; static int firstTime=1; + *flags=0; #ifdef ARCH_X86 if(gCpuCaps.hasMMX) @@ -746,9 +747,9 @@ SwsContext *getSwsContextFromCmdLine(int srcW, int srcH, int srcFormat, int dstW if(firstTime) { firstTime=0; - flags= SWS_PRINT_INFO; + *flags= SWS_PRINT_INFO; } - else if(verbose>1) flags= SWS_PRINT_INFO; + else if(verbose>1) *flags= SWS_PRINT_INFO; if(src_filter.lumH) freeVec(src_filter.lumH); if(src_filter.lumV) freeVec(src_filter.lumV); @@ -809,16 +810,27 @@ SwsContext *getSwsContextFromCmdLine(int srcW, int srcH, int srcFormat, int dstW switch(sws_flags) { - case 0: flags|= SWS_FAST_BILINEAR; break; - case 1: flags|= SWS_BILINEAR; break; - case 2: flags|= SWS_BICUBIC; break; - case 3: flags|= SWS_X; break; - case 4: flags|= SWS_POINT; break; - case 5: flags|= SWS_AREA; break; - default:flags|= SWS_BILINEAR; break; + case 0: *flags|= SWS_FAST_BILINEAR; break; + case 1: *flags|= SWS_BILINEAR; break; + case 2: *flags|= SWS_BICUBIC; break; + case 3: *flags|= SWS_X; break; + case 4: *flags|= SWS_POINT; break; + case 5: *flags|= SWS_AREA; break; + default:*flags|= SWS_BILINEAR; break; } + + *srcFilterParam= &src_filter; + *dstFilterParam= NULL; +} - return getSwsContext(srcW, srcH, srcFormat, dstW, dstH, dstFormat, flags, &src_filter, NULL); +// will use sws_flags & src_filter (from cmd line) +SwsContext *getSwsContextFromCmdLine(int srcW, int srcH, int srcFormat, int dstW, int dstH, int dstFormat) +{ + int flags; + SwsFilter *dstFilterParam, *srcFilterParam; + swsGetFlagsAndFilterFromCmdLine(&flags, &srcFilterParam, &dstFilterParam); + + return getSwsContext(srcW, srcH, srcFormat, dstW, dstH, dstFormat, flags, srcFilterParam, dstFilterParam); } @@ -1863,11 +1875,11 @@ SwsContext *getSwsContext(int srcW, int srcH, int srcFormat, int dstW, int dstH, // reuse chroma for 2 pixles rgb/bgr unless user wants full chroma interpolation if((isBGR(dstFormat) || isRGB(dstFormat)) && !(flags&SWS_FULL_CHR_H_INT)) c->chrDstHSubSample=1; - // drop eery 2. pixel for chroma calculation unless user wants full chroma - if((isBGR(srcFormat) || isRGB(srcFormat) || srcFormat==IMGFMT_YUY2) && !(flags&SWS_FULL_CHR_V)) - c->chrSrcVSubSample=1; + // drop some chroma lines if the user wants it + c->vChrDrop= (flags&SWS_SRC_V_CHR_DROP_MASK)>>SWS_SRC_V_CHR_DROP_SHIFT; + c->chrSrcVSubSample+= c->vChrDrop; - // drop eery 2. pixel for chroma calculation unless user wants full chroma + // drop every 2. pixel for chroma calculation unless user wants full chroma if((isBGR(srcFormat) || isRGB(srcFormat)) && !(flags&SWS_FULL_CHR_H_INP)) c->chrSrcHSubSample=1; diff --git a/postproc/swscale.h b/postproc/swscale.h index bd28e5b6e6..85af9a9d2a 100644 --- a/postproc/swscale.h +++ b/postproc/swscale.h @@ -24,9 +24,11 @@ #define SWS_POINT 0x10 #define SWS_AREA 0x20 +#define SWS_SRC_V_CHR_DROP_MASK 0x300 +#define SWS_SRC_V_CHR_DROP_SHIFT 8 + //the following 4 flags are not completly implemented //internal chrominace subsamling info -#define SWS_FULL_CHR_V 0x100 #define SWS_FULL_CHR_H_INT 0x200 //input subsampling info #define SWS_FULL_CHR_H_INP 0x400 @@ -46,6 +48,7 @@ typedef struct SwsContext{ int chrSrcHSubSample, chrSrcVSubSample; int chrIntHSubSample, chrIntVSubSample; int chrDstHSubSample, chrDstVSubSample; + int vChrDrop; int16_t **lumPixBuf; int16_t **chrPixBuf; @@ -125,6 +128,7 @@ void freeSwsContext(SwsContext *swsContext); SwsContext *getSwsContextFromCmdLine(int srcW, int srcH, int srcFormat, int dstW, int dstH, int dstFormat); SwsContext *getSwsContext(int srcW, int srcH, int srcFormat, int dstW, int dstH, int dstFormat, int flags, SwsFilter *srcFilter, SwsFilter *dstFilter); +void swsGetFlagsAndFilterFromCmdLine(int *flags, SwsFilter **srcFilterParam, SwsFilter **dstFilterParam); SwsVector *getGaussianVec(double variance, double quality); SwsVector *getConstVec(double c, int length); diff --git a/postproc/swscale_template.c b/postproc/swscale_template.c index b50a10f71b..6e14881cc5 100644 --- a/postproc/swscale_template.c +++ b/postproc/swscale_template.c @@ -683,9 +683,9 @@ static inline void RENAME(yuv2yuvX)(int16_t *lumFilter, int16_t **lumSrc, int lu : "%eax", "%edx", "%esi" ); #else -yuv2yuvXinC(c, lumFilter, lumSrc, lumFilterSize, +yuv2yuvXinC(lumFilter, lumSrc, lumFilterSize, chrFilter, chrSrc, chrFilterSize, - dest, uDest, vDest); + dest, uDest, vDest, dstW, chrDstW); #endif } @@ -2623,56 +2623,21 @@ static void RENAME(swScale)(SwsContext *c, uint8_t* srcParam[], int srcStridePar int dstStride[3]; uint8_t *src[3]; uint8_t *dst[3]; + + orderYUV(c->srcFormat, src, srcStride, srcParam, srcStrideParam); + orderYUV(c->dstFormat, dst, dstStride, dstParam, dstStrideParam); - if(c->srcFormat == IMGFMT_I420){ - src[0]= srcParam[0]; - src[1]= srcParam[2]; - src[2]= srcParam[1]; - srcStride[0]= srcStrideParam[0]; - srcStride[1]= srcStrideParam[2]; - srcStride[2]= srcStrideParam[1]; - } - else if(c->srcFormat==IMGFMT_YV12 || c->srcFormat==IMGFMT_YVU9){ - src[0]= srcParam[0]; - src[1]= srcParam[1]; - src[2]= srcParam[2]; - srcStride[0]= srcStrideParam[0]; - srcStride[1]= srcStrideParam[1]; - srcStride[2]= srcStrideParam[2]; - } - else if(isPacked(c->srcFormat)){ + if(isPacked(c->srcFormat)){ src[0]= src[1]= src[2]= srcParam[0]; - srcStride[0]= srcStrideParam[0]; + srcStride[0]= srcStride[1]= - srcStride[2]= srcStrideParam[0]<<1; - } - else if(isGray(c->srcFormat)){ - src[0]= srcParam[0]; - src[1]= - src[2]= NULL; - srcStride[0]= srcStrideParam[0]; - srcStride[1]= - srcStride[2]= 0; + srcStride[2]= srcStrideParam[0]; } + srcStride[1]<<= c->vChrDrop; + srcStride[2]<<= c->vChrDrop; - if(dstFormat == IMGFMT_I420){ - dst[0]= dstParam[0]; - dst[1]= dstParam[2]; - dst[2]= dstParam[1]; - dstStride[0]= dstStrideParam[0]; - dstStride[1]= dstStrideParam[2]; - dstStride[2]= dstStrideParam[1]; - }else{ - dst[0]= dstParam[0]; - dst[1]= dstParam[1]; - dst[2]= dstParam[2]; - dstStride[0]= dstStrideParam[0]; - dstStride[1]= dstStrideParam[1]; - dstStride[2]= dstStrideParam[2]; - } - // printf("swscale %X %X %X -> %X %X %X\n", (int)src[0], (int)src[1], (int)src[2], // (int)dst[0], (int)dst[1], (int)dst[2]); @@ -2878,10 +2843,10 @@ i--; if(isPlanarYUV(dstFormat)) //YV12 { if(dstY&1) uDest=vDest= NULL; - yuv2yuvXinC(c, + yuv2yuvXinC( vLumFilter+dstY*vLumFilterSize , lumSrcPtr, vLumFilterSize, vChrFilter+chrDstY*vChrFilterSize, chrSrcPtr, vChrFilterSize, - dest, uDest, vDest); + dest, uDest, vDest, dstW, chrDstW); } else {