帧内预测——initAdiPattern

来源:互联网 发布:蜗杆数控车床编程事例 编辑:程序博客网 时间:2024/05/16 09:04

近期开始接触HEVC,看了一些综述性的文章后开始看平台,可总感觉效果不佳,所以打算把每天看的东西都写一下,巩固巩固。首先是讲一下initAdiPattern这个函数,在看了hevc_cjl的博客:  http://blog.csdn.net/hevc_cjl/article/details/8184276?reload 之后,受益良多。

首先分析下这个函数的用途:这个函数位于帧内预测的亮度预测estIntraPredQT中,主要是用于初始化帧内模式。

细化其功能:(1)检测当前的PU相邻点的可用性(2)参考样点的替换 (3)参考样点的平滑滤波

通过下面这幅图能很好地理解代码的信息。如:

 // ----- 先进行样点值拷贝    Int l = 0;    // left border from bottom to top【左下->左上,滤波前参考样点值拷贝】    for (i = 0; i < uiCuHeight2; i++)    {      piFilterBuf[l++] = piAdiTemp[uiWidth * (uiCuHeight2 - i)];    }    // top left corner    piFilterBuf[l++] = piAdiTemp[0]; //【左上角点, 拷贝】    // above border from left to right    for (i=0; i < uiCuWidth2; i++)  // 【上->右上, 拷贝】    {      piFilterBuf[l++] = piAdiTemp[1 + i];  //l此时初始为uiCuHeight2+1  }  
以上代码为样本点信息拷贝过程,拷贝的过程是自左下而上,过AboveLeft而向右的过程


