1 /* 2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "bitstream_parser.h" 12 13 namespace webrtc { 14 BitstreamParser::BitstreamParser(const uint8_t* data, const uint32_t dataLength) : 15 _data(data), 16 _dataLength(dataLength), 17 _byteOffset(0), 18 _bitOffset(0) 19 { 20 } 21 // todo should we have any error codes from this? 22 23 uint8_t 24 BitstreamParser::Get1Bit() 25 { 26 uint8_t retVal = 0x1 & (_data[_byteOffset] >> (7-_bitOffset++)); 27 28 // prepare next byte 29 if(_bitOffset == 8) 30 { 31 _bitOffset = 0; 32 _byteOffset++; 33 } 34 return retVal; 35 } 36 37 uint8_t 38 BitstreamParser::Get2Bits() 39 { 40 uint8_t retVal = (Get1Bit() << 1); 41 retVal += Get1Bit(); 42 return retVal; 43 } 44 45 uint8_t 46 BitstreamParser::Get3Bits() 47 { 48 uint8_t retVal = (Get1Bit() << 2); 49 retVal += (Get1Bit() << 1); 50 retVal += Get1Bit(); 51 return retVal; 52 } 53 54 uint8_t 55 BitstreamParser::Get4Bits() 56 { 57 uint8_t retVal = (Get1Bit() << 3); 58 retVal += (Get1Bit() << 2); 59 retVal += (Get1Bit() << 1); 60 retVal += Get1Bit(); 61 return retVal; 62 } 63 64 uint8_t 65 BitstreamParser::Get5Bits() 66 { 67 uint8_t retVal = (Get1Bit() << 4); 68 retVal += (Get1Bit() << 3); 69 retVal += (Get1Bit() << 2); 70 retVal += (Get1Bit() << 1); 71 retVal += Get1Bit(); 72 return retVal; 73 } 74 75 uint8_t 76 BitstreamParser::Get6Bits() 77 { 78 uint8_t retVal = (Get1Bit() << 5); 79 retVal += (Get1Bit() << 4); 80 retVal += (Get1Bit() << 3); 81 retVal += (Get1Bit() << 2); 82 retVal += (Get1Bit() << 1); 83 retVal += Get1Bit(); 84 return retVal; 85 } 86 87 uint8_t 88 BitstreamParser::Get7Bits() 89 { 90 uint8_t retVal = (Get1Bit() << 6); 91 retVal += (Get1Bit() << 5); 92 retVal += (Get1Bit() << 4); 93 retVal += (Get1Bit() << 3); 94 retVal += (Get1Bit() << 2); 95 retVal += (Get1Bit() << 1); 96 retVal += Get1Bit(); 97 return retVal; 98 } 99 100 uint8_t 101 BitstreamParser::Get8Bits() 102 { 103 uint16_t retVal; 104 105 if(_bitOffset != 0) 106 { 107 // read 16 bits 108 retVal = (_data[_byteOffset] << 8)+ (_data[_byteOffset+1]) ; 109 retVal = retVal >> (8-_bitOffset); 110 } else 111 { 112 retVal = _data[_byteOffset]; 113 } 114 _byteOffset++; 115 return (uint8_t)retVal; 116 } 117 118 uint16_t 119 BitstreamParser::Get16Bits() 120 { 121 uint32_t retVal; 122 123 if(_bitOffset != 0) 124 { 125 // read 24 bits 126 retVal = (_data[_byteOffset] << 16) + (_data[_byteOffset+1] << 8) + (_data[_byteOffset+2]); 127 retVal = retVal >> (8-_bitOffset); 128 }else 129 { 130 // read 16 bits 131 retVal = (_data[_byteOffset] << 8) + (_data[_byteOffset+1]) ; 132 } 133 _byteOffset += 2; 134 return (uint16_t)retVal; 135 } 136 137 uint32_t 138 BitstreamParser::Get24Bits() 139 { 140 uint32_t retVal; 141 142 if(_bitOffset != 0) 143 { 144 // read 32 bits 145 retVal = (_data[_byteOffset] << 24) + (_data[_byteOffset+1] << 16) + (_data[_byteOffset+2] << 8) + (_data[_byteOffset+3]); 146 retVal = retVal >> (8-_bitOffset); 147 }else 148 { 149 // read 24 bits 150 retVal = (_data[_byteOffset] << 16) + (_data[_byteOffset+1] << 8) + (_data[_byteOffset+2]) ; 151 } 152 _byteOffset += 3; 153 return retVal & 0x00ffffff; // we need to clean up the high 8 bits 154 } 155 156 uint32_t 157 BitstreamParser::Get32Bits() 158 { 159 uint32_t retVal; 160 161 if(_bitOffset != 0) 162 { 163 // read 40 bits 164 uint64_t tempVal = _data[_byteOffset]; 165 tempVal <<= 8; 166 tempVal += _data[_byteOffset+1]; 167 tempVal <<= 8; 168 tempVal += _data[_byteOffset+2]; 169 tempVal <<= 8; 170 tempVal += _data[_byteOffset+3]; 171 tempVal <<= 8; 172 tempVal += _data[_byteOffset+4]; 173 tempVal >>= (8-_bitOffset); 174 175 retVal = uint32_t(tempVal); 176 }else 177 { 178 // read 32 bits 179 retVal = (_data[_byteOffset]<< 24) + (_data[_byteOffset+1] << 16) + (_data[_byteOffset+2] << 8) + (_data[_byteOffset+3]) ; 180 } 181 _byteOffset += 4; 182 return retVal; 183 } 184 185 // Exp-Golomb codes 186 /* 187 with "prefix" and "suffix" bits and assignment to codeNum ranges (informative) 188 Bit string form Range of codeNum 189 1 0 190 0 1 x0 1..2 191 0 0 1 x1 x0 3..6 192 0 0 0 1 x2 x1 x0 7..14 193 0 0 0 0 1 x3 x2 x1 x0 15..30 194 0 0 0 0 0 1 x4 x3 x2 x1 x0 31..62 195 */ 196 197 uint32_t 198 BitstreamParser::GetUE() 199 { 200 uint32_t retVal = 0; 201 uint8_t numLeadingZeros = 0; 202 203 while (Get1Bit() != 1) 204 { 205 numLeadingZeros++; 206 } 207 // prefix 208 retVal = (1 << numLeadingZeros) - 1; 209 210 // suffix 211 while (numLeadingZeros) 212 { 213 retVal += (Get1Bit() << --numLeadingZeros); 214 } 215 return retVal; 216 } 217 } // namespace webrtc 218