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

📄 umc_h264_redual_decoder_templates.h

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

#ifndef __UMC_H264_RESIDUAL_DECODER_TEMPLATES_H
#define __UMC_H264_RESIDUAL_DECODER_TEMPLATES_H

#include "umc_h264_dec_internal_cabac.h"

namespace UMC
{

// turn off the "code is not reachable from preceding code" remark
#pragma warning(disable : 128)
// turn off the "conditional expression is constant" warning
#pragma warning(disable: 280)
#pragma warning(disable: 4127)

enum
{
    LUMA_BLOCK_8X8_0            = 0x01,
    LUMA_BLOCK_8X8_1            = 0x02,
    LUMA_BLOCK_8X8_2            = 0x04,
    LUMA_BLOCK_8X8_3            = 0x08,

    CHROMA_AC_BLOCKS            = 0x20,
    CHROMA_DC_AC_BLOCKS         = 0x30
};

template <typename Coeffs, Ipp32s color_format, Ipp32s is_field>
class ResidualDecoderCAVLC
{
public:
    typedef Coeffs *  CoeffsPtr;

    virtual ~ResidualDecoderCAVLC() {}

    void DecodeCoefficients8x8_CAVLC(H264SegmentDecoderMultiThreaded * sd)
    {
        Ipp64u blockcbp;
        Ipp32u u8x8block = 1;
        Ipp32s uBlock;
        Ipp32u uBlockBit;

        Ipp32u uNC;
        Ipp32u uAboveIndex;
        Ipp32u uLeftIndex;
        Coeffs TempCoeffs[16];
        Ipp16s sNumCoeff;
        Ipp32s bFieldDecodeFlag = pGetMBFieldDecodingFlag(sd->m_cur_mb.GlobalMacroblockInfo);
        CoeffsPtr pCurCoeffs;
        bool advance_to_next_block=false;
        Ipp8u bf = sd->m_pCurrentFrame->m_PictureStructureForDec<FRM_STRUCTURE || bFieldDecodeFlag;
        Ipp8u cbp = sd->m_cur_mb.LocalMacroblockInfo->cbp;

        // Initialize blockcbp bits from input cbp (from the bitstream)
        blockcbp = 0;   // no coeffs
        for (uBlock=0; uBlock<5; uBlock++)
        {
            if (cbp & u8x8block)
                blockcbp |= blockcbp_table[uBlock];
            u8x8block <<= 1;
        }

        if (cbp & u8x8block)
        {
            switch(color_format)
            {
            case 1:
                blockcbp |= CONST_LL(0x3ff0000) << 1;
                break;
            case 2:
                blockcbp |= CONST_LL(0x3ffff0000) << 1;
                break;
            case 3:
                blockcbp |= CONST_LL(0x3ffffffff0000) << 1;
                break;
            }
        }

        uBlock      = 1;        // start block loop with first luma 4x4
        uBlockBit   = 2;
        blockcbp  >>= 1;

        for (uBlock = 1; uBlock<FIRST_DC_CHROMA; uBlock++)
        {
            uAboveIndex = BlockNumToMBColLuma[uBlock];
            uLeftIndex  = BlockNumToMBRowLuma[uBlock];
            pCurCoeffs = TempCoeffs;

            sNumCoeff = 0;
            if ((blockcbp & 1) != 0)
            {
                uNC = sd->GetBlocksLumaContext(uAboveIndex,uLeftIndex);

                // Get CAVLC-code coefficient info from bitstream. Following call
                // updates pbs, bitOffset, sNumCoeff, sNumTrOnes, TrOneSigns,
                // and uTotalZero and fills CoeffBuf and uRunBeforeBuf.
                memset(TempCoeffs, 0, 16*sizeof(Coeffs));
                sd->m_pBitStream->GetCAVLCInfoLuma(uNC,
                                                    16,
                                                    sNumCoeff,
                                                    &pCurCoeffs,
                                                    bf);
    #ifdef STORE_VLC
                FILE *fp=fopen(__VLC_FILE__,"a+t");
                if (fp)
                {
                    fprintf(fp,"I4 L %d %d\n",uNC,sNumCoeff);
                    fclose(fp);
                }
    #endif

                //copy coeffs from tempbuffer
                for (Ipp32s i=0;i<16;i++)
                {
                    CoeffsPtr coeffsPtr = (CoeffsPtr)sd->m_pCoeffBlocksWrite;
                    coeffsPtr[hp_scan8x8[bf][((uBlock-1)&3)+i*4]] = TempCoeffs[mp_scan4x4[bf][i]];
                }

                advance_to_next_block = true;
                sd->m_cur_mb.LocalMacroblockInfo->cbp4x4_luma |= uBlockBit;
            }

            if ((uBlock&3)==0 && advance_to_next_block) //end of 8x8 block
            {
                sd->m_pCoeffBlocksWrite += 64*(sizeof(Coeffs) / sizeof(sd->m_pCoeffBlocksWrite[0]));
                advance_to_next_block=false;
            }
            // Update num coeff storage for predicting future blocks
            sd->m_cur_mb.MacroblockCoeffsInfo->numCoeff[uLeftIndex * 4 + uAboveIndex] = (Ipp8u) sNumCoeff;

            blockcbp >>= 1;
            uBlockBit <<= 1;
        }   // uBlock

        if (!color_format)
            return;

        for (uBlock = FIRST_DC_CHROMA; uBlock < FIRST_AC_CHROMA; uBlock++)
        {
            if ((blockcbp & 1) != 0)
            {
                switch(color_format)
                {
                case 1:
                    sd->m_pBitStream->GetCAVLCInfoChroma0(sNumCoeff, (CoeffsPtr*)&sd->m_pCoeffBlocksWrite);
                    break;
                case 2:
                    sd->m_pBitStream->GetCAVLCInfoChroma2(sNumCoeff, (CoeffsPtr*)&sd->m_pCoeffBlocksWrite);
                    break;
                case 3:
                    sd->m_pBitStream->GetCAVLCInfoChroma4(sNumCoeff, (CoeffsPtr*)&sd->m_pCoeffBlocksWrite, 0);
                    break;
                default:
                    sNumCoeff = 0;
                    VM_ASSERT(false);
                    throw h264_exception(UMC_ERR_INVALID_STREAM);
                };

    #ifdef STORE_VLC
                FILE *fp=fopen(__VLC_FILE__,"a+t");
                if (fp)
                {
                    fprintf(fp,"I4 CDC %d %d\n",0,sNumCoeff);
                    fclose(fp);
                }
    #endif

                sd->m_cur_mb.LocalMacroblockInfo->cbp4x4_chroma[uBlock - FIRST_DC_CHROMA] |= (sNumCoeff ? 1 : 0);
            }

            blockcbp >>= 1;
            //  Can't early exit without setting numcoeff for rest of blocks
            if ((blockcbp == 0) && (uBlock == (FIRST_AC_CHROMA - 1)))
            {
                // no AC chroma coeffs, set chrroma NumCoef buffers to zero and exit
                //pMB->numCoeff[16]=pMB->numCoeff[17]=pMB->numCoeff[18]=pMB->numCoeff[19]=
                //pMB->numCoeff[20]=pMB->numCoeff[21]=pMB->numCoeff[22]=pMB->numCoeff[23]=0;
                return;
            }
        }   // uBlock

        uBlockBit = 2;

        Ipp32s colorFactor;

        switch(color_format)
        {
        case 1:
            colorFactor = 1;
            break;
        case 2:
            colorFactor = 2;
            break;
        case 3:
            colorFactor = 4;
            break;
        default:
            colorFactor = 0;
            VM_ASSERT(false);
        };

        for (uBlock = FIRST_AC_CHROMA; uBlock < FIRST_AC_CHROMA + 8*colorFactor; uBlock++)
        {
            if (uBlock == (FIRST_AC_CHROMA + 4*colorFactor))
                uBlockBit = 2;

            uAboveIndex = BlockNumToMBColChromaAC[color_format][uBlock-FIRST_AC_CHROMA];
            uLeftIndex  = BlockNumToMBRowChromaAC[color_format][uBlock-FIRST_AC_CHROMA];
            Ipp32u addval = uBlock >= (FIRST_AC_CHROMA + 4*colorFactor) ?
                (FIRST_AC_CHROMA + 4*colorFactor - 3) : 16;
            sNumCoeff = 0;
            if ((blockcbp & 1) != 0)
            {
                switch(color_format)
                {
                case 1:
                    uNC = sd->GetBlocksChromaContextBMEH(uAboveIndex, uLeftIndex, uBlock >= (FIRST_AC_CHROMA + 4*colorFactor));
                    break;
                case 2:
                    uNC = sd->GetBlocksChromaContextH2(uAboveIndex, uLeftIndex, uBlock >= (FIRST_AC_CHROMA + 4*colorFactor));
                    break;
                case 3:
                    uNC = sd->GetBlocksChromaContextH4(uAboveIndex, uLeftIndex, uBlock >= (FIRST_AC_CHROMA + 4*colorFactor));
                    break;
                default:
                    uNC = 0;
                    VM_ASSERT(false);
                    throw h264_exception(UMC_ERR_INVALID_STREAM);
                };

                // Get CAVLC-code coefficient info from bitstream. Following call
                // updates pbs, bitOffset, sNumCoeff, sNumTrOnes, TrOneSigns,
                // and uTotalZero and fills CoeffBuf and uRunBeforeBuf.
                sd->m_pBitStream->GetCAVLCInfoLuma(uNC,
                                                    15,
                                                    sNumCoeff,
                                                    (CoeffsPtr*)&sd->m_pCoeffBlocksWrite,
                                                    bf);
    #ifdef STORE_VLC
                FILE *fp=fopen(__VLC_FILE__,"a+t");
                if (fp)
                {
                    fprintf(fp,"I4 CAC %d %d\n",uNC,sNumCoeff);
                    fclose(fp);
                }
    #endif

                sd->m_cur_mb.LocalMacroblockInfo->cbp4x4_chroma[uBlock >= (FIRST_AC_CHROMA + 4*colorFactor)]
                    |= (sNumCoeff ? uBlockBit : 0);
            }
            // Update num coeff storage for predicting future blocks
            sd->m_cur_mb.MacroblockCoeffsInfo->numCoeff[uLeftIndex * 2 * (1 + (Ipp32s)(color_format == 3))
                + uAboveIndex + addval] = (Ipp8u)sNumCoeff;

            blockcbp >>= 1;
            uBlockBit <<= 1;
        }   // uBlock


        // update buffer position pointer
    } // void DecodeCoefficients8x8_CAVLC(H264SegmentDecoderMultiThreaded * sd)

#define SET_TO_ZERO_COEFFS_NUMBER(x_pos, y_pos) \
    { \
        pNumCoeffsArray[(y_pos) * 4 + x_pos] = (Ipp8u) 0; \
        pNumCoeffsArray[(y_pos) * 4 + x_pos + 1] = (Ipp8u) 0; \
        pNumCoeffsArray[(y_pos + 1) * 4 + x_pos] = (Ipp8u) 0; \
        pNumCoeffsArray[(y_pos + 1) * 4 + x_pos + 1] = (Ipp8u) 0; \
    }

#define DECODE_EXTERNAL_LUMA_BLOCK_CAVLC(x_pos, y_pos, block_num) \
    { \
        Ipp16s iCoeffsNumber; \
        /*  to be honest, VLCContext is an average of coeffs numbers \
            of neighbouring blocks */ \
        Ipp32s iVCLContext; \
        iVCLContext = sd->GetBlocksLumaContextExternal(); \
        /* decode block coeffs */ \
        sd->m_pBitStream->GetCAVLCInfoLuma(iVCLContext, \
                                                    iMaxNum, \
                                                    iCoeffsNumber, \
                                                    (CoeffsPtr *) &sd->m_pCoeffBlocksWrite, \
                                                    bf); \
        /* update final CBP */ \
        uFinalCBP |= (iCoeffsNumber) ? (1 << (block_num + 1)) : (0); \
        /* update a num coeff storage for a prediction of future blocks */ \
        pNumCoeffsArray[(y_pos) * 4 + x_pos] = (Ipp8u) iCoeffsNumber; \
    }

#define DECODE_TOP_LUMA_BLOCK_CAVLC(x_pos, y_pos, block_num) \
    { \
        Ipp16s iCoeffsNumber; \
        /*  to be honest, VLCContext is an average of coeffs numbers \
            of neighbouring blocks */ \
        Ipp32s iVCLContext; \
        iVCLContext = sd->GetBlocksLumaContextTop(x_pos, pNumCoeffsArray[x_pos - 1]); \
        /* decode block coeffs */ \
        sd->m_pBitStream->GetCAVLCInfoLuma(iVCLContext, \
                                                    iMaxNum, \
                                                    iCoeffsNumber, \
                                                    (CoeffsPtr *) &sd->m_pCoeffBlocksWrite, \
                                                    bf); \
        /* update final CBP */ \
        uFinalCBP |= (iCoeffsNumber) ? (1 << (block_num + 1)) : (0); \
        /* update a num coeff storage for a prediction of future blocks */ \
        pNumCoeffsArray[(y_pos) * 4 + x_pos] = (Ipp8u) iCoeffsNumber; \
    }

#define DECODE_LEFT_LUMA_BLOCK_CAVLC(x_pos, y_pos, block_num) \
    { \
        Ipp16s iCoeffsNumber; \
        /*  to be honest, VLCContext is an average of coeffs numbers \
            of neighbouring blocks */ \
        Ipp32s iVCLContext; \

⌨️ 快捷键说明

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