📄 umc_h264_segment_decoder_decode_mb.cpp
字号:
else
{
// Check for more than one predictor from different reference frame
// If there is only one predictor from this ref frame, then sonly will
// be pointing to it.
if ((*pRefIxl) != RefIndex)
uSameRefPicCount--;
else
{
sonly = sl;
}
if ((*pRefIxa) != RefIndex)
uSameRefPicCount--;
else
{
sonly = sa;
}
if ((*pRefIxr) != RefIndex)
uSameRefPicCount--;
else
{
sonly = sr;
}
if (uSameRefPicCount != 1)
{
// "normal" median prediction
px0 = sl->mvx;
px1 = sa->mvx;
px2 = sr->mvx;
#define MEDIAN_OF_3(a, b, c) (IPP_MIN((a),(b))) ^ (IPP_MIN((b),(c))) ^ (IPP_MIN((c),(a)))
*pMVx = MEDIAN_OF_3(px0, px1, px2);
py0 = sl->mvy;
py1 = sa->mvy;
py2 = sr->mvy;
*pMVy = MEDIAN_OF_3(py0, py1, py2);
}
else
{
// return MV at sonly
*pMVx = sonly->mvx;
*pMVy = sonly->mvy;
}
}
}
return;
} // void H264SegmentDecoder::ComputeMotionVectorPredictors(const Ipp8u ListNum,
// Used to obtain colocated motion vector and reference index for temporal
// direct B. Called only when the colocated MB is not INTRA. Uses the
// L0 and L1 reference indices of colocated MB to choose MV. Also translates
// the colocated reference index to be used into the correct L0 index
// for this slice.
void H264SegmentDecoder::GetDirectTemporalMV(Ipp32s MBCol,
Ipp32u ipos, // offset into MV and RefIndex storage
H264DecoderMotionVector *&MVL0, // return colocated MV here
Ipp8s &RefIndexL0) // return ref index here
{
//I'm not sure about this function correctness
VM_ASSERT(m_pRefPicList[1][0]);
H264DecoderMotionVector *pRefMVL0;
H264DecoderMotionVector *pRefMVL1;
Ipp8s *pRefRefIndexL0;
Ipp8s *pRefRefIndexL1;
H264DecoderFrame **pRefRefPicList;
// Set pointers to colocated list 0 ref index and MV
pRefRefIndexL0 = &m_pRefPicList[1][0]->m_mbinfo.RefIdxs[0][MBCol].RefIdxs[ipos];
pRefMVL0 = &m_pRefPicList[1][0]->m_mbinfo.MV[0][MBCol].MotionVectors[0];
Ipp16u uRefSliceNum=m_pRefPicList[1][0]->m_mbinfo.mbs[MBCol].slice_id;
VM_ASSERT(pRefRefIndexL0);
VM_ASSERT(pRefMVL0);
// Get ref index and MV from L0 of colocated ref MB if the
// colocated L0 ref index is >=0. Else use L1.
if (*pRefRefIndexL0 >= 0)
{
// Use colocated L0
MVL0 = pRefMVL0;
RefIndexL0 = *pRefRefIndexL0;
// Get pointer to ref pic list 0 of colocated
pRefRefPicList = m_pRefPicList[1][0]->GetRefPicList(uRefSliceNum, 0)->m_RefPicList;
}
else
{
// Use Ref L1
// Set pointers to colocated list 1 ref index and MV
pRefRefIndexL1 = &m_pRefPicList[1][0]->m_mbinfo.RefIdxs[1][MBCol].RefIdxs[ipos];
pRefMVL1 = &m_pRefPicList[1][0]->m_mbinfo.MV[1][MBCol].MotionVectors[0];
VM_ASSERT(pRefRefIndexL1);
VM_ASSERT(pRefMVL1);
RefIndexL0 = *pRefRefIndexL1;
// Use colocated L1
MVL0 = pRefMVL1;
// Get pointer to ref pic list 1 of colocated
pRefRefPicList = m_pRefPicList[1][0]->GetRefPicList(uRefSliceNum, 1)->m_RefPicList;
}
if (m_pRefPicList[1][0]->m_PictureStructureForDec==AFRM_STRUCTURE)
{
VM_ASSERT(0);//can't happen
AdjustIndex((MBCol & 1), GetMBFieldDecodingFlag(m_pRefPicList[1][0]->m_mbinfo.mbs[MBCol]), RefIndexL0);
}
VM_ASSERT(pRefRefPicList[RefIndexL0]);
Ipp32s index = pRefRefPicList[RefIndexL0]->m_index;
// find matching reference frame on current slice list 0
RefIndexL0 = 0;
for (; m_pRefPicList[0][RefIndexL0]; RefIndexL0++)
{
if (m_pRefPicList[0][RefIndexL0]->m_index == index)
{
return;
}
}
// can't happen
RefIndexL0 = 0;
} // void H264SegmentDecoder::GetDirectTemporalMV(Ipp32s MBCol,
void H264SegmentDecoder::GetDirectTemporalMVFLD(Ipp32s MBCol,
Ipp32u ipos, // offset into MV and RefIndex storage
H264DecoderMotionVector *& MVL0, // return colocated MV here
Ipp8s &RefIndexL0) // return ref index here
{
//I'm not sure about this function correctness
VM_ASSERT(m_pRefPicList[1][0]);
H264DecoderMotionVector *pRefMVL0;
H264DecoderMotionVector *pRefMVL1;
Ipp8s *pRefRefIndexL0;
Ipp8s *pRefRefIndexL1;
H264DecoderFrame **pRefRefPicList;
// Set pointers to colocated list 0 ref index and MV
pRefRefIndexL0 = &m_pRefPicList[1][0]->m_mbinfo.RefIdxs[0][MBCol].RefIdxs[ipos];
pRefMVL0 = &m_pRefPicList[1][0]->m_mbinfo.MV[0][MBCol].MotionVectors[0];
Ipp32s uRefSliceNum = m_pRefPicList[1][0]->m_mbinfo.mbs[MBCol].slice_id;
ReferenceFlags *pRefFields;
VM_ASSERT(pRefRefIndexL0);
VM_ASSERT(pRefMVL0);
// Get ref index and MV from L0 of colocated ref MB if the
// colocated L0 ref index is >=0. Else use L1.
if (*pRefRefIndexL0 >= 0)
{
// Use colocated L0
MVL0 = pRefMVL0;
RefIndexL0 = *pRefRefIndexL0;
// Get pointer to ref pic list 0 of colocated
pRefRefPicList = m_pRefPicList[1][0]->GetRefPicList(uRefSliceNum, 0)->m_RefPicList;
pRefFields = m_pRefPicList[1][0]->GetRefPicList(uRefSliceNum, 0)->m_Flags;
}
else
{
// Use Ref L1
// Set pointers to colocated list 1 ref index and MV
pRefRefIndexL1 = &m_pRefPicList[1][0]->m_mbinfo.RefIdxs[1][MBCol].RefIdxs[ipos];
pRefMVL1 = &m_pRefPicList[1][0]->m_mbinfo.MV[1][MBCol].MotionVectors[0];
VM_ASSERT(pRefRefIndexL1);
VM_ASSERT(pRefMVL1);
RefIndexL0 = *pRefRefIndexL1;
// Use colocated L1
MVL0 = pRefMVL1;
// Get pointer to ref pic list 1 of colocated
pRefRefPicList = m_pRefPicList[1][0]->GetRefPicList(uRefSliceNum, 1)->m_RefPicList;
pRefFields = m_pRefPicList[1][0]->GetRefPicList(uRefSliceNum, 1)->m_Flags;
}
// Translate the reference index of the colocated to current
// L0 index to the same reference picture, using picNum or
// LongTermPicNum as id criteria.
Ipp32s num_ref;
Ipp32s force_value;
if (m_pRefPicList[1][0]->m_PictureStructureForDec == FRM_STRUCTURE)
{
num_ref = m_field_index;
force_value = 1;
}
else if (m_pRefPicList[1][0]->m_PictureStructureForDec == AFRM_STRUCTURE)
{
if (GetMBFieldDecodingFlag(m_pRefPicList[1][0]->m_mbinfo.mbs[MBCol]))
{
Ipp32s field_selector = RefIndexL0&1;
RefIndexL0>>=1;
num_ref = (field_selector^(MBCol & 1));
force_value = 1;
}
else
{
num_ref = m_field_index;
force_value = 1;
}
}
else
{
num_ref = GetReferenceField(pRefFields, RefIndexL0);
force_value = 1;
}
VM_ASSERT(pRefRefPicList[RefIndexL0]);
Ipp32s index = pRefRefPicList[RefIndexL0]->m_index;
// find matching reference frame on current slice list 0
RefIndexL0 = 0;
for (; m_pRefPicList[0][RefIndexL0] != NULL; RefIndexL0++)
{
if (m_pRefPicList[0][RefIndexL0]->m_index == index &&
(force_value == 3 || GetReferenceField(m_pFields[0], RefIndexL0) == num_ref))
{
return;
}
}
// can't happen
RefIndexL0 = 0;
} // void H264SegmentDecoder::GetDirectTemporalMVFLD(Ipp32s MBCol,
void H264SegmentDecoder::GetDirectTemporalMVMBAFF(Ipp32s MBCol,
Ipp32u ipos, // offset into MV and RefIndex storage
H264DecoderMotionVector *& MVL0, // return colocated MV here
Ipp8s &RefIndexL0) // return ref index here
{
//I'm not sure about this function correctness
VM_ASSERT(m_pRefPicList[1][0]);
H264DecoderMotionVector *pRefMVL0;
H264DecoderMotionVector *pRefMVL1;
Ipp8s *pRefRefIndexL0;
Ipp8s *pRefRefIndexL1;
H264DecoderFrame **pRefRefPicList;
// Set pointers to colocated list 0 ref index and MV
pRefRefIndexL0 = &m_pRefPicList[1][0]->m_mbinfo.RefIdxs[0][MBCol].RefIdxs[ipos];
pRefMVL0 = &m_pRefPicList[1][0]->m_mbinfo.MV[0][MBCol].MotionVectors[0];
Ipp16u uRefSliceNum=m_pRefPicList[1][0]->m_mbinfo.mbs[MBCol].slice_id;
Ipp32u scale_idx=GetMBFieldDecodingFlag(m_pRefPicList[1][0]->m_mbinfo.mbs[MBCol]);
Ipp32u back_scale_idx=pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo);
Ipp32u field_selector = 0;
ReferenceFlags *pFields;
VM_ASSERT(pRefRefIndexL0);
VM_ASSERT(pRefMVL0);
// Get ref index and MV from L0 of colocated ref MB if the
// colocated L0 ref index is >=0. Else use L1.
RefIndexL0 = *pRefRefIndexL0;
if (RefIndexL0 >= 0)
{
// Use colocated L0
MVL0 = pRefMVL0;
// Get pointer to ref pic list 0 of colocated
pRefRefPicList = m_pRefPicList[1][0]->GetRefPicList(uRefSliceNum, 0)->m_RefPicList;
pFields = m_pRefPicList[1][0]->GetRefPicList(uRefSliceNum, 0)->m_Flags;
}
else
{
// Use Ref L1
// Set pointers to colocated list 1 ref index and MV
pRefRefIndexL1 = &m_pRefPicList[1][0]->m_mbinfo.RefIdxs[1][MBCol].RefIdxs[ipos];
pRefMVL1 = &m_pRefPicList[1][0]->m_mbinfo.MV[1][MBCol].MotionVectors[0];
pFields = m_pRefPicList[1][0]->GetRefPicList(uRefSliceNum, 1)->m_Flags;
VM_ASSERT(pRefRefIndexL1);
VM_ASSERT(pRefMVL1);
RefIndexL0 = *pRefRefIndexL1;
// Use colocated L1
MVL0 = pRefMVL1;
// Get pointer to ref pic list 1 of colocated
pRefRefPicList = m_pRefPicList[1][0]->GetRefPicList(uRefSliceNum, 1)->m_RefPicList;
}
if (m_pRefPicList[1][0]->m_PictureStructureForDec == AFRM_STRUCTURE)
{
AdjustIndex((MBCol & 1), GetMBFieldDecodingFlag(m_pRefPicList[1][0]->m_mbinfo.mbs[MBCol]), RefIndexL0);
field_selector = RefIndexL0&scale_idx;
RefIndexL0>>=scale_idx;
}
else if (m_pRefPicList[1][0]->m_PictureStructureForDec < FRM_STRUCTURE)
{
Ipp8s ref1field = (MBCol >= m_pRefPicList[1][0]->totalMBs);
field_selector = (ref1field != GetReferenceField(pFields, RefIndexL0));
}
VM_ASSERT(pRefRefPicList[RefIndexL0]);
VM_ASSERT(m_pRefPicList[1][0]->m_PictureStructureForDec != FRM_STRUCTURE);
Ipp32s index = pRefRefPicList[RefIndexL0]->m_index;
// find matching reference frame on current slice list 0
RefIndexL0 = 0;
for (; m_pRefPicList[0][RefIndexL0]; RefIndexL0++)
{
if (m_pRefPicList[0][RefIndexL0]->m_index == index)
{
RefIndexL0 <<= back_scale_idx;
RefIndexL0 = (Ipp8s)(RefIndexL0 | (field_selector&back_scale_idx));
return;
}
}
// can't happen
RefIndexL0 = 0;
} // void H264SegmentDecoder::GetDirectTemporalMVMBAFF(Ipp32s MBCol,
inline void GetScaledMV(Ipp32s pos,
H264DecoderMotionVector *directMVs,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -