📄 umc_h264_bitstream_inlines.h
字号:
/*
//
// 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_INLINES_H
#define __UMC_H264_BITSTREAM_INLINES_H
#include "vm_debug.h"
#include "umc_h264_bitstream.h"
#include "umc_h264_dec_init_tables_cabac.h"
#include "umc_h264_dec_tables.h"
using namespace UMC_H264_DECODER;
namespace UMC
{
#define _h264GetBits(current_data, offset, nbits, data) \
{ \
Ipp32u x; \
\
VM_ASSERT((nbits) > 0 && (nbits) <= 32); \
VM_ASSERT(offset >= 0 && offset <= 31); \
\
offset -= (nbits); \
\
if (offset >= 0) \
{ \
x = current_data[0] >> (offset + 1); \
} \
else \
{ \
offset += 32; \
\
x = current_data[1] >> (offset); \
x >>= 1; \
x += current_data[0] << (31 - offset); \
current_data++; \
} \
\
VM_ASSERT(offset >= 0 && offset <= 31); \
\
(data) = x & (((Ipp32u)0x01 << (nbits)) - 1); \
}
#define ippiSkipNBits(current_data, offset, nbits) \
{ \
/* check error(s) */ \
VM_ASSERT((nbits) > 0 && (nbits) <= 32); \
VM_ASSERT(offset >= 0 && offset <= 31); \
/* decrease number of available bits */ \
offset -= (nbits); \
/* normalize bitstream pointer */ \
if (0 > offset) \
{ \
offset += 32; \
current_data++; \
} \
/* check error(s) again */ \
VM_ASSERT(offset >= 0 && offset <= 31); \
}
#define ippiGetBits1(current_data, offset, data) \
{ \
data = ((current_data[0] >> (offset)) & 1); \
offset -= 1; \
if (offset < 0) \
{ \
offset = 31; \
current_data += 1; \
} \
}
//#define ippiGetBits1( current_data, offset, data) \
// _h264GetBits(current_data, offset, 1, data);
#define ippiGetBits8( current_data, offset, data) \
_h264GetBits(current_data, offset, 8, data);
#define ippiGetNBits( current_data, offset, nbits, data) \
_h264GetBits(current_data, offset, nbits, data);
#define ippiUngetNBits(current_data, offset, nbits) \
{ \
VM_ASSERT(offset >= 0 && offset <= 31); \
\
offset += (nbits); \
if (offset > 31) \
{ \
offset -= 32; \
current_data--; \
} \
\
VM_ASSERT(offset >= 0 && offset <= 31); \
}
#define ippiUngetBits32(current_data, offset) \
VM_ASSERT(offset >= 0 && offset <= 31); \
current_data--;
#define ippiAlignBSPointerRight(current_data, offset) \
{ \
if ((offset & 0x07) != 0x07) \
{ \
offset = (offset | 0x07) - 8; \
if (offset == -1) \
{ \
offset = 31; \
current_data++; \
} \
} \
}
#define ippiNextBits(current_data, offset, nbits, data) \
{ \
Ipp32s bp; \
Ipp32u x; \
\
VM_ASSERT((nbits) >= 0 && (nbits) <= 32); \
VM_ASSERT(offset >= 0 && offset <= 31); \
\
bp = offset - (nbits); \
\
if (bp < 0) \
{ \
bp += 32; \
x = current_data[1] >> bp; \
x >>= 1; \
x += current_data[0] << (31 - bp); \
} \
else \
{ \
x = current_data[0] >> bp; \
x >>= 1; \
} \
\
(data) = x & (((Ipp32u)0x01 << (nbits)) - 1); \
}
#define RefreshCABACBits(codOffset, pBits, iBits) \
{ \
Ipp16u *pRealPointer; \
/* we have to handle the bit pointer very thorougly. */ \
/* this sophisticated logic is used to avoid compilers' warnings. */ \
/* In two words we just select required word by the pointer */ \
pRealPointer = (Ipp16u *) (((Ipp8u *) 0) + \
((((Ipp8u *) pBits) - (Ipp8u *) 0) ^ 2)); \
codOffset |= *(pRealPointer) << (-iBits); \
pBits += 1; \
iBits += 16; \
}
inline
void H264Bitstream::AlignPointerRight(void)
{
ippiAlignBSPointerRight(m_pbs, m_bitOffset);
} // void H264Bitstream::AlignPointerRight(void)
inline
Ipp32u H264Bitstream::GetBits(const Ipp32u nbits)
{
Ipp32u w, n = nbits;
ippiGetNBits(m_pbs, m_bitOffset, n, w);
return(w);
} // H264Bitstream::GetBits()
inline
Ipp32u H264Bitstream::Get1Bit()
{
Ipp32u w;
ippiGetBits1(m_pbs, m_bitOffset, w);
return(w);
} // H264Bitstream::Get1Bit()
inline
bool H264Bitstream::NextBit()
{
Ipp32s bp;
Ipp32u w;
bp = m_bitOffset - 1;
if (bp < 0)
{
w = m_pbs[0] & 1;
if (w)
{
m_pbs++;
m_bitOffset = 31;
return true;
}
}
else
{
w = m_pbs[0] >> m_bitOffset;
w = w & 1;
if (w)
{
m_bitOffset = bp;
return true;
}
}
return false;
} // H264Bitstream::SearchBits()
inline
Ipp32u H264Bitstream::DecodeSingleBin_CABAC(Ipp32u ctxIdx)
{
Ipp32u codIOffset = m_lcodIOffset;
Ipp32u codIRange = m_lcodIRange;
Ipp32u codIRangeLPS;
Ipp32u pState = context_array[ctxIdx].pStateIdxAndVal;
Ipp32u binVal;
#ifdef STORE_CABAC_BITS
Ipp8u preState = context_array[ctxIdx].pStateIdxAndVal;
#endif
codIRangeLPS = rangeTabLPS[pState][(codIRange >> (6 + CABAC_MAGIC_BITS)) - 4];
codIRange -= codIRangeLPS << CABAC_MAGIC_BITS;
// most probably state.
// it is more likely to decode most probably value.
if (codIOffset < codIRange)
{
binVal = pState & 1;
context_array[ctxIdx].pStateIdxAndVal = transIdxMPS[pState];
#ifndef STORE_CABAC_BITS
// there is no likely case.
// we take new bit with 50% probability.
{
Ipp32s numBits = NumBitsToGetTableSmall[codIRange >> (CABAC_MAGIC_BITS + 7)];
codIRange <<= numBits;
codIOffset <<= numBits;
m_lcodIOffset = codIOffset;
m_lcodIRange = codIRange;
#if (CABAC_MAGIC_BITS > 0)
{
Ipp32s iMagicBits;
iMagicBits = m_iMagicBits - numBits;
// in most cases we don't require to refresh cabac variables.
if (iMagicBits)
{
m_iMagicBits = iMagicBits;
return binVal;
}
RefreshCABACBits(m_lcodIOffset, m_pMagicBits, iMagicBits);
m_iMagicBits = iMagicBits;
}
return binVal;
#else // !(CABAC_MAGIC_BITS > 0)
m_lcodIOffset |= GetBits(numBits);
return binVal;
#endif // (CABAC_MAGIC_BITS > 0)
}
#endif // STORE_CABAC_BITS
}
else
{
codIOffset -= codIRange;
codIRange = codIRangeLPS << CABAC_MAGIC_BITS;
binVal = (pState & 1) ^ 1;
context_array[ctxIdx].pStateIdxAndVal = transIdxLPS[pState];
}
// Renormalization process
// See subclause 9.3.3.2.2 of H.264
//if (codIRange < (0x100<<(CABAC_MAGIC_BITS)))
{
Ipp32s numBits = NumBitsToGetTbl[codIRange >> CABAC_MAGIC_BITS];
codIRange <<= numBits;
codIOffset <<= numBits;
#if (CABAC_MAGIC_BITS > 0)
{
Ipp32s iMagicBits;
iMagicBits = m_iMagicBits - numBits;
if (0 >= iMagicBits)
{
RefreshCABACBits(codIOffset, m_pMagicBits, iMagicBits);
m_iMagicBits = iMagicBits;
}
else
m_iMagicBits = iMagicBits;
}
#else // !(CABAC_MAGIC_BITS > 0)
codIOffset |= GetBits(numBits);
#endif // (CABAC_MAGIC_BITS > 0)
}
#ifdef STORE_CABAC_BITS
sym_cnt++;
if (cabac_bits==NULL) cabac_bits=fopen(__CABAC_FILE__,"w+t");
if (cabac_bits)
#ifdef CABAC_DECORER_COMP
fprintf(cabac_bits,"sb %d %d %d %d %d\n",
ctxIdx,
codIRange>>CABAC_MAGIC_BITS,
codIOffset>>CABAC_MAGIC_BITS,
binVal,sym_cnt);
#else
fprintf(cabac_bits,"sb %d %d %d %d %d %d %d\n",ctxIdx,preState>>1,preState&1,context_array[ctxIdx].pStateIdxAndVal>>1,context_array[ctxIdx].pStateIdxAndVal&1,binVal,sym_cnt);
#endif
fflush(cabac_bits);
#endif
m_lcodIOffset = codIOffset;
m_lcodIRange = codIRange;
return binVal;
} //Ipp32s H264Bitstream::DecodeSingleBin_CABAC(Ipp32s ctxIdx)
inline
Ipp32u H264Bitstream::DecodeSymbolEnd_CABAC(void)
{
Ipp32u binVal = 1;
Ipp32u codIOffset = m_lcodIOffset;
Ipp32u codIRange = m_lcodIRange;
// See subclause 9.3.3.2.4 of H.264 standard
if (codIOffset < (codIRange - (2 << CABAC_MAGIC_BITS)))
{
codIRange -= (2 << CABAC_MAGIC_BITS);
// Renormalization process
// See subclause 9.3.3.2.2 of H.264
if (codIRange < (0x100 << (CABAC_MAGIC_BITS)))
{
codIRange <<= 1;
codIOffset <<= 1;
#if (CABAC_MAGIC_BITS > 0)
m_iMagicBits -= 1;
if (0 >= m_iMagicBits)
RefreshCABACBits(codIOffset, m_pMagicBits, m_iMagicBits);
#else // !(CABAC_MAGIC_BITS > 0)
codIOffset |= GetBits(1);
#endif // (CABAC_MAGIC_BITS > 0)
}
binVal = 0;
m_lcodIOffset = codIOffset;
m_lcodIRange = codIRange;
}
#ifdef STORE_CABAC_BITS
sym_cnt++;
if (cabac_bits==NULL) cabac_bits=fopen(__CABAC_FILE__,"w+t");
if (cabac_bits)
#ifdef CABAC_DECORER_COMP
fprintf(cabac_bits,"fsb %d %d %d %d\n",m_lcodIRange>>CABAC_MAGIC_BITS,
m_lcodIOffset>>CABAC_MAGIC_BITS,
binVal,sym_cnt);
#else
fprintf(cabac_bits,"fsb %d %d\n",binVal,sym_cnt);
#endif
fflush(cabac_bits);
#endif
return binVal;
} //Ipp32s H264Bitstream::DecodeSymbolEnd_CABAC(void)
inline
Ipp32u H264Bitstream::DecodeBypass_CABAC(void)
{
// See subclause 9.3.3.2.3 of H.264 standard
Ipp32u binVal;
#if (CABAC_MAGIC_BITS > 0)
m_lcodIOffset = (m_lcodIOffset << 1);
m_iMagicBits -= 1;
if (0 >= m_iMagicBits)
RefreshCABACBits(m_lcodIOffset, m_pMagicBits, m_iMagicBits);
#else // !(CABAC_MAGIC_BITS > 0)
m_lcodIOffset = (m_lcodIOffset << 1) | Get1Bit();
#endif // (CABAC_MAGIC_BITS > 0)
if (m_lcodIOffset >= m_lcodIRange)
{
binVal = 1;
m_lcodIOffset -= m_lcodIRange;
}
else
{
binVal = 0;
}
#ifdef STORE_CABAC_BITS
sym_cnt++;
if (cabac_bits==NULL) cabac_bits=fopen(__CABAC_FILE__,"w+t");
if (cabac_bits)
#ifdef CABAC_DECORER_COMP
fprintf(cabac_bits,"bp %d %d %d %d\n",m_lcodIRange>>CABAC_MAGIC_BITS,
m_lcodIOffset>>CABAC_MAGIC_BITS,
binVal,sym_cnt);
#else
fprintf(cabac_bits,"bp %d %d\n",binVal,sym_cnt);
#endif
fflush(cabac_bits);
#endif
return binVal;
} //Ipp32s H264Bitstream::DecodeBypass_CABAC(void)
inline
Ipp32s H264Bitstream::DecodeBypassSign_CABAC(Ipp32s val)
{
// See subclause 9.3.3.2.3 of H.264 standard
Ipp32s binVal;
#if (CABAC_MAGIC_BITS > 0)
m_lcodIOffset = (m_lcodIOffset << 1);
m_iMagicBits -= 1;
if (0 >= m_iMagicBits)
RefreshCABACBits(m_lcodIOffset, m_pMagicBits, m_iMagicBits);
#else
m_lcodIOffset = (m_lcodIOffset << 1) | Get1Bit();
#endif
if (m_lcodIOffset >= m_lcodIRange)
{
binVal = -val;
m_lcodIOffset -= m_lcodIRange;
}
else
{
binVal = val;
}
#ifdef STORE_CABAC_BITS
sym_cnt++;
if (cabac_bits==NULL) cabac_bits=fopen(__CABAC_FILE__,"w+t");
if (cabac_bits)
#ifdef CABAC_DECORER_COMP
fprintf(cabac_bits,"bp %d %d %d %d\n",m_lcodIRange>>CABAC_MAGIC_BITS,
m_lcodIOffset>>CABAC_MAGIC_BITS,
binVal<0,sym_cnt);
#else
fprintf(cabac_bits,"bp %d %d\n",binVal<0,sym_cnt);
#endif
fflush(cabac_bits);
#endif
return binVal;
} // Ipp32s H264Bitstream::DecodeBypassSign_CABAC()
inline
Ipp32s H264Bitstream::GetVLCElement(bool bIsSigned)
{
Ipp32s sval = 0;
IppStatus ippRes = ippiDecodeExpGolombOne_H264_1u32s(&m_pbs, &m_bitOffset, &sval, bIsSigned);
if (ippStsNoErr > ippRes)
throw h264_exception(UMC_ERR_INVALID_STREAM);
return sval;
} // Ipp32s H264Bitstream::GetVLCElement(bool bIsSigned)
} // namespace UMC
#endif // __UMC_H264_BITSTREAM_INLINES_H
#endif // UMC_ENABLE_H264_VIDEO_DECODER
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -