H266/VVC 帧内预测 PDPC 技术

ops/2025/1/15 20:21:49/

PDPC_0">位置决定的帧内预测组合 PDPC

  1. VVC 中,对于帧内预测的 Planar 模式、DC 模式和几种角度模式需要使用 PDPC (position dependent intra prediction combination) 方法进一步处理。 PDPC 用于 DC 模式、Planar 模式、小于等于水平模式(模式 18) 的角度模式、大于等于垂直模式(模式 50)且小于等于模式 80 的角度模式,即对模式 19~49 之间的角度模式不使用 PDPC 技术。如果当前块是 Bdpcm 模式或 MRL 索引大于 0,则不使用 PDPC

  2. 预测值是由参考像素和预测值再次加权求得;其中wL,wT是它们各自对应的基于水平或竖直距离的权重,如下公式:
    p r e d ( x , , y , ) = C l i p ( 0 , ( 1 < < B i t D e p t h ) − 1 , ( w L . R − 1 , y + w T . R x , − 1 + ( 64 − w L − w T ) . p r e d ( x , , y , ) + 32 ) > > 6 ) pred(x^,,y^,) = Clip(0, (1<<BitDepth)-1, (wL.R_{-1,y} + wT.R_{x,-1} + (64-wL-wT).pred(x^,,y^,)+32)>>6) pred(x,,y,)=Clip(0,(1<<BitDepth)1,(wL.R1,y+wT.Rx,1+(64wLwT).pred(x,,y,)+32)>>6)

  3. 如果 PDPC 用于 Planar、DC、水平、垂直模式则不需要额外的边界滤波。对于 Planar 和 DC 模式的 PDPC 操作是相同的。对于角度模式,如果是 HOR_IDX 或 VER_IDX 则左侧或上方的参考像素不会被使用。PDPC 的权值和缩放因子取决 于预测模式和块尺寸。只有块的宽和高都大于等于 4 时才可以使用 PDPC

  4. 图 6 是各种预测模式时 PDPC 参考像素定义( Rx,−1 和 R−1,y )。预测值 pred (x’, y’)坐标为 (x’, y’)。对于对角线模式(模式 2 和模式 66),参考像素 Rx,−1 的坐标 x 为 x = x’ + y’ + 1, 参考像素 R−1,y 的坐标 y 为 y = x’ + y’ + 1。对于其他角度模式 Rx,−1 和 R−1,y 可能落地非整数像素位置,此时使用距其最近的整数像素值作为参考。
    在这里插入图片描述

  5. 修正权重wL,wT 的计算根据不同的模式有不同的计算方法,具体可以根据下表查找。这也可以从 VVenC 编码器源码中找到对应的实现,逻辑相对比较简单。
    在这里插入图片描述

    • 偏移量 scale 的计算:
      • 如果角度模式50~66时,scale = Min( 2, Log2( nTbH ) − Floor( Log2( 3 * invAngle − 2 ) ) + 8 )
      • 如果角度模式为2~18时,scale = Min( 2, Log2( nTbW ) − Floor( Log2( 3 * invAngle − 2 ) ) + 8 )
      • 否则,scale = ( ( Log2( nTbW ) + Log2( nTbH ) − 2 ) >> 2 )
  6. VVenC 编码器中是否使用 PDPC 技术在 IntraPrediction.cpp 文件中 initPredIntraParams 函数判断。
    在这里插入图片描述

