summaryrefslogtreecommitdiff
path: root/apps/codecs/lib/ffmpeg_put_bits.h
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs/lib/ffmpeg_put_bits.h')
-rw-r--r--apps/codecs/lib/ffmpeg_put_bits.h323
1 files changed, 323 insertions, 0 deletions
diff --git a/apps/codecs/lib/ffmpeg_put_bits.h b/apps/codecs/lib/ffmpeg_put_bits.h
new file mode 100644
index 0000000000..38db55fe18
--- /dev/null
+++ b/apps/codecs/lib/ffmpeg_put_bits.h
@@ -0,0 +1,323 @@
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 libavcodec/put_bits.h
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 <stdlib.h>
31#include "ffmpeg_bswap.h"
32#include "ffmpeg_intreadwrite.h"
33
34#define av_log(...)
35#define HAVE_FAST_UNALIGNED 0
36
37/* buf and buf_end must be present and used by every alternative writer. */
38typedef struct PutBitContext {
39#ifdef ALT_BITSTREAM_WRITER
40 uint8_t *buf, *buf_end;
41 int index;
42#else
43 uint32_t bit_buf;
44 int bit_left;
45 uint8_t *buf, *buf_ptr, *buf_end;
46#endif
47 int size_in_bits;
48} PutBitContext;
49
50/**
51 * Initializes the PutBitContext s.
52 *
53 * @param buffer the buffer where to put bits
54 * @param buffer_size the size in bytes of buffer
55 */
56static inline void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size)
57{
58 if(buffer_size < 0) {
59 buffer_size = 0;
60 buffer = NULL;
61 }
62
63 s->size_in_bits= 8*buffer_size;
64 s->buf = buffer;
65 s->buf_end = s->buf + buffer_size;
66#ifdef ALT_BITSTREAM_WRITER
67 s->index=0;
68 ((uint32_t*)(s->buf))[0]=0;
69// memset(buffer, 0, buffer_size);
70#else
71 s->buf_ptr = s->buf;
72 s->bit_left=32;
73 s->bit_buf=0;
74#endif
75}
76
77/**
78 * Returns the total number of bits written to the bitstream.
79 */
80static inline int put_bits_count(PutBitContext *s)
81{
82#ifdef ALT_BITSTREAM_WRITER
83 return s->index;
84#else
85 return (s->buf_ptr - s->buf) * 8 + 32 - s->bit_left;
86#endif
87}
88
89/**
90 * Pads the end of the output stream with zeros.
91 */
92static inline void flush_put_bits(PutBitContext *s)
93{
94#ifdef ALT_BITSTREAM_WRITER
95 align_put_bits(s);
96#else
97#ifndef BITSTREAM_WRITER_LE
98 s->bit_buf<<= s->bit_left;
99#endif
100 while (s->bit_left < 32) {
101 /* XXX: should test end of buffer */
102#ifdef BITSTREAM_WRITER_LE
103 *s->buf_ptr++=s->bit_buf;
104 s->bit_buf>>=8;
105#else
106 *s->buf_ptr++=s->bit_buf >> 24;
107 s->bit_buf<<=8;
108#endif
109 s->bit_left+=8;
110 }
111 s->bit_left=32;
112 s->bit_buf=0;
113#endif
114}
115
116#if defined(ALT_BITSTREAM_WRITER) || defined(BITSTREAM_WRITER_LE)
117#define align_put_bits align_put_bits_unsupported_here
118#define ff_put_string ff_put_string_unsupported_here
119#define ff_copy_bits ff_copy_bits_unsupported_here
120#else
121/**
122 * Pads the bitstream with zeros up to the next byte boundary.
123 */
124void align_put_bits(PutBitContext *s);
125
126/**
127 * Puts the string string in the bitstream.
128 *
129 * @param terminate_string 0-terminates the written string if value is 1
130 */
131void ff_put_string(PutBitContext *pb, const char *string, int terminate_string);
132
133/**
134 * Copies the content of src to the bitstream.
135 *
136 * @param length the number of bits of src to copy
137 */
138void ff_copy_bits(PutBitContext *pb, const uint8_t *src, int length);
139#endif
140
141/**
142 * Writes up to 31 bits into a bitstream.
143 * Use put_bits32 to write 32 bits.
144 */
145static inline void put_bits(PutBitContext *s, int n, unsigned int value)
146#ifndef ALT_BITSTREAM_WRITER
147{
148 unsigned int bit_buf;
149 int bit_left;
150
151 // printf("put_bits=%d %x\n", n, value);
152 //assert(n <= 31 && value < (1U << n));
153
154 bit_buf = s->bit_buf;
155 bit_left = s->bit_left;
156
157 // printf("n=%d value=%x cnt=%d buf=%x\n", n, value, bit_cnt, bit_buf);
158 /* XXX: optimize */
159#ifdef BITSTREAM_WRITER_LE
160 bit_buf |= value << (32 - bit_left);
161 if (n >= bit_left) {
162#if !HAVE_FAST_UNALIGNED
163 if (3 & (intptr_t) s->buf_ptr) {
164 AV_WL32(s->buf_ptr, bit_buf);
165 } else
166#endif
167 *(uint32_t *)s->buf_ptr = le2me_32(bit_buf);
168 s->buf_ptr+=4;
169 bit_buf = (bit_left==32)?0:value >> bit_left;
170 bit_left+=32;
171 }
172 bit_left-=n;
173#else
174 if (n < bit_left) {
175 bit_buf = (bit_buf<<n) | value;
176 bit_left-=n;
177 } else {
178 bit_buf<<=bit_left;
179 bit_buf |= value >> (n - bit_left);
180#if !HAVE_FAST_UNALIGNED
181 if (3 & (intptr_t) s->buf_ptr) {
182 AV_WB32(s->buf_ptr, bit_buf);
183 } else
184#endif
185 *(uint32_t *)s->buf_ptr = be2me_32(bit_buf);
186 //printf("bitbuf = %08x\n", bit_buf);
187 s->buf_ptr+=4;
188 bit_left+=32 - n;
189 bit_buf = value;
190 }
191#endif
192
193 s->bit_buf = bit_buf;
194 s->bit_left = bit_left;
195}
196#else /* ALT_BITSTREAM_WRITER defined */
197{
198# ifdef ALIGNED_BITSTREAM_WRITER
199# if ARCH_X86
200 __asm__ volatile(
201 "movl %0, %%ecx \n\t"
202 "xorl %%eax, %%eax \n\t"
203 "shrdl %%cl, %1, %%eax \n\t"
204 "shrl %%cl, %1 \n\t"
205 "movl %0, %%ecx \n\t"
206 "shrl $3, %%ecx \n\t"
207 "andl $0xFFFFFFFC, %%ecx \n\t"
208 "bswapl %1 \n\t"
209 "orl %1, (%2, %%ecx) \n\t"
210 "bswapl %%eax \n\t"
211 "addl %3, %0 \n\t"
212 "movl %%eax, 4(%2, %%ecx) \n\t"
213 : "=&r" (s->index), "=&r" (value)
214 : "r" (s->buf), "r" (n), "0" (s->index), "1" (value<<(-n))
215 : "%eax", "%ecx"
216 );
217# else
218 int index= s->index;
219 uint32_t *ptr= ((uint32_t *)s->buf)+(index>>5);
220
221 value<<= 32-n;
222
223 ptr[0] |= be2me_32(value>>(index&31));
224 ptr[1] = be2me_32(value<<(32-(index&31)));
225//if(n>24) printf("%d %d\n", n, value);
226 index+= n;
227 s->index= index;
228# endif
229# else //ALIGNED_BITSTREAM_WRITER
230# if ARCH_X86
231 __asm__ volatile(
232 "movl $7, %%ecx \n\t"
233 "andl %0, %%ecx \n\t"
234 "addl %3, %%ecx \n\t"
235 "negl %%ecx \n\t"
236 "shll %%cl, %1 \n\t"
237 "bswapl %1 \n\t"
238 "movl %0, %%ecx \n\t"
239 "shrl $3, %%ecx \n\t"
240 "orl %1, (%%ecx, %2) \n\t"
241 "addl %3, %0 \n\t"
242 "movl $0, 4(%%ecx, %2) \n\t"
243 : "=&r" (s->index), "=&r" (value)
244 : "r" (s->buf), "r" (n), "0" (s->index), "1" (value)
245 : "%ecx"
246 );
247# else
248 int index= s->index;
249 uint32_t *ptr= (uint32_t*)(((uint8_t *)s->buf)+(index>>3));
250
251 ptr[0] |= be2me_32(value<<(32-n-(index&7) ));
252 ptr[1] = 0;
253//if(n>24) printf("%d %d\n", n, value);
254 index+= n;
255 s->index= index;
256# endif
257# endif //!ALIGNED_BITSTREAM_WRITER
258}
259#endif
260
261static inline void put_sbits(PutBitContext *pb, int n, int32_t value)
262{
263 //assert(n >= 0 && n <= 31);
264
265 put_bits(pb, n, value & ((1<<n)-1));
266}
267
268/**
269 * Returns the pointer to the byte where the bitstream writer will put
270 * the next bit.
271 */
272static inline uint8_t* put_bits_ptr(PutBitContext *s)
273{
274#ifdef ALT_BITSTREAM_WRITER
275 return s->buf + (s->index>>3);
276#else
277 return s->buf_ptr;
278#endif
279}
280
281/**
282 * Skips the given number of bytes.
283 * PutBitContext must be flushed & aligned to a byte boundary before calling this.
284 */
285static inline void skip_put_bytes(PutBitContext *s, int n)
286{
287 //assert((put_bits_count(s)&7)==0);
288#ifdef ALT_BITSTREAM_WRITER
289 FIXME may need some cleaning of the buffer
290 s->index += n<<3;
291#else
292 //assert(s->bit_left==32);
293 s->buf_ptr += n;
294#endif
295}
296
297/**
298 * Skips the given number of bits.
299 * Must only be used if the actual values in the bitstream do not matter.
300 * If n is 0 the behavior is undefined.
301 */
302static inline void skip_put_bits(PutBitContext *s, int n)
303{
304#ifdef ALT_BITSTREAM_WRITER
305 s->index += n;
306#else
307 s->bit_left -= n;
308 s->buf_ptr-= 4*(s->bit_left>>5);
309 s->bit_left &= 31;
310#endif
311}
312
313/**
314 * Changes the end of the buffer.
315 *
316 * @param size the new size in bytes of the buffer where to put bits
317 */
318static inline void set_put_bits_buffer_size(PutBitContext *s, int size)
319{
320 s->buf_end= s->buf + size;
321}
322
323#endif /* AVCODEC_PUT_BITS_H */