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

📄 umc_h264_bitstream.h

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

#include "ippvc.h"
#include "umc_structures.h"
#include "umc_dynamic_cast.h"
#include "umc_h264_dec_defs_dec.h"
#include "umc_h264_dec_tables.h"
#include "umc_h264_dec_internal_cabac.h"

#define h264Peek1Bit(current_data, offset) \
    ((current_data[0] >> (offset)) & 1)

#define h264Drop1Bit(current_data, offset) \
{ \
    offset -= 1; \
    if (offset < 0) \
    { \
        offset = 31; \
        current_data += 1; \
    } \
}

namespace UMC
{

// CABAC magic mode switcher.
// Just put it to 0 to switch fast CABAC decoding off.
#define CABAC_MAGIC_BITS 16

#ifdef STORE_CABAC_BITS
extern FILE *cabac_bits;
extern Ipp32s sym_cnt;
#endif

// NAL unit definitions
#define NAL_STORAGE_IDC_BITS   0x60
#define NAL_UNITTYPE_BITS      0x1f

#define NUM_BLOCK_TYPES        8
#define NUM_MB_TYPE_CTX       11
#define NUM_BLOCK_TYPE_CTX     9
#define NUM_MVD_CTX           10
#define NUM_REF_NO_CTX         6
#define NUM_DELTA_QAUNT_CTX    4
#define NUM_MB_AFF_CTX         4

#define NUM_INTRA_PRED_CTX             2
#define NUM_CR_INTRA_PRED_CTX          4
#define NUM_CBP_CTX                    4
#define NUM_BLOCK_CBP_CTX              4
#define NUM_SIGN_COEFF_FLAG_CTX       15
#define NUM_LAST_SIGN_COEFF_FLAG_CTX  15
#define NUM_COEF_ONE_LEVEL_CTX         5
#define NUM_COEF_ABS_LEVEL_CTX         5

// Declare CABAC context type
#pragma pack(1)
typedef struct CABAC_CONTEXT
{
    Ipp8u pStateIdxAndVal;                                      // (Ipp8u) probability state index and value of most probable symbol

} CABAC_CONTEXT;
#pragma pack()

class H264Bitstream
{
    DYNAMIC_CAST_DECL_BASE(H264Bitstream)

public:
    // Default constructor
    H264Bitstream(void);
    // Constructor
    H264Bitstream(Ipp8u * const pb, const Ipp32u maxsize);
    // Destructor
    ~H264Bitstream(void);

    // Initialize bitstream to decoding.
    // This method isn't required to headers parsing.
    bool Init(void);

    // Find next start code
    Status AdvanceToNextSCP(void);
    // Check amount of data
    bool More_RBSP_Data();

    // Align bitstream pointer to the right
    inline
    void AlignPointerRight();

    // Reset the bitstream with new data pointer
    void Reset(Ipp8u * const pb, const Ipp32u maxsize);
    void Reset(Ipp8u * const pb, Ipp32s offset, const Ipp32u maxsize);

    Ipp32s GetSCP();

    // Get type of current NAL
    Status GetNALUnitType(NAL_Unit_Type &uNALUnitType,
                          Ipp8u &uNALStorageIDC);

    // Decode sequence parameter set
    Status GetSequenceParamSet(H264SeqParamSet *sps);
    // Decode sequence parameter set extension
    Status GetSequenceParamSetExtension(H264SeqParamSetExtension *sps_ex);

    void GetScalingList4x4(H264ScalingList4x4 *scl, Ipp8u *def, Ipp8u *scl_type);
    void GetScalingList8x8(H264ScalingList8x8 *scl, Ipp8u *def, Ipp8u *scl_type);

    // Decoding picture's parameter set functions
    Status GetPictureParamSetPart1(H264PicParamSet *pps);
    Status GetPictureParamSetPart2(H264PicParamSet *pps, const H264SeqParamSet *sps);

    Status GetPictureDelimiter(Ipp32u &PicCodType);

    Status ReadFillerData();
    void RollbackCurrentNALU();

    // Decoding slice header functions
    Status GetSliceHeaderPart1(H264SliceHeader *pSliceHeader);
    Status GetSliceHeaderPart2(H264SliceHeader *hdr, // slice header read goes here
                               const H264PicParamSet *pps,
                               bool bIsIDRSlice,
                               const H264SeqParamSet *sps,
                               Ipp8u NALRef_idc); // from slice header NAL unit

