FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/put_bits.h
Date: 2025-04-25 22:50:00
Exec Total Coverage
Lines: 129 138 93.5%
Functions: 22 22 100.0%
Branches: 36 54 66.7%

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 27332524 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 27332524 times.
27332524 if (buffer_size < 0) {
66 buffer_size = 0;
67 buffer = NULL;
68 }
69
70 27332524 s->buf = buffer;
71 27332524 s->buf_end = s->buf + buffer_size;
72 27332524 s->buf_ptr = s->buf;
73 27332524 s->bit_left = BUF_BITS;
74 27332524 s->bit_buf = 0;
75 27332524 }
76
77 /**
78 * @return the total number of bits written to the bitstream.
79 */
80 17753663 static inline int put_bits_count(PutBitContext *s)
81 {
82 17753663 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 448263 static inline int put_bytes_output(const PutBitContext *s)
90 {
91 av_assert2(s->bit_left == BUF_BITS);
92 448263 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 1695083 static inline int put_bytes_count(const PutBitContext *s, int round_up)
101 {
102
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);
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 32 static inline void rebase_put_bits(PutBitContext *s, uint8_t *buffer,
113 int buffer_size)
114 {
115
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
32 av_assert0(8*buffer_size >= put_bits_count(s));
116
117 32 s->buf_end = buffer + buffer_size;
118 32 s->buf_ptr = buffer + (s->buf_ptr - s->buf);
119 32 s->buf = buffer;
120 32 }
121
122 /**
123 * @return the number of bits available in the bitstream.
124 */
125 287443419 static inline int put_bits_left(PutBitContext* s)
126 {
127 287443419 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 35752265 static inline int put_bytes_left(const PutBitContext *s, int round_up)
136 {
137
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 35752265 times.
35752265 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 29491064 static inline void flush_put_bits(PutBitContext *s)
144 {
145 #ifndef BITSTREAM_WRITER_LE
146
2/2
✓ Branch 0 taken 26505739 times.
✓ Branch 1 taken 2984305 times.
29490044 if (s->bit_left < BUF_BITS)
147 26505739 s->bit_buf <<= s->bit_left;
148 #endif
149
2/2
✓ Branch 0 taken 91235206 times.
✓ Branch 1 taken 29491064 times.
120726270 while (s->bit_left < BUF_BITS) {
150
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 91235206 times.
91235206 av_assert0(s->buf_ptr < s->buf_end);
151 #ifdef BITSTREAM_WRITER_LE
152 3416 *s->buf_ptr++ = s->bit_buf;
153 3416 s->bit_buf >>= 8;
154 #else
155 91231790 *s->buf_ptr++ = s->bit_buf >> (BUF_BITS - 8);
156 91231790 s->bit_buf <<= 8;
157 #endif
158 91235206 s->bit_left += 8;
159 }
160 29491064 s->bit_left = BUF_BITS;
161 29491064 s->bit_buf = 0;
162 29491064 }
163
164 3063 static inline void flush_put_bits_le(PutBitContext *s)
165 {
166
2/2
✓ Branch 0 taken 13586 times.
✓ Branch 1 taken 3063 times.
16649 while (s->bit_left < BUF_BITS) {
167
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13586 times.
13586 av_assert0(s->buf_ptr < s->buf_end);
168 13586 *s->buf_ptr++ = s->bit_buf;
169 13586 s->bit_buf >>= 8;
170 13586 s->bit_left += 8;
171 }
172 3063 s->bit_left = BUF_BITS;
173 3063 s->bit_buf = 0;
174 3063 }
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 2507572422 static inline void put_bits_no_assert(PutBitContext *s, int n, BitBuf value)
198 {
199 BitBuf bit_buf;
200 int bit_left;
201
202 2507572422 bit_buf = s->bit_buf;
203 2507572422 bit_left = s->bit_left;
204
205 /* XXX: optimize */
206 #ifdef BITSTREAM_WRITER_LE
207 2869843 bit_buf |= value << (BUF_BITS - bit_left);
208
2/2
✓ Branch 0 taken 137505 times.
✓ Branch 1 taken 2732338 times.
2869843 if (n >= bit_left) {
209
1/2
✓ Branch 0 taken 137505 times.
✗ Branch 1 not taken.
137505 if (s->buf_end - s->buf_ptr >= sizeof(BitBuf)) {
210 137505 AV_WLBUF(s->buf_ptr, bit_buf);
211 137505 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 137505 bit_buf = value >> bit_left;
217 137505 bit_left += BUF_BITS;
218 }
219 2869843 bit_left -= n;
220 #else
221
2/2
✓ Branch 0 taken 2322786765 times.
✓ Branch 1 taken 181915814 times.
2504702579 if (n < bit_left) {
222 2322786765 bit_buf = (bit_buf << n) | value;
223 2322786765 bit_left -= n;
224 } else {
225 181915814 bit_buf <<= bit_left;
226 181915814 bit_buf |= value >> (n - bit_left);
227
1/2
✓ Branch 0 taken 181915814 times.
✗ Branch 1 not taken.
181915814 if (s->buf_end - s->buf_ptr >= sizeof(BitBuf)) {
228 181915814 AV_WBBUF(s->buf_ptr, bit_buf);
229 181915814 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 181915814 bit_left += BUF_BITS - n;
235 181915814 bit_buf = value;
236 }
237 #endif
238
239 2507572422 s->bit_buf = bit_buf;
240 2507572422 s->bit_left = bit_left;
241 2507572422 }
242
243 /**
244 * Write up to 31 bits into a bitstream.
245 * Use put_bits32 to write 32 bits.
246 */
247 2466548634 static inline void put_bits(PutBitContext *s, int n, BitBuf value)
248 {
249
2/4
✓ Branch 0 taken 99 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 99 times.
99 av_assert2(n <= 31 && value < (1UL << n));
250 2466548634 put_bits_no_assert(s, n, value);
251 2466548634 }
252
253 17219247 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 17219247 bit_buf = s->bit_buf;
261 17219247 bit_left = s->bit_left;
262
263 17219247 bit_buf |= value << (BUF_BITS - bit_left);
264
2/2
✓ Branch 0 taken 1516705 times.
✓ Branch 1 taken 15702542 times.
17219247 if (n >= bit_left) {
265
1/2
✓ Branch 0 taken 1516705 times.
✗ Branch 1 not taken.
1516705 if (s->buf_end - s->buf_ptr >= sizeof(BitBuf)) {
266 1516705 AV_WLBUF(s->buf_ptr, bit_buf);
267 1516705 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 1516705 bit_buf = value >> bit_left;
273 1516705 bit_left += BUF_BITS;
274 }
275 17219247 bit_left -= n;
276
277 17219247 s->bit_buf = bit_buf;
278 17219247 s->bit_left = bit_left;
279 17219247 }
280
281 243097970 static inline void put_sbits(PutBitContext *pb, int n, int32_t value)
282 {
283
2/4
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 42 times.
42 av_assert2(n >= 0 && n <= 31);
284
285 243097970 put_bits(pb, n, av_zero_extend(value, n));
286 243097970 }
287
288 /**
289 * Write exactly 32 bits into a bitstream.
290 */
291 4334764 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 4334764 put_bits_no_assert(s, 32, value);
298 4334764 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 63 bits into a bitstream.
333 */
334 36689024 static inline void put_bits63(PutBitContext *s, int n, uint64_t value)
335 {
336
2/4
✓ Branch 0 taken 79 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 79 times.
79 av_assert2(n < 64U && value < (UINT64_C(1) << n));
337
338 #if BUF_BITS >= 64
339 36689024 put_bits_no_assert(s, n, value);
340 #else
341 if (n < 32)
342 put_bits(s, n, value);
343 else if (n == 32)
344 put_bits32(s, value);
345 else if (n < 64) {
346 uint32_t lo = value & 0xffffffff;
347 uint32_t hi = value >> 32;
348 #ifdef BITSTREAM_WRITER_LE
349 put_bits32(s, lo);
350 put_bits(s, n - 32, hi);
351 #else
352 put_bits(s, n - 32, hi);
353 put_bits32(s, lo);
354 #endif
355 }
356 #endif
357 36689024 }
358
359 /**
360 * Write up to 64 bits into a bitstream.
361 */
362 80 static inline void put_bits64(PutBitContext *s, int n, uint64_t value)
363 {
364
4/6
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 79 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 79 times.
80 av_assert2((n == 64) || (n < 64 && value < (UINT64_C(1) << n)));
365
366
2/2
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 1 times.
80 if (n < 64) {
367 79 put_bits63(s, n, value);
368 } else {
369 1 uint32_t lo = value & 0xffffffff;
370 1 uint32_t hi = value >> 32;
371 #ifdef BITSTREAM_WRITER_LE
372 put_bits32(s, lo);
373 put_bits32(s, hi);
374 #else
375 1 put_bits32(s, hi);
376 1 put_bits32(s, lo);
377 #endif
378 }
379 80 }
380
381 4624 static inline void put_sbits63(PutBitContext *pb, int n, int64_t value)
382 {
383 av_assert2(n >= 0 && n < 64);
384
385 4624 put_bits63(pb, n, (uint64_t)(value) & (~(UINT64_MAX << n)));
386 4624 }
387
388 /**
389 * Return the pointer to the byte where the bitstream writer will put
390 * the next bit.
391 */
392 23020588 static inline uint8_t *put_bits_ptr(PutBitContext *s)
393 {
394 23020588 return s->buf_ptr;
395 }
396
397 /**
398 * Skip the given number of bytes.
399 * PutBitContext must be flushed & aligned to a byte boundary before calling this.
400 */
401 142777 static inline void skip_put_bytes(PutBitContext *s, int n)
402 {
403 av_assert2((put_bits_count(s) & 7) == 0);
404 av_assert2(s->bit_left == BUF_BITS);
405
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 142777 times.
142777 av_assert0(n <= s->buf_end - s->buf_ptr);
406 142777 s->buf_ptr += n;
407 142777 }
408
409 /**
410 * Skip the given number of bits.
411 * Must only be used if the actual values in the bitstream do not matter.
412 * If n is < 0 the behavior is undefined.
413 */
414 60 static inline void skip_put_bits(PutBitContext *s, int n)
415 {
416 60 unsigned bits = BUF_BITS - s->bit_left + n;
417 60 s->buf_ptr += sizeof(BitBuf) * (bits / BUF_BITS);
418 60 s->bit_left = BUF_BITS - (bits & (BUF_BITS - 1));
419 60 }
420
421 /**
422 * Change the end of the buffer.
423 *
424 * @param size the new size in bytes of the buffer where to put bits
425 */
426 5828 static inline void set_put_bits_buffer_size(PutBitContext *s, int size)
427 {
428
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5828 times.
5828 av_assert0(size <= INT_MAX/8 - BUF_BITS);
429 5828 s->buf_end = s->buf + size;
430 5828 }
431
432 /**
433 * Pad the bitstream with zeros up to the next byte boundary.
434 */
435 316189 static inline void align_put_bits(PutBitContext *s)
436 {
437 316189 put_bits(s, s->bit_left & 7, 0);
438 316189 }
439
440 #undef AV_WBBUF
441 #undef AV_WLBUF
442
443 #endif /* AVCODEC_PUT_BITS_H */
444