⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 swscale.c.svn-base

📁 mediastreamer2是开源的网络传输媒体流的库
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
                else if (flags & SWS_SPLINE)                {                    double p=-2.196152422706632;                    coeff = getSplineCoeff(1.0, 0.0, p, -p-1.0, d);                }                else {                    coeff= 0.0; //GCC warning killer                    ASSERT(0)                }                filter[i*filterSize + j]= coeff;                xx++;            }            xDstInSrc+= xInc1;        }    }    /* 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)    filter2= av_malloc(filter2Size*dstW*sizeof(double));    for (i=0; i<dstW; i++)    {        int j;        SwsVector scaleFilter;        SwsVector *outVec;        scaleFilter.coeff= filter + i*filterSize;        scaleFilter.length= filterSize;        if (srcFilter) outVec= sws_getConvVec(srcFilter, &scaleFilter);        else           outVec= &scaleFilter;        ASSERT(outVec->length == filter2Size)        //FIXME dstFilter        for (j=0; j<outVec->length; j++)        {            filter2[i*filter2Size + j]= outVec->coeff[j];        }        (*filterPos)[i]+= (filterSize-1)/2 - (filter2Size-1)/2;        if (outVec != &scaleFilter) sws_freeVec(outVec);    }    av_free(filter); filter=NULL;    /* 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;        double cutOff=0.0;        /* get rid off 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) break;            /* preserve monotonicity because the core can't handle the filter otherwise */            if (i<dstW-1 && (*filterPos)[i] >= (*filterPos)[i+1]) break;            // Move filter coeffs left            for (k=1; k<filter2Size; k++)                filter2[i*filter2Size + k - 1]= filter2[i*filter2Size + k];            filter2[i*filter2Size + k - 1]= 0.0;            (*filterPos)[i]++;        }        cutOff=0.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) 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 filter.        // vectorizing is worth it only if you have        // 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(double));    if (filterSize >= MAX_FILTER_SIZE)        return -1;    *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.0;            else               filter[i*filterSize + j]= filter2[i*filter2Size + j];        }    }    av_free(filter2); filter2=NULL;    //FIXME try to align filterpos if possible    //fix borders    for (i=0; i<dstW; i++)    {        int j;        if ((*filterPos)[i] < 0)        {            // Move filter coeffs 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 coeffs 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 MMXscaler which reads over the end    /* align at 16 for AltiVec (needed by hScale_altivec_real) */    *outFilter= av_mallocz(*outFilterSize*(dstW+1)*sizeof(int16_t));    /* Normalize & Store in outFilter */    for (i=0; i<dstW; i++)    {        int j;        double error=0;        double sum=0;        double scale= one;        for (j=0; j<filterSize; j++)        {            sum+= filter[i*filterSize + j];        }        scale/= sum;        for (j=0; j<*outFilterSize; j++)        {            double v= filter[i*filterSize + j]*scale + error;            int intV= floor(v + 0.5);            (*outFilter)[i*(*outFilterSize) + j]= intV;            error = v - intV;        }    }    (*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)];    }    av_free(filter);    return 0;}#ifdef COMPILE_MMX2static void initMMX2HScaler(int dstW, int xInc, uint8_t *funnyCode, int16_t *filter, int32_t *filterPos, int numSplits){    uint8_t *fragmentA;    long imm8OfPShufW1A;    long imm8OfPShufW2A;    long fragmentLengthA;    uint8_t *fragmentB;    long imm8OfPShufW1B;    long imm8OfPShufW2B;    long fragmentLengthB;    int fragmentPos;    int xpos, i;    // create an optimized horizontal scaling routine    //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                         0b, %0             \n\t"        "lea                         1b, %1             \n\t"        "lea                         2b, %2             \n\t"        "dec                         %1                 \n\t"        "dec                         %2                 \n\t"        "sub                         %0, %1             \n\t"        "sub                         %0, %2             \n\t"        "lea                         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                         0b, %0             \n\t"        "lea                         1b, %1             \n\t"        "lea                         2b, %2             \n\t"        "dec                         %1                 \n\t"        "dec                         %2                 \n\t"        "sub                         %0, %1             \n\t"        "sub                         %0, %2             \n\t"        "lea                         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;            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;            if (d+1<4)            {                int maxShift= 3-(d+1);                int shift=0;                memcpy(funnyCode + fragmentPos, fragmentB, fragmentLengthB);                funnyCode[fragmentPos + imm8OfPShufW1B]=                    (a+1) | ((b+1)<<2) | ((c+1)<<4) | ((d+1)<<6);                funnyCode[fragmentPos + imm8OfPShufW2B]=                    a | (b<<2) | (c<<4) | (d<<6);                if (i+3>=dstW) shift=maxShift; //avoid overread                else if ((filterPos[i/2]&3) <= maxShift) shift=filterPos[i/2]&3; //Align                if (shift && i>=shift)                {                    funnyCode[fragmentPos + imm8OfPShufW1B]+= 0x55*shift;                    funnyCode[fragmentPos + imm8OfPShufW2B]+= 0x55*shift;                    filterPos[i/2]-=shift;                }                fragmentPos+= fragmentLengthB;            }            else            {                int maxShift= 3-d;                int shift=0;                memcpy(funnyCode + fragmentPos, fragmentA, fragmentLengthA);                funnyCode[fragmentPos + imm8OfPShufW1A]=                funnyCode[fragmentPos + imm8OfPShufW2A]=                    a | (b<<2) | (c<<4) | (d<<6);                if (i+4>=dstW) shift=maxShift; //avoid overread                else if ((filterPos[i/2]&3) <= maxShift) shift=filterPos[i/2]&3; //partial align                if (shift && i>=shift)                {                    funnyCode[fragmentPos + imm8OfPShufW1A]+= 0x55*shift;                    funnyCode[fragmentPos + imm8OfPShufW2A]+= 0x55*shift;                    filterPos[i/2]-=shift;                }                fragmentPos+= fragmentLengthA;            }            funnyCode[fragmentPos]= RET;        }        xpos+=xInc;    }    filterPos[i/2]= xpos>>16; // needed to jump to the next part}#endif /* COMPILE_MMX2 */static void globalInit(void){    // generating tables:    int i;    for (i=0; i<768; i++){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -