put_bits.h (11221B)
1 /* 2 * copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at> 3 * 4 * This file is part of FFmpeg. 5 * 6 * FFmpeg is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * FFmpeg is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with FFmpeg; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21 /** 22 * @file 23 * bitstream writer API 24 */ 25 26 #ifndef AVCODEC_PUT_BITS_H 27 #define AVCODEC_PUT_BITS_H 28 29 #include <stdint.h> 30 #include <stddef.h> 31 32 #include "config.h" 33 #include "libavutil/intreadwrite.h" 34 #include "libavutil/avassert.h" 35 #include "libavutil/common.h" 36 37 #if ARCH_X86_64 38 // TODO: Benchmark and optionally enable on other 64-bit architectures. 39 typedef uint64_t BitBuf; 40 #define AV_WBBUF AV_WB64 41 #define AV_WLBUF AV_WL64 42 #else 43 typedef uint32_t BitBuf; 44 #define AV_WBBUF AV_WB32 45 #define AV_WLBUF AV_WL32 46 #endif 47 48 static const int BUF_BITS = 8 * sizeof(BitBuf); 49 50 typedef struct PutBitContext { 51 BitBuf bit_buf; 52 int bit_left; 53 uint8_t *buf, *buf_ptr, *buf_end; 54 } PutBitContext; 55 56 /** 57 * Initialize the PutBitContext s. 58 * 59 * @param buffer the buffer where to put bits 60 * @param buffer_size the size in bytes of buffer 61 */ 62 static inline void init_put_bits(PutBitContext *s, uint8_t *buffer, 63 int buffer_size) 64 { 65 if (buffer_size < 0) { 66 buffer_size = 0; 67 buffer = NULL; 68 } 69 70 s->buf = buffer; 71 s->buf_end = s->buf + buffer_size; 72 s->buf_ptr = s->buf; 73 s->bit_left = BUF_BITS; 74 s->bit_buf = 0; 75 } 76 77 /** 78 * @return the total number of bits written to the bitstream. 79 */ 80 static inline int put_bits_count(PutBitContext *s) 81 { 82 return (s->buf_ptr - s->buf) * 8 + BUF_BITS - s->bit_left; 83 } 84 85 /** 86 * @return the number of bytes output so far; may only be called 87 * when the PutBitContext is freshly initialized or flushed. 88 */ 89 static inline int put_bytes_output(const PutBitContext *s) 90 { 91 av_assert2(s->bit_left == BUF_BITS); 92 return s->buf_ptr - s->buf; 93 } 94 95 /** 96 * @param round_up When set, the number of bits written so far will be 97 * rounded up to the next byte. 98 * @return the number of bytes output so far. 99 */ 100 static inline int put_bytes_count(const PutBitContext *s, int round_up) 101 { 102 return s->buf_ptr - s->buf + ((BUF_BITS - s->bit_left + (round_up ? 7 : 0)) >> 3); 103 } 104 105 /** 106 * Rebase the bit writer onto a reallocated buffer. 107 * 108 * @param buffer the buffer where to put bits 109 * @param buffer_size the size in bytes of buffer, 110 * must be large enough to hold everything written so far 111 */ 112 static inline void rebase_put_bits(PutBitContext *s, uint8_t *buffer, 113 int buffer_size) 114 { 115 av_assert0(8*buffer_size >= put_bits_count(s)); 116 117 s->buf_end = buffer + buffer_size; 118 s->buf_ptr = buffer + (s->buf_ptr - s->buf); 119 s->buf = buffer; 120 } 121 122 /** 123 * @return the number of bits available in the bitstream. 124 */ 125 static inline int put_bits_left(PutBitContext* s) 126 { 127 return (s->buf_end - s->buf_ptr) * 8 - BUF_BITS + s->bit_left; 128 } 129 130 /** 131 * @param round_up When set, the number of bits written will be 132 * rounded up to the next byte. 133 * @return the number of bytes left. 134 */ 135 static inline int put_bytes_left(const PutBitContext *s, int round_up) 136 { 137 return s->buf_end - s->buf_ptr - ((BUF_BITS - s->bit_left + (round_up ? 7 : 0)) >> 3); 138 } 139 140 /** 141 * Pad the end of the output stream with zeros. 142 */ 143 static inline void flush_put_bits(PutBitContext *s) 144 { 145 #ifndef BITSTREAM_WRITER_LE 146 if (s->bit_left < BUF_BITS) 147 s->bit_buf <<= s->bit_left; 148 #endif 149 while (s->bit_left < BUF_BITS) { 150 av_assert0(s->buf_ptr < s->buf_end); 151 #ifdef BITSTREAM_WRITER_LE 152 *s->buf_ptr++ = s->bit_buf; 153 s->bit_buf >>= 8; 154 #else 155 *s->buf_ptr++ = s->bit_buf >> (BUF_BITS - 8); 156 s->bit_buf <<= 8; 157 #endif 158 s->bit_left += 8; 159 } 160 s->bit_left = BUF_BITS; 161 s->bit_buf = 0; 162 } 163 164 static inline void flush_put_bits_le(PutBitContext *s) 165 { 166 while (s->bit_left < BUF_BITS) { 167 av_assert0(s->buf_ptr < s->buf_end); 168 *s->buf_ptr++ = s->bit_buf; 169 s->bit_buf >>= 8; 170 s->bit_left += 8; 171 } 172 s->bit_left = BUF_BITS; 173 s->bit_buf = 0; 174 } 175 176 #ifdef BITSTREAM_WRITER_LE 177 #define ff_put_string ff_put_string_unsupported_here 178 #define ff_copy_bits ff_copy_bits_unsupported_here 179 #else 180 181 /** 182 * Put the string string in the bitstream. 183 * 184 * @param terminate_string 0-terminates the written string if value is 1 185 */ 186 void ff_put_string(PutBitContext *pb, const char *string, 187 int terminate_string); 188 189 /** 190 * Copy the content of src to the bitstream. 191 * 192 * @param length the number of bits of src to copy 193 */ 194 void ff_copy_bits(PutBitContext *pb, const uint8_t *src, int length); 195 #endif 196 197 static inline void put_bits_no_assert(PutBitContext *s, int n, BitBuf value) 198 { 199 BitBuf bit_buf; 200 int bit_left; 201 202 bit_buf = s->bit_buf; 203 bit_left = s->bit_left; 204 205 /* XXX: optimize */ 206 #ifdef BITSTREAM_WRITER_LE 207 bit_buf |= value << (BUF_BITS - bit_left); 208 if (n >= bit_left) { 209 if (s->buf_end - s->buf_ptr >= sizeof(BitBuf)) { 210 AV_WLBUF(s->buf_ptr, bit_buf); 211 s->buf_ptr += sizeof(BitBuf); 212 } else { 213 av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n"); 214 av_assert2(0); 215 } 216 bit_buf = value >> bit_left; 217 bit_left += BUF_BITS; 218 } 219 bit_left -= n; 220 #else 221 if (n < bit_left) { 222 bit_buf = (bit_buf << n) | value; 223 bit_left -= n; 224 } else { 225 bit_buf <<= bit_left; 226 bit_buf |= value >> (n - bit_left); 227 if (s->buf_end - s->buf_ptr >= sizeof(BitBuf)) { 228 AV_WBBUF(s->buf_ptr, bit_buf); 229 s->buf_ptr += sizeof(BitBuf); 230 } else { 231 av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n"); 232 av_assert2(0); 233 } 234 bit_left += BUF_BITS - n; 235 bit_buf = value; 236 } 237 #endif 238 239 s->bit_buf = bit_buf; 240 s->bit_left = bit_left; 241 } 242 243 /** 244 * Write up to 31 bits into a bitstream. 245 * Use put_bits32 to write 32 bits. 246 */ 247 static inline void put_bits(PutBitContext *s, int n, BitBuf value) 248 { 249 av_assert2(n <= 31 && value < (1UL << n)); 250 put_bits_no_assert(s, n, value); 251 } 252 253 static inline void put_bits_le(PutBitContext *s, int n, BitBuf value) 254 { 255 BitBuf bit_buf; 256 int bit_left; 257 258 av_assert2(n <= 31 && value < (1UL << n)); 259 260 bit_buf = s->bit_buf; 261 bit_left = s->bit_left; 262 263 bit_buf |= value << (BUF_BITS - bit_left); 264 if (n >= bit_left) { 265 if (s->buf_end - s->buf_ptr >= sizeof(BitBuf)) { 266 AV_WLBUF(s->buf_ptr, bit_buf); 267 s->buf_ptr += sizeof(BitBuf); 268 } else { 269 av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n"); 270 av_assert2(0); 271 } 272 bit_buf = value >> bit_left; 273 bit_left += BUF_BITS; 274 } 275 bit_left -= n; 276 277 s->bit_buf = bit_buf; 278 s->bit_left = bit_left; 279 } 280 281 static inline void put_sbits(PutBitContext *pb, int n, int32_t value) 282 { 283 av_assert2(n >= 0 && n <= 31); 284 285 put_bits(pb, n, av_zero_extend(value, n)); 286 } 287 288 /** 289 * Write exactly 32 bits into a bitstream. 290 */ 291 static void av_unused put_bits32(PutBitContext *s, uint32_t value) 292 { 293 BitBuf bit_buf; 294 int bit_left; 295 296 if (BUF_BITS > 32) { 297 put_bits_no_assert(s, 32, value); 298 return; 299 } 300 301 bit_buf = s->bit_buf; 302 bit_left = s->bit_left; 303 304 #ifdef BITSTREAM_WRITER_LE 305 bit_buf |= (BitBuf)value << (BUF_BITS - bit_left); 306 if (s->buf_end - s->buf_ptr >= sizeof(BitBuf)) { 307 AV_WLBUF(s->buf_ptr, bit_buf); 308 s->buf_ptr += sizeof(BitBuf); 309 } else { 310 av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n"); 311 av_assert2(0); 312 } 313 bit_buf = (uint64_t)value >> bit_left; 314 #else 315 bit_buf = (uint64_t)bit_buf << bit_left; 316 bit_buf |= (BitBuf)value >> (BUF_BITS - bit_left); 317 if (s->buf_end - s->buf_ptr >= sizeof(BitBuf)) { 318 AV_WBBUF(s->buf_ptr, bit_buf); 319 s->buf_ptr += sizeof(BitBuf); 320 } else { 321 av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n"); 322 av_assert2(0); 323 } 324 bit_buf = value; 325 #endif 326 327 s->bit_buf = bit_buf; 328 s->bit_left = bit_left; 329 } 330 331 /** 332 * Write up to 64 bits into a bitstream. 333 */ 334 static inline void put_bits64(PutBitContext *s, int n, uint64_t value) 335 { 336 av_assert2((n == 64) || (n < 64 && value < (UINT64_C(1) << n))); 337 338 if (n < 32) 339 put_bits(s, n, value); 340 else if (n == 32) 341 put_bits32(s, value); 342 else if (n < 64) { 343 uint32_t lo = value & 0xffffffff; 344 uint32_t hi = value >> 32; 345 #ifdef BITSTREAM_WRITER_LE 346 put_bits32(s, lo); 347 put_bits(s, n - 32, hi); 348 #else 349 put_bits(s, n - 32, hi); 350 put_bits32(s, lo); 351 #endif 352 } else { 353 uint32_t lo = value & 0xffffffff; 354 uint32_t hi = value >> 32; 355 #ifdef BITSTREAM_WRITER_LE 356 put_bits32(s, lo); 357 put_bits32(s, hi); 358 #else 359 put_bits32(s, hi); 360 put_bits32(s, lo); 361 #endif 362 363 } 364 } 365 366 static inline void put_sbits63(PutBitContext *pb, int n, int64_t value) 367 { 368 av_assert2(n >= 0 && n < 64); 369 370 put_bits64(pb, n, (uint64_t)(value) & (~(UINT64_MAX << n))); 371 } 372 373 /** 374 * Return the pointer to the byte where the bitstream writer will put 375 * the next bit. 376 */ 377 static inline uint8_t *put_bits_ptr(PutBitContext *s) 378 { 379 return s->buf_ptr; 380 } 381 382 /** 383 * Skip the given number of bytes. 384 * PutBitContext must be flushed & aligned to a byte boundary before calling this. 385 */ 386 static inline void skip_put_bytes(PutBitContext *s, int n) 387 { 388 av_assert2((put_bits_count(s) & 7) == 0); 389 av_assert2(s->bit_left == BUF_BITS); 390 av_assert0(n <= s->buf_end - s->buf_ptr); 391 s->buf_ptr += n; 392 } 393 394 /** 395 * Skip the given number of bits. 396 * Must only be used if the actual values in the bitstream do not matter. 397 * If n is < 0 the behavior is undefined. 398 */ 399 static inline void skip_put_bits(PutBitContext *s, int n) 400 { 401 unsigned bits = BUF_BITS - s->bit_left + n; 402 s->buf_ptr += sizeof(BitBuf) * (bits / BUF_BITS); 403 s->bit_left = BUF_BITS - (bits & (BUF_BITS - 1)); 404 } 405 406 /** 407 * Change the end of the buffer. 408 * 409 * @param size the new size in bytes of the buffer where to put bits 410 */ 411 static inline void set_put_bits_buffer_size(PutBitContext *s, int size) 412 { 413 av_assert0(size <= INT_MAX/8 - BUF_BITS); 414 s->buf_end = s->buf + size; 415 } 416 417 /** 418 * Pad the bitstream with zeros up to the next byte boundary. 419 */ 420 static inline void align_put_bits(PutBitContext *s) 421 { 422 put_bits(s, s->bit_left & 7, 0); 423 } 424 425 #undef AV_WBBUF 426 #undef AV_WLBUF 427 428 #endif /* AVCODEC_PUT_BITS_H */