zoukankan      html  css  js  c++  java
  • FFMPEG cubic scale 过程

    具体流程  ffmpeg/libswscale/swscale.c : 466

            ff_rotate_slice(hout_slice, lastPosY, lastCPosY);
    
            if (posY < lastLumSrcY + 1) { //luminance Scale
                for (i = lumStart; i < lumEnd; ++i)
                    desc[i].process(c, &desc[i], firstPosY, lastPosY - firstPosY + 1);
            }
    
            lumBufIndex += lastLumSrcY - lastInLumBuf;
            lastInLumBuf = lastLumSrcY;
    
            if (cPosY < lastChrSrcY + 1) {//X方向scale chroma
                for (i = chrStart; i < chrEnd; ++i)
                    desc[i].process(c, &desc[i], firstCPosY, lastCPosY - firstCPosY + 1);
            }
    
            chrBufIndex += lastChrSrcY - lastInChrBuf;
            lastInChrBuf = lastChrSrcY;
    
            // wrap buf index around to stay inside the ring buffer
            if (lumBufIndex >= vLumFilterSize)
                lumBufIndex -= vLumFilterSize;
            if (chrBufIndex >= vChrFilterSize)
                chrBufIndex -= vChrFilterSize;
            if (!enough_lines)
                break;  // we can't output a dstY line so let's try with the next slice
    
    #if HAVE_MMX_INLINE
            ff_updateMMXDitherTables(c, dstY, lumBufIndex, chrBufIndex,
                                  lastInLumBuf, lastInChrBuf);
    #endif
            if (should_dither) {
                c->chrDither8 = ff_dither_8x8_128[chrDstY & 7];
                c->lumDither8 = ff_dither_8x8_128[dstY    & 7];
            }
            if (dstY >= dstH - 2) {
                /* hmm looks like we can't use MMX here without overwriting
                 * this array's tail */
                ff_sws_init_output_funcs(c, &yuv2plane1, &yuv2planeX, &yuv2nv12cX,
                                         &yuv2packed1, &yuv2packed2, &yuv2packedX, &yuv2anyX);
                use_mmx_vfilter= 0;
                ff_init_vscale_pfn(c, yuv2plane1, yuv2planeX, yuv2nv12cX,
                               yuv2packed1, yuv2packed2, yuv2packedX, yuv2anyX, use_mmx_vfilter);
            }
    
            {
                for (i = vStart; i < vEnd; ++i)//Y方向scale
                    desc[i].process(c, &desc[i], dstY, 1);
            }

    hscale

    // bilinear / bicubic scaling
    static void hScale8To15_c(SwsContext *c, int16_t *dst, int dstW,
                              const uint8_t *src, const int16_t *filter,
                              const int32_t *filterPos, int filterSize)
    {
        int i;
        for (i = 0; i < dstW; i++) {
            int j;
            int srcPos = filterPos[i];
            int val    = 0;
            for (j = 0; j < filterSize; j++) {
                val += ((int)src[srcPos + j]) * filter[filterSize * i + j];
            }
            dst[i] = FFMIN(val >> 7, (1 << 15) - 1); // the cubic equation does overflow ...
        }
    }

    具体卷积核为

    $40 = {8192, 7314, 2220, -1092, -557, 247, 60, 0, 0, 0, 0, 0,

    -1342, 2220, 7314, 7314, 2220, -1092, -557, 247, 60, 0, 0, 0, 307, -557, -1092, 2220, 7314, 7314, 2220, -1092, -557, 247, 60, 0, 60, 247, -557, -1092, 2220, 7314, 7314, 2220, -1092, -557, 247, 60, 60, 247,
    -557, -1092, 2220, 7314, 7314, 2220, -1092, -557, 247, 60, 60, 247, -557, -1092, 2220, 7314, 7314, 2220, -1092, -557, 247, 60, 60, 247, -557, -1092, 2220, 7314, 7314, 2220, -1092, -557, 247, 60, 60, 247, -557, -1092, 2220, 7314, 7314, 2220, -1092, -557, 247, 60, 60,
    247, -557, -1092, 2220, 7314, 7314, 2220, -1092, -557, 247, 60, 60, 247, -557, -1092, 2220, 7314, 7314, 2220, -1092, -557, 247, 60, 60, 247, -557, -1092, 2220, 7314, 7314, 2220, -1092, -557, 247, 60, 60, 247, -557, -1092, 2220, 7314, 7314, 2220, -1092, -557, 247, 60}

    filterPos

    (gdb) p *filterPos@960
    $41 = {0, 0, 0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99, 101, 103, 105, 107, 109, 111, 113, 115, 117, 119, 121,
    123, 125, 127, 129, 131, 133, 135, 137, 139, 141, 143, 145, 147, 149, 151, 153, 155, 157, 159, 161, 163, 165, 167, 169, 171, 173, 175, 177, 179, 181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201, 203, 205, 207, 209, 211, 213, 215, 217, 219, 221, 223, 225, 227,
    229, 231, 233, 235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 255, 257, 259, 261, 263, 265, 267, 269, 271, 273, 275, 277, 279, 281, 283, 285, 287, 289, 291, 293, 295, 297, 299, 301, 303, 305, 307, 309, 311, 313, 315, 317, 319, 321, 323, 325, 327, 329, 331, 333,
    335, 337, 339, 341, 343, 345, 347, 349, 351, 353, 355, 357, 359, 361, 363, 365, 367, 369, 371, 373, 375, 377, 379, 381, 383, 385, 387, 389, 391, 393...}

    Lumi hscale

    static int lum_h_scale(SwsContext *c, SwsFilterDescriptor *desc, int sliceY, int sliceH)
    {
        FilterContext *instance = desc->instance;
        int srcW = desc->src->width;
        int dstW = desc->dst->width;
        int xInc = instance->xInc;
    
        int i;
        for (i = 0; i < sliceH; ++i) {
            uint8_t ** src = desc->src->plane[0].line;
            uint8_t ** dst = desc->dst->plane[0].line;
            int src_pos = sliceY+i - desc->src->plane[0].sliceY;
            int dst_pos = sliceY+i - desc->dst->plane[0].sliceY;
    
    
            if (c->hyscale_fast) {
                c->hyscale_fast(c, (int16_t*)dst[dst_pos], dstW, src[src_pos], srcW, xInc);
            } else {
                c->hyScale(c, (int16_t*)dst[dst_pos], dstW, (const uint8_t *)src[src_pos], instance->filter,
                           instance->filter_pos, instance->filter_size);
            }
    
            if (c->lumConvertRange)
                c->lumConvertRange((int16_t*)dst[dst_pos], dstW);
    
            desc->dst->plane[0].sliceH += 1;
    
            if (desc->alpha) {
                src = desc->src->plane[3].line;
                dst = desc->dst->plane[3].line;
    
                src_pos = sliceY+i - desc->src->plane[3].sliceY;
                dst_pos = sliceY+i - desc->dst->plane[3].sliceY;
    
                desc->dst->plane[3].sliceH += 1;
    
                if (c->hyscale_fast) {
                    c->hyscale_fast(c, (int16_t*)dst[dst_pos], dstW, src[src_pos], srcW, xInc);
                } else {
                    c->hyScale(c, (int16_t*)dst[dst_pos], dstW, (const uint8_t *)src[src_pos], instance->filter,
                                instance->filter_pos, instance->filter_size);
                }
            }
        }
    
        return sliceH;
    }

    chr h scale

    static int chr_h_scale(SwsContext *c, SwsFilterDescriptor *desc, int sliceY, int sliceH)
    {
        FilterContext *instance = desc->instance;
        int srcW = AV_CEIL_RSHIFT(desc->src->width, desc->src->h_chr_sub_sample);
        int dstW = AV_CEIL_RSHIFT(desc->dst->width, desc->dst->h_chr_sub_sample);
        int xInc = instance->xInc;
    
        uint8_t ** src1 = desc->src->plane[1].line;
        uint8_t ** dst1 = desc->dst->plane[1].line;
        uint8_t ** src2 = desc->src->plane[2].line;
        uint8_t ** dst2 = desc->dst->plane[2].line;
    
        int src_pos1 = sliceY - desc->src->plane[1].sliceY;
        int dst_pos1 = sliceY - desc->dst->plane[1].sliceY;
    
        int src_pos2 = sliceY - desc->src->plane[2].sliceY;
        int dst_pos2 = sliceY - desc->dst->plane[2].sliceY;
    
        int i;
        for (i = 0; i < sliceH; ++i) {
            if (c->hcscale_fast) {
                c->hcscale_fast(c, (uint16_t*)dst1[dst_pos1+i], (uint16_t*)dst2[dst_pos2+i], dstW, src1[src_pos1+i], src2[src_pos2+i], srcW, xInc);
            } else {
                c->hcScale(c, (uint16_t*)dst1[dst_pos1+i], dstW, src1[src_pos1+i], instance->filter, instance->filter_pos, instance->filter_size);
                c->hcScale(c, (uint16_t*)dst2[dst_pos2+i], dstW, src2[src_pos2+i], instance->filter, instance->filter_pos, instance->filter_size);
            }
    
            if (c->chrConvertRange)
                c->chrConvertRange((uint16_t*)dst1[dst_pos1+i], (uint16_t*)dst2[dst_pos2+i], dstW);
    
            desc->dst->plane[1].sliceH += 1;
            desc->dst->plane[2].sliceH += 1;
        }
        return sliceH;
    }
    static int chr_h_scale(SwsContext *c, SwsFilterDescriptor *desc, int sliceY, int sliceH)
     
    处理第sliceY行开始的数据,  一次处理的行数为sliceH
  • 相关阅读:
    团队作业六
    团队作业五
    团队作业(四)
    团队作业(三)
    团队作业二
    宇宙圣斗士队介绍
    团队作业之七
    团队作业之六
    团队作业五
    奥特曼小分队之四(Work Breakdown Structure)
  • 原文地址:https://www.cnblogs.com/luoyinjie/p/14500781.html
Copyright © 2011-2022 走看看