mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-03-28 12:32:17 +02:00
swScale internally uses yuv2rgb now if possible
Originally committed as revision 4555 to svn://svn.mplayerhq.hu/mplayer/trunk/postproc
This commit is contained in:
parent
6fe84b4327
commit
370799068d
@ -34,6 +34,7 @@
|
|||||||
#include "swscale.h"
|
#include "swscale.h"
|
||||||
#include "../cpudetect.h"
|
#include "../cpudetect.h"
|
||||||
#include "../libvo/img_format.h"
|
#include "../libvo/img_format.h"
|
||||||
|
#include "rgb2rgb.h"
|
||||||
#undef MOVNTQ
|
#undef MOVNTQ
|
||||||
#undef PAVGB
|
#undef PAVGB
|
||||||
|
|
||||||
@ -69,6 +70,7 @@
|
|||||||
|| (x)==IMGFMT_Y800)
|
|| (x)==IMGFMT_Y800)
|
||||||
#define isSupportedOut(x) ((x)==IMGFMT_YV12 || (x)==IMGFMT_I420 \
|
#define isSupportedOut(x) ((x)==IMGFMT_YV12 || (x)==IMGFMT_I420 \
|
||||||
|| (x)==IMGFMT_BGR32|| (x)==IMGFMT_BGR24|| (x)==IMGFMT_BGR16|| (x)==IMGFMT_BGR15)
|
|| (x)==IMGFMT_BGR32|| (x)==IMGFMT_BGR24|| (x)==IMGFMT_BGR16|| (x)==IMGFMT_BGR15)
|
||||||
|
#define isBGR(x) ((x)==IMGFMT_BGR32|| (x)==IMGFMT_BGR24|| (x)==IMGFMT_BGR16|| (x)==IMGFMT_BGR15)
|
||||||
|
|
||||||
#define RGB2YUV_SHIFT 16
|
#define RGB2YUV_SHIFT 16
|
||||||
#define BY ((int)( 0.098*(1<<RGB2YUV_SHIFT)+0.5))
|
#define BY ((int)( 0.098*(1<<RGB2YUV_SHIFT)+0.5))
|
||||||
@ -92,7 +94,6 @@ Special versions: fast Y 1:1 scaling (no interpolation in y direction)
|
|||||||
|
|
||||||
TODO
|
TODO
|
||||||
more intelligent missalignment avoidance for the horizontal scaler
|
more intelligent missalignment avoidance for the horizontal scaler
|
||||||
change the distance of the u & v buffer
|
|
||||||
write special vertical cubic upscale version
|
write special vertical cubic upscale version
|
||||||
Optimize C code (yv12 / minmax)
|
Optimize C code (yv12 / minmax)
|
||||||
add support for packed pixel yuv input & output
|
add support for packed pixel yuv input & output
|
||||||
@ -100,6 +101,7 @@ add support for Y8 output
|
|||||||
optimize bgr24 & bgr32
|
optimize bgr24 & bgr32
|
||||||
add BGR4 output support
|
add BGR4 output support
|
||||||
write special BGR->BGR scaler
|
write special BGR->BGR scaler
|
||||||
|
deglobalize yuv2rgb*.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define ABS(a) ((a) > 0 ? (a) : (-(a)))
|
#define ABS(a) ((a) > 0 ? (a) : (-(a)))
|
||||||
@ -1107,12 +1109,22 @@ cpuCaps= gCpuCaps;
|
|||||||
#endif //!RUNTIME_CPUDETECT
|
#endif //!RUNTIME_CPUDETECT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Warper functions for yuv2bgr */
|
||||||
|
static void planarYuvToBgr(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
|
||||||
|
int srcSliceH, uint8_t* dst[], int dstStride[]){
|
||||||
|
|
||||||
|
if(c->srcFormat==IMGFMT_YV12)
|
||||||
|
yuv2rgb( dst[0],src[0],src[1],src[2],c->srcW,c->srcH,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] );
|
||||||
|
}
|
||||||
|
|
||||||
SwsContext *getSwsContext(int srcW, int srcH, int srcFormat, int dstW, int dstH, int dstFormat, int flags,
|
SwsContext *getSwsContext(int srcW, int srcH, int srcFormat, int dstW, int dstH, int dstFormat, int flags,
|
||||||
SwsFilter *srcFilter, SwsFilter *dstFilter){
|
SwsFilter *srcFilter, SwsFilter *dstFilter){
|
||||||
|
|
||||||
SwsContext *c;
|
SwsContext *c;
|
||||||
int i;
|
int i;
|
||||||
|
int usesFilter;
|
||||||
SwsFilter dummyFilter= {NULL, NULL, NULL, NULL};
|
SwsFilter dummyFilter= {NULL, NULL, NULL, NULL};
|
||||||
|
|
||||||
#ifdef ARCH_X86
|
#ifdef ARCH_X86
|
||||||
@ -1162,6 +1174,33 @@ SwsContext *getSwsContext(int srcW, int srcH, int srcFormat, int dstW, int dstH,
|
|||||||
c->dstFormat= dstFormat;
|
c->dstFormat= dstFormat;
|
||||||
c->srcFormat= srcFormat;
|
c->srcFormat= srcFormat;
|
||||||
|
|
||||||
|
usesFilter=0;
|
||||||
|
if(dstFilter->lumV!=NULL && dstFilter->lumV->length>1) usesFilter=1;
|
||||||
|
if(dstFilter->lumH!=NULL && dstFilter->lumH->length>1) usesFilter=1;
|
||||||
|
if(dstFilter->chrV!=NULL && dstFilter->chrV->length>1) usesFilter=1;
|
||||||
|
if(dstFilter->chrH!=NULL && dstFilter->chrH->length>1) usesFilter=1;
|
||||||
|
if(srcFilter->lumV!=NULL && srcFilter->lumV->length>1) usesFilter=1;
|
||||||
|
if(srcFilter->lumH!=NULL && srcFilter->lumH->length>1) usesFilter=1;
|
||||||
|
if(srcFilter->chrV!=NULL && srcFilter->chrV->length>1) usesFilter=1;
|
||||||
|
if(srcFilter->chrH!=NULL && srcFilter->chrH->length>1) usesFilter=1;
|
||||||
|
|
||||||
|
/* special Cases */
|
||||||
|
if(srcW==dstW && srcH==dstH && !usesFilter)
|
||||||
|
{
|
||||||
|
/* yuv2bgr */
|
||||||
|
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);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(cpuCaps.hasMMX2)
|
if(cpuCaps.hasMMX2)
|
||||||
{
|
{
|
||||||
c->canMMX2BeUsed= (dstW >=srcW && (dstW&31)==0 && (srcW&15)==0) ? 1 : 0;
|
c->canMMX2BeUsed= (dstW >=srcW && (dstW&31)==0 && (srcW&15)==0) ? 1 : 0;
|
||||||
@ -1403,7 +1442,8 @@ SwsContext *getSwsContext(int srcW, int srcH, int srcFormat, int dstW, int dstH,
|
|||||||
printf("SwScaler:Chr srcW=%d srcH=%d dstW=%d dstH=%d xInc=%d yInc=%d\n",
|
printf("SwScaler:Chr srcW=%d srcH=%d dstW=%d dstH=%d xInc=%d yInc=%d\n",
|
||||||
c->chrSrcW, c->chrSrcH, c->chrDstW, c->chrDstH, c->chrXInc, c->chrYInc);
|
c->chrSrcW, c->chrSrcH, c->chrDstW, c->chrDstH, c->chrXInc, c->chrYInc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c->swScale= swScale;
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
#define SWS_MAX_REDUCE_CUTOFF 0.002
|
#define SWS_MAX_REDUCE_CUTOFF 0.002
|
||||||
|
|
||||||
/* this struct should be aligned on at least 32-byte boundary */
|
/* this struct should be aligned on at least 32-byte boundary */
|
||||||
typedef struct{
|
typedef struct SwsContext{
|
||||||
int srcW, srcH, dstW, dstH;
|
int srcW, srcH, dstW, dstH;
|
||||||
int chrSrcW, chrSrcH, chrDstW, chrDstH;
|
int chrSrcW, chrSrcH, chrDstW, chrDstH;
|
||||||
int lumXInc, chrXInc;
|
int lumXInc, chrXInc;
|
||||||
@ -78,6 +78,9 @@ typedef struct{
|
|||||||
int chrBufIndex;
|
int chrBufIndex;
|
||||||
int dstY;
|
int dstY;
|
||||||
int flags;
|
int flags;
|
||||||
|
|
||||||
|
void (*swScale)(struct SwsContext *context, uint8_t* src[], int srcStride[], int srcSliceY,
|
||||||
|
int srcSliceH, uint8_t* dst[], int dstStride[]);
|
||||||
} SwsContext;
|
} SwsContext;
|
||||||
//FIXME check init (where 0)
|
//FIXME check init (where 0)
|
||||||
|
|
||||||
@ -116,9 +119,6 @@ SwsContext *getSwsContextFromCmdLine(int srcW, int srcH, int srcFormat, int dstW
|
|||||||
SwsContext *getSwsContext(int srcW, int srcH, int srcFormat, int dstW, int dstH, int dstFormat, int flags,
|
SwsContext *getSwsContext(int srcW, int srcH, int srcFormat, int dstW, int dstH, int dstFormat, int flags,
|
||||||
SwsFilter *srcFilter, SwsFilter *dstFilter);
|
SwsFilter *srcFilter, SwsFilter *dstFilter);
|
||||||
|
|
||||||
extern void (*swScale)(SwsContext *context, uint8_t* src[], int srcStride[], int srcSliceY,
|
|
||||||
int srcSliceH, uint8_t* dst[], int dstStride[]);
|
|
||||||
|
|
||||||
SwsVector *getGaussianVec(double variance, double quality);
|
SwsVector *getGaussianVec(double variance, double quality);
|
||||||
SwsVector *getConstVec(double c, int length);
|
SwsVector *getConstVec(double c, int length);
|
||||||
SwsVector *getIdentityVec(void);
|
SwsVector *getIdentityVec(void);
|
||||||
|
@ -2192,7 +2192,7 @@ static void RENAME(swScale)(SwsContext *c, uint8_t* srcParam[], int srcStridePar
|
|||||||
uint8_t *src[3];
|
uint8_t *src[3];
|
||||||
uint8_t *dst[3];
|
uint8_t *dst[3];
|
||||||
|
|
||||||
if((c->srcFormat == IMGFMT_IYUV) || (c->srcFormat == IMGFMT_I420)){
|
if(c->srcFormat == IMGFMT_I420){
|
||||||
src[0]= srcParam[0];
|
src[0]= srcParam[0];
|
||||||
src[1]= srcParam[2];
|
src[1]= srcParam[2];
|
||||||
src[2]= srcParam[1];
|
src[2]= srcParam[1];
|
||||||
@ -2225,7 +2225,7 @@ static void RENAME(swScale)(SwsContext *c, uint8_t* srcParam[], int srcStridePar
|
|||||||
srcStride[2]= 0;
|
srcStride[2]= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((c->dstFormat == IMGFMT_IYUV) || (c->dstFormat == IMGFMT_I420)){
|
if(c->dstFormat == IMGFMT_I420){
|
||||||
dst[0]= dstParam[0];
|
dst[0]= dstParam[0];
|
||||||
dst[1]= dstParam[2];
|
dst[1]= dstParam[2];
|
||||||
dst[2]= dstParam[1];
|
dst[2]= dstParam[1];
|
||||||
@ -2235,7 +2235,9 @@ static void RENAME(swScale)(SwsContext *c, uint8_t* srcParam[], int srcStridePar
|
|||||||
dst[1]= dstParam[1];
|
dst[1]= dstParam[1];
|
||||||
dst[2]= dstParam[2];
|
dst[2]= dstParam[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//printf("sws Strides:%d %d %d -> %d %d %d\n", srcStride[0],srcStride[1],srcStride[2],
|
||||||
|
//dstStride[0],dstStride[1],dstStride[2]);
|
||||||
|
|
||||||
if(dstStride[0]%8 !=0 || dstStride[1]%8 !=0 || dstStride[2]%8 !=0)
|
if(dstStride[0]%8 !=0 || dstStride[1]%8 !=0 || dstStride[2]%8 !=0)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user