- add third_party src.
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / modules / rtp_rtcp / source / H264 / bitstream_parser.cc
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