組合平均法是在Merge列表構建過程中的一種填充候選的方法。
一、 在HEVC中,使用組合候選的方法作爲Merge候選列表構建的一種備選方法,該方法比較複雜,對於一個BSlice中的PU而言,其中需要兩個MV(一個前向、一個後向),因此在構建Merge候選列表的時候,每個候選需要提供兩個MV,當需要用到組合候選法去填充Merge列表的時候,需要對前面已經填充進列表中的前4個候選中的前後向MV使用兩兩組合的方式產生新的候選再放入到Merge列表中。組合的方式具體爲下表所示:
其中combIdx爲進行組合的候選MV對的序號,也是可能添加進Merge列表中最後一個候選的組合MV;L0CandIdx和L1CandIdx分別表示進行組合的兩個MV所在的候選項在原Merge候選列表中的序號。
如列表中所示,Merge列表中前4個候選的任意一個候選的前向MV和另一個候選的後向MV相互組合出一個新的MV對(新候選),總共12種組合方式,在這12中選出一個添加到Merge列表中,在檢查冗餘的基礎上,最多隻允許添加一個。
二、 在目前的VVC中,擯棄之前繁雜的組合候選的方式,L次會議上的L0090提出了簡化的成對平均候選的方法,不需要12種繁雜的組合,只需要將Merge列表中已經添加進去的前兩個候選(0、1)的前向MV進行兩兩平均得到新的前向MV,以及後向MV進行兩兩平均得到新的後向MV。然後用這兩個平均後的MV組合成一個新的候選,將該新候選添加到Merge列表中。在檢查冗餘的基礎上最多隻允許添加一個成對平均候選。
成對平均候選在VTM6.0中的代碼如下,有較爲詳細的註釋,如有註釋不對的地方歡迎指正:
#if JVET_L0090_PAIR_AVG
// pairwise-average candidates
//這裏開始成對平均候選的填充
{
if (cnt > 1 && cnt < maxNumMergeCand)//如果此時Merge列表還沒有被填滿
{
//對當前Merge候選項中進行初始化,即賦予零MV
mrgCtx.mvFieldNeighbours[cnt * 2].setMvField( Mv( 0, 0 ), NOT_VALID );
mrgCtx.mvFieldNeighbours[cnt * 2 + 1].setMvField( Mv( 0, 0 ), NOT_VALID );
// calculate average MV for L0 and L1 seperately
//接下來計算前後向各自的平均MV
unsigned char interDir = 0;
#if JVET_O0057_ALTHPELIF
//半像素插值濾波器是否可用
mrgCtx.useAltHpelIf[cnt] = (mrgCtx.useAltHpelIf[0] == mrgCtx.useAltHpelIf[1]) ? mrgCtx.useAltHpelIf[0] : false;
#endif
//對Merge列表中前兩個候選的前向和後向的MV分別進行循環
for( int refListId = 0; refListId < (slice.isInterB() ? 2 : 1); refListId++ )
{
const short refIdxI = mrgCtx.mvFieldNeighbours[0 * 2 + refListId].refIdx;//第一個候選的參考幀索引
const short refIdxJ = mrgCtx.mvFieldNeighbours[1 * 2 + refListId].refIdx;//第二個候選的參考幀索引
//如果兩個候選的MV都不可用,則直接跳出進行另一向MV的平均
if( (refIdxI == NOT_VALID) && (refIdxJ == NOT_VALID) )
{
continue;
}
interDir += 1 << refListId;
//如果兩個MV都有效,則對兩個MV進行兩兩平均
if( (refIdxI != NOT_VALID) && (refIdxJ != NOT_VALID) )
{
const Mv& MvI = mrgCtx.mvFieldNeighbours[0 * 2 + refListId].mv;//第一個候選的MV
const Mv& MvJ = mrgCtx.mvFieldNeighbours[1 * 2 + refListId].mv;//第二個候選的MV
// average two MVs
Mv avgMv = MvI;
avgMv += MvJ;
roundAffineMv(avgMv.hor, avgMv.ver, 1);
mrgCtx.mvFieldNeighbours[cnt * 2 + refListId].setMvField( avgMv, refIdxI );
}
// only one MV is valid, take the only one MV
//若只有其中一個MV有效,則僅僅將該有效的MV作爲平均的MV
else if( refIdxI != NOT_VALID )
{
Mv singleMv = mrgCtx.mvFieldNeighbours[0 * 2 + refListId].mv;
mrgCtx.mvFieldNeighbours[cnt * 2 + refListId].setMvField( singleMv, refIdxI );
}
else if( refIdxJ != NOT_VALID )
{
Mv singleMv = mrgCtx.mvFieldNeighbours[1 * 2 + refListId].mv;
mrgCtx.mvFieldNeighbours[cnt * 2 + refListId].setMvField( singleMv, refIdxJ );
}
}
mrgCtx.interDirNeighbours[cnt] = interDir;
//如果預測方向有效,則將該成對候選MV添加到Merge列表中去
if( interDir > 0 )
{
cnt++;
}
}
// early termination
if( cnt == maxNumMergeCand )
{
return;
}
}
#endif