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

📄 umc_h264_dec_slice_decoder_decode_pic.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/*
//
//              INTEL CORPORATION PROPRIETARY INFORMATION
//  This software is supplied under the terms of a license  agreement or
//  nondisclosure agreement with Intel Corporation and may not be copied
//  or disclosed except in  accordance  with the terms of that agreement.
//        Copyright (c) 2003-2007 Intel Corporation. All Rights Reserved.
//
//
*/
#include "umc_defs.h"
#if defined (UMC_ENABLE_H264_VIDEO_DECODER)

/*  DEBUG: this file is requred to changing name
    to umc_h264_dec_slice_decode_pic */

#include "umc_h264_slice_decoding.h"
#include "umc_h264_dec.h"
#include "vm_debug.h"
#include "umc_h264_frame_list.h"

namespace UMC
{
struct H264RefListInfo
{
    Ipp32s m_iNumShortEntriesInList;
    Ipp32s m_iNumLongEntriesInList;
    Ipp32s m_iNumFramesInL0List;
    Ipp32s m_iNumFramesInL1List;
    Ipp32s m_iNumFramesInLTList;
};

static
H264DecoderFrame *FindLastValidReference(H264DecoderFrame **pList, Ipp32s iLength)
{
    Ipp32s i;
    H264DecoderFrame *pLast = NULL;

    for (i = 0; i < iLength; i += 1)
    {
        if (pList[i])
            pLast = pList[i];
    }

    return pLast;

} // H264DecoderFrame *FindLastValidReference(H264DecoderFrame **pList,


FactorArrayAFF H264Slice::m_StaticFactorArrayAFF;

Status H264Slice::UpdateReferenceList(H264DBPList *pDecoderFrameList)
{
    Status ps = UMC_OK;
    RefPicListReorderInfo *pReorderInfo_L0 = &ReorderInfoL0;
    RefPicListReorderInfo *pReorderInfo_L1 = &ReorderInfoL1;
    H264SeqParamSet *sps = GetSeqParam();
    Ipp32u uMaxFrameNum;
    Ipp32u uMaxPicNum;
    H264DecoderFrame *pFrm;
    H264DecoderFrame *pHead = pDecoderFrameList->head();
    //Ipp32u i;
    H264DecoderFrame **pRefPicList0;
    H264DecoderFrame **pRefPicList1;
    ReferenceFlags *pFields0;
    ReferenceFlags *pFields1;
    Ipp32u NumShortTermRefs, NumLongTermRefs;
    H264RefListInfo rli;
    H264DecoderFrame *(pLastInList[2]) = {NULL, NULL};

    if (m_SliceHeader.is_auxiliary)
    {
        pHead = GetAuxiliaryFrame(pHead);
    }

    VM_ASSERT(m_pCurrentFrame);

    pRefPicList0 = m_pCurrentFrame->GetRefPicList(m_iNumber, 0)->m_RefPicList;
    pRefPicList1 = m_pCurrentFrame->GetRefPicList(m_iNumber, 1)->m_RefPicList;
    pFields0 = m_pCurrentFrame->GetRefPicList(m_iNumber, 0)->m_Flags;
    pFields1 = m_pCurrentFrame->GetRefPicList(m_iNumber, 1)->m_Flags;

    // Spec reference: 8.2.4, "Decoding process for reference picture lists
    // construction"

    // get pointers to the picture and sequence parameter sets currently in use
    uMaxFrameNum = (1<<sps->log2_max_frame_num);
    uMaxPicNum = (m_SliceHeader.field_pic_flag == 0) ? uMaxFrameNum : uMaxFrameNum<<1;

    for (pFrm = pHead; pFrm; pFrm = pFrm->future())
    {
        // update FrameNumWrap and picNum if frame number wrap occurred,
        // for short-term frames
        // TBD: modify for fields
        pFrm->UpdateFrameNumWrap((Ipp32s)m_SliceHeader.frame_num,
            uMaxFrameNum,
            m_pCurrentFrame->m_PictureStructureForDec +
            m_SliceHeader.bottom_field_flag);

        // For long-term references, update LongTermPicNum. Note this
        // could be done when LongTermFrameIdx is set, but this would
        // only work for frames, not fields.
        // TBD: modify for fields
        pFrm->UpdateLongTermPicNum(m_pCurrentFrame->m_PictureStructureForDec +
                                   m_SliceHeader.bottom_field_flag);
    }

    pRefPicList0[0] = 0;
    pRefPicList1[0] = 0;

    if ((m_SliceHeader.slice_type != INTRASLICE) && (m_SliceHeader.slice_type != S_INTRASLICE))
    {
        for (Ipp32s number = 0; number <= MAX_NUM_REF_FRAMES + 1; number++)
        {
            pRefPicList0[number] = 0;
            pRefPicList1[number] = 0;
            pFields0[number].field = 0;
            pFields0[number].isShortReference = 0;
            pFields1[number].field = 0;
            pFields1[number].isShortReference = 0;
        }

        // Detect and report no available reference frames
        pDecoderFrameList->countActiveRefs(NumShortTermRefs, NumLongTermRefs);
        if ((NumShortTermRefs + NumLongTermRefs) == 0)
        {
            VM_ASSERT(0);
            ps = UMC_ERR_INVALID_STREAM;
        }

        if (ps == UMC_OK)
        {
            /*static int kkkk = 0;
            kkkk++;*/

            // Initialize the reference picture lists
            // Note the slice header get function always fills num_ref_idx_lx_active
            // fields with a valid value; either the override from the slice
            // header in the bitstream or the values from the pic param set when
            // there is no override.
            if ((m_SliceHeader.slice_type == PREDSLICE) ||
                (m_SliceHeader.slice_type == S_PREDSLICE))
            {
                InitPSliceRefPicList(m_SliceHeader.field_pic_flag != 0,
                                     m_SliceHeader.num_ref_idx_l0_active,
                                     pRefPicList0,
                                     pDecoderFrameList);

                pLastInList[0] = FindLastValidReference(pRefPicList0,
                                                        m_SliceHeader.num_ref_idx_l0_active);
            }
            else
            {
                //pRefPicList1 = m_pCurrentFrame->GetRefPicList(m_iNumber, 1)->m_RefPicList;
                InitBSliceRefPicLists(m_SliceHeader.field_pic_flag != 0, m_SliceHeader.num_ref_idx_l0_active,
                                      m_SliceHeader.num_ref_idx_l1_active,
                                      pRefPicList0, pRefPicList1,
                                      pDecoderFrameList,
                                      rli);

                pLastInList[0] = FindLastValidReference(pRefPicList0,
                                                        m_SliceHeader.num_ref_idx_l0_active);
                pLastInList[1] = FindLastValidReference(pRefPicList1,
                                                        m_SliceHeader.num_ref_idx_l1_active);
            }

            // Reorder the reference picture lists
            Ipp8u num_ST_Ref0 = 0, num_ST_Ref1, num_LT_Ref = 0;
            if (m_pCurrentFrame->m_PictureStructureForDec < FRM_STRUCTURE)
            {
                rli.m_iNumFramesInL0List = AdjustRefPicListForFields(pRefPicList0, pFields0, rli);
                num_ST_Ref0 = (Ipp8u) rli.m_iNumShortEntriesInList;
                num_LT_Ref = (Ipp8u) rli.m_iNumLongEntriesInList;
            }

            if (BPREDSLICE == m_SliceHeader.slice_type)
            {
                if (m_pCurrentFrame->m_PictureStructureForDec < FRM_STRUCTURE)
                {
                    rli.m_iNumFramesInL1List = AdjustRefPicListForFields(pRefPicList1, pFields1, rli);
                    num_ST_Ref1 = (Ipp8u) rli.m_iNumShortEntriesInList;
                }

                if ((rli.m_iNumFramesInL0List == rli.m_iNumFramesInL1List) &&
                    (rli.m_iNumFramesInL0List > 1))
                {
                    bool isNeedSwap = true;
                    for (Ipp32s i = 0; i < rli.m_iNumFramesInL0List; i++)
                    {
                        if (pRefPicList1[i] != pRefPicList0[i] ||
                            pFields1[i].field != pFields0[i].field)
                        {
                            isNeedSwap = false;
                            break;
                        }
                    }

                    if (isNeedSwap)
                    {
                        swapValues(pRefPicList1[0], pRefPicList1[1]);
                        swapValues(pFields1[0], pFields1[1]);
                    }
                }
            }

            pRefPicList0[m_SliceHeader.num_ref_idx_l0_active] = 0;


            /*{
            FILE  * fl = fopen("d:/ipp.ref", "a+");
            fprintf(fl, "init - l0 - %d\n", kkkk);
            for (Ipp32s k1 = 0; k1 < m_SliceHeader.num_ref_idx_l0_active; k1++)
            {
                if (!pRefPicList0[k1])
                    break;
                fprintf(fl, "i - %d, field - %d, poc %d \n", k1, pFields0[k1].field, pRefPicList0[k1]->PicOrderCnt(pRefPicList0[k1]->GetNumberByParity(pFields0[k1].field)));
            }

            fprintf(fl, "l1 - %d\n", kkkk);
            for (Ipp32s  k1 = 0; k1 < m_SliceHeader.num_ref_idx_l1_active; k1++)
            {
                if (!pRefPicList1[k1])
                    break;
                fprintf(fl, "i - %d, field - %d, poc %d \n", k1, pFields1[k1].field, pRefPicList1[k1]->PicOrderCnt(pRefPicList1[k1]->GetNumberByParity(pFields1[k1].field)));
            }

            fclose(fl);
        }*/

            if (pReorderInfo_L0->num_entries > 0)
                ReOrderRefPicList(m_SliceHeader.field_pic_flag != 0, pRefPicList0, pFields0, pReorderInfo_L0, uMaxPicNum, m_SliceHeader.num_ref_idx_l0_active, pDecoderFrameList);

            if (BPREDSLICE == m_SliceHeader.slice_type)
            {
                pRefPicList1[m_SliceHeader.num_ref_idx_l1_active] = 0;

                if (pReorderInfo_L1->num_entries > 0)
                    ReOrderRefPicList(m_SliceHeader.field_pic_flag != 0, pRefPicList1, pFields1, pReorderInfo_L1, uMaxPicNum, m_SliceHeader.num_ref_idx_l1_active, pDecoderFrameList);
            }

            /*{kkkk++;
            FILE  * fl = fopen("d:/ipp.ref", "a+");
            fprintf(fl, "reorder - l0 - %d\n", kkkk);
            for (Ipp32s k1 = 0; k1 < m_SliceHeader.num_ref_idx_l0_active; k1++)
            {
                fprintf(fl, "i - %d, field - %d, poc %d \n", k1, pFields0[k1].field, pRefPicList0[k1]->PicOrderCnt(pRefPicList0[k1]->GetNumberByParity(pFields0[k1].field)));
            }

            fprintf(fl, "l1 - %d\n", kkkk);
            for (Ipp32s  k1 = 0; k1 < m_SliceHeader.num_ref_idx_l1_active; k1++)
            {
                fprintf(fl, "i - %d, field - %d, poc %d \n", k1, pFields1[k1].field, pRefPicList1[k1]->PicOrderCnt(pRefPicList1[k1]->GetNumberByParity(pFields1[k1].field)));
            }

            fclose(fl);
            }*/

            // set absent references
            {
                Ipp32s i;
                Ipp32s iCurField = 1;

                for (i = 0; i < m_SliceHeader.num_ref_idx_l0_active; i += 1)
                {
                    if (NULL == pRefPicList0[i])
                    {
                        pRefPicList0[i] = pLastInList[0];
                        pFields0[i].field = (Ipp8s) (iCurField ^= 1);
                        pFields0[i].isShortReference = 1;
                        m_pCurrentFrame->SetError(1);
                    }
                    else
                    {
                        m_pCurrentFrame->SetError(pRefPicList0[i]->IsFrameExist() ? 0 : 1);
                        pFields0[i].isShortReference =
                            pRefPicList0[i]->isShortTermRef(pRefPicList0[i]->GetNumberByParity(pFields0[i].field));
                    }
                }

                if (BPREDSLICE == m_SliceHeader.slice_type)
                {
                    iCurField = 1;

                    for (i = 0; i < m_SliceHeader.num_ref_idx_l1_active; i += 1)
                    {
                        if (NULL == pRefPicList1[i])
                        {
                            pRefPicList1[i] = pLastInList[1];
                            pFields1[i].field = (Ipp8s) (iCurField ^= 1);
                            pFields1[i].isShortReference = 1;
                            m_pCurrentFrame->SetError(1);
                        }
                        else
                        {
                            m_pCurrentFrame->SetError(pRefPicList1[i]->IsFrameExist() ? 0 : 1);
                            pFields1[i].isShortReference =
                                pRefPicList1[i]->isShortTermRef(pRefPicList1[i]->GetNumberByParity(pFields1[i].field));
                        }

                    }
                }
            }

            // If B slice, init scaling factors array
            if ((BPREDSLICE == m_SliceHeader.slice_type) && (pRefPicList1[0] != NULL))
                InitDistScaleFactor(
                        m_SliceHeader.num_ref_idx_l0_active,
                        m_SliceHeader.num_ref_idx_l1_active,
                        pRefPicList0, pRefPicList1, pFields0, pFields1);
        }
    }

    return ps;

} // Status H264Slice::UpdateRefPicList(H264DecoderFrameList *pDecoderFrameList)

void H264Slice::InitPSliceRefPicList(bool bIsFieldSlice,
                                     Ipp32s /*NumL0RefActive*/,
                                     H264DecoderFrame **pRefPicList,
                                     H264DecoderFrameList *pDecoderFrameList)
{
    Ipp32s j, k;
    Ipp32s NumFramesInList;
    H264DecoderFrame *pHead = pDecoderFrameList->head();
    H264DecoderFrame *pFrm;
    Ipp32s picNum;
    bool bError = false;

    VM_ASSERT(pRefPicList);

    if (m_SliceHeader.is_auxiliary)
    {
        pHead = GetAuxiliaryFrame(pHead);
    }

    NumFramesInList = 0;

    if (!bIsFieldSlice)
    {
        // Frame. Ref pic list ordering: Short term largest pic num to
        // smallest, followed by long term, largest long term pic num to
        // smallest. Note that ref pic list has one extra slot to assist
        // with re-ordering.
        for (pFrm = pHead; pFrm; pFrm = pFrm->future())
        {
            if (pFrm->isShortTermRef()==3)
            {
                // add to ordered list
                picNum = pFrm->PicNum(0);

                // find insertion point
                j=0;
                while (j<NumFramesInList &&

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -