x265-1.8版本-common/lowres.h注释

注:问号以及未注释部分 会在x265-1.9版本内更新

/*****************************************************************************
 * Copyright (C) 2013 x265 project
 *
 * Authors: Gopu Govindaswamy <gopu@multicorewareinc.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
 *
 * This program is also available under a commercial proprietary license.
 * For more information, contact us at license @ x265.com.
 *****************************************************************************/

#ifndef X265_LOWRES_H
#define X265_LOWRES_H

#include "primitives.h"
#include "common.h"
#include "picyuv.h"
#include "mv.h"

namespace X265_NS {
// private namespace

struct ReferencePlanes
{
    ReferencePlanes() { memset(this, 0, sizeof(ReferencePlanes)); }//初始化

    pixel*   fpelPlane[3];   //只是指针 如果是isLowres,则fpePlane[0] = lowresPlane[0]  如果是原始分辨率:分别为重构帧YUV的值  加权 指向加权帧位置
    pixel*   lowresPlane[4];//是4个指针,分别指向子类Lowres中buffer[4]的4个下采样亮度数据 用于分像素预测
    PicYuv*  reconPic;     //只在原始分辨率中使用,指向重构帧

    bool     isWeighted;   //在原分辨率中:表示是否加权  LookaheadTLD weightedRef中:初始化为false,表示是否加权
    bool     isLowres;     // 该帧是否是Low resolution,即下采样后的帧。isLowres标志只在Lowres::create()函数中才会被设置为true,其他情况均为false(构造函数ReferencePlanes()默认初始化为false)

    intptr_t lumaStride;  //当前步长信息,如果是lowres  则 width + 2 * origPic->m_lumaMarginX;  不足32补足32
    //                       如宽度为416, width = 416/2 = 208   208+ 2*96 =400 二进制:110010000
    //                       后五位有数据,向上取整32  400+16 = 416  110100000
    //                       如果为原始分辨率:则为重构帧的亮度步长

    intptr_t chromaStride;//只在原始分辨率中使用:为色度步长

    struct {
        int      weight;//权重系数    整个的权重系数等于:(1<<(7-shift)) + weight  目前的权重系数为guessScale * (1<<denom)+0.5f =  (1<<(7-log2WeightDenom)) + inputWeight      其中guessScale :√(原始帧方差/参考帧方差)
        int      offset;//offset信息 整帧所有像素偏移值
        int      shift;//权重系数左移位个数(为了保证精度)
        int      round;//用于四舍五入 其值为shift的一半 w[c].round = w[c].shift ? 1 << (w[c].shift - 1) : 0;
    } w[3];//只在原始分辨率中使用:存储加权帧的加权信息 从slice中copy过来

    pixel* getLumaAddr(uint32_t ctuAddr, uint32_t absPartIdx) { return fpelPlane[0] + reconPic->m_cuOffsetY[ctuAddr] + reconPic->m_buOffsetY[absPartIdx]; }
    pixel* getCbAddr(uint32_t ctuAddr, uint32_t absPartIdx)   { return fpelPlane[1] + reconPic->m_cuOffsetC[ctuAddr] + reconPic->m_buOffsetC[absPartIdx]; }
    pixel* getCrAddr(uint32_t ctuAddr, uint32_t absPartIdx)   { return fpelPlane[2] + reconPic->m_cuOffsetC[ctuAddr] + reconPic->m_buOffsetC[absPartIdx]; }

    /* lowres motion compensation, you must provide a buffer and stride for QPEL averaged pixels
     * in case QPEL is required.  Else it returns a pointer to the HPEL pixels */
    /** 函数功能      : 获取当前qmv下的参考考数据块(分像素作伪插值操作)
    /*  调用范围      : 只CostEstimateGroup::estimateCUCost和void mcLuma函数中被调用
    * \参数blockOffset: 当前块的位置
    * \参数        qmv: 其中一个mvc
    * \参数        buf: 存储1/4分像素插值数据
    * \参数  outstride: 更新当前步长
    * \返回           : 参考块数据 */
    inline pixel *lowresMC(intptr_t blockOffset, const MV& qmv, pixel *buf, intptr_t& outstride)
    {
        /*
        例如当前4块参考帧(同一参考帧,不同采样方法)
         87  94 101  98  97  96 105 102 103  93 
        102 104 104 122 127 130 132 135 119 106 
        153 148 141 151 148 147 146 136 136  82 
        126 122 132 138 146 140 133 130  76  43 
         62  66  62  56 102  70  90  68  53  45 
         63  74  61 108  62  74  68  51  45  40 
         82  94  54  94  63  61  50  48  42  41 
         83  74  71  78  65  50  51  45  39  36 
         64  52  89  80  53  50  47  44  39  33 
         47  57  66  60  49  51  47  45  37  35 

         91  99  98  99  94 103 101 105  98  93
        103 107 109 127 126 132 134 133 105 113
        152 152 144 148 147 145 147 131 119  50
        121 125 140 135 151 137 126 117  47  42
         63  64  58  85  75  84  85  58  46  42
         71  74  67  99  59  84  55  47  44  35
         90  79  72  74  66  54  49  45  42  38
         87  70  69  78  56  49  49  40  39  33
         59  62  96  65  48  49  46  42  35  34
         49  66  65  51  50  50  45  42  35  37

          92 100 107 119 119 119 120 120 107  80
         125 123 118 127 127 129 131 132 116 118
         164 156 154 162 165 164 155 149 126  46
          71  77  81  82 118  90 100  90  56  45
          65  70  68  77  82  78  86  56  46  43
          70  87  53 111  59  66  55  49  46  40
          86  87  57  85  66  55  49  47  39  39
          79  61  94  81  60  49  49  45  40  34
          48  51  67  71  50  50  47  43  37  33
          50  65  81  51  49  51  49  45  36  35

          96 105 110 122 116 122 120 116  92  86
         126 124 120 128 125 130 134 123 119  93
         157 160 160 161 166 161 149 151  74  43
          72  77  87  88 114  92  99  72  50  42
          67  70  59 102  57  97  70  50  43  38
          82  79  74  84  65  63  50  48  44  38
          95  72  64  79  62  50  49  42  40  34
          72  70  95  72  50  49  48  42  37  33
          51  56  75  58  49  49  44  42  33  36
          51  82  65  47  51  51  47  40  36  35
        **/
        if ((qmv.x | qmv.y) & 1)  //如果当前需要 1/4 分像素插值
        {
            //将分像素MV倒数第二位获取一个插值buf数据  倒数第一位获取一个插值buf数据 假设当前分像素MV为(3,1)
            int hpelA = (qmv.y & 2) | ((qmv.x & 2) >> 1);
            pixel *frefA = lowresPlane[hpelA] + blockOffset + (qmv.x >> 2) + (qmv.y >> 2) * lumaStride; //3,1 (x:0x11,y:0x01) 取倒数第二位(x:0x1x,y:0x0x)得到插值buf (yx:01)
           /* 如当前分像素MV为(3,1)  返回的是buf1的数据
           91  99  98  99  94 103 101 105
           103 107 109 127 126 132 134 133
           152 152 144 148 147 145 147 131
           121 125 140 135 151 137 126 117
           63  64  58  85  75  84  85  58
           71  74  67  99  59  84  55  47
           90  79  72  74  66  54  49  45
           87  70  69  78  56  49  49  40 
           **/
            int qmvx = qmv.x + (qmv.x & 1);      
            int qmvy = qmv.y + (qmv.y & 1);
            int hpelB = (qmvy & 2) | ((qmvx & 2) >> 1);  //将分像素倒数第二位四舍五入取整,获取一个新的MV (4,2), 当前分像素mv(0,2) 
            pixel *frefB = lowresPlane[hpelB] + blockOffset + (qmvx >> 2) + (qmvy >> 2) * lumaStride;//3,1 (x:00,y:10) 取倒数第二位(x:0x,y:1x)得到插值buf (yx:10)
           /* 如当前分像素MV为(3,1)  返回的是buf2的数据 (当前整像素MV(1,0))
           100 107 119 119 119 120 120 107  80
           123 118 127 127 129 131 132 116 118
           156 154 162 165 164 155 149 126  46
           77  81  82 118  90 100  90  56  45
           70  68  77  82  78  86  56  46  43
           87  53 111  59  66  55  49  46  40
           87  57  85  66  55  49  47  39  39
           61  94  81  60  49  49  45  40  34
           51  67  71  50  50  47  43  37  33
           65  81  51  49  51  49  45  36  35
           **/
            primitives.pu[LUMA_8x8].pixelavg_pp(buf, outstride, frefA, lumaStride, frefB, lumaStride, 32);//获取两块的平均值dst[x] = (src0[x] + src1[x] + 1) >> 1;
           /* 如当前分像素MV为(3,1)  返回的是
           96 103 109 109 107 112 111 106 
           113 113 118 127 128 132 133 125 
           154 153 153 157 156 150 148 129 
           99 103 111 127 121 119 108  87 
           67  66  68  84  77  85  71  52 
           79  64  89  79  63  70  52  47 
           89  68  79  70  61  52  48  42 
           74  82  75  69  53  49  47  40  
             **/
            return buf;
        }
        else
        {
            outstride = lumaStride;                      //更新实际的stride
            int hpel = (qmv.y & 2) | ((qmv.x & 2) >> 1); //选择参考帧buf(4份)位置:当前qmv.x 和qmv.y的后两位只可能是:00或者10 取y的倒数第二位为当前第一位 取x的倒数第二位当前第二位 组合:00 01 10 11 即:0,1,2,3
            /* 如当前分像素MV为(2,2)  返回的是采样3的buf
            96 105 110 122 116 122 120 116 
            126 124 120 128 125 130 134 123 
            157 160 160 161 166 161 149 151 
            72  77  87  88 114  92  99  72 
            67  70  59 102  57  97  70  50 
            82  79  74  84  65  63  50  48 
            95  72  64  79  62  50  49  42 
            72  70  95  72  50  49  48  42  
             **/
            return lowresPlane[hpel] + blockOffset + (qmv.x >> 2) + (qmv.y >> 2) * lumaStride;//返回参考块首地址
        }
    }
    /** 函数功能      : 函数功能相对于lowresMC函数基本一致,其返还的结果是sad或者satd值:获取伪分像素插值的sad值或者satd值
    /*  调用范围      : 只MotionEstimate::motionEstimate函数中被调用
    * \参数       fenc: 编码块首地址
    * \参数blockOffset: 当前块的位置
    * \参数        qmv: 其中一个mvc
    * \参数       comp: 用于计算sad或者satd的函数指针
    * \返回           : 伪分像素插值的sad值或者satd值*/
    inline int lowresQPelCost(pixel *fenc, intptr_t blockOffset, const MV& qmv, pixelcmp_t comp)
    {
        if ((qmv.x | qmv.y) & 1) //如果当前需要 1/4 分像素插值
        {
            ALIGN_VAR_16(pixel, subpelbuf[8 * 8]); //存储1/4分像素插值数据
            int hpelA = (qmv.y & 2) | ((qmv.x & 2) >> 1);
            pixel *frefA = lowresPlane[hpelA] + blockOffset + (qmv.x >> 2) + (qmv.y >> 2) * lumaStride;
            int qmvx = qmv.x + (qmv.x & 1);
            int qmvy = qmv.y + (qmv.y & 1);
            int hpelB = (qmvy & 2) | ((qmvx & 2) >> 1);
            pixel *frefB = lowresPlane[hpelB] + blockOffset + (qmvx >> 2) + (qmvy >> 2) * lumaStride;
            primitives.pu[LUMA_8x8].pixelavg_pp(subpelbuf, 8, frefA, lumaStride, frefB, lumaStride, 32);
            return comp(fenc, FENC_STRIDE, subpelbuf, 8); //获取伪分像素插值的sad值或者satd值
        }
        else
        {
            int hpel = (qmv.y & 2) | ((qmv.x & 2) >> 1);
            pixel *fref = lowresPlane[hpel] + blockOffset + (qmv.x >> 2) + (qmv.y >> 2) * lumaStride;
            return comp(fenc, FENC_STRIDE, fref, lumaStride); //获取伪分像素插值的sad值或者satd值
        }
    }
};

/* lowres buffers, sizes and strides */
struct Lowres : public ReferencePlanes
{
    pixel *buffer[4];          //这里需要申请4个buffer ,因为将要通过4 hpel下采样得到4份1/2亮度 用于分像素预测
    /* 查看 非asm函数frame_init_lowres_core
       这样做的目的是更好的通过1/2下采样视频的编码估计原始视频编码状态
       将亮度分四种方法进行1/2下采样
       原始点:
       82  89  86  86  93 
       85  89  99 101 113 
       96  97  97 100 104 
       106 108 107 111 109 
       127 156 133 139 137       
       0: 在行列选择偶数像素点为基准并选择相邻的右边、下边、右下机本身4个点作平均
       * * + +
       * * + +
       - - # #
       - - # #
       87  94
       102 104
       87 = ((((82 + 85 + 1) >> 1) + ((89 + 89 + 1) >> 1) + 1) >> 1)
       94 = ((((86 + 99 + 1) >> 1) + ((86 + 101 + 1) >> 1) + 1) >> 1)
       102= ((((96 + 106 + 1) >> 1) + ((97 + 108 + 1) >> 1) + 1) >> 1)
       104 = ((((97 + 107 + 1) >> 1) + ((100 + 111 + 1) >> 1) + 1) >> 1)
       h: 在行选择偶数像素点,在列选择奇数像素点为基准并选择相邻的右边、下边、右下机本身4个点作平均
       = * * = + +
       = * * = + +
       = - - = # #
       = - - = # #
       91  99 
       103 107 
       91 = ((((89 + 89 + 1) >> 1) + ((86 + 99 + 1) >> 1) + 1) >> 1) 
       99 = ((((86 + 101 + 1) >> 1) + ((93 + 113 + 1) >> 1) + 1) >> 1) 

       v: 在行选择奇数像素点,在列选择偶数像素点为基准并选择相邻的右边、下边、右下机本身4个点作平均
       = = = =
       * * + +
       * * + +
       = = = =
       - - # #
       - - # #
       92 100 
       125 123 
       92 = ((((85 + 96 + 1) >> 1) + ((89 + 97 + 1) >> 1) + 1) >> 1) 
       在行列选择奇数像素点为基准并选择相邻的右边、下边、右下机本身4个点作平均
       = = = = = =
       = * * = + +
       = * * = + +
       = = = = = =
       = - - = # #
       = - - = # #
       96 105
       126 124
       96 = ((((89 + 97 + 1) >> 1) + ((99 + 97 + 1) >> 1) + 1) >> 1) 
    **/

    int    frameNum;         // Presentation frame number 对应于未下采样原始帧的帧号poc
    int    sliceType;        // Slice type decided by lookahead 当前帧的帧类型
    //#define X265_TYPE_AUTO          0x0000  /* Let x265 choose the right type */
    //#define X265_TYPE_IDR           0x0001
    //#define X265_TYPE_I             0x0002
    //#define X265_TYPE_P             0x0003
    //#define X265_TYPE_BREF          0x0004  /* Non-disposable B-frame */
    //#define X265_TYPE_B             0x0005
    int    width;            // width of lowres frame in pixels 真实图像宽度/2  不够一个8x8的 补全8x8一个low CU
    int    lines;            // height of lowres frame in pixel lines 真实图像高度/2不够一个8x8的 补全8x8一个low CU
    int    leadingBframes;   // 当前帧前面有几个B\b帧(当前GOP下) number of leading B frames for P or I 

    bool   bScenecut;        // 当前是否是场景切换帧,初始化为false  Set to false if the frame cannot possibly be part of a real scenecut.
    bool   bKeyframe;        // 标记当前帧是否为IDR帧 初始化为false
    bool   bLastMiniGopBFrame;//标记当前帧是否为当前GOP的最后一个B帧, 初始化为 false

    /* lookahead output data */
    //第一维表示当前帧号poc-前向参考帧号poc   第二维表示后向参考帧号poc-当前帧号poc
    int64_t   costEst[X265_BFRAME_MAX + 2][X265_BFRAME_MAX + 2];      //[0][0]存储当前lowres中除边界块的全部intra8x8的SATD的累加和(SATD+5+4),其它存储相应帧之间的最优(SATD+mvcost+4)的累加和 B帧的cost会调整 score * 100 / (130 + param->bFrameBias) 开始全部初始化为-1 
    int64_t   costEstAq[X265_BFRAME_MAX + 2][X265_BFRAME_MAX + 2];    //用于自适应量化:[0][0]存储当前lowres中除边界块的全部intra8x8的(SATD+5+4)乘以invQscaleFactor>>8后的累加和 其它存储相应帧之间的最优(SATD+mvcost+4)乘以invQscaleFactor>>8后的累加和 ,开始全部初始化为-1
    int32_t*  rowSatds[X265_BFRAME_MAX + 2][X265_BFRAME_MAX + 2];     //存储空间中第三维度为lowres中有多少8x8块行, 其中[0][0][cuY]存储当前行的intra (SATD+5+4)值(经过fenc.invQscaleFactor>>8[cuXY]加权),
                                                                      //其它存储相应帧之间的(SATD+mvcost+4)值(经过fenc.invQscaleFactor[cuXY]>>8加权)   第三维第一个数据初始化为-1
    int       intraMbs[X265_BFRAME_MAX + 2];                          //维度表示当前帧号poc - 前向参考帧号poc:存储一帧中的除边界外intra块最优个数(如果有bi模式,并没有比较intra)  初始化为0
    int32_t*  intraCost;                                              //存储空间为lowres中有多少8x8块  存储对应8x8块的最优intra (SATD+5+4)值
    uint8_t*  intraMode;                                              //存储空间为lowres中有多少8x8块  存储对应8x8块的最优模式
    int64_t   satdCost;                                               //获取当前的framecost 如果需要参考帧,取参考帧列表中各自第一帧当做参考帧的framecost   在Lookahead::getEstimatedPictureCost获取值在RateControl::rateControlStart应用
    uint16_t* lowresCostForRc;//一个指针,指在vbv应用时用到,指向下面lowresCosts的一帧(跟上面的satdCost一样,只是分开到每个8x8块)   在Lookahead::getEstimatedPictureCost获取指针值(如果自适应量化重新更新cost的加权值) 在FrameEncoder::processRowEncoder应用
    //第一维表示当前帧号poc-前向参考帧号poc   第二维表示后向参考帧号poc-当前帧号poc  其中每个值都 | listused <<14   可以检测高14位的数字:0 表示 intra  1 表示前向搜索  2表示后向搜索  3 表示bi搜索   
    uint16_t(*lowresCosts[X265_BFRAME_MAX + 2][X265_BFRAME_MAX + 2]);//存储空间中第三维度为lowres中有多少8x8块,其中[0][0][cuxy] 存储对应8x8块的最优intra (SATD+5+4)值  其它存储相应(SATD+mvcost+4)或者intra(SATD+5+4)最优值
    //第一维表示前向帧还是后向帧,第二维用于标记当前list下的前向/后向第几帧 (如:当前poc = 3  则fenc->lowresMvs[0][0] 表示前向第一帧 poc=2 fenc->lowresMvs[1][1] 表示后向第二帧 poc=5 )
    int32_t*  lowresMvCosts[2][X265_BFRAME_MAX + 1];                 //存储空间中第三维度为lowres中有多少8x8块, 每个8x8存储着相应最优mv对应的satd +  mvcost
    MV*       lowresMvs[2][X265_BFRAME_MAX + 1];                     //[list][bframe] 存储空间中第三维度为lowres中有多少8x8块 并 将每一帧第一个8x8的mv.x 初始化为0x7FFF  每个8x8存储着相应mv信息
    uint32_t  maxBlocksInRow; //一行中有多少8x8块
    uint32_t  maxBlocksInCol; //一列中有多少8x8块

