DMVR的相關整理

DMVR(decode MV refinement)解碼端MV細化。

顧名思義,就是將MV在解碼端做一個細化操作,那麼相應的,就可以不在編碼端做過多的搜索細化等操作。好處是可以減小傳輸的碼率,縮短編碼時間。爲了保證質量,將細化的任務放在解碼端,雖然增加了一部分解碼時間,但在一定條件下,可以將增加的解碼時間減小到最少。


以上便是DMVR的思想:分爲兩步,第一步:構造template;第二步:搜索最匹配的塊。

代碼中的實現邏輯:

主要由幾個函數構成:

 Void xBIPMVRefine(TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefPicList, Int iWidth, Int iHeight, TComYuv* pOrgYuv, TComYuv* pDstYuv, UInt uiMaxSearchRounds, UInt nSearchStepShift, UInt& uiMinCost);
  UInt xDirectMCCost(Int iBitDepth, Pel* pRef, UInt uiRefStride, Pel* pOrg, UInt uiOrgStride, Int iWidth, Int iHeight);
  Void xPredInterLines(TComDataCU *cu, TComPicYuv *refPic, UInt partAddr, TComMv *mv, Int width, Int height, Pel* dstPix, Int dstStride, Bool bi, const Int bitDepth);
  Void xFillPredBorder(TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefPicList, Int iWidth, Int iHeight, TComYuv* pDstYuv);
#if HIS_DMVR_HALF_ME
  Void xGenerateFracPixel(TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefPicList, Int iWidth, Int iHeight, UInt nSearchStepShift);
#endif
#endif
  Void xWeightedAverage         ( TComYuv* pcYuvSrc0, TComYuv* pcYuvSrc1, Int iRefIdx0, Int iRefIdx1, UInt uiPartAddr, Int iWidth, Int iHeight, TComYuv* pcYuvDst, const BitDepths &clipBitDepths  
#if HIS_DMVR    
    , Bool bRefineflag
#endif
#if VCEG_AZ05_BIO                  
    , Bool bBIOapplied 
#endif
#if COM16_C1045_BIO_HARMO_IMPROV || JVET_C0027_BIO
    , TComDataCU * pCu
#endif
#if HIS_DMVR
    , Bool bOBMC
#endif
    );