// Function for initialization of intra prediction parameters
void IntraPrediction::initPredIntraParams(const CodingUnit& cu, const CompArea area, const SPS& sps)
{const ComponentID compId = area.compID;const ChannelType chType = toChannelType(compId);const bool        useISP = NOT_INTRA_SUBPARTITIONS != cu.ispMode && isLuma( chType );const Size   cuSize    = Size( cu.blocks[compId].width, cu.blocks[compId].height );const Size   puSize    = Size( area.width, area.height );const Size&  blockSize = useISP ? cuSize : puSize;const int      dirMode = CU::getFinalIntraMode(cu, chType);const int     predMode = getWideAngle( blockSize.width, blockSize.height, dirMode );m_ipaParam.isModeVer            = predMode >= DIA_IDX;m_ipaParam.multiRefIndex        = isLuma (chType) ? cu.multiRefIdx : 0 ;m_ipaParam.refFilterFlag        = false;m_ipaParam.interpolationFlag    = false;m_ipaParam.applyPDPC            = (puSize.width >= MIN_TB_SIZEY && puSize.height >= MIN_TB_SIZEY) && m_ipaParam.multiRefIndex == 0;const int    intraPredAngleMode = (m_ipaParam.isModeVer) ? predMode - VER_IDX : -(predMode - HOR_IDX);int absAng = 0;if (dirMode > DC_IDX && dirMode < NUM_LUMA_MODE) // intraPredAngle for directional modes{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 };static const int invAngTable[32] = {0,   16384, 8192, 5461, 4096, 2731, 2048, 1638, 1365, 1170, 1024, 910, 819, 712, 630, 565,512, 468,   420,  364,  321,  287,  256,  224,  191,  161,  128,  96,  64,  48,  32,  16};   // (512 * 32) / Angleconst int     absAngMode         = abs(intraPredAngleMode);const int     signAng            = intraPredAngleMode < 0 ? -1 : 1;absAng             = angTable  [absAngMode];m_ipaParam.absInvAngle           = invAngTable[absAngMode];m_ipaParam.intraPredAngle        = signAng * absAng;if (intraPredAngleMode < 0){m_ipaParam.applyPDPC = false;}else if (intraPredAngleMode > 0){const int sideSize = m_ipaParam.isModeVer ? puSize.height : puSize.width;const int maxScale = 2;m_ipaParam.angularScale = std::min(maxScale, floorLog2(sideSize) - (floorLog2(3 * m_ipaParam.absInvAngle - 2) - 8));m_ipaParam.applyPDPC &= m_ipaParam.angularScale >= 0;}}// high level conditions and DC intra predictionif( !isLuma( chType )|| useISP|| CU::isMIP( cu, chType ) //th remove this|| m_ipaParam.multiRefIndex|| DC_IDX == dirMode){}else if (cu.bdpcmM[chType]){m_ipaParam.refFilterFlag = false;}else if (dirMode == PLANAR_IDX) // Planar intra prediction{m_ipaParam.refFilterFlag = puSize.width * puSize.height > 32 ? true : false;}else if (!useISP)// HOR, VER and angular modes (MDIS){bool filterFlag = false;{const int diff = std::min<int>( abs( predMode - HOR_IDX ), abs( predMode - VER_IDX ) );const int log2Size = (Log2(puSize.width * puSize.height) >> 1);CHECK( log2Size >= MAX_INTRA_FILTER_DEPTHS, "Size not supported" );filterFlag = (diff > m_aucIntraFilter[log2Size]);}// Selelection of either ([1 2 1] / 4 ) refrence filter OR Gaussian 4-tap interpolation filterif (filterFlag){const bool isRefFilter       =  isIntegerSlope(absAng);CHECK( puSize.width * puSize.height <= 32, "DCT-IF interpolation filter is always used for 4x4, 4x8, and 8x4 luma CB" );m_ipaParam.refFilterFlag     =  isRefFilter;m_ipaParam.interpolationFlag = !isRefFilter;}}
}
  1. DC、Planar 模式的 PDPC 处理在 IntraPrediction.cpp 文件中 IntraPredSampleFilter_Core函数中完成。
    在这里插入图片描述
void  IntraPredSampleFilter_Core(PelBuf& dstBuf, const CPelBuf& pSrc)
{const int iWidth  = dstBuf.width;const int iHeight = dstBuf.height;const int scale = ((Log2(iWidth*iHeight) - 2) >> 2);CHECK(scale < 0 || scale > 31, "PDPC: scale < 0 || scale > 31");for (int y = 0; y < iHeight; y++){const int wT   = 32 >> std::min(31, ((y << 1) >> scale));const Pel left = pSrc.at(y + 1, 1);for (int x = 0; x < iWidth; x++){const int wL    = 32 >> std::min(31, ((x << 1) >> scale));const Pel top   = pSrc.at(x + 1, 0);const Pel val   = dstBuf.at(x, y);dstBuf.at(x, y) = val + ((wL * (left - val) + wT * (top - val) + 32) >> 6);}}
}
  1. 水平、垂直模式的 PDPC 处理在 IntraPrediction.cpp 文件中 IntraHorVerPDPC_Core函数中完成。
    在这里插入图片描述
void IntraHorVerPDPC_Core(Pel* pDsty,const int dstStride,Pel* refSide,const int width,const int height,int scale,const Pel* refMain, const ClpRng& clpRng)
{const Pel topLeft = refMain[0];for( int y = 0; y < height; y++ ){memcpy(pDsty,&refMain[1],width*sizeof(Pel));const Pel left    = refSide[1 + y];for (int x = 0; x < std::min(3 << scale, width); x++){const int wL  = 32 >> (2 * x >> scale);const Pel val = pDsty[x];pDsty[x]      = ClipPel(val + ((wL * (left - topLeft) + 32) >> 6), clpRng);}pDsty += dstStride;}
}
  1. 其他角度模式(2~17、51~66)的 PDPC 处理在 IntraPrediction.cpp 文件中 IntraAnglePDPC_Core函数中完成。
    在这里插入图片描述
void IntraAnglePDPC_Core(Pel* pDsty,const int dstStride,Pel* refSide,const int width,const int height,int scale,int invAngle)
{for (int y = 0; y<height; y++, pDsty += dstStride){int       invAngleSum = 256;for (int x = 0; x < std::min(3 << scale, width); x++){invAngleSum += invAngle;int wL   = 32 >> (2 * x >> scale);Pel left = refSide[y + (invAngleSum >> 9) + 1];pDsty[x] = pDsty[x] + ((wL * (left - pDsty[x]) + 32) >> 6);}}
}

http://www.ppmy.cn/ops/149014.html

相关文章

OA系统如何做好DDOS防护

OA系统如何做好DDOS防护&#xff1f;在数字化办公蔚然成风的当下&#xff0c;OA&#xff08;办公自动化&#xff09;系统作为企业内部管理与协作的神经中枢&#xff0c;其安全性和稳定性直接关系到企业的日常运营效率、信息流通效率以及长远发展。OA系统不仅承载着企业内部的日…

Swift语言的学习路线

Swift语言学习路线 Swift是一种由苹果公司开发的编程语言&#xff0c;主要用于开发iOS、macOS、watchOS以及tvOS的应用程序。自2014年发布以来&#xff0c;Swift以其简洁、易读和安全的特性&#xff0c;逐渐成为了移动开发和软件开发领域的重要语言。对于初学者来说&#xff0…

ip属地什么条件会改变?多角度深入探讨

IP属地&#xff0c;即IP地址的归属地&#xff0c;是互联网上设备连接时的一个关键信息&#xff0c;它通常反映了设备连接互联网时的地理位置。随着社交软件及各大平台推出IP归属地显示功能&#xff0c;IP属地的变化问题逐渐受到广大用户的关注。那么&#xff0c;IP属地在什么条…

Branch-Solve-Merge Improves Large Language Model Evaluation and Generation

题目 分支-求解-合并改进了大型语言模型的评估和生成 摘要 大型语言模型(LLM)经常用于多方面的语言生成和评估任务&#xff0c;这些任务涉及满足复杂的用户约束或考虑多个方面和标准。然而&#xff0c;由于模型缺乏一致性&#xff0c;无法计划和分解问题&#xff0c;他们的表现…

15.3 hana 修改 tenantDB中system用户的密码

1 登录systemDB查DB状态 SELECT * FROM M_DATABASES 2 systemDB中停<

Maven 构建:如何使用 maven-resources-plugin 处理资源文件

在 Java 项目的构建过程中&#xff0c;资源文件的管理是一个非常重要的环节。Maven 作为广泛使用的构建工具&#xff0c;提供了强大的插件系统&#xff0c;帮助开发者在构建时管理各种资源文件。而在这其中&#xff0c;maven-resources-plugin 插件扮演了至关重要的角色。 本文…

『SQLite』常见数据类型(动态类型系统)

通常大部分 SQL 数据库引擎都是使用静态的严格的类型&#xff0c;其值的数据类型由容器&#xff08;存储值的特定列&#xff09;来决定&#xff1b;而 SQLite 使用一个更普遍的动态类型系统。在 SQLite 中&#xff0c;值的数据类型与值本身是相关的&#xff0c;而不是与它的容器…

深入Android架构(从线程到AIDL)_12 Android UI 单线程程序

目录 6、 Android UI 单线程程序 單線程程序概念 单线程可避免线程安全问题 SurfaceView与非UI线程 6、 Android UI 单线程程序 單線程程序概念 单线程程序意谓着两个(或多个)线程不能共享对象或变量值。Android的UI是单线程程序的环境。UI控件(如Button等)都是由UI线程所…