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#ifndef _IH264D_BITSTRM_H_
22#define _IH264D_BITSTRM_H_
23/*!
24 *************************************************************************
25 * \file ih264d_bitstrm.h
26 *
27 * \brief
28 *  Contains all the declarations of bitstream reading routines
29 *
30 * \date
31 *    20/11/2002
32 *
33 * \author  AI
34 *************************************************************************
35 */
36
37/* Includes */
38#include <stdio.h>
39#include <stdlib.h>
40#include "ih264_typedefs.h"
41#include "ih264_macros.h"
42#include "ih264_platform_macros.h"
43
44#define INT_IN_BYTES        4
45#define INT_IN_BITS         32
46
47/* Based on level 1.2 of baseline profile */
48/* 396[MAX_FS] * 128 * 1.5 [ChromaFormatParameter] / sizeof(UWORD32)
49 i.e  396 * 128 * 1.5 / 4 = 19008 */
50/* Based on level 3 of main profile */
51/* 1620[MAX_FS] * 128 * 1.5 [ChromaFormatParameter] / sizeof(UWORD32)
52 i.e  1620 * 128 * 1.5 / 4= 77760 */
53#define SIZE_OF_BUFFER      77760
54
55/* Structure for the ps_bitstrm */
56typedef struct
57{
58    UWORD32 u4_ofst; /* Offset in the buffer for the current bit */
59    UWORD32 *pu4_buffer; /* Bitstream Buffer  */
60    UWORD32 u4_max_ofst; /* Position of the last bit read in the current buffer */
61    void * pv_codec_handle; /* For Error Handling */
62} dec_bit_stream_t;
63
64/* To read the next bit */
65UWORD8 ih264d_get_bit_h264(dec_bit_stream_t *);
66
67/* To read the next specified number of bits */
68UWORD32 ih264d_get_bits_h264(dec_bit_stream_t *, UWORD32);
69
70/* To see the next specified number of bits */
71UWORD32 ih264d_next_bits_h264(dec_bit_stream_t *, UWORD32);
72
73/* To flush a specified number of bits*/
74WORD32 ih264d_flush_bits_h264(dec_bit_stream_t *, WORD32);
75
76/*!
77 **************************************************************************
78 * \if Function name : MoreRbspData \endif
79 *
80 * \brief
81 *    Determines whether there is more data in RBSP or not.
82 *
83 * \param ps_bitstrm : Pointer to bitstream
84 *
85 * \return
86 *    Returns 1 if there is more data in RBSP before rbsp_trailing_bits().
87 *    Otherwise it returns FALSE.
88 **************************************************************************
89 */
90
91#define MORE_RBSP_DATA(ps_bitstrm) \
92  (ps_bitstrm->u4_ofst < ps_bitstrm->u4_max_ofst)
93#define EXCEED_OFFSET(ps_bitstrm) \
94  (ps_bitstrm->u4_ofst > ps_bitstrm->u4_max_ofst)
95
96void GoToByteBoundary(dec_bit_stream_t * ps_bitstrm);
97UWORD8 ih264d_check_byte_aligned(dec_bit_stream_t * ps_bitstrm);
98
99/*****************************************************************************/
100/* Define a macro for inlining of GETBIT:                                    */
101/*****************************************************************************/
102#define   GETBIT(u4_code, u4_offset, pu4_bitstream)                         \
103{                                                                           \
104    UWORD32 *pu4_buf =  (pu4_bitstream);                                    \
105    UWORD32 u4_word_off = ((u4_offset) >> 5);                               \
106    UWORD32 u4_bit_off = (u4_offset) & 0x1F;                                \
107    u4_code = pu4_buf[u4_word_off] << u4_bit_off;                           \
108    (u4_offset)++;                                                          \
109    u4_code = (u4_code >> 31);                                              \
110}
111
112
113
114/*****************************************************************************/
115/* Define a macro for inlining of GETBITS: u4_no_bits shall not exceed 32    */
116/*****************************************************************************/
117#define     GETBITS(u4_code, u4_offset, pu4_bitstream, u4_no_bits)          \
118{                                                                           \
119    UWORD32 *pu4_buf =  (pu4_bitstream);                                    \
120    UWORD32 u4_word_off = ((u4_offset) >> 5);                               \
121    UWORD32 u4_bit_off = (u4_offset) & 0x1F;                                \
122    u4_code = pu4_buf[u4_word_off++] << u4_bit_off;                         \
123                                                                            \
124    if(u4_bit_off)                                                          \
125        u4_code |= (pu4_buf[u4_word_off] >> (INT_IN_BITS - u4_bit_off));    \
126    u4_code = u4_code >> (INT_IN_BITS - u4_no_bits);                        \
127    (u4_offset) += u4_no_bits;                                              \
128}                                                                           \
129                                                                            \
130
131/*****************************************************************************/
132/* Define a macro for inlining of NEXTBITS                                   */
133/*****************************************************************************/
134#define     NEXTBITS(u4_word, u4_offset, pu4_bitstream, u4_no_bits)         \
135{                                                                           \
136    UWORD32 *pu4_buf =  (pu4_bitstream);                                    \
137    UWORD32 u4_word_off = ((u4_offset) >> 5);                               \
138    UWORD32 u4_bit_off = (u4_offset) & 0x1F;                                \
139    u4_word = pu4_buf[u4_word_off++] << u4_bit_off;                         \
140    if(u4_bit_off)                                                          \
141        u4_word |= (pu4_buf[u4_word_off] >> (INT_IN_BITS - u4_bit_off));    \
142    u4_word = u4_word >> (INT_IN_BITS - u4_no_bits);                        \
143}
144/*****************************************************************************/
145/* Define a macro for inlining of NEXTBITS_32                                */
146/*****************************************************************************/
147#define     NEXTBITS_32(u4_word, u4_offset, pu4_bitstream)                  \
148{                                                                           \
149    UWORD32 *pu4_buf =  (pu4_bitstream);                                    \
150    UWORD32 u4_word_off = ((u4_offset) >> 5);                               \
151    UWORD32 u4_bit_off = (u4_offset) & 0x1F;                                \
152                                                                            \
153    u4_word = pu4_buf[u4_word_off++] << u4_bit_off;                         \
154    if(u4_bit_off)                                                          \
155    u4_word |= (pu4_buf[u4_word_off] >> (INT_IN_BITS - u4_bit_off));        \
156}
157
158
159/*****************************************************************************/
160/* Define a macro for inlining of FIND_ONE_IN_STREAM_32                      */
161/*****************************************************************************/
162#define   FIND_ONE_IN_STREAM_32(u4_ldz, u4_offset, pu4_bitstream)           \
163{                                                                           \
164    UWORD32 u4_word;                                                        \
165    NEXTBITS_32(u4_word, u4_offset, pu4_bitstream);                         \
166    u4_ldz = CLZ(u4_word);                                     \
167    (u4_offset) += (u4_ldz + 1);                                            \
168}
169
170/*****************************************************************************/
171/* Define a macro for inlining of FIND_ONE_IN_STREAM_LEN                     */
172/*****************************************************************************/
173#define   FIND_ONE_IN_STREAM_LEN(u4_ldz, u4_offset, pu4_bitstream, u4_len)  \
174{                                                                           \
175    UWORD32 u4_word;                                                        \
176    NEXTBITS_32(u4_word, u4_offset, pu4_bitstream);                         \
177    u4_ldz = CLZ(u4_word);                                     \
178    if(u4_ldz < u4_len)                                                     \
179    (u4_offset) += (u4_ldz + 1);                                            \
180    else                                                                    \
181    {                                                                       \
182        u4_ldz = u4_len;                                                    \
183        (u4_offset) += u4_ldz;                                              \
184    }                                                                       \
185}
186
187/*****************************************************************************/
188/* Define a macro for inlining of FLUSHBITS                                  */
189/*****************************************************************************/
190#define   FLUSHBITS(u4_offset, u4_no_bits)                                  \
191{                                                                           \
192        (u4_offset) += (u4_no_bits);                                        \
193}
194
195#endif  /* _BITSTREAM_H_ */
196