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