    /* used for vbvLookahead */
    /************************************************************************/
    /* 只存储到第一个GOP中:plannedType、plannedSatd、indB(用于计数) 
    /* 例如当前列表:PbbbPbbbPbbbP  出来之后变为:PbBbPbBbPbBbP 
    /* 第一个GOP(PbbbP) 存储了当前所有的framecost
    /* 进行标号:P0b1b2b3P4b5b6b7P8b9b10b11P12
    /* P0: 无任何存储
    /* b1:b3 P8 b5 b6 b7 P12 b9 b10 b11
    /* b2:b1 b3 P8 b5 b6 b7 P12 b9 b10 b11
    /* b3:P8 b5 b6 b7 P12 b9 b10 b11
    /* P4:b1 b2 b3 P8 b5 b6 b7 P12 b9 b10 b11
    /************************************************************************/
    int       plannedType[X265_LOOKAHEAD_MAX + 1];//当前GOP的后向非B帧,用于存储lookachead下的所有帧类型
    int64_t   plannedSatd[X265_LOOKAHEAD_MAX + 1];//当前GOP的后向非B帧,用于存储lookachead下的所有frame cost
    int       indB;//计数当前存储的framecost 的个数 初始化为0
    int       bframes;// 等于配置的 param->bframes;  最大连续的B帧个数

