X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fbitstream.h;h=5a5db5c9f23dd463b30e5b8bcf79e0969ded6a8e;hb=cb377ec55e975119312c3cc72b9e8924cbbcfc6e;hp=17b5d2b1c5e7bcff1011770f5b2d005425fe8452;hpb=8fbc6aae75403a7bbca595df9d3d3a9d835dc576;p=ffmpeg diff --git a/libavcodec/bitstream.h b/libavcodec/bitstream.h index 17b5d2b1c5e..5a5db5c9f23 100644 --- a/libavcodec/bitstream.h +++ b/libavcodec/bitstream.h @@ -1,35 +1,68 @@ +/* + * copyright (c) 2004 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + /** * @file bitstream.h * bitstream api header. */ -#ifndef BITSTREAM_H -#define BITSTREAM_H +#ifndef AVCODEC_BITSTREAM_H +#define AVCODEC_BITSTREAM_H -#include "log.h" +#include +#include +#include +#include "libavutil/bswap.h" +#include "libavutil/common.h" +#include "libavutil/intreadwrite.h" +#include "libavutil/log.h" + +#if defined(ALT_BITSTREAM_READER_LE) && !defined(ALT_BITSTREAM_READER) +# define ALT_BITSTREAM_READER +#endif //#define ALT_BITSTREAM_WRITER //#define ALIGNED_BITSTREAM_WRITER #if !defined(LIBMPEG2_BITSTREAM_READER) && !defined(A32_BITSTREAM_READER) && !defined(ALT_BITSTREAM_READER) -#define ALT_BITSTREAM_READER +# ifdef ARCH_ARMV4L +# define A32_BITSTREAM_READER +# else +# define ALT_BITSTREAM_READER //#define LIBMPEG2_BITSTREAM_READER //#define A32_BITSTREAM_READER +# endif #endif -#define LIBMPEG2_BITSTREAM_READER_HACK //add BERO extern const uint8_t ff_reverse[256]; -#if defined(ARCH_X86) || defined(ARCH_X86_64) +#if defined(ARCH_X86) // avoid +32 for shift optimization (gcc should do that ...) static inline int32_t NEG_SSR32( int32_t a, int8_t s){ - asm ("sarl %1, %0\n\t" + __asm__ ("sarl %1, %0\n\t" : "+r" (a) : "ic" ((uint8_t)(-s)) ); return a; } static inline uint32_t NEG_USR32(uint32_t a, int8_t s){ - asm ("shrl %1, %0\n\t" + __asm__ ("shrl %1, %0\n\t" : "+r" (a) : "ic" ((uint8_t)(-s)) ); @@ -90,11 +123,18 @@ static inline void flush_put_bits(PutBitContext *s) #ifdef ALT_BITSTREAM_WRITER align_put_bits(s); #else +#ifndef BITSTREAM_WRITER_LE s->bit_buf<<= s->bit_left; +#endif while (s->bit_left < 32) { /* XXX: should test end of buffer */ +#ifdef BITSTREAM_WRITER_LE + *s->buf_ptr++=s->bit_buf; + s->bit_buf>>=8; +#else *s->buf_ptr++=s->bit_buf >> 24; s->bit_buf<<=8; +#endif s->bit_left+=8; } s->bit_left=32; @@ -103,7 +143,8 @@ static inline void flush_put_bits(PutBitContext *s) } void align_put_bits(PutBitContext *s); -void ff_put_string(PutBitContext * pbc, char *s, int put_zero); +void ff_put_string(PutBitContext * pbc, const char *s, int put_zero); +void ff_copy_bits(PutBitContext *pb, const uint8_t *src, int length); /* bit input */ /* buffer, buffer_end and size_in_bits must be present and used by every reader */ @@ -138,42 +179,10 @@ typedef struct RL_VLC_ELEM { uint8_t run; } RL_VLC_ELEM; -#if defined(ARCH_SPARC) || defined(ARCH_ARMV4L) || defined(ARCH_MIPS) +#if defined(ARCH_SPARC) || defined(ARCH_ARMV4L) || defined(ARCH_MIPS) || defined(ARCH_BFIN) #define UNALIGNED_STORES_ARE_BAD #endif -/* used to avoid missaligned exceptions on some archs (alpha, ...) */ -#if defined(ARCH_X86) || defined(ARCH_X86_64) -# define unaligned16(a) (*(const uint16_t*)(a)) -# define unaligned32(a) (*(const uint32_t*)(a)) -# define unaligned64(a) (*(const uint64_t*)(a)) -#else -# ifdef __GNUC__ -# define unaligned(x) \ -static inline uint##x##_t unaligned##x(const void *v) { \ - struct Unaligned { \ - uint##x##_t i; \ - } __attribute__((packed)); \ - \ - return ((const struct Unaligned *) v)->i; \ -} -# elif defined(__DECC) -# define unaligned(x) \ -static inline uint##x##_t unaligned##x##(const void *v) { \ - return *(const __unaligned uint##x##_t *) v; \ -} -# else -# define unaligned(x) \ -static inline uint##x##_t unaligned##x##(const void *v) { \ - return *(const uint##x##_t *) v; \ -} -# endif -unaligned(16) -unaligned(32) -unaligned(64) -#undef unaligned -#endif //!ARCH_X86 - #ifndef ALT_BITSTREAM_WRITER static inline void put_bits(PutBitContext *s, int n, unsigned int value) { @@ -188,6 +197,24 @@ static inline void put_bits(PutBitContext *s, int n, unsigned int value) // printf("n=%d value=%x cnt=%d buf=%x\n", n, value, bit_cnt, bit_buf); /* XXX: optimize */ +#ifdef BITSTREAM_WRITER_LE + bit_buf |= value << (32 - bit_left); + if (n >= bit_left) { +#ifdef UNALIGNED_STORES_ARE_BAD + if (3 & (intptr_t) s->buf_ptr) { + s->buf_ptr[0] = bit_buf ; + s->buf_ptr[1] = bit_buf >> 8; + s->buf_ptr[2] = bit_buf >> 16; + s->buf_ptr[3] = bit_buf >> 24; + } else +#endif + *(uint32_t *)s->buf_ptr = le2me_32(bit_buf); + s->buf_ptr+=4; + bit_buf = (bit_left==32)?0:value >> bit_left; + bit_left+=32; + } + bit_left-=n; +#else if (n < bit_left) { bit_buf = (bit_buf<bit_buf = bit_buf; s->bit_left = bit_left; @@ -219,8 +247,8 @@ static inline void put_bits(PutBitContext *s, int n, unsigned int value) static inline void put_bits(PutBitContext *s, int n, unsigned int value) { # ifdef ALIGNED_BITSTREAM_WRITER -# if defined(ARCH_X86) || defined(ARCH_X86_64) - asm volatile( +# if defined(ARCH_X86) + __asm__ volatile( "movl %0, %%ecx \n\t" "xorl %%eax, %%eax \n\t" "shrdl %%cl, %1, %%eax \n\t" @@ -250,8 +278,8 @@ static inline void put_bits(PutBitContext *s, int n, unsigned int value) s->index= index; # endif # else //ALIGNED_BITSTREAM_WRITER -# if defined(ARCH_X86) || defined(ARCH_X86_64) - asm volatile( +# if defined(ARCH_X86) + __asm__ volatile( "movl $7, %%ecx \n\t" "andl %0, %%ecx \n\t" "addl %3, %%ecx \n\t" @@ -281,6 +309,13 @@ static inline void put_bits(PutBitContext *s, int n, unsigned int value) } #endif +static inline void put_sbits(PutBitContext *pb, int bits, int32_t val) +{ + assert(bits >= 0 && bits <= 31); + + put_bits(pb, bits, val & ((1<buffer)+(name##_index>>3) ) >> (name##_index&0x07);\ + name##_cache= AV_RL32( ((const uint8_t *)(gb)->buffer)+(name##_index>>3) ) >> (name##_index&0x07);\ # define SKIP_CACHE(name, gb, num)\ name##_cache >>= (num); # else # define UPDATE_CACHE(name, gb)\ - name##_cache= unaligned32_be( ((const uint8_t *)(gb)->buffer)+(name##_index>>3) ) << (name##_index&0x07);\ + name##_cache= AV_RB32( ((const uint8_t *)(gb)->buffer)+(name##_index>>3) ) << (name##_index&0x07);\ # define SKIP_CACHE(name, gb, num)\ name##_cache <<= (num); @@ -432,13 +447,16 @@ static inline int unaligned32_le(const void *v) # ifdef ALT_BITSTREAM_READER_LE # define SHOW_UBITS(name, gb, num)\ ((name##_cache) & (NEG_USR32(0xffffffff,num))) + +# define SHOW_SBITS(name, gb, num)\ + NEG_SSR32((name##_cache)<<(32-(num)), num) # else # define SHOW_UBITS(name, gb, num)\ NEG_USR32(name##_cache, num) -# endif # define SHOW_SBITS(name, gb, num)\ NEG_SSR32(name##_cache, num) +# endif # define GET_CACHE(name, gb)\ ((uint32_t)name##_cache) @@ -466,26 +484,13 @@ static inline void skip_bits_long(GetBitContext *s, int n){ (gb)->cache= name##_cache;\ (gb)->buffer_ptr= name##_buffer_ptr;\ -#ifdef LIBMPEG2_BITSTREAM_READER_HACK - -# define UPDATE_CACHE(name, gb)\ - if(name##_bit_count >= 0){\ - name##_cache+= (int)be2me_16(*(uint16_t*)name##_buffer_ptr) << name##_bit_count;\ - name##_buffer_ptr += 2;\ - name##_bit_count-= 16;\ - }\ - -#else - # define UPDATE_CACHE(name, gb)\ if(name##_bit_count >= 0){\ - name##_cache+= ((name##_buffer_ptr[0]<<8) + name##_buffer_ptr[1]) << name##_bit_count;\ + name##_cache+= AV_RB16(name##_buffer_ptr) << name##_bit_count; \ name##_buffer_ptr+=2;\ name##_bit_count-= 16;\ }\ -#endif - # define SKIP_CACHE(name, gb, num)\ name##_cache <<= (num);\ @@ -549,9 +554,9 @@ static inline void skip_bits_long(GetBitContext *s, int n){ name##_bit_count-= 32;\ }\ -#if defined(ARCH_X86) || defined(ARCH_X86_64) +#if defined(ARCH_X86) # define SKIP_CACHE(name, gb, num)\ - asm(\ + __asm__(\ "shldl %2, %1, %0 \n\t"\ "shll %2, %1 \n\t"\ : "+r" (name##_cache0), "+r" (name##_cache1)\ @@ -631,7 +636,7 @@ static inline int get_sbits(GetBitContext *s, int n){ } /** - * reads 0-17 bits. + * reads 1-17 bits. * Note, the alt bitstream reader can read up to 25 bits, but the libmpeg2 reader can't */ static inline unsigned int get_bits(GetBitContext *s, int n){ @@ -645,7 +650,7 @@ static inline unsigned int get_bits(GetBitContext *s, int n){ } /** - * shows 0-17 bits. + * shows 1-17 bits. * Note, the alt bitstream reader can read up to 25 bits, but the libmpeg2 reader can't */ static inline unsigned int show_bits(GetBitContext *s, int n){ @@ -699,8 +704,13 @@ static inline void skip_bits1(GetBitContext *s){ static inline unsigned int get_bits_long(GetBitContext *s, int n){ if(n<=17) return get_bits(s, n); else{ +#ifdef ALT_BITSTREAM_READER_LE + int ret= get_bits(s, 16); + return ret | (get_bits(s, n-16) << 16); +#else int ret= get_bits(s, 16) << (n-16); return ret | get_bits(s, n-16); +#endif } } @@ -757,21 +767,40 @@ static inline void init_get_bits(GetBitContext *s, #endif } -static void align_get_bits(GetBitContext *s) +static inline void align_get_bits(GetBitContext *s) { int n= (-get_bits_count(s)) & 7; if(n) skip_bits(s, n); } -int check_marker(GetBitContext *s, const char *msg); -int init_vlc(VLC *vlc, int nb_bits, int nb_codes, +#define init_vlc(vlc, nb_bits, nb_codes,\ + bits, bits_wrap, bits_size,\ + codes, codes_wrap, codes_size,\ + flags)\ + init_vlc_sparse(vlc, nb_bits, nb_codes,\ + bits, bits_wrap, bits_size,\ + codes, codes_wrap, codes_size,\ + NULL, 0, 0, flags) + +int init_vlc_sparse(VLC *vlc, int nb_bits, int nb_codes, const void *bits, int bits_wrap, int bits_size, const void *codes, int codes_wrap, int codes_size, + const void *symbols, int symbols_wrap, int symbols_size, int flags); -#define INIT_VLC_USE_STATIC 1 +#define INIT_VLC_USE_STATIC 1 ///< VERY strongly deprecated and forbidden #define INIT_VLC_LE 2 +#define INIT_VLC_USE_NEW_STATIC 4 void free_vlc(VLC *vlc); +#define INIT_VLC_STATIC(vlc, bits, a,b,c,d,e,f,g, static_size)\ +{\ + static VLC_TYPE table[static_size][2];\ + (vlc)->table= table;\ + (vlc)->table_allocated= static_size;\ + init_vlc(vlc, bits, a,b,c,d,e,f,g, INIT_VLC_USE_NEW_STATIC);\ +} + + /** * * if the vlc code is invalid and max_depth=1 than no bits will be removed @@ -838,11 +867,11 @@ void free_vlc(VLC *vlc); * parses a vlc code, faster then get_vlc() * @param bits is the number of bits which will be read at once, must be * identical to nb_bits in init_vlc() - * @param max_depth is the number of times bits bits must be readed to completly + * @param max_depth is the number of times bits bits must be read to completely * read the longest vlc code * = (max_vlc_length + bits - 1) / bits */ -static always_inline int get_vlc2(GetBitContext *s, VLC_TYPE (*table)[2], +static av_always_inline int get_vlc2(GetBitContext *s, VLC_TYPE (*table)[2], int bits, int max_depth) { int code; @@ -903,10 +932,10 @@ static inline int get_xbits_trace(GetBitContext *s, int n, char *file, const cha #define get_vlc(s, vlc) get_vlc_trace(s, (vlc)->table, (vlc)->bits, 3, __FILE__, __PRETTY_FUNCTION__, __LINE__) #define get_vlc2(s, tab, bits, max) get_vlc_trace(s, tab, bits, max, __FILE__, __PRETTY_FUNCTION__, __LINE__) -#define tprintf(...) av_log(NULL, AV_LOG_DEBUG, __VA_ARGS__) +#define tprintf(p, ...) av_log(p, AV_LOG_DEBUG, __VA_ARGS__) #else //TRACE -#define tprintf(...) {} +#define tprintf(p, ...) {} #endif static inline int decode012(GetBitContext *gb){ @@ -918,4 +947,11 @@ static inline int decode012(GetBitContext *gb){ return get_bits1(gb) + 1; } -#endif /* BITSTREAM_H */ +static inline int decode210(GetBitContext *gb){ + if (get_bits1(gb)) + return 0; + else + return 2 - get_bits1(gb); +} + +#endif /* AVCODEC_BITSTREAM_H */