Home | History | Annotate | Download | only in H264
      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