/src/libmpeg2/decoder/impeg2d_bitstream.c
Line | Count | Source |
1 | | /****************************************************************************** |
2 | | * |
3 | | * Copyright (C) 2015 The Android Open Source Project |
4 | | * |
5 | | * Licensed under the Apache License, Version 2.0 (the "License"); |
6 | | * you may not use this file except in compliance with the License. |
7 | | * You may obtain a copy of the License at: |
8 | | * |
9 | | * http://www.apache.org/licenses/LICENSE-2.0 |
10 | | * |
11 | | * Unless required by applicable law or agreed to in writing, software |
12 | | * distributed under the License is distributed on an "AS IS" BASIS, |
13 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
14 | | * See the License for the specific language governing permissions and |
15 | | * limitations under the License. |
16 | | * |
17 | | ***************************************************************************** |
18 | | * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore |
19 | | */ |
20 | | /*****************************************************************************/ |
21 | | /* */ |
22 | | /* File Name : impeg2d_bitstream.c */ |
23 | | /* */ |
24 | | /* Description : This file contains all the necessary examples to */ |
25 | | /* establish a consistent use of Ittiam C coding */ |
26 | | /* standards (based on Indian Hill C Standards) */ |
27 | | /* */ |
28 | | /* List of Functions : <List the functions defined in this file> */ |
29 | | /* */ |
30 | | /* Issues / Problems : None */ |
31 | | /* */ |
32 | | /* Revision History : */ |
33 | | /* */ |
34 | | /* DD MM YYYY Author(s) Changes (Describe the changes made) */ |
35 | | /* 10 01 2005 Ittiam Draft */ |
36 | | /* */ |
37 | | /*****************************************************************************/ |
38 | | #include <stdlib.h> |
39 | | |
40 | | #include "iv_datatypedef.h" |
41 | | #include "impeg2_defs.h" |
42 | | #include "impeg2_platform_macros.h" |
43 | | #include "impeg2_macros.h" |
44 | | #include "impeg2d_bitstream.h" |
45 | | |
46 | | #define BIT(val,bit) (UWORD16)(((val) >> (bit)) & 0x1) |
47 | | /****************************************************************************** |
48 | | * |
49 | | * Function Name : impeg2d_bit_stream_init |
50 | | * |
51 | | * Description : This is a Bitstream initialising function. |
52 | | * Arguments : |
53 | | * stream : Pointer to the Bitstream. |
54 | | * byteBuf : Address of the buffer |
55 | | * size : Size of the buffer in bytes |
56 | | * |
57 | | * Values Returned : None |
58 | | *******************************************************************************/ |
59 | | void impeg2d_bit_stream_init(stream_t *ps_stream, |
60 | | UWORD8 *pu1_byte_buf, |
61 | | UWORD32 u4_max_offset) |
62 | 87.5k | { |
63 | 87.5k | UWORD8 *pu1_byte_buff; |
64 | 87.5k | UWORD32 *pu4_word_buf; |
65 | 87.5k | size_t u4_byte_addr; |
66 | 87.5k | UWORD32 u4_temp1,u4_temp2; |
67 | | |
68 | | /* Set parameters of the stream structure.Associate the structure with |
69 | | the file */ |
70 | 87.5k | ps_stream->pv_bs_buf = pu1_byte_buf; |
71 | 87.5k | ps_stream->u4_offset = 0; |
72 | | |
73 | | /* Take care of unaligned address and create |
74 | | nearest greater aligned address */ |
75 | 87.5k | pu1_byte_buff = (UWORD8 *)pu1_byte_buf; |
76 | 87.5k | u4_byte_addr = (size_t)pu1_byte_buff; |
77 | | |
78 | 87.5k | if((u4_byte_addr & 3) == 1) |
79 | 6.43k | { |
80 | 6.43k | u4_temp1 = ((UWORD32)(*pu1_byte_buff++)) << 8; |
81 | 6.43k | u4_temp1 += ((UWORD32)(*pu1_byte_buff++)) << 16; |
82 | 6.43k | u4_temp1 += ((UWORD32)(*pu1_byte_buff++)) << 24; |
83 | | |
84 | 6.43k | pu4_word_buf = (UWORD32 *)pu1_byte_buff; |
85 | | |
86 | 6.43k | ps_stream->u4_offset = 8; |
87 | 6.43k | } |
88 | 81.0k | else if((u4_byte_addr & 3) == 2) |
89 | 9.50k | { |
90 | 9.50k | u4_temp1 = ((UWORD32)(*pu1_byte_buff++)) << 16; |
91 | 9.50k | u4_temp1 += ((UWORD32)(*pu1_byte_buff++)) << 24; |
92 | | |
93 | 9.50k | pu4_word_buf = (UWORD32 *)pu1_byte_buff; |
94 | | |
95 | 9.50k | ps_stream->u4_offset = 16; |
96 | 9.50k | } |
97 | 71.5k | else if((u4_byte_addr & 3) == 3) |
98 | 5.76k | { |
99 | 5.76k | u4_temp1 = (((UWORD32)(*pu1_byte_buff++)) << 24); |
100 | | |
101 | 5.76k | pu4_word_buf = (UWORD32 *)pu1_byte_buff; |
102 | | |
103 | 5.76k | ps_stream->u4_offset = 24; |
104 | 5.76k | } |
105 | 65.8k | else |
106 | 65.8k | { |
107 | 65.8k | pu4_word_buf = (UWORD32 *)pu1_byte_buff; |
108 | | |
109 | 65.8k | u4_temp1 = *pu4_word_buf++; |
110 | 65.8k | ps_stream->u4_offset = 0; |
111 | 65.8k | } |
112 | | |
113 | | /* convert the endian ness from Little endian to Big endian so that bits |
114 | | are in proper order from MSB to LSB */ |
115 | 87.5k | CONV_LE_TO_BE(u4_temp2,u4_temp1) |
116 | | |
117 | | /* Read One more word for buf nxt */ |
118 | 87.5k | u4_temp1 = *pu4_word_buf++; |
119 | 87.5k | ps_stream->u4_buf = u4_temp2; |
120 | | |
121 | 87.5k | CONV_LE_TO_BE(u4_temp2,u4_temp1) |
122 | | |
123 | 87.5k | ps_stream->u4_buf_nxt = u4_temp2; |
124 | | |
125 | 87.5k | ps_stream->pu4_buf_aligned = pu4_word_buf; |
126 | | |
127 | | |
128 | 87.5k | ps_stream->u4_max_offset = (u4_max_offset << 3) + ps_stream->u4_offset; |
129 | | |
130 | 87.5k | return; |
131 | 87.5k | } |
132 | | |
133 | | |
134 | | |
135 | | /****************************************************************************** |
136 | | * |
137 | | * Function Name : impeg2d_bit_stream_get_bit |
138 | | * |
139 | | * Description : This is a Bitstream processing function. It reads the |
140 | | * bit currently pointed by the bit pointer in the buffer and |
141 | | * advances the pointer by one. |
142 | | * Arguments : |
143 | | * stream : Pointer to the Bitstream. |
144 | | * |
145 | | * Values Returned : The bit read(0/1) |
146 | | *******************************************************************************/ |
147 | | UWORD8 impeg2d_bit_stream_get_bit(stream_t *ps_stream) |
148 | 2.28M | { |
149 | 2.28M | UWORD32 u4_bit,u4_offset,u4_temp; |
150 | 2.28M | UWORD32 u4_curr_bit; |
151 | | |
152 | 2.28M | u4_offset = ps_stream->u4_offset; |
153 | 2.28M | u4_curr_bit = u4_offset & 0x1F; |
154 | 2.28M | u4_bit = ps_stream->u4_buf; |
155 | | |
156 | | /* Move the current bit read from the current word to the |
157 | | least significant bit positions of 'c'.*/ |
158 | 2.28M | u4_bit >>= BITS_IN_INT - u4_curr_bit - 1; |
159 | | |
160 | 2.28M | u4_offset++; |
161 | | |
162 | | /* If the last bit of the last word of the buffer has been read update |
163 | | the currrent buf with next, and read next buf from bit stream buffer */ |
164 | 2.28M | if (u4_curr_bit == 31) |
165 | 141k | { |
166 | 141k | ps_stream->u4_buf = ps_stream->u4_buf_nxt; |
167 | | |
168 | 141k | if (ps_stream->u4_offset < ps_stream->u4_max_offset) |
169 | 141k | { |
170 | 141k | u4_temp = *(ps_stream->pu4_buf_aligned)++; |
171 | 141k | CONV_LE_TO_BE(ps_stream->u4_buf_nxt,u4_temp) |
172 | 141k | } |
173 | 141k | } |
174 | 2.28M | ps_stream->u4_offset = u4_offset; |
175 | | |
176 | 2.28M | return (u4_bit & 0x1); |
177 | 2.28M | } |
178 | | /****************************************************************************** |
179 | | * |
180 | | * Function Name : impeg2d_bit_stream_flush |
181 | | * |
182 | | * Description : This is a Bitstream processing function. It |
183 | | * advances the bit and byte pointers appropriately |
184 | | * |
185 | | * Arguments : |
186 | | * ctxt : Pointer to the Bitstream. |
187 | | * numBits : No of bits to be read |
188 | | * |
189 | | * Values Returned : None |
190 | | *******************************************************************************/ |
191 | | void impeg2d_bit_stream_flush(void* pv_ctxt, UWORD32 u4_no_of_bits) |
192 | 523M | { |
193 | 523M | stream_t *ps_stream = (stream_t *)pv_ctxt; |
194 | | |
195 | | |
196 | 523M | if (ps_stream->u4_offset <= ps_stream->u4_max_offset) |
197 | 523M | { |
198 | | /* We have to flush the bytes even if the offset is equal to the maximum |
199 | | * offset. This will ensure that a stream with an error exactly at the |
200 | | * offset will not get stuck in an infinite loop - If we do not flush |
201 | | * these bytes, then we keep feeding the erroneous bits. |
202 | | */ |
203 | 523M | FLUSH_BITS(ps_stream->u4_offset,ps_stream->u4_buf,ps_stream->u4_buf_nxt,u4_no_of_bits,ps_stream->pu4_buf_aligned) |
204 | 523M | } |
205 | 523M | return; |
206 | 523M | } |
207 | | /****************************************************************************** |
208 | | * |
209 | | * Function Name : impeg2d_bit_stream_flush_to_byte_boundary |
210 | | * |
211 | | * Description : This is a Bitstream processing function.It advances |
212 | | * the bit and byte pointers to next byte boundary |
213 | | * |
214 | | * Arguments : |
215 | | * stream : Pointer to the Bitstream. |
216 | | * NoOfBits : No of bits to be read |
217 | | * |
218 | | * Values Returned : The bits read (upto 32 bits maximum) starting from the |
219 | | * least significant bit and going towards most significant |
220 | | * bit in the order of their occurence. |
221 | | *******************************************************************************/ |
222 | | void impeg2d_bit_stream_flush_to_byte_boundary(void* pv_ctxt) |
223 | 2.53M | { |
224 | 2.53M | UWORD8 u1_bit_offset; |
225 | 2.53M | stream_t *ps_stream = (stream_t *)pv_ctxt; |
226 | | |
227 | 2.53M | u1_bit_offset = (ps_stream->u4_offset) & 0x7; |
228 | | |
229 | | |
230 | | /* if it is not byte aligned make it byte aligned*/ |
231 | 2.53M | if(u1_bit_offset != 0) |
232 | 1.93M | { |
233 | 1.93M | impeg2d_bit_stream_flush(ps_stream,(8 - u1_bit_offset)); |
234 | 1.93M | } |
235 | | |
236 | | |
237 | | |
238 | 2.53M | } |
239 | | |
240 | | |
241 | | /****************************************************************************** |
242 | | * |
243 | | * Function Name : ibits_next |
244 | | * |
245 | | * Description : This is a Bitstream processing function.It gets the |
246 | | * specified number of bits from the buffer without |
247 | | * altering the current pointers. It is used mainly to |
248 | | * check for some specific pattern of bits like start |
249 | | * code. This is equivalent to next_bits() function |
250 | | * defined in MPEG-4 Visual Standard Definition of functions |
251 | | * |
252 | | * Arguments : |
253 | | * ctxt : Pointer to the Bitstream. |
254 | | * numBits : No of bits to be read |
255 | | * |
256 | | * Values Returned : The bits read (upto 32 bits maximum) starting from the |
257 | | * least significant bit and going towards most significant |
258 | | * bit in the order of their occurence. |
259 | | *******************************************************************************/ |
260 | | UWORD32 impeg2d_bit_stream_nxt( stream_t *ps_stream, WORD32 i4_no_of_bits) |
261 | 778M | { |
262 | 778M | UWORD32 u4_bits,u4_offset,u4_temp; |
263 | 778M | UWORD8 u4_bit_ptr; |
264 | | |
265 | 778M | ASSERT(i4_no_of_bits > 0); |
266 | | |
267 | 778M | u4_offset = ps_stream->u4_offset; |
268 | 778M | u4_bit_ptr = u4_offset & 0x1F; |
269 | 778M | u4_bits = ps_stream->u4_buf << u4_bit_ptr; |
270 | | |
271 | 778M | u4_bit_ptr += i4_no_of_bits; |
272 | 778M | if(32 < u4_bit_ptr) |
273 | 227M | { |
274 | | /* Read bits from the next word if necessary */ |
275 | 227M | u4_temp = ps_stream->u4_buf_nxt; |
276 | 227M | u4_bit_ptr &= (BITS_IN_INT - 1); |
277 | | |
278 | 227M | u4_temp = (u4_temp >> (BITS_IN_INT - u4_bit_ptr)); |
279 | | |
280 | | /* u4_temp consists of bits,if any that had to be read from the next word |
281 | | of the buffer.The bits read from both the words are concatenated and |
282 | | moved to the least significant positions of 'u4_bits'*/ |
283 | 227M | u4_bits = (u4_bits >> (32 - i4_no_of_bits)) | u4_temp; |
284 | 227M | } |
285 | 551M | else |
286 | 551M | { |
287 | 551M | u4_bits = (u4_bits >> (32 - i4_no_of_bits)); |
288 | 551M | } |
289 | | |
290 | 778M | return (u4_bits); |
291 | 778M | } |
292 | | /****************************************************************************** |
293 | | * |
294 | | * Function Name : impeg2d_bit_stream_get |
295 | | * |
296 | | * Description : This is a Bitstream processing function. It reads a |
297 | | * specified number of bits from the current bit |
298 | | * position and advances the bit and byte pointers |
299 | | * appropriately |
300 | | * Arguments : |
301 | | * ctxt : Pointer to the Bitstream. |
302 | | * numBits : No of bits to be read |
303 | | * |
304 | | * Values Returned : The bits read (upto 32 bits maximum) starting from the |
305 | | * least significant bit and going towards most significant |
306 | | * bit in the order of their occurence. |
307 | | *******************************************************************************/ |
308 | | |
309 | | UWORD32 impeg2d_bit_stream_get(void* pv_ctxt, UWORD32 u4_num_bits) |
310 | 351M | { |
311 | 351M | UWORD32 u4_next_bits = impeg2d_bit_stream_nxt(pv_ctxt, u4_num_bits); |
312 | 351M | impeg2d_bit_stream_flush(pv_ctxt, u4_num_bits); |
313 | 351M | return(u4_next_bits); |
314 | 351M | } |
315 | | |
316 | | |
317 | | |
318 | | /****************************************************************************** |
319 | | * |
320 | | * Function Name : impeg2d_bit_stream_num_bits_read |
321 | | * |
322 | | * Description : This is a Bitstream processing function. It reads a |
323 | | * specified number of bits from the current bit |
324 | | * position and advances the bit and byte pointers |
325 | | * appropriately |
326 | | * Arguments : |
327 | | * ctxt : Pointer to the Bitstream. |
328 | | * numBits : No of bits to be read |
329 | | * |
330 | | * Values Returned : The bits read (upto 16 bits maximum) starting from the |
331 | | * least significant bit and going towards most significant |
332 | | * bit in the order of their occurence. |
333 | | *******************************************************************************/ |
334 | | UWORD32 impeg2d_bit_stream_num_bits_read(void* pv_ctxt) |
335 | 14.0k | { |
336 | 14.0k | stream_t *u4_no_of_bitsstream = (stream_t *)pv_ctxt; |
337 | 14.0k | size_t u4_temp; |
338 | 14.0k | UWORD32 u4_bits_read; |
339 | 14.0k | u4_temp = (size_t)(u4_no_of_bitsstream->pv_bs_buf); |
340 | 14.0k | u4_temp &= 0x3; |
341 | 14.0k | u4_bits_read = (u4_no_of_bitsstream->u4_offset - (u4_temp << 3)); |
342 | | |
343 | 14.0k | return(u4_bits_read); |
344 | | |
345 | 14.0k | } |
346 | | |
347 | | |