📄 mpeg4ip_bitstream.h
字号:
/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is MPEG4IP. * * The Initial Developer of the Original Code is Cisco Systems Inc. * Portions created by Cisco Systems Inc. are * Copyright (C) Cisco Systems Inc. 2001-2005. All Rights Reserved. * * Contributor(s): * Bill May wmay@cisco.com */#ifndef __BITSTREAM_H__#define __BITSTREAM_H__ 1#include "mpeg4ip.h"#ifndef MIN#define MIN(a, b) (((a) < (b)) ? (a) : (b))#endiftypedef enum BitstreamErr_t { BITSTREAM_TOO_MANY_BITS, BITSTREAM_PAST_END,} BitstreamErr_t;class CBitstream { public: CBitstream(void) { m_verbose = 0;}; CBitstream(const uint8_t *buffer, uint32_t bit_len) { m_verbose = 0; init(buffer, bit_len); }; ~CBitstream (void) {}; void init(const uint8_t *buffer, uint32_t bit_len) { m_chDecBuffer = buffer; m_chDecBufferSize = bit_len; m_bBookmarkOn = 0; m_uNumOfBitsInBuffer = 0; }; void init(const char *buffer, uint32_t bit_len) { init((const uint8_t *)buffer, (uint32_t)bit_len); }; void init(const char *buffer, int bit_len) { init((const uint8_t *)buffer, (uint32_t)bit_len); }; void init(const uint8_t *buffer, int bit_len) { init(buffer, (uint32_t)bit_len); }; void init(const char *buffer, unsigned short bit_len) { init((const uint8_t *)buffer, (uint32_t)bit_len); }; void init(const uint8_t *buffer, unsigned short bit_len) { init(buffer, (uint32_t)bit_len); }; uint32_t GetBits(uint32_t numBits) { uint32_t retData; static const uint32_t msk[33] = { 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff }; if (numBits > 32) { throw BITSTREAM_TOO_MANY_BITS; } if (numBits == 0) { return 0; } if (m_uNumOfBitsInBuffer >= numBits) { // don't need to read from FILE m_uNumOfBitsInBuffer -= numBits; retData = m_chDecData >> m_uNumOfBitsInBuffer; // wmay - this gets done below...retData &= msk[numBits]; } else { uint32_t nbits; nbits = numBits - m_uNumOfBitsInBuffer; if (nbits == 32) retData = 0; else retData = m_chDecData << nbits; switch ((nbits - 1) / 8) { case 3: nbits -= 8; if (m_chDecBufferSize < 8) throw BITSTREAM_PAST_END; retData |= *m_chDecBuffer++ << nbits; m_chDecBufferSize -= 8; // fall through case 2: nbits -= 8; if (m_chDecBufferSize < 8) throw BITSTREAM_PAST_END; retData |= *m_chDecBuffer++ << nbits; m_chDecBufferSize -= 8; case 1: nbits -= 8; if (m_chDecBufferSize < 8) throw BITSTREAM_PAST_END; retData |= *m_chDecBuffer++ << nbits; m_chDecBufferSize -= 8; case 0: break; } if (m_chDecBufferSize < nbits) { throw BITSTREAM_PAST_END; } m_chDecData = *m_chDecBuffer++; m_uNumOfBitsInBuffer = MIN(8, m_chDecBufferSize) - nbits; m_chDecBufferSize -= MIN(8, m_chDecBufferSize); retData |= (m_chDecData >> m_uNumOfBitsInBuffer) & msk[nbits]; } if (m_verbose) printf("bits %d value %x\n", numBits, retData&msk[numBits]); return (retData & msk[numBits]); }; int getbits(uint32_t bits, uint32_t *retvalue) { try { *retvalue = GetBits(bits); } catch (...) { return -1; } return 0; } int peekbits(uint32_t bits, uint32_t *retvalue) { int ret; bookmark(1); ret = getbits(bits, retvalue); bookmark(0); return (ret); } uint32_t PeekBits(uint32_t bits) { uint32_t ret; bookmark(1); ret = GetBits(bits); bookmark(0); return ret; } void bookmark(int bSet) { if (m_verbose) { printf("bookmark\n"); } if (bSet) { m_uNumOfBitsInBuffer_bookmark = m_uNumOfBitsInBuffer; m_chDecBuffer_bookmark = m_chDecBuffer; m_chDecBufferSize_bookmark = m_chDecBufferSize; m_bBookmarkOn = 1; m_chDecData_bookmark = m_chDecData; } else { m_uNumOfBitsInBuffer = m_uNumOfBitsInBuffer_bookmark; m_chDecBuffer = m_chDecBuffer_bookmark; m_chDecBufferSize = m_chDecBufferSize_bookmark; m_chDecData = m_chDecData_bookmark; m_bBookmarkOn = 0; } }; int bits_remain (void) { return m_chDecBufferSize + m_uNumOfBitsInBuffer; }; int byte_align(void) { int temp = 0; if (m_uNumOfBitsInBuffer != 0) { temp = GetBits(m_uNumOfBitsInBuffer);#if 0 temp = m_uNumOfBitsInBuffer; m_uNumOfBitsInBuffer = 0; m_chDecBuffer++; m_chDecBufferSize -= MIN(m_chDecBufferSize,8);#endif } else { // if we are byte aligned, check for 0x7f value - this will indicate // we need to skip those bits uint8_t readval; readval = PeekBits(8); if (readval == 0x7f) { readval = GetBits(8); } } return (temp); }; void set_verbose(int verbose) { m_verbose = verbose; }; private: uint32_t m_uNumOfBitsInBuffer; const uint8_t *m_chDecBuffer; uint8_t m_chDecData, m_chDecData_bookmark; uint32_t m_chDecBufferSize; int m_bBookmarkOn; uint32_t m_uNumOfBitsInBuffer_bookmark; const uint8_t *m_chDecBuffer_bookmark; uint32_t m_chDecBufferSize_bookmark; int m_verbose;};#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -