HM中参考图像列表的设置

原文地址:http://blog.csdn.net/yangxiao_xiang/article/details/8872173

对于帧间预测而言,一定会涉及到参考图像的问题,但是搞清楚HM中参考图像是如何配置,对理解其编码结构尤为关键。顾名思义,参考图像应该是属于picture级别的,因此可以在compressGOP函数中找到相应的函数。主要包括以下三个函数:

1、arrangeLongtermPicturesInRPS(pcSlice, rcListPic);

2、pcSlice->setRefPicList ( rcListPic );

3、pcSlice->setRefPOCList();

首先说第一个函数,主要是在RPS(Reference Picture Set)句法中设置LongTermPicture,那么什么是LT呢?参考图像主要有以下三种:long-term,short-term before curr和short-term after curr。第一个函数就是用来提供long-term 参考图像的,具体实现可以查看函数,这里不做重点叙述。



重点是第二个函数setRefPicList,上面我们了解到参考图像主要有三种,但是最后参考图像列表中的参考图像是通过下面的方式确定的。那些在参考列表中用到的参考图像,其标志为1,相反,则为0;故setRefPicList函数的实现过程是先通过标志位判断(if(m_pcRPS->getUsed(i)))确定三种参考图像的实际参考帧(如下面第一部分),然后再通过ref_pic_list_init过程,再组成list0和list1列表,实现过程详见程序。


