📄 umc_h264_dec_slice_decoder_decode_pic.cpp
字号:
// Long term references:
// The ordered list is the same for L0 and L1, is ordered by ascending
// LongTermPicNum. The ordered list is created using local temp then
// appended to the L0 and L1 lists after the short-term references.
for (pFrm = pHead; pFrm; pFrm = pFrm->future())
{
if (pFrm->isShortTermRef())
{
// add to ordered list
FrmPicOrderCnt = pFrm->PicOrderCnt(0,2);//returns POC of reference field (or min if both are reference)
if (FrmPicOrderCnt <= CurrPicOrderCnt)
{
// Previous reference to L0, order large to small
j=0;
while (j < NumFramesInL0List &&
(pRefPicList0[j]->PicOrderCnt(0,2) > FrmPicOrderCnt))
j++;
// make room if needed
if (pRefPicList0[j])
{
for (k = NumFramesInL0List; k > j; k--)
{
// Avoid writing beyond end of list
if (k > MAX_NUM_REF_FRAMES-1)
{
VM_ASSERT(0);
bError = true;
break;
}
pRefPicList0[k] = pRefPicList0[k-1];
}
}
// add the short-term reference
pRefPicList0[j] = pFrm;
NumFramesInL0List++;
}
else
{
// Future reference to L1, order small to large
j=0;
while (j<NumFramesInL1List &&
pRefPicList1[j]->PicOrderCnt(0,2) < FrmPicOrderCnt)
j++;
// make room if needed
if (pRefPicList1[j])
{
for (k=NumFramesInL1List; k>j; k--)
{
// Avoid writing beyond end of list
if (k > MAX_NUM_REF_FRAMES-1)
{
VM_ASSERT(0);
bError = true;
break;
}
pRefPicList1[k] = pRefPicList1[k-1];
}
}
// add the short-term reference
pRefPicList1[j] = pFrm;
NumFramesInL1List++;
}
} // short-term B
else if (pFrm->isLongTermRef())
{
// long term reference
LongTermPicNum = pFrm->LongTermPicNum(0,2);
// order smallest to largest
j=0;
while (j < NumFramesInLTList &&
LTRefPicList[j]->LongTermPicNum(0,2) < LongTermPicNum)
j++;
// make room if needed
if (LTRefPicList[j])
{
for (k=NumFramesInLTList; k>j; k--)
{
// Avoid writing beyond end of list
if (k > MAX_NUM_REF_FRAMES-1)
{
VM_ASSERT(0);
bError = true;
break;
}
LTRefPicList[k] = LTRefPicList[k-1];
}
}
// add the long-term reference
LTRefPicList[j] = pFrm;
NumFramesInLTList++;
} // long term reference
if (bError) break;
} // for pFrm
if ((NumFramesInL0List+NumFramesInL1List+NumFramesInLTList) < MAX_NUM_REF_FRAMES)
{
// Complete L0 and L1 lists
// Add future short-term references to L0 list, after previous
for (i=0; i<NumFramesInL1List; i++)
pRefPicList0[NumFramesInL0List+i] = pRefPicList1[i];
// Add previous short-term references to L1 list, after future
for (i=0; i<NumFramesInL0List; i++)
pRefPicList1[NumFramesInL1List+i] = pRefPicList0[i];
// Add long term list to both L0 and L1
for (i=0; i<NumFramesInLTList; i++)
{
pRefPicList0[NumFramesInL0List+NumFramesInL1List+i] = LTRefPicList[i];
pRefPicList1[NumFramesInL0List+NumFramesInL1List+i] = LTRefPicList[i];
}
// Special rule: When L1 has more than one entry and L0 == L1, all entries,
// swap the first two entries of L1.
// They can be equal only if there are no future or no previous short-term
// references. For fields will be done later.
/*
if ((NumFramesInL0List == 0 || NumFramesInL1List == 0) &&
((NumFramesInL0List+NumFramesInL1List+NumFramesInLTList) > 1))
{
pRefPicList1[0] = pRefPicList0[1];
pRefPicList1[1] = pRefPicList0[0];
}*/
}
else
{
// too many reference frames
VM_ASSERT(0);
}
}
rli.m_iNumFramesInL0List = NumFramesInL0List;
rli.m_iNumFramesInL1List = NumFramesInL1List;
rli.m_iNumFramesInLTList = NumFramesInLTList;
} // void H264Slice::InitBSliceRefPicLists(bool bIsFieldSlice,
#define CalculateDSF(index, value, value_mv) \
/* compute scaling ratio for temporal direct and implicit weighting*/ \
tb = picCntCur - picCntRef0; /* distance from previous */ \
td = picCntRef1 - picCntRef0; /* distance between ref0 and ref1 */ \
\
/* special rule: if td is 0 or if L0 is long-term reference, use */ \
/* L0 motion vectors and equal weighting.*/ \
if (td == 0 || pRefPicList0[index]->isLongTermRef(pRefPicList0[index]->GetNumberByParity(RefFieldTop))) \
{ \
/* These values can be used directly in scaling calculations */ \
/* to get back L0 or can use conditional test to choose L0. */ \
value = 128; /* for equal weighting */ \
value_mv = 256; \
} \
else \
{ \
tb = IPP_MAX(-128,tb); \
tb = IPP_MIN(127,tb); \
td = IPP_MAX(-128,td); \
td = IPP_MIN(127,td); \
\
VM_ASSERT(td != 0); \
\
tx = (16384 + abs(td/2))/td; \
\
DistScaleFactor = (tb*tx + 32)>>6; \
DistScaleFactor = IPP_MAX(-1024, DistScaleFactor); \
DistScaleFactor = IPP_MIN(1023, DistScaleFactor); \
\
if (isL1LongTerm || DistScaleFactor < -256 || DistScaleFactor > 512) \
value = 128; /* equal weighting */ \
else \
value = (FactorArrayValue)DistScaleFactor; \
\
value_mv = (FactorArrayValue)DistScaleFactor; \
}
void H264Slice::InitDistScaleFactor(Ipp32s NumL0RefActive,
Ipp32s NumL1RefActive,
H264DecoderFrame **pRefPicList0,
H264DecoderFrame **pRefPicList1,
ReferenceFlags *pFields0,
ReferenceFlags *pFields1)
{
Ipp32s L0Index, L1Index;
Ipp32s picCntRef0;
Ipp32s picCntRef1;
Ipp32s picCntCur;
Ipp32s DistScaleFactor;
FactorArrayValue *pDistScaleFactor;
FactorArrayValue *pDistScaleFactorMV;
Ipp32s tb;
Ipp32s td;
Ipp32s tx;
VM_ASSERT(NumL0RefActive <= MAX_NUM_REF_FRAMES);
VM_ASSERT(pRefPicList1[0]);
bool isL1LongTerm = false;
picCntCur = m_pCurrentFrame->PicOrderCnt(m_pCurrentFrame->GetNumberByParity(m_SliceHeader.bottom_field_flag));
bool isNeedScale = (m_pPicParamSet->weighted_bipred_idc == 2);
if (!isNeedScale)
NumL1RefActive = 1;
for (L1Index = NumL1RefActive - 1; L1Index >=0 ; L1Index--)
{
pDistScaleFactor = m_DistScaleFactor.values[L1Index]; //frames or fields
pDistScaleFactorMV = m_DistScaleFactorMV.values; //frames or fields
Ipp32s RefField = m_pCurrentFrame->m_PictureStructureForDec >= FRM_STRUCTURE ?
0 : GetReferenceField(pFields1, L1Index);
picCntRef1 = pRefPicList1[L1Index]->PicOrderCnt(pRefPicList1[L1Index]->GetNumberByParity(RefField));
isL1LongTerm = pRefPicList1[L1Index]->isLongTermRef(pRefPicList1[L1Index]->GetNumberByParity(RefField));
for (L0Index = 0; L0Index < NumL0RefActive; L0Index++)
{
Ipp32s RefFieldTop = (m_pCurrentFrame->m_PictureStructureForDec >= FRM_STRUCTURE) ?
0 : GetReferenceField(pFields0, L0Index);
picCntRef0 = pRefPicList0[L0Index]->PicOrderCnt(pRefPicList0[L0Index]->GetNumberByParity(RefFieldTop));
CalculateDSF(L0Index, pDistScaleFactor[L0Index], pDistScaleFactorMV[L0Index]);
}
}
if (m_pCurrentFrame->m_PictureStructureForDec == AFRM_STRUCTURE)
{
if (!m_DistScaleFactorAFF && isNeedScale)
m_DistScaleFactorAFF = new FactorArrayAFF();
if (!m_DistScaleFactorMVAFF)
m_DistScaleFactorMVAFF = new FactorArrayMVAFF();
if (!isNeedScale)
{
m_DistScaleFactorAFF = &m_StaticFactorArrayAFF;
}
for (L1Index = NumL1RefActive - 1; L1Index >=0 ; L1Index--)
{
// [curmb field],[ref1field],[ref0field]
pDistScaleFactor = m_DistScaleFactorAFF->values[L1Index][0][0][0]; //complementary field pairs, cf=top r1=top,r0=top
pDistScaleFactorMV = m_DistScaleFactorMVAFF->values[0][0][0]; //complementary field pairs, cf=top r1=top,r0=top
picCntCur = m_pCurrentFrame->PicOrderCnt(m_pCurrentFrame->GetNumberByParity(0), 1);
picCntRef1 = pRefPicList1[L1Index]->PicOrderCnt(pRefPicList1[L1Index]->GetNumberByParity(0), 1);
isL1LongTerm = pRefPicList1[L1Index]->isLongTermRef(pRefPicList1[L1Index]->GetNumberByParity(0));
for (L0Index=0; L0Index<NumL0RefActive; L0Index++)
{
VM_ASSERT(pRefPicList0[L0Index]);
Ipp32s RefFieldTop = 0;
picCntRef0 = pRefPicList0[L0Index]->PicOrderCnt(pRefPicList0[L0Index]->GetNumberByParity(0), 1);
CalculateDSF(L0Index, pDistScaleFactor[L0Index], pDistScaleFactorMV[L0Index]);
}
pDistScaleFactor = m_DistScaleFactorAFF->values[L1Index][0][1][0]; //complementary field pairs, cf=top r1=top,r0=bottom
pDistScaleFactorMV = m_DistScaleFactorMVAFF->values[0][1][0]; //complementary field pairs, cf=top r1=top,r0=bottom
for (L0Index=0; L0Index < NumL0RefActive; L0Index++)
{
VM_ASSERT(pRefPicList0[L0Index]);
Ipp32s RefFieldTop = 1;
picCntRef0 = pRefPicList0[L0Index]->PicOrderCnt(pRefPicList0[L0Index]->GetNumberByParity(1), 1);
CalculateDSF(L0Index, pDistScaleFactor[L0Index], pDistScaleFactorMV[L0Index]);
}
pDistScaleFactor = m_DistScaleFactorAFF->values[L1Index][0][0][1]; //complementary field pairs, cf=top r1=top,r0=top
pDistScaleFactorMV = m_DistScaleFactorMVAFF->values[0][0][1]; //complementary field pairs, cf=top r1=top,r0=top
picCntRef1 = pRefPicList1[L1Index]->PicOrderCnt(pRefPicList1[L1Index]->GetNumberByParity(1), 1);
isL1LongTerm = pRefPicList1[L1Index]->isLongTermRef(pRefPicList1[L1Index]->GetNumberByParity(1));
for (L0Index=0; L0Index<NumL0RefActive; L0Index++)
{
VM_ASSERT(pRefPicList0[L0Index]);
Ipp32s RefFieldTop = 0;
picCntRef0 = pRefPicList0[L0Index]->PicOrderCnt(pRefPicList0[L0Index]->GetNumberByParity(0), 1);
CalculateDSF(L0Index, pDistScaleFactor[L0Index], pDistScaleFactorMV[L0Index]);
}
pDistScaleFactor = m_DistScaleFactorAFF->values[L1Index][0][1][1]; //complementary field pairs, cf=top r1=top,r0=bottom
pDistScaleFactorMV = m_DistScaleFactorMVAFF->values[0][1][1]; //complementary field pairs, cf=top r1=top,r0=bottom
for (L0Index=0; L0Index < NumL0RefActive; L0Index++)
{
VM_ASSERT(pRefPicList0[L0Index]);
Ipp32s RefFieldTop = 1;
picCntRef0 = pRefPicList0[L0Index]->PicOrderCnt(pRefPicList0[L0Index]->GetNumberByParity(1),1);
CalculateDSF(L0Index, pDistScaleFactor[L0Index], pDistScaleFactorMV[L0Index]);
}
/*--------------------------------------------------------------------*/
picCntCur = m_pCurrentFrame->PicOrderCnt(m_pCurrentFrame->GetNumberByParity(1), 1);
picCntRef1 = pRefPicList1[L1Index]->PicOrderCnt(pRefPicList1[L1Index]->GetNumberByParity(0), 1);
isL1LongTerm = pRefPicList1[L1Index]->isLongTermRef(pRefPicList1[L1Index]->GetNumberByParity(0));
pDistScaleFactor = m_DistScaleFactorAFF->values[L1Index][1][0][0]; //complementary field pairs, cf=bottom r1=bottom,r0=top
pDistScaleFactorMV = m_DistScaleFactorMVAFF->values[1][0][0]; //complementary field pairs, cf=bottom r1=bottom,r0=top
for (L0Index=0; L0Index<NumL0RefActive; L0Index++)
{
VM_ASSERT(pRefPicList0[L0Index]);
Ipp32s RefFieldTop = 0;
picCntRef0 = pRefPicList0[L0Index]->PicOrderCnt(pRefPicList0[L0Index]->GetNumberByParity(0), 1);
CalculateDSF(L0Index, pDistScaleFactor[L0Index], pDistScaleFactorMV[L0Index]);
}
pDistScaleFactor = m_DistScaleFactorAFF->values[L1Index][1][1][0]; //complementary field pairs, cf=bottom r1=bottom,r0=bottom
pDistScaleFactorMV = m_DistScaleFactorMVAFF->values[1][1][0]; //complementary field pairs, cf=bottom r1=bottom,r0=bottom
for (L0Index=0; L0Index < NumL0RefActive; L0Index++)
{
VM_ASSERT(pRefPicList0[L0Index]);
Ipp32s RefFieldTop = 1;
picCntRef0 = pRefPicList0[L0Index]->PicOrderCnt(pRefPicList0[L0Index]->GetNumberByParity(1), 1);
CalculateDSF(L0Index, pDistScaleFactor[L0Index], pDistScaleFactorMV[L0Index]);
}
picCntRef1 = pRefPicList1[L1Index]->PicOrderCnt(pRefPicList1[L1Index]->GetNumberByParity(1), 1);
isL1LongTerm = pRefPicList1[L1Index]->isLongTermRef(pRefPicList1[L1Index]->GetNumberByParity(1));
pDistScaleFactor = m_DistScaleFactorAFF->values[L1Index][1][0][1]; //complementary field pairs, cf=bottom r1=bottom,r0=top
pDistScaleFactorMV = m_DistScaleFactorMVAFF->values[1][0][1]; //complementary field pairs, cf=bottom r1=bottom,r0=top
for (L0Index=0; L0Index<NumL0RefActive; L0Index++)
{
VM_ASSERT(pRefPicList0[L0Index]);
Ipp32s RefFieldTop = 0;
picCntRef0 = pRefPicList0[L0Index]->PicOrderCnt(pRefPicList0[L0Index]->GetNumberByParity(0), 1);
CalculateDSF(L0Index, pDistScaleFactor[L0Index], pDistScaleFactorMV[L0Index]);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -