Mercurial > mplayer.hg
comparison postproc/swscale.c @ 4294:21dbbbbd5479
a few filters (should be removed/merged when arpis videofilter stuff is finished)
-ssf cgb=<float> -> chrominance gaussian blur (nice to improve picture quality)
-ssf lgb=<float> -> luminance gaussian blur (dunno what its good for)
-ssf chs=<int> -> shift chrominance horizontally
-ssf cvs=<int> -> shift chrominance vertically
these will only work if the swscaler is used at all
author | michael |
---|---|
date | Mon, 21 Jan 2002 15:22:28 +0000 |
parents | 1f8ceb12284d |
children | 67c56df76a44 |
comparison
equal
deleted
inserted
replaced
4293:1b6f6519b037 | 4294:21dbbbbd5479 |
---|---|
58 | 58 |
59 TODO | 59 TODO |
60 more intelligent missalignment avoidance for the horizontal scaler | 60 more intelligent missalignment avoidance for the horizontal scaler |
61 dither in C | 61 dither in C |
62 change the distance of the u & v buffer | 62 change the distance of the u & v buffer |
63 Move static / global vars into a struct so multiple scalers can be used | |
64 write special vertical cubic upscale version | 63 write special vertical cubic upscale version |
65 Optimize C code (yv12 / minmax) | 64 Optimize C code (yv12 / minmax) |
66 */ | 65 */ |
67 | 66 |
68 #define ABS(a) ((a) > 0 ? (a) : (-(a))) | 67 #define ABS(a) ((a) > 0 ? (a) : (-(a))) |
142 static int clip_yuvtab_40cf[768]; | 141 static int clip_yuvtab_40cf[768]; |
143 | 142 |
144 //global sws_flags from the command line | 143 //global sws_flags from the command line |
145 int sws_flags=0; | 144 int sws_flags=0; |
146 | 145 |
146 //global srcFilter | |
147 SwsFilter src_filter= {NULL, NULL, NULL, NULL}; | |
148 | |
149 float sws_lum_gblur= 0.0; | |
150 float sws_chr_gblur= 0.0; | |
151 int sws_chr_vshift= 0; | |
152 int sws_chr_hshift= 0; | |
153 | |
147 /* cpuCaps combined from cpudetect and whats actually compiled in | 154 /* cpuCaps combined from cpudetect and whats actually compiled in |
148 (if there is no support for something compiled in it wont appear here) */ | 155 (if there is no support for something compiled in it wont appear here) */ |
149 static CpuCaps cpuCaps; | 156 static CpuCaps cpuCaps; |
150 | 157 |
151 void (*swScale)(SwsContext *context, uint8_t* src[], int srcStride[], int srcSliceY, | 158 void (*swScale)(SwsContext *context, uint8_t* src[], int srcStride[], int srcSliceY, |
152 int srcSliceH, uint8_t* dst[], int dstStride[])=NULL; | 159 int srcSliceH, uint8_t* dst[], int dstStride[])=NULL; |
160 | |
161 static SwsVector *getConvVec(SwsVector *a, SwsVector *b); | |
153 | 162 |
154 #ifdef CAN_COMPILE_X86_ASM | 163 #ifdef CAN_COMPILE_X86_ASM |
155 void in_asm_used_var_warning_killer() | 164 void in_asm_used_var_warning_killer() |
156 { | 165 { |
157 volatile int i= yCoeff+vrCoeff+ubCoeff+vgCoeff+ugCoeff+bF8+bFC+w400+w80+w10+ | 166 volatile int i= yCoeff+vrCoeff+ubCoeff+vgCoeff+ugCoeff+bF8+bFC+w400+w80+w10+ |
452 static SwsContext *context=NULL; | 461 static SwsContext *context=NULL; |
453 int dstFormat; | 462 int dstFormat; |
454 int flags=0; | 463 int flags=0; |
455 static int firstTime=1; | 464 static int firstTime=1; |
456 int dstStride3[3]= {dstStride, dstStride>>1, dstStride>>1}; | 465 int dstStride3[3]= {dstStride, dstStride>>1, dstStride>>1}; |
457 static SwsFilter srcFilter={NULL, NULL, NULL, NULL}; | |
458 | 466 |
459 if(firstTime) | 467 if(firstTime) |
460 { | 468 { |
461 flags= SWS_PRINT_INFO; | 469 flags= SWS_PRINT_INFO; |
462 firstTime=0; | 470 firstTime=0; |
463 {/* | 471 |
464 SwsVector *g= getGaussianVec(1.7, 2); | 472 if(src_filter.lumH) free(src_filter.lumH); |
465 SwsVector *id= getIdentityVec(); | 473 if(src_filter.lumV) free(src_filter.lumV); |
466 scaleVec(g, 0.2); | 474 if(src_filter.chrH) free(src_filter.chrH); |
467 | 475 if(src_filter.chrV) free(src_filter.chrV); |
468 | 476 |
469 // srcFilter.chrH= diffVec(id, g); | 477 if(sws_lum_gblur!=0.0){ |
470 // srcFilter.chrH= shiftVec(id, 20); | 478 src_filter.lumH= getGaussianVec(sws_lum_gblur, 3.0); |
471 srcFilter.chrH= g; | 479 src_filter.lumV= getGaussianVec(sws_lum_gblur, 3.0); |
472 // freeVec(g); | 480 }else{ |
473 freeVec(id); | 481 src_filter.lumH= getIdentityVec(); |
474 | 482 src_filter.lumV= getIdentityVec(); |
475 normalizeVec(srcFilter.chrH, 1.0); | 483 } |
476 printVec(srcFilter.chrH); | 484 |
477 | 485 if(sws_chr_gblur!=0.0){ |
478 srcFilter.lumV= srcFilter.lumH= srcFilter.chrV= srcFilter.chrH; | 486 src_filter.chrH= getGaussianVec(sws_chr_gblur, 3.0); |
479 srcFilter.lumH = srcFilter.lumV = NULL; | 487 src_filter.chrV= getGaussianVec(sws_chr_gblur, 3.0); |
480 // srcFilter.chrH = srcFilter.chrV = NULL; | 488 }else{ |
481 */} | 489 src_filter.chrH= getIdentityVec(); |
490 src_filter.chrV= getIdentityVec(); | |
491 } | |
492 | |
493 if(sws_chr_hshift) | |
494 shiftVec(src_filter.chrH, sws_chr_hshift); | |
495 | |
496 if(sws_chr_vshift) | |
497 shiftVec(src_filter.chrV, sws_chr_vshift); | |
498 | |
482 } | 499 } |
483 | 500 |
484 switch(dstbpp) | 501 switch(dstbpp) |
485 { | 502 { |
486 case 8 : dstFormat= IMGFMT_Y8; break; | 503 case 8 : dstFormat= IMGFMT_Y8; break; |
499 case 2: flags|= SWS_BICUBIC; break; | 516 case 2: flags|= SWS_BICUBIC; break; |
500 case 3: flags|= SWS_X; break; | 517 case 3: flags|= SWS_X; break; |
501 default:flags|= SWS_BILINEAR; break; | 518 default:flags|= SWS_BILINEAR; break; |
502 } | 519 } |
503 | 520 |
504 if(!context) context=getSwsContext(srcW, srcH, IMGFMT_YV12, dstW, dstH, dstFormat, flags, &srcFilter, NULL); | 521 if(!context) context=getSwsContext(srcW, srcH, IMGFMT_YV12, dstW, dstH, dstFormat, flags, &src_filter, NULL); |
505 | 522 |
506 | 523 |
507 swScale(context, src, srcStride, srcSliceY, srcSliceH, dst, dstStride3); | 524 swScale(context, src, srcStride, srcSliceY, srcSliceH, dst, dstStride3); |
508 } | 525 } |
509 | 526 |
658 SwsVector *outVec; | 675 SwsVector *outVec; |
659 | 676 |
660 scaleFilter.coeff= filter + i*filterSize; | 677 scaleFilter.coeff= filter + i*filterSize; |
661 scaleFilter.length= filterSize; | 678 scaleFilter.length= filterSize; |
662 | 679 |
663 if(srcFilter) outVec= convVec(srcFilter, &scaleFilter); | 680 if(srcFilter) outVec= getConvVec(srcFilter, &scaleFilter); |
664 else outVec= &scaleFilter; | 681 else outVec= &scaleFilter; |
665 | 682 |
666 ASSERT(outVec->length == filter2Size) | 683 ASSERT(outVec->length == filter2Size) |
667 //FIXME dstFilter | 684 //FIXME dstFilter |
668 | 685 |
943 const int widthAlign= dstFormat==IMGFMT_YV12 ? 16 : 8; | 960 const int widthAlign= dstFormat==IMGFMT_YV12 ? 16 : 8; |
944 SwsContext *c; | 961 SwsContext *c; |
945 int i; | 962 int i; |
946 SwsFilter dummyFilter= {NULL, NULL, NULL, NULL}; | 963 SwsFilter dummyFilter= {NULL, NULL, NULL, NULL}; |
947 | 964 |
965 #ifdef ARCH_X86 | |
966 if(gCpuCaps.hasMMX) | |
967 asm volatile("emms\n\t"::: "memory"); | |
968 #endif | |
969 | |
948 if(swScale==NULL) globalInit(); | 970 if(swScale==NULL) globalInit(); |
949 | 971 |
950 /* sanity check */ | 972 /* sanity check */ |
951 if(srcW<1 || srcH<1 || dstW<1 || dstH<1) return NULL; | 973 if(srcW<1 || srcH<1 || dstW<1 || dstH<1) return NULL; |
952 | 974 |
1241 | 1263 |
1242 for(i=0; i<a->length; i++) | 1264 for(i=0; i<a->length; i++) |
1243 a->coeff[i]*= scalar; | 1265 a->coeff[i]*= scalar; |
1244 } | 1266 } |
1245 | 1267 |
1246 SwsVector *convVec(SwsVector *a, SwsVector *b){ | 1268 static SwsVector *getConvVec(SwsVector *a, SwsVector *b){ |
1247 int length= a->length + b->length - 1; | 1269 int length= a->length + b->length - 1; |
1248 double *coeff= memalign(sizeof(double), length*sizeof(double)); | 1270 double *coeff= memalign(sizeof(double), length*sizeof(double)); |
1249 int i, j; | 1271 int i, j; |
1250 SwsVector *vec= malloc(sizeof(SwsVector)); | 1272 SwsVector *vec= malloc(sizeof(SwsVector)); |
1251 | 1273 |
1263 } | 1285 } |
1264 | 1286 |
1265 return vec; | 1287 return vec; |
1266 } | 1288 } |
1267 | 1289 |
1268 SwsVector *sumVec(SwsVector *a, SwsVector *b){ | 1290 static SwsVector *sumVec(SwsVector *a, SwsVector *b){ |
1269 int length= MAX(a->length, b->length); | 1291 int length= MAX(a->length, b->length); |
1270 double *coeff= memalign(sizeof(double), length*sizeof(double)); | 1292 double *coeff= memalign(sizeof(double), length*sizeof(double)); |
1271 int i; | 1293 int i; |
1272 SwsVector *vec= malloc(sizeof(SwsVector)); | 1294 SwsVector *vec= malloc(sizeof(SwsVector)); |
1273 | 1295 |
1280 for(i=0; i<b->length; i++) coeff[i + (length-1)/2 - (b->length-1)/2]+= b->coeff[i]; | 1302 for(i=0; i<b->length; i++) coeff[i + (length-1)/2 - (b->length-1)/2]+= b->coeff[i]; |
1281 | 1303 |
1282 return vec; | 1304 return vec; |
1283 } | 1305 } |
1284 | 1306 |
1285 SwsVector *diffVec(SwsVector *a, SwsVector *b){ | 1307 static SwsVector *diffVec(SwsVector *a, SwsVector *b){ |
1286 int length= MAX(a->length, b->length); | 1308 int length= MAX(a->length, b->length); |
1287 double *coeff= memalign(sizeof(double), length*sizeof(double)); | 1309 double *coeff= memalign(sizeof(double), length*sizeof(double)); |
1288 int i; | 1310 int i; |
1289 SwsVector *vec= malloc(sizeof(SwsVector)); | 1311 SwsVector *vec= malloc(sizeof(SwsVector)); |
1290 | 1312 |
1298 | 1320 |
1299 return vec; | 1321 return vec; |
1300 } | 1322 } |
1301 | 1323 |
1302 /* shift left / or right if "shift" is negative */ | 1324 /* shift left / or right if "shift" is negative */ |
1303 SwsVector *shiftVec(SwsVector *a, int shift){ | 1325 static SwsVector *getShiftedVec(SwsVector *a, int shift){ |
1304 int length= a->length + ABS(shift)*2; | 1326 int length= a->length + ABS(shift)*2; |
1305 double *coeff= memalign(sizeof(double), length*sizeof(double)); | 1327 double *coeff= memalign(sizeof(double), length*sizeof(double)); |
1306 int i, j; | 1328 int i, j; |
1307 SwsVector *vec= malloc(sizeof(SwsVector)); | 1329 SwsVector *vec= malloc(sizeof(SwsVector)); |
1308 | 1330 |
1313 | 1335 |
1314 for(i=0; i<a->length; i++) | 1336 for(i=0; i<a->length; i++) |
1315 { | 1337 { |
1316 coeff[i + (length-1)/2 - (a->length-1)/2 - shift]= a->coeff[i]; | 1338 coeff[i + (length-1)/2 - (a->length-1)/2 - shift]= a->coeff[i]; |
1317 } | 1339 } |
1340 | |
1341 return vec; | |
1342 } | |
1343 | |
1344 void shiftVec(SwsVector *a, int shift){ | |
1345 SwsVector *shifted= getShiftedVec(a, shift); | |
1346 free(a->coeff); | |
1347 a->coeff= shifted->coeff; | |
1348 a->length= shifted->length; | |
1349 free(shifted); | |
1350 } | |
1351 | |
1352 void addVec(SwsVector *a, SwsVector *b){ | |
1353 SwsVector *sum= sumVec(a, b); | |
1354 free(a->coeff); | |
1355 a->coeff= sum->coeff; | |
1356 a->length= sum->length; | |
1357 free(sum); | |
1358 } | |
1359 | |
1360 void subVec(SwsVector *a, SwsVector *b){ | |
1361 SwsVector *diff= diffVec(a, b); | |
1362 free(a->coeff); | |
1363 a->coeff= diff->coeff; | |
1364 a->length= diff->length; | |
1365 free(diff); | |
1366 } | |
1367 | |
1368 void convVec(SwsVector *a, SwsVector *b){ | |
1369 SwsVector *conv= getConvVec(a, b); | |
1370 free(a->coeff); | |
1371 a->coeff= conv->coeff; | |
1372 a->length= conv->length; | |
1373 free(conv); | |
1374 } | |
1375 | |
1376 SwsVector *cloneVec(SwsVector *a){ | |
1377 double *coeff= memalign(sizeof(double), a->length*sizeof(double)); | |
1378 int i; | |
1379 SwsVector *vec= malloc(sizeof(SwsVector)); | |
1380 | |
1381 vec->coeff= coeff; | |
1382 vec->length= a->length; | |
1383 | |
1384 for(i=0; i<a->length; i++) coeff[i]= a->coeff[i]; | |
1318 | 1385 |
1319 return vec; | 1386 return vec; |
1320 } | 1387 } |
1321 | 1388 |
1322 void printVec(SwsVector *a){ | 1389 void printVec(SwsVector *a){ |