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

📄 umc_h264_segment_decoder_decode_mb_types.cpp

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

#include "umc_h264_segment_decoder.h"
#include "umc_h264_dec.h"
#include "umc_h264_bitstream_inlines.h"
#include "vm_debug.h"
#include "umc_h264_dec_tables.h"

namespace UMC
{

///////////////////////////////////////////////////////////////////////////////
// lookup table to translate B frame type code to MB type
const
Ipp8u CodeToMBTypeB[] =
{
    MBTYPE_DIRECT,          // 0
    MBTYPE_FORWARD,
    MBTYPE_BACKWARD,
    MBTYPE_BIDIR,
    MBTYPE_INTER_16x8,
    MBTYPE_INTER_8x16,      // 5
    MBTYPE_INTER_16x8,
    MBTYPE_INTER_8x16,
    MBTYPE_INTER_16x8,
    MBTYPE_INTER_8x16,
    MBTYPE_INTER_16x8,      // 10
    MBTYPE_INTER_8x16,
    MBTYPE_INTER_16x8,
    MBTYPE_INTER_8x16,
    MBTYPE_INTER_16x8,
    MBTYPE_INTER_8x16,      // 15
    MBTYPE_INTER_16x8,
    MBTYPE_INTER_8x16,
    MBTYPE_INTER_16x8,
    MBTYPE_INTER_8x16,
    MBTYPE_INTER_16x8,      // 20
    MBTYPE_INTER_8x16,
    MBTYPE_INTER_8x8
};

// lookup table to extract prediction direction from MB type code for
// 16x8 and 8x16 MB types. Contains direction for first and second
// subblocks at each entry.
const
Ipp8u CodeToBDir[][2] =
{
    {D_DIR_FWD, D_DIR_FWD},
    {D_DIR_BWD, D_DIR_BWD},
    {D_DIR_FWD, D_DIR_BWD},
    {D_DIR_BWD, D_DIR_FWD},
    {D_DIR_FWD, D_DIR_BIDIR},
    {D_DIR_BWD, D_DIR_BIDIR},
    {D_DIR_BIDIR, D_DIR_FWD},
    {D_DIR_BIDIR, D_DIR_BWD},
    {D_DIR_BIDIR, D_DIR_BIDIR}
};

// lookup table to translate B frame 8x8 subblock code to type and
// prediction direction
static
const struct
{
    Ipp8u type;
    Ipp8u dir;
} CodeToSBTypeAndDir[] =
{
    {SBTYPE_DIRECT, D_DIR_DIRECT},
    {SBTYPE_8x8, D_DIR_FWD},
    {SBTYPE_8x8, D_DIR_BWD},
    {SBTYPE_8x8, D_DIR_BIDIR},
    {SBTYPE_8x4, D_DIR_FWD},
    {SBTYPE_4x8, D_DIR_FWD},
    {SBTYPE_8x4, D_DIR_BWD},
    {SBTYPE_4x8, D_DIR_BWD},
    {SBTYPE_8x4, D_DIR_BIDIR},
    {SBTYPE_4x8, D_DIR_BIDIR},
    {SBTYPE_4x4, D_DIR_FWD},
    {SBTYPE_4x4, D_DIR_BWD},
    {SBTYPE_4x4, D_DIR_BIDIR}
};

const
Ipp32s NIT2LIN[16] =
{
    0, 1, 4, 5,
    2, 3, 6, 7,
    8, 9,12,13,
    10,11,14,15
};

void H264SegmentDecoder::DecodeMBFieldDecodingFlag_CAVLC(void)
{
    Ipp32u bit = m_pBitStream->Get1Bit();

    pSetPairMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo,
                                m_cur_mb.GlobalMacroblockPairInfo,
                                bit);

} // void H264SegmentDecoder::DecodeMBFieldDecodingFlag_CAVLC(void)

void H264SegmentDecoder::DecodeMBFieldDecodingFlag(void)
{
    Ipp32s iFirstMB = m_pSlice->GetFirstMBNumber();
    Ipp32s iCurrentField = 0;
    Ipp32s mbAddr;

    // try to get left MB pair info
    mbAddr = m_CurMBAddr - 2;
    if ((iFirstMB <= mbAddr) &&
        (m_CurMB_X))
    {
        iCurrentField = GetMBFieldDecodingFlag(m_gmbinfo->mbs[mbAddr]);
    }
    else
    {
        // get above MB pair info
        mbAddr = m_CurMBAddr - mb_width * 2;
        if ((iFirstMB <= mbAddr) &&
            (m_CurMB_Y))
            iCurrentField = GetMBFieldDecodingFlag(m_gmbinfo->mbs[mbAddr]);
    }

    pSetPairMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo,
                                m_cur_mb.GlobalMacroblockPairInfo,
                                iCurrentField);

} // void H264SegmentDecoder::DecodeMBFieldDecodingFlag(void)

