📄 umc_h264_segment_decoder_mt.cpp
字号:
// Set MV for all DIRECT 4x4 subblocks
Ipp32s sb, sbcolpartoffset;
Ipp8s colocatedRefIndex;
H264DecoderMotionVector *pRefMV; // will be colocated L0 or L1
Ipp32s MBsCol[4];
Ipp32s sbColPartOffset[4];
if (m_IsUseDirect8x8Inference)
{
sbColPartOffset[0] = 0;
sbColPartOffset[2] = 12;
MBsCol[0] = GetColocatedLocation(m_pRefPicList[1][0], field, sbColPartOffset[0]);
MBsCol[1] = MBsCol[0];
sbColPartOffset[1] = sbColPartOffset[0]+3;
MBsCol[2] = GetColocatedLocation(m_pRefPicList[1][0], field, sbColPartOffset[2]);
MBsCol[3] = MBsCol[2];
sbColPartOffset[3] = sbColPartOffset[2]+3;
}
else
{
sbColPartOffset[0] = 0;
sbColPartOffset[2] = 8;
MBsCol[0] = GetColocatedLocation(m_pRefPicList[1][0], field, sbColPartOffset[0]);
MBsCol[1] = MBsCol[0];
sbColPartOffset[1] = sbColPartOffset[0]+2;
MBsCol[2] = GetColocatedLocation(m_pRefPicList[1][0], field, sbColPartOffset[2]);
MBsCol[3] = MBsCol[2];
sbColPartOffset[3] = sbColPartOffset[2]+2;
}
for (sb=0; sb<4; sb++)
{
if (m_cur_mb.GlobalMacroblockInfo->sbtype[sb] != SBTYPE_DIRECT)
{
bAll8x8AreSame = 17;
continue;
}
// DIRECT 8x8 block
bAll4x4AreSame = 0;
Ipp32u MBCol=MBsCol[sb];
H264DecoderMotionVector *pRefMVL0 = m_pRefPicList[1][0]->m_mbinfo.MV[0][MBCol].MotionVectors;
H264DecoderMotionVector *pRefMVL1 = m_pRefPicList[1][0]->m_mbinfo.MV[1][MBCol].MotionVectors;
Ipp8s *pColocatedRefIndexL0 = m_pRefPicList[1][0]->m_mbinfo.RefIdxs[0][MBCol].RefIdxs;
Ipp8s *pColocatedRefIndexL1 = m_pRefPicList[1][0]->m_mbinfo.RefIdxs[1][MBCol].RefIdxs;
bool isInter = IS_INTER_MBTYPE(m_pRefPicList[1][0]->m_mbinfo.mbs[MBCol].mbtype);
sbcolpartoffset = sbColPartOffset[sb];
colocatedRefIndex = pColocatedRefIndexL0[sbcolpartoffset];
if (colocatedRefIndex >= 0)
{
// use L0 colocated
pRefMV = pRefMVL0;
}
else
{
// use L1 colocated
colocatedRefIndex = pColocatedRefIndexL1[sbcolpartoffset];
pRefMV = pRefMVL1;
}
bool isNeedToCheckMVS = isInter && bL1RefPicisShortTerm && (colocatedRefIndex == 0) && ((RefIndexL0 != -1) || (RefIndexL1 != -1));
if (isNeedToCheckMVS)
{
// 4 4x4 blocks
for (ypos = 0; ypos < 2; ypos++)
{
for (xpos = 0; xpos < 2; xpos++)
{
sbcolpartoffset = m_IsUseDirect8x8Inference ? sbColPartOffset[sb]:sbColPartOffset[sb]+ypos*4+xpos;
bool bUseZeroPredL0 = false;
bool bUseZeroPredL1 = false;
Ipp32s sbpartoffset = (ypos+(sb&2))*4+(sb&1)*2;
VM_ASSERT(pRefMV);
if (pRefMV[sbcolpartoffset].mvx >= -1 &&
pRefMV[sbcolpartoffset].mvx <= 1 &&
pRefMV[sbcolpartoffset].mvy >= -1 &&
pRefMV[sbcolpartoffset].mvy <= 1)
{
// All subpart conditions for forcing zero pred are met,
// use final RefIndexLx==0 condition for L0,L1.
bUseZeroPredL0 = (RefIndexL0 == 0);
bUseZeroPredL1 = (RefIndexL1 == 0);
bAll4x4AreSame ++;
}
if (!bUseZeroPredL0)
{
pFwdMV->MotionVectors[xpos+sbpartoffset].mvx = (Ipp16s) mvxL0;
pFwdMV->MotionVectors[xpos+sbpartoffset].mvy = (Ipp16s) mvyL0;
}
else
{
pFwdMV->MotionVectors[xpos+sbpartoffset].mvx = 0;
pFwdMV->MotionVectors[xpos+sbpartoffset].mvy = 0;
}
if (!bUseZeroPredL1)
{
pBwdMV->MotionVectors[xpos+sbpartoffset].mvx = (Ipp16s) mvxL1;
pBwdMV->MotionVectors[xpos+sbpartoffset].mvy = (Ipp16s) mvyL1;
}
else
{
pBwdMV->MotionVectors[xpos+sbpartoffset].mvx = 0;
pBwdMV->MotionVectors[xpos+sbpartoffset].mvy = 0;
}
} // xpos
} // ypos // next row of subblocks
}
else
{
H264DecoderMotionVector mv;
mv.mvx = (Ipp16s)mvxL0;
mv.mvy = (Ipp16s)mvyL0;
storeStructInformationInto8x8<H264DecoderMotionVector>(&pFwdMV->MotionVectors[subblock_block_mapping[sb]], mv);
mv.mvx = (Ipp16s)mvxL1;
mv.mvy = (Ipp16s)mvyL1;
storeStructInformationInto8x8<H264DecoderMotionVector>(&pBwdMV->MotionVectors[subblock_block_mapping[sb]], mv);
}
// set direction for 8x8 block
m_cur_mb.LocalMacroblockInfo->sbdir[sb] = (Ipp8u)uPredDir;
// set type for 8x8 block
if (!bAll4x4AreSame || bAll4x4AreSame == 4)
m_cur_mb.GlobalMacroblockInfo->sbtype[sb] = SBTYPE_8x8;
else
m_cur_mb.GlobalMacroblockInfo->sbtype[sb] = SBTYPE_4x4;
bAll8x8AreSame += bAll4x4AreSame;
} // for sb
// set mbtype to 8x8 if it was not; use larger type if possible
if (!bAll8x8AreSame || bAll8x8AreSame == 16)
{
if (uPredDir == D_DIR_DIRECT_SPATIAL_FWD)
m_cur_mb.GlobalMacroblockInfo->mbtype= MBTYPE_FORWARD;
else if (uPredDir == D_DIR_DIRECT_SPATIAL_BWD)
m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_BACKWARD;
else
m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_BIDIR;
}
else
{
m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTER_8x8;
}
} // void H264SegmentDecoderMultiThreaded::ReconstructDirectMotionVectorsSpatial(H264DecoderFrame **
void H264SegmentDecoderMultiThreaded::GetMVD4x4_CABAC(const Ipp8u *pBlkIdx,
const Ipp8u *pCodMVd,
Ipp32u ListNum)
{
Ipp32u i, j, m = 0;
// new
const H264DecoderMotionVector MV0 = {0, 0};
H264DecoderMotionVector *pMVd = m_cur_mb.MVs[ListNum + 2]->MotionVectors;
for (i = 0; i < 16; i ++)
{
j = pBlkIdx[i];
if ((m_cur_mb.GlobalMacroblockInfo->mbtype == MBTYPE_INTER_8x8 ||
m_cur_mb.GlobalMacroblockInfo->mbtype == MBTYPE_INTER_8x8_REF0) &&
!(i & 3))
m = i;
// new
H264DecoderMotionVector mvd;
switch (pCodMVd[j])
{
case CodNone:
pMVd[j] = MV0;
m++;
break;
case CodInBS:
mvd = GetSE_MVD_CABAC(ListNum, j);
pMVd[j] = mvd;
break;
case CodLeft:
pMVd[j] = pMVd[j - 1];
break;
case CodAbov:
pMVd[j] = pMVd[j - 4];
break;
case CodSkip:
pMVd[j] = MV0;
break;
}
} // for i
} // void H264SegmentDecoderMultiThreaded::GetMVD4x4_CABAC(const Ipp8u *pBlkIdx,
void H264SegmentDecoderMultiThreaded::ReconstructMotionVectors4x4(const Ipp8u *pBlkIdx,
const Ipp8u *pCodMVd,
Ipp32u ListNum)
{
Ipp32u i, j, m = 0;
// new
const H264DecoderMotionVector MV0 = {0, 0};
H264DecoderMotionVector *pMV = m_cur_mb.MVs[ListNum]->MotionVectors;
H264DecoderMotionVector *pMVd = m_cur_mb.MVs[ListNum + 2]->MotionVectors;
Ipp8s *pRIx = m_cur_mb.RefIdxs[ListNum]->RefIdxs;
// old
for (i = 0; i < 16; i ++)
{
j = pBlkIdx[i];
if ((m_cur_mb.GlobalMacroblockInfo->mbtype == MBTYPE_INTER_8x8 ||
m_cur_mb.GlobalMacroblockInfo->mbtype == MBTYPE_INTER_8x8_REF0) &&
!(i & 3))
m = i;
// new
H264DecoderMotionVector mv;
H264DecoderMotionVector mvd;
Ipp32s mvpx, mvpy;
switch (pCodMVd[j])
{
case CodNone:
pMV[j] = MV0;
m++;
break;
case CodInBS:
// TBD optimization - modify to compute predictors here instead of calling this method
ComputeMotionVectorPredictors((Ipp8u) ListNum,
pRIx[j],
m++,
&mvpx,
&mvpy);
mvd = pMVd[j];
// new & old
mv.mvx = (Ipp16s) (mvpx + (Ipp32s) mvd.mvx);
mv.mvy = (Ipp16s) (mvpy + (Ipp32s) mvd.mvy);
if (mv.mvy > m_MVDistortion[ListNum])
m_MVDistortion[ListNum] = mv.mvy;
// new
pMV[j] = mv;
break;
case CodLeft:
pMV[j] = pMV[j - 1];
break;
case CodAbov:
pMV[j] = pMV[j - 4];
break;
case CodSkip:
break;
}
} // for i
} // void H264SegmentDecoderMultiThreaded::ReconstructMotionVectors4x4(const Ipp8u *pBlkIdx,
void H264SegmentDecoderMultiThreaded::GetMVD4x4_CABAC(const Ipp8u pCodMVd,
Ipp32u ListNum)
{
Ipp32u k;
H264DecoderMotionVector *pMVd = m_cur_mb.MVs[ListNum + 2]->MotionVectors;
H264DecoderMotionVector mvd;
#ifdef __ICL
__assume_aligned(pMVd, 16);
#endif
if(pCodMVd == CodNone)
{
memset(&pMVd[0],0,16*sizeof(H264DecoderMotionVector));
}
else
{
mvd = GetSE_MVD_CABAC(ListNum, 0);
for (k = 0; k < 16; k ++)
{
pMVd[k].mvx = mvd.mvx;
pMVd[k].mvy = mvd.mvy;
} // for k
}
} // void H264SegmentDecoderMultiThreaded::GetMVD4x4_CABAC(const Ipp8u pCodMVd,
void H264SegmentDecoderMultiThreaded::ReconstructMotionVectors4x4(const Ipp8u pCodMVd,
Ipp32u ListNum)
{
Ipp32u k;
H264DecoderMotionVector *pMV = m_cur_mb.MVs[ListNum]->MotionVectors;
H264DecoderMotionVector *pMVd = m_cur_mb.MVs[ListNum + 2]->MotionVectors;
Ipp8s *pRIx = m_cur_mb.RefIdxs[ListNum]->RefIdxs;
H264DecoderMotionVector mv;
H264DecoderMotionVector mvd;
Ipp32s mvpx, mvpy;
#ifdef __ICL
__assume_aligned(pMV, 16);
__assume_aligned(pMVd, 16);
#endif
if(pCodMVd == CodNone)
{
//pMV[0].mvx = pMV[0].mvy = pMVd[0].mvx = pMVd[0].mvy = 0;
memset(&pMV[0],0,16*sizeof(H264DecoderMotionVector));
}
else
{
ComputeMotionVectorPredictors( (Ipp8u) ListNum,
pRIx[0],
0, &mvpx, &mvpy);
mvd = pMVd[0];
mv.mvx = (Ipp16s) (mvpx + (Ipp32s) mvd.mvx);
mv.mvy = (Ipp16s) (mvpy + (Ipp32s) mvd.mvy);
if (mv.mvy > m_MVDistortion[ListNum])
m_MVDistortion[ListNum] = mv.mvy;
for (k = 0; k < 16; k ++)
{
pMV[k].mvx = mv.mvx;
pMV[k].mvy = mv.mvy;
} // for k
}
} // void H264SegmentDecoderMultiThreaded::ReconstructMotionVectors4x4(const Ipp8u pCodMVd,
void H264SegmentDecoderMultiThreaded::GetMVD4x4_16x8_CABAC(const Ipp8u *pCodMVd,
Ipp32u ListNum)
{
Ipp32u k;
H264DecoderMotionVector *pMVd = m_cur_mb.MVs[ListNum + 2]->MotionVectors;
H264DecoderMotionVector mvd;
#ifdef __ICL
__assume_aligned(pMVd, 16);
#endif
if(pCodMVd[0] == CodNone)
{
memset(&pMVd[0],0,8*sizeof(H264DecoderMotionVector));
}
else
{
mvd = GetSE_MVD_CABAC(ListNum, 0);
for (k = 0; k < 8; k ++)
{
pMVd[k].mvx = mvd.mvx;
pMVd[k].mvy = mvd.mvy;
} // for k
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -