Mercurial > mplayer.hg
changeset 6503:5a2bd4021c8e
cleanup & grayscale support
author | michael |
---|---|
date | Sat, 22 Jun 2002 20:37:30 +0000 |
parents | 01ada897cc89 |
children | 11c0ddb83168 |
files | postproc/swscale.c postproc/swscale_template.c |
diffstat | 2 files changed, 109 insertions(+), 128 deletions(-) [+] |
line wrap: on
line diff
--- a/postproc/swscale.c Sat Jun 22 12:12:42 2002 +0000 +++ b/postproc/swscale.c Sat Jun 22 20:37:30 2002 +0000 @@ -18,7 +18,7 @@ /* supported Input formats: YV12, I420, IYUV, YUY2, BGR32, BGR24, BGR16, BGR15, RGB32, RGB24, Y8, Y800 - supported output formats: YV12, I420, IYUV, BGR15, BGR16, BGR24, BGR32 (grayscale soon too) + supported output formats: YV12, I420, IYUV, BGR15, BGR16, BGR24, BGR32, Y8, Y800 BGR15/16 support dithering unscaled special converters @@ -100,26 +100,21 @@ #endif //FIXME replace this with something faster -#define isBGR(x) ((x)==IMGFMT_BGR32|| (x)==IMGFMT_BGR24|| (x)==IMGFMT_BGR16|| (x)==IMGFMT_BGR15) -#define isRGB(x) ((x)==IMGFMT_RGB32|| (x)==IMGFMT_RGB24|| (x)==IMGFMT_RGB16|| (x)==IMGFMT_RGB15) -#define isPlanarYUV(x) ((x)==IMGFMT_YV12 || (x)==IMGFMT_I420 || (x)==IMGFMT_IYUV|| (x)==IMGFMT_YVU9 || (x)==IMGFMT_IF09) -#define isYUV(x) (!(isBGR(x) || isRGB(x))) -#define isHalfChrV(x) ((x)==IMGFMT_YV12 || (x)==IMGFMT_I420 || (x)==IMGFMT_IYUV) +#define isPlanarYUV(x) ((x)==IMGFMT_YV12 || (x)==IMGFMT_I420 || (x)==IMGFMT_YVU9) +#define isYUV(x) ((x)==IMGFMT_YUY2 || isPlanarYUV(x)) +#define isHalfChrV(x) ((x)==IMGFMT_YV12 || (x)==IMGFMT_I420) #define isHalfChrH(x) ((x)==IMGFMT_YUY2 || (x)==IMGFMT_YV12 || (x)==IMGFMT_I420) -#define isPacked(x) (isYUV(x) && !isPlanarYUV(x)) -#define isGray(x) ((x)==IMGFMT_Y800) /* Behaviour the same as PACKED but it's PLANAR */ +#define isGray(x) ((x)==IMGFMT_Y800) #define isSupportedIn(x) ((x)==IMGFMT_YV12 || (x)==IMGFMT_I420 || (x)==IMGFMT_YUY2 \ || (x)==IMGFMT_BGR32|| (x)==IMGFMT_BGR24|| (x)==IMGFMT_BGR16|| (x)==IMGFMT_BGR15\ || (x)==IMGFMT_RGB32|| (x)==IMGFMT_RGB24\ || (x)==IMGFMT_Y800) #define isSupportedOut(x) ((x)==IMGFMT_YV12 || (x)==IMGFMT_I420 \ - || (x)==IMGFMT_BGR32|| (x)==IMGFMT_BGR24|| (x)==IMGFMT_BGR16|| (x)==IMGFMT_BGR15) -#define isSupportedUnscaledIn(x) ((x)==IMGFMT_YV12 || (x)==IMGFMT_I420 || (x)==IMGFMT_YUY2 || (x)==IMGFMT_NV12 \ || (x)==IMGFMT_BGR32|| (x)==IMGFMT_BGR24|| (x)==IMGFMT_BGR16|| (x)==IMGFMT_BGR15\ - || (x)==IMGFMT_RGB32|| (x)==IMGFMT_RGB24\ || (x)==IMGFMT_Y800) -#define isSupportedUnscaledOut(x) ((x)==IMGFMT_YV12 || (x)==IMGFMT_I420 || (x) == IMGFMT_YUY2 \ - || (x)==IMGFMT_BGR32|| (x)==IMGFMT_BGR24|| (x)==IMGFMT_BGR16|| (x)==IMGFMT_BGR15) +#define isRGB(x) (((x)&IMGFMT_RGB_MASK)==IMGFMT_RGB) +#define isBGR(x) (((x)&IMGFMT_BGR_MASK)==IMGFMT_BGR) +#define isPacked(x) ((x)==IMGFMT_YUY2 || isRGB(x) || isBGR(x)) #define RGB2YUV_SHIFT 16 #define BY ((int)( 0.098*(1<<RGB2YUV_SHIFT)+0.5)) @@ -1300,7 +1295,7 @@ yuv2rgb( dst,src[0],src[2],src[1],c->srcW,srcSliceH,dstStride[0],srcStride[0],srcStride[1] ); } -static void Planar2PackedWrapper(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY, +static void PlanarToYuy2Wrapper(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t* dstParam[], int dstStride[]){ uint8_t *dst=dstParam[0] + dstStride[0]*srcSliceY; @@ -1542,54 +1537,49 @@ dstStride[0], dstStride[1], srcStride[0]); } +/** + * bring pointers in YUV order instead of YVU + */ +static inline void orderYUV(SwsContext *c, uint8_t * sortedP[], int sortedStride[], uint8_t * p[], int stride[]){ + if(c->srcFormat == IMGFMT_YV12){ + sortedP[0]= p[0]; + sortedP[1]= p[1]; + sortedP[2]= p[2]; + sortedStride[0]= sortedStride[0]; + sortedStride[1]= sortedStride[1]; + sortedStride[2]= sortedStride[2]; + } + else if(isPacked(c->srcFormat) || isGray(c->srcFormat)) + { + sortedP[0]= p[0]; + sortedP[1]= + sortedP[2]= NULL; + sortedStride[0]= sortedStride[0]; + sortedStride[1]= + sortedStride[2]= 0; + } + else /* I420 */ + { + sortedP[0]= p[0]; + sortedP[1]= p[2]; + sortedP[2]= p[1]; + sortedStride[0]= sortedStride[0]; + sortedStride[1]= sortedStride[2]; + sortedStride[2]= sortedStride[1]; + } +} /* unscaled copy like stuff (assumes nearly identical formats) */ static void simpleCopy(SwsContext *c, uint8_t* srcParam[], int srcStrideParam[], int srcSliceY, - int srcSliceH, uint8_t* dstParam[], int dstStride[]){ + int srcSliceH, uint8_t* dstParam[], int dstStrideParam[]){ int srcStride[3]; + int dstStride[3]; uint8_t *src[3]; uint8_t *dst[3]; - if(isPlanarYUV(c->srcFormat)) - { - if(c->srcFormat == IMGFMT_I420 || c->srcFormat == IMGFMT_IYUV){ - 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 - { - 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) || isGray(c->srcFormat)){ - src[0]= srcParam[0]; - src[1]= - src[2]= NULL; - srcStride[0]= srcStrideParam[0]; - srcStride[1]= - srcStride[2]= 0; - } - - if(c->dstFormat == IMGFMT_I420 || c->dstFormat == IMGFMT_IYUV){ - dst[0]= dstParam[0]; - dst[1]= dstParam[2]; - dst[2]= dstParam[1]; - - }else{ - dst[0]= dstParam[0]; - dst[1]= dstParam[1]; - dst[2]= dstParam[2]; - } + orderYUV(c, src, srcStride, srcParam, srcStrideParam); + orderYUV(c, dst, dstStride, dstParam, dstStrideParam); if(isPacked(c->srcFormat)) { @@ -1616,45 +1606,41 @@ } } else - { /* Planar YUV */ + { /* Planar YUV or gray */ int plane; for(plane=0; plane<3; plane++) { - int length; - int y; - int height; - if(c->srcFormat == IMGFMT_YVU9 || c->srcFormat == IMGFMT_IF09) + int length= plane==0 ? c->srcW : ((c->srcW+1)>>1); + int y= plane==0 ? srcSliceY: ((srcSliceY+1)>>1); + int height= plane==0 ? srcSliceH: ((srcSliceH+1)>>1); + + if((isGray(c->srcFormat) || isGray(c->dstFormat)) && plane>0) { - length= plane==0 ? c->srcW : ((c->srcW+1)>>2); - y= plane==0 ? srcSliceY: ((srcSliceY+1)>>2); - height= plane==0 ? srcSliceH: ((srcSliceH+1)>>2); + if(!isGray(c->dstFormat)) + memset(dst[plane], 0, dstStride[plane]*height); } else { - length= plane==0 ? c->srcW : ((c->srcW+1)>>1); - y= plane==0 ? srcSliceY: ((srcSliceY+1)>>1); - height= plane==0 ? srcSliceH: ((srcSliceH+1)>>1); - } - - if(dstStride[plane]==srcStride[plane]) - memcpy(dst[plane] + dstStride[plane]*y, src[plane], height*dstStride[plane]); - else - { - int i; - uint8_t *srcPtr= src[plane]; - uint8_t *dstPtr= dst[plane] + dstStride[plane]*y; - for(i=0; i<height; i++) + if(dstStride[plane]==srcStride[plane]) + memcpy(dst[plane] + dstStride[plane]*y, src[plane], height*dstStride[plane]); + else { - memcpy(dstPtr, srcPtr, length); - srcPtr+= srcStride[plane]; - dstPtr+= dstStride[plane]; + int i; + uint8_t *srcPtr= src[plane]; + uint8_t *dstPtr= dst[plane] + dstStride[plane]*y; + for(i=0; i<height; i++) + { + memcpy(dstPtr, srcPtr, length); + srcPtr+= srcStride[plane]; + dstPtr+= dstStride[plane]; + } } } } } } -static uint32_t remove_dup_fourcc(uint32_t fourcc) +static int remove_dup_fourcc(int fourcc) { switch(fourcc) { @@ -1670,51 +1656,31 @@ SwsContext *c; int i; int usesFilter; - int simple_copy, unscaled_copy; + int unscaled; SwsFilter dummyFilter= {NULL, NULL, NULL, NULL}; - #ifdef ARCH_X86 if(gCpuCaps.hasMMX) asm volatile("emms\n\t"::: "memory"); #endif - if(swScale==NULL) globalInit(); /* avoid dupplicate Formats, so we dont need to check to much */ srcFormat = remove_dup_fourcc(srcFormat); dstFormat = remove_dup_fourcc(dstFormat); - /* don't refuse this beauty */ - unscaled_copy = (srcW == dstW && srcH == dstH); - simple_copy = (srcW == dstW && srcH == dstH && srcFormat == dstFormat); - if(!simple_copy) + + unscaled = (srcW == dstW && srcH == dstH); + + if(!isSupportedIn(srcFormat)) { - if(unscaled_copy) - { - if(!isSupportedUnscaledIn(srcFormat)) - { - MSG_ERR("swScaler: %s is not supported as input format\n", vo_format_name(srcFormat)); - return NULL; - } - if(!isSupportedUnscaledOut(dstFormat)) - { - MSG_ERR("swScaler: %s is not supported as output format\n", vo_format_name(dstFormat)); - return NULL; - } - } - else - { - if(!isSupportedIn(srcFormat)) - { - MSG_ERR("swScaler: %s is not supported as input format\n", vo_format_name(srcFormat)); - return NULL; - } - if(!isSupportedOut(dstFormat)) - { - MSG_ERR("swScaler: %s is not supported as output format\n", vo_format_name(dstFormat)); - return NULL; - } - } + MSG_ERR("swScaler: %s is not supported as input format\n", vo_format_name(srcFormat)); + return NULL; } + if(!isSupportedOut(dstFormat)) + { + MSG_ERR("swScaler: %s is not supported as output format\n", vo_format_name(dstFormat)); + return NULL; + } + /* sanity check */ if(srcW<4 || srcH<1 || dstW<8 || dstH<1) //FIXME check if these are enough and try to lowwer them after fixing the relevant parts of the code { @@ -1750,7 +1716,7 @@ if(srcFilter->chrH!=NULL && srcFilter->chrH->length>1) usesFilter=1; /* unscaled special Cases */ - if(srcW==dstW && srcH==dstH && !usesFilter) + if(unscaled && !usesFilter) { /* yv12_to_nv12 */ if((srcFormat == IMGFMT_YV12||srcFormat==IMGFMT_I420)&&dstFormat == IMGFMT_NV12) @@ -1765,7 +1731,7 @@ /* yv12_to_yuy2 */ if((srcFormat == IMGFMT_YV12||srcFormat==IMGFMT_I420)&&dstFormat == IMGFMT_YUY2) { - c->swScale= Planar2PackedWrapper; + c->swScale= PlanarToYuy2Wrapper; if(flags&SWS_PRINT_INFO) MSG_INFO("SwScaler: using unscaled %s -> %s special converter\n", @@ -1793,7 +1759,8 @@ } /* simple copy */ - if(srcFormat == dstFormat || (isPlanarYUV(srcFormat) && isPlanarYUV(dstFormat))) + if(srcFormat == dstFormat + || ((isPlanarYUV(srcFormat)||isGray(srcFormat)) && (isPlanarYUV(dstFormat)||isGray(dstFormat)))) { c->swScale= simpleCopy; @@ -1802,7 +1769,7 @@ vo_format_name(srcFormat), vo_format_name(dstFormat)); return c; } - + /* bgr32to24 & rgb32to24*/ if((srcFormat==IMGFMT_BGR32 && dstFormat==IMGFMT_BGR24) ||(srcFormat==IMGFMT_RGB32 && dstFormat==IMGFMT_RGB24)) @@ -2424,7 +2391,6 @@ void freeSwsContext(SwsContext *c){ int i; - if(!c) return; if(c->lumPixBuf)
--- a/postproc/swscale_template.c Sat Jun 22 12:12:42 2002 +0000 +++ b/postproc/swscale_template.c Sat Jun 22 20:37:30 2002 +0000 @@ -717,14 +717,17 @@ : "%eax" ); #else - //FIXME Optimize (just quickly writen not opti..) - //FIXME replace MINMAX with LUTs int i; for(i=0; i<dstW; i++) { int val= lumSrc[i]>>7; + + if(val&256){ + if(val<0) val=0; + else val=255; + } - dest[i]= MIN(MAX(val>>19, 0), 255); + dest[i]= val; } if(uDest != NULL) @@ -733,8 +736,15 @@ int u=chrSrc[i]>>7; int v=chrSrc[i + 2048]>>7; - uDest[i]= MIN(MAX(u>>19, 0), 255); - vDest[i]= MIN(MAX(v>>19, 0), 255); + if((u|v)&256){ + if(u<0) u=0; + else if (u>255) u=255; + if(v<0) v=0; + else if (v>255) v=255; + } + + uDest[i]= u; + vDest[i]= v; } #endif } @@ -2575,6 +2585,7 @@ const int lumXInc= c->lumXInc; const int chrXInc= c->chrXInc; const int dstFormat= c->dstFormat; + const int srcFormat= c->srcFormat; const int flags= c->flags; const int canMMX2BeUsed= c->canMMX2BeUsed; int16_t *vLumFilterPos= c->vLumFilterPos; @@ -2609,7 +2620,7 @@ int dstStride[3]; uint8_t *src[3]; uint8_t *dst[3]; - + if(c->srcFormat == IMGFMT_I420){ src[0]= srcParam[0]; src[1]= srcParam[2]; @@ -2626,7 +2637,7 @@ srcStride[1]= srcStrideParam[1]; srcStride[2]= srcStrideParam[2]; } - else if(isPacked(c->srcFormat) || isBGR(c->srcFormat) || isRGB(c->srcFormat)){ + else if(isPacked(c->srcFormat)){ src[0]= src[1]= src[2]= srcParam[0]; @@ -2729,7 +2740,9 @@ ASSERT(lastInChrBuf + 1 - (srcSliceY>>1) < ((srcSliceH+1)>>1)) ASSERT(lastInChrBuf + 1 - (srcSliceY>>1) >= 0) //FIXME replace parameters through context struct (some at least) - RENAME(hcscale)(chrPixBuf[ chrBufIndex ], chrDstW, src1, src2, (srcW+1)>>1, chrXInc, + + if(!(isGray(srcFormat) || isGray(dstFormat))) + RENAME(hcscale)(chrPixBuf[ chrBufIndex ], chrDstW, src1, src2, (srcW+1)>>1, chrXInc, flags, canMMX2BeUsed, hChrFilter, hChrFilterPos, hChrFilterSize, funnyUVCode, c->srcFormat, formatConvBuffer, c->chrMmx2Filter, c->chrMmx2FilterPos); @@ -2768,7 +2781,9 @@ ASSERT(chrBufIndex < 2*vChrBufSize) ASSERT(lastInChrBuf + 1 - (srcSliceY>>1) < ((srcSliceH+1)>>1)) ASSERT(lastInChrBuf + 1 - (srcSliceY>>1) >= 0) - RENAME(hcscale)(chrPixBuf[ chrBufIndex ], chrDstW, src1, src2, (srcW+1)>>1, chrXInc, + + if(!(isGray(srcFormat) || isGray(dstFormat))) + RENAME(hcscale)(chrPixBuf[ chrBufIndex ], chrDstW, src1, src2, (srcW+1)>>1, chrXInc, flags, canMMX2BeUsed, hChrFilter, hChrFilterPos, hChrFilterSize, funnyUVCode, c->srcFormat, formatConvBuffer, c->chrMmx2Filter, c->chrMmx2FilterPos); @@ -2788,9 +2803,9 @@ #endif if(dstY < dstH-2) { - if(isPlanarYUV(dstFormat)) //YV12 like + if(isPlanarYUV(dstFormat) || isGray(dstFormat)) //YV12 like { - if(dstY&1) uDest=vDest= NULL; //FIXME split functions in lumi / chromi + if((dstY&1) || isGray(dstFormat)) uDest=vDest= NULL; //FIXME split functions in lumi / chromi if(vLumFilterSize == 1 && vChrFilterSize == 1) // Unscaled YV12 { int16_t *lumBuf = lumPixBuf[0];