    Status GetSliceHeaderPart3(H264SliceHeader *hdr, // slice header read goes here
                               PredWeightTable *pPredWeight_L0, // L0 weight table goes here
                               PredWeightTable *pPredWeight_L1, // L1 weight table goes here
                               RefPicListReorderInfo *pReorderInfo_L0,
                               RefPicListReorderInfo *pReorderInfo_L1,
                               AdaptiveMarkingInfo *pAdaptiveMarkingInfo,
                               const H264PicParamSet *pps,
                               const H264SeqParamSet *sps,
                               Ipp8u NALRef_idc); // from slice header NAL unit

    // Parse SEI message
    Ipp32s ParseSEI(H264SeqParamSet **sps, Ipp32s current_sps, H264SEIPayLoad *spl);

    template <typename Coeffs> inline
    void GetCAVLCInfoLuma(Ipp32u uVLCSelect, // N, obtained from num coeffs of above/left blocks
                            Ipp32s uMaxNumCoeff,
                            Ipp16s &sNumCoeff,
                            Coeffs **ppPosCoefbuf, // buffer to return up to 16
                            Ipp32s field_flag)
    {
        // Calls CAVLC bitstream decoding functions to obtain nonzero coefficients
        // and related information, returning in passed buffers and passed-by-reference
        // parameters.
        // Bitstream pointer and offset are updated by called functions and are
        // updated on return.

        if (uVLCSelect < 2)
        {
            if (h264Peek1Bit(m_pbs, m_bitOffset))
            {
                h264Drop1Bit(m_pbs, m_bitOffset);
                sNumCoeff = 0;
                return;
            }
        }

        IppStatus ippRes;

        ippRes = DecodeCAVLCCoeffs_H264(&m_pbs,
                                        &m_bitOffset,
                                        &sNumCoeff,
                                        ppPosCoefbuf,
                                        uVLCSelect,
                                        (Ipp16s)uMaxNumCoeff,
                                        (const Ipp32s **) m_tblCoeffToken,
                                        (const Ipp32s **) m_tblTotalZeros,
                                        (const Ipp32s **) m_tblRunBefore,
                                        (Ipp32s*) mp_scan4x4[field_flag]);

        if (ippStsNoErr > ippRes)
            throw h264_exception(UMC_ERR_INVALID_STREAM);

    } // void GetCAVLCInfoLuma(Ipp32u uVLCSelect,

    template <typename Coeffs>
    void GetCAVLCInfoChroma0(Ipp16s &sNumCoeff, Coeffs **ppPosCoefbuf)
    {
        IppStatus ippRes = DecodeCAVLCChromaDcCoeffs_H264(&m_pbs,
                                                          &m_bitOffset,
                                                          &sNumCoeff,
                                                          ppPosCoefbuf,
                                                          m_tblCoeffToken[3],
                                                          (const Ipp32s **) m_tblTotalZerosCR,
                                                          (const Ipp32s **) m_tblRunBefore);

        if (ippStsNoErr > ippRes)
            throw h264_exception(UMC_ERR_INVALID_STREAM);

    } // void GetCAVLCInfoChroma0(Ipp16s &sNumCoeff,


    template <typename Coeffs>
    void GetCAVLCInfoChroma2(Ipp16s &sNumCoeff, Coeffs **ppPosCoefbuf)
    {
        IppStatus ippRes = DecodeCAVLCChromaDcCoeffs422_H264(&m_pbs,
                                                             &m_bitOffset,
                                                             &sNumCoeff,
                                                             ppPosCoefbuf,
                                                             m_tblCoeffToken[4],
                                                             (const Ipp32s **) m_tblTotalZerosCR422,
                                                             (const Ipp32s **) m_tblRunBefore);
        if (ippStsNoErr > ippRes)
            throw h264_exception(UMC_ERR_INVALID_STREAM);
    } // void GetCAVLCInfoChroma2(Ipp16s &sNumCoeff,


    template <typename Coeffs>
    void GetCAVLCInfoChroma4(Ipp16s &sNumCoeff, Coeffs **ppPosCoefbuf,
                           Ipp8u field_flag)
    {
        IppStatus ippRes = DecodeCAVLCCoeffs_H264(&m_pbs,
                                                  &m_bitOffset,
                                                  &sNumCoeff,
                                                  ppPosCoefbuf,
                                                  0,
                                                  16,
                                                  (const Ipp32s **) m_tblCoeffToken,
                                                  (const Ipp32s **) m_tblTotalZeros,
                                                  (const Ipp32s **) m_tblRunBefore,
                                                  (Ipp32s*)mp_scan4x4[field_flag]);

        if (ippStsNoErr > ippRes)
            throw h264_exception(UMC_ERR_INVALID_STREAM);
    } // void GetCAVLCInfoChroma4(Ipp16s &sNumCoeff,


