H.266/VVC代码学习:DC模式和Planar模式

本文深入探讨了视频编码中两种特殊角度模式:DC模式和Planar模式。DC模式适用于大面积平坦区域,通过计算左右及上方参考像素平均值进行预测。Planar模式则适用于像素值缓慢变化的区域,通过复杂的加权平均计算预测值。文章详细解析了两种模式的计算方法及代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Planar模式和DC模式时两种特殊的角度模式,分别对应于模式号0和1。

一、DC模式

DC模式适用于大面积平坦区域,其预测值是通过计算左边和(或)上边参考像素的平均值获得的。

1.1、计算

DC模式预测值的计算和块的形状有关:

  • 当宽等于高时,用左侧参考像素和上边参考像素的平均值作为预测值填充整个块
  • 当宽大于高时,用上边参考像素的平均值作为预测值填充整个块
  • 当宽小于高时,用左侧参考像素的平均值作为预测值填充整个块

1.2、代码

xPredIntraDc函数是DC模式的入口函数,主要功能是调用xGetPredValDc函数生成DC值,然后将DC值填充整个块

void IntraPrediction::xPredIntraDc( const CPelBuf &pSrc, PelBuf &pDst, const ChannelType channelType, const bool enableBoundaryFilter )
{
  //DC模式适用于大面积平坦区域,其预测值由其左侧和(或)上侧参考像素值得到。
  const Pel dcval = xGetPredValDc( pSrc, pDst );//生成DC值
  pDst.fill( dcval );//填充
}

xGetPredValDc函数用来生成DC值

// Function for calculating DC value of the reference samples used in Intra prediction
//NOTE: Bit-Limit - 25-bit source
Pel IntraPrediction::xGetPredValDc( const CPelBuf &pSrc, const Size &dstSize )
{
  CHECK( dstSize.width == 0 || dstSize.height == 0, "Empty area provided" );

  int idx, sum = 0;
  Pel dcVal;
  const int width  = dstSize.width;
  const int height = dstSize.height;
  const auto denom     = (width == height) ? (width << 1) : std::max(width,height);
  const auto divShift  = floorLog2(denom);
  const auto divOffset = (denom >> 1);

  if ( width >= height )//宽大于高时,只用预测像素宽的平均值
  {
    for( idx = 0; idx < width; idx++ )
    {
      sum += pSrc.at(m_ipaParam.multiRefIndex + 1 + idx, 0);
    }
  }
  if ( width <= height )//宽小于高时,只用预测像素高的平均值
  {
    for( idx = 0; idx < height; idx++ )
    {
      sum += pSrc.at(m_ipaParam.multiRefIndex + 1 + idx, 1);
    }
  }

  dcVal = (sum + divOffset) >> divShift;//四舍五入求平均值
  return dcVal;
}

二、Planar模式

Planar模式适用于像素渐变的情况,即适用于像素值缓慢变换的区域。

2.1、计算

计算方法:根据a,b,c,d求加权平均,权重与距离有关;

具体计算公式如下:

横向预测值为 pred_h(x,y) = (width-x-1)*b + (x+1)*a

纵向预测值为 pred_v(x,y) = (height-y-1)*d + (y+1)*c

最终预测值为 pred(x,y) = (pred_h(x,y) + pred_v(x,y) + offset) >> shift

其中,x=0,1···width-1;y=0,1···height-1

2.2、代码

/** Function for deriving planar intra prediction. This function derives the prediction samples for planar mode (intra coding).
 */

//NOTE: Bit-Limit - 24-bit source
void IntraPrediction::xPredIntraPlanar( const CPelBuf &pSrc, PelBuf &pDst )
{
  const uint32_t width  = pDst.width;
  const uint32_t height = pDst.height;

#if JVET_P0329_PLANAR_SIMPLIFICATION
  const uint32_t log2W = floorLog2( width );
  const uint32_t log2H = floorLog2( height );
#else
  const uint32_t log2W  = floorLog2(width  < 2 ? 2 : width);
  const uint32_t log2H  = floorLog2(height < 2 ? 2 : height);
#endif

  int leftColumn[MAX_CU_SIZE + 1], topRow[MAX_CU_SIZE + 1], bottomRow[MAX_CU_SIZE], rightColumn[MAX_CU_SIZE];
  const uint32_t offset = 1 << (log2W + log2H);//后面用于四舍五入

  // Get left and above reference column and row
  // 获得参考像素
  for( int k = 0; k < width + 1; k++ )
  {
    topRow[k] = pSrc.at( k + 1, 0 );//获取上一行的像素值
  }

  for( int k = 0; k < height + 1; k++ )
  {
    leftColumn[k] = pSrc.at(k + 1, 1);//获取左一列的像素值
  }
  /**
  * Planar模式横向的预测值为 pred_h(x,y) = (width-x-1)*leftcolumn(y) + (x+1)*topRight
  * Planar模式纵向的预测值为 pred_v(x,y) = (height-y-1)*topRow(x) + (y+1)*bottomLeft
  * 最终预测值为:pred(x,y) = (pred_h + pred_v + offset) >> shift
  *
  * 代码里将上式调整为:pred_h(x,y) = width*leftcolumn(y) + (x+1)*[topRight-leftcolumn(y)]
  *                     pred_v(x,y) = height*topRow(x) + (y+1)*[bottomLeft-topRow(x)]
  **/

  // Prepare intermediate variables used in interpolation
  // 准备用于插值的中间变量
  int bottomLeft = leftColumn[height];//左边界下一个
  int topRight = topRow[width];//上边界右一位
  //填充四个边缘的值
  for( int k = 0; k < width; k++ )
  {
    bottomRow[k] = bottomLeft - topRow[k];
    topRow[k]    = topRow[k] << log2H;//实现height*topRow(x) 
  }

  for( int k = 0; k < height; k++ )
  {
    rightColumn[k] = topRight - leftColumn[k];
    leftColumn[k]  = leftColumn[k] << log2W;//实现width*leftcolumn(y)
  }
  //填充Planar模式CU内部的像素值
  const uint32_t finalShift = 1 + log2W + log2H;
  const uint32_t stride     = pDst.stride;
  Pel*       pred       = pDst.buf;//预测像素的首地址

  for( int y = 0; y < height; y++, pred += stride )
  {
    int horPred = leftColumn[y];//水平方向预测值

    for( int x = 0; x < width; x++ )
    {
      horPred += rightColumn[y];//累加,通过循环实现(x+1)*[topRight-leftcolumn(y)]
      topRow[x] += bottomRow[x];//累加,通过循环实现(y+1)*[bottomLeft-topRow(x)]

      int vertPred = topRow[x];//垂直方向预测值
      //水平方向预测像素的权重和高度有关,垂直方向的预测像素的权重和宽度有关
      pred[x]      = ( ( horPred << log2H ) + ( vertPred << log2W ) + offset ) >> finalShift;//加权后求平均值,获得最终预测像素
    }
  }
}

 

<think>嗯,用户问的是视频编码中的MPM是什么意思。首先,我需要确认MPM的全称。在视频编码领域,MPM通常代表“Most Probable Mode”,也就是最可能模式。这个术语常见于像H.265/HEVCH.266/VVC这样的编码标准中,特别是在帧内预测的部分。 接下来,我需要回忆一下帧内预测的基本概念。帧内预测是利用当前块周围已编码的相邻块的信息来预测当前块的像素值,从而减少需要编码的数据量。MPM的作用应该是在这里优化预测模式的选择,提高编码效率。 然后,具体到MPM的工作机制。在HEVC中,当对一个CU(编码单元)进行帧内预测时,编码器会先根据左侧上方的相邻块的预测模式,生成一个MPM列表。这个列表通常包含3到6个最可能的模式,这样编码器只需要在这个列表中选择模式,而不是遍历所有可能的模式,从而减少计算量编码比特数。例如,H.265中可能有3个MPM候选,而H.266/VVC可能增加到6个,以支持更复杂的预测需求。 另外,我需要考虑用户可能的背景。他们可能对视频编码有一定了解,但需要明确MPM的具体应用优势。可能需要解释为什么MPM能提高效率,比如减少模式决策的复杂度,加快编码速度,同时保持压缩效率。 还要注意引用相关的标准或文档,比如HEVC或VVC的标准文档,或者引用用户提供的参考资料。比如用户提供的引用[2]中提到CTB大小不变,需要IDR图片来刷新缓冲,这可能编码过程中的参数变化有关,虽然MPM不直接相关,但可以注意是否有间接联系。 最后,生成相关问题时要覆盖MPM的作用、在不同标准中的差异、对编码效率的影响,以及与帧间预测的区别等方面。这样用户可以通过这些问题进一步深入了解MPM的相关知识。</think>### 视频编码中MPM的含义解析 在视频编码技术中,**MPM(Most Probable Mode,最可能模式)** 是帧内预测(Intra Prediction)的关键优化机制,主要用于高效选择最佳预测模式。其核心作用是通过减少候选模式数量来提升编码效率[^1]。 #### 1. MPM的定义与作用 - **基本原理**:MPM基于相邻块的预测模式相关性,构建候选模式列表(通常包含3-6个模式)。例如,在H.265/HEVC中,MPM列表包含3种候选模式;而H.266/VVC扩展至6种以适应更复杂的预测需求。 - **数学表达**:若相邻块A(左)B(上)的预测模式分别为$M_A$$M_B$,MPM候选列表可能包含$M_A$、$M_B$及其衍生模式,如平面模式Planar)或DC模式。 - **编码优化**:通过仅比较候选列表中的模式,编码器可将模式决策复杂度从全模式遍历(如H.264的9种)降低到对数级别,同时维持压缩率[^2]。 #### 2. 技术实现示例 在HEVC标准中,MPM列表生成规则如下: 1. 若$M_A = M_B$,则列表包含$M_A$、平面模式DC模式 2. 若$M_A \neq M_B$,列表包含$M_A$、$M_B$及第三种通过角度推导的模式 #### 3. 与编码流程的关联 MPM机制与编码单元(CTU)划分密切相关。如引用[2]所述,CTB(Coding Tree Block)尺寸的稳定性保证了MPM推导的可靠性。当CTB尺寸需要变更时,需通过SPS(序列参数集)更新IDR(即时解码刷新)实现,这与MPM的上下文依赖特性一致。 ```text 典型MPM工作流程: 1. 获取相邻块预测模式 2. 生成MPM候选列表 3. 计算各候选模式率失真代价 4. 选择最优模式进行编码 ```
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值