• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2 *
3 * Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore
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 /**
19 *******************************************************************************
20 * @file
21 *  ihevcd_bitstream.c
22 *
23 * @brief
24 *  Contains functions for bitstream access
25 *
26 * @author
27 *  Harish
28 *
29 * @par List of Functions:
30 * - ihevcd_bits_init()
31 * - ihevcd_bits_flush()
32 * - ihevcd_bits_flush_to_byte_boundary()
33 * - ihevcd_bits_nxt()
34 * - ihevcd_bits_nxt32()
35 * - ihevcd_bits_get()
36 * - ihevcd_bits_num_bits_remaining()
37 * - ihevcd_bits_num_bits_consumed()
38 * - ihevcd_sev()
39 * - ihevcd_uev()
40 *
41 *
42 * @remarks
43 *  None
44 *
45 *******************************************************************************
46 */
47 /*****************************************************************************/
48 /* File Includes                                                             */
49 /*****************************************************************************/
50 #include <stdio.h>
51 #include <stddef.h>
52 #include <stdlib.h>
53 #include <string.h>
54 #include <assert.h>
55 #include "ihevc_typedefs.h"
56 #include "iv.h"
57 #include "ivd.h"
58 #include "ihevcd_cxa.h"
59 
60 #include "ihevc_defs.h"
61 #include "ihevc_debug.h"
62 #include "ihevc_structs.h"
63 #include "ihevc_macros.h"
64 #include "ihevc_platform_macros.h"
65 #include "ihevc_cabac_tables.h"
66 
67 #include "ihevcd_defs.h"
68 #include "ihevcd_function_selector.h"
69 #include "ihevcd_structs.h"
70 #include "ihevcd_error.h"
71 #include "ihevcd_bitstream.h"
72 
73 /*****************************************************************************/
74 /* Function Prototypes                                                       */
75 /*****************************************************************************/
76 
77 /**
78 *******************************************************************************
79 *
80 * @brief
81 *  Function used for bitstream structure initialization
82 *
83 * @par Description:
84 *  Initialize bitstream structure elements
85 *
86 * @param[in] ps_bitstrm
87 *  Pointer to bitstream structure
88 *
89 * @param[in] pu1_buf
90 *  Pointer to bitstream data
91 *
92 * @param[in] u4_numbytes
93 *  Number of bytes in bitstream
94 *
95 * @returns  none
96 *
97 * @remarks
98 *  Assumes pu1_buf is aligned to 4 bytes. If not aligned  then all bitstream
99 * accesses will be unaligned and hence  costlier. Since this is codec memory
100 * that holds emulation prevented data, assumption of aligned to 4 bytes is
101 * valid
102 *
103 *******************************************************************************
104 */
ihevcd_bits_init(bitstrm_t * ps_bitstrm,UWORD8 * pu1_buf,UWORD32 u4_numbytes)105 void ihevcd_bits_init(bitstrm_t *ps_bitstrm,
106                       UWORD8 *pu1_buf,
107                       UWORD32 u4_numbytes)
108 {
109     UWORD32 u4_cur_word;
110     UWORD32 u4_nxt_word;
111     UWORD32 u4_temp;
112     UWORD32 *pu4_buf;
113 
114     pu4_buf     = (UWORD32 *)pu1_buf;
115     u4_temp = *pu4_buf++;
116     u4_cur_word = ITT_BIG_ENDIAN(u4_temp);
117     u4_temp = *pu4_buf++;
118     u4_nxt_word = ITT_BIG_ENDIAN(u4_temp);
119 
120     ps_bitstrm->u4_bit_ofst     = 0;
121     ps_bitstrm->pu1_buf_base    = pu1_buf;
122     ps_bitstrm->pu4_buf         = pu4_buf;
123     ps_bitstrm->u4_cur_word     = u4_cur_word;
124     ps_bitstrm->u4_nxt_word     = u4_nxt_word;
125 
126     ps_bitstrm->pu1_buf_max     = pu1_buf + u4_numbytes + 8;
127 
128     return;
129 }
130 
131 /**
132 *******************************************************************************
133 *
134 * @brief
135 *  Flushes given number of bits. Bits consumed increases by  this number
136 *
137 * @par Description:
138 *  Increment bit offset by numbits. If bit offset increases  beyond 32, then
139 * move nxt_word to cur_word, read next  word32 to nxt_word after endian
140 * conversion
141 *
142 * @param[in] ps_bitstrm
143 *  Pointer to bitstream structure
144 *
145 * @param[in] u4_numbits
146 *  Number of bits to be flushed
147 *
148 * @returns  None
149 *
150 * @remarks
151 *
152 *
153 *******************************************************************************
154 */
ihevcd_bits_flush(bitstrm_t * ps_bitstrm,UWORD32 u4_numbits)155 void ihevcd_bits_flush(bitstrm_t *ps_bitstrm, UWORD32 u4_numbits)
156 {
157 
158     BITS_FLUSH(ps_bitstrm->pu4_buf,
159                ps_bitstrm->u4_bit_ofst,
160                ps_bitstrm->u4_cur_word,
161                ps_bitstrm->u4_nxt_word,
162                u4_numbits);
163 
164     return;
165 }
166 
167 /**
168 *******************************************************************************
169 *
170 * @brief
171 *  Flushes to next byte boundary.Bits consumed increases by  this number
172 *
173 * @par Description:
174 *  Compute number of bits remaining in the current byte  then call
175 * ihevcd_bits_flush() bits with this number
176 *
177 * @param[in] ps_bitstrm
178 *  Pointer to bitstream structure
179 *
180 * @returns  None
181 *
182 * @remarks
183 *
184 *
185 *******************************************************************************
186 */
ihevcd_bits_flush_to_byte_boundary(bitstrm_t * ps_bitstrm)187 void ihevcd_bits_flush_to_byte_boundary(bitstrm_t *ps_bitstrm)
188 {
189     UWORD32 u4_numbits;
190     u4_numbits = (ps_bitstrm->u4_bit_ofst) & 7;
191 
192     u4_numbits = 8 - u4_numbits;
193 
194     BITS_FLUSH(ps_bitstrm->pu4_buf,
195                ps_bitstrm->u4_bit_ofst,
196                ps_bitstrm->u4_cur_word,
197                ps_bitstrm->u4_nxt_word,
198                u4_numbits);
199 
200     return;
201 }
202 
203 /**
204 *******************************************************************************
205 *
206 * @brief
207 *  Seeks by given number of bits in the bitstream from current position
208 *
209 * @par Description:
210 *  Add given number of bits to bitstream offset and update pu4_buf, cur_word and
211 *  nxt_word accordingly
212 *
213 * @param[in] ps_bitstrm
214 *  Pointer to bitstream structure
215 *
216 * @param[in] numbits
217 *  Number of bits to seek
218 *
219 * @returns  None
220 *
221 * @remarks
222 * Assumes emulation prevention has been done before and the buffer does not
223 * contain any emulation prevention bytes
224 *
225 *******************************************************************************
226 */
ihevcd_bits_seek(bitstrm_t * ps_bitstrm,WORD32 numbits)227 void ihevcd_bits_seek(bitstrm_t *ps_bitstrm, WORD32 numbits)
228 {
229     WORD32 val;
230     ASSERT(numbits >= -32);
231     ASSERT(numbits <= 32);
232     /* Check if Seeking backwards*/
233     if(numbits < 0)
234     {
235         UWORD32 abs_numbits = -numbits;
236         if(ps_bitstrm->u4_bit_ofst >= abs_numbits)
237         {
238             /* If the current offset is greater than number of bits to seek back,
239              * then subtract abs_numbits from offset and return.
240              */
241             ps_bitstrm->u4_bit_ofst -= abs_numbits;
242             return;
243         }
244         else
245         {
246             /* If the current offset is lesser than number of bits to seek back,
247              * then subtract abs_numbits from offset and add 32 and move cur_word to nxt_word
248              * and load cur_word appropriately and decrement pu4_buf
249              */
250             ps_bitstrm->u4_bit_ofst -= abs_numbits;
251             ps_bitstrm->u4_bit_ofst += 32;
252             ps_bitstrm->pu4_buf--;
253 
254             val = *(ps_bitstrm->pu4_buf - 2);
255             ps_bitstrm->u4_nxt_word = ps_bitstrm->u4_cur_word;
256             ps_bitstrm->u4_cur_word = ITT_BIG_ENDIAN(val);
257             return;
258         }
259     }
260     else
261     {
262         /* Not supported/tested currently */
263         ASSERT(1);
264         BITS_FLUSH(ps_bitstrm->pu4_buf,
265                    ps_bitstrm->u4_bit_ofst,
266                    ps_bitstrm->u4_cur_word,
267                    ps_bitstrm->u4_nxt_word,
268                    numbits);
269 
270 
271     }
272     return;
273 }
274 /**
275 *******************************************************************************
276 *
277 * @brief
278 *  Snoops for next numbits number of bits from the bitstream this does not
279 * update the bitstream offset and does not  consume the bits
280 *
281 * @par Description:
282 *  Extract required number of bits from cur_word & nxt_word  return these
283 * bits
284 *
285 * @param[in] ps_bitstrm
286 *  Pointer to bitstream structure
287 *
288 * @param[in] u4_numbits
289 *  Number of bits
290 *
291 * @returns  Next u4_numbits number of bits
292 *
293 * @remarks
294 *
295 *
296 *******************************************************************************
297 */
ihevcd_bits_nxt(bitstrm_t * ps_bitstrm,UWORD32 u4_numbits)298 UWORD32 ihevcd_bits_nxt(bitstrm_t *ps_bitstrm, UWORD32 u4_numbits)
299 {
300     UWORD32 u4_bits_read;
301 
302     BITS_NXT(u4_bits_read,
303              ps_bitstrm->pu4_buf,
304              ps_bitstrm->u4_bit_ofst,
305              ps_bitstrm->u4_cur_word,
306              ps_bitstrm->u4_nxt_word,
307              u4_numbits);
308     return u4_bits_read;
309 }
310 /**
311 *******************************************************************************
312 *
313 * @brief
314 *  Snoops for next 32 bits from the bitstream  this does not update the
315 * bitstream offset and does not  consume the bits
316 *
317 * @par Description:
318 *  Extract required number of bits from cur_word & nxt_word  return these
319 * bits
320 *
321 * @param[in] ps_bitstrm
322 *  Pointer to bitstream structure
323 *
324 * @param[in] u4_numbits
325 *  Number of bits
326 *
327 * @returns  Next 32 bits
328 *
329 * @remarks
330 *
331 *
332 *******************************************************************************
333 */
ihevcd_bits_nxt32(bitstrm_t * ps_bitstrm,UWORD32 u4_numbits)334 UWORD32 ihevcd_bits_nxt32(bitstrm_t *ps_bitstrm, UWORD32 u4_numbits)
335 {
336     UWORD32 u4_bits_read;
337     UNUSED(u4_numbits);
338     BITS_NXT32(u4_bits_read,
339                ps_bitstrm->pu4_buf,
340                ps_bitstrm->u4_bit_ofst,
341                ps_bitstrm->u4_cur_word,
342                ps_bitstrm->u4_nxt_word);
343     return u4_bits_read;
344 }
345 
346 /**
347 *******************************************************************************
348 *
349 * @brief
350 *  Reads next numbits number of bits from the bitstream  this updates the
351 * bitstream offset and consumes the bits
352 *
353 * @par Description:
354 *  Extract required number of bits from cur_word & nxt_word  return these
355 * bits
356 *
357 * @param[in] ps_bitstrm
358 *  Pointer to bitstream structure
359 *
360 * @param[in] u4_numbits
361 *  Number of bits
362 *
363 * @returns  Bits read
364 *
365 * @remarks
366 *
367 *
368 *******************************************************************************
369 */
ihevcd_bits_get(bitstrm_t * ps_bitstrm,UWORD32 u4_numbits)370 UWORD32 ihevcd_bits_get(bitstrm_t *ps_bitstrm, UWORD32 u4_numbits)
371 {
372     UWORD32 u4_bits_read;
373 
374     BITS_GET(u4_bits_read,
375              ps_bitstrm->pu4_buf,
376              ps_bitstrm->u4_bit_ofst,
377              ps_bitstrm->u4_cur_word,
378              ps_bitstrm->u4_nxt_word,
379              u4_numbits);
380     return u4_bits_read;
381 
382 }
383 
384 /**
385 *******************************************************************************
386 *
387 * @brief
388 *  Returns the number of bits remaining in the bitstream
389 *
390 * @par Description:
391 *  Compute number of bits remaining based on current pointer and buffer base
392 * and current offset. Since 8 bytes are  read at the start into cur_word and
393 * nxt_word and are not  consumed, 8 has to be subtracted
394 *
395 * @param[in] ps_bitstrm
396 *  Pointer to bitstream structure
397 *
398 * @returns  Total number of bits remaining
399 *
400 * @remarks
401 *
402 *
403 *******************************************************************************
404 */
ihevcd_bits_num_bits_remaining(bitstrm_t * ps_bitstrm)405 UWORD32  ihevcd_bits_num_bits_remaining(bitstrm_t *ps_bitstrm)
406 {
407     UWORD32 u4_bits_consumed;
408     UWORD32 u4_size_in_bits;
409 
410     /* 8 bytes are read in cur_word and nxt_word at the start. Hence */
411     /* subtract 8 bytes */
412     u4_bits_consumed = (UWORD32)(((UWORD8 *)ps_bitstrm->pu4_buf -
413                                   (UWORD8 *)ps_bitstrm->pu1_buf_base - 8) <<
414                                  3) + ps_bitstrm->u4_bit_ofst;
415 
416     u4_size_in_bits = (UWORD32)(ps_bitstrm->pu1_buf_max -
417                     ps_bitstrm->pu1_buf_base);
418     return (u4_size_in_bits - u4_bits_consumed);
419 }
420 
421 /**
422 *******************************************************************************
423 *
424 * @brief
425 *  Returns the number of bits consumed in the bitstream
426 *
427 * @par Description:
428 *  Compute number of bits consumed based on current pointer  and buffer base
429 * and current offset. Since 8 bytes are  read at the start into cur_word and
430 * nxt_word and are not  consumed, 8 has to be subtracted
431 *
432 * @param[in] ps_bitstrm
433 *  Pointer to bitstream structure
434 *
435 * @returns  Total number of bits bits consumed
436 *
437 * @remarks
438 *
439 *
440 *******************************************************************************
441 */
ihevcd_bits_num_bits_consumed(bitstrm_t * ps_bitstrm)442 UWORD32  ihevcd_bits_num_bits_consumed(bitstrm_t *ps_bitstrm)
443 {
444     UWORD32 u4_bits_consumed;
445     /* 8 bytes are read in cur_word and nxt_word at the start. Hence */
446     /* subtract 8 bytes */
447 
448     u4_bits_consumed = (UWORD32)(((UWORD8 *)ps_bitstrm->pu4_buf -
449                                   (UWORD8 *)ps_bitstrm->pu1_buf_base - 8) <<
450                                  3) + ps_bitstrm->u4_bit_ofst;
451     return u4_bits_consumed;
452 }
453 
454 /**
455 *******************************************************************************
456 *
457 * @brief
458 *  Reads unsigned integer 0-th order exp-golomb-coded syntax element from
459 * the bitstream  Section: 9.2
460 *
461 * @par Description:
462 *  Extract required number of bits from cur_word & nxt_word  return these
463 * bits
464 *
465 * @param[in] ps_bitstrm
466 *  Pointer to bitstream structure
467 *
468 * @returns  UEV decoded syntax element
469 *
470 * @remarks
471 *
472 *
473 *******************************************************************************
474 */
ihevcd_uev(bitstrm_t * ps_bitstrm)475 UWORD32 ihevcd_uev(bitstrm_t *ps_bitstrm)
476 {
477     UWORD32 u4_bits_read;
478     UWORD32 u4_clz;
479 
480 
481     /***************************************************************/
482     /* Find leading zeros in next 32 bits                          */
483     /***************************************************************/
484     BITS_NXT32(u4_bits_read,
485                ps_bitstrm->pu4_buf,
486                ps_bitstrm->u4_bit_ofst,
487                ps_bitstrm->u4_cur_word,
488                ps_bitstrm->u4_nxt_word);
489 
490 
491     u4_clz = CLZ(u4_bits_read);
492 
493     BITS_FLUSH(ps_bitstrm->pu4_buf,
494                ps_bitstrm->u4_bit_ofst,
495                ps_bitstrm->u4_cur_word,
496                ps_bitstrm->u4_nxt_word,
497                (u4_clz + 1));
498 
499     u4_bits_read = 0;
500     if(u4_clz)
501     {
502         BITS_GET(u4_bits_read,
503                  ps_bitstrm->pu4_buf,
504                  ps_bitstrm->u4_bit_ofst,
505                  ps_bitstrm->u4_cur_word,
506                  ps_bitstrm->u4_nxt_word,
507                  u4_clz);
508     }
509     return ((1 << u4_clz) + u4_bits_read - 1);
510 
511 }
512 
513 /**
514 *******************************************************************************
515 *
516 * @brief
517 *  Reads signed integer 0-th order exp-golomb-coded syntax  element from the
518 * bitstream. Function similar to get_uev  Section: 9.2.1
519 *
520 * @par Description:
521 *  Extract required number of bits from cur_word & nxt_word  return these
522 * bits
523 *
524 * @param[in] ps_bitstrm
525 *  Pointer to bitstream structure
526 *
527 * @returns  UEV decoded syntax element
528 *
529 * @remarks
530 *
531 *
532 *******************************************************************************
533 */
ihevcd_sev(bitstrm_t * ps_bitstrm)534 WORD32 ihevcd_sev(bitstrm_t *ps_bitstrm)
535 {
536     UWORD32 u4_bits_read;
537     UWORD32 u4_clz;
538     UWORD32 u4_abs_val;
539 
540 
541     /***************************************************************/
542     /* Find leading zeros in next 32 bits                          */
543     /***************************************************************/
544     BITS_NXT32(u4_bits_read,
545                ps_bitstrm->pu4_buf,
546                ps_bitstrm->u4_bit_ofst,
547                ps_bitstrm->u4_cur_word,
548                ps_bitstrm->u4_nxt_word);
549 
550 
551     u4_clz = CLZ(u4_bits_read);
552 
553     BITS_FLUSH(ps_bitstrm->pu4_buf,
554                ps_bitstrm->u4_bit_ofst,
555                ps_bitstrm->u4_cur_word,
556                ps_bitstrm->u4_nxt_word,
557                (u4_clz + 1));
558 
559     u4_bits_read = 0;
560     if(u4_clz)
561     {
562         BITS_GET(u4_bits_read,
563                  ps_bitstrm->pu4_buf,
564                  ps_bitstrm->u4_bit_ofst,
565                  ps_bitstrm->u4_cur_word,
566                  ps_bitstrm->u4_nxt_word,
567                  u4_clz);
568     }
569     u4_abs_val = ((1 << u4_clz) + u4_bits_read) >> 1;
570     if(u4_bits_read & 0x1)
571         return (-(WORD32)u4_abs_val);
572     else
573         return (u4_abs_val);
574 }
575 
576 
577 
578 
579 
580 
581