Void TComPrediction::xWeightedAverage( TComYuv* pcYuvSrc0, TComYuv* pcYuvSrc1, Int iRefIdx0, Int iRefIdx1, UInt uiPartIdx, Int iWidth, Int iHeight, TComYuv* pcYuvDst, const BitDepths &clipBitDepths
#if HIS_DMVR						  // src0和src1分別是兩個參考圖像,			後面idx是倆圖像序號,		  然後是當前塊的idx	然後是塊大小				這個是生成的預測塊
,Bool bRefineflag
#endif
#if VCEG_AZ05_BIO                  
  ,bool bBIOapplied
#endif
#if COM16_C1045_BIO_HARMO_IMPROV || JVET_C0027_BIO
  , TComDataCU * pCu
#endif
#if HIS_DMVR
  , Bool bOBMC
#endif
)
{
  if( iRefIdx0 >= 0 && iRefIdx1 >= 0 )
  {
#if HIS_DMVR
Int iPOC0=pCu->getSlice()->getRefPOC(REF_PIC_LIST_0, iRefIdx0);
Int iPOC1=pCu->getSlice()->getRefPOC(REF_PIC_LIST_1, iRefIdx1);
Int iPOC = pCu->getSlice()->getPOC();
Bool bBIPMVRefine = !bOBMC && (iPOC - iPOC0)*(iPOC - iPOC1) < 0 && pCu->getMergeFlag(uiPartIdx) && !pCu->getICFlag(uiPartIdx) && !pCu->getAffineFlag(uiPartIdx) && bRefineflag;
bBIPMVRefine &= pCu->getMergeType(uiPartIdx) == MGR_TYPE_DEFAULT_N;
bBIPMVRefine &= !pCu->getFRUCMgrMode(uiPartIdx);
if (bBIPMVRefine )
{
pcYuvDst->addAvg( pcYuvSrc0, pcYuvSrc1, uiPartIdx, iWidth, iHeight, clipBitDepths, false, true );//對預測塊進行加權,形成template

//list 0
//get init cost
pcYuvSrc0->toLast(uiPartIdx, iWidth, iHeight, clipBitDepths);//???幹啥的?放大了像素值,就沒了?
UInt uiMinCost = xDirectMCCost(pCu->getSlice()->getSPS()->getBitDepth( CHANNEL_TYPE_LUMA ), pcYuvDst->getAddr( COMPONENT_Y , uiPartIdx ) , pcYuvDst->getStride( COMPONENT_Y ) , pcYuvSrc0->getAddr( COMPONENT_Y , uiPartIdx ) , pcYuvSrc0->getStride( COMPONENT_Y ) , iWidth , iHeight);
								//這個cost算的是初始代價,就是加權後的template和src0中MV對應圖像的cost。
//generate/interpolate extended pred with integer pixel interval
pcYuvSrc0->copyToPartXYComponent(COMPONENT_Y, uiPartIdx, &m_cYuvPredTemp, HIS_DMVR_INTME_RANGE, HIS_DMVR_INTME_RANGE, iWidth, iHeight);
xFillPredBorder(pCu, uiPartIdx, REF_PIC_LIST_0, iWidth, iHeight, &m_cYuvPredTemp); 

//mv refinement//然後遍歷周圍8處的cost,確定最小的cost。
xBIPMVRefine(pCu, uiPartIdx, REF_PIC_LIST_0, iWidth, iHeight, pcYuvDst, pcYuvSrc0, HIS_DMVR_INTME_RANGE, 2+VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE, uiMinCost);
#if HIS_DMVR_HALF_ME  //下面產生的分像素保存在一個4*4的矩陣m_filteredBlock[x][x]中
xGenerateFracPixel(pCu, uiPartIdx, REF_PIC_LIST_0, iWidth, iHeight, 1+VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE);   
xBIPMVRefine(pCu, uiPartIdx, REF_PIC_LIST_0, iWidth, iHeight, pcYuvDst, pcYuvSrc0, 1  , 1+VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE, uiMinCost);
#endif

//get new prediction
TComMv cMv = pCu->getCUMvField(REF_PIC_LIST_0)->getMv(uiPartIdx);
TComPicYuv* pRefPic = pCu->getSlice()->getRefPic(REF_PIC_LIST_0, pCu->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiPartIdx))->getPicYuvRec();
iRefListIdx = 0;//下面的函數是根據MV進行亞像素插值生成預測塊,最後的亞像素塊應該存到了src0中,應該是以pRefPic爲參考進行插值的。
xPredInterBlk( COMPONENT_Y  , pCu , pRefPic , uiPartIdx , &cMv , iWidth , iHeight , pcYuvSrc0 , true , pCu->getSlice()->getSPS()->getBitDepth( CHANNEL_TYPE_LUMA ), bBIOapplied);
xPredInterBlk( COMPONENT_Cb , pCu , pRefPic , uiPartIdx , &cMv , iWidth , iHeight , pcYuvSrc0 , true , pCu->getSlice()->getSPS()->getBitDepth( CHANNEL_TYPE_CHROMA ));
xPredInterBlk( COMPONENT_Cr , pCu , pRefPic , uiPartIdx , &cMv , iWidth , iHeight , pcYuvSrc0 , true , pCu->getSlice()->getSPS()->getBitDepth( CHANNEL_TYPE_CHROMA ));
再記錄一些零碎的東西:1.繼續解決裏面不懂的東西;2.這個好像也算是加權預測了;3.用在雙向預測中。4.這個東西確實是只用在merge模式中,雖然是在MC的過程中調用的,但是由bBIPMVRefine 這個參數來控制,這個參數複製的過程用到了&&usemerge,所以雖然AMVP也會調用MC,但是由於這個與的過程永遠爲0,所以不會進行DMVR;5.以後想起什麼再寫
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章