    /*calcAdaptiveQuantFrame 计算
    假设原始帧亮度16x16块的方差标记为 sY  像素个数nY = 16x16 =256  AC能量记为: acY = nY*sY
    假设原始帧色度 8x8 块的方差标记为 sCr、sCb  像素个数nC = 8x8 =64 AC能量记为: acCb = nC*sCb acCr = nC*sCr
    当前块的AC能量记为:ac =  acY + acCb + acCr
    每个16x16块按照光栅扫描记为 ac(i) , 总共个数为n
    AC能量经过矫正后的值:Jac = (energy*(1/(2^(2*(X265_DEPTH-8)))) + 1)^0.1
    当前所有块的平均值为 JAveAc = (Σ(Jac)/n
    当前所有块的平方和均值为 JAveAc2 = (Σ((Jac)^2))/n
    当前自适应量化的强度记为:strength   
    当前的位宽为 depth
    如果:param->rc.aqMode = X265_AQ_NONE 
    qpAqOffset     [i] =  0 
    qpCuTreeOffset [i] =  0
    invQscaleFactor[i] =  256(即权重系数为1 因为真正的权重为 invQscaleFactor[i]>>8)
    如果:param->rc.aqMode = X265_AQ_VARIANCE
    strength = param->rc.aqStrength * 1.0397f;  
    qp_adj   = strength * (log2(Jac(i)) - (14.427 + 2*(depth-8))))
    qpAqOffset     [i] = qp_adj
    qpCuTreeOffset [i] = qp_adj
    invQscaleFactor[i] = x265_exp2fix8(qp_adj)
    如果:param->rc.aqMode = X265_AQ_AUTO_VARIANCE
    strength = param->rc.aqStrength * JAveAc;
    bias_strength = param->rc.aqStrength;     
    qp_adj   = strength * (Jac - JAveAc); 
    qpAqOffset     [i] = qp_adj
    qpCuTreeOffset [i] = qp_adj
    invQscaleFactor[i] = x265_exp2fix8(qp_adj)
    如果:param->rc.aqMode = X265_AQ_AUTO_VARIANCE_BIASED
    strength = param->rc.aqStrength * JAveAc ;
    bias_strength = param->rc.aqStrength;     
    qp_adj   =   strength * (Jac - JAveAc) + bias_strength * (1.f - 11.f / (Jac * Jac));     
    qpAqOffset     [i] = qp_adj
    qpCuTreeOffset [i] = qp_adj
    invQscaleFactor[i] = x265_exp2fix8(qp_adj)
**/
    double*   qpAqOffset;      // AQ QP offset values for each 16x16 CU
     /* 用处:当前存储的为qpoffset值
       空间大小:一帧中16x16块的个数
       如果是1pass 或者非参考帧 在calcAdaptiveQuantFrame中计算,如果是2pass 从1pass文件中直接读取 
    **/
    double*   qpCuTreeOffset;  // cuTree QP offset values for each 16x16 CU
     /* 用处:当前存储的为qpoffset值
       空间大小:一帧中16x16块的个数
       如果是1pass 或者非参考帧 在calcAdaptiveQuantFrame中计算 cuTreeFinish计算,如果是2pass 从1pass文件中直接读取 
    **/
    int*      invQscaleFactor; // qScale values for qp Aq Offsets
     /* 用处:对CUcost进行加权,方差越大,权重系数越小,cost越小(图像越平坦 cost越小)
        空间大小:一帧中16x16块的个数
       如果是1pass 或者非参考帧 在calcAdaptiveQuantFrame中计算,如果是2pass 从1pass文件中直接读取
    **/
    uint64_t  wp_ssd[3];       // This is different than SSDY, this is sum(pixel^2) - sum(pixel)^2 for entire frame
                               //存储一整原始帧的AC能量(约等于 n倍的方差 n为图像像素个数) 0,1,2 分别表示Y、U、V 数据在calcAdaptiveQuantFrame函数计算
                               //Σ(x^2) - (Σx * Σx)/n = n*Variance (n倍的方差) (含补全8x8块)边像素值
    uint64_t  wp_sum[3];       //存储未下采样原始帧所有像素的和(Σx)  0,1,2 分别表示Y、U、V  在calcAdaptiveQuantFrame函数计算 (含补全8x8块)边像素值

