ADPCM Codecs
put_bits.h
Go to the documentation of this file.
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 
26 #pragma once
27 
28 #include <stdint.h>
29 #include <stddef.h>
30 
31 #include "config-adpcm.h"
32 #include "intreadwrite.h"
33 #include "adpcm.h"
34 
35 namespace adpcm_ffmpeg {
36 
37 
38 #if ARCH_X86_64
39 // TODO: Benchmark and optionally enable on other 64-bit architectures.
40 typedef uint64_t BitBuf;
41 #define AV_WBBUF AV_WB64
42 #define AV_WLBUF AV_WL64
43 #else
44 typedef uint32_t BitBuf;
45 #define AV_WBBUF AV_WB32
46 #define AV_WLBUF AV_WL32
47 #endif
48 
49 static const int BUF_BITS = 8 * sizeof(BitBuf);
50 
51 typedef struct PutBitContext {
52  BitBuf bit_buf;
53  int bit_left;
54  uint8_t *buf, *buf_ptr, *buf_end;
56 
63 static inline void init_put_bits(PutBitContext *s, uint8_t *buffer,
64  int buffer_size)
65 {
66  if (buffer_size < 0) {
67  buffer_size = 0;
68  buffer = NULL;
69  }
70 
71  s->buf = buffer;
72  s->buf_end = s->buf + buffer_size;
73  s->buf_ptr = s->buf;
74  s->bit_left = BUF_BITS;
75  s->bit_buf = 0;
76 }
77 
81 static inline int put_bits_count(PutBitContext *s)
82 {
83  return (s->buf_ptr - s->buf) * 8 + BUF_BITS - s->bit_left;
84 }
85 
90 static inline int put_bytes_output(const PutBitContext *s)
91 {
92  av_assert(s->bit_left == BUF_BITS);
93  return s->buf_ptr - s->buf;
94 }
95 
101 static inline int put_bytes_count(const PutBitContext *s, int round_up)
102 {
103  return s->buf_ptr - s->buf + ((BUF_BITS - s->bit_left + (round_up ? 7 : 0)) >> 3);
104 }
105 
113 static inline void rebase_put_bits(PutBitContext *s, uint8_t *buffer,
114  int buffer_size)
115 {
116  av_assert(8*buffer_size >= put_bits_count(s));
117 
118  s->buf_end = buffer + buffer_size;
119  s->buf_ptr = buffer + (s->buf_ptr - s->buf);
120  s->buf = buffer;
121 }
122 
126 static inline int put_bits_left(PutBitContext* s)
127 {
128  return (s->buf_end - s->buf_ptr) * 8 - BUF_BITS + s->bit_left;
129 }
130 
136 static inline int put_bytes_left(const PutBitContext *s, int round_up)
137 {
138  return s->buf_end - s->buf_ptr - ((BUF_BITS - s->bit_left + (round_up ? 7 : 0)) >> 3);
139 }
140 
144 static inline void flush_put_bits(PutBitContext *s)
145 {
146 #ifndef BITSTREAM_WRITER_LE
147  if (s->bit_left < BUF_BITS)
148  s->bit_buf <<= s->bit_left;
149 #endif
150  while (s->bit_left < BUF_BITS) {
151  av_assert(s->buf_ptr < s->buf_end);
152 #ifdef BITSTREAM_WRITER_LE
153  *s->buf_ptr++ = s->bit_buf;
154  s->bit_buf >>= 8;
155 #else
156  *s->buf_ptr++ = s->bit_buf >> (BUF_BITS - 8);
157  s->bit_buf <<= 8;
158 #endif
159  s->bit_left += 8;
160  }
161  s->bit_left = BUF_BITS;
162  s->bit_buf = 0;
163 }
164 
165 static inline void flush_put_bits_le(PutBitContext *s)
166 {
167  while (s->bit_left < BUF_BITS) {
168  av_assert(s->buf_ptr < s->buf_end);
169  *s->buf_ptr++ = s->bit_buf;
170  s->bit_buf >>= 8;
171  s->bit_left += 8;
172  }
173  s->bit_left = BUF_BITS;
174  s->bit_buf = 0;
175 }
176 
177 #ifdef BITSTREAM_WRITER_LE
178 #define ff_put_string ff_put_string_unsupported_here
179 #define ff_copy_bits ff_copy_bits_unsupported_here
180 #else
181 
187 void ff_put_string(PutBitContext *pb, const char *string,
188  int terminate_string);
189 
195 void ff_copy_bits(PutBitContext *pb, const uint8_t *src, int length);
196 #endif
197 
198 static inline void put_bits_no_assert(PutBitContext *s, int n, BitBuf value)
199 {
200  BitBuf bit_buf;
201  int bit_left;
202 
203  bit_buf = s->bit_buf;
204  bit_left = s->bit_left;
205 
206  /* XXX: optimize */
207 #ifdef BITSTREAM_WRITER_LE
208  bit_buf |= value << (BUF_BITS - bit_left);
209  if (n >= bit_left) {
210  if (s->buf_end - s->buf_ptr >= sizeof(BitBuf)) {
211  AV_WLBUF(s->buf_ptr, bit_buf);
212  s->buf_ptr += sizeof(BitBuf);
213  } else {
214  av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n");
215  av_assert(0);
216  }
217  bit_buf = value >> bit_left;
218  bit_left += BUF_BITS;
219  }
220  bit_left -= n;
221 #else
222  if (n < bit_left) {
223  bit_buf = (bit_buf << n) | value;
224  bit_left -= n;
225  } else {
226  bit_buf <<= bit_left;
227  bit_buf |= value >> (n - bit_left);
228  if (s->buf_end - s->buf_ptr >= sizeof(BitBuf)) {
229  AV_WBBUF(s->buf_ptr, bit_buf);
230  s->buf_ptr += sizeof(BitBuf);
231  } else {
232  av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n");
233  av_assert(0);
234  }
235  bit_left += BUF_BITS - n;
236  bit_buf = value;
237  }
238 #endif
239 
240  s->bit_buf = bit_buf;
241  s->bit_left = bit_left;
242 }
243 
248 static inline void put_bits(PutBitContext *s, int n, BitBuf value)
249 {
250  av_assert(n <= 31 && value < (1UL << n));
251  put_bits_no_assert(s, n, value);
252 }
253 
254 static inline void put_bits_le(PutBitContext *s, int n, BitBuf value)
255 {
256  BitBuf bit_buf;
257  int bit_left;
258 
259  av_assert(n <= 31 && value < (1UL << n));
260 
261  bit_buf = s->bit_buf;
262  bit_left = s->bit_left;
263 
264  bit_buf |= value << (BUF_BITS - bit_left);
265  if (n >= bit_left) {
266  if (s->buf_end - s->buf_ptr >= sizeof(BitBuf)) {
267  AV_WLBUF(s->buf_ptr, bit_buf);
268  s->buf_ptr += sizeof(BitBuf);
269  } else {
270  av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n");
271  av_assert(0);
272  }
273  bit_buf = value >> bit_left;
274  bit_left += BUF_BITS;
275  }
276  bit_left -= n;
277 
278  s->bit_buf = bit_buf;
279  s->bit_left = bit_left;
280 }
281 
282 static inline void put_sbits(PutBitContext *pb, int n, int32_t value)
283 {
284  av_assert(n >= 0 && n <= 31);
285 
286  put_bits(pb, n, av_mod_uintp2(value, n));
287 }
288 
292 static void av_unused put_bits32(PutBitContext *s, uint32_t value)
293 {
294  BitBuf bit_buf;
295  int bit_left;
296 
297  if (BUF_BITS > 32) {
298  put_bits_no_assert(s, 32, value);
299  return;
300  }
301 
302  bit_buf = s->bit_buf;
303  bit_left = s->bit_left;
304 
305 #ifdef BITSTREAM_WRITER_LE
306  bit_buf |= (BitBuf)value << (BUF_BITS - bit_left);
307  if (s->buf_end - s->buf_ptr >= sizeof(BitBuf)) {
308  AV_WLBUF(s->buf_ptr, bit_buf);
309  s->buf_ptr += sizeof(BitBuf);
310  } else {
311  av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n");
312  av_assert(0);
313  }
314  bit_buf = (uint64_t)value >> bit_left;
315 #else
316  bit_buf = (uint64_t)bit_buf << bit_left;
317  bit_buf |= (BitBuf)value >> (BUF_BITS - bit_left);
318  if (s->buf_end - s->buf_ptr >= sizeof(BitBuf)) {
319  AV_WBBUF(s->buf_ptr, bit_buf);
320  s->buf_ptr += sizeof(BitBuf);
321  } else {
322  av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n");
323  av_assert(0);
324  }
325  bit_buf = value;
326 #endif
327 
328  s->bit_buf = bit_buf;
329  s->bit_left = bit_left;
330 }
331 
335 static inline void put_bits64(PutBitContext *s, int n, uint64_t value)
336 {
337  av_assert((n == 64) || (n < 64 && value < (UINT64_C(1) << n)));
338 
339  if (n < 32)
340  put_bits(s, n, value);
341  else if (n == 32)
342  put_bits32(s, value);
343  else if (n < 64) {
344  uint32_t lo = value & 0xffffffff;
345  uint32_t hi = value >> 32;
346 #ifdef BITSTREAM_WRITER_LE
347  put_bits32(s, lo);
348  put_bits(s, n - 32, hi);
349 #else
350  put_bits(s, n - 32, hi);
351  put_bits32(s, lo);
352 #endif
353  } else {
354  uint32_t lo = value & 0xffffffff;
355  uint32_t hi = value >> 32;
356 #ifdef BITSTREAM_WRITER_LE
357  put_bits32(s, lo);
358  put_bits32(s, hi);
359 #else
360  put_bits32(s, hi);
361  put_bits32(s, lo);
362 #endif
363 
364  }
365 }
366 
367 static inline void put_sbits63(PutBitContext *pb, int n, int64_t value)
368 {
369  av_assert(n >= 0 && n < 64);
370 
371  put_bits64(pb, n, (uint64_t)(value) & (~(UINT64_MAX << n)));
372 }
373 
378 static inline uint8_t *put_bits_ptr(PutBitContext *s)
379 {
380  return s->buf_ptr;
381 }
382 
387 static inline void skip_put_bytes(PutBitContext *s, int n)
388 {
389  av_assert((put_bits_count(s) & 7) == 0);
390  av_assert(s->bit_left == BUF_BITS);
391  av_assert(n <= s->buf_end - s->buf_ptr);
392  s->buf_ptr += n;
393 }
394 
400 static inline void skip_put_bits(PutBitContext *s, int n)
401 {
402  unsigned bits = BUF_BITS - s->bit_left + n;
403  s->buf_ptr += sizeof(BitBuf) * (bits / BUF_BITS);
404  s->bit_left = BUF_BITS - (bits & (BUF_BITS - 1));
405 }
406 
412 static inline void set_put_bits_buffer_size(PutBitContext *s, int size)
413 {
414  av_assert(size <= INT_MAX/8 - BUF_BITS);
415  s->buf_end = s->buf + size;
416 }
417 
421 static inline void align_put_bits(PutBitContext *s)
422 {
423  put_bits(s, s->bit_left & 7, 0);
424 }
425 
426 #undef AV_WBBUF
427 #undef AV_WLBUF
428 
429 }
Definition: put_bits.h:51