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. 39typedef uint64_t BitBuf; 40#define AV_WBBUF AV_WB64 41#define AV_WLBUF AV_WL64 42#else 43typedef uint32_t BitBuf; 44#define AV_WBBUF AV_WB32 45#define AV_WLBUF AV_WL32 46#endif 47 48static const int BUF_BITS = 8 * sizeof(BitBuf); 49 50typedef 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 */ 62static 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 */ 80static 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 */ 89static 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 */ 100static 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 */ 112static 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 */ 125static 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 */ 135static 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 */ 143static 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 164static 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 */ 186void 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 */ 194void ff_copy_bits(PutBitContext *pb, const uint8_t *src, int length); 195#endif 196 197static 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 */ 247static 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 253static 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 281static 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_mod_uintp2(value, n)); 286} 287 288/** 289 * Write exactly 32 bits into a bitstream. 290 */ 291static 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 */ 334static 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/** 367 * Return the pointer to the byte where the bitstream writer will put 368 * the next bit. 369 */ 370static inline uint8_t *put_bits_ptr(PutBitContext *s) 371{ 372 return s->buf_ptr; 373} 374 375/** 376 * Skip the given number of bytes. 377 * PutBitContext must be flushed & aligned to a byte boundary before calling this. 378 */ 379static inline void skip_put_bytes(PutBitContext *s, int n) 380{ 381 av_assert2((put_bits_count(s) & 7) == 0); 382 av_assert2(s->bit_left == BUF_BITS); 383 av_assert0(n <= s->buf_end - s->buf_ptr); 384 s->buf_ptr += n; 385} 386 387/** 388 * Skip the given number of bits. 389 * Must only be used if the actual values in the bitstream do not matter. 390 * If n is < 0 the behavior is undefined. 391 */ 392static inline void skip_put_bits(PutBitContext *s, int n) 393{ 394 unsigned bits = BUF_BITS - s->bit_left + n; 395 s->buf_ptr += sizeof(BitBuf) * (bits / BUF_BITS); 396 s->bit_left = BUF_BITS - (bits & (BUF_BITS - 1)); 397} 398 399/** 400 * Change the end of the buffer. 401 * 402 * @param size the new size in bytes of the buffer where to put bits 403 */ 404static inline void set_put_bits_buffer_size(PutBitContext *s, int size) 405{ 406 av_assert0(size <= INT_MAX/8 - BUF_BITS); 407 s->buf_end = s->buf + size; 408} 409 410/** 411 * Pad the bitstream with zeros up to the next byte boundary. 412 */ 413static inline void align_put_bits(PutBitContext *s) 414{ 415 put_bits(s, s->bit_left & 7, 0); 416} 417 418#undef AV_WBBUF 419#undef AV_WLBUF 420 421#endif /* AVCODEC_PUT_BITS_H */ 422