H.266/VVC VTM 6-BCW符号化端子加速アルゴリズムを読む
5828 ワード
VVVCのBCWは多様な双方向予測重みを提供し,符号化の必要性を決定する.ここでは、文書JVET−N 0646に記載されている符号化端子加速アルゴリズムおよびVTMの実装の一部を記録する.
1、加速アルゴリズム
1.1 affineモーション推定の一部スキップ
不等重み条件下でaffineモード部分条件下で運動推定をスキップした.等重みのaffine動き推定後、affine interモードが現在の最適モードである場合にのみ動き推定を行い、他の重みの動き推定を行う.
1.2 low-delay画像RD検出回数の減少
low-delay画像については、1/4画素、1画素、および4画素精度を含む5種類の重みのRD検出が必要であり、まず1/4画素精度を検出し、1画素および4画素精度で部分重みRDをスキップする.まず,1/4画素精度で不等重みのRDcostを計算し,1画素と4画素条件下で対等重み条件と1/4画素精度で最小の重みのセットのみをRD検出した.
1.3参照画像が同じ場合のスキップモーション推定
いくつかのRAモードの画像について、同じフレームが2つの参照フレームリストに同時に現れることがある.同時に満たす(a.参照フレームは同じ;b.時間層は1より大きい;c.動きベクトル精度は1/4である.)3つの条件下で不等重みの動き推定をスキップします.この規則は4パラメータのaffine双方向予測にも適用できる.
1.4時間層とPOC距離に基づいてRD検出をスキップする
は同時に満足する(a.時間層は4;b.任意の参照フレームPOCは現在のフレームから1未満、c.QPは32より大きい).をクリックして、不等重みのRDO決定をスキップします.
1.5運動推定における定点計算の使用
双方向予測の動き推定では、1つのMVを固定して別のMVを検索し、MV 1を固定してMV 0を調整します.MV 0の検索対象は
T=((O≪3)-w·P_1 )·(1/(8-w))
定点計算を行うため、検索対象を
T=(O·a_1-P_1·a_2+round)≫N
そのうちγ=(1≪N)/(8-w); a_1=γ≪3; a_2=γ*w; round=1≪(N-1)
2、部分コード実現
VTMはEncCfgオブジェクトにm_を加えたBcwFastは、関数getUseBcwFast()を使用して取得できるオープン高速アルゴリズムを表します.
2.1 EncCu::xCheckRDCostInter()
は1.2内容に対応する.
現在の最適モードがフレーム間モードであり、現在の重みが不等重みであり、現在の重みが不等重みである場合、今回のRD検出をスキップする.すなわち、最適モードがフレーム間モードである場合には、対等重みまたは最適重みのみRD検出を行う.
等重みでcostが他のモードの1.05倍より大きい場合、不等重みRD検出はスキップされる.一方向予測であれば,不等重みのRD検出をスキップする.1回目の検出後、条件(1.4中の条件に対応)を満たすと、後続のRDO検出はスキップされる.
2.2 void InterSearch::predInterSearch()
affineが最適モード条件である場合にのみ、不等重みのaffine動き探索が行われる.
非LDC条件でaffineモードを選択すると、不等重みのフレーム間双方向動き推定がスキップされる.
参照フレームPOCが同じ場合、動き推定値はスキップされ、1.3の条件に対応する.
1、加速アルゴリズム
1.1 affineモーション推定の一部スキップ
不等重み条件下でaffineモード部分条件下で運動推定をスキップした.等重みのaffine動き推定後、affine interモードが現在の最適モードである場合にのみ動き推定を行い、他の重みの動き推定を行う.
1.2 low-delay画像RD検出回数の減少
low-delay画像については、1/4画素、1画素、および4画素精度を含む5種類の重みのRD検出が必要であり、まず1/4画素精度を検出し、1画素および4画素精度で部分重みRDをスキップする.まず,1/4画素精度で不等重みのRDcostを計算し,1画素と4画素条件下で対等重み条件と1/4画素精度で最小の重みのセットのみをRD検出した.
1.3参照画像が同じ場合のスキップモーション推定
いくつかのRAモードの画像について、同じフレームが2つの参照フレームリストに同時に現れることがある.同時に満たす(a.参照フレームは同じ;b.時間層は1より大きい;c.動きベクトル精度は1/4である.)3つの条件下で不等重みの動き推定をスキップします.この規則は4パラメータのaffine双方向予測にも適用できる.
1.4時間層とPOC距離に基づいてRD検出をスキップする
は同時に満足する(a.時間層は4;b.任意の参照フレームPOCは現在のフレームから1未満、c.QPは32より大きい).をクリックして、不等重みのRDO決定をスキップします.
1.5運動推定における定点計算の使用
双方向予測の動き推定では、1つのMVを固定して別のMVを検索し、MV 1を固定してMV 0を調整します.MV 0の検索対象は
T=((O≪3)-w·P_1 )·(1/(8-w))
定点計算を行うため、検索対象を
T=(O·a_1-P_1·a_2+round)≫N
そのうちγ=(1≪N)/(8-w); a_1=γ≪3; a_2=γ*w; round=1≪(N-1)
2、部分コード実現
VTMはEncCfgオブジェクトにm_を加えたBcwFastは、関数getUseBcwFast()を使用して取得できるオープン高速アルゴリズムを表します.
2.1 EncCu::xCheckRDCostInter()
は1.2内容に対応する.
if( m_pcEncCfg->getUseBcwFast() && tempCS->slice->getCheckLDC() && g_BcwSearchOrder[bcwLoopIdx] != BCW_DEFAULT
&& (m_bestBcwIdx[0] >= 0 && g_BcwSearchOrder[bcwLoopIdx] != m_bestBcwIdx[0])
&& (m_bestBcwIdx[1] >= 0 && g_BcwSearchOrder[bcwLoopIdx] != m_bestBcwIdx[1]))
{
continue;
}
現在の最適モードがフレーム間モードであり、現在の重みが不等重みであり、現在の重みが不等重みである場合、今回のRD検出をスキップする.すなわち、最適モードがフレーム間モードである場合には、対等重みまたは最適重みのみRD検出を行う.
if( m_pcEncCfg->getUseBcwFast() )
{
auto blkCache = dynamic_cast< CacheBlkInfoCtrl* >(m_modeCtrl);
if( blkCache )
{
bool isBestInter = blkCache->getInter(bestCS->area);
uint8_t bestBcwIdx = blkCache->getBcwIdx(bestCS->area);
if( isBestInter && g_BcwSearchOrder[bcwLoopIdx] != BCW_DEFAULT && g_BcwSearchOrder[bcwLoopIdx] != bestBcwIdx )
{
continue;
}
}
}
等重みでcostが他のモードの1.05倍より大きい場合、不等重みRD検出はスキップされる.一方向予測であれば,不等重みのRD検出をスキップする.1回目の検出後、条件(1.4中の条件に対応)を満たすと、後続のRDO検出はスキップされる.
double skipTH = MAX_DOUBLE;
skipTH = (m_pcEncCfg->getUseBcwFast() ? 1.05 : MAX_DOUBLE);
if( equBcwCost > curBestCost * skipTH )
{
break;
}
if( m_pcEncCfg->getUseBcwFast() )
{
if( isEqualUni == true && m_pcEncCfg->getIntraPeriod() == -1 )
{
break;
}
}
if( g_BcwSearchOrder[bcwLoopIdx] == BCW_DEFAULT && xIsBcwSkip(cu) && m_pcEncCfg->getUseBcwFast() )
{
break;
}
bool xIsBcwSkip(const CodingUnit& cu)
{
if (cu.slice->getSliceType() != B_SLICE)
{
return true;
}
return((m_pcEncCfg->getBaseQP() > 32) && ((cu.slice->getTLayer() >= 4)
|| ((cu.refIdxBi[0] >= 0 && cu.refIdxBi[1] >= 0)
&& (abs(cu.slice->getPOC() - cu.slice->getRefPOC(REF_PIC_LIST_0, cu.refIdxBi[0])) == 1
|| abs(cu.slice->getPOC() - cu.slice->getRefPOC(REF_PIC_LIST_1, cu.refIdxBi[1])) == 1))));
}
2.2 void InterSearch::predInterSearch()
affineが最適モード条件である場合にのみ、不等重みのaffine動き探索が行われる.
if (cu.Y().width > 8 && cu.Y().height > 8 && cu.slice->getSPS()->getUseAffine()
&& checkAffine
&& (bcwIdx == BCW_DEFAULT || m_affineModeSelected || !m_pcEncCfg->getUseBcwFast())
)
{
...
MvField cHevcMvField[2];
cHevcMvField[0].setMvField( pu.mv[REF_PIC_LIST_0], pu.refIdx[REF_PIC_LIST_0] );
cHevcMvField[1].setMvField( pu.mv[REF_PIC_LIST_1], pu.refIdx[REF_PIC_LIST_1] );
// do affine ME & Merge
cu.affineType = AFFINEMODEL_4PARAM;
Mv acMvAffine4Para[2][33][3];
int refIdx4Para[2] = { -1, -1 };
xPredAffineInterSearch(pu, origBuf, puIdx, uiLastModeTemp, uiAffineCost, cMvHevcTemp, acMvAffine4Para, refIdx4Para, bcwIdx, enforceBcwPred,
((cu.slice->getSPS()->getUseBcw() == true) ? getWeightIdxBits(bcwIdx) : 0));
if ( pu.cu->imv == 0 )
{
storeAffineMotion( pu.mvAffi, pu.refIdx, AFFINEMODEL_4PARAM, bcwIdx );
}
if ( cu.slice->getSPS()->getUseAffineType() )
{
if ( uiAffineCost < uiHevcCost * 1.05 ) ///< condition for 6 parameter affine ME
{
...
xPredAffineInterSearch(pu, origBuf, puIdx, uiLastModeTemp, uiAffine6Cost, cMvHevcTemp, acMvAffine4Para, refIdx4Para, bcwIdx, enforceBcwPred,
((cu.slice->getSPS()->getUseBcw() == true) ? getWeightIdxBits(bcwIdx) : 0));
...
}
uiAffineCost += m_pcRdCost->getCost( 1 ); // add one bit for affine_type
}
...
}
非LDC条件でaffineモードを選択すると、不等重みのフレーム間双方向動き推定がスキップされる.
// Bi-predictive Motion estimation
if( ( cs.slice->isInterB() ) && ( PU::isBipredRestriction( pu ) == false )
&& (cu.slice->getCheckLDC() || bcwIdx == BCW_DEFAULT || !m_affineModeSelected || !m_pcEncCfg->getUseBcwFast())
)
{...}
参照フレームPOCが同じ場合、動き推定値はスキップされ、1.3の条件に対応する.
if( m_pcEncCfg->getUseBcwFast() && (bcwIdx != BCW_DEFAULT)
&& (pu.cu->slice->getRefPic(eRefPicList, iRefIdxTemp)->getPOC() == pu.cu->slice->getRefPic(RefPicList(1 - iRefList), pu.refIdx[1 - iRefList])->getPOC())
&& (!pu.cu->imv && pu.cu->slice->getTLayer()>1))
{
continue;
}