00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00026 #ifndef AVCODEC_PUT_BITS_H
00027 #define AVCODEC_PUT_BITS_H
00028
00029 #include <stdint.h>
00030 #include <stdlib.h>
00031 #include <assert.h>
00032 #include "libavutil/bswap.h"
00033 #include "libavutil/common.h"
00034 #include "libavutil/intreadwrite.h"
00035 #include "libavutil/log.h"
00036 #include "mathops.h"
00037 #include "config.h"
00038
00039
00040
00041
00042
00043 typedef struct PutBitContext {
00044 #ifdef ALT_BITSTREAM_WRITER
00045 uint8_t *buf, *buf_end;
00046 int index;
00047 #else
00048 uint32_t bit_buf;
00049 int bit_left;
00050 uint8_t *buf, *buf_ptr, *buf_end;
00051 #endif
00052 int size_in_bits;
00053 } PutBitContext;
00054
00061 static inline void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size)
00062 {
00063 if(buffer_size < 0) {
00064 buffer_size = 0;
00065 buffer = NULL;
00066 }
00067
00068 s->size_in_bits= 8*buffer_size;
00069 s->buf = buffer;
00070 s->buf_end = s->buf + buffer_size;
00071 #ifdef ALT_BITSTREAM_WRITER
00072 s->index=0;
00073 ((uint32_t*)(s->buf))[0]=0;
00074
00075 #else
00076 s->buf_ptr = s->buf;
00077 s->bit_left=32;
00078 s->bit_buf=0;
00079 #endif
00080 }
00081
00085 static inline int put_bits_count(PutBitContext *s)
00086 {
00087 #ifdef ALT_BITSTREAM_WRITER
00088 return s->index;
00089 #else
00090 return (s->buf_ptr - s->buf) * 8 + 32 - s->bit_left;
00091 #endif
00092 }
00093
00097 static inline void flush_put_bits(PutBitContext *s)
00098 {
00099 #ifdef ALT_BITSTREAM_WRITER
00100 align_put_bits(s);
00101 #else
00102 #ifndef BITSTREAM_WRITER_LE
00103 if (s->bit_left < 32)
00104 s->bit_buf<<= s->bit_left;
00105 #endif
00106 while (s->bit_left < 32) {
00107
00108 #ifdef BITSTREAM_WRITER_LE
00109 *s->buf_ptr++=s->bit_buf;
00110 s->bit_buf>>=8;
00111 #else
00112 *s->buf_ptr++=s->bit_buf >> 24;
00113 s->bit_buf<<=8;
00114 #endif
00115 s->bit_left+=8;
00116 }
00117 s->bit_left=32;
00118 s->bit_buf=0;
00119 #endif
00120 }
00121
00122 #if defined(ALT_BITSTREAM_WRITER) || defined(BITSTREAM_WRITER_LE)
00123 #define align_put_bits align_put_bits_unsupported_here
00124 #define ff_put_string ff_put_string_unsupported_here
00125 #define ff_copy_bits ff_copy_bits_unsupported_here
00126 #else
00127
00130 void align_put_bits(PutBitContext *s);
00131
00137 void ff_put_string(PutBitContext *pb, const char *string, int terminate_string);
00138
00144 void ff_copy_bits(PutBitContext *pb, const uint8_t *src, int length);
00145 #endif
00146
00151 static inline void put_bits(PutBitContext *s, int n, unsigned int value)
00152 #ifndef ALT_BITSTREAM_WRITER
00153 {
00154 unsigned int bit_buf;
00155 int bit_left;
00156
00157
00158 assert(n <= 31 && value < (1U << n));
00159
00160 bit_buf = s->bit_buf;
00161 bit_left = s->bit_left;
00162
00163
00164
00165 #ifdef BITSTREAM_WRITER_LE
00166 bit_buf |= value << (32 - bit_left);
00167 if (n >= bit_left) {
00168 #if !HAVE_FAST_UNALIGNED
00169 if (3 & (intptr_t) s->buf_ptr) {
00170 AV_WL32(s->buf_ptr, bit_buf);
00171 } else
00172 #endif
00173 *(uint32_t *)s->buf_ptr = av_le2ne32(bit_buf);
00174 s->buf_ptr+=4;
00175 bit_buf = (bit_left==32)?0:value >> bit_left;
00176 bit_left+=32;
00177 }
00178 bit_left-=n;
00179 #else
00180 if (n < bit_left) {
00181 bit_buf = (bit_buf<<n) | value;
00182 bit_left-=n;
00183 } else {
00184 bit_buf<<=bit_left;
00185 bit_buf |= value >> (n - bit_left);
00186 #if !HAVE_FAST_UNALIGNED
00187 if (3 & (intptr_t) s->buf_ptr) {
00188 AV_WB32(s->buf_ptr, bit_buf);
00189 } else
00190 #endif
00191 *(uint32_t *)s->buf_ptr = av_be2ne32(bit_buf);
00192
00193 s->buf_ptr+=4;
00194 bit_left+=32 - n;
00195 bit_buf = value;
00196 }
00197 #endif
00198
00199 s->bit_buf = bit_buf;
00200 s->bit_left = bit_left;
00201 }
00202 #else
00203 {
00204 # ifdef ALIGNED_BITSTREAM_WRITER
00205 # if ARCH_X86
00206 __asm__ volatile(
00207 "movl %0, %%ecx \n\t"
00208 "xorl %%eax, %%eax \n\t"
00209 "shrdl %%cl, %1, %%eax \n\t"
00210 "shrl %%cl, %1 \n\t"
00211 "movl %0, %%ecx \n\t"
00212 "shrl $3, %%ecx \n\t"
00213 "andl $0xFFFFFFFC, %%ecx \n\t"
00214 "bswapl %1 \n\t"
00215 "orl %1, (%2, %%ecx) \n\t"
00216 "bswapl %%eax \n\t"
00217 "addl %3, %0 \n\t"
00218 "movl %%eax, 4(%2, %%ecx) \n\t"
00219 : "=&r" (s->index), "=&r" (value)
00220 : "r" (s->buf), "r" (n), "0" (s->index), "1" (value<<(-n))
00221 : "%eax", "%ecx"
00222 );
00223 # else
00224 int index= s->index;
00225 uint32_t *ptr= ((uint32_t *)s->buf)+(index>>5);
00226
00227 value<<= 32-n;
00228
00229 ptr[0] |= av_be2ne32(value>>(index&31));
00230 ptr[1] = av_be2ne32(value<<(32-(index&31)));
00231
00232 index+= n;
00233 s->index= index;
00234 # endif
00235 # else //ALIGNED_BITSTREAM_WRITER
00236 # if ARCH_X86
00237 __asm__ volatile(
00238 "movl $7, %%ecx \n\t"
00239 "andl %0, %%ecx \n\t"
00240 "addl %3, %%ecx \n\t"
00241 "negl %%ecx \n\t"
00242 "shll %%cl, %1 \n\t"
00243 "bswapl %1 \n\t"
00244 "movl %0, %%ecx \n\t"
00245 "shrl $3, %%ecx \n\t"
00246 "orl %1, (%%ecx, %2) \n\t"
00247 "addl %3, %0 \n\t"
00248 "movl $0, 4(%%ecx, %2) \n\t"
00249 : "=&r" (s->index), "=&r" (value)
00250 : "r" (s->buf), "r" (n), "0" (s->index), "1" (value)
00251 : "%ecx"
00252 );
00253 # else
00254 int index= s->index;
00255 uint32_t *ptr= (uint32_t*)(((uint8_t *)s->buf)+(index>>3));
00256
00257 ptr[0] |= av_be2ne32(value<<(32-n-(index&7) ));
00258 ptr[1] = 0;
00259
00260 index+= n;
00261 s->index= index;
00262 # endif
00263 # endif
00264 }
00265 #endif
00266
00267 static inline void put_sbits(PutBitContext *pb, int n, int32_t value)
00268 {
00269 assert(n >= 0 && n <= 31);
00270
00271 put_bits(pb, n, value & ((1<<n)-1));
00272 }
00273
00277 static void av_unused put_bits32(PutBitContext *s, uint32_t value)
00278 {
00279 int lo = value & 0xffff;
00280 int hi = value >> 16;
00281 #ifdef BITSTREAM_WRITER_LE
00282 put_bits(s, 16, lo);
00283 put_bits(s, 16, hi);
00284 #else
00285 put_bits(s, 16, hi);
00286 put_bits(s, 16, lo);
00287 #endif
00288 }
00289
00294 static inline uint8_t* put_bits_ptr(PutBitContext *s)
00295 {
00296 #ifdef ALT_BITSTREAM_WRITER
00297 return s->buf + (s->index>>3);
00298 #else
00299 return s->buf_ptr;
00300 #endif
00301 }
00302
00307 static inline void skip_put_bytes(PutBitContext *s, int n)
00308 {
00309 assert((put_bits_count(s)&7)==0);
00310 #ifdef ALT_BITSTREAM_WRITER
00311 FIXME may need some cleaning of the buffer
00312 s->index += n<<3;
00313 #else
00314 assert(s->bit_left==32);
00315 s->buf_ptr += n;
00316 #endif
00317 }
00318
00324 static inline void skip_put_bits(PutBitContext *s, int n)
00325 {
00326 #ifdef ALT_BITSTREAM_WRITER
00327 s->index += n;
00328 #else
00329 s->bit_left -= n;
00330 s->buf_ptr-= 4*(s->bit_left>>5);
00331 s->bit_left &= 31;
00332 #endif
00333 }
00334
00340 static inline void set_put_bits_buffer_size(PutBitContext *s, int size)
00341 {
00342 s->buf_end= s->buf + size;
00343 }
00344
00345 #endif