⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 umc_h264_dec_slice_decoder_decode_pic.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
        // 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 + -