📄 umc_h264_segment_decoder_mt_reconstruct_mv.cpp
字号:
mv.mvx = (Ipp16s) (mvPred.mvx + pMVd[iColumnNum].mvx);
mv.mvy = (Ipp16s) (mvPred.mvy + pMVd[iColumnNum].mvy);
if (mv.mvy > m_MVDistortion[iListNum])
m_MVDistortion[iListNum] = mv.mvy;
pMV[iColumnNum] = mv;
}
} // void H264SegmentDecoderMultiThreaded::ReconstructMVs4x4Top(Ipp32s iListNum,
void H264SegmentDecoderMultiThreaded::ReconstructMVs4x4Left(Ipp32s iListNum,
Ipp32s iRowNum)
{
H264DecoderMotionVector mvPred;
H264DecoderMotionVector *pMV = m_cur_mb.MVs[iListNum]->MotionVectors;
H264DecoderMotionVector *pMVd = m_cur_mb.MVs[iListNum + 2]->MotionVectors;
// get the prediction
ReconstructMVPredictorLeftBlockFewCheckRef(iListNum, iRowNum, &mvPred);
#ifdef __ICL
__assume_aligned(pMV, 16);
__assume_aligned(pMVd, 16);
#endif // __ICL
{
H264DecoderMotionVector mv;
// calculate new vector
mv.mvx = (Ipp16s) (mvPred.mvx + pMVd[iRowNum * 4].mvx);
mv.mvy = (Ipp16s) (mvPred.mvy + pMVd[iRowNum * 4].mvy);
if (mv.mvy > m_MVDistortion[iListNum])
m_MVDistortion[iListNum] = mv.mvy;
pMV[iRowNum * 4] = mv;
}
} // void H264SegmentDecoderMultiThreaded::ReconstructMVs4x4LeftFewCheckRef(Ipp32s iListNum,
void H264SegmentDecoderMultiThreaded::ReconstructMVs4x4Internal(Ipp32s iListNum,
Ipp32s iBlockNum,
Ipp32s iAddrC)
{
H264DecoderMotionVector mvPred;
H264DecoderMotionVector *pMV = m_cur_mb.MVs[iListNum]->MotionVectors;
H264DecoderMotionVector *pMVd = m_cur_mb.MVs[iListNum + 2]->MotionVectors;
// get the prediction
ReconstructMVPredictorInternalBlock(iListNum, iBlockNum, iAddrC, &mvPred);
#ifdef __ICL
__assume_aligned(pMV, 16);
__assume_aligned(pMVd, 16);
#endif // __ICL
{
H264DecoderMotionVector mv;
// calculate new vector
mv.mvx = (Ipp16s) (mvPred.mvx + pMVd[iBlockNum].mvx);
mv.mvy = (Ipp16s) (mvPred.mvy + pMVd[iBlockNum].mvy);
if (mv.mvy > m_MVDistortion[iListNum])
m_MVDistortion[iListNum] = mv.mvy;
pMV[iBlockNum] = mv;
}
} // void H264SegmentDecoderMultiThreaded::ReconstructMVs4x4Internal(Ipp32s iListNum,
void H264SegmentDecoderMultiThreaded::ReconstructMVs4x4InternalFewCheckRef(Ipp32s iListNum,
Ipp32s iBlockNum,
Ipp32s iAddrC)
{
H264DecoderMotionVector mvPred;
H264DecoderMotionVector *pMV = m_cur_mb.MVs[iListNum]->MotionVectors;
H264DecoderMotionVector *pMVd = m_cur_mb.MVs[iListNum + 2]->MotionVectors;
// get the prediction
ReconstructMVPredictorInternalBlockFewCheckRef(iListNum, iBlockNum, iAddrC, &mvPred);
#ifdef __ICL
__assume_aligned(pMV, 16);
__assume_aligned(pMVd, 16);
#endif // __ICL
{
H264DecoderMotionVector mv;
// calculate new vector
mv.mvx = (Ipp16s) (mvPred.mvx + pMVd[iBlockNum].mvx);
mv.mvy = (Ipp16s) (mvPred.mvy + pMVd[iBlockNum].mvy);
if (mv.mvy > m_MVDistortion[iListNum])
m_MVDistortion[iListNum] = mv.mvy;
pMV[iBlockNum] = mv;
}
} // void H264SegmentDecoderMultiThreaded::ReconstructMVs4x4InternalFewCheckRef(Ipp32s iListNum,
void H264SegmentDecoderMultiThreaded::ReconstructMVs4x4InternalNoCheckRef(Ipp32s iListNum,
Ipp32s iBlockNum)
{
H264DecoderMotionVector mvPred;
H264DecoderMotionVector *pMV = m_cur_mb.MVs[iListNum]->MotionVectors;
H264DecoderMotionVector *pMVd = m_cur_mb.MVs[iListNum + 2]->MotionVectors;
// get the prediction
ReconstructMVPredictorInternalBlockNoCheckRef(iListNum, iBlockNum, &mvPred);
#ifdef __ICL
__assume_aligned(pMV, 16);
__assume_aligned(pMVd, 16);
#endif // __ICL
{
H264DecoderMotionVector mv;
// calculate new vector
mv.mvx = (Ipp16s) (mvPred.mvx + pMVd[iBlockNum].mvx);
mv.mvy = (Ipp16s) (mvPred.mvy + pMVd[iBlockNum].mvy);
if (mv.mvy > m_MVDistortion[iListNum])
m_MVDistortion[iListNum] = mv.mvy;
pMV[iBlockNum] = mv;
}
} // void H264SegmentDecoderMultiThreaded::ReconstructMVs4x4InternalNoCheckRef(Ipp32s iListNum,
#define MEDIAN_OF_3(a, b, c) \
(Ipp16s) ((IPP_MIN((a),(b))) ^ (IPP_MIN((b),(c))) ^ (IPP_MIN((c),(a))))
void H264SegmentDecoderMultiThreaded::ReconstructMVPredictorExternalBlock(Ipp32s iListNum,
H264DecoderBlockLocation mbAddrC,
H264DecoderMotionVector *pPred)
{
H264DecoderBlockLocation mbAddrA, mbAddrB;
// get neighbouring addresses
mbAddrA = m_cur_mb.CurrentBlockNeighbours.mbs_left[0];
mbAddrB = m_cur_mb.CurrentBlockNeighbours.mb_above;
if (-1 == mbAddrC.mb_num)
mbAddrC = m_cur_mb.CurrentBlockNeighbours.mb_above_left;
// when B & C partition is not available, use only A partition
if ((-1 == (mbAddrB.mb_num & mbAddrC.mb_num)) &&
(-1 != mbAddrA.mb_num))
{
H264DecoderMacroblockMVs *pMVs;
pMVs = m_gmbinfo->MV[iListNum];
*pPred = pMVs[mbAddrA.mb_num].MotionVectors[mbAddrA.block_num];
return;
}
else
{
// if one and only on of the reference indixes is equal to
// the current reference index, use owning it partition
{
H264DecoderMacroblockRefIdxs *pRefIdcs = m_gmbinfo->RefIdxs[iListNum];
Ipp32s curRefIdx = m_cur_mb.RefIdxs[iListNum]->RefIdxs[0];
Ipp32s refIdxA, refIdxB, refIdxC;
Ipp32s iEqual;
refIdxA = (-1 != mbAddrA.mb_num) ? (pRefIdcs[mbAddrA.mb_num].RefIdxs[mbAddrA.block_num]) : (-1);
refIdxB = (-1 != mbAddrB.mb_num) ? (pRefIdcs[mbAddrB.mb_num].RefIdxs[mbAddrB.block_num]) : (-1);
refIdxC = (-1 != mbAddrC.mb_num) ? (pRefIdcs[mbAddrC.mb_num].RefIdxs[mbAddrC.block_num]) : (-1);
iEqual = 0;
iEqual += (curRefIdx == refIdxA) ? (1) : (0);
iEqual += (curRefIdx == refIdxB) ? (1) : (0);
iEqual += (curRefIdx == refIdxC) ? (1) : (0);
if (1 == iEqual)
{
H264DecoderMacroblockMVs *pMVs;
pMVs = m_gmbinfo->MV[iListNum];
if (curRefIdx == refIdxA)
*pPred = pMVs[mbAddrA.mb_num].MotionVectors[mbAddrA.block_num];
else if (curRefIdx == refIdxB)
*pPred = pMVs[mbAddrB.mb_num].MotionVectors[mbAddrB.block_num];
else
*pPred = pMVs[mbAddrC.mb_num].MotionVectors[mbAddrC.block_num];
return;
}
}
// there is true median of A, B and C partition
{
H264DecoderMotionVector mvA, mvB, mvC;
{
H264DecoderMacroblockMVs *pMVs = m_gmbinfo->MV[iListNum];
static H264DecoderMotionVector mvZero = {0, 0};
mvA = (-1 != mbAddrA.mb_num) ? (pMVs[mbAddrA.mb_num].MotionVectors[mbAddrA.block_num]) : (mvZero);
mvB = (-1 != mbAddrB.mb_num) ? (pMVs[mbAddrB.mb_num].MotionVectors[mbAddrB.block_num]) : (mvZero);
mvC = (-1 != mbAddrC.mb_num) ? (pMVs[mbAddrC.mb_num].MotionVectors[mbAddrC.block_num]) : (mvZero);
}
pPred->mvx = MEDIAN_OF_3(mvA.mvx, mvB.mvx, mvC.mvx);
pPred->mvy = MEDIAN_OF_3(mvA.mvy, mvB.mvy, mvC.mvy);
}
}
} // void H264SegmentDecoderMultiThreaded::ReconstructMVPredictorExternalBlock(Ipp32s iListNum,
void H264SegmentDecoderMultiThreaded::ReconstructMVPredictorExternalBlockMBAFF(Ipp32s iListNum,
H264DecoderBlockLocation mbAddrC,
H264DecoderMotionVector *pPred)
{
H264DecoderBlockLocation mbAddrA, mbAddrB;
// get neighbouring addresses
mbAddrA = m_cur_mb.CurrentBlockNeighbours.mbs_left[0];
mbAddrB = m_cur_mb.CurrentBlockNeighbours.mb_above;
if (-1 == mbAddrC.mb_num)
mbAddrC = m_cur_mb.CurrentBlockNeighbours.mb_above_left;
// when B & C partition is not available, use only A partition
if ((-1 == (mbAddrB.mb_num & mbAddrC.mb_num)) &&
(-1 != mbAddrA.mb_num))
{
H264DecoderMacroblockMVs *pMVs;
pMVs = m_gmbinfo->MV[iListNum];
*pPred = pMVs[mbAddrA.mb_num].MotionVectors[mbAddrA.block_num];
// adjust vertical vector
pPred->mvy <<= GetMBFieldDecodingFlag(m_gmbinfo->mbs[mbAddrA.mb_num]);
if (pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo))
pPred->mvy /= 2;
return;
}
else
{
// if one and only on of the reference indixes is equal to
// the current reference index, use owning it partition
{
Ipp32s curFldFlag = pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo);
Ipp32s fldFlagA = GetMBFieldDecodingFlag(m_gmbinfo->mbs[mbAddrA.mb_num]);
Ipp32s fldFlagB = GetMBFieldDecodingFlag(m_gmbinfo->mbs[mbAddrB.mb_num]);
Ipp32s fldFlagC = GetMBFieldDecodingFlag(m_gmbinfo->mbs[mbAddrC.mb_num]);
H264DecoderMacroblockRefIdxs *pRefIdcs = m_gmbinfo->RefIdxs[iListNum];
Ipp32s curRefIdx = (m_cur_mb.RefIdxs[iListNum]->RefIdxs[0]);
Ipp32s refIdxA, refIdxB, refIdxC;
Ipp32s iEqual;
refIdxA = (-1 != mbAddrA.mb_num) ?
((pRefIdcs[mbAddrA.mb_num].RefIdxs[mbAddrA.block_num] << curFldFlag) >> fldFlagA) :
(-1);
refIdxB = (-1 != mbAddrB.mb_num) ?
((pRefIdcs[mbAddrB.mb_num].RefIdxs[mbAddrB.block_num] << curFldFlag) >> fldFlagB) :
(-1);
refIdxC = (-1 != mbAddrC.mb_num) ?
((pRefIdcs[mbAddrC.mb_num].RefIdxs[mbAddrC.block_num] << curFldFlag) >> fldFlagC) :
(-1);
iEqual = 0;
iEqual += (curRefIdx == refIdxA) ? (1) : (0);
iEqual += (curRefIdx == refIdxB) ? (1) : (0);
iEqual += (curRefIdx == refIdxC) ? (1) : (0);
if (1 == iEqual)
{
H264DecoderMacroblockMVs *pMVs;
pMVs = m_gmbinfo->MV[iListNum];
H264DecoderBlockLocation mbNeighbour;
if (curRefIdx == refIdxA)
mbNeighbour = mbAddrA;
else if (curRefIdx == refIdxB)
mbNeighbour = mbAddrB;
else
mbNeighbour = mbAddrC;
*pPred = pMVs[mbNeighbour.mb_num].MotionVectors[mbNeighbour.block_num];
// adjust vertical vector
pPred->mvy <<= GetMBFieldDecodingFlag(m_gmbinfo->mbs[mbNeighbour.mb_num]);
if (curFldFlag)
pPred->mvy /= 2;
return;
}
}
// there is true median of A, B and C partition
{
H264DecoderMotionVector mvA, mvB, mvC;
{
H264DecoderMacroblockMVs *pMVs = m_gmbinfo->MV[iListNum];
static H264DecoderMotionVector mvZero = {0, 0};
if (0 <= mbAddrA.mb_num)
{
mvA = pMVs[mbAddrA.mb_num].MotionVectors[mbAddrA.block_num];
mvA.mvy <<= GetMBFieldDecodingFlag(m_gmbinfo->mbs[mbAddrA.mb_num]);
}
else
mvA = mvZero;
if (0 <= mbAddrB.mb_num)
{
mvB = pMVs[mbAddrB.mb_num].MotionVectors[mbAddrB.block_num];
mvB.mvy <<= GetMBFieldDecodingFlag(m_gmbinfo->mbs[mbAddrB.mb_num]);
}
else
mvB = mvZero;
if (0 <= mbAddrC.mb_num)
{
mvC = pMVs[mbAddrC.mb_num].MotionVectors[mbAddrC.block_num];
mvC.mvy <<= GetMBFieldDecodingFlag(m_gmbinfo->mbs[mbAddrC.mb_num]);
}
else
mvC = mvZero;
}
pPred->mvx = MEDIAN_OF_3(mvA.mvx, mvB.mvx, mvC.mvx);
pPred->mvy = MEDIAN_OF_3(mvA.mvy, mvB.mvy, mvC.mvy);
// adjust vertical vector
if (pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo))
pPred->mvy /= 2;
}
}
} // void H264SegmentDecoderMultiThreaded::ReconstructMVPredictorExternalBlockMBAFF(Ipp32s iListNum,
void H264SegmentDecoderMultiThreaded::ReconstructMVPredictorTopBlock(Ipp32s iListNum,
Ipp32s iColumnNum,
H264DecoderBlockLocation mbAddrC,
H264DecoderMotionVector *pPred)
{
H264DecoderBlockLocation mbAddrB;
// get neighbouring addresses
mbAddrB = m_cur_mb.CurrentBlockNeighbours.mb_above;
mbAddrB.block_num += iColumnNum;
if (-1 == mbAddrC.mb_num)
{
mbAddrC = m_cur_mb.CurrentBlockNeighbours.mb_above;
mbAddrC.block_num += iColumnNum - 1;
}
// when B & C partition is not available, use only A partition
if (-1 == (mbAddrB.mb_num & mbAddrC.mb_num))
{
*pPred = m_cur_mb.MVs[iListNum]->MotionVectors[iColumnNum - 1];
return;
}
else
{
// if one and only on of the reference indixes is equal to
// the current reference index, use owning it partition
{
H264DecoderMacroblockRefIdxs *pRefIdcs = m_gmbinfo->RefIdxs[iListNum];
Ipp8s *pCurRefIdcs = m_cur_mb.RefIdxs[iListNum]->RefIdxs;
Ipp32s curRefIdx = pCurRefIdcs[iColumnNum];
Ipp32s refIdxA, refIdxB, refIdxC;
Ipp32s iEqual;
refIdxA = pCurRefIdcs[iColumnNum - 1];
refIdxB = (-1 != mbAddrB.mb_num) ? (pRefIdcs[mbAddrB.mb_num].RefIdxs[mbAddrB.block_num]) : (-1);
refIdxC = (-1 != mbAddrC.mb_num) ? (pRefIdcs[mbAddrC.mb_num].RefIdxs[mbAddrC.block_num]) : (-1);
iEqual = 0;
iEqual += (curRefIdx == refIdxA) ? (1) : (0);
iEqual += (curRefIdx == refIdxB) ? (1) : (0);
iEqual += (curRefIdx == refIdxC) ? (1) : (0);
if (1 == iEqual)
{
H264DecoderMacroblockMVs *pMVs;
pMVs = m_gmbinfo->MV[iListNum];
if (curRefIdx == refIdxA)
*pPred = m_cur_mb.MVs[iListNum]->MotionVectors[iColumnNum - 1];
else if (curRefIdx == refIdxB)
*pPred = pMVs[mbAddrB.mb_num].MotionVectors[mbAddrB.block_num];
else
*pPred = pMVs[mbAddrC.mb_num].MotionVectors[mbAddrC.block_num];
return;
}
}
// there is true median of A, B and C partition
{
H264DecoderMotionVector mvA, mvB, mvC;
{
H264DecoderMacroblockMVs *pMVs = m_gmbinfo->MV[iListNum];
static H264DecoderMotionVector mvZero = {0, 0};
mvA = m_cur_mb.MVs[iListNum]->MotionVectors[iColumnNum - 1];
mvB = (-1 != mbAddrB.mb_num) ? (pMVs[mbAddrB.mb_num].MotionVectors[mbAddrB.block_num]) : (mvZero);
mvC = (-1 != mbAddrC.mb_num) ? (pMVs[mbAddrC.mb_num].MotionVectors[mbAddrC.block_num]) : (mvZero);
}
pPred->mvx = MEDIAN_OF_3(mvA.mvx, mvB.mvx, mvC.mvx);
pPred->mvy = MEDIAN_OF_3(mvA.mvy, mvB.mvy, mvC.mvy);
}
}
} // void H264SegmentDecoderMultiThreaded::ReconstructMVPredictorTopBlock(Ipp32s iListNum,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -