blob: 68ed3911957487b504c3e1c8bcb1b4f089aa6a60
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 "libavutil/intreadwrite.h" |
33 | #include "libavutil/avassert.h" |
34 | |
35 | typedef struct PutBitContext { |
36 | uint32_t bit_buf; |
37 | int bit_left; |
38 | uint8_t *buf, *buf_ptr, *buf_end; |
39 | int size_in_bits; |
40 | } PutBitContext; |
41 | |
42 | /** |
43 | * Initialize the PutBitContext s. |
44 | * |
45 | * @param buffer the buffer where to put bits |
46 | * @param buffer_size the size in bytes of buffer |
47 | */ |
48 | static inline void init_put_bits(PutBitContext *s, uint8_t *buffer, |
49 | int buffer_size) |
50 | { |
51 | if (buffer_size < 0) { |
52 | buffer_size = 0; |
53 | buffer = NULL; |
54 | } |
55 | |
56 | s->size_in_bits = 8 * buffer_size; |
57 | s->buf = buffer; |
58 | s->buf_end = s->buf + buffer_size; |
59 | s->buf_ptr = s->buf; |
60 | s->bit_left = 32; |
61 | s->bit_buf = 0; |
62 | } |
63 | |
64 | /** |
65 | * Rebase the bit writer onto a reallocated buffer. |
66 | * |
67 | * @param buffer the buffer where to put bits |
68 | * @param buffer_size the size in bytes of buffer, |
69 | * must be larger than the previous size |
70 | */ |
71 | static inline void rebase_put_bits(PutBitContext *s, uint8_t *buffer, |
72 | int buffer_size) |
73 | { |
74 | av_assert0(8*buffer_size > s->size_in_bits); |
75 | |
76 | s->buf_end = buffer + buffer_size; |
77 | s->buf_ptr = buffer + (s->buf_ptr - s->buf); |
78 | s->buf = buffer; |
79 | s->size_in_bits = 8 * buffer_size; |
80 | } |
81 | |
82 | /** |
83 | * @return the total number of bits written to the bitstream. |
84 | */ |
85 | static inline int put_bits_count(PutBitContext *s) |
86 | { |
87 | return (s->buf_ptr - s->buf) * 8 + 32 - s->bit_left; |
88 | } |
89 | |
90 | /** |
91 | * @return the number of bits available in the bitstream. |
92 | */ |
93 | static inline int put_bits_left(PutBitContext* s) |
94 | { |
95 | return (s->buf_end - s->buf_ptr) * 8 - 32 + s->bit_left; |
96 | } |
97 | |
98 | /** |
99 | * Pad the end of the output stream with zeros. |
100 | */ |
101 | static inline void flush_put_bits(PutBitContext *s) |
102 | { |
103 | #ifndef BITSTREAM_WRITER_LE |
104 | if (s->bit_left < 32) |
105 | s->bit_buf <<= s->bit_left; |
106 | #endif |
107 | while (s->bit_left < 32) { |
108 | av_assert0(s->buf_ptr < s->buf_end); |
109 | #ifdef BITSTREAM_WRITER_LE |
110 | *s->buf_ptr++ = s->bit_buf; |
111 | s->bit_buf >>= 8; |
112 | #else |
113 | *s->buf_ptr++ = s->bit_buf >> 24; |
114 | s->bit_buf <<= 8; |
115 | #endif |
116 | s->bit_left += 8; |
117 | } |
118 | s->bit_left = 32; |
119 | s->bit_buf = 0; |
120 | } |
121 | |
122 | #ifdef BITSTREAM_WRITER_LE |
123 | #define avpriv_align_put_bits align_put_bits_unsupported_here |
124 | #define avpriv_put_string ff_put_string_unsupported_here |
125 | #define avpriv_copy_bits avpriv_copy_bits_unsupported_here |
126 | #else |
127 | /** |
128 | * Pad the bitstream with zeros up to the next byte boundary. |
129 | */ |
130 | void avpriv_align_put_bits(PutBitContext *s); |
131 | |
132 | /** |
133 | * Put the string string in the bitstream. |
134 | * |
135 | * @param terminate_string 0-terminates the written string if value is 1 |
136 | */ |
137 | void avpriv_put_string(PutBitContext *pb, const char *string, |
138 | int terminate_string); |
139 | |
140 | /** |
141 | * Copy the content of src to the bitstream. |
142 | * |
143 | * @param length the number of bits of src to copy |
144 | */ |
145 | void avpriv_copy_bits(PutBitContext *pb, const uint8_t *src, int length); |
146 | #endif |
147 | |
148 | /** |
149 | * Write up to 31 bits into a bitstream. |
150 | * Use put_bits32 to write 32 bits. |
151 | */ |
152 | static inline void put_bits(PutBitContext *s, int n, unsigned int value) |
153 | { |
154 | unsigned int bit_buf; |
155 | int bit_left; |
156 | |
157 | av_assert2(n <= 31 && value < (1U << n)); |
158 | |
159 | bit_buf = s->bit_buf; |
160 | bit_left = s->bit_left; |
161 | |
162 | /* XXX: optimize */ |
163 | #ifdef BITSTREAM_WRITER_LE |
164 | bit_buf |= value << (32 - bit_left); |
165 | if (n >= bit_left) { |
166 | if (3 < s->buf_end - s->buf_ptr) { |
167 | AV_WL32(s->buf_ptr, bit_buf); |
168 | s->buf_ptr += 4; |
169 | } else { |
170 | av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n"); |
171 | av_assert2(0); |
172 | } |
173 | bit_buf = value >> bit_left; |
174 | bit_left += 32; |
175 | } |
176 | bit_left -= n; |
177 | #else |
178 | if (n < bit_left) { |
179 | bit_buf = (bit_buf << n) | value; |
180 | bit_left -= n; |
181 | } else { |
182 | bit_buf <<= bit_left; |
183 | bit_buf |= value >> (n - bit_left); |
184 | if (3 < s->buf_end - s->buf_ptr) { |
185 | AV_WB32(s->buf_ptr, bit_buf); |
186 | s->buf_ptr += 4; |
187 | } else { |
188 | av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n"); |
189 | av_assert2(0); |
190 | } |
191 | bit_left += 32 - n; |
192 | bit_buf = value; |
193 | } |
194 | #endif |
195 | |
196 | s->bit_buf = bit_buf; |
197 | s->bit_left = bit_left; |
198 | } |
199 | |
200 | static inline void put_sbits(PutBitContext *pb, int n, int32_t value) |
201 | { |
202 | av_assert2(n >= 0 && n <= 31); |
203 | |
204 | put_bits(pb, n, av_mod_uintp2(value, n)); |
205 | } |
206 | |
207 | /** |
208 | * Write exactly 32 bits into a bitstream. |
209 | */ |
210 | static void av_unused put_bits32(PutBitContext *s, uint32_t value) |
211 | { |
212 | int lo = value & 0xffff; |
213 | int hi = value >> 16; |
214 | #ifdef BITSTREAM_WRITER_LE |
215 | put_bits(s, 16, lo); |
216 | put_bits(s, 16, hi); |
217 | #else |
218 | put_bits(s, 16, hi); |
219 | put_bits(s, 16, lo); |
220 | #endif |
221 | } |
222 | |
223 | /** |
224 | * Return the pointer to the byte where the bitstream writer will put |
225 | * the next bit. |
226 | */ |
227 | static inline uint8_t *put_bits_ptr(PutBitContext *s) |
228 | { |
229 | return s->buf_ptr; |
230 | } |
231 | |
232 | /** |
233 | * Skip the given number of bytes. |
234 | * PutBitContext must be flushed & aligned to a byte boundary before calling this. |
235 | */ |
236 | static inline void skip_put_bytes(PutBitContext *s, int n) |
237 | { |
238 | av_assert2((put_bits_count(s) & 7) == 0); |
239 | av_assert2(s->bit_left == 32); |
240 | av_assert0(n <= s->buf_end - s->buf_ptr); |
241 | s->buf_ptr += n; |
242 | } |
243 | |
244 | /** |
245 | * Skip the given number of bits. |
246 | * Must only be used if the actual values in the bitstream do not matter. |
247 | * If n is 0 the behavior is undefined. |
248 | */ |
249 | static inline void skip_put_bits(PutBitContext *s, int n) |
250 | { |
251 | s->bit_left -= n; |
252 | s->buf_ptr -= 4 * (s->bit_left >> 5); |
253 | s->bit_left &= 31; |
254 | } |
255 | |
256 | /** |
257 | * Change the end of the buffer. |
258 | * |
259 | * @param size the new size in bytes of the buffer where to put bits |
260 | */ |
261 | static inline void set_put_bits_buffer_size(PutBitContext *s, int size) |
262 | { |
263 | av_assert0(size <= INT_MAX/8 - 32); |
264 | s->buf_end = s->buf + size; |
265 | s->size_in_bits = 8*size; |
266 | } |
267 | |
268 | #endif /* AVCODEC_PUT_BITS_H */ |
269 |