    void GetOrg(Ipp32u **pbs, Ipp32u *size);
    void GetState(Ipp32u **pbs, Ipp32u *bitOffset);
    void SetState(Ipp32u *pbs, Ipp32u bitOffset);

    // Read one VLC Ipp32s or Ipp32u value from bitstream
    inline
    Ipp32s GetVLCElement(bool bIsSigned);

    // Reads bits from buffer.
    inline
    Ipp32u GetBits(const Ipp32u nbits);

    // Reads one bit from the buffer.
    inline
    Ipp32u Get1Bit();

    // Searches for a code with known number of bits.
    bool SearchBits(const Ipp32u nbits,
                    const Ipp32u code,
                    const Ipp32u lookahead);
    bool NextBit();

    // Set current decoding position
    void SetDecodedBytes(size_t);

    inline
    size_t BytesDecoded()
    {
        return static_cast<size_t>((Ipp8u*)m_pbs - (Ipp8u*)m_pbsBase) +
                ((31 - m_bitOffset) >> 3);
    }
    inline
    size_t BytesLeft()
    {
        return((Ipp32s)m_maxBsSize - (Ipp32s) BytesDecoded());
    }

    inline size_t GetAllBitsCount()
    {
        return m_maxBsSize;
    }

    inline
    size_t BytesDecodedRoundOff()
    {
        return static_cast<size_t>((Ipp8u*)m_pbs - (Ipp8u*)m_pbsBase);
    }

    //
    // CABAC decoding function(s)
    //

    // Initialize CABAC decoding engine
    void InitializeDecodingEngine_CABAC(void);
    // Terminate CABAC decoding engine, rollback prereaded bits
    void TerminateDecode_CABAC(void);

    // Initialize CABAC context(s) in intra slices
    void InitializeContextVariablesIntra_CABAC(Ipp32s SliceQPy);

    // Initialize CABAC context(s) in inter slices
    void InitializeContextVariablesInter_CABAC(Ipp32s SliceQPy,
                                               Ipp32s cabac_init_idc);

    // Decode order of single bins
    Ipp32u DecodeSingleBinOnes_CABAC(Ipp32u ctxIdx,
                                     Ipp32s &binIdx);

    // Decode Ipp32s coefficient value
    Ipp32s DecodeSignedLevel_CABAC(Ipp32u ctxIdxOffset,
                                   Ipp32u &numDecodAbsLevelEq1,
                                   Ipp32u &numDecodAbsLevelGt1,
                                   Ipp32u max_value);
    Ipp32s DecodeSingleSignedLevel_CABAC(Ipp32u ctxIdxOffset);

    // Decode single bin from stream
    inline
    Ipp32u DecodeSingleBin_CABAC(Ipp32u ctxIdx);

    // Decode single bin using bypass decoding
    inline
    Ipp32u DecodeBypass_CABAC();

    inline
    Ipp32s DecodeBypassSign_CABAC(Ipp32s val);

    // Decode multiple bins using bypass decoding until ==1
    inline
    Ipp32u DecodeBypassOnes_CABAC();

    // Decode end symbol
    inline
    Ipp32u DecodeSymbolEnd_CABAC();

    template <typename Coeffs>
    void ResidualBlock8x8_CABAC(bool field_decoding_flag,
                                const Ipp32s *single_scan,
                                Coeffs *pPosCoefbuf)
    {
        // See subclause 7.3.5.3.2 of H.264 standard
        Ipp32u ctxIdxOffset, ctxIdxInc, ctxIdxOffsetLast;
        Ipp32u numDecodAbsLevelEq1 = 0, numDecodAbsLevelGt1 = 0;
        const Ipp32u *ctxIdxBase;
        const Ipp32s* pHPFF = hp_CtxIdxInc_sig_coeff_flag[field_decoding_flag];

        Ipp32s maxNumCoeffminus1 = 63;
        Ipp32u ncoefs = 0;
        Ipp32s i = 0;

⌨️ 快捷键说明

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