99683a3077
in the past it was startcode,string,00,7F,startcode now it is startcode,string,stratcode both are mpeg4 compliant, as according to the standard the userdata lasts until the next 00 00 01 (startcode prefix) but some very primitive decoders which simply skip until the first 00 byte and then expect the next valid startcode might fail with the old variant, just a theory though (didnt test if quicktime can decode it now) Originally committed as revision 2767 to svn://svn.ffmpeg.org/ffmpeg/trunk
1174 lines
28 KiB
C
1174 lines
28 KiB
C
/**
|
|
* @file common.h
|
|
* common internal api header.
|
|
*/
|
|
|
|
#ifndef COMMON_H
|
|
#define COMMON_H
|
|
|
|
#if defined(WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
|
|
# define CONFIG_WIN32
|
|
#endif
|
|
|
|
//#define ALT_BITSTREAM_WRITER
|
|
//#define ALIGNED_BITSTREAM_WRITER
|
|
|
|
#define ALT_BITSTREAM_READER
|
|
//#define LIBMPEG2_BITSTREAM_READER
|
|
//#define A32_BITSTREAM_READER
|
|
#define LIBMPEG2_BITSTREAM_READER_HACK //add BERO
|
|
|
|
#ifndef M_PI
|
|
#define M_PI 3.14159265358979323846
|
|
#endif
|
|
|
|
#ifdef HAVE_AV_CONFIG_H
|
|
/* only include the following when compiling package */
|
|
# include "config.h"
|
|
|
|
# include <stdlib.h>
|
|
# include <stdio.h>
|
|
# include <string.h>
|
|
# include <ctype.h>
|
|
# ifndef __BEOS__
|
|
# include <errno.h>
|
|
# else
|
|
# include "berrno.h"
|
|
# endif
|
|
# include <math.h>
|
|
|
|
# ifndef ENODATA
|
|
# define ENODATA 61
|
|
# endif
|
|
|
|
#include <stddef.h>
|
|
#ifndef offsetof
|
|
# define offsetof(T,F) ((unsigned int)((char *)&((T *)0)->F))
|
|
#endif
|
|
|
|
#define AVOPTION_CODEC_BOOL(name, help, field) \
|
|
{ name, help, offsetof(AVCodecContext, field), FF_OPT_TYPE_BOOL }
|
|
#define AVOPTION_CODEC_DOUBLE(name, help, field, minv, maxv, defval) \
|
|
{ name, help, offsetof(AVCodecContext, field), FF_OPT_TYPE_DOUBLE, minv, maxv, defval }
|
|
#define AVOPTION_CODEC_FLAG(name, help, field, flag, defval) \
|
|
{ name, help, offsetof(AVCodecContext, field), FF_OPT_TYPE_FLAG, flag, 0, defval }
|
|
#define AVOPTION_CODEC_INT(name, help, field, minv, maxv, defval) \
|
|
{ name, help, offsetof(AVCodecContext, field), FF_OPT_TYPE_INT, minv, maxv, defval }
|
|
#define AVOPTION_CODEC_STRING(name, help, field, str, val) \
|
|
{ name, help, offsetof(AVCodecContext, field), FF_OPT_TYPE_STRING, .defval = val, .defstr = str }
|
|
#define AVOPTION_CODEC_RCOVERRIDE(name, help, field) \
|
|
{ name, help, offsetof(AVCodecContext, field), FF_OPT_TYPE_RCOVERRIDE, .defval = 0, .defstr = NULL }
|
|
#define AVOPTION_SUB(ptr) { .name = NULL, .help = (const char*)ptr }
|
|
#define AVOPTION_END() AVOPTION_SUB(NULL)
|
|
|
|
struct AVOption;
|
|
#ifdef HAVE_MMX
|
|
extern const struct AVOption avoptions_common[3 + 5];
|
|
#else
|
|
extern const struct AVOption avoptions_common[3];
|
|
#endif
|
|
extern const struct AVOption avoptions_workaround_bug[11];
|
|
|
|
#endif /* HAVE_AV_CONFIG_H */
|
|
|
|
/* Suppress restrict if it was not defined in config.h. */
|
|
#ifndef restrict
|
|
# define restrict
|
|
#endif
|
|
|
|
#if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 0)
|
|
# define always_inline __attribute__((always_inline)) inline
|
|
#else
|
|
# define always_inline inline
|
|
#endif
|
|
|
|
#ifndef EMULATE_INTTYPES
|
|
# include <inttypes.h>
|
|
#else
|
|
typedef signed char int8_t;
|
|
typedef signed short int16_t;
|
|
typedef signed int int32_t;
|
|
typedef unsigned char uint8_t;
|
|
typedef unsigned short uint16_t;
|
|
typedef unsigned int uint32_t;
|
|
|
|
# ifdef CONFIG_WIN32
|
|
typedef signed __int64 int64_t;
|
|
typedef unsigned __int64 uint64_t;
|
|
# else /* other OS */
|
|
typedef signed long long int64_t;
|
|
typedef unsigned long long uint64_t;
|
|
# endif /* other OS */
|
|
#endif /* HAVE_INTTYPES_H */
|
|
|
|
#ifndef INT64_MAX
|
|
#define INT64_MAX 9223372036854775807LL
|
|
#endif
|
|
|
|
#ifdef EMULATE_FAST_INT
|
|
/* note that we don't emulate 64bit ints */
|
|
typedef signed char int_fast8_t;
|
|
typedef signed int int_fast16_t;
|
|
typedef signed int int_fast32_t;
|
|
typedef unsigned char uint_fast8_t;
|
|
typedef unsigned int uint_fast16_t;
|
|
typedef unsigned int uint_fast32_t;
|
|
#endif
|
|
|
|
#if defined(CONFIG_OS2) || defined(CONFIG_SUNOS)
|
|
static inline float floorf(float f) {
|
|
return floor(f);
|
|
}
|
|
#endif
|
|
|
|
#ifdef CONFIG_WIN32
|
|
|
|
/* windows */
|
|
|
|
# ifndef __MINGW32__
|
|
# define int64_t_C(c) (c ## i64)
|
|
# define uint64_t_C(c) (c ## i64)
|
|
|
|
# ifdef HAVE_AV_CONFIG_H
|
|
# define inline __inline
|
|
# endif
|
|
|
|
# else
|
|
# define int64_t_C(c) (c ## LL)
|
|
# define uint64_t_C(c) (c ## ULL)
|
|
# endif /* __MINGW32__ */
|
|
|
|
# ifdef HAVE_AV_CONFIG_H
|
|
# ifdef _DEBUG
|
|
# define DEBUG
|
|
# endif
|
|
|
|
# define snprintf _snprintf
|
|
# define vsnprintf _vsnprintf
|
|
# endif
|
|
|
|
/* CONFIG_WIN32 end */
|
|
#elif defined (CONFIG_OS2)
|
|
/* OS/2 EMX */
|
|
|
|
#ifndef int64_t_C
|
|
#define int64_t_C(c) (c ## LL)
|
|
#define uint64_t_C(c) (c ## ULL)
|
|
#endif
|
|
|
|
#ifdef HAVE_AV_CONFIG_H
|
|
|
|
#ifdef USE_FASTMEMCPY
|
|
#include "fastmemcpy.h"
|
|
#endif
|
|
|
|
#include <float.h>
|
|
|
|
#endif /* HAVE_AV_CONFIG_H */
|
|
|
|
/* CONFIG_OS2 end */
|
|
#else
|
|
|
|
/* unix */
|
|
|
|
#ifndef int64_t_C
|
|
#define int64_t_C(c) (c ## LL)
|
|
#define uint64_t_C(c) (c ## ULL)
|
|
#endif
|
|
|
|
#ifdef HAVE_AV_CONFIG_H
|
|
|
|
# ifdef USE_FASTMEMCPY
|
|
# include "fastmemcpy.h"
|
|
# endif
|
|
# endif /* HAVE_AV_CONFIG_H */
|
|
|
|
#endif /* !CONFIG_WIN32 && !CONFIG_OS2 */
|
|
|
|
#ifdef HAVE_AV_CONFIG_H
|
|
|
|
# include "bswap.h"
|
|
|
|
# if defined(__MINGW32__) || defined(__CYGWIN__) || \
|
|
defined(__OS2__) || (defined (__OpenBSD__) && !defined(__ELF__))
|
|
# define MANGLE(a) "_" #a
|
|
# else
|
|
# define MANGLE(a) #a
|
|
# endif
|
|
|
|
/* debug stuff */
|
|
|
|
# ifndef DEBUG
|
|
# define NDEBUG
|
|
# endif
|
|
# include <assert.h>
|
|
|
|
/* dprintf macros */
|
|
# if defined(CONFIG_WIN32) && !defined(__MINGW32__)
|
|
|
|
inline void dprintf(const char* fmt,...) {}
|
|
|
|
# else
|
|
|
|
# ifdef DEBUG
|
|
# define dprintf(fmt,...) printf(fmt, __VA_ARGS__)
|
|
# else
|
|
# define dprintf(fmt,...)
|
|
# endif
|
|
|
|
# endif /* !CONFIG_WIN32 */
|
|
|
|
# define av_abort() do { av_log(NULL, AV_LOG_ERROR, "Abort at %s:%d\n", __FILE__, __LINE__); abort(); } while (0)
|
|
|
|
//rounded divison & shift
|
|
#define RSHIFT(a,b) ((a) > 0 ? ((a) + (1<<((b)-1)))>>(b) : ((a) + (1<<((b)-1))-1)>>(b))
|
|
/* assume b>0 */
|
|
#define ROUNDED_DIV(a,b) (((a)>0 ? (a) + ((b)>>1) : (a) - ((b)>>1))/(b))
|
|
#define ABS(a) ((a) >= 0 ? (a) : (-(a)))
|
|
|
|
#define FFMAX(a,b) ((a) > (b) ? (a) : (b))
|
|
#define FFMIN(a,b) ((a) > (b) ? (b) : (a))
|
|
|
|
extern const uint32_t inverse[256];
|
|
|
|
#ifdef ARCH_X86
|
|
# define FASTDIV(a,b) \
|
|
({\
|
|
int ret,dmy;\
|
|
asm volatile(\
|
|
"mull %3"\
|
|
:"=d"(ret),"=a"(dmy)\
|
|
:"1"(a),"g"(inverse[b])\
|
|
);\
|
|
ret;\
|
|
})
|
|
#elif defined(CONFIG_FASTDIV)
|
|
# define FASTDIV(a,b) ((uint32_t)((((uint64_t)a)*inverse[b])>>32))
|
|
#else
|
|
# define FASTDIV(a,b) ((a)/(b))
|
|
#endif
|
|
|
|
#ifdef 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"
|
|
: "+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"
|
|
: "+r" (a)
|
|
: "ic" ((uint8_t)(-s))
|
|
);
|
|
return a;
|
|
}
|
|
#else
|
|
# define NEG_SSR32(a,s) ((( int32_t)(a))>>(32-(s)))
|
|
# define NEG_USR32(a,s) (((uint32_t)(a))>>(32-(s)))
|
|
#endif
|
|
|
|
/* bit output */
|
|
|
|
struct PutBitContext;
|
|
|
|
typedef void (*WriteDataFunc)(void *, uint8_t *, int);
|
|
|
|
typedef struct PutBitContext {
|
|
#ifdef ALT_BITSTREAM_WRITER
|
|
uint8_t *buf, *buf_end;
|
|
int index;
|
|
#else
|
|
uint32_t bit_buf;
|
|
int bit_left;
|
|
uint8_t *buf, *buf_ptr, *buf_end;
|
|
#endif
|
|
} PutBitContext;
|
|
|
|
void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size);
|
|
|
|
int put_bits_count(PutBitContext *s);
|
|
void align_put_bits(PutBitContext *s);
|
|
void flush_put_bits(PutBitContext *s);
|
|
void put_string(PutBitContext * pbc, char *s, int put_zero);
|
|
|
|
/* bit input */
|
|
|
|
typedef struct GetBitContext {
|
|
const uint8_t *buffer, *buffer_end;
|
|
#ifdef ALT_BITSTREAM_READER
|
|
int index;
|
|
#elif defined LIBMPEG2_BITSTREAM_READER
|
|
uint8_t *buffer_ptr;
|
|
uint32_t cache;
|
|
int bit_count;
|
|
#elif defined A32_BITSTREAM_READER
|
|
uint32_t *buffer_ptr;
|
|
uint32_t cache0;
|
|
uint32_t cache1;
|
|
int bit_count;
|
|
#endif
|
|
int size_in_bits;
|
|
} GetBitContext;
|
|
|
|
static inline int get_bits_count(GetBitContext *s);
|
|
|
|
#define VLC_TYPE int16_t
|
|
|
|
typedef struct VLC {
|
|
int bits;
|
|
VLC_TYPE (*table)[2]; ///< code, bits
|
|
int table_size, table_allocated;
|
|
} VLC;
|
|
|
|
typedef struct RL_VLC_ELEM {
|
|
int16_t level;
|
|
int8_t len;
|
|
uint8_t run;
|
|
} RL_VLC_ELEM;
|
|
|
|
#ifdef ARCH_SPARC64
|
|
#define UNALIGNED_STORES_ARE_BAD
|
|
#endif
|
|
|
|
/* used to avoid missaligned exceptions on some archs (alpha, ...) */
|
|
#ifdef ARCH_X86
|
|
# define unaligned32(a) (*(uint32_t*)(a))
|
|
#else
|
|
# ifdef __GNUC__
|
|
static inline uint32_t unaligned32(const void *v) {
|
|
struct Unaligned {
|
|
uint32_t i;
|
|
} __attribute__((packed));
|
|
|
|
return ((const struct Unaligned *) v)->i;
|
|
}
|
|
# elif defined(__DECC)
|
|
static inline uint32_t unaligned32(const void *v) {
|
|
return *(const __unaligned uint32_t *) v;
|
|
}
|
|
# else
|
|
static inline uint32_t unaligned32(const void *v) {
|
|
return *(const uint32_t *) v;
|
|
}
|
|
# endif
|
|
#endif //!ARCH_X86
|
|
|
|
#ifndef ALT_BITSTREAM_WRITER
|
|
static inline void put_bits(PutBitContext *s, int n, unsigned int value)
|
|
{
|
|
unsigned int bit_buf;
|
|
int bit_left;
|
|
|
|
#ifdef STATS
|
|
st_out_bit_counts[st_current_index] += n;
|
|
#endif
|
|
// printf("put_bits=%d %x\n", n, value);
|
|
assert(n == 32 || value < (1U << n));
|
|
|
|
bit_buf = s->bit_buf;
|
|
bit_left = s->bit_left;
|
|
|
|
// printf("n=%d value=%x cnt=%d buf=%x\n", n, value, bit_cnt, bit_buf);
|
|
/* XXX: optimize */
|
|
if (n < bit_left) {
|
|
bit_buf = (bit_buf<<n) | value;
|
|
bit_left-=n;
|
|
} else {
|
|
bit_buf<<=bit_left;
|
|
bit_buf |= value >> (n - bit_left);
|
|
#ifdef UNALIGNED_STORES_ARE_BAD
|
|
if (3 & (int) s->buf_ptr) {
|
|
s->buf_ptr[0] = bit_buf >> 24;
|
|
s->buf_ptr[1] = bit_buf >> 16;
|
|
s->buf_ptr[2] = bit_buf >> 8;
|
|
s->buf_ptr[3] = bit_buf ;
|
|
} else
|
|
#endif
|
|
*(uint32_t *)s->buf_ptr = be2me_32(bit_buf);
|
|
//printf("bitbuf = %08x\n", bit_buf);
|
|
s->buf_ptr+=4;
|
|
bit_left+=32 - n;
|
|
bit_buf = value;
|
|
}
|
|
|
|
s->bit_buf = bit_buf;
|
|
s->bit_left = bit_left;
|
|
}
|
|
#endif
|
|
|
|
|
|
#ifdef ALT_BITSTREAM_WRITER
|
|
static inline void put_bits(PutBitContext *s, int n, unsigned int value)
|
|
{
|
|
# ifdef ALIGNED_BITSTREAM_WRITER
|
|
# ifdef ARCH_X86
|
|
asm volatile(
|
|
"movl %0, %%ecx \n\t"
|
|
"xorl %%eax, %%eax \n\t"
|
|
"shrdl %%cl, %1, %%eax \n\t"
|
|
"shrl %%cl, %1 \n\t"
|
|
"movl %0, %%ecx \n\t"
|
|
"shrl $3, %%ecx \n\t"
|
|
"andl $0xFFFFFFFC, %%ecx \n\t"
|
|
"bswapl %1 \n\t"
|
|
"orl %1, (%2, %%ecx) \n\t"
|
|
"bswapl %%eax \n\t"
|
|
"addl %3, %0 \n\t"
|
|
"movl %%eax, 4(%2, %%ecx) \n\t"
|
|
: "=&r" (s->index), "=&r" (value)
|
|
: "r" (s->buf), "r" (n), "0" (s->index), "1" (value<<(-n))
|
|
: "%eax", "%ecx"
|
|
);
|
|
# else
|
|
int index= s->index;
|
|
uint32_t *ptr= ((uint32_t *)s->buf)+(index>>5);
|
|
|
|
value<<= 32-n;
|
|
|
|
ptr[0] |= be2me_32(value>>(index&31));
|
|
ptr[1] = be2me_32(value<<(32-(index&31)));
|
|
//if(n>24) printf("%d %d\n", n, value);
|
|
index+= n;
|
|
s->index= index;
|
|
# endif
|
|
# else //ALIGNED_BITSTREAM_WRITER
|
|
# ifdef ARCH_X86
|
|
asm volatile(
|
|
"movl $7, %%ecx \n\t"
|
|
"andl %0, %%ecx \n\t"
|
|
"addl %3, %%ecx \n\t"
|
|
"negl %%ecx \n\t"
|
|
"shll %%cl, %1 \n\t"
|
|
"bswapl %1 \n\t"
|
|
"movl %0, %%ecx \n\t"
|
|
"shrl $3, %%ecx \n\t"
|
|
"orl %1, (%%ecx, %2) \n\t"
|
|
"addl %3, %0 \n\t"
|
|
"movl $0, 4(%%ecx, %2) \n\t"
|
|
: "=&r" (s->index), "=&r" (value)
|
|
: "r" (s->buf), "r" (n), "0" (s->index), "1" (value)
|
|
: "%ecx"
|
|
);
|
|
# else
|
|
int index= s->index;
|
|
uint32_t *ptr= (uint32_t*)(((uint8_t *)s->buf)+(index>>3));
|
|
|
|
ptr[0] |= be2me_32(value<<(32-n-(index&7) ));
|
|
ptr[1] = 0;
|
|
//if(n>24) printf("%d %d\n", n, value);
|
|
index+= n;
|
|
s->index= index;
|
|
# endif
|
|
# endif //!ALIGNED_BITSTREAM_WRITER
|
|
}
|
|
#endif
|
|
|
|
|
|
static inline uint8_t* pbBufPtr(PutBitContext *s)
|
|
{
|
|
#ifdef ALT_BITSTREAM_WRITER
|
|
return s->buf + (s->index>>3);
|
|
#else
|
|
return s->buf_ptr;
|
|
#endif
|
|
}
|
|
|
|
/* Bitstream reader API docs:
|
|
name
|
|
abritary name which is used as prefix for the internal variables
|
|
|
|
gb
|
|
getbitcontext
|
|
|
|
OPEN_READER(name, gb)
|
|
loads gb into local variables
|
|
|
|
CLOSE_READER(name, gb)
|
|
stores local vars in gb
|
|
|
|
UPDATE_CACHE(name, gb)
|
|
refills the internal cache from the bitstream
|
|
after this call at least MIN_CACHE_BITS will be available,
|
|
|
|
GET_CACHE(name, gb)
|
|
will output the contents of the internal cache, next bit is MSB of 32 or 64 bit (FIXME 64bit)
|
|
|
|
SHOW_UBITS(name, gb, num)
|
|
will return the nest num bits
|
|
|
|
SHOW_SBITS(name, gb, num)
|
|
will return the nest num bits and do sign extension
|
|
|
|
SKIP_BITS(name, gb, num)
|
|
will skip over the next num bits
|
|
note, this is equinvalent to SKIP_CACHE; SKIP_COUNTER
|
|
|
|
SKIP_CACHE(name, gb, num)
|
|
will remove the next num bits from the cache (note SKIP_COUNTER MUST be called before UPDATE_CACHE / CLOSE_READER)
|
|
|
|
SKIP_COUNTER(name, gb, num)
|
|
will increment the internal bit counter (see SKIP_CACHE & SKIP_BITS)
|
|
|
|
LAST_SKIP_CACHE(name, gb, num)
|
|
will remove the next num bits from the cache if it is needed for UPDATE_CACHE otherwise it will do nothing
|
|
|
|
LAST_SKIP_BITS(name, gb, num)
|
|
is equinvalent to SKIP_LAST_CACHE; SKIP_COUNTER
|
|
|
|
for examples see get_bits, show_bits, skip_bits, get_vlc
|
|
*/
|
|
|
|
static inline int unaligned32_be(const void *v)
|
|
{
|
|
#ifdef CONFIG_ALIGN
|
|
const uint8_t *p=v;
|
|
return (((p[0]<<8) | p[1])<<16) | (p[2]<<8) | (p[3]);
|
|
#else
|
|
return be2me_32( unaligned32(v)); //original
|
|
#endif
|
|
}
|
|
|
|
#ifdef ALT_BITSTREAM_READER
|
|
# define MIN_CACHE_BITS 25
|
|
|
|
# define OPEN_READER(name, gb)\
|
|
int name##_index= (gb)->index;\
|
|
int name##_cache= 0;\
|
|
|
|
# define CLOSE_READER(name, gb)\
|
|
(gb)->index= name##_index;\
|
|
|
|
# define UPDATE_CACHE(name, gb)\
|
|
name##_cache= unaligned32_be( ((uint8_t *)(gb)->buffer)+(name##_index>>3) ) << (name##_index&0x07);\
|
|
|
|
# define SKIP_CACHE(name, gb, num)\
|
|
name##_cache <<= (num);\
|
|
|
|
// FIXME name?
|
|
# define SKIP_COUNTER(name, gb, num)\
|
|
name##_index += (num);\
|
|
|
|
# define SKIP_BITS(name, gb, num)\
|
|
{\
|
|
SKIP_CACHE(name, gb, num)\
|
|
SKIP_COUNTER(name, gb, num)\
|
|
}\
|
|
|
|
# define LAST_SKIP_BITS(name, gb, num) SKIP_COUNTER(name, gb, num)
|
|
# define LAST_SKIP_CACHE(name, gb, num) ;
|
|
|
|
# define SHOW_UBITS(name, gb, num)\
|
|
NEG_USR32(name##_cache, num)
|
|
|
|
# define SHOW_SBITS(name, gb, num)\
|
|
NEG_SSR32(name##_cache, num)
|
|
|
|
# define GET_CACHE(name, gb)\
|
|
((uint32_t)name##_cache)
|
|
|
|
static inline int get_bits_count(GetBitContext *s){
|
|
return s->index;
|
|
}
|
|
#elif defined LIBMPEG2_BITSTREAM_READER
|
|
//libmpeg2 like reader
|
|
|
|
# define MIN_CACHE_BITS 17
|
|
|
|
# define OPEN_READER(name, gb)\
|
|
int name##_bit_count=(gb)->bit_count;\
|
|
int name##_cache= (gb)->cache;\
|
|
uint8_t * name##_buffer_ptr=(gb)->buffer_ptr;\
|
|
|
|
# define CLOSE_READER(name, gb)\
|
|
(gb)->bit_count= name##_bit_count;\
|
|
(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;\
|
|
((uint16_t*)name##_buffer_ptr)++;\
|
|
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##_buffer_ptr+=2;\
|
|
name##_bit_count-= 16;\
|
|
}\
|
|
|
|
#endif
|
|
|
|
# define SKIP_CACHE(name, gb, num)\
|
|
name##_cache <<= (num);\
|
|
|
|
# define SKIP_COUNTER(name, gb, num)\
|
|
name##_bit_count += (num);\
|
|
|
|
# define SKIP_BITS(name, gb, num)\
|
|
{\
|
|
SKIP_CACHE(name, gb, num)\
|
|
SKIP_COUNTER(name, gb, num)\
|
|
}\
|
|
|
|
# define LAST_SKIP_BITS(name, gb, num) SKIP_BITS(name, gb, num)
|
|
# define LAST_SKIP_CACHE(name, gb, num) SKIP_CACHE(name, gb, num)
|
|
|
|
# define SHOW_UBITS(name, gb, num)\
|
|
NEG_USR32(name##_cache, num)
|
|
|
|
# define SHOW_SBITS(name, gb, num)\
|
|
NEG_SSR32(name##_cache, num)
|
|
|
|
# define GET_CACHE(name, gb)\
|
|
((uint32_t)name##_cache)
|
|
|
|
static inline int get_bits_count(GetBitContext *s){
|
|
return (s->buffer_ptr - s->buffer)*8 - 16 + s->bit_count;
|
|
}
|
|
|
|
#elif defined A32_BITSTREAM_READER
|
|
|
|
# define MIN_CACHE_BITS 32
|
|
|
|
# define OPEN_READER(name, gb)\
|
|
int name##_bit_count=(gb)->bit_count;\
|
|
uint32_t name##_cache0= (gb)->cache0;\
|
|
uint32_t name##_cache1= (gb)->cache1;\
|
|
uint32_t * name##_buffer_ptr=(gb)->buffer_ptr;\
|
|
|
|
# define CLOSE_READER(name, gb)\
|
|
(gb)->bit_count= name##_bit_count;\
|
|
(gb)->cache0= name##_cache0;\
|
|
(gb)->cache1= name##_cache1;\
|
|
(gb)->buffer_ptr= name##_buffer_ptr;\
|
|
|
|
# define UPDATE_CACHE(name, gb)\
|
|
if(name##_bit_count > 0){\
|
|
const uint32_t next= be2me_32( *name##_buffer_ptr );\
|
|
name##_cache0 |= NEG_USR32(next,name##_bit_count);\
|
|
name##_cache1 |= next<<name##_bit_count;\
|
|
name##_buffer_ptr++;\
|
|
name##_bit_count-= 32;\
|
|
}\
|
|
|
|
#ifdef ARCH_X86
|
|
# define SKIP_CACHE(name, gb, num)\
|
|
asm(\
|
|
"shldl %2, %1, %0 \n\t"\
|
|
"shll %2, %1 \n\t"\
|
|
: "+r" (name##_cache0), "+r" (name##_cache1)\
|
|
: "Ic" ((uint8_t)num)\
|
|
);
|
|
#else
|
|
# define SKIP_CACHE(name, gb, num)\
|
|
name##_cache0 <<= (num);\
|
|
name##_cache0 |= NEG_USR32(name##_cache1,num);\
|
|
name##_cache1 <<= (num);
|
|
#endif
|
|
|
|
# define SKIP_COUNTER(name, gb, num)\
|
|
name##_bit_count += (num);\
|
|
|
|
# define SKIP_BITS(name, gb, num)\
|
|
{\
|
|
SKIP_CACHE(name, gb, num)\
|
|
SKIP_COUNTER(name, gb, num)\
|
|
}\
|
|
|
|
# define LAST_SKIP_BITS(name, gb, num) SKIP_BITS(name, gb, num)
|
|
# define LAST_SKIP_CACHE(name, gb, num) SKIP_CACHE(name, gb, num)
|
|
|
|
# define SHOW_UBITS(name, gb, num)\
|
|
NEG_USR32(name##_cache0, num)
|
|
|
|
# define SHOW_SBITS(name, gb, num)\
|
|
NEG_SSR32(name##_cache0, num)
|
|
|
|
# define GET_CACHE(name, gb)\
|
|
(name##_cache0)
|
|
|
|
static inline int get_bits_count(GetBitContext *s){
|
|
return ((uint8_t*)s->buffer_ptr - s->buffer)*8 - 32 + s->bit_count;
|
|
}
|
|
|
|
#endif
|
|
|
|
/**
|
|
* read mpeg1 dc style vlc (sign bit + mantisse with no MSB).
|
|
* if MSB not set it is negative
|
|
* @param n length in bits
|
|
* @author BERO
|
|
*/
|
|
static inline int get_xbits(GetBitContext *s, int n){
|
|
register int tmp;
|
|
register int32_t cache;
|
|
OPEN_READER(re, s)
|
|
UPDATE_CACHE(re, s)
|
|
cache = GET_CACHE(re,s);
|
|
if ((int32_t)cache<0) { //MSB=1
|
|
tmp = NEG_USR32(cache,n);
|
|
} else {
|
|
// tmp = (-1<<n) | NEG_USR32(cache,n) + 1; mpeg12.c algo
|
|
// tmp = - (NEG_USR32(cache,n) ^ ((1 << n) - 1)); h263.c algo
|
|
tmp = - NEG_USR32(~cache,n);
|
|
}
|
|
LAST_SKIP_BITS(re, s, n)
|
|
CLOSE_READER(re, s)
|
|
return tmp;
|
|
}
|
|
|
|
static inline int get_sbits(GetBitContext *s, int n){
|
|
register int tmp;
|
|
OPEN_READER(re, s)
|
|
UPDATE_CACHE(re, s)
|
|
tmp= SHOW_SBITS(re, s, n);
|
|
LAST_SKIP_BITS(re, s, n)
|
|
CLOSE_READER(re, s)
|
|
return tmp;
|
|
}
|
|
|
|
/**
|
|
* reads 0-17 bits.
|
|
* Note, the alt bitstream reader can read upto 25 bits, but the libmpeg2 reader cant
|
|
*/
|
|
static inline unsigned int get_bits(GetBitContext *s, int n){
|
|
register int tmp;
|
|
OPEN_READER(re, s)
|
|
UPDATE_CACHE(re, s)
|
|
tmp= SHOW_UBITS(re, s, n);
|
|
LAST_SKIP_BITS(re, s, n)
|
|
CLOSE_READER(re, s)
|
|
return tmp;
|
|
}
|
|
|
|
unsigned int get_bits_long(GetBitContext *s, int n);
|
|
|
|
/**
|
|
* shows 0-17 bits.
|
|
* Note, the alt bitstream reader can read upto 25 bits, but the libmpeg2 reader cant
|
|
*/
|
|
static inline unsigned int show_bits(GetBitContext *s, int n){
|
|
register int tmp;
|
|
OPEN_READER(re, s)
|
|
UPDATE_CACHE(re, s)
|
|
tmp= SHOW_UBITS(re, s, n);
|
|
// CLOSE_READER(re, s)
|
|
return tmp;
|
|
}
|
|
|
|
unsigned int show_bits_long(GetBitContext *s, int n);
|
|
|
|
static inline void skip_bits(GetBitContext *s, int n){
|
|
//Note gcc seems to optimize this to s->index+=n for the ALT_READER :))
|
|
OPEN_READER(re, s)
|
|
UPDATE_CACHE(re, s)
|
|
LAST_SKIP_BITS(re, s, n)
|
|
CLOSE_READER(re, s)
|
|
}
|
|
|
|
static inline unsigned int get_bits1(GetBitContext *s){
|
|
#ifdef ALT_BITSTREAM_READER
|
|
int index= s->index;
|
|
uint8_t result= s->buffer[ index>>3 ];
|
|
result<<= (index&0x07);
|
|
result>>= 8 - 1;
|
|
index++;
|
|
s->index= index;
|
|
|
|
return result;
|
|
#else
|
|
return get_bits(s, 1);
|
|
#endif
|
|
}
|
|
|
|
static inline unsigned int show_bits1(GetBitContext *s){
|
|
return show_bits(s, 1);
|
|
}
|
|
|
|
static inline void skip_bits1(GetBitContext *s){
|
|
skip_bits(s, 1);
|
|
}
|
|
|
|
void init_get_bits(GetBitContext *s,
|
|
const uint8_t *buffer, int buffer_size);
|
|
|
|
int check_marker(GetBitContext *s, const char *msg);
|
|
void align_get_bits(GetBitContext *s);
|
|
int init_vlc(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);
|
|
void free_vlc(VLC *vlc);
|
|
|
|
/**
|
|
*
|
|
* if the vlc code is invalid and max_depth=1 than no bits will be removed
|
|
* if the vlc code is invalid and max_depth>1 than the number of bits removed
|
|
* is undefined
|
|
*/
|
|
#define GET_VLC(code, name, gb, table, bits, max_depth)\
|
|
{\
|
|
int n, index, nb_bits;\
|
|
\
|
|
index= SHOW_UBITS(name, gb, bits);\
|
|
code = table[index][0];\
|
|
n = table[index][1];\
|
|
\
|
|
if(max_depth > 1 && n < 0){\
|
|
LAST_SKIP_BITS(name, gb, bits)\
|
|
UPDATE_CACHE(name, gb)\
|
|
\
|
|
nb_bits = -n;\
|
|
\
|
|
index= SHOW_UBITS(name, gb, nb_bits) + code;\
|
|
code = table[index][0];\
|
|
n = table[index][1];\
|
|
if(max_depth > 2 && n < 0){\
|
|
LAST_SKIP_BITS(name, gb, nb_bits)\
|
|
UPDATE_CACHE(name, gb)\
|
|
\
|
|
nb_bits = -n;\
|
|
\
|
|
index= SHOW_UBITS(name, gb, nb_bits) + code;\
|
|
code = table[index][0];\
|
|
n = table[index][1];\
|
|
}\
|
|
}\
|
|
SKIP_BITS(name, gb, n)\
|
|
}
|
|
|
|
#define GET_RL_VLC(level, run, name, gb, table, bits, max_depth)\
|
|
{\
|
|
int n, index, nb_bits;\
|
|
\
|
|
index= SHOW_UBITS(name, gb, bits);\
|
|
level = table[index].level;\
|
|
n = table[index].len;\
|
|
\
|
|
if(max_depth > 1 && n < 0){\
|
|
LAST_SKIP_BITS(name, gb, bits)\
|
|
UPDATE_CACHE(name, gb)\
|
|
\
|
|
nb_bits = -n;\
|
|
\
|
|
index= SHOW_UBITS(name, gb, nb_bits) + level;\
|
|
level = table[index].level;\
|
|
n = table[index].len;\
|
|
}\
|
|
run= table[index].run;\
|
|
SKIP_BITS(name, gb, n)\
|
|
}
|
|
|
|
// deprecated, dont use get_vlc for new code, use get_vlc2 instead or use GET_VLC directly
|
|
static inline int get_vlc(GetBitContext *s, VLC *vlc)
|
|
{
|
|
int code;
|
|
VLC_TYPE (*table)[2]= vlc->table;
|
|
|
|
OPEN_READER(re, s)
|
|
UPDATE_CACHE(re, s)
|
|
|
|
GET_VLC(code, re, s, table, vlc->bits, 3)
|
|
|
|
CLOSE_READER(re, s)
|
|
return code;
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
* read the longest vlc code
|
|
* = (max_vlc_length + bits - 1) / bits
|
|
*/
|
|
static always_inline int get_vlc2(GetBitContext *s, VLC_TYPE (*table)[2],
|
|
int bits, int max_depth)
|
|
{
|
|
int code;
|
|
|
|
OPEN_READER(re, s)
|
|
UPDATE_CACHE(re, s)
|
|
|
|
GET_VLC(code, re, s, table, bits, max_depth)
|
|
|
|
CLOSE_READER(re, s)
|
|
return code;
|
|
}
|
|
|
|
//#define TRACE
|
|
|
|
#ifdef TRACE
|
|
|
|
static inline void print_bin(int bits, int n){
|
|
int i;
|
|
|
|
for(i=n-1; i>=0; i--){
|
|
printf("%d", (bits>>i)&1);
|
|
}
|
|
for(i=n; i<24; i++)
|
|
printf(" ");
|
|
}
|
|
|
|
static inline int get_bits_trace(GetBitContext *s, int n, char *file, char *func, int line){
|
|
int r= get_bits(s, n);
|
|
|
|
print_bin(r, n);
|
|
printf("%5d %2d %3d bit @%5d in %s %s:%d\n", r, n, r, get_bits_count(s)-n, file, func, line);
|
|
return r;
|
|
}
|
|
static inline int get_vlc_trace(GetBitContext *s, VLC_TYPE (*table)[2], int bits, int max_depth, char *file, char *func, int line){
|
|
int show= show_bits(s, 24);
|
|
int pos= get_bits_count(s);
|
|
int r= get_vlc2(s, table, bits, max_depth);
|
|
int len= get_bits_count(s) - pos;
|
|
int bits2= show>>(24-len);
|
|
|
|
print_bin(bits2, len);
|
|
|
|
printf("%5d %2d %3d vlc @%5d in %s %s:%d\n", bits2, len, r, pos, file, func, line);
|
|
return r;
|
|
}
|
|
static inline int get_xbits_trace(GetBitContext *s, int n, char *file, char *func, int line){
|
|
int show= show_bits(s, n);
|
|
int r= get_xbits(s, n);
|
|
|
|
print_bin(show, n);
|
|
printf("%5d %2d %3d xbt @%5d in %s %s:%d\n", show, n, r, get_bits_count(s)-n, file, func, line);
|
|
return r;
|
|
}
|
|
|
|
#define get_bits(s, n) get_bits_trace(s, n, __FILE__, __PRETTY_FUNCTION__, __LINE__)
|
|
#define get_bits1(s) get_bits_trace(s, 1, __FILE__, __PRETTY_FUNCTION__, __LINE__)
|
|
#define get_xbits(s, n) get_xbits_trace(s, n, __FILE__, __PRETTY_FUNCTION__, __LINE__)
|
|
#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 printf
|
|
|
|
#else //TRACE
|
|
#define tprintf(_arg...) {}
|
|
#endif
|
|
|
|
/* define it to include statistics code (useful only for optimizing
|
|
codec efficiency */
|
|
//#define STATS
|
|
|
|
#ifdef STATS
|
|
|
|
enum {
|
|
ST_UNKNOWN,
|
|
ST_DC,
|
|
ST_INTRA_AC,
|
|
ST_INTER_AC,
|
|
ST_INTRA_MB,
|
|
ST_INTER_MB,
|
|
ST_MV,
|
|
ST_NB,
|
|
};
|
|
|
|
extern int st_current_index;
|
|
extern unsigned int st_bit_counts[ST_NB];
|
|
extern unsigned int st_out_bit_counts[ST_NB];
|
|
|
|
void print_stats(void);
|
|
#endif
|
|
|
|
/* misc math functions */
|
|
extern const uint8_t ff_log2_tab[256];
|
|
|
|
static inline int av_log2(unsigned int v)
|
|
{
|
|
int n;
|
|
|
|
n = 0;
|
|
if (v & 0xffff0000) {
|
|
v >>= 16;
|
|
n += 16;
|
|
}
|
|
if (v & 0xff00) {
|
|
v >>= 8;
|
|
n += 8;
|
|
}
|
|
n += ff_log2_tab[v];
|
|
|
|
return n;
|
|
}
|
|
|
|
static inline int av_log2_16bit(unsigned int v)
|
|
{
|
|
int n;
|
|
|
|
n = 0;
|
|
if (v & 0xff00) {
|
|
v >>= 8;
|
|
n += 8;
|
|
}
|
|
n += ff_log2_tab[v];
|
|
|
|
return n;
|
|
}
|
|
|
|
/* median of 3 */
|
|
static inline int mid_pred(int a, int b, int c)
|
|
{
|
|
#if 0
|
|
int t= (a-b)&((a-b)>>31);
|
|
a-=t;
|
|
b+=t;
|
|
b-= (b-c)&((b-c)>>31);
|
|
b+= (a-b)&((a-b)>>31);
|
|
|
|
return b;
|
|
#else
|
|
if(a>b){
|
|
if(c>b){
|
|
if(c>a) b=a;
|
|
else b=c;
|
|
}
|
|
}else{
|
|
if(b>c){
|
|
if(c>a) b=c;
|
|
else b=a;
|
|
}
|
|
}
|
|
return b;
|
|
#endif
|
|
}
|
|
|
|
static inline int clip(int a, int amin, int amax)
|
|
{
|
|
if (a < amin)
|
|
return amin;
|
|
else if (a > amax)
|
|
return amax;
|
|
else
|
|
return a;
|
|
}
|
|
|
|
/* math */
|
|
extern const uint8_t ff_sqrt_tab[128];
|
|
|
|
int64_t ff_gcd(int64_t a, int64_t b);
|
|
|
|
static inline int ff_sqrt(int a)
|
|
{
|
|
int ret=0;
|
|
int s;
|
|
int ret_sq=0;
|
|
|
|
if(a<128) return ff_sqrt_tab[a];
|
|
|
|
for(s=15; s>=0; s--){
|
|
int b= ret_sq + (1<<(s*2)) + (ret<<s)*2;
|
|
if(b<=a){
|
|
ret_sq=b;
|
|
ret+= 1<<s;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* converts fourcc string to int
|
|
*/
|
|
static inline int ff_get_fourcc(const char *s){
|
|
assert( strlen(s)==4 );
|
|
|
|
return (s[0]) + (s[1]<<8) + (s[2]<<16) + (s[3]<<24);
|
|
}
|
|
|
|
#define MKTAG(a,b,c,d) (a | (b << 8) | (c << 16) | (d << 24))
|
|
#define MKBETAG(a,b,c,d) (d | (c << 8) | (b << 16) | (a << 24))
|
|
|
|
|
|
#ifdef ARCH_X86
|
|
#define MASK_ABS(mask, level)\
|
|
asm volatile(\
|
|
"cdq \n\t"\
|
|
"xorl %1, %0 \n\t"\
|
|
"subl %1, %0 \n\t"\
|
|
: "+a" (level), "=&d" (mask)\
|
|
);
|
|
#else
|
|
#define MASK_ABS(mask, level)\
|
|
mask= level>>31;\
|
|
level= (level^mask)-mask;
|
|
#endif
|
|
|
|
|
|
#if __CPU__ >= 686 && !defined(RUNTIME_CPUDETECT)
|
|
#define COPY3_IF_LT(x,y,a,b,c,d)\
|
|
asm volatile (\
|
|
"cmpl %0, %3 \n\t"\
|
|
"cmovl %3, %0 \n\t"\
|
|
"cmovl %4, %1 \n\t"\
|
|
"cmovl %5, %2 \n\t"\
|
|
: "+r" (x), "+r" (a), "+r" (c)\
|
|
: "r" (y), "r" (b), "r" (d)\
|
|
);
|
|
#else
|
|
#define COPY3_IF_LT(x,y,a,b,c,d)\
|
|
if((y)<(x)){\
|
|
(x)=(y);\
|
|
(a)=(b);\
|
|
(c)=(d);\
|
|
}
|
|
#endif
|
|
|
|
#ifdef ARCH_X86
|
|
static inline long long rdtsc()
|
|
{
|
|
long long l;
|
|
asm volatile( "rdtsc\n\t"
|
|
: "=A" (l)
|
|
);
|
|
return l;
|
|
}
|
|
|
|
#define START_TIMER \
|
|
static uint64_t tsum=0;\
|
|
static int tcount=0;\
|
|
static int tskip_count=0;\
|
|
uint64_t tend;\
|
|
uint64_t tstart= rdtsc();\
|
|
|
|
#define STOP_TIMER(id) \
|
|
tend= rdtsc();\
|
|
if(tcount<2 || tend - tstart < 8*tsum/tcount){\
|
|
tsum+= tend - tstart;\
|
|
tcount++;\
|
|
}else\
|
|
tskip_count++;\
|
|
if(256*256*256*64%(tcount+tskip_count)==0){\
|
|
fprintf(stderr, "%Ld dezicycles in %s, %d runs, %d skips\n", tsum*10/tcount, id, tcount, tskip_count);\
|
|
}
|
|
#endif
|
|
|
|
#define CLAMP_TO_8BIT(d) ((d > 0xff) ? 0xff : (d < 0) ? 0 : d)
|
|
|
|
/* avoid usage of various functions */
|
|
#define malloc please_use_av_malloc
|
|
#define free please_use_av_free
|
|
#define realloc please_use_av_realloc
|
|
|
|
#define CHECKED_ALLOCZ(p, size)\
|
|
{\
|
|
p= av_mallocz(size);\
|
|
if(p==NULL && (size)!=0){\
|
|
perror("malloc");\
|
|
goto fail;\
|
|
}\
|
|
}
|
|
|
|
#endif /* HAVE_AV_CONFIG_H */
|
|
|
|
#endif /* COMMON_H */
|