218 lines
5.0 KiB
C++
218 lines
5.0 KiB
C++
|
/*
|
||
|
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||
|
*
|
||
|
* Use of this source code is governed by a BSD-style license
|
||
|
* that can be found in the LICENSE file in the root of the source
|
||
|
* tree. An additional intellectual property rights grant can be found
|
||
|
* in the file PATENTS. All contributing project authors may
|
||
|
* be found in the AUTHORS file in the root of the source tree.
|
||
|
*/
|
||
|
|
||
|
#include "bitstream_parser.h"
|
||
|
|
||
|
namespace webrtc {
|
||
|
BitstreamParser::BitstreamParser(const WebRtc_UWord8* data, const WebRtc_UWord32 dataLength) :
|
||
|
_data(data),
|
||
|
_dataLength(dataLength),
|
||
|
_byteOffset(0),
|
||
|
_bitOffset(0)
|
||
|
{
|
||
|
}
|
||
|
// todo should we have any error codes from this?
|
||
|
|
||
|
WebRtc_UWord8
|
||
|
BitstreamParser::Get1Bit()
|
||
|
{
|
||
|
WebRtc_UWord8 retVal = 0x1 & (_data[_byteOffset] >> (7-_bitOffset++));
|
||
|
|
||
|
// prepare next byte
|
||
|
if(_bitOffset == 8)
|
||
|
{
|
||
|
_bitOffset = 0;
|
||
|
_byteOffset++;
|
||
|
}
|
||
|
return retVal;
|
||
|
}
|
||
|
|
||
|
WebRtc_UWord8
|
||
|
BitstreamParser::Get2Bits()
|
||
|
{
|
||
|
WebRtc_UWord8 retVal = (Get1Bit() << 1);
|
||
|
retVal += Get1Bit();
|
||
|
return retVal;
|
||
|
}
|
||
|
|
||
|
WebRtc_UWord8
|
||
|
BitstreamParser::Get3Bits()
|
||
|
{
|
||
|
WebRtc_UWord8 retVal = (Get1Bit() << 2);
|
||
|
retVal += (Get1Bit() << 1);
|
||
|
retVal += Get1Bit();
|
||
|
return retVal;
|
||
|
}
|
||
|
|
||
|
WebRtc_UWord8
|
||
|
BitstreamParser::Get4Bits()
|
||
|
{
|
||
|
WebRtc_UWord8 retVal = (Get1Bit() << 3);
|
||
|
retVal += (Get1Bit() << 2);
|
||
|
retVal += (Get1Bit() << 1);
|
||
|
retVal += Get1Bit();
|
||
|
return retVal;
|
||
|
}
|
||
|
|
||
|
WebRtc_UWord8
|
||
|
BitstreamParser::Get5Bits()
|
||
|
{
|
||
|
WebRtc_UWord8 retVal = (Get1Bit() << 4);
|
||
|
retVal += (Get1Bit() << 3);
|
||
|
retVal += (Get1Bit() << 2);
|
||
|
retVal += (Get1Bit() << 1);
|
||
|
retVal += Get1Bit();
|
||
|
return retVal;
|
||
|
}
|
||
|
|
||
|
WebRtc_UWord8
|
||
|
BitstreamParser::Get6Bits()
|
||
|
{
|
||
|
WebRtc_UWord8 retVal = (Get1Bit() << 5);
|
||
|
retVal += (Get1Bit() << 4);
|
||
|
retVal += (Get1Bit() << 3);
|
||
|
retVal += (Get1Bit() << 2);
|
||
|
retVal += (Get1Bit() << 1);
|
||
|
retVal += Get1Bit();
|
||
|
return retVal;
|
||
|
}
|
||
|
|
||
|
WebRtc_UWord8
|
||
|
BitstreamParser::Get7Bits()
|
||
|
{
|
||
|
WebRtc_UWord8 retVal = (Get1Bit() << 6);
|
||
|
retVal += (Get1Bit() << 5);
|
||
|
retVal += (Get1Bit() << 4);
|
||
|
retVal += (Get1Bit() << 3);
|
||
|
retVal += (Get1Bit() << 2);
|
||
|
retVal += (Get1Bit() << 1);
|
||
|
retVal += Get1Bit();
|
||
|
return retVal;
|
||
|
}
|
||
|
|
||
|
WebRtc_UWord8
|
||
|
BitstreamParser::Get8Bits()
|
||
|
{
|
||
|
WebRtc_UWord16 retVal;
|
||
|
|
||
|
if(_bitOffset != 0)
|
||
|
{
|
||
|
// read 16 bits
|
||
|
retVal = (_data[_byteOffset] << 8)+ (_data[_byteOffset+1]) ;
|
||
|
retVal = retVal >> (8-_bitOffset);
|
||
|
} else
|
||
|
{
|
||
|
retVal = _data[_byteOffset];
|
||
|
}
|
||
|
_byteOffset++;
|
||
|
return (WebRtc_UWord8)retVal;
|
||
|
}
|
||
|
|
||
|
WebRtc_UWord16
|
||
|
BitstreamParser::Get16Bits()
|
||
|
{
|
||
|
WebRtc_UWord32 retVal;
|
||
|
|
||
|
if(_bitOffset != 0)
|
||
|
{
|
||
|
// read 24 bits
|
||
|
retVal = (_data[_byteOffset] << 16) + (_data[_byteOffset+1] << 8) + (_data[_byteOffset+2]);
|
||
|
retVal = retVal >> (8-_bitOffset);
|
||
|
}else
|
||
|
{
|
||
|
// read 16 bits
|
||
|
retVal = (_data[_byteOffset] << 8) + (_data[_byteOffset+1]) ;
|
||
|
}
|
||
|
_byteOffset += 2;
|
||
|
return (WebRtc_UWord16)retVal;
|
||
|
}
|
||
|
|
||
|
WebRtc_UWord32
|
||
|
BitstreamParser::Get24Bits()
|
||
|
{
|
||
|
WebRtc_UWord32 retVal;
|
||
|
|
||
|
if(_bitOffset != 0)
|
||
|
{
|
||
|
// read 32 bits
|
||
|
retVal = (_data[_byteOffset] << 24) + (_data[_byteOffset+1] << 16) + (_data[_byteOffset+2] << 8) + (_data[_byteOffset+3]);
|
||
|
retVal = retVal >> (8-_bitOffset);
|
||
|
}else
|
||
|
{
|
||
|
// read 24 bits
|
||
|
retVal = (_data[_byteOffset] << 16) + (_data[_byteOffset+1] << 8) + (_data[_byteOffset+2]) ;
|
||
|
}
|
||
|
_byteOffset += 3;
|
||
|
return retVal & 0x00ffffff; // we need to clean up the high 8 bits
|
||
|
}
|
||
|
|
||
|
WebRtc_UWord32
|
||
|
BitstreamParser::Get32Bits()
|
||
|
{
|
||
|
WebRtc_UWord32 retVal;
|
||
|
|
||
|
if(_bitOffset != 0)
|
||
|
{
|
||
|
// read 40 bits
|
||
|
WebRtc_UWord64 tempVal = _data[_byteOffset];
|
||
|
tempVal <<= 8;
|
||
|
tempVal += _data[_byteOffset+1];
|
||
|
tempVal <<= 8;
|
||
|
tempVal += _data[_byteOffset+2];
|
||
|
tempVal <<= 8;
|
||
|
tempVal += _data[_byteOffset+3];
|
||
|
tempVal <<= 8;
|
||
|
tempVal += _data[_byteOffset+4];
|
||
|
tempVal >>= (8-_bitOffset);
|
||
|
|
||
|
retVal = WebRtc_UWord32(tempVal);
|
||
|
}else
|
||
|
{
|
||
|
// read 32 bits
|
||
|
retVal = (_data[_byteOffset]<< 24) + (_data[_byteOffset+1] << 16) + (_data[_byteOffset+2] << 8) + (_data[_byteOffset+3]) ;
|
||
|
}
|
||
|
_byteOffset += 4;
|
||
|
return retVal;
|
||
|
}
|
||
|
|
||
|
// Exp-Golomb codes
|
||
|
/*
|
||
|
with "prefix" and "suffix" bits and assignment to codeNum ranges (informative)
|
||
|
Bit string form Range of codeNum
|
||
|
1 0
|
||
|
0 1 x0 1..2
|
||
|
0 0 1 x1 x0 3..6
|
||
|
0 0 0 1 x2 x1 x0 7..14
|
||
|
0 0 0 0 1 x3 x2 x1 x0 15..30
|
||
|
0 0 0 0 0 1 x4 x3 x2 x1 x0 31..62
|
||
|
*/
|
||
|
|
||
|
WebRtc_UWord32
|
||
|
BitstreamParser::GetUE()
|
||
|
{
|
||
|
WebRtc_UWord32 retVal = 0;
|
||
|
WebRtc_UWord8 numLeadingZeros = 0;
|
||
|
|
||
|
while (Get1Bit() != 1)
|
||
|
{
|
||
|
numLeadingZeros++;
|
||
|
}
|
||
|
// prefix
|
||
|
retVal = (1 << numLeadingZeros) - 1;
|
||
|
|
||
|
// suffix
|
||
|
while (numLeadingZeros)
|
||
|
{
|
||
|
retVal += (Get1Bit() << --numLeadingZeros);
|
||
|
}
|
||
|
return retVal;
|
||
|
}
|
||
|
} // namespace webrtc
|