• 帧内预测中的initPredIntraParams()函数 (负参考方向处在跑代码时再看一遍)


    帧内预测流程(还有几个小细节)_青椒鸡汤的博客-CSDN博客_帧内预测

    H.266/VVC-VTM代码学习-帧内预测01-初始化帧内预测参数IntraPrediction::initPredIntraParams_liaojq2020的博客-CSDN博客

    H.266/VVC代码学习:帧内预测之初始化帧内预测参数(initPredIntraParams)_涵小呆的博客-CSDN博客 H.266/VVC代码学习:帧内预测之角度预测函数(predIntraAng、xPredIntraAng)_涵小呆的博客-CSDN博客_vvc 帧内预测

    1. // Function for initialization of intra prediction parameters
    2. void IntraPrediction::initPredIntraParams(const PredictionUnit & pu, const CompArea area, const SPS& sps)
    3. {
    4. //当前area的分量
    5. const ComponentID compId = area.compID;
    6. //色度还是亮度
    7. const ChannelType chType = toChannelType(compId);
    8. //是否使用ISP
    9. const bool useISP = NOT_INTRA_SUBPARTITIONS != pu.cu->ispMode && isLuma( chType );
    10. //cu大小
    11. const Size cuSize = Size( pu.cu->blocks[compId].width, pu.cu->blocks[compId].height );
    12. //pu大小
    13. const Size puSize = Size( area.width, area.height );
    14. //块大小,看是否用ISP
    15. const Size& blockSize = useISP ? cuSize : puSize;
    16. //预测模式
    17. const int dirMode = PU::getFinalIntraMode(pu, chType);
    18. //将预测模式转换为宽角度模式
    19. const int predMode = getModifiedWideAngle( blockSize.width, blockSize.height, dirMode );
    20. //模式标号大于34视作垂直类模式
    21. m_ipaParam.isModeVer = predMode >= DIA_IDX;
    22. //获得参考行索引
    23. m_ipaParam.multiRefIndex = isLuma (chType) ? pu.multiRefIdx : 0 ;
    24. //参考像素滤波初始化为否
    25. m_ipaParam.refFilterFlag = false;
    26. //插值初始化为否
    27. m_ipaParam.interpolationFlag = false;
    28. //是否提供PDPC技术(若PU边长均≥4且使用0号参考行则提供PDPC)
    29. m_ipaParam.applyPDPC = (puSize.width >= MIN_TB_SIZEY && puSize.height >= MIN_TB_SIZEY) && m_ipaParam.multiRefIndex == 0;
    30. const int intraPredAngleMode = (m_ipaParam.isModeVer) ? predMode - VER_IDX : -(predMode - HOR_IDX);
    31. int absAng = 0;
    32. //预测模式是角度模式(即模式号大于DC)且模式号小于LUMA模式总数67
    33. if (dirMode > DC_IDX && dirMode < NUM_LUMA_MODE) // intraPredAngle for directional modes
    34. {
    35. static const int angTable[32] = { 0, 1, 2, 3, 4, 6, 8, 10, 12, 14, 16, 18, 20, 23, 26, 29, 32, 35, 39, 45, 51, 57, 64, 73, 86, 102, 128, 171, 256, 341, 512, 1024 };
    36. static const int invAngTable[32] = {
    37. 0, 16384, 8192, 5461, 4096, 2731, 2048, 1638, 1365, 1170, 1024, 910, 819, 712, 630, 565,
    38. 512, 468, 420, 364, 321, 287, 256, 224, 191, 161, 128, 96, 64, 48, 32, 16
    39. }; // (512 * 32) / Angle
    40. //模式偏离水平或垂直的值(取绝对值),值范围为0~32
    41. const int absAngMode = abs(intraPredAngleMode);
    42. //模式19~49(模式号大于水平,小于垂直)为-1,其他为1
    43. const int signAng = intraPredAngleMode < 0 ? -1 : 1;
    44. //角度模式对应偏移值offset
    45. absAng = angTable [absAngMode];
    46. // 每种角度对应的投影位置
    47. m_ipaParam.absInvAngle = invAngTable[absAngMode];
    48. //角度偏移值,带正负号
    49. m_ipaParam.intraPredAngle = signAng * absAng;
    50. if (intraPredAngleMode < 0)
    51. {
    52. //模式19~49不用PDPC
    53. m_ipaParam.applyPDPC = false;
    54. }
    55. else if (intraPredAngleMode > 0)
    56. {
    57. //根据预测模式对应侧的长度
    58. const int sideSize = m_ipaParam.isModeVer ? puSize.height : puSize.width;
    59. //缩放的设置
    60. const int maxScale = 2;
    61. m_ipaParam.angularScale = std::min(maxScale, floorLog2(sideSize) - (floorLog2(3 * m_ipaParam.absInvAngle - 2) - 8));
    62. m_ipaParam.applyPDPC &= m_ipaParam.angularScale >= 0;
    63. }
    64. }

    predmode:为宽角度模式下当前预测模式的序号。款角度预测模式范围是-14~80

    如图,模式2 ~ 66表示传统的帧内预测模式,模式 -1 ~ -14以及模式67 ~ 80表示宽角度预测模式。 

    intraPredAngle变量指代的是角度偏移值,,即每一种角度模式都相当于在水平方向或者垂直方向上做了一个角度偏移,从角度模式到偏移值的映射如下表所示:

     absInvAngle变量表示反角度参数,具体地计算为

    在VTM中为了消除除法运算,预先将(512 * 32) /Angle的值存了起来,存在了invAngTable表中。
     

    intraPredAngleMode :先判断当前模式是垂直还是水平然后再根据情况得出值。注意:因为这里将宽角度预测模式也算入,所以范围是-16~32。这个参数在后面通过计算可以查表得出当前模式的偏移值和范角度参数

    angTable[32]:这个表里存的是各个角度模式对应的偏移值

    invAngTable[32]:这个表里存的是反角度对应的偏移值。目的是避免在运行时的除法运算,预先存入结果。举例,角度模式32的偏移值是-26,512*32/26再求绝对值等于565(上取整).与参考像素的投影有关

    举几个例子

    几个角度模式偏移值的计算
    23780
    predMode23780
    intraPredAngleMode16-1330
    absAngMode161330
    signAng1-11
    absAng3223512
    absInvAngle51271232
    intraPredAngle32-23512

    这里参考之前写的博客,中的参考像素投影,负角度方向的投影。代码跑这里时详细看一遍

    angularScale:角度缩放的设置,之后再看

    1. /********************判断是否对参考像素进行滤波**********************/
    2. // high level conditions and DC intra prediction
    3. //SPS标识不进行参考像素滤波
    4. //不是亮度分量
    5. //使用ISP
    6. //PU块用了MIP
    7. //多参考行
    8. //DC模式
    9. if( sps.getSpsRangeExtension().getIntraSmoothingDisabledFlag()
    10. || !isLuma( chType )
    11. || useISP
    12. || PU::isMIP( pu, chType )
    13. || m_ipaParam.multiRefIndex
    14. || DC_IDX == dirMode
    15. )
    16. {
    17. }
    18. ***不滤波***
    19. //如果当前块是亮度同时为BDPCM模式
    20. //色度BDPCM模式
    21. else if ((isLuma(chType) && pu.cu->bdpcmMode) || (!isLuma(chType) && pu.cu->bdpcmModeChroma)) // BDPCM
    22. {
    23. m_ipaParam.refFilterFlag = false;
    24. }
    25. //planar模式
    26. //pu的宽*高大于32就滤波
    27. else if (dirMode == PLANAR_IDX) // Planar intra prediction
    28. {
    29. m_ipaParam.refFilterFlag = puSize.width * puSize.height > 32 ? true : false;
    30. }
    31. //不用ISP
    32. else if (!useISP)// HOR, VER and angular modes (MDIS)
    33. {
    34. bool filterFlag = false;
    35. {
    36. //与水平模式或垂直模式的模式标号差
    37. const int diff = std::min<int>( abs( predMode - HOR_IDX ), abs( predMode - VER_IDX ) );
    38. //log2(width)和log2(height)的均值
    39. const int log2Size = ((floorLog2(puSize.width) + floorLog2(puSize.height)) >> 1);
    40. CHECK( log2Size >= MAX_INTRA_FILTER_DEPTHS, "Size not supported" );
    41. //与水平模式或垂直模式的模式标号差是否大于log2(width)和log2(height)的均值对应的值
    42. //log2(width)和log2(height)的均值 对应值
    43. // 0 24
    44. // 1 24
    45. // 2 24
    46. // 3 14
    47. // 4 2
    48. // 5 0
    49. // 6 0
    50. // 7 0
    51. filterFlag = (diff > m_aucIntraFilter[log2Size]);
    52. }
    53. // Selelection of either ([1 2 1] / 4 ) refrence filter OR Gaussian 4-tap interpolation filter
    54. if (filterFlag)
    55. {
    56. //return (0 == (absAng & 0x1F)),即是否为32的整数倍
    57. const bool isRefFilter = isIntegerSlope(absAng);
    58. CHECK( puSize.width * puSize.height <= 32, "DCT-IF interpolation filter is always used for 4x4, 4x8, and 8x4 luma CB" );
    59. m_ipaParam.refFilterFlag = isRefFilter;
    60. m_ipaParam.interpolationFlag = !isRefFilter;
    61. }
    62. }
    63. }

    diff :当前块宽角度模式下的模式号与水平,垂直模式号的差取绝对值,然后较小值

    m_aucIntraFilter[]:下标从0开始,比如log2Size=6时,对应0

    log2(width)和log2(height)的均值对应值
    024
    124
    224
    314
    42
    50
    60
    70

     const bool isRefFilter  =  isIntegerSlope(absAng):这里推测是特定预测模式才参考像素滤波。角度偏移值为32的整数倍,才进行参考像素滤波。

    这里可参考HEVC的滤波条件,之后再看VVC的标准

  • 相关阅读:
    Spring Security 中,想在权限中使用通配符,怎么做?
    【适合所有群体】云原生从入门到精通(GO、Docker、K8S、微服务)【只此一文,踏入山巅】(持续更新,预计2022年7月底完结)
    Transformer/Bert
    CSS的概念和基本用法
    分享几个查看操作系统版本信息的方法
    Vue事件处理器:事件绑定基础、事件修饰符:stop、prevent、capture、self、once;
    CentOS 7.6环境下Nginx1.23.3下载安装配置使用教程
    CSS媒体查询-物理像素-逻辑像素
    go实战学习——context包学习理解笔记
    Java 字节流写数据如何实现换行,以及如何追加填写数据
  • 原文地址:https://blog.csdn.net/dfhg54/article/details/125514712