| 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 | |