comparison postproc/swscale.c @ 4467:9512d6832b38

YUY2, BGR24, BGR32 input support (no mmx yet)
author michael
date Fri, 01 Feb 2002 19:25:09 +0000
parents 5dd78b21afbc
children 76fb5d33e6eb
comparison
equal deleted inserted replaced
4466:bc7b7102c147 4467:9512d6832b38
15 along with this program; if not, write to the Free Software 15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */ 17 */
18 18
19 /* 19 /*
20 supported Input formats: YV12, I420, IYUV (grayscale soon too) 20 supported Input formats: YV12, I420, IYUV, YUY2, BGR32, BGR24 (grayscale soon too)
21 supported output formats: YV12, I420, IYUV, BGR15, BGR16, BGR24, BGR32 (grayscale soon too) 21 supported output formats: YV12, I420, IYUV, BGR15, BGR16, BGR24, BGR32 (grayscale soon too)
22 BGR15/16 support dithering 22 BGR15/16 support dithering
23 */ 23 */
24 24
25 #include <inttypes.h> 25 #include <inttypes.h>
41 //#define HAVE_3DNOW 41 //#define HAVE_3DNOW
42 //#undef HAVE_MMX 42 //#undef HAVE_MMX
43 //#undef ARCH_X86 43 //#undef ARCH_X86
44 #define DITHER1XBPP 44 #define DITHER1XBPP
45 45
46 #define RET 0xC3 //near return opcode 46 #define RET 0xC3 //near return opcode for X86
47 47
48 #ifdef MP_DEBUG 48 #ifdef MP_DEBUG
49 #define ASSERT(x) if(!(x)) { printf("ASSERT " #x " failed\n"); *((int*)0)=0; } 49 #define ASSERT(x) if(!(x)) { printf("ASSERT " #x " failed\n"); *((int*)0)=0; }
50 #else 50 #else
51 #define ASSERT(x) ; 51 #define ASSERT(x) ;
56 #else 56 #else
57 #define PI 3.14159265358979323846 57 #define PI 3.14159265358979323846
58 #endif 58 #endif
59 59
60 //FIXME replace this with something faster 60 //FIXME replace this with something faster
61 #define isYUV(x) ((x)==IMGFMT_YV12 || (x)==IMGFMT_I420 || (x)==IMGFMT_IYUV)
62 #define isPlanarYUV(x) ((x)==IMGFMT_YV12 || (x)==IMGFMT_I420 || (x)==IMGFMT_IYUV) 61 #define isPlanarYUV(x) ((x)==IMGFMT_YV12 || (x)==IMGFMT_I420 || (x)==IMGFMT_IYUV)
62 #define isYUV(x) ((x)==IMGFMT_YUY2 || isPlanarYUV(x))
63 #define isHalfChrV(x) ((x)==IMGFMT_YV12 || (x)==IMGFMT_I420 || (x)==IMGFMT_IYUV) 63 #define isHalfChrV(x) ((x)==IMGFMT_YV12 || (x)==IMGFMT_I420 || (x)==IMGFMT_IYUV)
64 #define isHalfChrH(x) ((x)==IMGFMT_YV12 || (x)==IMGFMT_I420 || (x)==IMGFMT_IYUV) 64 #define isHalfChrH(x) ((x)==IMGFMT_YUY2 || (x)==IMGFMT_YV12 || (x)==IMGFMT_I420 || (x)==IMGFMT_IYUV)
65 #define isPacked(x) ((x)==IMGFMT_YUY2 || (x)==IMGFMT_BGR32|| (x)==IMGFMT_BGR24)
66
67 #define RGB2YUV_SHIFT 8
68 #define BY ((int)( 0.098*(1<<RGB2YUV_SHIFT)+0.5))
69 #define BV ((int)(-0.071*(1<<RGB2YUV_SHIFT)+0.5))
70 #define BU ((int)( 0.439*(1<<RGB2YUV_SHIFT)+0.5))
71 #define GY ((int)( 0.504*(1<<RGB2YUV_SHIFT)+0.5))
72 #define GV ((int)(-0.368*(1<<RGB2YUV_SHIFT)+0.5))
73 #define GU ((int)(-0.291*(1<<RGB2YUV_SHIFT)+0.5))
74 #define RY ((int)( 0.257*(1<<RGB2YUV_SHIFT)+0.5))
75 #define RV ((int)( 0.439*(1<<RGB2YUV_SHIFT)+0.5))
76 #define RU ((int)(-0.148*(1<<RGB2YUV_SHIFT)+0.5))
65 77
66 extern int verbose; // defined in mplayer.c 78 extern int verbose; // defined in mplayer.c
67 /* 79 /*
68 NOTES 80 NOTES
69 81
78 write special vertical cubic upscale version 90 write special vertical cubic upscale version
79 Optimize C code (yv12 / minmax) 91 Optimize C code (yv12 / minmax)
80 add support for packed pixel yuv input & output 92 add support for packed pixel yuv input & output
81 add support for Y8 input & output 93 add support for Y8 input & output
82 add BGR4 output support 94 add BGR4 output support
83 add BGR32 / BGR24 input support 95 write special BGR->BGR scaler
84 */ 96 */
85 97
86 #define ABS(a) ((a) > 0 ? (a) : (-(a))) 98 #define ABS(a) ((a) > 0 ? (a) : (-(a)))
87 #define MIN(a,b) ((a) > (b) ? (b) : (a)) 99 #define MIN(a,b) ((a) > (b) ? (b) : (a))
88 #define MAX(a,b) ((a) < (b) ? (b) : (a)) 100 #define MAX(a,b) ((a) < (b) ? (b) : (a))
1103 if(swScale==NULL) globalInit(); 1115 if(swScale==NULL) globalInit();
1104 1116
1105 /* sanity check */ 1117 /* sanity check */
1106 if(srcW<4 || srcH<1 || dstW<8 || dstH<1) return NULL; //FIXME check if these are enough and try to lowwer them after fixing the relevant parts of the code 1118 if(srcW<4 || srcH<1 || dstW<8 || dstH<1) return NULL; //FIXME check if these are enough and try to lowwer them after fixing the relevant parts of the code
1107 1119
1108 if(srcFormat!=IMGFMT_YV12 && srcFormat!=IMGFMT_I420 && srcFormat!=IMGFMT_IYUV) return NULL; 1120 // if(!isSupportedIn(srcFormat)) return NULL;
1121 // if(!isSupportedOut(dstFormat)) return NULL;
1109 1122
1110 if(!dstFilter) dstFilter= &dummyFilter; 1123 if(!dstFilter) dstFilter= &dummyFilter;
1111 if(!srcFilter) srcFilter= &dummyFilter; 1124 if(!srcFilter) srcFilter= &dummyFilter;
1112 1125
1113 c= memalign(64, sizeof(SwsContext)); 1126 c= memalign(64, sizeof(SwsContext));
1133 } 1146 }
1134 } 1147 }
1135 else 1148 else
1136 c->canMMX2BeUsed=0; 1149 c->canMMX2BeUsed=0;
1137 1150
1151
1152 /* dont use full vertical UV input/internaly if the source doesnt even have it */
1153 if(isHalfChrV(srcFormat)) c->flags= flags= flags&(~SWS_FULL_CHR_V);
1154 /* dont use full horizontal UV input if the source doesnt even have it */
1155 if(isHalfChrH(srcFormat)) c->flags= flags= flags&(~SWS_FULL_CHR_H_INP);
1156 /* dont use full horizontal UV internally if the destination doesnt even have it */
1157 if(isHalfChrH(dstFormat)) c->flags= flags= flags&(~SWS_FULL_CHR_H_INT);
1158
1159 if(flags&SWS_FULL_CHR_H_INP) c->chrSrcW= srcW;
1160 else c->chrSrcW= (srcW+1)>>1;
1161
1162 if(flags&SWS_FULL_CHR_H_INT) c->chrDstW= dstW;
1163 else c->chrDstW= (dstW+1)>>1;
1164
1165 if(flags&SWS_FULL_CHR_V) c->chrSrcH= srcH;
1166 else c->chrSrcH= (srcH+1)>>1;
1167
1168 if(isHalfChrV(dstFormat)) c->chrDstH= (dstH+1)>>1;
1169 else c->chrDstH= dstH;
1170
1171 c->chrXInc= ((c->chrSrcW<<16) + (c->chrDstW>>1))/c->chrDstW;
1172 c->chrYInc= ((c->chrSrcH<<16) + (c->chrDstH>>1))/c->chrDstH;
1173
1174
1138 // match pixel 0 of the src to pixel 0 of dst and match pixel n-2 of src to pixel n-2 of dst 1175 // match pixel 0 of the src to pixel 0 of dst and match pixel n-2 of src to pixel n-2 of dst
1139 // but only for the FAST_BILINEAR mode otherwise do correct scaling 1176 // but only for the FAST_BILINEAR mode otherwise do correct scaling
1140 // n-2 is the last chrominance sample available 1177 // n-2 is the last chrominance sample available
1141 // this is not perfect, but noone shuld notice the difference, the more correct variant 1178 // this is not perfect, but noone shuld notice the difference, the more correct variant
1142 // would be like the vertical one, but that would require some special code for the 1179 // would be like the vertical one, but that would require some special code for the
1143 // first and last pixel 1180 // first and last pixel
1144 if(flags&SWS_FAST_BILINEAR) 1181 if(flags&SWS_FAST_BILINEAR)
1145 { 1182 {
1146 if(c->canMMX2BeUsed) c->lumXInc+= 20; 1183 if(c->canMMX2BeUsed)
1184 {
1185 c->lumXInc+= 20;
1186 c->chrXInc+= 20;
1187 }
1147 //we dont use the x86asm scaler if mmx is available 1188 //we dont use the x86asm scaler if mmx is available
1148 else if(cpuCaps.hasMMX) c->lumXInc = ((srcW-2)<<16)/(dstW-2) - 20; 1189 else if(cpuCaps.hasMMX)
1149 } 1190 {
1150 1191 c->lumXInc = ((srcW-2)<<16)/(dstW-2) - 20;
1151 /* set chrXInc & chrDstW */ 1192 c->chrXInc = ((c->chrSrcW-2)<<16)/(c->chrDstW-2) - 20;
1152 if((flags&SWS_FULL_UV_IPOL) && !isHalfChrH(dstFormat)) 1193 }
1153 c->chrXInc= c->lumXInc>>1, c->chrDstW= dstW; 1194 }
1154 else
1155 c->chrXInc= c->lumXInc, c->chrDstW= (dstW+1)>>1;
1156
1157 /* set chrYInc & chrDstH */
1158 if(isHalfChrV(dstFormat))
1159 c->chrYInc= c->lumYInc, c->chrDstH= (dstH+1)>>1;
1160 else c->chrYInc= c->lumYInc>>1, c->chrDstH= dstH;
1161 1195
1162 /* precalculate horizontal scaler filter coefficients */ 1196 /* precalculate horizontal scaler filter coefficients */
1163 { 1197 {
1164 const int filterAlign= cpuCaps.hasMMX ? 4 : 1; 1198 const int filterAlign= cpuCaps.hasMMX ? 4 : 1;
1165 1199
1244 fprintf(stderr, "\nSwScaler: FAST_BILINEAR scaler "); 1278 fprintf(stderr, "\nSwScaler: FAST_BILINEAR scaler ");
1245 else if(flags&SWS_BILINEAR) 1279 else if(flags&SWS_BILINEAR)
1246 fprintf(stderr, "\nSwScaler: BILINEAR scaler "); 1280 fprintf(stderr, "\nSwScaler: BILINEAR scaler ");
1247 else if(flags&SWS_BICUBIC) 1281 else if(flags&SWS_BICUBIC)
1248 fprintf(stderr, "\nSwScaler: BICUBIC scaler "); 1282 fprintf(stderr, "\nSwScaler: BICUBIC scaler ");
1283 else if(flags&SWS_X)
1284 fprintf(stderr, "\nSwScaler: Experimental scaler ");
1249 else if(flags&SWS_POINT) 1285 else if(flags&SWS_POINT)
1250 fprintf(stderr, "\nSwScaler: Nearest Neighbor / POINT scaler "); 1286 fprintf(stderr, "\nSwScaler: Nearest Neighbor / POINT scaler ");
1251 else if(flags&SWS_AREA) 1287 else if(flags&SWS_AREA)
1252 fprintf(stderr, "\nSwScaler: Area Averageing scaler "); 1288 fprintf(stderr, "\nSwScaler: Area Averageing scaler ");
1253 else 1289 else
1342 else if(dstFormat==IMGFMT_BGR15) 1378 else if(dstFormat==IMGFMT_BGR15)
1343 printf("SwScaler: using %s YV12->BGR15 Converter\n", cpuCaps.hasMMX ? "MMX" : "C"); 1379 printf("SwScaler: using %s YV12->BGR15 Converter\n", cpuCaps.hasMMX ? "MMX" : "C");
1344 1380
1345 printf("SwScaler: %dx%d -> %dx%d\n", srcW, srcH, dstW, dstH); 1381 printf("SwScaler: %dx%d -> %dx%d\n", srcW, srcH, dstW, dstH);
1346 } 1382 }
1347 1383 if((flags & SWS_PRINT_INFO) && verbose>1)
1384 {
1385 printf("SwScaler:Lum srcW=%d srcH=%d dstW=%d dstH=%d xInc=%d yInc=%d\n",
1386 c->srcW, c->srcH, c->dstW, c->dstH, c->lumXInc, c->lumYInc);
1387 printf("SwScaler:Chr srcW=%d srcH=%d dstW=%d dstH=%d xInc=%d yInc=%d\n",
1388 c->chrSrcW, c->chrSrcH, c->chrDstW, c->chrDstH, c->chrXInc, c->chrYInc);
1389 }
1390
1348 return c; 1391 return c;
1349 } 1392 }
1350 1393
1351 /** 1394 /**
1352 * returns a normalized gaussian curve used to filter stuff 1395 * returns a normalized gaussian curve used to filter stuff