HEVC參考幀列表管理代碼部分

這篇文章大部分內容轉載於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列表,實現過程詳見程序。



  1. Void TComSlice::setRefPicList( TComList<TComPic*>& rcListPic )  
  2. {  
  3.   if (m_eSliceType == I_SLICE)  
  4.   {//==對於I幀而言,直接返回==//  
  5.     ::memset( m_apcRefPicList, 0, sizeof (m_apcRefPicList));  
  6.     ::memset( m_aiNumRefIdx,   0, sizeof ( m_aiNumRefIdx ));  
  7.       
  8.     return;  
  9.   }  
  10.     
  11.   m_aiNumRefIdx[0] = getNumRefIdx(REF_PIC_LIST_0); //==list0參考圖像數目==//  
  12.   m_aiNumRefIdx[1] = getNumRefIdx(REF_PIC_LIST_1); <span style="font-family: Arial, Helvetica, sans-serif;">//==list0參考圖像數目==//  
  13. </span>  
  14.   TComPic*  pcRefPic= NULL;  
  15.   TComPic*  RefPicSetStCurr0[16];  
  16.   TComPic*  RefPicSetStCurr1[16];  
  17.   TComPic*  RefPicSetLtCurr[16];  
  18.   UInt NumPocStCurr0 = 0;  
  19.   UInt NumPocStCurr1 = 0;  
  20.   UInt NumPocLtCurr = 0;  
  21.   Int i;  
  22.   
  23.   for(i=0; i < m_pcRPS->getNumberOfNegativePictures(); i++)  
  24.   {// 設置short term negative(即前向參考圖像)  
  25.     if(m_pcRPS->getUsed(i))  
  26.     {  
  27.       pcRefPic = xGetRefPic(rcListPic, getPOC()+m_pcRPS->getDeltaPOC(i));  
  28.       pcRefPic->setIsLongTerm(0);  
  29.       pcRefPic->setIsUsedAsLongTerm(0);  
  30.       pcRefPic->getPicYuvRec()->extendPicBorder();  
  31.       RefPicSetStCurr0[NumPocStCurr0 ] = pcRefPic;  
  32.       NumPocStCurr0++;  
  33.       pcRefPic->setCheckLTMSBPresent(false);    
  34.     }  
  35.   }  
  36.   for(; i < m_pcRPS->getNumberOfNegativePictures()+m_pcRPS->getNumberOfPositivePictures(); i++)  
  37.   {// 設置short term positive(即後向參考圖像)  
  38.     if(m_pcRPS->getUsed(i))  
  39.     {  
  40.       pcRefPic = xGetRefPic(rcListPic, getPOC()+m_pcRPS->getDeltaPOC(i));  
  41.       pcRefPic->setIsLongTerm(0);  
  42.       pcRefPic->setIsUsedAsLongTerm(0);  
  43.       pcRefPic->getPicYuvRec()->extendPicBorder();  
  44.       RefPicSetStCurr1[NumPocStCurr1] = pcRefPic;  
  45.       NumPocStCurr1++;  
  46.       pcRefPic->setCheckLTMSBPresent(false);    
  47.     }  
  48.   }  
  49.   for(i = m_pcRPS->getNumberOfNegativePictures()+m_pcRPS->getNumberOfPositivePictures()+m_pcRPS->getNumberOfLongtermPictures()-1; i > m_pcRPS->getNumberOfNegativePictures()+m_pcRPS->getNumberOfPositivePictures()-1 ; i--)  
  50.   {//==設置long term參考圖像==//  
  51.     if(m_pcRPS->getUsed(i))  
  52.     {  
  53.       pcRefPic = xGetLongTermRefPic(rcListPic, m_pcRPS->getPOC(i));  
  54.       pcRefPic->setIsLongTerm(1);  
  55.       pcRefPic->setIsUsedAsLongTerm(1);  
  56.       pcRefPic->getPicYuvRec()->extendPicBorder();  
  57.       RefPicSetLtCurr[NumPocLtCurr] = pcRefPic;  
  58.       NumPocLtCurr++;  
  59.     }  
  60.     if(pcRefPic==NULL)   
  61.     {  
  62.       pcRefPic = xGetLongTermRefPic(rcListPic, m_pcRPS->getPOC(i));  
  63.     }  
  64.     pcRefPic->setCheckLTMSBPresent(m_pcRPS->getCheckLTMSBPresent(i));    
  65.   }  
  66.   // ref_pic_list_init  
  67. #if RPL_INIT_FIX  
  68.   TComPic*  rpsCurrList0[MAX_NUM_REF+1];  
  69.   TComPic*  rpsCurrList1[MAX_NUM_REF+1];  
  70.   Int numPocTotalCurr = NumPocStCurr0 + NumPocStCurr1 + NumPocLtCurr;  
  71.   
  72.   {  
  73.     Int cIdx = 0;  
  74.     for ( i=0; i<NumPocStCurr0; i++, cIdx++)  
  75.     {//==(0<=cIdx<NumPocStCurr0)==//  
  76.       rpsCurrList0[cIdx] = RefPicSetStCurr0[i];  
  77.     }  
  78.     for ( i=0; i<NumPocStCurr1; i++, cIdx++)  
  79.     {//==(NumPocStCurr0<=cIdx<NumPocStCurr1+NumPocStCurr0)==//  
  80.       rpsCurrList0[cIdx] = RefPicSetStCurr1[i];  
  81.     }  
  82.     for ( i=0; i<NumPocLtCurr;  i++, cIdx++)  
  83.     {//==(NumPocStCurr1<=cIdx<numPocTotalCurr)==//  
  84.       rpsCurrList0[cIdx] = RefPicSetLtCurr[i];  
  85.     }  
  86.   }  
  87.   
  88.   if (m_eSliceType==B_SLICE)  
  89.   {  
  90.     Int cIdx = 0;  
  91.     for ( i=0; i<NumPocStCurr1; i++, cIdx++)  
  92.     {//==(0<=cIdx<NumPocStCurr0)==//  
  93.       rpsCurrList1[cIdx] = RefPicSetStCurr1[i];  
  94.     }  
  95.     for ( i=0; i<NumPocStCurr0; i++, cIdx++)  
  96.     {//==(NumPocStCurr0<=cIdx<NumPocStCurr1+NumPocStCurr0)==//  
  97.       rpsCurrList1[cIdx] = RefPicSetStCurr0[i];  
  98.     }  
  99.     for ( i=0; i<NumPocLtCurr;  i++, cIdx++)  
  100.     {//==(NumPocStCurr1+NumPocStCurr0<=cIdx<numPocTotalCurr)==//  
  101.       rpsCurrList1[cIdx] = RefPicSetLtCurr[i];  
  102.     }  
  103.   }  
  104.      
  105.   ///=====Unification of reference picture list modification processes(參考JCTVC-H0138)=====///  
  106.   for (Int rIdx = 0; rIdx <= (m_aiNumRefIdx[0]-1); rIdx ++)  
  107.   {//===修正list0列表===//  
  108.     m_apcRefPicList[0][rIdx] = m_RefPicListModification.getRefPicListModificationFlagL0() ? rpsCurrList0[ m_RefPicListModification.getRefPicSetIdxL0(rIdx) ] : rpsCurrList0[rIdx % numPocTotalCurr];  
  109.   }  
  110.   if ( m_eSliceType == P_SLICE )  
  111.   {//////////////////==若爲P幀,則list1爲零==/////////////////////////////  
  112.     m_aiNumRefIdx[1] = 0;  
  113.     ::memset( m_apcRefPicList[1], 0, sizeof(m_apcRefPicList[1]));  
  114.   }  
  115.   else  
  116.   {//===修正list1列表===//  
  117.     for (Int rIdx = 0; rIdx <= (m_aiNumRefIdx[1]-1); rIdx ++)  
  118.     {  
  119.       m_apcRefPicList[1][rIdx] = m_RefPicListModification.getRefPicListModificationFlagL1() ? rpsCurrList1[ m_RefPicListModification.getRefPicSetIdxL1(rIdx) ] : rpsCurrList1[rIdx % numPocTotalCurr];  
  120.     }  
  121.   }  

而最後一個函數setRefPOCList就是實現將參考圖像轉化成其相應的POC列表。

  1. Void TComSlice::setRefPOCList       ()  
  2. {//===將參考圖像列表轉化成相應的POC===//  
  3.   for (Int iDir = 0; iDir < 2; iDir++)  
  4.   {  
  5.     for (Int iNumRefIdx = 0; iNumRefIdx < m_aiNumRefIdx[iDir]; iNumRefIdx++)  
  6.     {  
  7.       m_aiRefPOCList[iDir][iNumRefIdx] = m_apcRefPicList[iDir][iNumRefIdx]->getPOC();  
  8.     }  
  9.   }  
  10. }  


另外在第二個函數中有涉及到ListModification(列表修正)的問題,由於篇幅有限,將和 List Combination(參考列表聯合)一起留到後續再討論!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章