Revision 37079906

View differences:

postproc/swscale.c
34 34
#include "swscale.h"
35 35
#include "../cpudetect.h"
36 36
#include "../libvo/img_format.h"
37
#include "rgb2rgb.h"
37 38
#undef MOVNTQ
38 39
#undef PAVGB
39 40

  
......
69 70
			|| (x)==IMGFMT_Y800)
70 71
#define isSupportedOut(x) ((x)==IMGFMT_YV12 || (x)==IMGFMT_I420 \
71 72
			|| (x)==IMGFMT_BGR32|| (x)==IMGFMT_BGR24|| (x)==IMGFMT_BGR16|| (x)==IMGFMT_BGR15)
73
#define isBGR(x)       ((x)==IMGFMT_BGR32|| (x)==IMGFMT_BGR24|| (x)==IMGFMT_BGR16|| (x)==IMGFMT_BGR15)
72 74

  
73 75
#define RGB2YUV_SHIFT 16
74 76
#define BY ((int)( 0.098*(1<<RGB2YUV_SHIFT)+0.5))
......
92 94

  
93 95
TODO
94 96
more intelligent missalignment avoidance for the horizontal scaler
95
change the distance of the u & v buffer
96 97
write special vertical cubic upscale version
97 98
Optimize C code (yv12 / minmax)
98 99
add support for packed pixel yuv input & output
......
100 101
optimize bgr24 & bgr32
101 102
add BGR4 output support
102 103
write special BGR->BGR scaler
104
deglobalize yuv2rgb*.c
103 105
*/
104 106

  
105 107
#define ABS(a) ((a) > 0 ? (a) : (-(a)))
......
1107 1109
#endif //!RUNTIME_CPUDETECT
1108 1110
}
1109 1111

  
1112
/* Warper functions for yuv2bgr */
1113
static void planarYuvToBgr(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
1114
             int srcSliceH, uint8_t* dst[], int dstStride[]){
1115

  
1116
	if(c->srcFormat==IMGFMT_YV12)
1117
		yuv2rgb( dst[0],src[0],src[1],src[2],c->srcW,c->srcH,dstStride[0],srcStride[0],srcStride[1] );
1118
	else /* I420 & IYUV */
1119
		yuv2rgb( dst[0],src[0],src[2],src[1],c->srcW,c->srcH,dstStride[0],srcStride[0],srcStride[1] );
1120
}
1110 1121

  
1111 1122
SwsContext *getSwsContext(int srcW, int srcH, int srcFormat, int dstW, int dstH, int dstFormat, int flags,
1112 1123
                         SwsFilter *srcFilter, SwsFilter *dstFilter){
1113 1124

  
1114 1125
	SwsContext *c;
1115 1126
	int i;
1127
	int usesFilter;
1116 1128
	SwsFilter dummyFilter= {NULL, NULL, NULL, NULL};
1117 1129

  
1118 1130
#ifdef ARCH_X86
......
1162 1174
	c->dstFormat= dstFormat;
1163 1175
	c->srcFormat= srcFormat;
1164 1176

  
1177
	usesFilter=0;
1178
	if(dstFilter->lumV!=NULL && dstFilter->lumV->length>1) usesFilter=1;
1179
	if(dstFilter->lumH!=NULL && dstFilter->lumH->length>1) usesFilter=1;
1180
	if(dstFilter->chrV!=NULL && dstFilter->chrV->length>1) usesFilter=1;
1181
	if(dstFilter->chrH!=NULL && dstFilter->chrH->length>1) usesFilter=1;
1182
	if(srcFilter->lumV!=NULL && srcFilter->lumV->length>1) usesFilter=1;
1183
	if(srcFilter->lumH!=NULL && srcFilter->lumH->length>1) usesFilter=1;
1184
	if(srcFilter->chrV!=NULL && srcFilter->chrV->length>1) usesFilter=1;
1185
	if(srcFilter->chrH!=NULL && srcFilter->chrH->length>1) usesFilter=1;
1186
	
1187
	/* special Cases */
1188
	if(srcW==dstW && srcH==dstH && !usesFilter)
1189
	{
1190
		/* yuv2bgr */
1191
		if(isPlanarYUV(srcFormat) && isBGR(dstFormat))
1192
		{
1193
			// FIXME multiple yuv2rgb converters wont work that way cuz that thing is full of globals&statics
1194
			yuv2rgb_init( dstFormat&0xFF /* =bpp */, MODE_BGR);
1195
			c->swScale= planarYuvToBgr;
1196
			
1197
			if(flags&SWS_PRINT_INFO)
1198
				printf("SwScaler: using unscaled %s -> %s special converter\n", 
1199
					vo_format_name(srcFormat), vo_format_name(dstFormat));
1200
			return c;
1201
		}
1202
	}
1203

  
1165 1204
	if(cpuCaps.hasMMX2)
1166 1205
	{
1167 1206
		c->canMMX2BeUsed= (dstW >=srcW && (dstW&31)==0 && (srcW&15)==0) ? 1 : 0;
......
1403 1442
		printf("SwScaler:Chr srcW=%d srcH=%d dstW=%d dstH=%d xInc=%d yInc=%d\n",
1404 1443
			c->chrSrcW, c->chrSrcH, c->chrDstW, c->chrDstH, c->chrXInc, c->chrYInc);
1405 1444
	}
1406
	
1445

  
1446
	c->swScale= swScale;
1407 1447
	return c;
1408 1448
}
1409 1449

  
postproc/swscale.h
37 37
#define SWS_MAX_REDUCE_CUTOFF 0.002
38 38

  
39 39
/* this struct should be aligned on at least 32-byte boundary */
40
typedef struct{
40
typedef struct SwsContext{
41 41
	int srcW, srcH, dstW, dstH;
42 42
	int chrSrcW, chrSrcH, chrDstW, chrDstH;
43 43
	int lumXInc, chrXInc;
......
78 78
	int chrBufIndex;
79 79
	int dstY;
80 80
	int flags;
81

  
82
	void (*swScale)(struct SwsContext *context, uint8_t* src[], int srcStride[], int srcSliceY,
83
             int srcSliceH, uint8_t* dst[], int dstStride[]);
81 84
} SwsContext;
82 85
//FIXME check init (where 0)
83 86

  
......
116 119
SwsContext *getSwsContext(int srcW, int srcH, int srcFormat, int dstW, int dstH, int dstFormat, int flags,
117 120
			 SwsFilter *srcFilter, SwsFilter *dstFilter);
118 121

  
119
extern void (*swScale)(SwsContext *context, uint8_t* src[], int srcStride[], int srcSliceY,
120
             int srcSliceH, uint8_t* dst[], int dstStride[]);
121

  
122 122
SwsVector *getGaussianVec(double variance, double quality);
123 123
SwsVector *getConstVec(double c, int length);
124 124
SwsVector *getIdentityVec(void);
postproc/swscale_template.c
2192 2192
	uint8_t *src[3];
2193 2193
	uint8_t *dst[3];
2194 2194
	
2195
	if((c->srcFormat == IMGFMT_IYUV) || (c->srcFormat == IMGFMT_I420)){
2195
	if(c->srcFormat == IMGFMT_I420){
2196 2196
		src[0]= srcParam[0];
2197 2197
		src[1]= srcParam[2];
2198 2198
		src[2]= srcParam[1];
......
2225 2225
		srcStride[2]= 0;
2226 2226
	}
2227 2227

  
2228
	if((c->dstFormat == IMGFMT_IYUV) || (c->dstFormat == IMGFMT_I420)){
2228
	if(c->dstFormat == IMGFMT_I420){
2229 2229
		dst[0]= dstParam[0];
2230 2230
		dst[1]= dstParam[2];
2231 2231
		dst[2]= dstParam[1];
......
2235 2235
		dst[1]= dstParam[1];
2236 2236
		dst[2]= dstParam[2];
2237 2237
	}
2238
	
2238

  
2239
//printf("sws Strides:%d %d %d -> %d %d %d\n", srcStride[0],srcStride[1],srcStride[2],
2240
//dstStride[0],dstStride[1],dstStride[2]);
2239 2241

  
2240 2242
	if(dstStride[0]%8 !=0 || dstStride[1]%8 !=0 || dstStride[2]%8 !=0)
2241 2243
	{

Also available in: Unified diff