1 | /* |
2 | Copyright (c) 2012, Broadcom Europe Ltd |
3 | All rights reserved. |
4 | |
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted provided that the following conditions are met: |
7 | * Redistributions of source code must retain the above copyright |
8 | notice, this list of conditions and the following disclaimer. |
9 | * Redistributions in binary form must reproduce the above copyright |
10 | notice, this list of conditions and the following disclaimer in the |
11 | documentation and/or other materials provided with the distribution. |
12 | * Neither the name of the copyright holder nor the |
13 | names of its contributors may be used to endorse or promote products |
14 | derived from this software without specific prior written permission. |
15 | |
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY |
20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ |
27 | |
28 | #ifndef VC_CONTAINERS_BITS_H |
29 | #define VC_CONTAINERS_BITS_H |
30 | |
31 | #include "containers/containers.h" |
32 | |
33 | /** Bit stream structure |
34 | * Value are read from the buffer, taking bits from MSB to LSB in sequential |
35 | * bytes until the number of bit and the number of bytes runs out. */ |
36 | typedef struct vc_container_bits_tag |
37 | { |
38 | const uint8_t *buffer; /**< Buffer from which to take bits */ |
39 | uint32_t bytes; /**< Number of bytes available from buffer */ |
40 | uint32_t bits; /**< Number of bits available at current pointer */ |
41 | } VC_CONTAINER_BITS_T; |
42 | |
43 | /** Initialise a bit stream object. |
44 | * |
45 | * \pre bit_stream is not NULL. |
46 | * |
47 | * \param bit_stream The bit stream object to initialise. |
48 | * \param buffer Pointer to the start of the byte buffer. |
49 | * \param available Number of bytes in the bit stream. |
50 | */ |
51 | void vc_container_bits_init(VC_CONTAINER_BITS_T *bit_stream, const uint8_t *buffer, uint32_t available); |
52 | |
53 | /** Invalidates the bit stream. |
54 | * Also returns zero, because it allows callers that need to invalidate and |
55 | * immediately return zero to do so in a single statement. |
56 | * |
57 | * \pre bit_stream is not NULL. |
58 | * |
59 | * \param bit_stream The bit stream object. |
60 | * \return Zero, always. |
61 | */ |
62 | uint32_t vc_container_bits_invalidate( VC_CONTAINER_BITS_T *bit_stream ); |
63 | |
64 | /** Returns true if the bit stream is currently valid. |
65 | * The stream becomes invalid when a read or skip operation goe beyond the end |
66 | * of the stream. |
67 | * |
68 | * \pre bit_stream is not NULL. |
69 | * |
70 | * \param bit_stream The bit stream object. |
71 | * \return True if the stream is valid, false if it is invalid. |
72 | */ |
73 | bool vc_container_bits_valid(VC_CONTAINER_BITS_T *bit_stream); |
74 | |
75 | /** Reset a valid bit stream object to appear empty. |
76 | * Once a stream has become invalid, reset has no effect. |
77 | * |
78 | * \pre bit_stream is not NULL. |
79 | * |
80 | * \param bit_stream The bit stream object. |
81 | */ |
82 | void vc_container_bits_reset(VC_CONTAINER_BITS_T *bit_stream); |
83 | |
84 | /** Return the current byte pointer for the bit stream. |
85 | * |
86 | * \pre bit_stream is not NULL. |
87 | * \pre The stream is on a byte boundary. |
88 | * |
89 | * \param bit_stream The bit stream object. |
90 | * \return The current byte pointer, or NULL if the stream is invalid. |
91 | */ |
92 | const uint8_t *vc_container_bits_current_pointer(const VC_CONTAINER_BITS_T *bit_stream); |
93 | |
94 | /** Copy one bit stream to another. |
95 | * If the source stream is invalid, the destination one will become so as well. |
96 | * |
97 | * \pre Neither bit stream is NULL. |
98 | * |
99 | * \param dst The destination bit stream object. |
100 | * \param src The source bit stream object. |
101 | */ |
102 | void vc_container_bits_copy_stream(VC_CONTAINER_BITS_T *dst, const VC_CONTAINER_BITS_T *src); |
103 | |
104 | /** Return the number of bits left to take from the stream. |
105 | * If the stream is invalid, zero is returned. |
106 | * |
107 | * \pre bit_stream is not NULL. |
108 | * |
109 | * \param bit_stream The bit stream object. |
110 | * \return The number of bits left to take. |
111 | */ |
112 | uint32_t vc_container_bits_available(const VC_CONTAINER_BITS_T *bit_stream); |
113 | |
114 | /** Return the number of bytes left to take from the stream. |
115 | * If the stream is invalid, zero is returned. |
116 | * |
117 | * \pre bit_stream is not NULL. |
118 | * |
119 | * \param bit_stream The bit stream object. |
120 | * \return The number of bytes left to take. |
121 | */ |
122 | uint32_t vc_container_bits_bytes_available(const VC_CONTAINER_BITS_T *bit_stream); |
123 | |
124 | /** Skip past a number of bits in the stream. |
125 | * If bits_to_skip is greater than the number of bits available in the stream, |
126 | * the stream becomes invalid. |
127 | * If the stream is already invalid, this has no effect. |
128 | * |
129 | * \pre bit_stream is not NULL. |
130 | * |
131 | * \param bit_stream The bit stream object. |
132 | * \param bits_to_skip The number of bits to skip. |
133 | */ |
134 | void vc_container_bits_skip(VC_CONTAINER_BITS_T *bit_stream, uint32_t bits_to_skip); |
135 | |
136 | /** Skip past a number of bytes in the stream. |
137 | * If bytes_to_skip is greater than the number of bytes available in the stream, |
138 | * the stream becomes invalid. |
139 | * If the stream is already invalid, this has no effect. |
140 | * |
141 | * \pre bit_stream is not NULL. |
142 | * \pre The stream is on a byte boundary. |
143 | * |
144 | * \param bit_stream The bit stream object. |
145 | * \param bytes_to_skip The number of bytes to skip. |
146 | */ |
147 | void vc_container_bits_skip_bytes(VC_CONTAINER_BITS_T *bit_stream, uint32_t bytes_to_skip); |
148 | |
149 | /** Reduce the length of the bit stream by a number of bytes. |
150 | * This reduces the number of bits/bytes available without changing the current |
151 | * position in the stream. If bytes_to_reduce is greater than the number of |
152 | * bytes available in the stream, the stream becomes invalid. |
153 | * If the stream is already invalid, this has no effect. |
154 | * |
155 | * \pre bit_stream is not NULL. |
156 | * |
157 | * \param bit_stream The bit stream object. |
158 | * \param bytes_to_reduce The number of bytes by which to reduce the stream. |
159 | */ |
160 | void vc_container_bits_reduce_bytes(VC_CONTAINER_BITS_T *bit_stream, uint32_t bytes_to_reduce); |
161 | |
162 | /** Copies a number of bytes from the stream to a byte buffer. |
163 | * If the stream is or becomes invalid, no data is copied. |
164 | * |
165 | * \pre bit_stream is not NULL. |
166 | * \pre The stream is on a byte boundary. |
167 | * |
168 | * \param bit_stream The bit stream object. |
169 | * \param bytes_to_copy The number of bytes to copy. |
170 | * \param dst The byte buffer destination. |
171 | */ |
172 | void vc_container_bits_copy_bytes(VC_CONTAINER_BITS_T *bit_stream, uint32_t bytes_to_copy, uint8_t *dst); |
173 | |
174 | /** Returns the next value_bits from the stream. The last bit will be the least |
175 | * significant bit in the returned value. |
176 | * If value_bits is greater than the number of bits available in the stream, |
177 | * the stream becomes invalid. |
178 | * If the stream is invalid, or becomes invalid while reading the value, zero |
179 | * is returned. |
180 | * |
181 | * \pre bit_stream is not NULL. |
182 | * \pre value_bits is not larger than 32. |
183 | * |
184 | * \param bit_stream The bit stream object. |
185 | * \param value_bits The number of bits to retrieve. |
186 | * \return The value read from the stream, or zero if the stream is invalid. |
187 | */ |
188 | uint32_t vc_container_bits_read_u32(VC_CONTAINER_BITS_T *bit_stream, uint32_t value_bits); |
189 | |
190 | /** Skips the next Exp-Golomb value in the stream. |
191 | * See section 9.1 of ITU-T REC H.264 201003 for details. |
192 | * If there are not enough bits in the stream to complete an Exp-Golomb value, |
193 | * the stream becomes invalid. |
194 | * If the stream is already invalid, this has no effect. |
195 | * |
196 | * \pre bit_stream is not NULL. |
197 | * |
198 | * \param bit_stream The bit stream object. |
199 | */ |
200 | void vc_container_bits_skip_exp_golomb(VC_CONTAINER_BITS_T *bit_stream); |
201 | |
202 | /** Returns the next unsigned Exp-Golomb value from the stream. |
203 | * See section 9.1 of ITU-T REC H.264 201003 for details. |
204 | * If there are not enough bits in the stream to complete an Exp-Golomb value, |
205 | * the stream becomes invalid. |
206 | * If the next unsigned Exp-Golomb value in the stream is larger than 32 bits, |
207 | * or the stream is or becomes invalid, zero is returned. |
208 | * |
209 | * \pre bit_stream is not NULL. |
210 | * |
211 | * \param bit_stream The bit stream object. |
212 | * \return The next unsigned value from the stream, or zero on error. |
213 | */ |
214 | uint32_t vc_container_bits_read_u32_exp_golomb(VC_CONTAINER_BITS_T *bit_stream); |
215 | |
216 | /** Returns the next signed Exp-Golomb value from the stream. |
217 | * See section 9.1.1 of ITU-T REC H.264 201003 for details. |
218 | * If there are not enough bits in the stream to complete an Exp-Golomb value, |
219 | * the stream becomes invalid. |
220 | * If the next signed Exp-Golomb value in the stream is larger than 32 bits, |
221 | * or the stream is or becomes invalid, zero is returned. |
222 | * |
223 | * \pre bit_stream is not NULL. |
224 | * |
225 | * \param bit_stream The bit stream object. |
226 | * \return The next signed value from the stream, or zero on error. |
227 | */ |
228 | int32_t vc_container_bits_read_s32_exp_golomb(VC_CONTAINER_BITS_T *bit_stream); |
229 | |
230 | /****************************************************************************** |
231 | * Macros reduce function name length and enable logging of some operations * |
232 | ******************************************************************************/ |
233 | #define BITS_INIT(ctx, bits, buffer, available) (VC_CONTAINER_PARAM_UNUSED(ctx), vc_container_bits_init(bits, buffer, available)) |
234 | #define BITS_INVALIDATE(ctx, bits) (VC_CONTAINER_PARAM_UNUSED(ctx), vc_container_bits_invalidate(bits)) |
235 | #define BITS_VALID(ctx, bits) (VC_CONTAINER_PARAM_UNUSED(ctx), vc_container_bits_valid(bits)) |
236 | #define BITS_RESET(ctx, bits) (VC_CONTAINER_PARAM_UNUSED(ctx), vc_container_bits_reset(bits)) |
237 | #define BITS_AVAILABLE(ctx, bits) (VC_CONTAINER_PARAM_UNUSED(ctx), vc_container_bits_available(bits)) |
238 | #define BITS_BYTES_AVAILABLE(ctx, bits) (VC_CONTAINER_PARAM_UNUSED(ctx), vc_container_bits_bytes_available(bits)) |
239 | #define BITS_CURRENT_POINTER(ctx, bits) (VC_CONTAINER_PARAM_UNUSED(ctx), vc_container_bits_current_pointer(bits)) |
240 | #define BITS_COPY_STREAM(ctx, dst, src) (VC_CONTAINER_PARAM_UNUSED(ctx), vc_container_bits_copy_stream(dst, src)) |
241 | |
242 | #ifdef ENABLE_CONTAINERS_LOG_FORMAT |
243 | |
244 | typedef enum { |
245 | VC_CONTAINER_BITS_LOG_SKIP, |
246 | VC_CONTAINER_BITS_LOG_SKIP_BYTES, |
247 | VC_CONTAINER_BITS_LOG_U8, |
248 | VC_CONTAINER_BITS_LOG_U16, |
249 | VC_CONTAINER_BITS_LOG_U32, |
250 | VC_CONTAINER_BITS_LOG_COPY_BYTES, |
251 | VC_CONTAINER_BITS_LOG_REDUCE_BYTES, |
252 | VC_CONTAINER_BITS_LOG_EG_SKIP, |
253 | VC_CONTAINER_BITS_LOG_EG_U32, |
254 | VC_CONTAINER_BITS_LOG_EG_S32, |
255 | } VC_CONTAINER_BITS_LOG_OP_T; |
256 | |
257 | /** Logs an operation with void return. |
258 | * |
259 | * \pre None of p_ctx, txt or bit_stream are NULL. |
260 | * |
261 | * \param p_ctx Container context. |
262 | * \param indent Indent level. |
263 | * \param txt Description of what is being read. |
264 | * \param bit_stream The bit stream object. |
265 | * \param op The operation just performed. |
266 | * \param length The length of the operation. |
267 | */ |
268 | void vc_container_bits_log(VC_CONTAINER_T *p_ctx, uint32_t indent, const char *txt, VC_CONTAINER_BITS_T *bit_stream, VC_CONTAINER_BITS_LOG_OP_T op, uint32_t length); |
269 | |
270 | /** Logs an operation with unsigned 32-bit integer return. |
271 | * |
272 | * \pre None of p_ctx, txt or bit_stream are NULL. |
273 | * |
274 | * \param p_ctx Container context. |
275 | * \param indent Indent level. |
276 | * \param txt Description of what is being read. |
277 | * \param bit_stream The bit stream object. |
278 | * \param op The operation just performed. |
279 | * \param length The length of the operation. |
280 | * \param value The value returned by the operation. |
281 | * \return The unsigned 32-bit integer value passed in. |
282 | */ |
283 | uint32_t vc_container_bits_log_u32(VC_CONTAINER_T *p_ctx, uint32_t indent, const char *txt, VC_CONTAINER_BITS_T *bit_stream, VC_CONTAINER_BITS_LOG_OP_T op, uint32_t length, uint32_t value); |
284 | |
285 | /** Logs an operation with signed 32-bit integer return. |
286 | * |
287 | * \pre None of p_ctx, txt or bit_stream are NULL. |
288 | * |
289 | * \param p_ctx Container context. |
290 | * \param indent Indent level. |
291 | * \param txt Description of what is being read. |
292 | * \param bit_stream The bit stream object. |
293 | * \param op The operation just performed. |
294 | * \param length The length of the operation. |
295 | * \param value The value returned by the operation. |
296 | * \return The signed 32-bit integer value passed in. |
297 | */ |
298 | int32_t vc_container_bits_log_s32(VC_CONTAINER_T *p_ctx, uint32_t indent, const char *txt, VC_CONTAINER_BITS_T *bit_stream, VC_CONTAINER_BITS_LOG_OP_T op, uint32_t length, int32_t value); |
299 | |
300 | #ifndef BITS_LOG_INDENT |
301 | # ifndef CONTAINER_HELPER_LOG_INDENT |
302 | # define BITS_LOG_INDENT(ctx) 0 |
303 | # else |
304 | # define BITS_LOG_INDENT(ctx) ((ctx)->priv->io->module ? CONTAINER_HELPER_LOG_INDENT(a) : 0) |
305 | # endif |
306 | #endif |
307 | |
308 | #define BITS_SKIP(ctx, bits, length, txt) (vc_container_bits_skip(bits, length), vc_container_bits_log(ctx, BITS_LOG_INDENT(ctx), txt, bits, VC_CONTAINER_BITS_LOG_SKIP, length)) |
309 | #define BITS_SKIP_BYTES(ctx, bits, length, txt) (vc_container_bits_skip_bytes(bits, length), vc_container_bits_log(ctx, BITS_LOG_INDENT(ctx), txt, bits, VC_CONTAINER_BITS_LOG_SKIP_BYTES, length)) |
310 | |
311 | #define BITS_READ_U8(ctx, bits, length, txt) (uint8_t)vc_container_bits_log_u32(ctx, BITS_LOG_INDENT(ctx), txt, bits, VC_CONTAINER_BITS_LOG_U8, length, vc_container_bits_read_u32(bits, length)) |
312 | #define BITS_READ_U16(ctx, bits, length, txt) (uint16_t)vc_container_bits_log_u32(ctx, BITS_LOG_INDENT(ctx), txt, bits, VC_CONTAINER_BITS_LOG_U16, length, vc_container_bits_read_u32(bits, length)) |
313 | #define BITS_READ_U32(ctx, bits, length, txt) vc_container_bits_log_u32(ctx, BITS_LOG_INDENT(ctx), txt, bits, VC_CONTAINER_BITS_LOG_U32, length, vc_container_bits_read_u32(bits, length)) |
314 | |
315 | #define BITS_COPY_BYTES(ctx, bits, length, dst, txt) (vc_container_bits_copy_bytes(bits, length, dst), vc_container_bits_log(ctx, BITS_LOG_INDENT(ctx), txt, bits, VC_CONTAINER_BITS_LOG_COPY_BYTES, length)) |
316 | |
317 | #define BITS_REDUCE_BYTES(ctx, bits, length, txt) (vc_container_bits_reduce_bytes(bits, length), vc_container_bits_log(ctx, BITS_LOG_INDENT(ctx), txt, bits, VC_CONTAINER_BITS_LOG_REDUCE_BYTES, length)) |
318 | |
319 | #define BITS_SKIP_EXP(ctx, bits, txt) (vc_container_bits_skip_exp_golomb(bits), vc_container_bits_log(ctx, BITS_LOG_INDENT(ctx), txt, bits, VC_CONTAINER_BITS_LOG_EG_SKIP, 0)) |
320 | |
321 | #define BITS_READ_S32_EXP(ctx, bits, txt) vc_container_bits_log_s32(ctx, BITS_LOG_INDENT(ctx), txt, bits, VC_CONTAINER_BITS_LOG_EG_S32, 0, vc_container_bits_read_s32_exp_golomb(bits)) |
322 | #define BITS_READ_U32_EXP(ctx, bits, txt) vc_container_bits_log_u32(ctx, BITS_LOG_INDENT(ctx), txt, bits, VC_CONTAINER_BITS_LOG_EG_U32, 0, vc_container_bits_read_u32_exp_golomb(bits)) |
323 | |
324 | #else /* ENABLE_CONTAINERS_LOG_FORMAT */ |
325 | |
326 | #define BITS_SKIP(ctx, bits, length, txt) (VC_CONTAINER_PARAM_UNUSED(ctx), VC_CONTAINER_PARAM_UNUSED(txt), vc_container_bits_skip(bits, length)) |
327 | #define BITS_SKIP_BYTES(ctx, bits, length, txt) (VC_CONTAINER_PARAM_UNUSED(ctx), VC_CONTAINER_PARAM_UNUSED(txt), vc_container_bits_skip_bytes(bits, length)) |
328 | |
329 | #define BITS_READ_U8(ctx, bits, length, txt) (uint8_t)(VC_CONTAINER_PARAM_UNUSED(ctx), VC_CONTAINER_PARAM_UNUSED(txt), vc_container_bits_read_u32(bits, length)) |
330 | #define BITS_READ_U16(ctx, bits, length, txt) (uint16_t)(VC_CONTAINER_PARAM_UNUSED(ctx), VC_CONTAINER_PARAM_UNUSED(txt), vc_container_bits_read_u32(bits, length)) |
331 | #define BITS_READ_U32(ctx, bits, length, txt) (VC_CONTAINER_PARAM_UNUSED(ctx), VC_CONTAINER_PARAM_UNUSED(txt), vc_container_bits_read_u32(bits, length)) |
332 | |
333 | #define BITS_COPY_BYTES(ctx, bits, length, dst, txt) (VC_CONTAINER_PARAM_UNUSED(ctx), VC_CONTAINER_PARAM_UNUSED(txt), vc_container_bits_copy_bytes(bits, length, dst)) |
334 | |
335 | #define BITS_REDUCE_BYTES(ctx, bits, length, txt) (VC_CONTAINER_PARAM_UNUSED(ctx), VC_CONTAINER_PARAM_UNUSED(txt), vc_container_bits_reduce_bytes(bits, length)) |
336 | |
337 | #define BITS_SKIP_EXP(ctx, bits, txt) (VC_CONTAINER_PARAM_UNUSED(ctx), VC_CONTAINER_PARAM_UNUSED(txt), vc_container_bits_skip_exp_golomb(bits)) |
338 | |
339 | #define BITS_READ_S32_EXP(ctx, bits, txt) (VC_CONTAINER_PARAM_UNUSED(ctx), VC_CONTAINER_PARAM_UNUSED(txt), vc_container_bits_read_s32_exp_golomb(bits)) |
340 | #define BITS_READ_U32_EXP(ctx, bits, txt) (VC_CONTAINER_PARAM_UNUSED(ctx), VC_CONTAINER_PARAM_UNUSED(txt), vc_container_bits_read_u32_exp_golomb(bits)) |
341 | |
342 | #endif /* ENABLE_CONTAINERS_LOG_FORMAT */ |
343 | |
344 | #endif /* VC_CONTAINERS_BITS_H */ |
345 | |