FFmpeg
Loading...
Searching...
No Matches
put_bits.h
Go to the documentation of this file.
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"
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#define BUF_BITS 64
43#else
44typedef uint32_t BitBuf;
45#define AV_WBBUF AV_WB32
46#define AV_WLBUF AV_WL32
47#define BUF_BITS 32
48#endif
49
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 * Inform the compiler that a PutBitContext is flushed (i.e. if it has just
79 * been initialized or flushed). Undefined behaviour occurs if this is used
80 * with a PutBitContext for which this is not true.
81 */
82static inline void put_bits_assume_flushed(const PutBitContext *s)
83{
84 av_assume(s->bit_left == BUF_BITS);
85}
86
87/**
88 * @return the total number of bits written to the bitstream.
89 */
90static inline int put_bits_count(PutBitContext *s)
91{
92 return (s->buf_ptr - s->buf) * 8 + BUF_BITS - s->bit_left;
93}
94
95/**
96 * @return the number of bytes output so far; may only be called
97 * when the PutBitContext is freshly initialized or flushed.
98 */
99static inline int put_bytes_output(const PutBitContext *s)
100{
101 av_assert2(s->bit_left == BUF_BITS);
102 return s->buf_ptr - s->buf;
103}
104
105/**
106 * @param round_up When set, the number of bits written so far will be
107 * rounded up to the next byte.
108 * @return the number of bytes output so far.
109 */
110static inline int put_bytes_count(const PutBitContext *s, int round_up)
111{
112 return s->buf_ptr - s->buf + ((BUF_BITS - s->bit_left + (round_up ? 7 : 0)) >> 3);
113}
114
115/**
116 * Rebase the bit writer onto a reallocated buffer.
117 *
118 * @param buffer the buffer where to put bits
119 * @param buffer_size the size in bytes of buffer,
120 * must be large enough to hold everything written so far
121 */
122static inline void rebase_put_bits(PutBitContext *s, uint8_t *buffer,
123 int buffer_size)
124{
125 av_assert0(8*buffer_size >= put_bits_count(s));
126
127 s->buf_end = buffer + buffer_size;
128 s->buf_ptr = buffer + (s->buf_ptr - s->buf);
129 s->buf = buffer;
130}
131
132/**
133 * @return the number of bits available in the bitstream.
134 */
135static inline int put_bits_left(PutBitContext* s)
136{
137 return (s->buf_end - s->buf_ptr) * 8 - BUF_BITS + s->bit_left;
138}
139
140/**
141 * @param round_up When set, the number of bits written will be
142 * rounded up to the next byte.
143 * @return the number of bytes left.
144 */
145static inline int put_bytes_left(const PutBitContext *s, int round_up)
146{
147 return s->buf_end - s->buf_ptr - ((BUF_BITS - s->bit_left + (round_up ? 7 : 0)) >> 3);
148}
149
150/**
151 * Pad the end of the output stream with zeros.
152 */
153static inline void flush_put_bits(PutBitContext *s)
154{
155#ifndef BITSTREAM_WRITER_LE
156 if (s->bit_left < BUF_BITS)
157 s->bit_buf <<= s->bit_left;
158#endif
159 while (s->bit_left < BUF_BITS) {
160 av_assert0(s->buf_ptr < s->buf_end);
161#ifdef BITSTREAM_WRITER_LE
162 *s->buf_ptr++ = s->bit_buf;
163 s->bit_buf >>= 8;
164#else
165 *s->buf_ptr++ = s->bit_buf >> (BUF_BITS - 8);
166 s->bit_buf <<= 8;
167#endif
168 s->bit_left += 8;
169 }
170 s->bit_left = BUF_BITS;
171 s->bit_buf = 0;
172}
173
175{
176 while (s->bit_left < BUF_BITS) {
177 av_assert0(s->buf_ptr < s->buf_end);
178 *s->buf_ptr++ = s->bit_buf;
179 s->bit_buf >>= 8;
180 s->bit_left += 8;
181 }
182 s->bit_left = BUF_BITS;
183 s->bit_buf = 0;
184}
185
186#ifdef BITSTREAM_WRITER_LE
187#define ff_put_string ff_put_string_unsupported_here
188#define ff_copy_bits ff_copy_bits_unsupported_here
189#else
190
191/**
192 * Put the string string in the bitstream.
193 *
194 * @param terminate_string 0-terminates the written string if value is 1
195 */
196void ff_put_string(PutBitContext *pb, const char *string,
197 int terminate_string);
198
199/**
200 * Copy the content of src to the bitstream.
201 *
202 * @param length the number of bits of src to copy
203 */
204void ff_copy_bits(PutBitContext *pb, const uint8_t *src, int length);
205#endif
206
207static inline void put_bits_no_assert(PutBitContext *s, int n, BitBuf value)
208{
209 BitBuf bit_buf;
210 int bit_left;
211
212 bit_buf = s->bit_buf;
213 bit_left = s->bit_left;
214
215 /* XXX: optimize */
216#ifdef BITSTREAM_WRITER_LE
217 bit_buf |= value << (BUF_BITS - bit_left);
218 if (n >= bit_left) {
219 if (s->buf_end - s->buf_ptr >= sizeof(BitBuf)) {
220 AV_WLBUF(s->buf_ptr, bit_buf);
221 s->buf_ptr += sizeof(BitBuf);
222 } else {
223 av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n");
224 av_assert2(0);
225 }
226 bit_buf = value >> bit_left;
227 bit_left += BUF_BITS;
228 }
229 bit_left -= n;
230#else
231 if (n < bit_left) {
232 bit_buf = (bit_buf << n) | value;
233 bit_left -= n;
234 } else {
235 bit_buf <<= bit_left;
236 bit_buf |= value >> (n - bit_left);
237 if (s->buf_end - s->buf_ptr >= sizeof(BitBuf)) {
238 AV_WBBUF(s->buf_ptr, bit_buf);
239 s->buf_ptr += sizeof(BitBuf);
240 } else {
241 av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n");
242 av_assert2(0);
243 }
244 bit_left += BUF_BITS - n;
245 bit_buf = value;
246 }
247#endif
248
249 s->bit_buf = bit_buf;
250 s->bit_left = bit_left;
251}
252
253/**
254 * Write up to 31 bits into a bitstream.
255 * Use put_bits32 to write 32 bits.
256 */
257static inline void put_bits(PutBitContext *s, int n, BitBuf value)
258{
259 av_assert2(n <= 31 && value < (BitBuf)(1U << n));
261}
262
263static inline void put_bits_le(PutBitContext *s, int n, BitBuf value)
264{
265 BitBuf bit_buf;
266 int bit_left;
267
268 av_assert2(n <= 31 && value < (BitBuf)(1U << n));
269
270 bit_buf = s->bit_buf;
271 bit_left = s->bit_left;
272
273 bit_buf |= value << (BUF_BITS - bit_left);
274 if (n >= bit_left) {
275 if (s->buf_end - s->buf_ptr >= sizeof(BitBuf)) {
276 AV_WLBUF(s->buf_ptr, bit_buf);
277 s->buf_ptr += sizeof(BitBuf);
278 } else {
279 av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n");
280 av_assert2(0);
281 }
282 bit_buf = value >> bit_left;
283 bit_left += BUF_BITS;
284 }
285 bit_left -= n;
286
287 s->bit_buf = bit_buf;
288 s->bit_left = bit_left;
289}
290
291static inline void put_sbits(PutBitContext *pb, int n, int32_t value)
292{
293 av_assert2(n >= 0 && n <= 31);
294
295 put_bits(pb, n, av_zero_extend(value, n));
296}
297
298/**
299 * Write exactly 32 bits into a bitstream.
300 */
301av_unused static void put_bits32(PutBitContext *s, uint32_t value)
302{
303 BitBuf bit_buf;
304 int bit_left;
305
306 if (BUF_BITS > 32) {
308 return;
309 }
310
311 bit_buf = s->bit_buf;
312 bit_left = s->bit_left;
313
314#ifdef BITSTREAM_WRITER_LE
315 bit_buf |= (BitBuf)value << (BUF_BITS - bit_left);
316 if (s->buf_end - s->buf_ptr >= sizeof(BitBuf)) {
317 AV_WLBUF(s->buf_ptr, bit_buf);
318 s->buf_ptr += sizeof(BitBuf);
319 } else {
320 av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n");
321 av_assert2(0);
322 }
323 bit_buf = (uint64_t)value >> bit_left;
324#else
325 bit_buf = (uint64_t)bit_buf << bit_left;
326 bit_buf |= (BitBuf)value >> (BUF_BITS - bit_left);
327 if (s->buf_end - s->buf_ptr >= sizeof(BitBuf)) {
328 AV_WBBUF(s->buf_ptr, bit_buf);
329 s->buf_ptr += sizeof(BitBuf);
330 } else {
331 av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n");
332 av_assert2(0);
333 }
334 bit_buf = value;
335#endif
336
337 s->bit_buf = bit_buf;
338 s->bit_left = bit_left;
339}
340
341/**
342 * Write up to 63 bits into a bitstream.
343 */
344static inline void put_bits63(PutBitContext *s, int n, uint64_t value)
345{
346 av_assert2(n < 64U && value < (UINT64_C(1) << n));
347
348#if BUF_BITS >= 64
350#else
351 if (n < 32)
352 put_bits(s, n, value);
353 else if (n == 32)
355 else if (n < 64) {
356 uint32_t lo = value & 0xffffffff;
357 uint32_t hi = value >> 32;
358#ifdef BITSTREAM_WRITER_LE
359 put_bits32(s, lo);
360 put_bits(s, n - 32, hi);
361#else
362 put_bits(s, n - 32, hi);
363 put_bits32(s, lo);
364#endif
365 }
366#endif
367}
368
369/**
370 * Write up to 64 bits into a bitstream.
371 */
372static inline void put_bits64(PutBitContext *s, int n, uint64_t value)
373{
374 av_assert2((n == 64) || (n < 64 && value < (UINT64_C(1) << n)));
375
376 if (n < 64) {
377 put_bits63(s, n, value);
378 } else {
379 uint32_t lo = value & 0xffffffff;
380 uint32_t hi = value >> 32;
381#ifdef BITSTREAM_WRITER_LE
382 put_bits32(s, lo);
383 put_bits32(s, hi);
384#else
385 put_bits32(s, hi);
386 put_bits32(s, lo);
387#endif
388 }
389}
390
391static inline void put_sbits63(PutBitContext *pb, int n, int64_t value)
392{
393 av_assert2(n >= 0 && n < 64);
394
395 put_bits63(pb, n, (uint64_t)(value) & (~(UINT64_MAX << n)));
396}
397
398/**
399 * Return the pointer to the byte where the bitstream writer will put
400 * the next bit.
401 */
402static inline uint8_t *put_bits_ptr(PutBitContext *s)
403{
404 return s->buf_ptr;
405}
406
407/**
408 * Skip the given number of bytes.
409 * PutBitContext must be flushed & aligned to a byte boundary before calling this.
410 */
411static inline void skip_put_bytes(PutBitContext *s, int n)
412{
413 av_assert2((put_bits_count(s) & 7) == 0);
414 av_assert2(s->bit_left == BUF_BITS);
415 av_assert0(n <= s->buf_end - s->buf_ptr);
416 s->buf_ptr += n;
417}
418
419/**
420 * Skip the given number of bits.
421 * Must only be used if the actual values in the bitstream do not matter.
422 * If n is < 0 the behavior is undefined.
423 */
424static inline void skip_put_bits(PutBitContext *s, int n)
425{
426 unsigned bits = BUF_BITS - s->bit_left + n;
427 s->buf_ptr += sizeof(BitBuf) * (bits / BUF_BITS);
428 s->bit_left = BUF_BITS - (bits & (BUF_BITS - 1));
429}
430
431/**
432 * Change the end of the buffer.
433 *
434 * @param size the new size in bytes of the buffer where to put bits
435 */
437{
438 av_assert0(size <= INT_MAX/8 - BUF_BITS);
439 s->buf_end = s->buf + size;
440}
441
442/**
443 * Pad the bitstream with zeros up to the next byte boundary.
444 */
445static inline void align_put_bits(PutBitContext *s)
446{
447 put_bits(s, s->bit_left & 7, 0);
448}
449
450#undef AV_WBBUF
451#undef AV_WLBUF
452
453#endif /* AVCODEC_PUT_BITS_H */
int32_t
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition avassert.h:68
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
#define av_assume(cond)
Definition avassert.h:119
#define s(width, name)
Definition cbs_vp9.c:198
common internal and external API header
#define av_zero_extend
Definition common.h:151
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
double value
Definition eval.c:102
static const uint8_t bits[8]
Definition fastaudio.c:100
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
#define av_unused
Definition attributes.h:164
static void put_sbits(PutBitContext *pb, int n, int32_t value)
Definition put_bits.h:291
static void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size)
Initialize the PutBitContext s.
Definition put_bits.h:62
static void put_bits_le(PutBitContext *s, int n, BitBuf value)
Definition put_bits.h:263
static void rebase_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size)
Rebase the bit writer onto a reallocated buffer.
Definition put_bits.h:122
static void flush_put_bits_le(PutBitContext *s)
Definition put_bits.h:174
static void set_put_bits_buffer_size(PutBitContext *s, int size)
Change the end of the buffer.
Definition put_bits.h:436
static void put_bits64(PutBitContext *s, int n, uint64_t value)
Write up to 64 bits into a bitstream.
Definition put_bits.h:372
static void skip_put_bits(PutBitContext *s, int n)
Skip the given number of bits.
Definition put_bits.h:424
static int put_bits_count(PutBitContext *s)
Definition put_bits.h:90
static void put_bits_no_assert(PutBitContext *s, int n, BitBuf value)
Definition put_bits.h:207
static uint8_t * put_bits_ptr(PutBitContext *s)
Return the pointer to the byte where the bitstream writer will put the next bit.
Definition put_bits.h:402
static int put_bytes_count(const PutBitContext *s, int round_up)
Definition put_bits.h:110
static int put_bits_left(PutBitContext *s)
Definition put_bits.h:135
static void put_sbits63(PutBitContext *pb, int n, int64_t value)
Definition put_bits.h:391
static int put_bytes_left(const PutBitContext *s, int round_up)
Definition put_bits.h:145
static void flush_put_bits(PutBitContext *s)
Pad the end of the output stream with zeros.
Definition put_bits.h:153
#define AV_WLBUF
Definition put_bits.h:46
static void put_bits63(PutBitContext *s, int n, uint64_t value)
Write up to 63 bits into a bitstream.
Definition put_bits.h:344
static int put_bytes_output(const PutBitContext *s)
Definition put_bits.h:99
void ff_copy_bits(PutBitContext *pb, const uint8_t *src, int length)
Copy the content of src to the bitstream.
Definition bitstream.c:49
static void skip_put_bytes(PutBitContext *s, int n)
Skip the given number of bytes.
Definition put_bits.h:411
static av_unused void put_bits32(PutBitContext *s, uint32_t value)
Write exactly 32 bits into a bitstream.
Definition put_bits.h:301
static void align_put_bits(PutBitContext *s)
Pad the bitstream with zeros up to the next byte boundary.
Definition put_bits.h:445
static void put_bits(PutBitContext *s, int n, BitBuf value)
Write up to 31 bits into a bitstream.
Definition put_bits.h:257
static void put_bits_assume_flushed(const PutBitContext *s)
Inform the compiler that a PutBitContext is flushed (i.e.
Definition put_bits.h:82
#define BUF_BITS
Definition put_bits.h:47
uint32_t BitBuf
Definition put_bits.h:44
#define AV_WBBUF
Definition put_bits.h:45
void ff_put_string(PutBitContext *pb, const char *string, int terminate_string)
Put the string string in the bitstream.
Definition bitstream.c:39
Definition kmvc.c:54
BitBuf bit_buf
Definition put_bits.h:51
uint8_t * buf
Definition put_bits.h:53
uint8_t * buf_ptr
Definition put_bits.h:53
uint8_t * buf_end
Definition put_bits.h:53
#define av_log(a,...)
#define src
Definition vp8dsp.c:248
static char buffer[20]
Definition seek.c:32
int size