Mercurial > mplayer.hg
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 |