Mercurial > libavcodec.hg
comparison bitstream.h @ 9411:4cb7c65fc775 libavcodec
Split bitstream.h, put the bitstream writer stuff in the new file
put_bits.h.
author | stefano |
---|---|
date | Sun, 12 Apr 2009 08:35:26 +0000 |
parents | e74131a0652d |
children |
comparison
equal
deleted
inserted
replaced
9410:f7bd7e90ef9f | 9411:4cb7c65fc775 |
---|---|
37 | 37 |
38 #if defined(ALT_BITSTREAM_READER_LE) && !defined(ALT_BITSTREAM_READER) | 38 #if defined(ALT_BITSTREAM_READER_LE) && !defined(ALT_BITSTREAM_READER) |
39 # define ALT_BITSTREAM_READER | 39 # define ALT_BITSTREAM_READER |
40 #endif | 40 #endif |
41 | 41 |
42 //#define ALT_BITSTREAM_WRITER | |
43 //#define ALIGNED_BITSTREAM_WRITER | |
44 #if !defined(LIBMPEG2_BITSTREAM_READER) && !defined(A32_BITSTREAM_READER) && !defined(ALT_BITSTREAM_READER) | 42 #if !defined(LIBMPEG2_BITSTREAM_READER) && !defined(A32_BITSTREAM_READER) && !defined(ALT_BITSTREAM_READER) |
45 # if ARCH_ARM | 43 # if ARCH_ARM |
46 # define A32_BITSTREAM_READER | 44 # define A32_BITSTREAM_READER |
47 # else | 45 # else |
48 # define ALT_BITSTREAM_READER | 46 # define ALT_BITSTREAM_READER |
71 } | 69 } |
72 #else | 70 #else |
73 # define NEG_SSR32(a,s) ((( int32_t)(a))>>(32-(s))) | 71 # define NEG_SSR32(a,s) ((( int32_t)(a))>>(32-(s))) |
74 # define NEG_USR32(a,s) (((uint32_t)(a))>>(32-(s))) | 72 # define NEG_USR32(a,s) (((uint32_t)(a))>>(32-(s))) |
75 #endif | 73 #endif |
76 | |
77 /* bit output */ | |
78 | |
79 /* buf and buf_end must be present and used by every alternative writer. */ | |
80 typedef struct PutBitContext { | |
81 #ifdef ALT_BITSTREAM_WRITER | |
82 uint8_t *buf, *buf_end; | |
83 int index; | |
84 #else | |
85 uint32_t bit_buf; | |
86 int bit_left; | |
87 uint8_t *buf, *buf_ptr, *buf_end; | |
88 #endif | |
89 int size_in_bits; | |
90 } PutBitContext; | |
91 | |
92 /** | |
93 * Initializes the PutBitContext \p s. | |
94 * | |
95 * @param buffer the buffer where to put bits | |
96 * @param buffer_size the size in bytes of \p buffer | |
97 */ | |
98 static inline void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size) | |
99 { | |
100 if(buffer_size < 0) { | |
101 buffer_size = 0; | |
102 buffer = NULL; | |
103 } | |
104 | |
105 s->size_in_bits= 8*buffer_size; | |
106 s->buf = buffer; | |
107 s->buf_end = s->buf + buffer_size; | |
108 #ifdef ALT_BITSTREAM_WRITER | |
109 s->index=0; | |
110 ((uint32_t*)(s->buf))[0]=0; | |
111 // memset(buffer, 0, buffer_size); | |
112 #else | |
113 s->buf_ptr = s->buf; | |
114 s->bit_left=32; | |
115 s->bit_buf=0; | |
116 #endif | |
117 } | |
118 | |
119 /** | |
120 * Returns the total number of bits written to the bitstream. | |
121 */ | |
122 static inline int put_bits_count(PutBitContext *s) | |
123 { | |
124 #ifdef ALT_BITSTREAM_WRITER | |
125 return s->index; | |
126 #else | |
127 return (s->buf_ptr - s->buf) * 8 + 32 - s->bit_left; | |
128 #endif | |
129 } | |
130 | |
131 /** | |
132 * Pads the end of the output stream with zeros. | |
133 */ | |
134 static inline void flush_put_bits(PutBitContext *s) | |
135 { | |
136 #ifdef ALT_BITSTREAM_WRITER | |
137 align_put_bits(s); | |
138 #else | |
139 #ifndef BITSTREAM_WRITER_LE | |
140 s->bit_buf<<= s->bit_left; | |
141 #endif | |
142 while (s->bit_left < 32) { | |
143 /* XXX: should test end of buffer */ | |
144 #ifdef BITSTREAM_WRITER_LE | |
145 *s->buf_ptr++=s->bit_buf; | |
146 s->bit_buf>>=8; | |
147 #else | |
148 *s->buf_ptr++=s->bit_buf >> 24; | |
149 s->bit_buf<<=8; | |
150 #endif | |
151 s->bit_left+=8; | |
152 } | |
153 s->bit_left=32; | |
154 s->bit_buf=0; | |
155 #endif | |
156 } | |
157 | |
158 /** | |
159 * Pads the bitstream with zeros up to the next byte boundary. | |
160 */ | |
161 void align_put_bits(PutBitContext *s); | |
162 | |
163 /** | |
164 * Puts the string \p s in the bitstream. | |
165 * | |
166 * @param terminate_string 0-terminates the written string if value is 1 | |
167 */ | |
168 void ff_put_string(PutBitContext * pbc, const char *s, int terminate_string); | |
169 | |
170 /** | |
171 * Copies the content of \p src to the bitstream. | |
172 * | |
173 * @param length the number of bits of \p src to copy | |
174 */ | |
175 void ff_copy_bits(PutBitContext *pb, const uint8_t *src, int length); | |
176 | 74 |
177 /* bit input */ | 75 /* bit input */ |
178 /* buffer, buffer_end and size_in_bits must be present and used by every reader */ | 76 /* buffer, buffer_end and size_in_bits must be present and used by every reader */ |
179 typedef struct GetBitContext { | 77 typedef struct GetBitContext { |
180 const uint8_t *buffer, *buffer_end; | 78 const uint8_t *buffer, *buffer_end; |
205 int16_t level; | 103 int16_t level; |
206 int8_t len; | 104 int8_t len; |
207 uint8_t run; | 105 uint8_t run; |
208 } RL_VLC_ELEM; | 106 } RL_VLC_ELEM; |
209 | 107 |
210 static inline void put_bits(PutBitContext *s, int n, unsigned int value) | |
211 #ifndef ALT_BITSTREAM_WRITER | |
212 { | |
213 unsigned int bit_buf; | |
214 int bit_left; | |
215 | |
216 // printf("put_bits=%d %x\n", n, value); | |
217 assert(n == 32 || value < (1U << n)); | |
218 | |
219 bit_buf = s->bit_buf; | |
220 bit_left = s->bit_left; | |
221 | |
222 // printf("n=%d value=%x cnt=%d buf=%x\n", n, value, bit_cnt, bit_buf); | |
223 /* XXX: optimize */ | |
224 #ifdef BITSTREAM_WRITER_LE | |
225 bit_buf |= value << (32 - bit_left); | |
226 if (n >= bit_left) { | |
227 #if !HAVE_FAST_UNALIGNED | |
228 if (3 & (intptr_t) s->buf_ptr) { | |
229 AV_WL32(s->buf_ptr, bit_buf); | |
230 } else | |
231 #endif | |
232 *(uint32_t *)s->buf_ptr = le2me_32(bit_buf); | |
233 s->buf_ptr+=4; | |
234 bit_buf = (bit_left==32)?0:value >> bit_left; | |
235 bit_left+=32; | |
236 } | |
237 bit_left-=n; | |
238 #else | |
239 if (n < bit_left) { | |
240 bit_buf = (bit_buf<<n) | value; | |
241 bit_left-=n; | |
242 } else { | |
243 bit_buf<<=bit_left; | |
244 bit_buf |= value >> (n - bit_left); | |
245 #if !HAVE_FAST_UNALIGNED | |
246 if (3 & (intptr_t) s->buf_ptr) { | |
247 AV_WB32(s->buf_ptr, bit_buf); | |
248 } else | |
249 #endif | |
250 *(uint32_t *)s->buf_ptr = be2me_32(bit_buf); | |
251 //printf("bitbuf = %08x\n", bit_buf); | |
252 s->buf_ptr+=4; | |
253 bit_left+=32 - n; | |
254 bit_buf = value; | |
255 } | |
256 #endif | |
257 | |
258 s->bit_buf = bit_buf; | |
259 s->bit_left = bit_left; | |
260 } | |
261 #else /* ALT_BITSTREAM_WRITER defined */ | |
262 { | |
263 # ifdef ALIGNED_BITSTREAM_WRITER | |
264 # if ARCH_X86 | |
265 __asm__ volatile( | |
266 "movl %0, %%ecx \n\t" | |
267 "xorl %%eax, %%eax \n\t" | |
268 "shrdl %%cl, %1, %%eax \n\t" | |
269 "shrl %%cl, %1 \n\t" | |
270 "movl %0, %%ecx \n\t" | |
271 "shrl $3, %%ecx \n\t" | |
272 "andl $0xFFFFFFFC, %%ecx \n\t" | |
273 "bswapl %1 \n\t" | |
274 "orl %1, (%2, %%ecx) \n\t" | |
275 "bswapl %%eax \n\t" | |
276 "addl %3, %0 \n\t" | |
277 "movl %%eax, 4(%2, %%ecx) \n\t" | |
278 : "=&r" (s->index), "=&r" (value) | |
279 : "r" (s->buf), "r" (n), "0" (s->index), "1" (value<<(-n)) | |
280 : "%eax", "%ecx" | |
281 ); | |
282 # else | |
283 int index= s->index; | |
284 uint32_t *ptr= ((uint32_t *)s->buf)+(index>>5); | |
285 | |
286 value<<= 32-n; | |
287 | |
288 ptr[0] |= be2me_32(value>>(index&31)); | |
289 ptr[1] = be2me_32(value<<(32-(index&31))); | |
290 //if(n>24) printf("%d %d\n", n, value); | |
291 index+= n; | |
292 s->index= index; | |
293 # endif | |
294 # else //ALIGNED_BITSTREAM_WRITER | |
295 # if ARCH_X86 | |
296 __asm__ volatile( | |
297 "movl $7, %%ecx \n\t" | |
298 "andl %0, %%ecx \n\t" | |
299 "addl %3, %%ecx \n\t" | |
300 "negl %%ecx \n\t" | |
301 "shll %%cl, %1 \n\t" | |
302 "bswapl %1 \n\t" | |
303 "movl %0, %%ecx \n\t" | |
304 "shrl $3, %%ecx \n\t" | |
305 "orl %1, (%%ecx, %2) \n\t" | |
306 "addl %3, %0 \n\t" | |
307 "movl $0, 4(%%ecx, %2) \n\t" | |
308 : "=&r" (s->index), "=&r" (value) | |
309 : "r" (s->buf), "r" (n), "0" (s->index), "1" (value) | |
310 : "%ecx" | |
311 ); | |
312 # else | |
313 int index= s->index; | |
314 uint32_t *ptr= (uint32_t*)(((uint8_t *)s->buf)+(index>>3)); | |
315 | |
316 ptr[0] |= be2me_32(value<<(32-n-(index&7) )); | |
317 ptr[1] = 0; | |
318 //if(n>24) printf("%d %d\n", n, value); | |
319 index+= n; | |
320 s->index= index; | |
321 # endif | |
322 # endif //!ALIGNED_BITSTREAM_WRITER | |
323 } | |
324 #endif | |
325 | |
326 static inline void put_sbits(PutBitContext *pb, int bits, int32_t val) | |
327 { | |
328 assert(bits >= 0 && bits <= 31); | |
329 | |
330 put_bits(pb, bits, val & ((1<<bits)-1)); | |
331 } | |
332 | |
333 | |
334 static inline uint8_t* pbBufPtr(PutBitContext *s) | |
335 { | |
336 #ifdef ALT_BITSTREAM_WRITER | |
337 return s->buf + (s->index>>3); | |
338 #else | |
339 return s->buf_ptr; | |
340 #endif | |
341 } | |
342 | |
343 /** | |
344 * Skips the given number of bytes. | |
345 * PutBitContext must be flushed & aligned to a byte boundary before calling this. | |
346 */ | |
347 static inline void skip_put_bytes(PutBitContext *s, int n){ | |
348 assert((put_bits_count(s)&7)==0); | |
349 #ifdef ALT_BITSTREAM_WRITER | |
350 FIXME may need some cleaning of the buffer | |
351 s->index += n<<3; | |
352 #else | |
353 assert(s->bit_left==32); | |
354 s->buf_ptr += n; | |
355 #endif | |
356 } | |
357 | |
358 /** | |
359 * Skips the given number of bits. | |
360 * Must only be used if the actual values in the bitstream do not matter. | |
361 * If \p n is 0 the behavior is undefined. | |
362 */ | |
363 static inline void skip_put_bits(PutBitContext *s, int n){ | |
364 #ifdef ALT_BITSTREAM_WRITER | |
365 s->index += n; | |
366 #else | |
367 s->bit_left -= n; | |
368 s->buf_ptr-= s->bit_left>>5; | |
369 s->bit_left &= 31; | |
370 #endif | |
371 } | |
372 | |
373 /** | |
374 * Changes the end of the buffer. | |
375 * | |
376 * @param size the new size in bytes of the buffer where to put bits | |
377 */ | |
378 static inline void set_put_bits_buffer_size(PutBitContext *s, int size){ | |
379 s->buf_end= s->buf + size; | |
380 } | |
381 | |
382 /* Bitstream reader API docs: | 108 /* Bitstream reader API docs: |
383 name | 109 name |
384 arbitrary name which is used as prefix for the internal variables | 110 arbitrary name which is used as prefix for the internal variables |
385 | 111 |
386 gb | 112 gb |