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 | #else | ||
43 | typedef uint32_t BitBuf; | ||
44 | #define AV_WBBUF AV_WB32 | ||
45 | #define AV_WLBUF AV_WL32 | ||
46 | #endif | ||
47 | |||
48 | static const int BUF_BITS = 8 * sizeof(BitBuf); | ||
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 | 27326520 | 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 27326520 times.
|
27326520 | if (buffer_size < 0) { |
66 | ✗ | buffer_size = 0; | |
67 | ✗ | buffer = NULL; | |
68 | } | ||
69 | |||
70 | 27326520 | s->buf = buffer; | |
71 | 27326520 | s->buf_end = s->buf + buffer_size; | |
72 | 27326520 | s->buf_ptr = s->buf; | |
73 | 27326520 | s->bit_left = BUF_BITS; | |
74 | 27326520 | s->bit_buf = 0; | |
75 | 27326520 | } | |
76 | |||
77 | /** | ||
78 | * @return the total number of bits written to the bitstream. | ||
79 | */ | ||
80 | 17644147 | static inline int put_bits_count(PutBitContext *s) | |
81 | { | ||
82 | 17644147 | 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 | 271312 | static inline int put_bytes_output(const PutBitContext *s) | |
90 | { | ||
91 | av_assert2(s->bit_left == BUF_BITS); | ||
92 | 271312 | 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 | 1632305 | static inline int put_bytes_count(const PutBitContext *s, int round_up) | |
101 | { | ||
102 |
2/2✓ Branch 0 taken 1491144 times.
✓ Branch 1 taken 141161 times.
|
1632305 | 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 | 33 | 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 33 times.
|
33 | av_assert0(8*buffer_size >= put_bits_count(s)); |
116 | |||
117 | 33 | s->buf_end = buffer + buffer_size; | |
118 | 33 | s->buf_ptr = buffer + (s->buf_ptr - s->buf); | |
119 | 33 | s->buf = buffer; | |
120 | 33 | } | |
121 | |||
122 | /** | ||
123 | * @return the number of bits available in the bitstream. | ||
124 | */ | ||
125 | 287442566 | static inline int put_bits_left(PutBitContext* s) | |
126 | { | ||
127 | 287442566 | 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 | 35704879 | static inline int put_bytes_left(const PutBitContext *s, int round_up) | |
136 | { | ||
137 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 35704879 times.
|
35704879 | 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 | 29483134 | static inline void flush_put_bits(PutBitContext *s) | |
144 | { | ||
145 | #ifndef BITSTREAM_WRITER_LE | ||
146 |
2/2✓ Branch 0 taken 26498797 times.
✓ Branch 1 taken 2983317 times.
|
29482114 | if (s->bit_left < BUF_BITS) |
147 | 26498797 | s->bit_buf <<= s->bit_left; | |
148 | #endif | ||
149 |
2/2✓ Branch 0 taken 91217785 times.
✓ Branch 1 taken 29483134 times.
|
120700919 | while (s->bit_left < BUF_BITS) { |
150 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 91217785 times.
|
91217785 | 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 | 91214369 | *s->buf_ptr++ = s->bit_buf >> (BUF_BITS - 8); | |
156 | 91214369 | s->bit_buf <<= 8; | |
157 | #endif | ||
158 | 91217785 | s->bit_left += 8; | |
159 | } | ||
160 | 29483134 | s->bit_left = BUF_BITS; | |
161 | 29483134 | s->bit_buf = 0; | |
162 | 29483134 | } | |
163 | |||
164 | 3063 | static inline void flush_put_bits_le(PutBitContext *s) | |
165 | { | ||
166 |
2/2✓ Branch 0 taken 13560 times.
✓ Branch 1 taken 3063 times.
|
16623 | while (s->bit_left < BUF_BITS) { |
167 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 13560 times.
|
13560 | av_assert0(s->buf_ptr < s->buf_end); |
168 | 13560 | *s->buf_ptr++ = s->bit_buf; | |
169 | 13560 | s->bit_buf >>= 8; | |
170 | 13560 | 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 | 2482464581 | static inline void put_bits_no_assert(PutBitContext *s, int n, BitBuf value) | |
198 | { | ||
199 | BitBuf bit_buf; | ||
200 | int bit_left; | ||
201 | |||
202 | 2482464581 | bit_buf = s->bit_buf; | |
203 | 2482464581 | bit_left = s->bit_left; | |
204 | |||
205 | /* XXX: optimize */ | ||
206 | #ifdef BITSTREAM_WRITER_LE | ||
207 | 2869862 | bit_buf |= value << (BUF_BITS - bit_left); | |
208 |
2/2✓ Branch 0 taken 137505 times.
✓ Branch 1 taken 2732357 times.
|
2869862 | 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 | 2869862 | bit_left -= n; | |
220 | #else | ||
221 |
2/2✓ Branch 0 taken 2299369170 times.
✓ Branch 1 taken 180225549 times.
|
2479594719 | if (n < bit_left) { |
222 | 2299369170 | bit_buf = (bit_buf << n) | value; | |
223 | 2299369170 | bit_left -= n; | |
224 | } else { | ||
225 | 180225549 | bit_buf <<= bit_left; | |
226 | 180225549 | bit_buf |= value >> (n - bit_left); | |
227 |
1/2✓ Branch 0 taken 180225549 times.
✗ Branch 1 not taken.
|
180225549 | if (s->buf_end - s->buf_ptr >= sizeof(BitBuf)) { |
228 | 180225549 | AV_WBBUF(s->buf_ptr, bit_buf); | |
229 | 180225549 | 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 | 180225549 | bit_left += BUF_BITS - n; | |
235 | 180225549 | bit_buf = value; | |
236 | } | ||
237 | #endif | ||
238 | |||
239 | 2482464581 | s->bit_buf = bit_buf; | |
240 | 2482464581 | s->bit_left = bit_left; | |
241 | 2482464581 | } | |
242 | |||
243 | /** | ||
244 | * Write up to 31 bits into a bitstream. | ||
245 | * Use put_bits32 to write 32 bits. | ||
246 | */ | ||
247 | 2478120178 | static inline void put_bits(PutBitContext *s, int n, BitBuf value) | |
248 | { | ||
249 |
2/4✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 193 times.
|
193 | av_assert2(n <= 31 && value < (1UL << n)); |
250 | 2478120178 | put_bits_no_assert(s, n, value); | |
251 | 2478120178 | } | |
252 | |||
253 | 17270667 | 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 | 17270667 | bit_buf = s->bit_buf; | |
261 | 17270667 | bit_left = s->bit_left; | |
262 | |||
263 | 17270667 | bit_buf |= value << (BUF_BITS - bit_left); | |
264 |
2/2✓ Branch 0 taken 1516709 times.
✓ Branch 1 taken 15753958 times.
|
17270667 | if (n >= bit_left) { |
265 |
1/2✓ Branch 0 taken 1516709 times.
✗ Branch 1 not taken.
|
1516709 | if (s->buf_end - s->buf_ptr >= sizeof(BitBuf)) { |
266 | 1516709 | AV_WLBUF(s->buf_ptr, bit_buf); | |
267 | 1516709 | 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 | 1516709 | bit_buf = value >> bit_left; | |
273 | 1516709 | bit_left += BUF_BITS; | |
274 | } | ||
275 | 17270667 | bit_left -= n; | |
276 | |||
277 | 17270667 | s->bit_buf = bit_buf; | |
278 | 17270667 | s->bit_left = bit_left; | |
279 | 17270667 | } | |
280 | |||
281 | 243103554 | static inline void put_sbits(PutBitContext *pb, int n, int32_t value) | |
282 | { | ||
283 |
2/4✓ Branch 0 taken 45 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 45 times.
|
45 | av_assert2(n >= 0 && n <= 31); |
284 | |||
285 | 243103554 | put_bits(pb, n, av_zero_extend(value, n)); | |
286 | 243103554 | } | |
287 | |||
288 | /** | ||
289 | * Write exactly 32 bits into a bitstream. | ||
290 | */ | ||
291 | 4344403 | static void av_unused put_bits32(PutBitContext *s, uint32_t value) | |
292 | { | ||
293 | BitBuf bit_buf; | ||
294 | int bit_left; | ||
295 | |||
296 |
1/2✓ Branch 0 taken 4344403 times.
✗ Branch 1 not taken.
|
4344403 | if (BUF_BITS > 32) { |
297 | 4344403 | put_bits_no_assert(s, 32, value); | |
298 | 4344403 | 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 64 bits into a bitstream. | ||
333 | */ | ||
334 | 32329929 | static inline void put_bits64(PutBitContext *s, int n, uint64_t value) | |
335 | { | ||
336 |
3/6✓ Branch 0 taken 86 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 86 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 86 times.
|
86 | av_assert2((n == 64) || (n < 64 && value < (UINT64_C(1) << n))); |
337 | |||
338 |
2/2✓ Branch 0 taken 32321060 times.
✓ Branch 1 taken 8869 times.
|
32329929 | if (n < 32) |
339 | 32321060 | put_bits(s, n, value); | |
340 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8868 times.
|
8869 | else if (n == 32) |
341 | 1 | put_bits32(s, value); | |
342 |
1/2✓ Branch 0 taken 8868 times.
✗ Branch 1 not taken.
|
8868 | else if (n < 64) { |
343 | 8868 | uint32_t lo = value & 0xffffffff; | |
344 | 8868 | uint32_t hi = value >> 32; | |
345 | #ifdef BITSTREAM_WRITER_LE | ||
346 | 6 | put_bits32(s, lo); | |
347 | 6 | put_bits(s, n - 32, hi); | |
348 | #else | ||
349 | 8862 | put_bits(s, n - 32, hi); | |
350 | 8862 | put_bits32(s, lo); | |
351 | #endif | ||
352 | } else { | ||
353 | ✗ | uint32_t lo = value & 0xffffffff; | |
354 | ✗ | uint32_t hi = value >> 32; | |
355 | #ifdef BITSTREAM_WRITER_LE | ||
356 | ✗ | put_bits32(s, lo); | |
357 | ✗ | put_bits32(s, hi); | |
358 | #else | ||
359 | ✗ | put_bits32(s, hi); | |
360 | ✗ | put_bits32(s, lo); | |
361 | #endif | ||
362 | |||
363 | } | ||
364 | 32329929 | } | |
365 | |||
366 | 4624 | static inline void put_sbits63(PutBitContext *pb, int n, int64_t value) | |
367 | { | ||
368 | av_assert2(n >= 0 && n < 64); | ||
369 | |||
370 | 4624 | put_bits64(pb, n, (uint64_t)(value) & (~(UINT64_MAX << n))); | |
371 | 4624 | } | |
372 | |||
373 | /** | ||
374 | * Return the pointer to the byte where the bitstream writer will put | ||
375 | * the next bit. | ||
376 | */ | ||
377 | 23195410 | static inline uint8_t *put_bits_ptr(PutBitContext *s) | |
378 | { | ||
379 | 23195410 | return s->buf_ptr; | |
380 | } | ||
381 | |||
382 | /** | ||
383 | * Skip the given number of bytes. | ||
384 | * PutBitContext must be flushed & aligned to a byte boundary before calling this. | ||
385 | */ | ||
386 | 139582 | static inline void skip_put_bytes(PutBitContext *s, int n) | |
387 | { | ||
388 | av_assert2((put_bits_count(s) & 7) == 0); | ||
389 | av_assert2(s->bit_left == BUF_BITS); | ||
390 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 139582 times.
|
139582 | av_assert0(n <= s->buf_end - s->buf_ptr); |
391 | 139582 | s->buf_ptr += n; | |
392 | 139582 | } | |
393 | |||
394 | /** | ||
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. | ||
398 | */ | ||
399 | 60 | static inline void skip_put_bits(PutBitContext *s, int n) | |
400 | { | ||
401 | 60 | unsigned bits = BUF_BITS - s->bit_left + n; | |
402 | 60 | s->buf_ptr += sizeof(BitBuf) * (bits / BUF_BITS); | |
403 | 60 | s->bit_left = BUF_BITS - (bits & (BUF_BITS - 1)); | |
404 | 60 | } | |
405 | |||
406 | /** | ||
407 | * Change the end of the buffer. | ||
408 | * | ||
409 | * @param size the new size in bytes of the buffer where to put bits | ||
410 | */ | ||
411 | 5128 | static inline void set_put_bits_buffer_size(PutBitContext *s, int size) | |
412 | { | ||
413 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5128 times.
|
5128 | av_assert0(size <= INT_MAX/8 - BUF_BITS); |
414 | 5128 | s->buf_end = s->buf + size; | |
415 | 5128 | } | |
416 | |||
417 | /** | ||
418 | * Pad the bitstream with zeros up to the next byte boundary. | ||
419 | */ | ||
420 | 316142 | static inline void align_put_bits(PutBitContext *s) | |
421 | { | ||
422 | 316142 | put_bits(s, s->bit_left & 7, 0); | |
423 | 316142 | } | |
424 | |||
425 | #undef AV_WBBUF | ||
426 | #undef AV_WLBUF | ||
427 | |||
428 | #endif /* AVCODEC_PUT_BITS_H */ | ||
429 |