📄 umc_h264_dec_decode_pic.cpp
字号:
// references. 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); } } // not field slice else { Ipp32s CurrPicOrderCnt = m_pCurrentFrame->PicOrderCnt(m_field_index); // Short term references: // Need L0 and L1 lists. Both contain 2 sets of reference frames ordered // by PicOrderCnt. The "previous" set contains the reference frames with // a PicOrderCnt < current frame. The "future" set contains the reference // frames with a PicOrderCnt > current frame. In both cases the ordering // is from closest to current frame to farthest. L0 has the previous set // followed by the future set; L1 has the future set followed by the previous set. // Accomplish this by one pass through the decoded frames list creating // the ordered previous list in the L0 array and the ordered future list // in the L1 array. Then copy from both to the other for the second set. // 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; 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); } } // for pFrm } // If the number of reference pictures on the lists is greater than the // number of active references, discard the "extras". /* if (NumFramesInL0List > NumL0RefActive) { for (i=NumFramesInL0List-1; i>=NumL0RefActive; i--) pRefPicList0[i] = NULL; } if (NumFramesInL1List > NumL1RefActive) { for (i=NumFramesInL1List-1; i>=NumL1RefActive; i--) pRefPicList1[i] = NULL; }*/ m_NumFramesInL0List = NumFramesInL0List; m_NumFramesInL1List = NumFramesInL1List; m_NumFramesInLTList = NumFramesInLTList;} // InitBSliceRefPicLists//////////////////////////////////////////////////////////////////////////////// InitDistScaleFactor// Calculates the scaling factor used for B slice temporal motion vector// scaling and for B slice bidir predictin weighting using the picordercnt// values from the current and both reference frames, saving the result// to the DistScaleFactor array for future use. The array is initialized// with out of range values whenever a bitstream unit is received that// might invalidate the data (for example a B slice header resulting in// modified reference picture lists). For scaling, the list1 [0] entry// is always used.//////////////////////////////////////////////////////////////////////////////#define CalculateDSF(index) \ /* 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(m_field_index)) \ { \ /* These values can be used directly in scaling calculations */ \ /* to get back L0 or can use conditional test to choose L0. */ \ pDistScaleFactor[L0Index] = 128; /* for equal weighting */ \ pDistScaleFactorMV[L0Index] = 256; \ } \ else \ { \ \ tb = MAX(-128,tb); \ tb = MIN(127,tb); \ td = MAX(-128,td); \ td = MIN(127,td); \ \ VM_ASSERT(td != 0); \ \ tx = (16384 + abs(td/2))/td; \ \ DistScaleFactor = (tb*tx + 32)>>6; \ DistScaleFactor = MAX(-1024, DistScaleFactor); \ DistScaleFactor = MIN(1023, DistScaleFactor); \ \ if (DistScaleFactor < -256 || DistScaleFactor > 512) \ pDistScaleFactor[L0Index] = 128; /* equal weighting */ \ else \ pDistScaleFactor[L0Index] = DistScaleFactor; \ \ pDistScaleFactorMV[L0Index] = DistScaleFactor; \ }void H264VideoDecoder::InitDistScaleFactor( Ipp32s NumL0RefActive, H264DecoderFrame **pRefPicList0, H264DecoderFrame **pRefPicList1, Ipp8s *pFields0, Ipp8s *pFields1){ Ipp8s L0Index; Ipp32u picCntRef0; Ipp32u picCntRef1; Ipp32u picCntCur; Ipp32s DistScaleFactor; Ipp32s *pDistScaleFactor; Ipp32s *pDistScaleFactorMV; Ipp32s tb; Ipp32s td; Ipp32s tx; VM_ASSERT(NumL0RefActive <= MAX_NUM_REF_FRAMES); VM_ASSERT(pRefPicList1[0]); pDistScaleFactor = m_CurSliceInfo.DistScaleFactor; //frames or fields pDistScaleFactorMV = m_CurSliceInfo.DistScaleFactorMV; //frames or fields if(m_pCurrentFrame->m_PictureStructureForRef>=FRM_STRUCTURE ) { picCntRef1 = pRefPicList1[0]->PicOrderCnt(0); } else { Ipp8u RefField=pRefPicList1[0]->GetNumberByParity(GetReferenceField(pFields1,0)); picCntRef1 = pRefPicList1[0]->PicOrderCnt(RefField); } picCntCur = m_pCurrentFrame->PicOrderCnt(m_field_index);//m_PicOrderCnt; for (L0Index=0; L0Index<NumL0RefActive; L0Index++) { if(m_pCurrentFrame->m_PictureStructureForRef>=FRM_STRUCTURE ) { VM_ASSERT(pRefPicList0[L0Index]); picCntRef0 = pRefPicList0[L0Index]->PicOrderCnt(0); } else { Ipp8s RefFieldTop; //ref0 RefFieldTop = GetReferenceField(pFields0,L0Index); VM_ASSERT(pRefPicList0[L0Index]); picCntRef0 = pRefPicList0[L0Index]->PicOrderCnt(pRefPicList1[0]->GetNumberByParity(RefFieldTop)); } CalculateDSF(L0Index); } if (m_pCurrentFrame->m_PictureStructureForRef==AFRM_STRUCTURE) { // [curmb field],[ref1field],[ref0field] pDistScaleFactor = m_CurSliceInfo.DistScaleFactorAFF[0][0][0]; //complementary field pairs, cf=top r1=top,r0=top pDistScaleFactorMV = m_CurSliceInfo.DistScaleFactorMVAFF[0][0][0]; //complementary field pairs, cf=top r1=top,r0=top picCntCur = m_pCurrentFrame->PicOrderCnt(0,1); picCntRef1 = pRefPicList1[0]->PicOrderCnt(0,1); for (L0Index=0; L0Index<NumL0RefActive; L0Index++) { VM_ASSERT(pRefPicList0[L0Index]); picCntRef0 = pRefPicList0[L0Index]->PicOrderCnt(0,1); CalculateDSF(L0Index); } pDistScaleFactor =m_CurSliceInfo.DistScaleFactorAFF[0][0][1]; //complementary field pairs, cf=top r1=top,r0=bottom pDistScaleFactorMV = m_CurSliceInfo.DistScaleFactorMVAFF[0][0][1]; //complementary field pairs, cf=top r1=top,r0=bottom picCntCur = m_pCurrentFrame->PicOrderCnt(0,1); picCntRef1 = pRefPicList1[0]->PicOrderCnt(0,1); for (L0Index=0; L0Index<NumL0RefActive; L0Index++) { VM_ASSERT(pRefPicList0[L0Index]); picCntRef0 = pRefPicList0[L0Index]->PicOrderCnt(1,1); CalculateDSF(L0Index); } pDistScaleFactor = m_CurSliceInfo.DistScaleFactorAFF[0][1][0]; //complementary field pairs, cf=top r1=bottom,r0=top pDistScaleFactorMV = m_CurSliceInfo.DistScaleFactorMVAFF[0][1][0]; //complementary field pairs, cf=top r1=bottom,r0=top picCntCur = m_pCurrentFrame->PicOrderCnt(0,1); picCntRef1 = pRefPicList1[0]->PicOrderCnt(1,1); for (L0Index=0; L0Index<NumL0RefActive; L0Index++) { VM_ASSERT(pRefPicList0[L0Index]); picCntRef0 = pRefPicList0[L0Index]->PicOrderCnt(0,1); CalculateDSF(L0Index); } pDistScaleFactor = m_CurSliceInfo.DistScaleFactorAFF[0][1][1]; //complementary field pairs, cf=top r1=bottom,r0=bottom pDistScaleFactorMV = m_CurSliceInfo.DistScaleFactorMVAFF[0][1][1]; //complementary field pairs, cf=top r1=bottom,r0=bottom picCntCur = m_pCurrentFrame->PicOrderCnt(0,1); picCntRef1 = pRefPicList1[0]->PicOrderCnt(1,1); for (L0Index=0; L0Index<NumL0RefActive; L0Index++) { VM_ASSERT(pRefPicList0[L0Index]); picCntRef0 = pRefPicList0[L0Index]->PicOrderCnt(1,1); CalculateDSF(L0Index); } /*--------------------------------------------------------------------*/ pDistScaleFactor = m_CurSliceInfo.DistScaleFactorAFF[1][0][0]; //complementary field pairs, cf=bottom r1=top,r0=top pDistScaleFactorMV = m_CurSliceInfo.DistScaleFactorMVAFF[1][0][0]; //complementary field pairs, cf=bottom r1=top,r0=top picCntCur = m_pCurrentFrame->PicOrderCnt(1,1); picCntRef1 = pRefPicList1[0]->PicOrderCnt(0,1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -