diff options
author | ramiro <ramiro@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2010-01-24 02:08:22 +0000 |
---|---|---|
committer | ramiro <ramiro@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2010-01-24 02:08:22 +0000 |
commit | d9f2d9d62c3db77459d9bdce11e4dc33815f97bd (patch) | |
tree | 8c0a2e50ccdb56848b701a85f814273005fbce98 /libswscale | |
parent | 4e90199d2ee19ecaab142ee6e34327ac5dda6166 (diff) | |
download | mpv-d9f2d9d62c3db77459d9bdce11e4dc33815f97bd.tar.bz2 mpv-d9f2d9d62c3db77459d9bdce11e4dc33815f97bd.tar.xz |
Split swscale.c into scaler code (swscale.c) and utility code (utils.c).
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30411 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libswscale')
-rw-r--r-- | libswscale/Makefile | 2 | ||||
-rw-r--r-- | libswscale/swscale.c | 1551 | ||||
-rw-r--r-- | libswscale/swscale_internal.h | 17 | ||||
-rw-r--r-- | libswscale/utils.c | 1589 |
4 files changed, 1620 insertions, 1539 deletions
diff --git a/libswscale/Makefile b/libswscale/Makefile index 247ae8d239..085027789e 100644 --- a/libswscale/Makefile +++ b/libswscale/Makefile @@ -5,7 +5,7 @@ FFLIBS = avutil HEADERS = swscale.h -OBJS = options.o rgb2rgb.o swscale.o yuv2rgb.o +OBJS = options.o rgb2rgb.o swscale.o utils.o yuv2rgb.o OBJS-$(ARCH_BFIN) += bfin/internal_bfin.o \ bfin/swscale_bfin.o \ diff --git a/libswscale/swscale.c b/libswscale/swscale.c index 67a9364c97..fb46dcd5fe 100644 --- a/libswscale/swscale.c +++ b/libswscale/swscale.c @@ -54,23 +54,12 @@ untested special converters BGR24 -> YV12 */ -#define _SVID_SOURCE //needed for MAP_ANONYMOUS #include <inttypes.h> #include <string.h> #include <math.h> #include <stdio.h> #include "config.h" #include <assert.h> -#if HAVE_SYS_MMAN_H -#include <sys/mman.h> -#if defined(MAP_ANON) && !defined(MAP_ANONYMOUS) -#define MAP_ANONYMOUS MAP_ANON -#endif -#endif -#if HAVE_VIRTUALALLOC -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#endif #include "swscale.h" #include "swscale_internal.h" #include "rgb2rgb.h" @@ -80,22 +69,6 @@ untested special converters #include "libavutil/bswap.h" #include "libavutil/pixdesc.h" -unsigned swscale_version(void) -{ - return LIBSWSCALE_VERSION_INT; -} - -const char *swscale_configuration(void) -{ - return FFMPEG_CONFIGURATION; -} - -const char *swscale_license(void) -{ -#define LICENSE_PREFIX "libswscale license: " - return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1; -} - #undef MOVNTQ #undef PAVGB @@ -107,92 +80,12 @@ const char *swscale_license(void) #define FAST_BGR2YV12 // use 7 bit coefficients instead of 15 bit -#define RET 0xC3 //near return opcode for x86 - #ifdef M_PI #define PI M_PI #else #define PI 3.14159265358979323846 #endif -#define isSupportedIn(x) ( \ - (x)==PIX_FMT_YUV420P \ - || (x)==PIX_FMT_YUVA420P \ - || (x)==PIX_FMT_YUYV422 \ - || (x)==PIX_FMT_UYVY422 \ - || (x)==PIX_FMT_RGB48BE \ - || (x)==PIX_FMT_RGB48LE \ - || (x)==PIX_FMT_RGB32 \ - || (x)==PIX_FMT_RGB32_1 \ - || (x)==PIX_FMT_BGR24 \ - || (x)==PIX_FMT_BGR565 \ - || (x)==PIX_FMT_BGR555 \ - || (x)==PIX_FMT_BGR32 \ - || (x)==PIX_FMT_BGR32_1 \ - || (x)==PIX_FMT_RGB24 \ - || (x)==PIX_FMT_RGB565 \ - || (x)==PIX_FMT_RGB555 \ - || (x)==PIX_FMT_GRAY8 \ - || (x)==PIX_FMT_YUV410P \ - || (x)==PIX_FMT_YUV440P \ - || (x)==PIX_FMT_NV12 \ - || (x)==PIX_FMT_NV21 \ - || (x)==PIX_FMT_GRAY16BE \ - || (x)==PIX_FMT_GRAY16LE \ - || (x)==PIX_FMT_YUV444P \ - || (x)==PIX_FMT_YUV422P \ - || (x)==PIX_FMT_YUV411P \ - || (x)==PIX_FMT_PAL8 \ - || (x)==PIX_FMT_BGR8 \ - || (x)==PIX_FMT_RGB8 \ - || (x)==PIX_FMT_BGR4_BYTE \ - || (x)==PIX_FMT_RGB4_BYTE \ - || (x)==PIX_FMT_YUV440P \ - || (x)==PIX_FMT_MONOWHITE \ - || (x)==PIX_FMT_MONOBLACK \ - || (x)==PIX_FMT_YUV420P16LE \ - || (x)==PIX_FMT_YUV422P16LE \ - || (x)==PIX_FMT_YUV444P16LE \ - || (x)==PIX_FMT_YUV420P16BE \ - || (x)==PIX_FMT_YUV422P16BE \ - || (x)==PIX_FMT_YUV444P16BE \ - ) - -int sws_isSupportedInput(enum PixelFormat pix_fmt) -{ - return isSupportedIn(pix_fmt); -} - -#define isSupportedOut(x) ( \ - (x)==PIX_FMT_YUV420P \ - || (x)==PIX_FMT_YUVA420P \ - || (x)==PIX_FMT_YUYV422 \ - || (x)==PIX_FMT_UYVY422 \ - || (x)==PIX_FMT_YUV444P \ - || (x)==PIX_FMT_YUV422P \ - || (x)==PIX_FMT_YUV411P \ - || isRGB(x) \ - || isBGR(x) \ - || (x)==PIX_FMT_NV12 \ - || (x)==PIX_FMT_NV21 \ - || (x)==PIX_FMT_GRAY16BE \ - || (x)==PIX_FMT_GRAY16LE \ - || (x)==PIX_FMT_GRAY8 \ - || (x)==PIX_FMT_YUV410P \ - || (x)==PIX_FMT_YUV440P \ - || (x)==PIX_FMT_YUV420P16LE \ - || (x)==PIX_FMT_YUV422P16LE \ - || (x)==PIX_FMT_YUV444P16LE \ - || (x)==PIX_FMT_YUV420P16BE \ - || (x)==PIX_FMT_YUV422P16BE \ - || (x)==PIX_FMT_YUV444P16BE \ - ) - -int sws_isSupportedOutput(enum PixelFormat pix_fmt) -{ - return isSupportedOut(pix_fmt); -} - #define isPacked(x) ( \ (x)==PIX_FMT_PAL8 \ || (x)==PIX_FMT_YUYV422 \ @@ -213,8 +106,6 @@ int sws_isSupportedOutput(enum PixelFormat pix_fmt) #define RV ( (int)(0.500*224/255*(1<<RGB2YUV_SHIFT)+0.5)) #define RU (-(int)(0.169*224/255*(1<<RGB2YUV_SHIFT)+0.5)) -extern const int32_t ff_yuv2rgb_coeffs[8][4]; - static const double rgb2yuv_table[8][9]={ {0.7152, 0.0722, 0.2126, -0.386, 0.5, -0.115, -0.454, -0.046, 0.5}, {0.7152, 0.0722, 0.2126, -0.386, 0.5, -0.115, -0.454, -0.046, 0.5}, @@ -379,14 +270,6 @@ DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[8][8]={ }; #endif -const char *sws_format_name(enum PixelFormat format) -{ - if ((unsigned)format < PIX_FMT_NB && av_pix_fmt_descriptors[format].name) - return av_pix_fmt_descriptors[format].name; - else - return "Unknown format"; -} - static av_always_inline void yuv2yuvX16inC_template(const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize, const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize, const int16_t **alpSrc, uint16_t *dest, uint16_t *uDest, uint16_t *vDest, uint16_t *aDest, @@ -1331,515 +1214,7 @@ static inline void monoblack2Y(uint8_t *dst, const uint8_t *src, long width, uin #endif //ARCH_X86 -static double getSplineCoeff(double a, double b, double c, double d, double dist) -{ -// printf("%f %f %f %f %f\n", a,b,c,d,dist); - if (dist<=1.0) return ((d*dist + c)*dist + b)*dist +a; - else return getSplineCoeff( 0.0, - b+ 2.0*c + 3.0*d, - c + 3.0*d, - -b- 3.0*c - 6.0*d, - dist-1.0); -} - -static int initFilter(int16_t **outFilter, int16_t **filterPos, int *outFilterSize, int xInc, - int srcW, int dstW, int filterAlign, int one, int flags, - SwsVector *srcFilter, SwsVector *dstFilter, double param[2]) -{ - int i; - int filterSize; - int filter2Size; - int minFilterSize; - int64_t *filter=NULL; - int64_t *filter2=NULL; - const int64_t fone= 1LL<<54; - int ret= -1; -#if ARCH_X86 - if (flags & SWS_CPU_CAPS_MMX) - __asm__ volatile("emms\n\t"::: "memory"); //FIXME this should not be required but it IS (even for non-MMX versions) -#endif - - // NOTE: the +1 is for the MMX scaler which reads over the end - FF_ALLOC_OR_GOTO(NULL, *filterPos, (dstW+1)*sizeof(int16_t), fail); - - if (FFABS(xInc - 0x10000) <10) { // unscaled - int i; - filterSize= 1; - FF_ALLOCZ_OR_GOTO(NULL, filter, dstW*sizeof(*filter)*filterSize, fail); - - for (i=0; i<dstW; i++) { - filter[i*filterSize]= fone; - (*filterPos)[i]=i; - } - - } else if (flags&SWS_POINT) { // lame looking point sampling mode - int i; - int xDstInSrc; - filterSize= 1; - FF_ALLOC_OR_GOTO(NULL, filter, dstW*sizeof(*filter)*filterSize, fail); - - xDstInSrc= xInc/2 - 0x8000; - for (i=0; i<dstW; i++) { - int xx= (xDstInSrc - ((filterSize-1)<<15) + (1<<15))>>16; - - (*filterPos)[i]= xx; - filter[i]= fone; - xDstInSrc+= xInc; - } - } else if ((xInc <= (1<<16) && (flags&SWS_AREA)) || (flags&SWS_FAST_BILINEAR)) { // bilinear upscale - int i; - int xDstInSrc; - filterSize= 2; - FF_ALLOC_OR_GOTO(NULL, filter, dstW*sizeof(*filter)*filterSize, fail); - - xDstInSrc= xInc/2 - 0x8000; - for (i=0; i<dstW; i++) { - int xx= (xDstInSrc - ((filterSize-1)<<15) + (1<<15))>>16; - int j; - - (*filterPos)[i]= xx; - //bilinear upscale / linear interpolate / area averaging - for (j=0; j<filterSize; j++) { - int64_t coeff= fone - FFABS((xx<<16) - xDstInSrc)*(fone>>16); - if (coeff<0) coeff=0; - filter[i*filterSize + j]= coeff; - xx++; - } - xDstInSrc+= xInc; - } - } else { - int xDstInSrc; - int sizeFactor; - - if (flags&SWS_BICUBIC) sizeFactor= 4; - else if (flags&SWS_X) sizeFactor= 8; - else if (flags&SWS_AREA) sizeFactor= 1; //downscale only, for upscale it is bilinear - else if (flags&SWS_GAUSS) sizeFactor= 8; // infinite ;) - else if (flags&SWS_LANCZOS) sizeFactor= param[0] != SWS_PARAM_DEFAULT ? ceil(2*param[0]) : 6; - else if (flags&SWS_SINC) sizeFactor= 20; // infinite ;) - else if (flags&SWS_SPLINE) sizeFactor= 20; // infinite ;) - else if (flags&SWS_BILINEAR) sizeFactor= 2; - else { - sizeFactor= 0; //GCC warning killer - assert(0); - } - - if (xInc <= 1<<16) filterSize= 1 + sizeFactor; // upscale - else filterSize= 1 + (sizeFactor*srcW + dstW - 1)/ dstW; - - if (filterSize > srcW-2) filterSize=srcW-2; - - FF_ALLOC_OR_GOTO(NULL, filter, dstW*sizeof(*filter)*filterSize, fail); - - xDstInSrc= xInc - 0x10000; - for (i=0; i<dstW; i++) { - int xx= (xDstInSrc - ((filterSize-2)<<16)) / (1<<17); - int j; - (*filterPos)[i]= xx; - for (j=0; j<filterSize; j++) { - int64_t d= ((int64_t)FFABS((xx<<17) - xDstInSrc))<<13; - double floatd; - int64_t coeff; - - if (xInc > 1<<16) - d= d*dstW/srcW; - floatd= d * (1.0/(1<<30)); - - if (flags & SWS_BICUBIC) { - int64_t B= (param[0] != SWS_PARAM_DEFAULT ? param[0] : 0) * (1<<24); - int64_t C= (param[1] != SWS_PARAM_DEFAULT ? param[1] : 0.6) * (1<<24); - int64_t dd = ( d*d)>>30; - int64_t ddd= (dd*d)>>30; - - if (d < 1LL<<30) - coeff = (12*(1<<24)-9*B-6*C)*ddd + (-18*(1<<24)+12*B+6*C)*dd + (6*(1<<24)-2*B)*(1<<30); - else if (d < 1LL<<31) - coeff = (-B-6*C)*ddd + (6*B+30*C)*dd + (-12*B-48*C)*d + (8*B+24*C)*(1<<30); - else - coeff=0.0; - coeff *= fone>>(30+24); - } -/* else if (flags & SWS_X) { - double p= param ? param*0.01 : 0.3; - coeff = d ? sin(d*PI)/(d*PI) : 1.0; - coeff*= pow(2.0, - p*d*d); - }*/ - else if (flags & SWS_X) { - double A= param[0] != SWS_PARAM_DEFAULT ? param[0] : 1.0; - double c; - - if (floatd<1.0) - c = cos(floatd*PI); - else - c=-1.0; - if (c<0.0) c= -pow(-c, A); - else c= pow( c, A); - coeff= (c*0.5 + 0.5)*fone; - } else if (flags & SWS_AREA) { - int64_t d2= d - (1<<29); - if (d2*xInc < -(1LL<<(29+16))) coeff= 1.0 * (1LL<<(30+16)); - else if (d2*xInc < (1LL<<(29+16))) coeff= -d2*xInc + (1LL<<(29+16)); - else coeff=0.0; - coeff *= fone>>(30+16); - } else if (flags & SWS_GAUSS) { - double p= param[0] != SWS_PARAM_DEFAULT ? param[0] : 3.0; - coeff = (pow(2.0, - p*floatd*floatd))*fone; - } else if (flags & SWS_SINC) { - coeff = (d ? sin(floatd*PI)/(floatd*PI) : 1.0)*fone; - } else if (flags & SWS_LANCZOS) { - double p= param[0] != SWS_PARAM_DEFAULT ? param[0] : 3.0; - coeff = (d ? sin(floatd*PI)*sin(floatd*PI/p)/(floatd*floatd*PI*PI/p) : 1.0)*fone; - if (floatd>p) coeff=0; - } else if (flags & SWS_BILINEAR) { - coeff= (1<<30) - d; - if (coeff<0) coeff=0; - coeff *= fone >> 30; - } else if (flags & SWS_SPLINE) { - double p=-2.196152422706632; - coeff = getSplineCoeff(1.0, 0.0, p, -p-1.0, floatd) * fone; - } else { - coeff= 0.0; //GCC warning killer - assert(0); - } - - filter[i*filterSize + j]= coeff; - xx++; - } - xDstInSrc+= 2*xInc; - } - } - - /* apply src & dst Filter to filter -> filter2 - av_free(filter); - */ - assert(filterSize>0); - filter2Size= filterSize; - if (srcFilter) filter2Size+= srcFilter->length - 1; - if (dstFilter) filter2Size+= dstFilter->length - 1; - assert(filter2Size>0); - FF_ALLOCZ_OR_GOTO(NULL, filter2, filter2Size*dstW*sizeof(*filter2), fail); - - for (i=0; i<dstW; i++) { - int j, k; - - if(srcFilter) { - for (k=0; k<srcFilter->length; k++) { - for (j=0; j<filterSize; j++) - filter2[i*filter2Size + k + j] += srcFilter->coeff[k]*filter[i*filterSize + j]; - } - } else { - for (j=0; j<filterSize; j++) - filter2[i*filter2Size + j]= filter[i*filterSize + j]; - } - //FIXME dstFilter - - (*filterPos)[i]+= (filterSize-1)/2 - (filter2Size-1)/2; - } - av_freep(&filter); - - /* try to reduce the filter-size (step1 find size and shift left) */ - // Assume it is near normalized (*0.5 or *2.0 is OK but * 0.001 is not). - minFilterSize= 0; - for (i=dstW-1; i>=0; i--) { - int min= filter2Size; - int j; - int64_t cutOff=0.0; - - /* get rid of near zero elements on the left by shifting left */ - for (j=0; j<filter2Size; j++) { - int k; - cutOff += FFABS(filter2[i*filter2Size]); - - if (cutOff > SWS_MAX_REDUCE_CUTOFF*fone) break; - - /* preserve monotonicity because the core can't handle the filter otherwise */ - if (i<dstW-1 && (*filterPos)[i] >= (*filterPos)[i+1]) break; - - // move filter coefficients left - for (k=1; k<filter2Size; k++) - filter2[i*filter2Size + k - 1]= filter2[i*filter2Size + k]; - filter2[i*filter2Size + k - 1]= 0; - (*filterPos)[i]++; - } - - cutOff=0; - /* count near zeros on the right */ - for (j=filter2Size-1; j>0; j--) { - cutOff += FFABS(filter2[i*filter2Size + j]); - - if (cutOff > SWS_MAX_REDUCE_CUTOFF*fone) break; - min--; - } - - if (min>minFilterSize) minFilterSize= min; - } - - if (flags & SWS_CPU_CAPS_ALTIVEC) { - // we can handle the special case 4, - // so we don't want to go to the full 8 - if (minFilterSize < 5) - filterAlign = 4; - - // We really don't want to waste our time - // doing useless computation, so fall back on - // the scalar C code for very small filters. - // Vectorizing is worth it only if you have a - // decent-sized vector. - if (minFilterSize < 3) - filterAlign = 1; - } - - if (flags & SWS_CPU_CAPS_MMX) { - // special case for unscaled vertical filtering - if (minFilterSize == 1 && filterAlign == 2) - filterAlign= 1; - } - - assert(minFilterSize > 0); - filterSize= (minFilterSize +(filterAlign-1)) & (~(filterAlign-1)); - assert(filterSize > 0); - filter= av_malloc(filterSize*dstW*sizeof(*filter)); - if (filterSize >= MAX_FILTER_SIZE*16/((flags&SWS_ACCURATE_RND) ? APCK_SIZE : 16) || !filter) - goto fail; - *outFilterSize= filterSize; - - if (flags&SWS_PRINT_INFO) - av_log(NULL, AV_LOG_VERBOSE, "SwScaler: reducing / aligning filtersize %d -> %d\n", filter2Size, filterSize); - /* try to reduce the filter-size (step2 reduce it) */ - for (i=0; i<dstW; i++) { - int j; - - for (j=0; j<filterSize; j++) { - if (j>=filter2Size) filter[i*filterSize + j]= 0; - else filter[i*filterSize + j]= filter2[i*filter2Size + j]; - if((flags & SWS_BITEXACT) && j>=minFilterSize) - filter[i*filterSize + j]= 0; - } - } - - //FIXME try to align filterPos if possible - - //fix borders - for (i=0; i<dstW; i++) { - int j; - if ((*filterPos)[i] < 0) { - // move filter coefficients left to compensate for filterPos - for (j=1; j<filterSize; j++) { - int left= FFMAX(j + (*filterPos)[i], 0); - filter[i*filterSize + left] += filter[i*filterSize + j]; - filter[i*filterSize + j]=0; - } - (*filterPos)[i]= 0; - } - - if ((*filterPos)[i] + filterSize > srcW) { - int shift= (*filterPos)[i] + filterSize - srcW; - // move filter coefficients right to compensate for filterPos - for (j=filterSize-2; j>=0; j--) { - int right= FFMIN(j + shift, filterSize-1); - filter[i*filterSize +right] += filter[i*filterSize +j]; - filter[i*filterSize +j]=0; - } - (*filterPos)[i]= srcW - filterSize; - } - } - - // Note the +1 is for the MMX scaler which reads over the end - /* align at 16 for AltiVec (needed by hScale_altivec_real) */ - FF_ALLOCZ_OR_GOTO(NULL, *outFilter, *outFilterSize*(dstW+1)*sizeof(int16_t), fail); - - /* normalize & store in outFilter */ - for (i=0; i<dstW; i++) { - int j; - int64_t error=0; - int64_t sum=0; - - for (j=0; j<filterSize; j++) { - sum+= filter[i*filterSize + j]; - } - sum= (sum + one/2)/ one; - for (j=0; j<*outFilterSize; j++) { - int64_t v= filter[i*filterSize + j] + error; - int intV= ROUNDED_DIV(v, sum); - (*outFilter)[i*(*outFilterSize) + j]= intV; - error= v - intV*sum; - } - } - - (*filterPos)[dstW]= (*filterPos)[dstW-1]; // the MMX scaler will read over the end - for (i=0; i<*outFilterSize; i++) { - int j= dstW*(*outFilterSize); - (*outFilter)[j + i]= (*outFilter)[j + i - (*outFilterSize)]; - } - - ret=0; -fail: - av_free(filter); - av_free(filter2); - return ret; -} - -#ifdef COMPILE_MMX2 -static int initMMX2HScaler(int dstW, int xInc, uint8_t *filterCode, int16_t *filter, int32_t *filterPos, int numSplits) -{ - uint8_t *fragmentA; - x86_reg imm8OfPShufW1A; - x86_reg imm8OfPShufW2A; - x86_reg fragmentLengthA; - uint8_t *fragmentB; - x86_reg imm8OfPShufW1B; - x86_reg imm8OfPShufW2B; - x86_reg fragmentLengthB; - int fragmentPos; - - int xpos, i; - - // create an optimized horizontal scaling routine - /* This scaler is made of runtime-generated MMX2 code using specially - * tuned pshufw instructions. For every four output pixels, if four - * input pixels are enough for the fast bilinear scaling, then a chunk - * of fragmentB is used. If five input pixels are needed, then a chunk - * of fragmentA is used. - */ - - //code fragment - - __asm__ volatile( - "jmp 9f \n\t" - // Begin - "0: \n\t" - "movq (%%"REG_d", %%"REG_a"), %%mm3 \n\t" - "movd (%%"REG_c", %%"REG_S"), %%mm0 \n\t" - "movd 1(%%"REG_c", %%"REG_S"), %%mm1 \n\t" - "punpcklbw %%mm7, %%mm1 \n\t" - "punpcklbw %%mm7, %%mm0 \n\t" - "pshufw $0xFF, %%mm1, %%mm1 \n\t" - "1: \n\t" - "pshufw $0xFF, %%mm0, %%mm0 \n\t" - "2: \n\t" - "psubw %%mm1, %%mm0 \n\t" - "movl 8(%%"REG_b", %%"REG_a"), %%esi \n\t" - "pmullw %%mm3, %%mm0 \n\t" - "psllw $7, %%mm1 \n\t" - "paddw %%mm1, %%mm0 \n\t" - - "movq %%mm0, (%%"REG_D", %%"REG_a") \n\t" - - "add $8, %%"REG_a" \n\t" - // End - "9: \n\t" -// "int $3 \n\t" - "lea " LOCAL_MANGLE(0b) ", %0 \n\t" - "lea " LOCAL_MANGLE(1b) ", %1 \n\t" - "lea " LOCAL_MANGLE(2b) ", %2 \n\t" - "dec %1 \n\t" - "dec %2 \n\t" - "sub %0, %1 \n\t" - "sub %0, %2 \n\t" - "lea " LOCAL_MANGLE(9b) ", %3 \n\t" - "sub %0, %3 \n\t" - - - :"=r" (fragmentA), "=r" (imm8OfPShufW1A), "=r" (imm8OfPShufW2A), - "=r" (fragmentLengthA) - ); - - __asm__ volatile( - "jmp 9f \n\t" - // Begin - "0: \n\t" - "movq (%%"REG_d", %%"REG_a"), %%mm3 \n\t" - "movd (%%"REG_c", %%"REG_S"), %%mm0 \n\t" - "punpcklbw %%mm7, %%mm0 \n\t" - "pshufw $0xFF, %%mm0, %%mm1 \n\t" - "1: \n\t" - "pshufw $0xFF, %%mm0, %%mm0 \n\t" - "2: \n\t" - "psubw %%mm1, %%mm0 \n\t" - "movl 8(%%"REG_b", %%"REG_a"), %%esi \n\t" - "pmullw %%mm3, %%mm0 \n\t" - "psllw $7, %%mm1 \n\t" - "paddw %%mm1, %%mm0 \n\t" - - "movq %%mm0, (%%"REG_D", %%"REG_a") \n\t" - - "add $8, %%"REG_a" \n\t" - // End - "9: \n\t" -// "int $3 \n\t" - "lea " LOCAL_MANGLE(0b) ", %0 \n\t" - "lea " LOCAL_MANGLE(1b) ", %1 \n\t" - "lea " LOCAL_MANGLE(2b) ", %2 \n\t" - "dec %1 \n\t" - "dec %2 \n\t" - "sub %0, %1 \n\t" - "sub %0, %2 \n\t" - "lea " LOCAL_MANGLE(9b) ", %3 \n\t" - "sub %0, %3 \n\t" - - - :"=r" (fragmentB), "=r" (imm8OfPShufW1B), "=r" (imm8OfPShufW2B), - "=r" (fragmentLengthB) - ); - - xpos= 0; //lumXInc/2 - 0x8000; // difference between pixel centers - fragmentPos=0; - - for (i=0; i<dstW/numSplits; i++) { - int xx=xpos>>16; - - if ((i&3) == 0) { - int a=0; - int b=((xpos+xInc)>>16) - xx; - int c=((xpos+xInc*2)>>16) - xx; - int d=((xpos+xInc*3)>>16) - xx; - int inc = (d+1<4); - uint8_t *fragment = (d+1<4) ? fragmentB : fragmentA; - x86_reg imm8OfPShufW1 = (d+1<4) ? imm8OfPShufW1B : imm8OfPShufW1A; - x86_reg imm8OfPShufW2 = (d+1<4) ? imm8OfPShufW2B : imm8OfPShufW2A; - x86_reg fragmentLength = (d+1<4) ? fragmentLengthB : fragmentLengthA; - int maxShift= 3-(d+inc); - int shift=0; - - if (filterCode) { - filter[i ] = (( xpos & 0xFFFF) ^ 0xFFFF)>>9; - filter[i+1] = (((xpos+xInc ) & 0xFFFF) ^ 0xFFFF)>>9; - filter[i+2] = (((xpos+xInc*2) & 0xFFFF) ^ 0xFFFF)>>9; - filter[i+3] = (((xpos+xInc*3) & 0xFFFF) ^ 0xFFFF)>>9; - filterPos[i/2]= xx; - - memcpy(filterCode + fragmentPos, fragment, fragmentLength); - - filterCode[fragmentPos + imm8OfPShufW1]= - (a+inc) | ((b+inc)<<2) | ((c+inc)<<4) | ((d+inc)<<6); - filterCode[fragmentPos + imm8OfPShufW2]= - a | (b<<2) | (c<<4) | (d<<6); - - if (i+4-inc>=dstW) shift=maxShift; //avoid overread - else if ((filterPos[i/2]&3) <= maxShift) shift=filterPos[i/2]&3; //Align - - if (shift && i>=shift) { - filterCode[fragmentPos + imm8OfPShufW1]+= 0x55*shift; - filterCode[fragmentPos + imm8OfPShufW2]+= 0x55*shift; - filterPos[i/2]-=shift; - } - } - - fragmentPos+= fragmentLength; - - if (filterCode) - filterCode[fragmentPos]= RET; - } - xpos+=xInc; - } - if (filterCode) - filterPos[((i/2)+1)&(~1)]= xpos>>16; // needed to jump to the next part - - return fragmentPos + 1; -} -#endif /* COMPILE_MMX2 */ - -static SwsFunc getSwsFunc(SwsContext *c) +SwsFunc ff_getSwsFunc(SwsContext *c) { #if CONFIG_RUNTIME_CPUDETECT int flags = c->flags; @@ -2260,137 +1635,9 @@ static int planarCopy(SwsContext *c, const uint8_t* src[], int srcStride[], int return srcSliceH; } -static void getSubSampleFactors(int *h, int *v, enum PixelFormat format) -{ - *h = av_pix_fmt_descriptors[format].log2_chroma_w; - *v = av_pix_fmt_descriptors[format].log2_chroma_h; -} - -static uint16_t roundToInt16(int64_t f) -{ - int r= (f + (1<<15))>>16; - if (r<-0x7FFF) return 0x8000; - else if (r> 0x7FFF) return 0x7FFF; - else return r; -} - -int sws_setColorspaceDetails(SwsContext *c, const int inv_table[4], int srcRange, const int table[4], int dstRange, int brightness, int contrast, int saturation) +int ff_hardcodedcpuflags(void) { - int64_t crv = inv_table[0]; - int64_t cbu = inv_table[1]; - int64_t cgu = -inv_table[2]; - int64_t cgv = -inv_table[3]; - int64_t cy = 1<<16; - int64_t oy = 0; - - memcpy(c->srcColorspaceTable, inv_table, sizeof(int)*4); - memcpy(c->dstColorspaceTable, table, sizeof(int)*4); - - c->brightness= brightness; - c->contrast = contrast; - c->saturation= saturation; - c->srcRange = srcRange; - c->dstRange = dstRange; - if (isYUV(c->dstFormat) || isGray(c->dstFormat)) return -1; - - c->uOffset= 0x0400040004000400LL; - c->vOffset= 0x0400040004000400LL; - - if (!srcRange) { - cy= (cy*255) / 219; - oy= 16<<16; - } else { - crv= (crv*224) / 255; - cbu= (cbu*224) / 255; - cgu= (cgu*224) / 255; - cgv= (cgv*224) / 255; - } - - cy = (cy *contrast )>>16; - crv= (crv*contrast * saturation)>>32; - cbu= (cbu*contrast * saturation)>>32; - cgu= (cgu*contrast * saturation)>>32; - cgv= (cgv*contrast * saturation)>>32; - - oy -= 256*brightness; - - c->yCoeff= roundToInt16(cy *8192) * 0x0001000100010001ULL; - c->vrCoeff= roundToInt16(crv*8192) * 0x0001000100010001ULL; - c->ubCoeff= roundToInt16(cbu*8192) * 0x0001000100010001ULL; - c->vgCoeff= roundToInt16(cgv*8192) * 0x0001000100010001ULL; - c->ugCoeff= roundToInt16(cgu*8192) * 0x0001000100010001ULL; - c->yOffset= roundToInt16(oy * 8) * 0x0001000100010001ULL; - - c->yuv2rgb_y_coeff = (int16_t)roundToInt16(cy <<13); - c->yuv2rgb_y_offset = (int16_t)roundToInt16(oy << 9); - c->yuv2rgb_v2r_coeff= (int16_t)roundToInt16(crv<<13); - c->yuv2rgb_v2g_coeff= (int16_t)roundToInt16(cgv<<13); - c->yuv2rgb_u2g_coeff= (int16_t)roundToInt16(cgu<<13); - c->yuv2rgb_u2b_coeff= (int16_t)roundToInt16(cbu<<13); - - ff_yuv2rgb_c_init_tables(c, inv_table, srcRange, brightness, contrast, saturation); - //FIXME factorize - -#ifdef COMPILE_ALTIVEC - if (c->flags & SWS_CPU_CAPS_ALTIVEC) - ff_yuv2rgb_init_tables_altivec(c, inv_table, brightness, contrast, saturation); -#endif - return 0; -} - -int sws_getColorspaceDetails(SwsContext *c, int **inv_table, int *srcRange, int **table, int *dstRange, int *brightness, int *contrast, int *saturation) -{ - if (isYUV(c->dstFormat) || isGray(c->dstFormat)) return -1; - - *inv_table = c->srcColorspaceTable; - *table = c->dstColorspaceTable; - *srcRange = c->srcRange; - *dstRange = c->dstRange; - *brightness= c->brightness; - *contrast = c->contrast; - *saturation= c->saturation; - - return 0; -} - -static int handle_jpeg(enum PixelFormat *format) -{ - switch (*format) { - case PIX_FMT_YUVJ420P: - *format = PIX_FMT_YUV420P; - return 1; - case PIX_FMT_YUVJ422P: - *format = PIX_FMT_YUV422P; - return 1; - case PIX_FMT_YUVJ444P: - *format = PIX_FMT_YUV444P; - return 1; - case PIX_FMT_YUVJ440P: - *format = PIX_FMT_YUV440P; - return 1; - default: - return 0; - } -} - -SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat, - int dstW, int dstH, enum PixelFormat dstFormat, int flags, - SwsFilter *srcFilter, SwsFilter *dstFilter, const double *param) -{ - - SwsContext *c; - int i; - int usesVFilter, usesHFilter; - int unscaled, needsDither; - int srcRange, dstRange; - SwsFilter dummyFilter= {NULL, NULL, NULL, NULL}; -#if ARCH_X86 - if (flags & SWS_CPU_CAPS_MMX) - __asm__ volatile("emms\n\t"::: "memory"); -#endif - -#if !CONFIG_RUNTIME_CPUDETECT //ensure that the flags match the compiled variant if cpudetect is off - flags &= ~(SWS_CPU_CAPS_MMX|SWS_CPU_CAPS_MMX2|SWS_CPU_CAPS_3DNOW|SWS_CPU_CAPS_ALTIVEC|SWS_CPU_CAPS_BFIN); + int flags = 0; #if COMPILE_TEMPLATE_MMX2 flags |= SWS_CPU_CAPS_MMX|SWS_CPU_CAPS_MMX2; #elif COMPILE_TEMPLATE_AMD3DNOW @@ -2402,116 +1649,21 @@ SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat, #elif ARCH_BFIN flags |= SWS_CPU_CAPS_BFIN; #endif -#endif /* CONFIG_RUNTIME_CPUDETECT */ - if (!rgb15to16) sws_rgb2rgb_init(flags); + return flags; +} + +void ff_get_unscaled_swscale(SwsContext *c) +{ + const enum PixelFormat srcFormat = c->srcFormat; + const enum PixelFormat dstFormat = c->dstFormat; + const int flags = c->flags; + const int dstH = c->dstH; + int needsDither; - unscaled = (srcW == dstW && srcH == dstH); needsDither= (isBGR(dstFormat) || isRGB(dstFormat)) && (fmt_depth(dstFormat))<24 && ((fmt_depth(dstFormat))<(fmt_depth(srcFormat)) || (!(isRGB(srcFormat) || isBGR(srcFormat)))); - srcRange = handle_jpeg(&srcFormat); - dstRange = handle_jpeg(&dstFormat); - - if (!isSupportedIn(srcFormat)) { - av_log(NULL, AV_LOG_ERROR, "swScaler: %s is not supported as input pixel format\n", sws_format_name(srcFormat)); - return NULL; - } - if (!isSupportedOut(dstFormat)) { - av_log(NULL, AV_LOG_ERROR, "swScaler: %s is not supported as output pixel format\n", sws_format_name(dstFormat)); - return NULL; - } - - i= flags & ( SWS_POINT - |SWS_AREA - |SWS_BILINEAR - |SWS_FAST_BILINEAR - |SWS_BICUBIC - |SWS_X - |SWS_GAUSS - |SWS_LANCZOS - |SWS_SINC - |SWS_SPLINE - |SWS_BICUBLIN); - if(!i || (i & (i-1))) { - av_log(NULL, AV_LOG_ERROR, "swScaler: Exactly one scaler algorithm must be chosen\n"); - return NULL; - } - - /* sanity check */ - if (srcW<4 || srcH<1 || dstW<8 || dstH<1) { //FIXME check if these are enough and try to lowwer them after fixing the relevant parts of the code - av_log(NULL, AV_LOG_ERROR, "swScaler: %dx%d -> %dx%d is invalid scaling dimension\n", - srcW, srcH, dstW, dstH); - return NULL; - } - if(srcW > VOFW || dstW > VOFW) { - av_log(NULL, AV_LOG_ERROR, "swScaler: Compile-time maximum width is "AV_STRINGIFY(VOFW)" change VOF/VOFW and recompile\n"); - return NULL; - } - - if (!dstFilter) dstFilter= &dummyFilter; - if (!srcFilter) srcFilter= &dummyFilter; - - FF_ALLOCZ_OR_GOTO(NULL, c, sizeof(SwsContext), fail); - - c->av_class = &sws_context_class; - c->srcW= srcW; - c->srcH= srcH; - c->dstW= dstW; - c->dstH= dstH; - c->lumXInc= ((srcW<<16) + (dstW>>1))/dstW; - c->lumYInc= ((srcH<<16) + (dstH>>1))/dstH; - c->flags= flags; - c->dstFormat= dstFormat; - c->srcFormat= srcFormat; - c->vRounder= 4* 0x0001000100010001ULL; - - usesHFilter= usesVFilter= 0; - if (dstFilter->lumV && dstFilter->lumV->length>1) usesVFilter=1; |