Void TComPattern::initAdiPattern( TComDataCU* pcCU, UInt uiZorderIdxInPart, UInt uiPartDepth, Int* piAdiBuf, Int iOrgBufStride, Int iOrgBufHeight, Bool& bAbove, Bool& bLeft, Bool bLMmode )  {    Pel*  piRoiOrigin;//piRoiOrgin指向重建Yuv图像对应于当前PU所在位置的首地址    Int*  piAdiTemp;  //    UInt  uiCuWidth   = pcCU->getWidth(0) >> uiPartDepth; //CU宽    UInt  uiCuHeight  = pcCU->getHeight(0)>> uiPartDepth; //CU高    UInt  uiCuWidth2  = uiCuWidth<<1;//  uiCuWidth*2  UInt  uiCuHeight2 = uiCuHeight<<1;    UInt  uiWidth;    UInt  uiHeight;    Int   iPicStride = pcCU->getPic()->getStride(); //图像跨度(原图像宽度 + 两边扩充的参考像素点)     Int   iUnitSize = 0;      Int   iNumUnitsInCu = 0;      Int   iTotalUnits = 0;      Bool  bNeighborFlags[4 * MAX_NUM_SPU_W + 1]; //!< 用于存放4个方向上的相邻样点值的【可用性】,4*32+1    Int   iNumIntraNeighbor = 0;                 ////!< 给可用邻块进行计数          UInt uiPartIdxLT, uiPartIdxRT, uiPartIdxLB;      ////! 获取当前PU左上角LT,右上角RT以及左下角LB 以4x4块为单位的Z-order(Zscan)    pcCU->deriveLeftRightTopIdxAdi( uiPartIdxLT, uiPartIdxRT, uiZorderIdxInPart, uiPartDepth );      pcCU->deriveLeftBottomIdxAdi  ( uiPartIdxLB,              uiZorderIdxInPart, uiPartDepth );        iUnitSize      = g_uiMaxCUWidth >> g_uiMaxCUDepth;  // 4     iNumUnitsInCu  = uiCuWidth / iUnitSize;    // 当前CU的宽/4  = 宽方向上,iUnitSize的个数    iTotalUnits    = (iNumUnitsInCu << 2) + 1; //(iNumUnitsInCu*4) + 1           // (扫描顺序是从左下到左上,再从左上到右上)     bNeighborFlags[iNumUnitsInCu*2] = isAboveLeftAvailable( pcCU, uiPartIdxLT );    iNumIntraNeighbor  += (Int)(bNeighborFlags[iNumUnitsInCu*2]);    iNumIntraNeighbor  += isAboveAvailable     ( pcCU, uiPartIdxLT, uiPartIdxRT, bNeighborFlags+(iNumUnitsInCu*2)+1 );    iNumIntraNeighbor  += isAboveRightAvailable( pcCU, uiPartIdxLT, uiPartIdxRT, bNeighborFlags+(iNumUnitsInCu*3)+1 );    iNumIntraNeighbor  += isLeftAvailable      ( pcCU, uiPartIdxLT, uiPartIdxLB, bNeighborFlags+(iNumUnitsInCu*2)-1 );    iNumIntraNeighbor  += isBelowLeftAvailable ( pcCU, uiPartIdxLT, uiPartIdxLB, bNeighborFlags+ iNumUnitsInCu   -1 );        bAbove = true;  //之前定义为FALSE  bLeft  = true;  //同上    uiWidth=uiCuWidth2+1;    uiHeight=uiCuHeight2+1;        if (((uiWidth<<2)>iOrgBufStride)||((uiHeight<<2)>iOrgBufHeight))  //判定范围  {      return;    }     //! piRoiOrigin指向当前PU左上角    piRoiOrigin = pcCU->getPic()->getPicYuvRec()->getLumaAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU()+uiZorderIdxInPart );    piAdiTemp   = piAdiBuf;        // 参考样点的替换(填补)过程    fillReferenceSamples (g_bitDepthY, piRoiOrigin, piAdiTemp, bNeighborFlags, iNumIntraNeighbor, iUnitSize, iNumUnitsInCu, iTotalUnits, uiCuWidth, uiCuHeight, uiWidth, uiHeight, iPicStride, bLMmode);
// ****************************************************    //! 下面所进行的工作主要是对参考样点进行3抽头的滤波。    //    piAdiBuf指向滤波前的参考样点的首地址,在滤波前,先将所有参考样点拷贝到piFilterBuf指向的区域,    //! 经滤波后的样点值保存在piFilterBufN指向的区域,最终将滤波后的样点值拷贝到piFilterBuf1。      //  值得一提的是,最终的结果是,piAdiBuf指向的区域是未经滤波的样点值,而piFilterBuf1指向的区域是经过    //! 滤波的样点值,两者的地址相差uiWH = uiWidth * uiHeight = (uiCuWidth2 + 1) * (uiCuHeight2 + 1),这就解释了在进行     //! 真正的帧内预测时,在需要滤波时,指向piAdiBuf的指针需要加上uiWH的偏移量。    Int   i;    // generate filtered intra prediction samples    Int iBufSize = uiCuHeight2 + uiCuWidth2 + 1;  //结合图中信息比较    UInt uiWH = uiWidth * uiHeight;               // number of elements in one buffer      Int* piFilteredBuf1 = piAdiBuf + uiWH;        // 1. filter buffer    Int* piFilteredBuf2 = piFilteredBuf1 + uiWH;  // 2. filter buffer    Int* piFilterBuf = piFilteredBuf2 + uiWH;     // buffer for 2. filtering (sequential)      //piFilterBufN 存放的是参考样点经3抽头滤波后的值    Int* piFilterBufN = piFilterBuf + iBufSize;   // buffer for 1. filtering (sequential)          // ----- 先进行样点值拷贝    Int l = 0;    // left border from bottom to top【左下->左上,滤波前参考样点值拷贝】    for (i = 0; i < uiCuHeight2; i++)    {      piFilterBuf[l++] = piAdiTemp[uiWidth * (uiCuHeight2 - i)];    }    // top left corner    piFilterBuf[l++] = piAdiTemp[0]; //【左上角点, 拷贝】    // above border from left to right    for (i=0; i < uiCuWidth2; i++)  // 【上->右上, 拷贝】    {      piFilterBuf[l++] = piAdiTemp[1 + i];    }       //对32*32的块进行 StrongIntraSmoothing if (pcCU->getSlice()->getSPS()->getUseStrongIntraSmoothing()) //cfg里面设置    {      Int blkSize = 32;      Int bottomLeft = piFilterBuf[0];      Int topLeft = piFilterBuf[uiCuHeight2];      Int topRight = piFilterBuf[iBufSize-1];      Int threshold = 1 << (g_bitDepthY - 5);//8      Bool bilinearLeft = abs(bottomLeft+topLeft-2*piFilterBuf[uiCuHeight]) < threshold;      Bool bilinearAbove  = abs(topLeft+topRight-2*piFilterBuf[uiCuHeight2+uiCuHeight]) < threshold;          if (uiCuWidth>=blkSize && (bilinearLeft && bilinearAbove))      {        Int shift = g_aucConvertToBit[uiCuWidth] + 3;  // log2(uiCuHeight2) =7       piFilterBufN[0] = piFilterBuf[0];        piFilterBufN[uiCuHeight2] = piFilterBuf[uiCuHeight2];        piFilterBufN[iBufSize - 1] = piFilterBuf[iBufSize - 1];        for (i = 1; i < uiCuHeight2; i++)        {          piFilterBufN[i] = ((uiCuHeight2-i)*bottomLeft + i*topLeft + uiCuHeight) >> shift;        }            for (i = 1; i < uiCuWidth2; i++)        {          piFilterBufN[uiCuHeight2 + i] = ((uiCuWidth2-i)*topLeft + i*topRight + uiCuWidth) >> shift;        }      }      else       {        // 1. filtering with [1 2 1]        piFilterBufN[0] = piFilterBuf[0];        piFilterBufN[iBufSize - 1] = piFilterBuf[iBufSize - 1];        for (i = 1; i < iBufSize - 1; i++)        {          piFilterBufN[i] = (piFilterBuf[i - 1] + 2 * piFilterBuf[i]+piFilterBuf[i + 1] + 2) >> 2; // 最后 +2是为了四舍五入取整        }      }    }    else     {      // 1. filtering with [1 2 1]       piFilterBufN[0] = piFilterBuf[0];      piFilterBufN[iBufSize - 1] = piFilterBuf[iBufSize - 1];        for (i = 1; i < iBufSize - 1; i++)      {        piFilterBufN[i] = (piFilterBuf[i - 1] + 2 * piFilterBuf[i]+piFilterBuf[i + 1] + 2) >> 2;      }    }      // fill 1. filter buffer with filtered values    l=0;    for (i = 0; i < uiCuHeight2; i++)    {      piFilteredBuf1[uiWidth * (uiCuHeight2 - i)] = piFilterBufN[l++];    }    piFilteredBuf1[0] = piFilterBufN[l++];    for (i = 0; i < uiCuWidth2; i++)    {      piFilteredBuf1[1 + i] = piFilterBufN[l++];    }  }

	
				
		
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 闲鱼快递损坏了怎么办 寄快递东西坏了怎么办 快递邮寄东西坏了怎么办 快递被别人拆了怎么办 淘宝买的东西包装破损怎么办 寄血液被退回来怎么办 快递被安检扣了怎么办 淘宝原单退回运费怎么办 运输过程中包裹破损怎么办 天猫没收到货签收怎么办 收到的快递坏了怎么办 自寄的快递少了怎么办 邮的东西弄坏了怎么办 物流签收后发现货物损坏怎么办 发现客人损坏了酒店物品怎么办 东西坏了签收了怎么办 朋友圈贩卖三无产品你怎么办 付钱给微商没有保障怎么办 电镀锌钢带生锈怎么办 电机机油从空气滤芯里流出怎么办 把塑料皮套吃了怎么办 塑料框眼镜有点小了怎么办 出口纸箱打了钉怎么办 买房子交款单据丢了怎么办 买房子所有单据丢失怎么办 车险单据都丢了怎么办 真空包装的东西里面有空气怎么办 发货物忘记写唛头了怎么办 Word文档撤销按钮删除了怎么办 ai保存时未响应怎么办 ai还没保存卡了怎么办 ai卡住了没保存怎么办 屁股沟有硬块红肿怎么办 卧室床选太大了怎么办 画板的笔尖掉了怎么办 宜家水壶盖子有水怎么办 背滤鱼缸除油膜怎么办 书多了没地方放怎么办 学生在教室内丢手机怎么办 新车尾箱坏了怎么办 放书的箱子烂了怎么办