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
00038
00039
00040
00041
00042 typedef struct PutBitContext {
00043 #ifdef ALT_BITSTREAM_WRITER
00044 uint8_t *buf, *buf_end;
00045 int index;
00046 #else
00047 uint32_t bit_buf;
00048 int bit_left;
00049 uint8_t *buf, *buf_ptr, *buf_end;
00050 #endif
00051 int size_in_bits;
00052 } PutBitContext;
00053
00060 static inline void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size)
00061 {
00062 if(buffer_size < 0) {
00063 buffer_size = 0;
00064 buffer = NULL;
00065 }
00066
00067 s->size_in_bits= 8*buffer_size;
00068 s->buf = buffer;
00069 s->buf_end = s->buf + buffer_size;
00070 #ifdef ALT_BITSTREAM_WRITER
00071 s->index=0;
00072 ((uint32_t*)(s->buf))[0]=0;
00073
00074 #else
00075 s->buf_ptr = s->buf;
00076 s->bit_left=32;
00077 s->bit_buf=0;
00078 #endif
00079 }
00080
00084 static inline int put_bits_count(PutBitContext *s)
00085 {
00086 #ifdef ALT_BITSTREAM_WRITER
00087 return s->index;
00088 #else
00089 return (s->buf_ptr - s->buf) * 8 + 32 - s->bit_left;
00090 #endif
00091 }
00092
00096 static inline void flush_put_bits(PutBitContext *s)
00097 {
00098 #ifdef ALT_BITSTREAM_WRITER
00099 align_put_bits(s);
00100 #else
00101 #ifndef BITSTREAM_WRITER_LE
00102 s->bit_buf<<= s->bit_left;
00103 #endif
00104 while (s->bit_left < 32) {
00105
00106 #ifdef BITSTREAM_WRITER_LE
00107 *s->buf_ptr++=s->bit_buf;
00108 s->bit_buf>>=8;
00109 #else
00110 *s->buf_ptr++=s->bit_buf >> 24;
00111 s->bit_buf<<=8;
00112 #endif
00113 s->bit_left+=8;
00114 }
00115 s->bit_left=32;
00116 s->bit_buf=0;
00117 #endif
00118 }
00119
00120 #if defined(ALT_BITSTREAM_WRITER) || defined(BITSTREAM_WRITER_LE)
00121 #define align_put_bits align_put_bits_unsupported_here
00122 #define ff_put_string ff_put_string_unsupported_here
00123 #define ff_copy_bits ff_copy_bits_unsupported_here
00124 #else
00125
00128 void align_put_bits(PutBitContext *s);
00129
00135 void ff_put_string(PutBitContext *pb, const char *string, int terminate_string);
00136
00142 void ff_copy_bits(PutBitContext *pb, const uint8_t *src, int length);
00143 #endif
00144
00149 static inline void put_bits(PutBitContext *s, int n, unsigned int value)
00150 #ifndef ALT_BITSTREAM_WRITER
00151 {
00152 unsigned int bit_buf;
00153 int bit_left;
00154
00155
00156 assert(n <= 31 && value < (1U << n));
00157
00158 bit_buf = s->bit_buf;
00159 bit_left = s->bit_left;
00160
00161
00162
00163 #ifdef BITSTREAM_WRITER_LE
00164 bit_buf |= value << (32 - bit_left);
00165 if (n >= bit_left) {
00166 #if !HAVE_FAST_UNALIGNED
00167 if (3 & (intptr_t) s->buf_ptr) {
00168 AV_WL32(s->buf_ptr, bit_buf);
00169 } else
00170 #endif
00171 *(uint32_t *)s->buf_ptr = le2me_32(bit_buf);
00172 s->buf_ptr+=4;
00173 bit_buf = (bit_left==32)?0:value >> bit_left;
00174 bit_left+=32;
00175 }
00176 bit_left-=n;
00177 #else
00178 if (n < bit_left) {
00179 bit_buf = (bit_buf<<n) | value;
00180 bit_left-=n;
00181 } else {
00182 bit_buf<<=bit_left;
00183 bit_buf |= value >> (n - bit_left);
00184 #if !HAVE_FAST_UNALIGNED
00185 if (3 & (intptr_t) s->buf_ptr) {
00186 AV_WB32(s->buf_ptr, bit_buf);
00187 } else
00188 #endif
00189 *(uint32_t *)s->buf_ptr = be2me_32(bit_buf);
00190
00191 s->buf_ptr+=4;
00192 bit_left+=32 - n;
00193 bit_buf = value;
00194 }
00195 #endif
00196
00197 s->bit_buf = bit_buf;
00198 s->bit_left = bit_left;
00199 }
00200 #else
00201 {
00202 # ifdef ALIGNED_BITSTREAM_WRITER
00203 # if ARCH_X86
00204 __asm__ volatile(
00205 "movl %0, %%ecx \n\t"
00206 "xorl %%eax, %%eax \n\t"
00207 "shrdl %%cl, %1, %%eax \n\t"
00208 "shrl %%cl, %1 \n\t"
00209 "movl %0, %%ecx \n\t"
00210 "shrl $3, %%ecx \n\t"
00211 "andl $0xFFFFFFFC, %%ecx \n\t"
00212 "bswapl %1 \n\t"
00213 "orl %1, (%2, %%ecx) \n\t"
00214 "bswapl %%eax \n\t"
00215 "addl %3, %0 \n\t"
00216 "movl %%eax, 4(%2, %%ecx) \n\t"
00217 : "=&r" (s->index), "=&r" (value)
00218 : "r" (s->buf), "r" (n), "0" (s->index), "1" (value<<(-n))
00219 : "%eax", "%ecx"
00220 );
00221 # else
00222 int index= s->index;
00223 uint32_t *ptr= ((uint32_t *)s->buf)+(index>>5);
00224
00225 value<<= 32-n;
00226
00227 ptr[0] |= be2me_32(value>>(index&31));
00228 ptr[1] = be2me_32(value<<(32-(index&31)));
00229
00230 index+= n;
00231 s->index= index;
00232 # endif
00233 # else //ALIGNED_BITSTREAM_WRITER
00234 # if ARCH_X86
00235 __asm__ volatile(
00236 "movl $7, %%ecx \n\t"
00237 "andl %0, %%ecx \n\t"
00238 "addl %3, %%ecx \n\t"
00239 "negl %%ecx \n\t"
00240 "shll %%cl, %1 \n\t"
00241 "bswapl %1 \n\t"
00242 "movl %0, %%ecx \n\t"
00243 "shrl $3, %%ecx \n\t"
00244 "orl %1, (%%ecx, %2) \n\t"
00245 "addl %3, %0 \n\t"
00246 "movl $0, 4(%%ecx, %2) \n\t"
00247 : "=&r" (s->index), "=&r" (value)
00248 : "r" (s->buf), "r" (n), "0" (s->index), "1" (value)
00249 : "%ecx"
00250 );
00251 # else
00252 int index= s->index;
00253 uint32_t *ptr= (uint32_t*)(((uint8_t *)s->buf)+(index>>3));
00254
00255 ptr[0] |= be2me_32(value<<(32-n-(index&7) ));
00256 ptr[1] = 0;
00257
00258 index+= n;
00259 s->index= index;
00260 # endif
00261 # endif
00262 }
00263 #endif
00264
00265 static inline void put_sbits(PutBitContext *pb, int n, int32_t value)
00266 {
00267 assert(n >= 0 && n <= 31);
00268
00269 put_bits(pb, n, value & ((1<<n)-1));
00270 }
00271
00275 static void av_unused put_bits32(PutBitContext *s, uint32_t value)
00276 {
00277 int lo = value & 0xffff;
00278 int hi = value >> 16;
00279 #ifdef BITSTREAM_WRITER_LE
00280 put_bits(s, 16, lo);
00281 put_bits(s, 16, hi);
00282 #else
00283 put_bits(s, 16, hi);
00284 put_bits(s, 16, lo);
00285 #endif
00286 }
00287
00292 static inline uint8_t* put_bits_ptr(PutBitContext *s)
00293 {
00294 #ifdef ALT_BITSTREAM_WRITER
00295 return s->buf + (s->index>>3);
00296 #else
00297 return s->buf_ptr;
00298 #endif
00299 }
00300
00305 static inline void skip_put_bytes(PutBitContext *s, int n)
00306 {
00307 assert((put_bits_count(s)&7)==0);
00308 #ifdef ALT_BITSTREAM_WRITER
00309 FIXME may need some cleaning of the buffer
00310 s->index += n<<3;
00311 #else
00312 assert(s->bit_left==32);
00313 s->buf_ptr += n;
00314 #endif
00315 }
00316
00322 static inline void skip_put_bits(PutBitContext *s, int n)
00323 {
00324 #ifdef ALT_BITSTREAM_WRITER
00325 s->index += n;
00326 #else
00327 s->bit_left -= n;
00328 s->buf_ptr-= 4*(s->bit_left>>5);
00329 s->bit_left &= 31;
00330 #endif
00331 }
00332
00338 static inline void set_put_bits_buffer_size(PutBitContext *s, int size)
00339 {
00340 s->buf_end= s->buf + size;
00341 }
00342
00343 #endif