diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2002-02-06 21:59:23 +0000 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2002-02-06 21:59:23 +0000 |
commit | b6654a5464a77bb885ce0d17224f9edbe07d67ba (patch) | |
tree | 2d41ccc09f0ff3dd2b1a8952563283a66ffbe488 /postproc/swscale.c | |
parent | 370799068d1735fcc564c1e5861affe8217a79a3 (diff) | |
download | ffmpeg-b6654a5464a77bb885ce0d17224f9edbe07d67ba.tar.gz |
101 (yuv2rgb with mpeg1,...) ;)
simple copy if possible (same format, no scaling, ...)
Originally committed as revision 4556 to svn://svn.mplayerhq.hu/mplayer/trunk/postproc
Diffstat (limited to 'postproc/swscale.c')
-rw-r--r-- | postproc/swscale.c | 121 |
1 files changed, 115 insertions, 6 deletions
diff --git a/postproc/swscale.c b/postproc/swscale.c index d86edf19c9..21f1466d71 100644 --- a/postproc/swscale.c +++ b/postproc/swscale.c @@ -557,7 +557,7 @@ void SwScale_YV12slice(unsigned char* src[], int srcStride[], int srcSliceY , if(!context) context=getSwsContextFromCmdLine(srcW, srcH, IMGFMT_YV12, dstW, dstH, dstFormat); - swScale(context, src, srcStride, srcSliceY, srcSliceH, dst, dstStride3); + context->swScale(context, src, srcStride, srcSliceY, srcSliceH, dst, dstStride3); } // will use sws_flags & src_filter (from cmd line) @@ -1111,12 +1111,110 @@ cpuCaps= gCpuCaps; /* Warper functions for yuv2bgr */ static void planarYuvToBgr(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY, - int srcSliceH, uint8_t* dst[], int dstStride[]){ + int srcSliceH, uint8_t* dstParam[], int dstStride[]){ + uint8_t *dst=dstParam[0] + dstStride[0]*srcSliceY; if(c->srcFormat==IMGFMT_YV12) - yuv2rgb( dst[0],src[0],src[1],src[2],c->srcW,c->srcH,dstStride[0],srcStride[0],srcStride[1] ); + yuv2rgb( dst,src[0],src[1],src[2],c->srcW,srcSliceH,dstStride[0],srcStride[0],srcStride[1] ); else /* I420 & IYUV */ - yuv2rgb( dst[0],src[0],src[2],src[1],c->srcW,c->srcH,dstStride[0],srcStride[0],srcStride[1] ); + yuv2rgb( dst,src[0],src[2],src[1],c->srcW,srcSliceH,dstStride[0],srcStride[0],srcStride[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 srcStride[3]; + uint8_t *src[3]; + uint8_t *dst[3]; + + 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){ + 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){ + 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]; + } + + if(isPacked(c->srcFormat)) + { + if(dstStride[0]==srcStride[0]) + memcpy(dst[0] + dstStride[0]*srcSliceY, src[0], srcSliceH*dstStride[0]); + else + { + int i; + uint8_t *srcPtr= src[0]; + uint8_t *dstPtr= dst[0] + dstStride[0]*srcSliceY; + int length; + + if(c->srcFormat==IMGFMT_YUY2) length= c->srcW*2; + else if(c->srcFormat==IMGFMT_BGR15) length= c->srcW*2; + else if(c->srcFormat==IMGFMT_BGR16) length= c->srcW*2; + else if(c->srcFormat==IMGFMT_BGR24) length= c->srcW*3; + else if(c->srcFormat==IMGFMT_BGR32) length= c->srcW*4; + else return; /* that shouldnt happen */ + + for(i=0; i<srcSliceH; i++) + { + memcpy(dstPtr, srcPtr, length); + srcPtr+= srcStride[0]; + dstPtr+= dstStride[0]; + } + } + } + else + { /* Planar YUV */ + int plane; + for(plane=0; plane<3; plane++) + { + 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); +printf("%d %d %d %d %d %d\n", plane, length, y, height, dstStride[plane], srcStride[plane] ); + 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++) + { + memcpy(dstPtr, srcPtr, length); + srcPtr+= srcStride[plane]; + dstPtr+= dstStride[plane]; + } + } + } + } } SwsContext *getSwsContext(int srcW, int srcH, int srcFormat, int dstW, int dstH, int dstFormat, int flags, @@ -1191,9 +1289,20 @@ SwsContext *getSwsContext(int srcW, int srcH, int srcFormat, int dstW, int dstH, if(isPlanarYUV(srcFormat) && isBGR(dstFormat)) { // FIXME multiple yuv2rgb converters wont work that way cuz that thing is full of globals&statics - yuv2rgb_init( dstFormat&0xFF /* =bpp */, MODE_BGR); + yuv2rgb_init( dstFormat&0xFF /* =bpp */, MODE_RGB); c->swScale= planarYuvToBgr; - + + if(flags&SWS_PRINT_INFO) + printf("SwScaler: using unscaled %s -> %s special converter\n", + vo_format_name(srcFormat), vo_format_name(dstFormat)); + return c; + } + + /* simple copy */ + if(srcFormat == dstFormat || (isPlanarYUV(srcFormat) && isPlanarYUV(dstFormat))) + { + c->swScale= simpleCopy; + if(flags&SWS_PRINT_INFO) printf("SwScaler: using unscaled %s -> %s special converter\n", vo_format_name(srcFormat), vo_format_name(dstFormat)); |