📄 umc_h264_segment_decoder_decode_mb.cpp
字号:
Ipp32s *pDistScaleFactorMV,
Ipp32s RefIndexL0,
Ipp32s scale,
Ipp32s scale_idx,
H264DecoderMotionVector &pFwdMV,
H264DecoderMotionVector &pBwdMV,
Ipp32s mvDistortion[2])
{
H264DecoderMotionVector MV = directMVs[pos];
switch(scale)
{
case 1:
MV.mvy /= 2;
break;
case -1:
MV.mvy *= 2;
break;
}
pFwdMV.mvx = (Ipp16s)((MV.mvx * pDistScaleFactorMV[RefIndexL0 >> scale_idx] + 128) >> 8);
pFwdMV.mvy = (Ipp16s)((MV.mvy * pDistScaleFactorMV[RefIndexL0 >> scale_idx] + 128) >> 8);
pBwdMV.mvx = (Ipp16s)(pFwdMV.mvx - MV.mvx);
pBwdMV.mvy = (Ipp16s)(pFwdMV.mvy - MV.mvy);
if (pFwdMV.mvy > mvDistortion[0])
mvDistortion[0] = pFwdMV.mvy;
if (pBwdMV.mvy > mvDistortion[1])
mvDistortion[1] = pBwdMV.mvy;
}
void H264SegmentDecoder::DecodeDirectMotionVectorsTemporal_8x8Inference()
{
// Use forward and backward ratios to scale the reference vectors to
// produce the forward and backward vectors, for either a 16x16 macroblock
// (16 vectors) or an 8x8 block (4 vectors)
// When bRefMBIsInter is false, set the MV to zero.
FactorArrayValue *pDistScaleFactorMV;
Ipp32u sb;
Ipp32s ref_mvoffset, sboffset = 0;
Ipp8s RefIndexL0 = 0, RefIndexL1 = 0;
H264DecoderMotionVector MV = {0};
Ipp32s mvxf, mvyf, mvxb, mvyb;
// set up pointers to where MV and RefIndex will be stored
H264DecoderMotionVector *pFwdMV = m_cur_mb.MVs[0]->MotionVectors;
H264DecoderMotionVector *pBwdMV = m_cur_mb.MVs[1]->MotionVectors;
Ipp8s *pRefIndexL0 = m_cur_mb.RefIdxs[0]->RefIdxs;
Ipp8s *pRefIndexL1 = m_cur_mb.RefIdxs[1]->RefIdxs;
Ipp32u scale_idx = pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo);
bool isAll8x8Same = true;
H264DecoderMotionVector * first_mv_fwd_all = &(pFwdMV[0]);
H264DecoderMotionVector * first_mv_bwd_all = &(pBwdMV[0]);
Ipp8s *first_refL0_all = &pRefIndexL0[0];
Ipp8s *first_refL1_all = &pRefIndexL1[0];
for (sb = 0; sb<4; sb++)
{
if (m_cur_mb.GlobalMacroblockInfo->sbtype[sb] != SBTYPE_DIRECT)
{
isAll8x8Same = false;
continue;
}
switch (sb)
{
case 0:
ref_mvoffset = 0; // upper left corner
sboffset = 0;
break;
case 1:
ref_mvoffset = 3; // upper right corner
sboffset = 2;
break;
case 2:
ref_mvoffset = 12; // lower left corner
sboffset = 8;
break;
case 3:
ref_mvoffset = 3 + 12; // lower right corner
sboffset = 2 + 8;
break;
}
Ipp32s MBCol;
Ipp32s scale;
MBCol = GetColocatedLocation(m_pRefPicList[1][0], GetReferenceField(m_pFields[1], 0), ref_mvoffset, &scale);
bool bRefMBIsInter = IS_INTER_MBTYPE(m_pRefPicList[1][0]->m_mbinfo.mbs[MBCol].mbtype);
RefIndexL1 = 0;
if (bRefMBIsInter)
{
H264DecoderMotionVector * directMVs;
// Get colocated MV and translated ref index
switch(m_pCurrentFrame->m_PictureStructureForDec)
{
case FLD_STRUCTURE:
GetDirectTemporalMVFLD(MBCol, ref_mvoffset, directMVs, RefIndexL0);
break;
case FRM_STRUCTURE:
GetDirectTemporalMV(MBCol,ref_mvoffset, directMVs, RefIndexL0);
break;
case AFRM_STRUCTURE:
GetDirectTemporalMVMBAFF(MBCol,ref_mvoffset, directMVs, RefIndexL0);
break;
default:
VM_ASSERT(false);
directMVs = 0;
}
if (scale_idx)
{
Ipp32s curfield = (m_CurMBAddr & 1);
Ipp32s ref0field = curfield ^ (RefIndexL0&1);
pDistScaleFactorMV = m_pSlice->GetDistScaleFactorMVAFF()->values[curfield][ref0field][curfield];
}
else
{
pDistScaleFactorMV = m_pSlice->GetDistScaleFactorMV()->values;
}
MV = directMVs[ref_mvoffset];
switch(scale)
{
case 1: MV.mvy/=2;
break;
case -1:MV.mvy*=2;
break;
}
// Reference MV from outside corner 4x4
mvxf = Ipp32s
((MV.mvx * pDistScaleFactorMV[RefIndexL0>>scale_idx] + 128) >> 8);
mvxb = mvxf - MV.mvx;
mvyf = Ipp32s
((MV.mvy * pDistScaleFactorMV[RefIndexL0>>scale_idx] + 128) >> 8);
mvyb = mvyf - MV.mvy;
}
else
{
mvxf = 0;
mvyf = 0;
mvxb = 0;
mvyb = 0;
RefIndexL0 = 0;
}
if (mvyf > m_MVDistortion[0])
m_MVDistortion[0] = mvyf;
if (mvyb > m_MVDistortion[1])
m_MVDistortion[1] = mvyb;
// Save MV to all 4 4x4's for this 8x8.
pFwdMV[sboffset].mvx = (Ipp16s) mvxf;
pFwdMV[sboffset].mvy = (Ipp16s) mvyf;
pBwdMV[sboffset].mvx = (Ipp16s) mvxb;
pBwdMV[sboffset].mvy = (Ipp16s) mvyb;
pFwdMV[sboffset+1].mvx = (Ipp16s) mvxf;
pFwdMV[sboffset+1].mvy = (Ipp16s) mvyf;
pBwdMV[sboffset+1].mvx = (Ipp16s) mvxb;
pBwdMV[sboffset+1].mvy = (Ipp16s) mvyb;
pFwdMV[sboffset+4].mvx = (Ipp16s) mvxf;
pFwdMV[sboffset+4].mvy = (Ipp16s) mvyf;
pBwdMV[sboffset+4].mvx = (Ipp16s) mvxb;
pBwdMV[sboffset+4].mvy = (Ipp16s) mvyb;
pFwdMV[sboffset+4+1].mvx = (Ipp16s) mvxf;
pFwdMV[sboffset+4+1].mvy = (Ipp16s) mvyf;
pBwdMV[sboffset+4+1].mvx = (Ipp16s) mvxb;
pBwdMV[sboffset+4+1].mvy = (Ipp16s) mvyb;
pRefIndexL0[sboffset] = RefIndexL0;
pRefIndexL1[sboffset] = RefIndexL1;
pRefIndexL0[sboffset+1] = RefIndexL0;
pRefIndexL1[sboffset+1] = RefIndexL1;
pRefIndexL0[sboffset+4] = RefIndexL0;
pRefIndexL1[sboffset+4] = RefIndexL1;
pRefIndexL0[sboffset+4+1] = RefIndexL0;
pRefIndexL1[sboffset+4+1] = RefIndexL1;
m_cur_mb.LocalMacroblockInfo->sbdir[sb]=D_DIR_DIRECT;
m_cur_mb.GlobalMacroblockInfo->sbtype[sb]=SBTYPE_8x8;
if (isAll8x8Same)
{
isAll8x8Same &=
(pFwdMV[sboffset].mvx == first_mv_fwd_all->mvx) &
(pFwdMV[sboffset].mvy == first_mv_fwd_all->mvy) &
(pBwdMV[sboffset].mvx == first_mv_bwd_all->mvx) &
(pBwdMV[sboffset].mvy == first_mv_bwd_all->mvy) &
(RefIndexL0 == *first_refL0_all) &
(RefIndexL1 == *first_refL1_all);
}
} // for sb
// set mbtype to 8x8 if it was not; use larger type if possible
if (isAll8x8Same)
{
m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_BIDIR;
}
else
{
m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTER_8x8;
}
} // void H264SegmentDecoder::DecodeDirectMotionVectorsTemporal_8x8Inference(H264DecoderFrame **pRefPicList0,
void H264SegmentDecoder::ComputeDirectSpatialRefIdx(Ipp32s *pRefIndexL0,
Ipp32s *pRefIndexL1)
{
Ipp32s refIdxL0 = -1;
Ipp32s refIdxL1 = -1;
// usual case
if (0 == m_pSliceHeader->MbaffFrameFlag)
{
H264DecoderBlockLocation mbAddr;
// get left block location
mbAddr = m_cur_mb.CurrentBlockNeighbours.mbs_left[0];
if (0 <= mbAddr.mb_num)
{
refIdxL0 = m_gmbinfo->RefIdxs[0][mbAddr.mb_num].RefIdxs[mbAddr.block_num];
refIdxL1 = m_gmbinfo->RefIdxs[1][mbAddr.mb_num].RefIdxs[mbAddr.block_num];
}
// get aboue location
mbAddr = m_cur_mb.CurrentBlockNeighbours.mb_above;
if (0 <= mbAddr.mb_num)
{
Ipp32u tmp;
tmp = m_gmbinfo->RefIdxs[0][mbAddr.mb_num].RefIdxs[mbAddr.block_num];
refIdxL0 = (((Ipp32u) refIdxL0) <= tmp) ? (refIdxL0) : (tmp);
tmp = m_gmbinfo->RefIdxs[1][mbAddr.mb_num].RefIdxs[mbAddr.block_num];
refIdxL1 = (((Ipp32u) refIdxL1) <= tmp) ? (refIdxL1) : (tmp);
}
// get above left (right) location
mbAddr = m_cur_mb.CurrentBlockNeighbours.mb_above_right;
if (0 <= mbAddr.mb_num)
{
Ipp32u tmp;
tmp = m_gmbinfo->RefIdxs[0][mbAddr.mb_num].RefIdxs[mbAddr.block_num];
refIdxL0 = (((Ipp32u) refIdxL0) <= tmp) ? (refIdxL0) : (tmp);
tmp = m_gmbinfo->RefIdxs[1][mbAddr.mb_num].RefIdxs[mbAddr.block_num];
refIdxL1 = (((Ipp32u) refIdxL1) <= tmp) ? (refIdxL1) : (tmp);
}
else
{
mbAddr = m_cur_mb.CurrentBlockNeighbours.mb_above_left;
if (0 <= mbAddr.mb_num)
{
Ipp32u tmp;
tmp = m_gmbinfo->RefIdxs[0][mbAddr.mb_num].RefIdxs[mbAddr.block_num];
refIdxL0 = (((Ipp32u) refIdxL0) <= tmp) ? (refIdxL0) : (tmp);
tmp = m_gmbinfo->RefIdxs[1][mbAddr.mb_num].RefIdxs[mbAddr.block_num];
refIdxL1 = (((Ipp32u) refIdxL1) <= tmp) ? (refIdxL1) : (tmp);
}
}
}
// MBAFF case
else
{
H264DecoderBlockLocation mbAddr;
H264DecoderMacroblockGlobalInfo *pInfo;
Ipp32s cur_field;
pInfo = m_gmbinfo->mbs;
cur_field = GetMBFieldDecodingFlag(pInfo[m_CurMBAddr]);
//
// do not try to find corresponding place in the standard
// we use optimized calculations
//
// get left block location
mbAddr = m_cur_mb.CurrentBlockNeighbours.mbs_left[0];
if (0 <= mbAddr.mb_num)
{
Ipp32s neighbour_frame = GetMBFieldDecodingFlag(pInfo[mbAddr.mb_num]) ^ 1;
refIdxL0 = m_gmbinfo->RefIdxs[0][mbAddr.mb_num].RefIdxs[mbAddr.block_num];
refIdxL1 = m_gmbinfo->RefIdxs[1][mbAddr.mb_num].RefIdxs[mbAddr.block_num];
refIdxL0 <<= (cur_field + neighbour_frame);
refIdxL1 <<= (cur_field + neighbour_frame);
}
// get aboue location
mbAddr = m_cur_mb.CurrentBlockNeighbours.mb_above;
if (0 <= mbAddr.mb_num)
{
Ipp32u tmp;
Ipp32s neighbour_frame = GetMBFieldDecodingFlag(pInfo[mbAddr.mb_num]) ^ 1;
tmp = m_gmbinfo->RefIdxs[0][mbAddr.mb_num].RefIdxs[mbAddr.block_num];
tmp <<= (cur_field + neighbour_frame);
refIdxL0 = (((Ipp32u) refIdxL0) <= tmp) ? (refIdxL0) : (tmp);
tmp = m_gmbinfo->RefIdxs[1][mbAddr.mb_num].RefIdxs[mbAddr.block_num];
tmp <<= (cur_field + neighbour_frame);
refIdxL1 = (((Ipp32u) refIdxL1) <= tmp) ? (refIdxL1) : (tmp);
}
// get above left (right) location
mbAddr = m_cur_mb.CurrentBlockNeighbours.mb_above_right;
if (0 <= mbAddr.mb_num)
{
Ipp32u tmp;
Ipp32s neighbour_frame = GetMBFieldDecodingFlag(pInfo[mbAddr.mb_num]) ^ 1;
tmp = m_gmbinfo->RefIdxs[0][mbAddr.mb_num].RefIdxs[mbAddr.block_num];
tmp <<= (cur_field + neighbour_frame);
refId
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -