2 * copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
4 * This file is part of FFmpeg.
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.
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.
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
23 * bitstream writer API
26 #ifndef AVCODEC_PUT_BITS_H
27 #define AVCODEC_PUT_BITS_H
33 #include "libavutil/intreadwrite.h"
34 #include "libavutil/avassert.h"
35 #include "libavutil/common.h"
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
43 typedef uint32_t BitBuf
;
44 #define AV_WBBUF AV_WB32
45 #define AV_WLBUF AV_WL32
48 static const int BUF_BITS
= 8 * sizeof(BitBuf
);
50 typedef struct PutBitContext
{
53 uint8_t *buf
, *buf_ptr
, *buf_end
;
57 * Initialize the PutBitContext s.
59 * @param buffer the buffer where to put bits
60 * @param buffer_size the size in bytes of buffer
62 static inline void init_put_bits(PutBitContext
*s
, uint8_t *buffer
,
65 if (buffer_size
< 0) {
71 s
->buf_end
= s
->buf
+ buffer_size
;
73 s
->bit_left
= BUF_BITS
;
78 * @return the total number of bits written to the bitstream.
80 static inline int put_bits_count(PutBitContext
*s
)
82 return (s
->buf_ptr
- s
->buf
) * 8 + BUF_BITS
- s
->bit_left
;
86 * @return the number of bytes output so far; may only be called
87 * when the PutBitContext is freshly initialized or flushed.
89 static inline int put_bytes_output(const PutBitContext
*s
)
91 av_assert2(s
->bit_left
== BUF_BITS
);
92 return s
->buf_ptr
- s
->buf
;
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.
100 static inline int put_bytes_count(const PutBitContext
*s
, int round_up
)
102 return s
->buf_ptr
- s
->buf
+ ((BUF_BITS
- s
->bit_left
+ (round_up
? 7 : 0)) >> 3);
106 * Rebase the bit writer onto a reallocated buffer.
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
112 static inline void rebase_put_bits(PutBitContext
*s
, uint8_t *buffer
,
115 av_assert0(8*buffer_size
>= put_bits_count(s
));
117 s
->buf_end
= buffer
+ buffer_size
;
118 s
->buf_ptr
= buffer
+ (s
->buf_ptr
- s
->buf
);
123 * @return the number of bits available in the bitstream.
125 static inline int put_bits_left(PutBitContext
* s
)
127 return (s
->buf_end
- s
->buf_ptr
) * 8 - BUF_BITS
+ s
->bit_left
;
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.
135 static inline int put_bytes_left(const PutBitContext
*s
, int round_up
)
137 return s
->buf_end
- s
->buf_ptr
- ((BUF_BITS
- s
->bit_left
+ (round_up
? 7 : 0)) >> 3);
141 * Pad the end of the output stream with zeros.
143 static inline void flush_put_bits(PutBitContext
*s
)
145 #ifndef BITSTREAM_WRITER_LE
146 if (s
->bit_left
< BUF_BITS
)
147 s
->bit_buf
<<= s
->bit_left
;
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
;
155 *s
->buf_ptr
++ = s
->bit_buf
>> (BUF_BITS
- 8);
160 s
->bit_left
= BUF_BITS
;
164 static inline void flush_put_bits_le(PutBitContext
*s
)
166 while (s
->bit_left
< BUF_BITS
) {
167 av_assert0(s
->buf_ptr
< s
->buf_end
);
168 *s
->buf_ptr
++ = s
->bit_buf
;
172 s
->bit_left
= BUF_BITS
;
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
182 * Put the string string in the bitstream.
184 * @param terminate_string 0-terminates the written string if value is 1
186 void ff_put_string(PutBitContext
*pb
, const char *string
,
187 int terminate_string
);
190 * Copy the content of src to the bitstream.
192 * @param length the number of bits of src to copy
194 void ff_copy_bits(PutBitContext
*pb
, const uint8_t *src
, int length
);
197 static inline void put_bits_no_assert(PutBitContext
*s
, int n
, BitBuf value
)
202 bit_buf
= s
->bit_buf
;
203 bit_left
= s
->bit_left
;
206 #ifdef BITSTREAM_WRITER_LE
207 bit_buf
|= value
<< (BUF_BITS
- 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
);
213 av_log(NULL
, AV_LOG_ERROR
, "Internal error, put_bits buffer too small\n");
216 bit_buf
= value
>> bit_left
;
217 bit_left
+= BUF_BITS
;
222 bit_buf
= (bit_buf
<< n
) | value
;
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
);
231 av_log(NULL
, AV_LOG_ERROR
, "Internal error, put_bits buffer too small\n");
234 bit_left
+= BUF_BITS
- n
;
239 s
->bit_buf
= bit_buf
;
240 s
->bit_left
= bit_left
;
244 * Write up to 31 bits into a bitstream.
245 * Use put_bits32 to write 32 bits.
247 static inline void put_bits(PutBitContext
*s
, int n
, BitBuf value
)
249 av_assert2(n
<= 31 && value
< (1UL << n
));
250 put_bits_no_assert(s
, n
, value
);
253 static inline void put_bits_le(PutBitContext
*s
, int n
, BitBuf value
)
258 av_assert2(n
<= 31 && value
< (1UL << n
));
260 bit_buf
= s
->bit_buf
;
261 bit_left
= s
->bit_left
;
263 bit_buf
|= value
<< (BUF_BITS
- 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
);
269 av_log(NULL
, AV_LOG_ERROR
, "Internal error, put_bits buffer too small\n");
272 bit_buf
= value
>> bit_left
;
273 bit_left
+= BUF_BITS
;
277 s
->bit_buf
= bit_buf
;
278 s
->bit_left
= bit_left
;
281 static inline void put_sbits(PutBitContext
*pb
, int n
, int32_t value
)
283 av_assert2(n
>= 0 && n
<= 31);
285 put_bits(pb
, n
, av_mod_uintp2(value
, n
));
289 * Write exactly 32 bits into a bitstream.
291 static void av_unused
put_bits32(PutBitContext
*s
, uint32_t value
)
297 put_bits_no_assert(s
, 32, value
);
301 bit_buf
= s
->bit_buf
;
302 bit_left
= s
->bit_left
;
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
);
310 av_log(NULL
, AV_LOG_ERROR
, "Internal error, put_bits buffer too small\n");
313 bit_buf
= (uint64_t)value
>> bit_left
;
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
);
321 av_log(NULL
, AV_LOG_ERROR
, "Internal error, put_bits buffer too small\n");
327 s
->bit_buf
= bit_buf
;
328 s
->bit_left
= bit_left
;
332 * Write up to 64 bits into a bitstream.
334 static inline void put_bits64(PutBitContext
*s
, int n
, uint64_t value
)
336 av_assert2((n
== 64) || (n
< 64 && value
< (UINT64_C(1) << n
)));
339 put_bits(s
, n
, value
);
341 put_bits32(s
, value
);
343 uint32_t lo
= value
& 0xffffffff;
344 uint32_t hi
= value
>> 32;
345 #ifdef BITSTREAM_WRITER_LE
347 put_bits(s
, n
- 32, hi
);
349 put_bits(s
, n
- 32, hi
);
353 uint32_t lo
= value
& 0xffffffff;
354 uint32_t hi
= value
>> 32;
355 #ifdef BITSTREAM_WRITER_LE
366 static inline void put_sbits63(PutBitContext
*pb
, int n
, int64_t value
)
368 av_assert2(n
>= 0 && n
< 64);
370 put_bits64(pb
, n
, (uint64_t)(value
) & (~(UINT64_MAX
<< n
)));
374 * Return the pointer to the byte where the bitstream writer will put
377 static inline uint8_t *put_bits_ptr(PutBitContext
*s
)
383 * Skip the given number of bytes.
384 * PutBitContext must be flushed & aligned to a byte boundary before calling this.
386 static inline void skip_put_bytes(PutBitContext
*s
, int n
)
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
);
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.
399 static inline void skip_put_bits(PutBitContext
*s
, int n
)
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));
407 * Change the end of the buffer.
409 * @param size the new size in bytes of the buffer where to put bits
411 static inline void set_put_bits_buffer_size(PutBitContext
*s
, int size
)
413 av_assert0(size
<= INT_MAX
/8 - BUF_BITS
);
414 s
->buf_end
= s
->buf
+ size
;
418 * Pad the bitstream with zeros up to the next byte boundary.
420 static inline void align_put_bits(PutBitContext
*s
)
422 put_bits(s
, s
->bit_left
& 7, 0);
428 #endif /* AVCODEC_PUT_BITS_H */