Void TComSlice::setRefPicList( TComList<TComPic*>& rcListPic )
{
  if (m_eSliceType == I_SLICE)
  {//==对于I帧而言,直接返回==//
    ::memset( m_apcRefPicList, 0, sizeof (m_apcRefPicList));
    ::memset( m_aiNumRefIdx,   0, sizeof ( m_aiNumRefIdx ));
    
    return;
  }
  
  m_aiNumRefIdx[0] = getNumRefIdx(REF_PIC_LIST_0); //==list0参考图像数目==//
  m_aiNumRefIdx[1] = getNumRefIdx(REF_PIC_LIST_1); <span style="font-family: Arial, Helvetica, sans-serif;">//==list0参考图像数目==//
</span>
  TComPic*  pcRefPic= NULL;
  TComPic*  RefPicSetStCurr0[16];
  TComPic*  RefPicSetStCurr1[16];
  TComPic*  RefPicSetLtCurr[16];
  UInt NumPocStCurr0 = 0;
  UInt NumPocStCurr1 = 0;
  UInt NumPocLtCurr = 0;
  Int i;

  for(i=0; i < m_pcRPS->getNumberOfNegativePictures(); i++)
  {// 设置short term negative(即前向参考图像)
    if(m_pcRPS->getUsed(i))
    {
      pcRefPic = xGetRefPic(rcListPic, getPOC()+m_pcRPS->getDeltaPOC(i));
      pcRefPic->setIsLongTerm(0);
      pcRefPic->setIsUsedAsLongTerm(0);
      pcRefPic->getPicYuvRec()->extendPicBorder();
      RefPicSetStCurr0[NumPocStCurr0 ] = pcRefPic;
      NumPocStCurr0++;
      pcRefPic->setCheckLTMSBPresent(false);  
    }
  }
  for(; i < m_pcRPS->getNumberOfNegativePictures()+m_pcRPS->getNumberOfPositivePictures(); i++)
  {// 设置short term positive(即后向参考图像)
    if(m_pcRPS->getUsed(i))
    {
      pcRefPic = xGetRefPic(rcListPic, getPOC()+m_pcRPS->getDeltaPOC(i));
      pcRefPic->setIsLongTerm(0);
      pcRefPic->setIsUsedAsLongTerm(0);
      pcRefPic->getPicYuvRec()->extendPicBorder();
      RefPicSetStCurr1[NumPocStCurr1] = pcRefPic;
      NumPocStCurr1++;
      pcRefPic->setCheckLTMSBPresent(false);  
    }
  }
  for(i = m_pcRPS->getNumberOfNegativePictures()+m_pcRPS->getNumberOfPositivePictures()+m_pcRPS->getNumberOfLongtermPictures()-1; i > m_pcRPS->getNumberOfNegativePictures()+m_pcRPS->getNumberOfPositivePictures()-1 ; i--)
  {//==设置long term参考图像==//
    if(m_pcRPS->getUsed(i))
    {
      pcRefPic = xGetLongTermRefPic(rcListPic, m_pcRPS->getPOC(i));
      pcRefPic->setIsLongTerm(1);
      pcRefPic->setIsUsedAsLongTerm(1);
      pcRefPic->getPicYuvRec()->extendPicBorder();
      RefPicSetLtCurr[NumPocLtCurr] = pcRefPic;
      NumPocLtCurr++;
    }
    if(pcRefPic==NULL) 
    {
      pcRefPic = xGetLongTermRefPic(rcListPic, m_pcRPS->getPOC(i));
    }
    pcRefPic->setCheckLTMSBPresent(m_pcRPS->getCheckLTMSBPresent(i));  
  }
  // ref_pic_list_init
#if RPL_INIT_FIX
  TComPic*  rpsCurrList0[MAX_NUM_REF+1];
  TComPic*  rpsCurrList1[MAX_NUM_REF+1];
  Int numPocTotalCurr = NumPocStCurr0 + NumPocStCurr1 + NumPocLtCurr;

  {
    Int cIdx = 0;
    for ( i=0; i<NumPocStCurr0; i++, cIdx++)
    {//==(0<=cIdx<NumPocStCurr0)==//
      rpsCurrList0[cIdx] = RefPicSetStCurr0[i];
    }
    for ( i=0; i<NumPocStCurr1; i++, cIdx++)
    {//==(NumPocStCurr0<=cIdx<NumPocStCurr1+NumPocStCurr0)==//
      rpsCurrList0[cIdx] = RefPicSetStCurr1[i];
    }
    for ( i=0; i<NumPocLtCurr;  i++, cIdx++)
    {//==(NumPocStCurr1<=cIdx<numPocTotalCurr)==//
      rpsCurrList0[cIdx] = RefPicSetLtCurr[i];
    }
  }

  if (m_eSliceType==B_SLICE)
  {
    Int cIdx = 0;
    for ( i=0; i<NumPocStCurr1; i++, cIdx++)
    {//==(0<=cIdx<NumPocStCurr0)==//
      rpsCurrList1[cIdx] = RefPicSetStCurr1[i];
    }
    for ( i=0; i<NumPocStCurr0; i++, cIdx++)
    {//==(NumPocStCurr0<=cIdx<NumPocStCurr1+NumPocStCurr0)==//
      rpsCurrList1[cIdx] = RefPicSetStCurr0[i];
    }
    for ( i=0; i<NumPocLtCurr;  i++, cIdx++)
    {//==(NumPocStCurr1+NumPocStCurr0<=cIdx<numPocTotalCurr)==//
      rpsCurrList1[cIdx] = RefPicSetLtCurr[i];
    }
  }
   
  ///=====Unification of reference picture list modification processes(参考JCTVC-H0138)=====///
  for (Int rIdx = 0; rIdx <= (m_aiNumRefIdx[0]-1); rIdx ++)
  {//===修正list0列表===//
    m_apcRefPicList[0][rIdx] = m_RefPicListModification.getRefPicListModificationFlagL0() ? rpsCurrList0[ m_RefPicListModification.getRefPicSetIdxL0(rIdx) ] : rpsCurrList0[rIdx % numPocTotalCurr];
  }
  if ( m_eSliceType == P_SLICE )
  {//==若为P帧,则list1为零==/
    m_aiNumRefIdx[1] = 0;
    ::memset( m_apcRefPicList[1], 0, sizeof(m_apcRefPicList[1]));
  }
  else
  {//===修正list1列表===//
    for (Int rIdx = 0; rIdx <= (m_aiNumRefIdx[1]-1); rIdx ++)
    {
      m_apcRefPicList[1][rIdx] = m_RefPicListModification.getRefPicListModificationFlagL1() ? rpsCurrList1[ m_RefPicListModification.getRefPicSetIdxL1(rIdx) ] : rpsCurrList1[rIdx % numPocTotalCurr];
    }
  }

而最后一个函数setRefPOCList就是实现将参考图像转化成其相应的POC列表。

Void TComSlice::setRefPOCList       ()
{//===将参考图像列表转化成相应的POC===//
  for (Int iDir = 0; iDir < 2; iDir++)
  {
    for (Int iNumRefIdx = 0; iNumRefIdx < m_aiNumRefIdx[iDir]; iNumRefIdx++)
    {
      m_aiRefPOCList[iDir][iNumRefIdx] = m_apcRefPicList[iDir][iNumRefIdx]->getPOC();
    }
  }
}

另外在第二个函数中有涉及到ListModification(列表修正)的问题,由于篇幅有限,将和 List Combination(参考列表联合)一起留到后续再讨论!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值