FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/put_bits.h
Date: 2025-06-01 09:29:47
Exec Total Coverage
Lines: 128 141 90.8%
Functions: 23 23 100.0%
Branches: 35 56 62.5%

Line Branch Exec Source
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 #define BUF_BITS 64
43 #else
44 typedef uint32_t BitBuf;
45 #define AV_WBBUF AV_WB32
46 #define AV_WLBUF AV_WL32
47 #define BUF_BITS 32
48 #endif
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 27371179 static inline void init_put_bits(PutBitContext *s, uint8_t *buffer,
63 int buffer_size)
64 {
65
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27371179 times.
27371179 if (buffer_size < 0) {
66 buffer_size = 0;
67 buffer = NULL;
68 }
69
70 27371179 s->buf = buffer;
71 27371179 s->buf_end = s->buf + buffer_size;
72 27371179 s->buf_ptr = s->buf;
73 27371179 s->bit_left = BUF_BITS;
74 27371179 s->bit_buf = 0;
75 27371179 }
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 */
82 13810 static inline void put_bits_assume_flushed(const PutBitContext *s)
83 {
84
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13810 times.
13810 av_assume(s->bit_left == BUF_BITS);
85 13810 }
86
87 /**
88 * @return the total number of bits written to the bitstream.
89 */
90 17770634 static inline int put_bits_count(PutBitContext *s)
91 {
92 17770634 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 */
99 448398 static inline int put_bytes_output(const PutBitContext *s)
100 {
101 av_assert2(s->bit_left == BUF_BITS);
102 448398 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 */
110 1695083 static inline int put_bytes_count(const PutBitContext *s, int round_up)
111 {
112
2/2
✓ Branch 0 taken 1551272 times.
✓ Branch 1 taken 143811 times.
1695083 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 */
122 32 static inline void rebase_put_bits(PutBitContext *s, uint8_t *buffer,
123 int buffer_size)
124 {
125
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
32 av_assert0(8*buffer_size >= put_bits_count(s));
126
127 32 s->buf_end = buffer + buffer_size;
128 32 s->buf_ptr = buffer + (s->buf_ptr - s->buf);
129 32 s->buf = buffer;
130 32 }
131
132 /**
133 * @return the number of bits available in the bitstream.
134 */
135 287450459 static inline int put_bits_left(PutBitContext* s)
136 {
137 287450459 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 */
145 35752283 static inline int put_bytes_left(const PutBitContext *s, int round_up)
146 {
147
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 35752283 times.
35752283 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 */
153 29535324 static inline void flush_put_bits(PutBitContext *s)
154 {
155 #ifndef BITSTREAM_WRITER_LE
156
2/2
✓ Branch 0 taken 26549606 times.
✓ Branch 1 taken 2984698 times.
29534304 if (s->bit_left < BUF_BITS)
157 26549606 s->bit_buf <<= s->bit_left;
158 #endif
159
2/2
✓ Branch 0 taken 91336170 times.
✓ Branch 1 taken 29535324 times.
120871494 while (s->bit_left < BUF_BITS) {
160
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 91336170 times.
91336170 av_assert0(s->buf_ptr < s->buf_end);
161 #ifdef BITSTREAM_WRITER_LE
162 3416 *s->buf_ptr++ = s->bit_buf;
163 3416 s->bit_buf >>= 8;
164 #else
165 91332754 *s->buf_ptr++ = s->bit_buf >> (BUF_BITS - 8);
166 91332754 s->bit_buf <<= 8;
167 #endif
168 91336170 s->bit_left += 8;
169 }
170 29535324 s->bit_left = BUF_BITS;
171 29535324 s->bit_buf = 0;
172 29535324 }
173
174 3063 static inline void flush_put_bits_le(PutBitContext *s)
175 {
176
2/2
✓ Branch 0 taken 13599 times.
✓ Branch 1 taken 3063 times.
16662 while (s->bit_left < BUF_BITS) {
177
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13599 times.
13599 av_assert0(s->buf_ptr < s->buf_end);
178 13599 *s->buf_ptr++ = s->bit_buf;
179 13599 s->bit_buf >>= 8;
180 13599 s->bit_left += 8;
181 }
182 3063 s->bit_left = BUF_BITS;
183 3063 s->bit_buf = 0;
184 3063 }
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 */
196 void 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 */
204 void ff_copy_bits(PutBitContext *pb, const uint8_t *src, int length);
205 #endif
206
207 2507171079 static inline void put_bits_no_assert(PutBitContext *s, int n, BitBuf value)
208 {
209 BitBuf bit_buf;
210 int bit_left;
211
212 2507171079 bit_buf = s->bit_buf;
213 2507171079 bit_left = s->bit_left;
214
215 /* XXX: optimize */
216 #ifdef BITSTREAM_WRITER_LE
217 2869831 bit_buf |= value << (BUF_BITS - bit_left);
218
2/2
✓ Branch 0 taken 137505 times.
✓ Branch 1 taken 2732326 times.
2869831 if (n >= bit_left) {
219
1/2
✓ Branch 0 taken 137505 times.
✗ Branch 1 not taken.
137505 if (s->buf_end - s->buf_ptr >= sizeof(BitBuf)) {
220 137505 AV_WLBUF(s->buf_ptr, bit_buf);
221 137505 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 137505 bit_buf = value >> bit_left;
227 137505 bit_left += BUF_BITS;
228 }
229 2869831 bit_left -= n;
230 #else
231
2/2
✓ Branch 0 taken 2322365843 times.
✓ Branch 1 taken 181935405 times.
2504301248 if (n < bit_left) {
232 2322365843 bit_buf = (bit_buf << n) | value;
233 2322365843 bit_left -= n;
234 } else {
235 181935405 bit_buf <<= bit_left;
236 181935405 bit_buf |= value >> (n - bit_left);
237
1/2
✓ Branch 0 taken 181935405 times.
✗ Branch 1 not taken.
181935405 if (s->buf_end - s->buf_ptr >= sizeof(BitBuf)) {
238 181935405 AV_WBBUF(s->buf_ptr, bit_buf);
239 181935405 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 181935405 bit_left += BUF_BITS - n;
245 181935405 bit_buf = value;
246 }
247 #endif
248
249 2507171079 s->bit_buf = bit_buf;
250 2507171079 s->bit_left = bit_left;
251 2507171079 }
252
253 /**
254 * Write up to 31 bits into a bitstream.
255 * Use put_bits32 to write 32 bits.
256 */
257 2466140899 static inline void put_bits(PutBitContext *s, int n, BitBuf value)
258 {
259
2/4
✓ Branch 0 taken 82 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 82 times.
82 av_assert2(n <= 31 && value < (1UL << n));
260 2466140899 put_bits_no_assert(s, n, value);
261 2466140899 }
262
263 16854133 static 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 < (1UL << n));
269
270 16854133 bit_buf = s->bit_buf;
271 16854133 bit_left = s->bit_left;
272
273 16854133 bit_buf |= value << (BUF_BITS - bit_left);
274
2/2
✓ Branch 0 taken 1516389 times.
✓ Branch 1 taken 15337744 times.
16854133 if (n >= bit_left) {
275
1/2
✓ Branch 0 taken 1516389 times.
✗ Branch 1 not taken.
1516389 if (s->buf_end - s->buf_ptr >= sizeof(BitBuf)) {
276 1516389 AV_WLBUF(s->buf_ptr, bit_buf);
277 1516389 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 1516389 bit_buf = value >> bit_left;
283 1516389 bit_left += BUF_BITS;
284 }
285 16854133 bit_left -= n;
286
287 16854133 s->bit_buf = bit_buf;
288 16854133 s->bit_left = bit_left;
289 16854133 }
290
291 242677894 static inline void put_sbits(PutBitContext *pb, int n, int32_t value)
292 {
293
2/4
✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 23 times.
23 av_assert2(n >= 0 && n <= 31);
294
295 242677894 put_bits(pb, n, av_zero_extend(value, n));
296 242677894 }
297
298 /**
299 * Write exactly 32 bits into a bitstream.
300 */
301 4334762 static void av_unused put_bits32(PutBitContext *s, uint32_t value)
302 {
303 BitBuf bit_buf;
304 int bit_left;
305
306 if (BUF_BITS > 32) {
307 4334762 put_bits_no_assert(s, 32, value);
308 4334762 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 */
344 36695418 static inline void put_bits63(PutBitContext *s, int n, uint64_t value)
345 {
346
2/4
✓ Branch 0 taken 101 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 101 times.
101 av_assert2(n < 64U && value < (UINT64_C(1) << n));
347
348 #if BUF_BITS >= 64
349 36695418 put_bits_no_assert(s, n, value);
350 #else
351 if (n < 32)
352 put_bits(s, n, value);
353 else if (n == 32)
354 put_bits32(s, value);
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 36695418 }
368
369 /**
370 * Write up to 64 bits into a bitstream.
371 */
372 101 static inline void put_bits64(PutBitContext *s, int n, uint64_t value)
373 {
374
3/6
✓ Branch 0 taken 101 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 101 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 101 times.
101 av_assert2((n == 64) || (n < 64 && value < (UINT64_C(1) << n)));
375
376
1/2
✓ Branch 0 taken 101 times.
✗ Branch 1 not taken.
101 if (n < 64) {
377 101 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 101 }
390
391 4624 static inline void put_sbits63(PutBitContext *pb, int n, int64_t value)
392 {
393 av_assert2(n >= 0 && n < 64);
394
395 4624 put_bits63(pb, n, (uint64_t)(value) & (~(UINT64_MAX << n)));
396 4624 }
397
398 /**
399 * Return the pointer to the byte where the bitstream writer will put
400 * the next bit.
401 */
402 23020720 static inline uint8_t *put_bits_ptr(PutBitContext *s)
403 {
404 23020720 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 */
411 142873 static 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
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 142873 times.
142873 av_assert0(n <= s->buf_end - s->buf_ptr);
416 142873 s->buf_ptr += n;
417 142873 }
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 */
424 60 static inline void skip_put_bits(PutBitContext *s, int n)
425 {
426 60 unsigned bits = BUF_BITS - s->bit_left + n;
427 60 s->buf_ptr += sizeof(BitBuf) * (bits / BUF_BITS);
428 60 s->bit_left = BUF_BITS - (bits & (BUF_BITS - 1));
429 60 }
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 */
436 5828 static inline void set_put_bits_buffer_size(PutBitContext *s, int size)
437 {
438
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5828 times.
5828 av_assert0(size <= INT_MAX/8 - BUF_BITS);
439 5828 s->buf_end = s->buf + size;
440 5828 }
441
442 /**
443 * Pad the bitstream with zeros up to the next byte boundary.
444 */
445 314249 static inline void align_put_bits(PutBitContext *s)
446 {
447 314249 put_bits(s, s->bit_left & 7, 0);
448 314249 }
449
450 #undef AV_WBBUF
451 #undef AV_WLBUF
452
453 #endif /* AVCODEC_PUT_BITS_H */
454