Ipp32u H264SegmentDecoder::DecodeMBSkipRun_CAVLC(void)
{
    return (Ipp32u) m_pBitStream->GetVLCElement(false);

} // Ipp32u H264SegmentDecoder::DecodeMBSkipRun_CAVLC(void)

void H264SegmentDecoder::DecodeMBTypeISlice_CAVLC(void)
{
    Ipp32u uCodeNum;

    uCodeNum = m_pBitStream->GetVLCElement(false);

    // the macroblock has I_NxN type
    if (0 == uCodeNum)
        m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTRA;
    // the macroblock has I_16x16 type
    else if (25 != uCodeNum)
    {
        m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTRA_16x16;
        original_mb_type = (Ipp8u) (uCodeNum - 1);

        // set the CBP
        {
            uCodeNum -= 1;
            if (12 <= uCodeNum)
            {
                m_cur_mb.LocalMacroblockInfo->cbp = 0x0f;
                uCodeNum -= 12;
            }
            else
                m_cur_mb.LocalMacroblockInfo->cbp = 0x00;

            uCodeNum <<= 2;
            m_cur_mb.LocalMacroblockInfo->cbp = (Ipp8u) (m_cur_mb.LocalMacroblockInfo->cbp | (uCodeNum & 0x30));
        }
    }
    // the macroblock has PCM type
    else
        m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_PCM;

} // void H264SegmentDecoder::DecodeMBTypeISlice_CAVLC(void)

void H264SegmentDecoder::DecodeMBTypePSlice_CAVLC(void)
{
    Ipp32u uCodeNum;

    uCodeNum = m_pBitStream->GetVLCElement(false);

    // the macroblock has inter type
    if (5 > uCodeNum)
    {
        switch (uCodeNum)
        {
        case 0:
            m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_FORWARD;
            break;

        case 1:
            m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTER_16x8;
            break;

        case 2:
            m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTER_8x16;
            break;

        case 3:
        case 4:
            m_cur_mb.GlobalMacroblockInfo->mbtype = (Ipp8u) ((uCodeNum == 4) ?
                                                             MBTYPE_INTER_8x8_REF0 :
                                                             MBTYPE_INTER_8x8);
            // read subblock types
            {
                Ipp32s subblock;
                Ipp32s sbtype;

                for (subblock = 0; subblock < 4; subblock++)
                {
                    uCodeNum = m_pBitStream->GetVLCElement(false);

                    switch (uCodeNum)
                    {
                    case 0:
                        sbtype = SBTYPE_8x8;
                        break;

                    case 1:
                        sbtype = SBTYPE_8x4;
                        break;

                    case 2:
                        sbtype = SBTYPE_4x8;
                        break;

                    case 3:
                        sbtype = SBTYPE_4x4;
                        break;

                    default:
                        throw h264_exception(UMC_ERR_INVALID_STREAM);
                    }

                    m_cur_mb.GlobalMacroblockInfo->sbtype[subblock] = (Ipp8u) sbtype;
                }
            }
            break;
        }
    }
    else
    {
        uCodeNum -= 5;

        // the macroblock has I_NxN type
        if (0 == uCodeNum)
            m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTRA;
        // the macroblock has I_16x16 type
        else if (25 != uCodeNum)
        {
            m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTRA_16x16;
            original_mb_type = (Ipp8u) (uCodeNum - 1);

            // set the CBP
            {
                uCodeNum -= 1;
                if (12 <= uCodeNum)
                {
                    m_cur_mb.LocalMacroblockInfo->cbp = 0x0f;
                    uCodeNum -= 12;
                }
                else
                    m_cur_mb.LocalMacroblockInfo->cbp = 0x00;

                uCodeNum <<= 2;
                m_cur_mb.LocalMacroblockInfo->cbp = (Ipp8u) (m_cur_mb.LocalMacroblockInfo->cbp | (uCodeNum & 0x30));
            }
        }
        // the macroblock has PCM type
        else
            m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_PCM;
    }

} // void H264SegmentDecoder::DecodeMBTypePSlice_CAVLC(void)

void H264SegmentDecoder::DecodeMBTypeBSlice_CAVLC(void)
{
    Ipp32u uCodeNum;

    uCodeNum = m_pBitStream->GetVLCElement(false);

    // the macroblock has inter type
    if (uCodeNum < 23)
    {
        m_cur_mb.GlobalMacroblockInfo->mbtype = CodeToMBTypeB[uCodeNum];
        if (m_cur_mb.GlobalMacroblockInfo->mbtype  == MBTYPE_INTER_16x8 ||
            m_cur_mb.GlobalMacroblockInfo->mbtype == MBTYPE_INTER_8x16)
        {
            // direction for the two subblocks
            m_cur_mb.LocalMacroblockInfo->sbdir[0] = CodeToBDir[(uCodeNum-4)>>1][0];
            m_cur_mb.LocalMacroblockInfo->sbdir[1] = CodeToBDir[(uCodeNum-4)>>1][1];
        }
        else if (m_cur_mb.GlobalMacroblockInfo->mbtype == MBTYPE_INTER_8x8)
        {
            // read subblock types and prediction direction
            Ipp32u subblock;

            for (subblock = 0; subblock < 4; subblock++)
            {
                uCodeNum = m_pBitStream->GetVLCElement(false);
                if (uCodeNum < 13)
                {
                    m_cur_mb.GlobalMacroblockInfo->sbtype[subblock] =  CodeToSBTypeAndDir[uCodeNum].type;
                    m_cur_mb.LocalMacroblockInfo->sbdir[subblock] = CodeToSBTypeAndDir[uCodeNum].dir;
                }
                else
                    throw h264_exception(UMC_ERR_INVALID_STREAM);
            }
        }
    }
    else
    {
        uCodeNum -= 23;

        // the macroblock has I_NxN type
        if (0 == uCodeNum)
            m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTRA;
        // the macroblock has I_16x16 type
        else if (25 != uCodeNum)
        {
            m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTRA_16x16;
            original_mb_type = (Ipp8u) (uCodeNum - 1);

            // set the CBP
            {
                uCodeNum -= 1;
                if (12 <= uCodeNum)
                {
                    m_cur_mb.LocalMacroblockInfo->cbp = 0x0f;
                    uCodeNum -= 12;
                }
                else
                    m_cur_mb.LocalMacroblockInfo->cbp = 0x00;

                uCodeNum <<= 2;
                m_cur_mb.LocalMacroblockInfo->cbp = (Ipp8u) (m_cur_mb.LocalMacroblockInfo->cbp | (uCodeNum & 0x30));
            }
        }
        // the macroblock has PCM type
        else
            m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_PCM;
    }

} // void H264SegmentDecoder::DecodeMBTypeBSlice_CAVLC(void)

void H264SegmentDecoder::DecodeMacroBlockType(IntraType *pMBIntraTypes,
                                                Ipp32s *MBSkipCount, // On entry if < 0, run of skipped MBs has just been completed
                                                                     // On return, zero or skip MB run count read from bitstream
                                                Ipp32s *PassFDFDecode)
{
    Ipp32u uCodeNum;

    // interpretation of code depends upon slice type
    if (m_pSliceHeader->slice_type == INTRASLICE)
    {
        if (m_pSliceHeader->MbaffFrameFlag)
        {
            if ((m_CurMBAddr & 1)==0)
            {
                Ipp32u bit = m_pBitStream->Get1Bit();
                pSetPairMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo,m_cur_mb.GlobalMacroblockPairInfo,bit);
            }
        }
        else
        {
            pSetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo,0);
        }
        uCodeNum = m_pBitStream->GetVLCElement(false);
        if (uCodeNum == 0)
             m_cur_mb.GlobalMacroblockInfo->mbtype =  MBTYPE_INTRA;
        else if (uCodeNum == 25)
            m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_PCM;
        else
        {
            m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTRA_16x16;
            uCodeNum--;
        }
    }   // intra
    else
    {   // not Intra

        if (*MBSkipCount >= 0) //actually it has to be = 0
        {
            VM_ASSERT(*MBSkipCount<=0);
            uCodeNum = m_pBitStream->GetVLCElement(false);
            // skipped MB count

⌨️ 快捷键说明

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