VVC帧间预测(六)BCW

CU级加权双向预测

Bi-prediction with CU-level weight(BCW)是VVC中的新双向预测技术,在HEVC中进行双向预测时预测值等于前向预测值和后向预测值的均值。BCW不是简单的求均值而是对两个预测值进行加权。

相关定义如下:

const int8_t g_GbiLog2WeightBase = 3;
const int8_t g_GbiWeightBase = (1 << g_GbiLog2WeightBase);
const int8_t g_GbiWeights[GBI_NUM] = { -2, 3, 4, 5, 10 };

int8_t getGbiWeight(uint8_t gbiIdx, uint8_t uhRefFrmList)
{
  // Weghts for the model: P0 + w * (P1 - P0) = (1-w) * P0 + w * P1
  // Retuning  1-w for P0 or w for P1
    //!<对于P0返回8-w,对于P1返回w
  return (uhRefFrmList == REF_PIC_LIST_0 ? g_GbiWeightBase - g_GbiWeights[gbiIdx] : g_GbiWeights[gbiIdx]);
}

对于每个双向预测的CU其权值w由两种方法确定:1)对于non-merge CU,权值索引在MVD后传输;2)对于merge CU,权值索引由基于merge候选项索引的相邻块推断得到。

BCW只对含有256个及更多亮度像素的CU使用(即CU宽乘以CU高大于等于256)。对于low-delay图像,5个权值都可以使用。对于non-low-delay图像,只有3个权值w∈{3,4,5}可以使用。

  • 在编码端可以使用快速搜索算法在不增加编码复杂度的情况下找到权值索引。

  • 当和仿射运动一起使用时,只有当仿射模式是当前CU的最优模式时在进行仿射运动估计时才可以使用不相等的权值。

  • 当两个参考图像相同时,不相等的权值只在某些条件下使用。

  • 在特定条件下不去搜索不相等的权值,这取决于当前图像和它的参考图像的POC距离、QP、时域层。

BCW权值索引使用一个context coded bin和一个bypass coded bin编码。第一个context coded bin表明权值是否相等。如果使用不相等的权值,bypass coded bin表明使用哪一个不相等的权值。

加权预测Weighted prediction (WP)是H.264和HEVC用来提高渐变内容编码效率的工具,VVC也支持WP技术。WP为L0和L1中的每个参考图像传输加权参数(权值和偏置)。WP和BCW用来处理不同类型的视频内容。为了简化VVC解码器的设计,需要避免WP和BCW的交互,如果一个CU使用WP,那么BCW的权值索引就不需要传输默认为4(使用相等权值)。

扫描二维码关注公众号,回复: 8836901 查看本文章

对于使用merge模式的CU,权值索引由基于merge候选项索引的相邻块推断得来。这适用于普通merge模式和仿射merge模式类型1候选项。对于仿射merge模式类型2候选项,其仿射运动信息由至多3个块的运动信息生成,它的BCW索引由下面步骤生成:

1、把BCW索引范围{0,1,2,3,4}分成三组{0},{1,2,3},{4}。如果所有控制点的BCW索引都来自同一组,BCW索引按步骤2生成,否则,BCW索引等于2。

2、如果至少有2个控制点的BCW索引相同则使用该索引,否则,BCW索引等于2。

相关代码如下:

#if JVET_N0481_BCW_CONSTRUCTED_AFFINE 
void PU::getAffineControlPointCand(const PredictionUnit &pu, MotionInfo mi[4], int8_t neighGbi[4], bool isAvailable[4], int verIdx[4], int modelIdx, int verNum, AffineMergeCtx& affMrgType)
#else
void PU::getAffineControlPointCand( const PredictionUnit &pu, MotionInfo mi[4], bool isAvailable[4], int verIdx[4], int modelIdx, int verNum, AffineMergeCtx& affMrgType )
#endif
{
    ......
    #if JVET_N0481_BCW_CONSTRUCTED_AFFINE
    int gbiClass[5] = { -1,0,0,0,1 };  //!<BCW index分为3组
    if (dir == 3)
    {//!<idx0和idx1控制点的BCW索引相同
      if (neighGbi[idx0] == neighGbi[idx1] && gbiClass[neighGbi[idx0]] == gbiClass[neighGbi[idx2]])
      {
        gbiIdx = neighGbi[idx0];
      }//!<idx0和idx2控制点的BCW索引相同
      else if (neighGbi[idx0] == neighGbi[idx2] && gbiClass[neighGbi[idx0]] == gbiClass[neighGbi[idx1]])
      {
        gbiIdx = neighGbi[idx0];

      }//!<idx1和idx2控制点的BCW索引相同
      else if (neighGbi[idx1] == neighGbi[idx2] && gbiClass[neighGbi[idx0]] == gbiClass[neighGbi[idx1]])
      {
        gbiIdx = neighGbi[idx1];
      }
      else
      {
        gbiIdx = GBI_DEFAULT;
      }

    }

#endif
    ......
}

参考

JVET-L0646

JVET-N0481

感兴趣的请关注微信公众号Video Coding

发布了87 篇原创文章 · 获赞 108 · 访问量 25万+

猜你喜欢

转载自blog.csdn.net/Dillon2015/article/details/103875959