    /* cutree intermediate data */
    uint16_t* propagateCost;   //存储空间为lowres中有多少8x8块 存储每个8x8块的传播cost(累加传播cost + 加权intracost)*(intracost-最优cost)/intracost  用于计算可参考帧的qpCuTreeOffset值
    double    weightedCostDelta[X265_BFRAME_MAX + 2]; //如果weightsAnalyse中判断加权优存储参考帧(是下采样后的原始帧)加权的SATD/不加权的SATD,否则存储0 坐标为当前帧poc-参考帧poc ,初始化为0

    /** 函数功能   : 初始化数据,并申请空间内存
    /*  调用范围   : 只Frame::create函数中被调用
    * \参数 origPic: Frame.m_fencPic 原始帧YUV数据
    * \返回        : 是否申请内存成功 */
    bool create(PicYuv *origPic, int _bframes, bool bAqEnabled);
    /** 函数功能   : 释放空间内存
    /*  调用范围   : 只Frame::destroy函数中被调用
    * \返回        : null */
    void destroy();
    /** 函数功能   : 初始化信息,并进行下采样和扩边
    /*  调用范围   : 只void PreLookaheadGroup::processTasks函数中被调用
    * \返回        : null */
    void init(PicYuv *origPic, int poc);
};
}

#endif // ifndef X265_LOWRES_H


 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值