函数initAdiPattern

(1)检测当前PU的相邻样点包括左上、上、右上、左、左下邻域样点值的可用性,或者说检查这些点是否存在;(2)参考样点的替换过程,主要实现的是JCTVC-J1003即draft 8.4.4.2.2的内容,主要由函数fillReferenceSamples来完成,这个在之前的文章已经讨论过了;(3)相邻样点即参考样点的平滑滤波

uiWidth和uiHeight实际上对应的是代码中的uiCUWidth和uiCUHeight

/*
initAdiPattern函数【Adi = arbitrary direction intra prediction  】
(1晨不变)
(1)检测当前PU的相邻样点包括左上、上、右上、左、左下邻域样点值的可用性,或者说检查这些点是否存在;
(2)参考样点的替换过程,主要实现的是JCTVC-J1003即draft 8.4.4.2.2的内容,主要由函数fillReferenceSamples来完成, 这个在之前的文章已经讨论过了;
(3)相邻样点即参考样点的平滑滤波,主要实现draft 8.4.4.2.3的内容。
*/
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;  UInt  uiCuHeight2 = uiCuHeight<<1;  UInt  uiWidth;  UInt  uiHeight;  Int   iPicStride = pcCU->getPic()->getStride(); //图像跨度(原图像宽度 + 两边扩充的参考像素点)【wxl_125】  Int   iUnitSize = 0;   //变量解释见下面参数赋值【wxl_125】  Int   iNumUnitsInCu = 0;    Int   iTotalUnits = 0;  Bool  bNeighborFlags[4 * MAX_NUM_SPU_W + 1]; //!< 用于存放4个方向上的相邻样点值的【可用性】,4*32+1  Int   iNumIntraNeighbor = 0;                 !< 给可用邻块进行计数   【wxl_125:统计可以参考的领域块的数目】   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; // iTotalUnits = Top + RightTop + Left + LeftBottom + LeftTop   //                                            = iNumUnitsInCu + iNumUnitsInCu + iNumUnitsInCu + iNumUnitsInCu + 1    //  wxl_125:统计可以使用的领域参考块的数目    // (扫描顺序是从左下到左上,再从左上到右上)   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;  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;  //wxl_125: 参考样点的替换(填补)过程  fillReferenceSamples (g_bitDepthY, piRoiOrigin, piAdiTemp, bNeighborFlags, iNumIntraNeighbor, iUnitSize, iNumUnitsInCu, iTotalUnits, uiCuWidth, uiCuHeight, uiWidth, uiHeight, iPicStride, bLMmode);  // ****************************************************  //! (1晨)下面所进行的工作主要是对参考样点进行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;  // left and left above border + above and above right border + top left corner = length of 3. filter buffer  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);  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)  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]【wxl_125:首尾直接保存,中间样点值进行3抽头[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++];  }
}  

帧内预测-函数initAdiPattern相关推荐

  1. HEVC学习-帧内预测-亮度分量预测主函数

    QP的详解:https://blog.csdn.net/liangjiubujiu/article/details/80569391 代码部分:https://blog.csdn.net/HEVC_C ...

  2. HEVC帧内预测参考相邻帧代码解析

    作者:66 (转载请注明出处) 参考链接:http://blog.csdn.net/hevc_cjl/article/details/8200793 亮度分量的帧内预测涉及到的模块比较多,CU-> ...

  3. HEVC亮度分量帧内预测模式代码详解

    作者:66 (转载请注明出处) 从我自身的学习历程来看,建议大家先把理论扎实了再去理解代码,代码里也有注释,与理论的地方一对应加上一点C编程基础很容易就能理解. 我们先了解相关理论,此处可参考这一篇博 ...

  4. HEVC学习(六) —— 帧内预测系列之四

    本文主要把实现亮度分量帧内预测的主函数的大体框架通过代码注释的方式介绍一下. [cpp]  view plain copy Void TEncSearch::estIntraPredQT( TComD ...

  5. 帧内预测——initAdiPattern

    近期开始接触HEVC,看了一些综述性的文章后开始看平台,可总感觉效果不佳,所以打算把每天看的东西都写一下,巩固巩固.首先是讲一下initAdiPattern这个函数,在看了hevc_cjl的博客:  ...

  6. H.266/VVC代码学习:帧内预测之角度预测函数(predIntraAng、xPredIntraAng)

    predIntraAng函数 VTM中,帧内预测的角度预测的入口函数为predIntraAng函数,该函数主要是用于进行传统的帧内预测(Planar.DC.角度预测),然后对Planar和DC模式使用 ...

  7. VVC 帧内预测代码 xPredIntraAng()函数

    帧内预测中的initPredIntraParams()函数 (负参考方向处在跑代码时再看一遍)_青椒鸡汤的博客-CSDN博客 H.266/VVC-VTM代码学习-帧内预测05-Angular模式下计算 ...

  8. H.265之三 -帧内预测(3)

    今天主要介绍帧内预测一个很重要的函数initAdiPattern,它的主要功能有三个,(1)检测当前PU的相邻样点包括左上.上.右上.左.左下邻域样点值的可用性,或者说检查这些点是否存在:(2)参考样 ...

  9. HEVC学习(五) —— 帧内预测系列之三

    由于研究的需要,现将一晨不变大神的关于HEVC帧内预测的相关博客进行转载,方便自己查阅.一直都看一晨不变大神的帖子,受益匪浅.原著博客地址:http://blog.csdn.net/HEVC_CJL/ ...

最新文章

  1. 10 个有用的 PHP 代码
  2. 【pmcaff】一个微信创业者的吐血总结,这样才能做好营销,实用!
  3. 物联网设备的互操作性问题探讨
  4. 成对的歌曲,其总持续时间可被60整除
  5. 唯有自己变得强大_真正的自立,唯是让自己变得更加强大
  6. 异构内存管理 Heterogeneous Memory Management (HMM)
  7. mysql 优化关键字_MySQL 优化之 EXPLAIN 关键字
  8. char 转换 二进制 java_使用Java读取二进制文件并将其转换为char文件 - java
  9. Java调用C/C++的过程
  10. 编译原理(龙书):第三章部分题目参考答案
  11. ML Note 3.4 - 数据降维算法 PCA / t-SNE
  12. MySQL 子查询之 单行子查询及多行子查询
  13. 我的macOS常用软件清单
  14. 企业上云,打造数字经济新动能|中机智库
  15. 2011网易校园招聘笔试题
  16. SRC赏金平台汇总介绍
  17. Command ‘yum‘ not found, did you mean
  18. 算法系列之九:计算几何与图形学有关的几种常用算法(二)
  19. 数据库隔离级别的理解
  20. 2020年11月连云港计算机考试,连云港2020年中级经济师考试时间及考试科目

热门文章

  1. 【MATLAB教程案例15】基于WOA鲸鱼优化算法的函数极值计算matlab仿真及其他应用
  2. 高德地图定位获取当前地址城市街道等详细信息(全部代码)
  3. 魔戒中超眩的武器装备!
  4. 互联网快讯:微信视频号公布MCN招募计划;极米投影产品双十一持续热销;亚马逊计划再发射4538颗卫星
  5. 令克软件再推OpenAPI与MAS系统服务,强大引擎赋能券商多元化发展
  6. 要升级win11吗?电脑变板砖的那种
  7. FL Studio第 24 个年头:Image-Line 升级 FL Studio 21 音乐工作站
  8. HaiBox-E边缘计算盒子怎么样,关于HaiBox-E边缘计算盒子的评析
  9. 深度学习目标检测在游戏领域的应用
  10. 最简单的无线充电传输电路