mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2025-12-09 04:57:06 +03:00
262 lines
9.2 KiB
C
262 lines
9.2 KiB
C
/* ***** BEGIN LICENSE BLOCK *****
|
|
* Source last modified: $Id: bitstream.c,v 1.2 2005/09/27 20:31:11 jrecker Exp $
|
|
*
|
|
* Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved.
|
|
*
|
|
* The contents of this file, and the files included with this file,
|
|
* are subject to the current version of the RealNetworks Public
|
|
* Source License (the "RPSL") available at
|
|
* http://www.helixcommunity.org/content/rpsl unless you have licensed
|
|
* the file under the current version of the RealNetworks Community
|
|
* Source License (the "RCSL") available at
|
|
* http://www.helixcommunity.org/content/rcsl, in which case the RCSL
|
|
* will apply. You may also obtain the license terms directly from
|
|
* RealNetworks. You may not use this file except in compliance with
|
|
* the RPSL or, if you have a valid RCSL with RealNetworks applicable
|
|
* to this file, the RCSL. Please see the applicable RPSL or RCSL for
|
|
* the rights, obligations and limitations governing use of the
|
|
* contents of the file.
|
|
*
|
|
* This file is part of the Helix DNA Technology. RealNetworks is the
|
|
* developer of the Original Code and owns the copyrights in the
|
|
* portions it created.
|
|
*
|
|
* This file, and the files included with this file, is distributed
|
|
* and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
|
|
* KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
|
|
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
|
|
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
|
|
* ENJOYMENT OR NON-INFRINGEMENT.
|
|
*
|
|
* Technology Compatibility Kit Test Suite(s) Location:
|
|
* http://www.helixcommunity.org/content/tck
|
|
*
|
|
* Contributor(s):
|
|
*
|
|
* ***** END LICENSE BLOCK ***** */
|
|
|
|
/**************************************************************************************
|
|
* Fixed-point HE-AAC decoder
|
|
* Jon Recker (jrecker@real.com)
|
|
* February 2005
|
|
*
|
|
* bitstream.c - bitstream parsing functions
|
|
**************************************************************************************/
|
|
|
|
#include "bitstream.h"
|
|
|
|
/**************************************************************************************
|
|
* Function: SetBitstreamPointer
|
|
*
|
|
* Description: initialize bitstream reader
|
|
*
|
|
* Inputs: pointer to BitStreamInfo struct
|
|
* number of bytes in bitstream
|
|
* pointer to byte-aligned buffer of data to read from
|
|
*
|
|
* Outputs: initialized bitstream info struct
|
|
*
|
|
* Return: none
|
|
**************************************************************************************/
|
|
void SetBitstreamPointer(BitStreamInfo *bsi, int nBytes, unsigned char *buf)
|
|
{
|
|
/* init bitstream */
|
|
bsi->bytePtr = buf;
|
|
bsi->iCache = 0; /* 4-byte unsigned int */
|
|
bsi->cachedBits = 0; /* i.e. zero bits in cache */
|
|
bsi->nBytes = nBytes;
|
|
}
|
|
|
|
/**************************************************************************************
|
|
* Function: RefillBitstreamCache
|
|
*
|
|
* Description: read new data from bitstream buffer into 32-bit cache
|
|
*
|
|
* Inputs: pointer to initialized BitStreamInfo struct
|
|
*
|
|
* Outputs: updated bitstream info struct
|
|
*
|
|
* Return: none
|
|
*
|
|
* Notes: only call when iCache is completely drained (resets bitOffset to 0)
|
|
* always loads 4 new bytes except when bsi->nBytes < 4 (end of buffer)
|
|
* stores data as big-endian in cache, regardless of machine endian-ness
|
|
**************************************************************************************/
|
|
//Optimized for REV16, REV32 (FB)
|
|
static __inline void RefillBitstreamCache(BitStreamInfo *bsi)
|
|
{
|
|
int nBytes = bsi->nBytes;
|
|
if (nBytes >= 4) {
|
|
/* optimize for common case, independent of machine endian-ness */
|
|
bsi->iCache = (*bsi->bytePtr++) << 24;
|
|
bsi->iCache |= (*bsi->bytePtr++) << 16;
|
|
bsi->iCache |= (*bsi->bytePtr++) << 8;
|
|
bsi->iCache |= (*bsi->bytePtr++);
|
|
|
|
bsi->cachedBits = 32;
|
|
bsi->nBytes -= 4;
|
|
} else {
|
|
bsi->iCache = 0;
|
|
while (nBytes--) {
|
|
bsi->iCache |= (*bsi->bytePtr++);
|
|
bsi->iCache <<= 8;
|
|
}
|
|
bsi->iCache <<= ((3 - bsi->nBytes)*8);
|
|
bsi->cachedBits = 8*bsi->nBytes;
|
|
bsi->nBytes = 0;
|
|
}
|
|
}
|
|
|
|
/**************************************************************************************
|
|
* Function: GetBits
|
|
*
|
|
* Description: get bits from bitstream, advance bitstream pointer
|
|
*
|
|
* Inputs: pointer to initialized BitStreamInfo struct
|
|
* number of bits to get from bitstream
|
|
*
|
|
* Outputs: updated bitstream info struct
|
|
*
|
|
* Return: the next nBits bits of data from bitstream buffer
|
|
*
|
|
* Notes: nBits must be in range [0, 31], nBits outside this range masked by 0x1f
|
|
* for speed, does not indicate error if you overrun bit buffer
|
|
* if nBits == 0, returns 0
|
|
**************************************************************************************/
|
|
unsigned int GetBits(BitStreamInfo *bsi, int nBits)
|
|
{
|
|
unsigned int data, lowBits;
|
|
|
|
nBits &= 0x1f; /* nBits mod 32 to avoid unpredictable results like >> by negative amount */
|
|
data = bsi->iCache >> (31 - nBits); /* unsigned >> so zero-extend */
|
|
data >>= 1; /* do as >> 31, >> 1 so that nBits = 0 works okay (returns 0) */
|
|
bsi->iCache <<= nBits; /* left-justify cache */
|
|
bsi->cachedBits -= nBits; /* how many bits have we drawn from the cache so far */
|
|
|
|
/* if we cross an int boundary, refill the cache */
|
|
if (bsi->cachedBits < 0) {
|
|
lowBits = -bsi->cachedBits;
|
|
RefillBitstreamCache(bsi);
|
|
data |= bsi->iCache >> (32 - lowBits); /* get the low-order bits */
|
|
|
|
bsi->cachedBits -= lowBits; /* how many bits have we drawn from the cache so far */
|
|
bsi->iCache <<= lowBits; /* left-justify cache */
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
/**************************************************************************************
|
|
* Function: GetBitsNoAdvance
|
|
*
|
|
* Description: get bits from bitstream, do not advance bitstream pointer
|
|
*
|
|
* Inputs: pointer to initialized BitStreamInfo struct
|
|
* number of bits to get from bitstream
|
|
*
|
|
* Outputs: none (state of BitStreamInfo struct left unchanged)
|
|
*
|
|
* Return: the next nBits bits of data from bitstream buffer
|
|
*
|
|
* Notes: nBits must be in range [0, 31], nBits outside this range masked by 0x1f
|
|
* for speed, does not indicate error if you overrun bit buffer
|
|
* if nBits == 0, returns 0
|
|
**************************************************************************************/
|
|
unsigned int GetBitsNoAdvance(BitStreamInfo *bsi, int nBits)
|
|
{
|
|
unsigned char *buf;
|
|
unsigned int data, iCache;
|
|
signed int lowBits;
|
|
|
|
nBits &= 0x1f; /* nBits mod 32 to avoid unpredictable results like >> by negative amount */
|
|
data = bsi->iCache >> (31 - nBits); /* unsigned >> so zero-extend */
|
|
data >>= 1; /* do as >> 31, >> 1 so that nBits = 0 works okay (returns 0) */
|
|
lowBits = nBits - bsi->cachedBits; /* how many bits do we have left to read */
|
|
|
|
/* if we cross an int boundary, read next bytes in buffer */
|
|
if (lowBits > 0) {
|
|
iCache = 0;
|
|
buf = bsi->bytePtr;
|
|
while (lowBits > 0) {
|
|
iCache <<= 8;
|
|
if (buf < bsi->bytePtr + bsi->nBytes)
|
|
iCache |= (unsigned int)*buf++;
|
|
lowBits -= 8;
|
|
}
|
|
lowBits = -lowBits;
|
|
data |= iCache >> lowBits;
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
/**************************************************************************************
|
|
* Function: AdvanceBitstream
|
|
*
|
|
* Description: move bitstream pointer ahead
|
|
*
|
|
* Inputs: pointer to initialized BitStreamInfo struct
|
|
* number of bits to advance bitstream
|
|
*
|
|
* Outputs: updated bitstream info struct
|
|
*
|
|
* Return: none
|
|
*
|
|
* Notes: generally used following GetBitsNoAdvance(bsi, maxBits)
|
|
**************************************************************************************/
|
|
void AdvanceBitstream(BitStreamInfo *bsi, int nBits)
|
|
{
|
|
nBits &= 0x1f;
|
|
if (nBits > bsi->cachedBits) {
|
|
nBits -= bsi->cachedBits;
|
|
RefillBitstreamCache(bsi);
|
|
}
|
|
bsi->iCache <<= nBits;
|
|
bsi->cachedBits -= nBits;
|
|
}
|
|
|
|
/**************************************************************************************
|
|
* Function: CalcBitsUsed
|
|
*
|
|
* Description: calculate how many bits have been read from bitstream
|
|
*
|
|
* Inputs: pointer to initialized BitStreamInfo struct
|
|
* pointer to start of bitstream buffer
|
|
* bit offset into first byte of startBuf (0-7)
|
|
*
|
|
* Outputs: none
|
|
*
|
|
* Return: number of bits read from bitstream, as offset from startBuf:startOffset
|
|
**************************************************************************************/
|
|
int CalcBitsUsed(BitStreamInfo *bsi, unsigned char *startBuf, int startOffset)
|
|
{
|
|
int bitsUsed;
|
|
|
|
bitsUsed = (bsi->bytePtr - startBuf) * 8;
|
|
bitsUsed -= bsi->cachedBits;
|
|
bitsUsed -= startOffset;
|
|
|
|
return bitsUsed;
|
|
}
|
|
|
|
/**************************************************************************************
|
|
* Function: ByteAlignBitstream
|
|
*
|
|
* Description: bump bitstream pointer to start of next byte
|
|
*
|
|
* Inputs: pointer to initialized BitStreamInfo struct
|
|
*
|
|
* Outputs: byte-aligned bitstream BitStreamInfo struct
|
|
*
|
|
* Return: none
|
|
*
|
|
* Notes: if bitstream is already byte-aligned, do nothing
|
|
**************************************************************************************/
|
|
void ByteAlignBitstream(BitStreamInfo *bsi)
|
|
{
|
|
int offset;
|
|
|
|
offset = bsi->cachedBits & 0x07;
|
|
AdvanceBitstream(bsi, offset);
|
|
}
|