/src/ffmpeg/libavcodec/put_bits.h
Line | Count | 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 | 0 | #define AV_WBBUF AV_WB64 |
41 | | #define AV_WLBUF AV_WL64 |
42 | 0 | #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 | | static inline void init_put_bits(PutBitContext *s, uint8_t *buffer, |
63 | | int buffer_size) |
64 | 0 | { |
65 | 0 | if (buffer_size < 0) { |
66 | 0 | buffer_size = 0; |
67 | 0 | buffer = NULL; |
68 | 0 | } |
69 | |
|
70 | 0 | s->buf = buffer; |
71 | 0 | s->buf_end = s->buf + buffer_size; |
72 | 0 | s->buf_ptr = s->buf; |
73 | 0 | s->bit_left = BUF_BITS; |
74 | 0 | s->bit_buf = 0; |
75 | 0 | } |
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 | | static inline void put_bits_assume_flushed(const PutBitContext *s) |
83 | 0 | { |
84 | 0 | av_assume(s->bit_left == BUF_BITS); |
85 | 0 | } |
86 | | |
87 | | /** |
88 | | * @return the total number of bits written to the bitstream. |
89 | | */ |
90 | | static inline int put_bits_count(PutBitContext *s) |
91 | 0 | { |
92 | 0 | return (s->buf_ptr - s->buf) * 8 + BUF_BITS - s->bit_left; |
93 | 0 | } |
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 | | static inline int put_bytes_output(const PutBitContext *s) |
100 | 0 | { |
101 | 0 | av_assert2(s->bit_left == BUF_BITS); |
102 | 0 | return s->buf_ptr - s->buf; |
103 | 0 | } |
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 | | static inline int put_bytes_count(const PutBitContext *s, int round_up) |
111 | 0 | { |
112 | 0 | return s->buf_ptr - s->buf + ((BUF_BITS - s->bit_left + (round_up ? 7 : 0)) >> 3); |
113 | 0 | } |
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 | | static inline void rebase_put_bits(PutBitContext *s, uint8_t *buffer, |
123 | | int buffer_size) |
124 | 0 | { |
125 | 0 | av_assert0(8*buffer_size >= put_bits_count(s)); |
126 | 0 |
|
127 | 0 | s->buf_end = buffer + buffer_size; |
128 | 0 | s->buf_ptr = buffer + (s->buf_ptr - s->buf); |
129 | 0 | s->buf = buffer; |
130 | 0 | } |
131 | | |
132 | | /** |
133 | | * @return the number of bits available in the bitstream. |
134 | | */ |
135 | | static inline int put_bits_left(PutBitContext* s) |
136 | 0 | { |
137 | 0 | return (s->buf_end - s->buf_ptr) * 8 - BUF_BITS + s->bit_left; |
138 | 0 | } |
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 | | static inline int put_bytes_left(const PutBitContext *s, int round_up) |
146 | 0 | { |
147 | 0 | return s->buf_end - s->buf_ptr - ((BUF_BITS - s->bit_left + (round_up ? 7 : 0)) >> 3); |
148 | 0 | } |
149 | | |
150 | | /** |
151 | | * Pad the end of the output stream with zeros. |
152 | | */ |
153 | | static inline void flush_put_bits(PutBitContext *s) |
154 | 0 | { |
155 | 0 | #ifndef BITSTREAM_WRITER_LE |
156 | 0 | if (s->bit_left < BUF_BITS) |
157 | 0 | s->bit_buf <<= s->bit_left; |
158 | 0 | #endif |
159 | 0 | while (s->bit_left < BUF_BITS) { |
160 | 0 | 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 | 0 | *s->buf_ptr++ = s->bit_buf >> (BUF_BITS - 8); |
166 | 0 | s->bit_buf <<= 8; |
167 | 0 | #endif |
168 | 0 | s->bit_left += 8; |
169 | 0 | } |
170 | 0 | s->bit_left = BUF_BITS; |
171 | 0 | s->bit_buf = 0; |
172 | 0 | } |
173 | | |
174 | | static inline void flush_put_bits_le(PutBitContext *s) |
175 | 0 | { |
176 | 0 | while (s->bit_left < BUF_BITS) { |
177 | 0 | av_assert0(s->buf_ptr < s->buf_end); |
178 | 0 | *s->buf_ptr++ = s->bit_buf; |
179 | 0 | s->bit_buf >>= 8; |
180 | 0 | s->bit_left += 8; |
181 | 0 | } |
182 | 0 | s->bit_left = BUF_BITS; |
183 | 0 | s->bit_buf = 0; |
184 | 0 | } |
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 | | static inline void put_bits_no_assert(PutBitContext *s, int n, BitBuf value) |
208 | 0 | { |
209 | 0 | BitBuf bit_buf; |
210 | 0 | int bit_left; |
211 | |
|
212 | 0 | bit_buf = s->bit_buf; |
213 | 0 | 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 | 0 | if (n < bit_left) { |
232 | 0 | bit_buf = (bit_buf << n) | value; |
233 | 0 | bit_left -= n; |
234 | 0 | } else { |
235 | 0 | bit_buf <<= bit_left; |
236 | 0 | bit_buf |= value >> (n - bit_left); |
237 | 0 | if (s->buf_end - s->buf_ptr >= sizeof(BitBuf)) { |
238 | 0 | AV_WBBUF(s->buf_ptr, bit_buf); |
239 | 0 | s->buf_ptr += sizeof(BitBuf); |
240 | 0 | } else { |
241 | 0 | av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n"); |
242 | 0 | av_assert2(0); |
243 | 0 | } |
244 | 0 | bit_left += BUF_BITS - n; |
245 | 0 | bit_buf = value; |
246 | 0 | } |
247 | 0 | #endif |
248 | |
|
249 | 0 | s->bit_buf = bit_buf; |
250 | 0 | s->bit_left = bit_left; |
251 | 0 | } |
252 | | |
253 | | /** |
254 | | * Write up to 31 bits into a bitstream. |
255 | | * Use put_bits32 to write 32 bits. |
256 | | */ |
257 | | static inline void put_bits(PutBitContext *s, int n, BitBuf value) |
258 | 0 | { |
259 | 0 | av_assert2(n <= 31 && value < (BitBuf)(1U << n)); |
260 | 0 | put_bits_no_assert(s, n, value); |
261 | 0 | } |
262 | | |
263 | | static inline void put_bits_le(PutBitContext *s, int n, BitBuf value) |
264 | 0 | { |
265 | 0 | BitBuf bit_buf; |
266 | 0 | int bit_left; |
267 | 0 |
|
268 | 0 | av_assert2(n <= 31 && value < (BitBuf)(1U << n)); |
269 | 0 |
|
270 | 0 | bit_buf = s->bit_buf; |
271 | 0 | bit_left = s->bit_left; |
272 | 0 |
|
273 | 0 | bit_buf |= value << (BUF_BITS - bit_left); |
274 | 0 | if (n >= bit_left) { |
275 | 0 | if (s->buf_end - s->buf_ptr >= sizeof(BitBuf)) { |
276 | 0 | AV_WLBUF(s->buf_ptr, bit_buf); |
277 | 0 | s->buf_ptr += sizeof(BitBuf); |
278 | 0 | } else { |
279 | 0 | av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n"); |
280 | 0 | av_assert2(0); |
281 | 0 | } |
282 | 0 | bit_buf = value >> bit_left; |
283 | 0 | bit_left += BUF_BITS; |
284 | 0 | } |
285 | 0 | bit_left -= n; |
286 | 0 |
|
287 | 0 | s->bit_buf = bit_buf; |
288 | 0 | s->bit_left = bit_left; |
289 | 0 | } |
290 | | |
291 | | static inline void put_sbits(PutBitContext *pb, int n, int32_t value) |
292 | 0 | { |
293 | 0 | av_assert2(n >= 0 && n <= 31); |
294 | 0 |
|
295 | 0 | put_bits(pb, n, av_zero_extend(value, n)); |
296 | 0 | } |
297 | | |
298 | | /** |
299 | | * Write exactly 32 bits into a bitstream. |
300 | | */ |
301 | | av_unused static void put_bits32(PutBitContext *s, uint32_t value) |
302 | 0 | { |
303 | 0 | BitBuf bit_buf; |
304 | 0 | int bit_left; |
305 | 0 |
|
306 | 0 | if (BUF_BITS > 32) { |
307 | 0 | put_bits_no_assert(s, 32, value); |
308 | 0 | return; |
309 | 0 | } |
310 | 0 |
|
311 | 0 | bit_buf = s->bit_buf; |
312 | 0 | bit_left = s->bit_left; |
313 | 0 |
|
314 | 0 | #ifdef BITSTREAM_WRITER_LE |
315 | 0 | bit_buf |= (BitBuf)value << (BUF_BITS - bit_left); |
316 | 0 | if (s->buf_end - s->buf_ptr >= sizeof(BitBuf)) { |
317 | 0 | AV_WLBUF(s->buf_ptr, bit_buf); |
318 | 0 | s->buf_ptr += sizeof(BitBuf); |
319 | 0 | } else { |
320 | 0 | av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n"); |
321 | 0 | av_assert2(0); |
322 | 0 | } |
323 | 0 | bit_buf = (uint64_t)value >> bit_left; |
324 | 0 | #else |
325 | 0 | bit_buf = (uint64_t)bit_buf << bit_left; |
326 | 0 | bit_buf |= (BitBuf)value >> (BUF_BITS - bit_left); |
327 | 0 | if (s->buf_end - s->buf_ptr >= sizeof(BitBuf)) { |
328 | 0 | AV_WBBUF(s->buf_ptr, bit_buf); |
329 | 0 | s->buf_ptr += sizeof(BitBuf); |
330 | 0 | } else { |
331 | 0 | av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n"); |
332 | 0 | av_assert2(0); |
333 | 0 | } |
334 | 0 | bit_buf = value; |
335 | 0 | #endif |
336 | 0 |
|
337 | 0 | s->bit_buf = bit_buf; |
338 | 0 | s->bit_left = bit_left; |
339 | 0 | } |
340 | | |
341 | | /** |
342 | | * Write up to 63 bits into a bitstream. |
343 | | */ |
344 | | static inline void put_bits63(PutBitContext *s, int n, uint64_t value) |
345 | 0 | { |
346 | 0 | av_assert2(n < 64U && value < (UINT64_C(1) << n)); |
347 | 0 |
|
348 | 0 | #if BUF_BITS >= 64 |
349 | 0 | put_bits_no_assert(s, n, value); |
350 | 0 | #else |
351 | 0 | if (n < 32) |
352 | 0 | put_bits(s, n, value); |
353 | 0 | else if (n == 32) |
354 | 0 | put_bits32(s, value); |
355 | 0 | else if (n < 64) { |
356 | 0 | uint32_t lo = value & 0xffffffff; |
357 | 0 | uint32_t hi = value >> 32; |
358 | 0 | #ifdef BITSTREAM_WRITER_LE |
359 | 0 | put_bits32(s, lo); |
360 | 0 | put_bits(s, n - 32, hi); |
361 | 0 | #else |
362 | 0 | put_bits(s, n - 32, hi); |
363 | 0 | put_bits32(s, lo); |
364 | 0 | #endif |
365 | 0 | } |
366 | 0 | #endif |
367 | 0 | } |
368 | | |
369 | | /** |
370 | | * Write up to 64 bits into a bitstream. |
371 | | */ |
372 | | static inline void put_bits64(PutBitContext *s, int n, uint64_t value) |
373 | 0 | { |
374 | 0 | av_assert2((n == 64) || (n < 64 && value < (UINT64_C(1) << n))); |
375 | 0 |
|
376 | 0 | if (n < 64) { |
377 | 0 | put_bits63(s, n, value); |
378 | 0 | } else { |
379 | 0 | uint32_t lo = value & 0xffffffff; |
380 | 0 | uint32_t hi = value >> 32; |
381 | 0 | #ifdef BITSTREAM_WRITER_LE |
382 | 0 | put_bits32(s, lo); |
383 | 0 | put_bits32(s, hi); |
384 | 0 | #else |
385 | 0 | put_bits32(s, hi); |
386 | 0 | put_bits32(s, lo); |
387 | 0 | #endif |
388 | 0 | } |
389 | 0 | } |
390 | | |
391 | | static inline void put_sbits63(PutBitContext *pb, int n, int64_t value) |
392 | 0 | { |
393 | 0 | av_assert2(n >= 0 && n < 64); |
394 | 0 |
|
395 | 0 | put_bits63(pb, n, (uint64_t)(value) & (~(UINT64_MAX << n))); |
396 | 0 | } |
397 | | |
398 | | /** |
399 | | * Return the pointer to the byte where the bitstream writer will put |
400 | | * the next bit. |
401 | | */ |
402 | | static inline uint8_t *put_bits_ptr(PutBitContext *s) |
403 | 0 | { |
404 | 0 | return s->buf_ptr; |
405 | 0 | } |
406 | | |
407 | | /** |
408 | | * Skip the given number of bytes. |
409 | | * PutBitContext must be flushed & aligned to a byte boundary before calling this. |
410 | | */ |
411 | | static inline void skip_put_bytes(PutBitContext *s, int n) |
412 | 0 | { |
413 | 0 | av_assert2((put_bits_count(s) & 7) == 0); |
414 | 0 | av_assert2(s->bit_left == BUF_BITS); |
415 | 0 | av_assert0(n <= s->buf_end - s->buf_ptr); |
416 | 0 | s->buf_ptr += n; |
417 | 0 | } |
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 | | static inline void skip_put_bits(PutBitContext *s, int n) |
425 | 0 | { |
426 | 0 | unsigned bits = BUF_BITS - s->bit_left + n; |
427 | 0 | s->buf_ptr += sizeof(BitBuf) * (bits / BUF_BITS); |
428 | 0 | s->bit_left = BUF_BITS - (bits & (BUF_BITS - 1)); |
429 | 0 | } |
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 | | static inline void set_put_bits_buffer_size(PutBitContext *s, int size) |
437 | 0 | { |
438 | 0 | av_assert0(size <= INT_MAX/8 - BUF_BITS); |
439 | 0 | s->buf_end = s->buf + size; |
440 | 0 | } |
441 | | |
442 | | /** |
443 | | * Pad the bitstream with zeros up to the next byte boundary. |
444 | | */ |
445 | | static inline void align_put_bits(PutBitContext *s) |
446 | 0 | { |
447 | 0 | put_bits(s, s->bit_left & 7, 0); |
448 | 0 | } |
449 | | |
450 | | #undef AV_WBBUF |
451 | | #undef AV_WLBUF |
452 | | |
453 | | #endif /* AVCODEC_PUT_BITS_H */ |