blob: 8b2aa15315d22c4d165e1463d39b3a75d5372c90
1 | #ifndef AVCODEC_PUT_BITS_H |
2 | #define AVCODEC_PUT_BITS_H |
3 | |
4 | #include <linux/kernel.h> |
5 | #include <linux/types.h> |
6 | #include "common.h" |
7 | |
8 | struct put_bits_context { |
9 | u32 bit_buf; |
10 | int bit_left; |
11 | u8 *buf; |
12 | u8 *buf_ptr; |
13 | u8 *buf_end; |
14 | int size_in_bits; |
15 | }; |
16 | |
17 | /** |
18 | * Initialize the struct put_bits_context s. |
19 | * |
20 | * @param buffer the buffer where to put bits |
21 | * @param buffer_size the size in bytes of buffer |
22 | */ |
23 | static inline void init_put_bits(struct put_bits_context *s, |
24 | u8 *buffer, int buffer_size) |
25 | { |
26 | if (buffer_size < 0) { |
27 | buffer_size = 0; |
28 | buffer = NULL; |
29 | } |
30 | |
31 | s->size_in_bits = 8 * buffer_size; |
32 | s->buf = buffer; |
33 | s->buf_end = s->buf + buffer_size; |
34 | s->buf_ptr = s->buf; |
35 | s->bit_left = 32; |
36 | s->bit_buf = 0; |
37 | } |
38 | |
39 | /** |
40 | * Rebase the bit writer onto a reallocated buffer. |
41 | * |
42 | * @param buffer the buffer where to put bits |
43 | * @param buffer_size the size in bytes of buffer, |
44 | * must be larger than the previous size |
45 | */ |
46 | static inline void rebase_put_bits(struct put_bits_context *s, |
47 | u8 *buffer, int buffer_size) |
48 | { |
49 | s->buf_end = buffer + buffer_size; |
50 | s->buf_ptr = buffer + (s->buf_ptr - s->buf); |
51 | s->buf = buffer; |
52 | s->size_in_bits = 8 * buffer_size; |
53 | } |
54 | |
55 | /** |
56 | * @return the total number of bits written to the bitstream. |
57 | */ |
58 | static inline int put_bits_count(struct put_bits_context *s) |
59 | { |
60 | return (s->buf_ptr - s->buf) * 8 + 32 - s->bit_left; |
61 | } |
62 | |
63 | /** |
64 | * @return the number of bits available in the bitstream. |
65 | */ |
66 | static inline int put_bits_left(struct put_bits_context* s) |
67 | { |
68 | return (s->buf_end - s->buf_ptr) * 8 - 32 + s->bit_left; |
69 | } |
70 | |
71 | /** |
72 | * Pad the end of the output stream with zeros. |
73 | */ |
74 | static inline void flush_put_bits(struct put_bits_context *s) |
75 | { |
76 | #ifndef BITSTREAM_WRITER_LE |
77 | if (s->bit_left < 32) |
78 | s->bit_buf <<= s->bit_left; |
79 | #endif |
80 | while (s->bit_left < 32) { |
81 | #ifdef BITSTREAM_WRITER_LE |
82 | *s->buf_ptr++ = s->bit_buf; |
83 | s->bit_buf >>= 8; |
84 | #else |
85 | *s->buf_ptr++ = s->bit_buf >> 24; |
86 | s->bit_buf <<= 8; |
87 | #endif |
88 | s->bit_left += 8; |
89 | } |
90 | s->bit_left = 32; |
91 | s->bit_buf = 0; |
92 | } |
93 | |
94 | static inline void flush_put_bits_le(struct put_bits_context *s) |
95 | { |
96 | while (s->bit_left < 32) { |
97 | *s->buf_ptr++ = s->bit_buf; |
98 | s->bit_buf >>= 8; |
99 | s->bit_left += 8; |
100 | } |
101 | s->bit_left = 32; |
102 | s->bit_buf = 0; |
103 | } |
104 | |
105 | #ifdef BITSTREAM_WRITER_LE |
106 | #define avpriv_align_put_bits align_put_bits_unsupported_here |
107 | #define avpriv_put_string ff_put_string_unsupported_here |
108 | #define avpriv_copy_bits avpriv_copy_bits_unsupported_here |
109 | #else |
110 | /** |
111 | * Pad the bitstream with zeros up to the next byte boundary. |
112 | */ |
113 | void avpriv_align_put_bits(struct put_bits_context *s); |
114 | |
115 | /** |
116 | * Put the string string in the bitstream. |
117 | * |
118 | * @param terminate_string 0-terminates the written string if value is 1 |
119 | */ |
120 | void avpriv_put_string(struct put_bits_context *pb, |
121 | const char *string, int terminate_string); |
122 | |
123 | /** |
124 | * Copy the content of src to the bitstream. |
125 | * |
126 | * @param length the number of bits of src to copy |
127 | */ |
128 | void avpriv_copy_bits(struct put_bits_context *pb, const u8 *src, int length); |
129 | #endif |
130 | |
131 | /** |
132 | * Write up to 31 bits into a bitstream. |
133 | * Use put_bits32 to write 32 bits. |
134 | */ |
135 | static inline void put_bits(struct put_bits_context *s, int n, u32 value) |
136 | { |
137 | u32 bit_buf; |
138 | int bit_left; |
139 | |
140 | bit_buf = s->bit_buf; |
141 | bit_left = s->bit_left; |
142 | |
143 | /* XXX: optimize */ |
144 | #ifdef BITSTREAM_WRITER_LE |
145 | bit_buf |= value << (32 - bit_left); |
146 | if (n >= bit_left) { |
147 | if (3 < s->buf_end - s->buf_ptr) { |
148 | AV_WL32(s->buf_ptr, bit_buf); |
149 | s->buf_ptr += 4; |
150 | } else { |
151 | pr_err("Internal error, put_bits buffer too small\n"); |
152 | } |
153 | bit_buf = value >> bit_left; |
154 | bit_left += 32; |
155 | } |
156 | bit_left -= n; |
157 | #else |
158 | if (n < bit_left) { |
159 | bit_buf = (bit_buf << n) | value; |
160 | bit_left -= n; |
161 | } else { |
162 | bit_buf <<= bit_left; |
163 | bit_buf |= value >> (n - bit_left); |
164 | if (3 < s->buf_end - s->buf_ptr) { |
165 | AV_WB32(s->buf_ptr, bit_buf); |
166 | s->buf_ptr += 4; |
167 | } else { |
168 | pr_err("Internal error, put_bits buffer too small\n"); |
169 | } |
170 | bit_left += 32 - n; |
171 | bit_buf = value; |
172 | } |
173 | #endif |
174 | s->bit_buf = bit_buf; |
175 | s->bit_left = bit_left; |
176 | } |
177 | |
178 | static inline void put_bits_le(struct put_bits_context *s, int n, u32 value) |
179 | { |
180 | u32 bit_buf; |
181 | int bit_left; |
182 | |
183 | bit_buf = s->bit_buf; |
184 | bit_left = s->bit_left; |
185 | |
186 | bit_buf |= value << (32 - bit_left); |
187 | if (n >= bit_left) { |
188 | if (3 < s->buf_end - s->buf_ptr) { |
189 | AV_WL32(s->buf_ptr, bit_buf); |
190 | s->buf_ptr += 4; |
191 | } else { |
192 | pr_err("Internal error, put_bits buffer too small\n"); |
193 | } |
194 | bit_buf = value >> bit_left; |
195 | bit_left += 32; |
196 | } |
197 | bit_left -= n; |
198 | |
199 | s->bit_buf = bit_buf; |
200 | s->bit_left = bit_left; |
201 | } |
202 | |
203 | static inline u32 av_mod_uintp2(u32 a, u32 p) |
204 | { |
205 | return a & ((1 << p) - 1); |
206 | } |
207 | |
208 | static inline void put_sbits(struct put_bits_context *pb, int n, int32_t value) |
209 | { |
210 | put_bits(pb, n, av_mod_uintp2(value, n)); |
211 | } |
212 | |
213 | /** |
214 | * Write exactly 32 bits into a bitstream. |
215 | */ |
216 | static void put_bits32(struct put_bits_context *s, u32 value) |
217 | { |
218 | u32 bit_buf; |
219 | int bit_left; |
220 | |
221 | bit_buf = s->bit_buf; |
222 | bit_left = s->bit_left; |
223 | |
224 | #ifdef BITSTREAM_WRITER_LE |
225 | bit_buf |= value << (32 - bit_left); |
226 | if (3 < s->buf_end - s->buf_ptr) { |
227 | AV_WL32(s->buf_ptr, bit_buf); |
228 | s->buf_ptr += 4; |
229 | } else { |
230 | pr_err("Internal error, put_bits buffer too small\n"); |
231 | } |
232 | bit_buf = (uint64_t)value >> bit_left; |
233 | #else |
234 | bit_buf = (uint64_t)bit_buf << bit_left; |
235 | bit_buf |= value >> (32 - bit_left); |
236 | if (3 < s->buf_end - s->buf_ptr) { |
237 | AV_WB32(s->buf_ptr, bit_buf); |
238 | s->buf_ptr += 4; |
239 | } else { |
240 | pr_err("Internal error, put_bits buffer too small\n"); |
241 | } |
242 | bit_buf = value; |
243 | #endif |
244 | |
245 | s->bit_buf = bit_buf; |
246 | s->bit_left = bit_left; |
247 | } |
248 | |
249 | /** |
250 | * Write up to 64 bits into a bitstream. |
251 | */ |
252 | static inline void put_bits64(struct put_bits_context *s, int n, uint64_t value) |
253 | { |
254 | if (n < 32) |
255 | put_bits(s, n, value); |
256 | else if (n == 32) |
257 | put_bits32(s, value); |
258 | else if (n < 64) { |
259 | u32 lo = value & 0xffffffff; |
260 | u32 hi = value >> 32; |
261 | #ifdef BITSTREAM_WRITER_LE |
262 | put_bits32(s, lo); |
263 | put_bits(s, n - 32, hi); |
264 | #else |
265 | put_bits(s, n - 32, hi); |
266 | put_bits32(s, lo); |
267 | #endif |
268 | } else { |
269 | u32 lo = value & 0xffffffff; |
270 | u32 hi = value >> 32; |
271 | #ifdef BITSTREAM_WRITER_LE |
272 | put_bits32(s, lo); |
273 | put_bits32(s, hi); |
274 | #else |
275 | put_bits32(s, hi); |
276 | put_bits32(s, lo); |
277 | #endif |
278 | } |
279 | } |
280 | |
281 | /** |
282 | * Return the pointer to the byte where the bitstream writer will put |
283 | * the next bit. |
284 | */ |
285 | static inline u8 *put_bits_ptr(struct put_bits_context *s) |
286 | { |
287 | return s->buf_ptr; |
288 | } |
289 | |
290 | /** |
291 | * Skip the given number of bytes. |
292 | * struct put_bits_context must be flushed & aligned to a byte boundary before calling this. |
293 | */ |
294 | static inline void skip_put_bytes(struct put_bits_context *s, int n) |
295 | { |
296 | s->buf_ptr += n; |
297 | } |
298 | |
299 | /** |
300 | * Skip the given number of bits. |
301 | * Must only be used if the actual values in the bitstream do not matter. |
302 | * If n is 0 the behavior is undefined. |
303 | */ |
304 | static inline void skip_put_bits(struct put_bits_context *s, int n) |
305 | { |
306 | s->bit_left -= n; |
307 | s->buf_ptr -= 4 * (s->bit_left >> 5); |
308 | s->bit_left &= 31; |
309 | } |
310 | |
311 | /** |
312 | * Change the end of the buffer. |
313 | * |
314 | * @param size the new size in bytes of the buffer where to put bits |
315 | */ |
316 | static inline void set_put_bits_buffer_size(struct put_bits_context *s, int size) |
317 | { |
318 | s->buf_end = s->buf + size; |
319 | s->size_in_bits = 8*size; |
320 | } |
321 | |
322 | #endif /* AVCODEC_PUT_BITS_H */ |
323 | |
324 |