fillMvpCand函数的功能就是为AMVP建立候选列表。
AMVP的理论见:
http://blog.csdn.net/lin453701006/article/details/54340405
fillMvpCand主要流程如下,主要来看空域候选列表:
一、建立空域候选列表:
1. 按顺序搜索左侧块A0-A1-scaled A0-scaled A1,只要有一个MV存在,写入候选列表,跳出进行下一步。
2. 按顺序搜索上方块B0-B1-B2(-scaled B0-scaled B1-scaled B2),只要有一个MV存在,写入候选列表,跳出进行下一步。而其中scaled B0-scaled B1-scaled B2只有当A0和A1的MV都不存在时,才进行搜索。
3. 空域候选列表长度为2时,即左侧和上方各选出了一个候选,则对两者进行比较,相同时进行合并。
4. 空域候选列表建立完成。
二、当空域候选数量少于2个,且启用时域候选时,建立时域候选列表。
三、如果空域+时域候选个数少于2,则使用(0,0)补足。
代码如下:
/** Constructs a list of candidates for AMVP (See specification, section "Derivation process for motion vector predictor candidates")
* \param uiPartIdx
* \param uiPartAddr
* \param eRefPicList
* \param iRefIdx
* \param pInfo
*/
Void TComDataCU::fillMvpCand ( const UInt partIdx, const UInt partAddr, const RefPicList eRefPicList, const Int refIdx, AMVPInfo* pInfo ) const
{
pInfo->iN = 0;
if (refIdx < 0)
{
return;
}
/**********************************************空域候选列表*************************************************/
//-- Get Spatial MV
UInt partIdxLT, partIdxRT, partIdxLB;
deriveLeftRightTopIdx( partIdx, partIdxLT, partIdxRT ); //获取左上角、右上角块地址
deriveLeftBottomIdx( partIdx, partIdxLB ); //获取左下角块地址
Bool isScaledFlagLX = false; /// variable name from specification; true when the PUs below left or left are available (availableA0 || availableA1).
{
UInt idx;
const TComDataCU* tmpCU = getPUBelowLeft(idx, partIdxLB); //左下角块A0所在的CU
isScaledFlagLX = (tmpCU != NULL) && (tmpCU->isInter(idx)); //A0块MV是否存在