最近要开始研究HEVC帧内预测和显著度的关系,所以先把HM的帧内预测理一理,有些东西总是记了忘,所以干脆写下这。HM与X265有相关,变量有的定义类似。
- struct PredictionUnit
- {
- uint32_t ctuAddr; // raster index of current CTU within its picture
- uint32_t cuAbsPartIdx; // z-order offset of current CU within its CTU
- uint32_t puAbsPartIdx; // z-order offset of current PU with its CU
- int width;
- int height;
- PredictionUnit(const CUData& cu, const CUGeom& cuGeom, int puIdx);
- };
- class Predict
- {
- public:
- enum { ADI_BUF_STRIDE = (2 * MAX_CU_SIZE + 1 + 15) }; // alignment to 16 bytes
- /* Weighted prediction scaling values built from slice parameters (bitdepth scaled) */
- struct WeightValues
- {
- int w, o, offset, shift, round;
- };
- struct IntraNeighbors//Predict内部类 用于存储周边块的可用标记等信息
- {
- int numIntraNeighbor;//统计当前预测块周边多少可用4x4相邻块
- int totalUnits;//周边4x4块个数 左下、左边、左上角1个、上边、右上
- int aboveUnits;//上边4x4个数:上边 右上
- int leftUnits;//左边4x4个数:左边、左下
- int unitWidth;//当前最小块宽度,4
- int unitHeight;//当前最小块高度,4
- int log2TrSize;//当前PU-TU深度
- bool bNeighborFlags[4 * MAX_NUM_SPU_W + 1];//空间大小为65 存储周边标记是否可用 存储方式: 左下、左边(左下和左边按照离左上角由远及近存储0:左下左下像素点....左上角4x4块像素点)、左上角一点、上边、右上
- /*
- 标记对应块是否可用(4x4),如当前PU为64x64:
- 拥有4x4个数tuWidthInUnits = 16,tuHeightInUnits=16
- 左上角参考像素点标记:bNeighborFlags[tuHeightInUnits *2] :bNeighborFlags[32]
- 上边行参考像素点标记:bNeighborFlags[tuHeightInUnits *2+1 ....tuHeightInUnits *2+tuWidthInUnits]:bNeighborFlags[33~48]
- 右上边行参考像素点标记:bNeighborFlags[tuHeightInUnits *2+tuWidthInUnits+1 ....tuHeightInUnits *2+2*tuWidthInUnits]:bNeighborFlags[49~64]
- 左边行参考像素点标记:bNeighborFlags[tuHeightInUnits ....tuHeightInUnits *2-1]:bNeighborFlags[16~31]
- 左下边行参考像素点标记:bNeighborFlags[0 ....tuHeightInUnits - 1]:bNeighborFlags[0~15]
- **/
- };
- ShortYuv m_predShortYuv[2]; /* temporary storage for weighted prediction */
- int16_t* m_immedVals;
- // Unfiltered/filtered neighbours of the current partition.
- pixel intraNeighbourBuf[2][258];// 存储当前周边行的数据 第一维是参考数据,第二维是经过滤波后的数据
- /*
- 如当前PU为64x64:
- tuWidthInUnits = 16,tuHeightInUnits=16
- 左上角参考像素点:0
- 上边行参考像素点:1~16
- 右上边行参考像素点:17~32
- 左边行参考像素点:33~48
- 左下边行参考像素点:49~64
- **/
- /* Slice information */
- int m_csp;
- int m_hChromaShift;
- int m_vChromaShift;
- Predict();
- ~Predict();
- bool allocBuffers(int csp);
- // motion compensation functions
- void predInterLumaPixel(const PredictionUnit& pu, Yuv& dstYuv, const PicYuv& refPic, const MV& mv) const;
- void predInterChromaPixel(const PredictionUnit& pu, Yuv& dstYuv, const PicYuv& refPic, const MV& mv) const;
- void predInterLumaShort(const PredictionUnit& pu, ShortYuv& dstSYuv, const PicYuv& refPic, const MV& mv) const;
- void predInterChromaShort(const PredictionUnit& pu, ShortYuv& dstSYuv, const PicYuv& refPic, const MV& mv) const;
- void addWeightBi(const PredictionUnit& pu, Yuv& predYuv, const ShortYuv& srcYuv0, const ShortYuv& srcYuv1, const WeightValues wp0[3], const WeightValues wp1[3], bool bLuma, bool bChroma) const;
- void addWeightUni(const PredictionUnit& pu, Yuv& predYuv, const ShortYuv& srcYuv, const WeightValues wp[3], bool bLuma, bool bChroma) const;
- void motionCompensation(const CUData& cu, const PredictionUnit& pu, Yuv& predYuv, bool bLuma, bool bChroma);
- /* Angular Intra */
- /** 函数功能 : 按照当前的亮度预测方向获取预测值
- /* 调用范围 : 只在codeIntraLumaQT、codeIntraLumaTSkip、residualTransformQuantIntra函数中被调用
- * \参数 dirMode : 当前亮度方向
- * \参数 dst : PU预测块地址
- * \参数 stride : 原始块步长
- * \参数 log2TrSize : 当前PU的最大变换大小
- * 返回值 : null**/
- void predIntraLumaAng(uint32_t dirMode, pixel* pred, intptr_t stride, uint32_t log2TrSize);
- void predIntraChromaAng(uint32_t dirMode, pixel* pred, intptr_t stride, uint32_t log2TrSizeC);
- /** 函数功能 : 获取intra周边参考像素点 并对其滤波
- * \参数 cu : 当前编码的CU
- * \参数 cuGeom : 当前CU几何信息
- * \参数 puAbsPartIdx : 为当前PU在当前CU下的zigzag标号,不是CTU下的zigzag标号
- * \参数 intraNeighbors : 当前PU周边块的可用信息
- * \参数 dirMode : 具体亮度模式 或者 ALL_IDX(在搜索intra方向时是此值)
- * 返回值 : null**/
- void initAdiPattern(const CUData& cu, const CUGeom& cuGeom, uint32_t puAbsPartIdx, const IntraNeighbors& intraNeighbors, int dirMode);
- void initAdiPatternChroma(const CUData& cu, const CUGeom& cuGeom, uint32_t puAbsPartIdx, const IntraNeighbors& intraNeighbors, uint32_t chromaId);
- /* Intra prediction helper functions */
- /** 函数功能 : 返回intraNeighbors中周边可用块信息
- * \参数 cu : 当前编码的CU
- * \参数 absPartIdx : 为当前PU在当前CU下的zigzag标号,不是CTU下的zigzag标号
- * \参数 tuDepth : 当前的TU深度
- * \参数 isLuma : 当前是否为亮度模式
- * \参数 intraNeighbors : 用于存储当前块的周边信息
- * 返回值 : null**/
- static void initIntraNeighbors(const CUData& cu, uint32_t absPartIdx, uint32_t tuDepth, bool isLuma, IntraNeighbors *IntraNeighbors);
- /** 函数功能 : 获取周边行数据 并且 填充数据 对应不可用的块 按照由远及近遍历左下、左、左上角、上边 、右上顺序填充(选择前面第一个可用位置)
- /* 调用范围 : 只在initAdiPattern和initAdiPatternChroma中调用
- * \参数 adiOrigin : PU左上角在重构帧对应的pixel地址
- * \参数 picStride : 重构帧步长
- * \参数 intraNeighbors : 当前PU周边块的可用信息
- * \参数 dst[258] : 存储周边参考像素值: 存储方式 左上角一点 上边 右上 左边 左下
- * 返回值 : null**/
- static void fillReferenceSamples(const pixel* adiOrigin, intptr_t picStride, const IntraNeighbors& intraNeighbors, pixel dst[258]);
- /** 函数功能 : 返回当前左上角像素点是否可用
- * \参数 cip : 帧内预测是否受限(不能参考inter块)
- * \参数 cu : 当前编码的CU
- * \参数 partIdxLT : 当前PU左上角像素点在CTU中的zigzag标号
- * 返回值 : 返回当前左上角像素点是否可用**/
- template<bool cip>
- static bool isAboveLeftAvailable(const CUData& cu, uint32_t partIdxLT);
- template<bool cip>
- /** 函数功能 : 返回当前上边行像素点可用个数
- * \参数 cip : 帧内预测是否受限(不能参考inter块)
- * \参数 cu : 当前编码的CU
- * \参数 partIdxLT : 当前PU左上角像素点在CTU中的zigzag标号
- * \参数 partIdxRT : 当前PU右上角像素点在CTU中的zigzag标号
- * \参数 bValidFlags : 用于存上边可用4x4块的标记
- * 返回值 : 返回上边行可用的4x4块个数**/
- static int isAboveAvailable(const CUData& cu, uint32_t partIdxLT, uint32_t partIdxRT, bool* bValidFlags);
- /** 函数功能 : 返回当前左边行像素点可用个数
- * \参数 cip : 帧内预测是否受限(不能参考inter块)
- * \参数 cu : 当前编码的CU
- * \参数 partIdxLT : 当前PU左上角像素点在CTU中的zigzag标号
- * \参数 partIdxLB : 当前PU左下角像素点在CTU中的zigzag标号
- * \参数 bValidFlags : 用于存边可用4x4块的标记
- * 返回值 : 返回左边行可用的4x4块个数**/
- template<bool cip>
- static int isLeftAvailable(const CUData& cu, uint32_t partIdxLT, uint32_t partIdxLB, bool* bValidFlags);
- /** 函数功能 : 返回当前右上边行像素点可用个数
- * \参数 cip : 帧内预测是否受限(不能参考inter块)
- * \参数 cu : 当前编码的CU
- * \参数 partIdxRT : 当前PU右上角像素点在CTU中的zigzag标号
- * \参数 bValidFlags : 用于存右上边可用4x4块的标记
- * \参数 numUnits : 当前PU宽度的4x4块个数
- * 返回值 : 返回右上边行可用的4x4块个数**/
- template<bool cip>
- static int isAboveRightAvailable(const CUData& cu, uint32_t partIdxRT, bool* bValidFlags, uint32_t numUnits);
- /** 函数功能 : 返回当前左下边行像素点可用个数
- * \参数 cip : 帧内预测是否受限(不能参考inter块)
- * \参数 cu : 当前编码的CU
- * \参数 partIdxLB : 当前PU左下角像素点在CTU中的zigzag标号
- * \参数 bValidFlags : 用于存左下边可用4x4块的标记
- * \参数 numUnits : 当前PU高度的4x4块个数
- * 返回值 : 返回左下边行可用的4x4块个数**/
- template<bool cip>
- static int isBelowLeftAvailable(const CUData& cu, uint32_t partIdxLB, bool* bValidFlags, uint32_t numUnits);
- };
- }
- #endif // ifndef X265_PREDICT_H