HM中去方塊濾波的禁用方法

有時候我們想禁用掉HM的去方塊濾波,測試下去方塊濾波的效果,很容易就想到要修改配置文件,根據註釋,容易找到:

       LoopFilterDisable             : 1           # Disable deblocking filter (0=Filter, 1=No Filter)

       但是運行完程序後就會發現,這個參數改爲0或者改爲1結果根本就是一樣的(如果用過JM的也會發現相同的問題)。那麼這到底是爲什麼呢?難道是程序的bug?其實不然,HM的編寫者還不至於犯下這種低級錯誤。

       仔細分析代碼後就能找到答案:我們可以找到配置文件LoopFilterDisable這個參數在HM中對應的變量被賦值的地方,在TEncSlice.initEncSlice中有這麼一段:


if ( m_pcCfg->getDeblockingFilterMetric() )  
{  
  rpcSlice->setDeblockingFilterOverrideFlag(true);  
  rpcSlice->setDeblockingFilterDisable(false);  
  rpcSlice->setDeblockingFilterBetaOffsetDiv2( 0 );  
  rpcSlice->setDeblockingFilterTcOffsetDiv2( 0 );  
} else  
if (rpcSlice->getPPS()->getDeblockingFilterControlPresentFlag()) //!< 該標誌必須有效配置文件對DBF參數的修改纔會起作用  
{  
  rpcSlice->getPPS()->setDeblockingFilterOverrideEnabledFlag( !m_pcCfg->getLoopFilterOffsetInPPS() );  
  rpcSlice->setDeblockingFilterOverrideFlag( !m_pcCfg->getLoopFilterOffsetInPPS() );  
  rpcSlice->getPPS()->setPicDisableDeblockingFilterFlag( m_pcCfg->getLoopFilterDisable() ); //!< *  
  rpcSlice->setDeblockingFilterDisable( m_pcCfg->getLoopFilterDisable() );  
  if ( !rpcSlice->getDeblockingFilterDisable())  
  {  
    if ( !m_pcCfg->getLoopFilterOffsetInPPS() && eSliceType!=I_SLICE)  
    {  
      rpcSlice->getPPS()->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_betaOffsetDiv2 + m_pcCfg->getLoopFilterBetaOffset() );  
      rpcSlice->getPPS()->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_tcOffsetDiv2 + m_pcCfg->getLoopFilterTcOffset() );  
      rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_betaOffsetDiv2 + m_pcCfg->getLoopFilterBetaOffset()  );  
      rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_tcOffsetDiv2 + m_pcCfg->getLoopFilterTcOffset() );  
    }  
    else  
    {  
    rpcSlice->getPPS()->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getLoopFilterBetaOffset() );  
    rpcSlice->getPPS()->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getLoopFilterTcOffset() );  
    rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getLoopFilterBetaOffset() );  
    rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getLoopFilterTcOffset() );  
    }  
  }  
}  
else  
{  
  rpcSlice->setDeblockingFilterOverrideFlag( false );  
  rpcSlice->setDeblockingFilterDisable( false ); //!< *  
  rpcSlice->setDeblockingFilterBetaOffsetDiv2( 0 );  
  rpcSlice->setDeblockingFilterTcOffsetDiv2( 0 );  
}  



只有在if (rpcSlice->getPPS()->getDeblockingFilterControlPresentFlag())成立的時候,配置文件中跟DBF有關的參數的值纔會用於HM中對應變量的賦值,而這個flag對應到配置文件中就是:

     DeblockingFilterControlPresent: 1           # Dbl control params present (0=not present, 1=present)     

    於是真相大白了,只有在該參數爲1的前提下,配置文件中其他相關參數的設置纔會起作用。

 那麼爲什麼要這麼做呢?道理也不難想到——保證編解碼器的一致性,如果沒有一個句法元素來表明是否進行去方塊濾波,那麼解碼器解碼後得到的重建圖像就有可能與編碼端存在偏差。那麼爲什麼不單獨就用一個句法元素就好,還要額外用另外一個句法元素來進行控制呢?原因是,DBF的參數不止濾波與否這個,還有另外幾個;很多時候,這幾個參數值可以都用默認值,解碼器和編碼器都是一致的,則碼流只需傳輸一個句法元素,用於表明是否採用默認參數,即deblocking_filter_control_present_flag。一旦該句法元素爲1,則再額外傳輸跟DBF相關的幾個參數對應的句法元素。這種方法能較好的節省碼流。

發佈了20 篇原創文章 · 獲贊 21 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章