FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/put_bits.h
Date: 2021-09-26 18:22:30
Exec Total Coverage
Lines: 117 148 79.1%
Branches: 29 46 63.0%

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
36 #if ARCH_X86_64
37 // TODO: Benchmark and optionally enable on other 64-bit architectures.
38 typedef uint64_t BitBuf;
39 #define AV_WBBUF AV_WB64
40 #define AV_WLBUF AV_WL64
41 #else
42 typedef uint32_t BitBuf;
43 #define AV_WBBUF AV_WB32
44 #define AV_WLBUF AV_WL32
45 #endif
46
47 static const int BUF_BITS = 8 * sizeof(BitBuf);
48
49 typedef struct PutBitContext {
50 BitBuf bit_buf;
51 int bit_left;
52 uint8_t *buf, *buf_ptr, *buf_end;
53 } PutBitContext;
54
55 /**
56 * Initialize the PutBitContext s.
57 *
58 * @param buffer the buffer where to put bits
59 * @param buffer_size the size in bytes of buffer
60 */
61 25903164 static inline void init_put_bits(PutBitContext *s, uint8_t *buffer,
62 int buffer_size)
63 {
64
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25903164 times.
25903164 if (buffer_size < 0) {
65 buffer_size = 0;
66 buffer = NULL;
67 }
68
69 25903164 s->buf = buffer;
70 25903164 s->buf_end = s->buf + buffer_size;
71 25903164 s->buf_ptr = s->buf;
72 25903164 s->bit_left = BUF_BITS;
73 25903164 s->bit_buf = 0;
74 25903164 }
75
76 /**
77 * @return the total number of bits written to the bitstream.
78 */
79 13982095 static inline int put_bits_count(PutBitContext *s)
80 {
81 13982095 return (s->buf_ptr - s->buf) * 8 + BUF_BITS - s->bit_left;
82 }
83
84 /**
85 * @return the number of bytes output so far; may only be called
86 * when the PutBitContext is freshly initialized or flushed.
87 */
88 127334 static inline int put_bytes_output(const PutBitContext *s)
89 {
90 av_assert2(s->bit_left == BUF_BITS);
91 127334 return s->buf_ptr - s->buf;
92 }
93
94 /**
95 * @param round_up When set, the number of bits written so far will be
96 * rounded up to the next byte.
97 * @return the number of bytes output so far.
98 */
99 1279009 static inline int put_bytes_count(const PutBitContext *s, int round_up)
100 {
101
2/2
✓ Branch 0 taken 1237831 times.
✓ Branch 1 taken 41178 times.
1279009 return s->buf_ptr - s->buf + ((BUF_BITS - s->bit_left + (round_up ? 7 : 0)) >> 3);
102 }
103
104 /**
105 * Rebase the bit writer onto a reallocated buffer.
106 *
107 * @param buffer the buffer where to put bits
108 * @param buffer_size the size in bytes of buffer,
109 * must be large enough to hold everything written so far
110 */
111 25 static inline void rebase_put_bits(PutBitContext *s, uint8_t *buffer,
112 int buffer_size)
113 {
114
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 25 times.
25 av_assert0(8*buffer_size >= put_bits_count(s));
115
116 25 s->buf_end = buffer + buffer_size;
117 25 s->buf_ptr = buffer + (s->buf_ptr - s->buf);
118 25 s->buf = buffer;
119 25 }
120
121 /**
122 * @return the number of bits available in the bitstream.
123 */
124 271795301 static inline int put_bits_left(PutBitContext* s)
125 {
126 271795301 return (s->buf_end - s->buf_ptr) * 8 - BUF_BITS + s->bit_left;
127 }
128
129 /**
130 * @param round_up When set, the number of bits written will be
131 * rounded up to the next byte.
132 * @return the number of bytes left.
133 */
134 32702505 static inline int put_bytes_left(const PutBitContext *s, int round_up)
135 {
136
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32702505 times.
32702505 return s->buf_end - s->buf_ptr - ((BUF_BITS - s->bit_left + (round_up ? 7 : 0)) >> 3);
137 }
138
139 /**
140 * Pad the end of the output stream with zeros.
141 */
142 27097544 static inline void flush_put_bits(PutBitContext *s)
143 {
144 #ifndef BITSTREAM_WRITER_LE
145
2/2
✓ Branch 0 taken 24347024 times.
✓ Branch 1 taken 2749501 times.
27096525 if (s->bit_left < BUF_BITS)
146 24347024 s->bit_buf <<= s->bit_left;
147 #endif
148
2/2
✓ Branch 0 taken 83813688 times.
✓ Branch 1 taken 27097544 times.
110911232 while (s->bit_left < BUF_BITS) {
149
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 83813688 times.
83813688 av_assert0(s->buf_ptr < s->buf_end);
150 #ifdef BITSTREAM_WRITER_LE
151 3411 *s->buf_ptr++ = s->bit_buf;
152 3411 s->bit_buf >>= 8;
153 #else
154 83810277 *s->buf_ptr++ = s->bit_buf >> (BUF_BITS - 8);
155 83810277 s->bit_buf <<= 8;
156 #endif
157 83813688 s->bit_left += 8;
158 }
159 27097544 s->bit_left = BUF_BITS;
160 27097544 s->bit_buf = 0;
161 27097544 }
162
163 1263 static inline void flush_put_bits_le(PutBitContext *s)
164 {
165
2/2
✓ Branch 0 taken 5568 times.
✓ Branch 1 taken 1263 times.
6831 while (s->bit_left < BUF_BITS) {
166
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5568 times.
5568 av_assert0(s->buf_ptr < s->buf_end);
167 5568 *s->buf_ptr++ = s->bit_buf;
168 5568 s->bit_buf >>= 8;
169 5568 s->bit_left += 8;
170 }
171 1263 s->bit_left = BUF_BITS;
172 1263 s->bit_buf = 0;
173 1263 }
174
175 #ifdef BITSTREAM_WRITER_LE
176 #define ff_put_string ff_put_string_unsupported_here
177 #define ff_copy_bits ff_copy_bits_unsupported_here
178 #else
179
180 /**
181 * Put the string string in the bitstream.
182 *
183 * @param terminate_string 0-terminates the written string if value is 1
184 */
185 void ff_put_string(PutBitContext *pb, const char *string,
186 int terminate_string);
187
188 /**
189 * Copy the content of src to the bitstream.
190 *
191 * @param length the number of bits of src to copy
192 */
193 void ff_copy_bits(PutBitContext *pb, const uint8_t *src, int length);
194 #endif
195
196 2484345360 static inline void put_bits_no_assert(PutBitContext *s, int n, BitBuf value)
197 {
198 BitBuf bit_buf;
199 int bit_left;
200
201 2484345360 bit_buf = s->bit_buf;
202 2484345360 bit_left = s->bit_left;
203
204 /* XXX: optimize */
205 #ifdef BITSTREAM_WRITER_LE
206 2869753 bit_buf |= value << (BUF_BITS - bit_left);
207
2/2
✓ Branch 0 taken 137486 times.
✓ Branch 1 taken 2732267 times.
2869753 if (n >= bit_left) {
208
1/2
✓ Branch 0 taken 137486 times.
✗ Branch 1 not taken.
137486 if (s->buf_end - s->buf_ptr >= sizeof(BitBuf)) {
209 137486 AV_WLBUF(s->buf_ptr, bit_buf);
210 137486 s->buf_ptr += sizeof(BitBuf);
211 } else {
212 av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n");
213 av_assert2(0);
214 }
215 137486 bit_buf = value >> bit_left;
216 137486 bit_left += BUF_BITS;
217 }
218 2869753 bit_left -= n;
219 #else
220
2/2
✓ Branch 0 taken 2309837184 times.
✓ Branch 1 taken 171638423 times.
2481475607 if (n < bit_left) {
221 2309837184 bit_buf = (bit_buf << n) | value;
222 2309837184 bit_left -= n;
223 } else {
224 171638423 bit_buf <<= bit_left;
225 171638423 bit_buf |= value >> (n - bit_left);
226
1/2
✓ Branch 0 taken 171638423 times.
✗ Branch 1 not taken.
171638423 if (s->buf_end - s->buf_ptr >= sizeof(BitBuf)) {
227 171638423 AV_WBBUF(s->buf_ptr, bit_buf);
228 171638423 s->buf_ptr += sizeof(BitBuf);
229 } else {
230 av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n");
231 av_assert2(0);
232 }
233 171638423 bit_left += BUF_BITS - n;
234 171638423 bit_buf = value;
235 }
236 #endif
237
238 2484345360 s->bit_buf = bit_buf;
239 2484345360 s->bit_left = bit_left;
240 2484345360 }
241
242 /**
243 * Write up to 31 bits into a bitstream.
244 * Use put_bits32 to write 32 bits.
245 */
246 2480616469 static inline void put_bits(PutBitContext *s, int n, BitBuf value)
247 {
248 av_assert2(n <= 31 && value < (1UL << n));
249 2480616469 put_bits_no_assert(s, n, value);
250 2480616469 }
251
252 8360325 static inline void put_bits_le(PutBitContext *s, int n, BitBuf value)
253 {
254 BitBuf bit_buf;
255 int bit_left;
256
257 av_assert2(n <= 31 && value < (1UL << n));
258
259 8360325 bit_buf = s->bit_buf;
260 8360325 bit_left = s->bit_left;
261
262 8360325 bit_buf |= value << (BUF_BITS - bit_left);
263
2/2
✓ Branch 0 taken 646946 times.
✓ Branch 1 taken 7713379 times.
8360325 if (n >= bit_left) {
264
1/2
✓ Branch 0 taken 646946 times.
✗ Branch 1 not taken.
646946 if (s->buf_end - s->buf_ptr >= sizeof(BitBuf)) {
265 646946 AV_WLBUF(s->buf_ptr, bit_buf);
266 646946 s->buf_ptr += sizeof(BitBuf);
267 } else {
268 av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n");
269 av_assert2(0);
270 }
271 646946 bit_buf = value >> bit_left;
272 646946 bit_left += BUF_BITS;
273 }
274 8360325 bit_left -= n;
275
276 8360325 s->bit_buf = bit_buf;
277 8360325 s->bit_left = bit_left;
278 8360325 }
279
280 198825911 static inline void put_sbits(PutBitContext *pb, int n, int32_t value)
281 {
282 av_assert2(n >= 0 && n <= 31);
283
284 198825911 put_bits(pb, n, av_mod_uintp2(value, n));
285 198825911 }
286
287 /**
288 * Write exactly 32 bits into a bitstream.
289 */
290 3728891 static void av_unused put_bits32(PutBitContext *s, uint32_t value)
291 {
292 BitBuf bit_buf;
293 int bit_left;
294
295
1/2
✓ Branch 0 taken 3728891 times.
✗ Branch 1 not taken.
3728891 if (BUF_BITS > 32) {
296 3728891 put_bits_no_assert(s, 32, value);
297 3728891 return;
298 }
299
300 bit_buf = s->bit_buf;
301 bit_left = s->bit_left;
302
303 #ifdef BITSTREAM_WRITER_LE
304 bit_buf |= (BitBuf)value << (BUF_BITS - bit_left);
305 if (s->buf_end - s->buf_ptr >= sizeof(BitBuf)) {
306 AV_WLBUF(s->buf_ptr, bit_buf);
307 s->buf_ptr += sizeof(BitBuf);
308 } else {
309 av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n");
310 av_assert2(0);
311 }
312 bit_buf = (uint64_t)value >> bit_left;
313 #else
314 bit_buf = (uint64_t)bit_buf << bit_left;
315 bit_buf |= (BitBuf)value >> (BUF_BITS - bit_left);
316 if (s->buf_end - s->buf_ptr >= sizeof(BitBuf)) {
317 AV_WBBUF(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 = value;
324 #endif
325
326 s->bit_buf = bit_buf;
327 s->bit_left = bit_left;
328 }
329
330 /**
331 * Write up to 64 bits into a bitstream.
332 */
333 8175 static inline void put_bits64(PutBitContext *s, int n, uint64_t value)
334 {
335 av_assert2((n == 64) || (n < 64 && value < (UINT64_C(1) << n)));
336
337
2/2
✓ Branch 0 taken 4079 times.
✓ Branch 1 taken 4096 times.
8175 if (n < 32)
338 4079 put_bits(s, n, value);
339
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4096 times.
4096 else if (n == 32)
340 put_bits32(s, value);
341
1/2
✓ Branch 0 taken 4096 times.
✗ Branch 1 not taken.
4096 else if (n < 64) {
342 4096 uint32_t lo = value & 0xffffffff;
343 4096 uint32_t hi = value >> 32;
344 #ifdef BITSTREAM_WRITER_LE
345 put_bits32(s, lo);
346 put_bits(s, n - 32, hi);
347 #else
348 4096 put_bits(s, n - 32, hi);
349 4096 put_bits32(s, lo);
350 #endif
351 } else {
352 uint32_t lo = value & 0xffffffff;
353 uint32_t hi = value >> 32;
354 #ifdef BITSTREAM_WRITER_LE
355 put_bits32(s, lo);
356 put_bits32(s, hi);
357 #else
358 put_bits32(s, hi);
359 put_bits32(s, lo);
360 #endif
361
362 }
363 8175 }
364
365 /**
366 * Return the pointer to the byte where the bitstream writer will put
367 * the next bit.
368 */
369 21972036 static inline uint8_t *put_bits_ptr(PutBitContext *s)
370 {
371 21972036 return s->buf_ptr;
372 }
373
374 /**
375 * Skip the given number of bytes.
376 * PutBitContext must be flushed & aligned to a byte boundary before calling this.
377 */
378 168086 static inline void skip_put_bytes(PutBitContext *s, int n)
379 {
380 av_assert2((put_bits_count(s) & 7) == 0);
381 av_assert2(s->bit_left == BUF_BITS);
382
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 168086 times.
168086 av_assert0(n <= s->buf_end - s->buf_ptr);
383 168086 s->buf_ptr += n;
384 168086 }
385
386 /**
387 * Skip the given number of bits.
388 * Must only be used if the actual values in the bitstream do not matter.
389 * If n is < 0 the behavior is undefined.
390 */
391 static inline void skip_put_bits(PutBitContext *s, int n)
392 {
393 unsigned bits = BUF_BITS - s->bit_left + n;
394 s->buf_ptr += sizeof(BitBuf) * (bits / BUF_BITS);
395 s->bit_left = BUF_BITS - (bits & (BUF_BITS - 1));
396 }
397
398 /**
399 * Change the end of the buffer.
400 *
401 * @param size the new size in bytes of the buffer where to put bits
402 */
403 4054 static inline void set_put_bits_buffer_size(PutBitContext *s, int size)
404 {
405
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4054 times.
4054 av_assert0(size <= INT_MAX/8 - BUF_BITS);
406 4054 s->buf_end = s->buf + size;
407 4054 }
408
409 /**
410 * Pad the bitstream with zeros up to the next byte boundary.
411 */
412 402173 static inline void align_put_bits(PutBitContext *s)
413 {
414 402173 put_bits(s, s->bit_left & 7, 0);
415 402173 }
416
417 #undef AV_WBBUF
418 #undef AV_WLBUF
419
420 #endif /* AVCODEC_PUT_BITS_H */
421