zoukankan      html  css  js  c++  java
  • FFMPEG 内部 YUV444p-> NV12

    1. vscale 

    int ff_init_vscale(SwsContext *c, SwsFilterDescriptor *desc, SwsSlice *src, SwsSlice *dst)
    {
        VScalerContext *lumCtx = NULL;
        VScalerContext *chrCtx = NULL;
    
        if (isPlanarYUV(c->dstFormat) || (isGray(c->dstFormat) && !isALPHA(c->dstFormat))) {
            lumCtx = av_mallocz(sizeof(VScalerContext));
            if (!lumCtx)
                return AVERROR(ENOMEM);
    
    
            desc[0].process = lum_planar_vscale;if (!isGray(c->dstFormat)) {
                chrCtx = av_mallocz(sizeof(VScalerContext));
                if (!chrCtx)
                    return AVERROR(ENOMEM);
                desc[1].process = chr_planar_vscale;
                desc[1].instance = chrCtx;
                desc[1].src = src;
                desc[1].dst = dst;
            }
        } else {
            lumCtx = av_mallocz_array(sizeof(VScalerContext), 2);
            if (!lumCtx)
                return AVERROR(ENOMEM);
            chrCtx = &lumCtx[1];
    
            desc[0].process = c->yuv2packedX ? packed_vscale : any_vscale;
    void ff_init_vscale_pfn(SwsContext *c,
    {
        VScalerContext *lumCtx = NULL;
        VScalerContext *chrCtx = NULL;
        int idx = c->numDesc - (c->is_internal_gamma ? 2 : 1); //FIXME avoid hardcoding indexes
    
        if (isPlanarYUV(c->dstFormat) || (isGray(c->dstFormat) && !isALPHA(c->dstFormat))) {
            if (!isGray(c->dstFormat)) {
                chrCtx = c->desc[idx].instance;
    
                chrCtx->filter[0] = use_mmx ? (int16_t*)c->chrMmxFilter : c->vChrFilter;
                chrCtx->filter_size = c->vChrFilterSize;
                chrCtx->filter_pos = c->vChrFilterPos;
                chrCtx->isMMX = use_mmx;
    
                --idx;
                if (yuv2nv12cX)               chrCtx->pfn = yuv2nv12cX;
                else if (c->vChrFilterSize == 1) chrCtx->pfn = yuv2plane1;
                else                             chrCtx->pfn = yuv2planeX;

      vcscale

    static int chr_planar_vscale(SwsContext *c, SwsFilterDescriptor *desc, int sliceY, int sliceH)
    {
        const int chrSkipMask = (1 << desc->dst->v_chr_sub_sample) - 1;
        if (sliceY & chrSkipMask)
            return 0;
        else {
            VScalerContext *inst = desc->instance;
            int dstW = AV_CEIL_RSHIFT(desc->dst->width, desc->dst->h_chr_sub_sample);
            int chrSliceY = sliceY >> desc->dst->v_chr_sub_sample;
    
            int first = FFMAX(1-inst->filter_size, inst->filter_pos[chrSliceY]);
            int sp1 = first - desc->src->plane[1].sliceY;
            int sp2 = first - desc->src->plane[2].sliceY;
            int dp1 = chrSliceY - desc->dst->plane[1].sliceY;
            int dp2 = chrSliceY - desc->dst->plane[2].sliceY;
            uint8_t **src1 = desc->src->plane[1].line + sp1;
            uint8_t **src2 = desc->src->plane[2].line + sp2;
            uint8_t **dst1 = desc->dst->plane[1].line + dp1;
            uint8_t **dst2 = desc->dst->plane[2].line + dp2;
            uint16_t *filter = inst->filter[0] + (inst->isMMX ? 0 : chrSliceY * inst->filter_size);
    
            if (c->yuv2nv12cX) {
                ((yuv2interleavedX_fn)inst->pfn)(c, filter, inst->filter_size, (const int16_t**)src1, (const int16_t**)src2, dst1[0], dstW);
            } else if (inst->filter_size == 1) {
                ((yuv2planar1_fn)inst->pfn)((const int16_t*)src1[0], dst1[0], dstW, c->chrDither8, 0);
                ((yuv2planar1_fn)inst->pfn)((const int16_t*)src2[0], dst2[0], dstW, c->chrDither8, 3);
            } else {
                ((yuv2planarX_fn)inst->pfn)(filter, inst->filter_size, (const int16_t**)src1, dst1[0], dstW, c->chrDither8, 0);
                ((yuv2planarX_fn)inst->pfn)(filter, inst->filter_size, (const int16_t**)src2, dst2[0], dstW, c->chrDither8, inst->isMMX ? (c->uv_offx2 >> 1) : 3);
            }
        }
    
        return 1;
    }
    av_cold void ff_sws_init_output_funcs(SwsContext *c,
                                          yuv2planar1_fn *yuv2plane1,
                                          yuv2planarX_fn *yuv2planeX,
                                          yuv2interleavedX_fn *yuv2nv12cX,
                                          yuv2packed1_fn *yuv2packed1,
                                          yuv2packed2_fn *yuv2packed2,
                                          yuv2packedX_fn *yuv2packedX,
                                          yuv2anyX_fn *yuv2anyX)
    {
        enum AVPixelFormat dstFormat = c->dstFormat;
        const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(dstFormat);
    
        if (dstFormat == AV_PIX_FMT_P010LE || dstFormat == AV_PIX_FMT_P010BE) {
            *yuv2plane1 = isBE(dstFormat) ? yuv2p010l1_BE_c : yuv2p010l1_LE_c;
            *yuv2planeX = isBE(dstFormat) ? yuv2p010lX_BE_c : yuv2p010lX_LE_c;
            *yuv2nv12cX = yuv2p010cX_c;
            printf("1 
    ");
        } else if (is16BPS(dstFormat)) {
            *yuv2planeX = isBE(dstFormat) ? yuv2planeX_16BE_c  : yuv2planeX_16LE_c;
            *yuv2plane1 = isBE(dstFormat) ? yuv2plane1_16BE_c  : yuv2plane1_16LE_c;
            if (dstFormat == AV_PIX_FMT_P016LE || dstFormat == AV_PIX_FMT_P016BE) {
              *yuv2nv12cX = yuv2p016cX_c;
            }
        } else if (isNBPS(dstFormat)) {
            if (desc->comp[0].depth == 9) {
                *yuv2planeX = isBE(dstFormat) ? yuv2planeX_9BE_c  : yuv2planeX_9LE_c;
                *yuv2plane1 = isBE(dstFormat) ? yuv2plane1_9BE_c  : yuv2plane1_9LE_c;
            } else if (desc->comp[0].depth == 10) {
                *yuv2planeX = isBE(dstFormat) ? yuv2planeX_10BE_c  : yuv2planeX_10LE_c;
                *yuv2plane1 = isBE(dstFormat) ? yuv2plane1_10BE_c  : yuv2plane1_10LE_c;
            } else if (desc->comp[0].depth == 12) {
                *yuv2planeX = isBE(dstFormat) ? yuv2planeX_12BE_c  : yuv2planeX_12LE_c;
                *yuv2plane1 = isBE(dstFormat) ? yuv2plane1_12BE_c  : yuv2plane1_12LE_c;
            } else if (desc->comp[0].depth == 14) {
                *yuv2planeX = isBE(dstFormat) ? yuv2planeX_14BE_c  : yuv2planeX_14LE_c;
                *yuv2plane1 = isBE(dstFormat) ? yuv2plane1_14BE_c  : yuv2plane1_14LE_c;
            } else
                av_assert0(0);
        } else if (dstFormat == AV_PIX_FMT_GRAYF32BE) {
            *yuv2planeX = yuv2planeX_floatBE_c;
            *yuv2plane1 = yuv2plane1_floatBE_c;
        } else if (dstFormat == AV_PIX_FMT_GRAYF32LE) {
            *yuv2planeX = yuv2planeX_floatLE_c;
            *yuv2plane1 = yuv2plane1_floatLE_c;
        } else {
            *yuv2plane1 = yuv2plane1_8_c;
            *yuv2planeX = yuv2planeX_8_c;
            if (dstFormat == AV_PIX_FMT_NV12 || dstFormat == AV_PIX_FMT_NV21 ||
                dstFormat == AV_PIX_FMT_NV24 || dstFormat == AV_PIX_FMT_NV42)
                *yuv2nv12cX = yuv2nv12cX_c;
        }
    static void yuv2nv12cX_c(SwsContext *c, const int16_t *chrFilter, int chrFilterSize,
                            const int16_t **chrUSrc, const int16_t **chrVSrc,
                            uint8_t *dest, int chrDstW)
    {
        enum AVPixelFormat dstFormat = c->dstFormat;
        const uint8_t *chrDither = c->chrDither8;
        int i;
    
        if (dstFormat == AV_PIX_FMT_NV12 ||
            dstFormat == AV_PIX_FMT_NV24)
            for (i=0; i<chrDstW; i++) { //960
                int u = chrDither[i & 7] << 12; //0->6 0->6 ...
                int v = chrDither[(i + 3) & 7] << 12; //3->2 3->2 ...
                int j;
                for (j=0; j<chrFilterSize; j++) {
                    u += chrUSrc[j][i] * chrFilter[j];
                    v += chrVSrc[j][i] * chrFilter[j];
                }
                printed1 = 1;
    
                dest[2*i]= av_clip_uint8(u>>19);
                dest[2*i+1]= av_clip_uint8(v>>19);
            }
        else
            for (i=0; i<chrDstW; i++) {
                int u = chrDither[i & 7] << 12;
                int v = chrDither[(i + 3) & 7] << 12;
                int j;
                for (j=0; j<chrFilterSize; j++) {
                    u += chrUSrc[j][i] * chrFilter[j];
                    v += chrVSrc[j][i] * chrFilter[j];
                }
    
                dest[2*i]= av_clip_uint8(v>>19);
                dest[2*i+1]= av_clip_uint8(u>>19);
            }
    }
    /**  this is Y scale 
    
    static void yuv2planeX_8_c(const int16_t *filter, int filterSize,
                               const int16_t **src, uint8_t *dest, int dstW,
                               const uint8_t *dither, int offset)
    {
        int i;
    
        for (i=0; i<dstW; i++) {
            int val = dither[(i + offset) & 7] << 12;
            int j;
            for (j=0; j<filterSize; j++)
                val += src[j][i] * filter[j];
    
            dest[i]= av_clip_uint8(val>>19);
        }
    }
    
    
    **/

    2. hscale

      hcscale   hyScale 

    static av_cold void sws_init_swscale(SwsContext *c)
    {
        enum AVPixelFormat srcFormat = c->srcFormat;
    
        ff_sws_init_output_funcs(c, &c->yuv2plane1, &c->yuv2planeX,
                                 &c->yuv2nv12cX, &c->yuv2packed1,
                                 &c->yuv2packed2, &c->yuv2packedX, &c->yuv2anyX);
    
        ff_sws_init_input_funcs(c);
    
    
        if (c->srcBpc == 8) {
            if (c->dstBpc <= 14) {
                c->hyScale = c->hcScale = hScale8To15_c;
                if (c->flags & SWS_FAST_BILINEAR) {
                    c->hyscale_fast = ff_hyscale_fast_c;
                    c->hcscale_fast = ff_hcscale_fast_c;
                }
            } else {
                c->hyScale = c->hcScale = hScale8To19_c;
            }
        } else {
            c->hyScale = c->hcScale = c->dstBpc > 14 ? hScale16To19_c
                                                     : hScale16To15_c;
        }
    // 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 ...
        }
    }

    3. 

        if (dstFormat == AV_PIX_FMT_NV12 ||
            dstFormat == AV_PIX_FMT_NV24)
            for (i=0; i<chrDstW; i++) {
                int u = chrDither[i & 7] << 12;     
                int v = chrDither[(i + 3) & 7] << 12;   
                int j;
                for (j=0; j<chrFilterSize; j++) {
                    u += chrUSrc[j][i] * chrFilter[j];
                    v += chrVSrc[j][i] * chrFilter[j];
                }
                printed1 = 1;
    
                dest[2*i]= av_clip_uint8(u>>19);
                dest[2*i+1]= av_clip_uint8(v>>19);
            }
    chrFilter  =  {2048, 1786, 492, -172, -58, 0, 0, 0}
    chrDither = {64 64 64  ... }  8 个64



    FFMPEG YUV444P  -> NV12过程  未缩放

    yuv2plane1 = 0x11758b0 <ff_yuv2plane1_8_avx>,   ✔      缩放y通道

    yuv2planeX = 0x11751e0 <ff_yuv2planeX_8_avx>,    

    yuv2nv12cX = 0x113bac0 <yuv2nv12cX_c>,          ✔       将uv merge 起来

    hyScale = 0x1180010 <ff_hscale8to15_4_ssse3>,  ✔       缩放y plane 的 水平方向

    hcScale = 0x1180090 <ff_hscale8to15_8_ssse3>,   ✔      缩放 u plane 的水平方向   v plane 的水平方向

    FFMPEG YUV444P16LE -> P010 过程

    yuv2plane1 = 0x480860 <yuv2p010l1_LE_c>

    yuv2planeX = 0x4a6580 <yuv2p010lX_LE_c>

    yuv2nv12cX = 0x4806e0 <yuv2p010cX_c>   chrFilter =  {2048, 1786, 492, -172, -58, 0, 0, 0}  int32_t  

    hyScale = 0x4c5520 <ff_hscale16to15_4_ssse3>

    hcScale = 0x4c55a0 <ff_hscale16to15_8_ssse3>

    FFMPEG YUV444P16LE -> P016 过程

    yuv2plane1:0x4ba510 <ff_yuv2plane1_16_avx>      y
    yuv2planeX:0x4b9af0 <ff_yuv2planeX_16_sse4>          
    yuv2nv12cX:0x47f820 <yuv2p016cX_c>         y     chrFilter =  {2048, 1786, 492, -172, -58, 0, 0, 0}  int32_t  in = 187709 ... ... 
    hyScale:0x4c7200 <ff_hscale16to19_4_sse4>       y      
    hcScale:0x4c7290 <ff_hscale16to19_8_sse4>       y     
     
  • 相关阅读:
    Linux 内核 MCA 总线
    Linux 内核PC/104 和 PC/104+
    Linux 内核即插即用规范
    Linux 内核硬件资源
    Linux 内核 回顾: ISA
    Linux 内核硬件抽象
    Linux 内核硬件抽象
    Linux 内核PCI 中断
    Linux 内核存取 I/O 和内存空间
    哥们的面试经历
  • 原文地址:https://www.cnblogs.com/luoyinjie/p/14513728.html
Copyright © 2011-2022 走看看