]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/common.h
initial commit for Id RoQ and Interplay MVE multimedia subsystems
[ffmpeg] / libavcodec / common.h
index b456af0f1b0ecd9f0ffbbe9fd8a9e313a81497b9..48db2611558591808434af22fe6e3ebeca8b14f6 100644 (file)
@@ -16,6 +16,7 @@
 #define ALT_BITSTREAM_READER
 //#define LIBMPEG2_BITSTREAM_READER
 //#define A32_BITSTREAM_READER
+#define LIBMPEG2_BITSTREAM_READER_HACK //add BERO
 
 #ifdef HAVE_AV_CONFIG_H
 /* only include the following when compiling package */
@@ -46,6 +47,8 @@
 
 #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) \
@@ -115,13 +118,13 @@ typedef signed __int64 int64_t;
 
 #include <inttypes.h>
 
-#ifdef HAVE_AV_CONFIG_H
-
 #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
@@ -135,13 +138,14 @@ typedef signed __int64 int64_t;
 
 /* unix */
 
-#    include <inttypes.h>
+#include <inttypes.h>
 
-#    ifdef HAVE_AV_CONFIG_H
-#        ifndef int64_t_C
-#            define int64_t_C(c)     (c ## LL)
-#            define uint64_t_C(c)    (c ## ULL)
-#        endif
+#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"
@@ -155,7 +159,7 @@ typedef signed __int64 int64_t;
 #    include "bswap.h"
 
 #    if defined(__MINGW32__) || defined(__CYGWIN__) || \
-        defined(__OS2__) || defined (__OpenBSD__)
+        defined(__OS2__) || (defined (__OpenBSD__) && !defined(__ELF__))
 #        define MANGLE(a) "_" #a
 #    else
 #        define MANGLE(a) #a
@@ -194,6 +198,25 @@ inline void dprintf(const char* fmt,...) {}
 #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){
@@ -470,6 +493,16 @@ LAST_SKIP_BITS(name, gb, num)
 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
 
@@ -481,7 +514,7 @@ for examples see get_bits, show_bits, skip_bits, get_vlc
         (gb)->index= name##_index;\
 
 #   define UPDATE_CACHE(name, gb)\
-        name##_cache= be2me_32( unaligned32( ((uint8_t *)(gb)->buffer)+(name##_index>>3) ) ) << (name##_index&0x07);\
+        name##_cache= unaligned32_be( ((uint8_t *)(gb)->buffer)+(name##_index>>3) ) << (name##_index&0x07);\
 
 #   define SKIP_CACHE(name, gb, num)\
         name##_cache <<= (num);\
@@ -514,7 +547,7 @@ static inline int get_bits_count(GetBitContext *s){
 #elif defined LIBMPEG2_BITSTREAM_READER
 //libmpeg2 like reader
 
-#   define MIN_CACHE_BITS 16
+#   define MIN_CACHE_BITS 17
 
 #   define OPEN_READER(name, gb)\
         int name##_bit_count=(gb)->bit_count;\
@@ -526,13 +559,26 @@ static inline int get_bits_count(GetBitContext *s){
         (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){\
+    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);\
 
@@ -628,6 +674,44 @@ static inline int get_bits_count(GetBitContext *s){
 
 #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)
@@ -638,6 +722,12 @@ static inline unsigned int get_bits(GetBitContext *s, int n){
     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)
@@ -647,6 +737,8 @@ static inline unsigned int show_bits(GetBitContext *s, int n){
     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)
@@ -784,6 +876,59 @@ static always_inline int get_vlc2(GetBitContext *s, VLC_TYPE (*table)[2],
     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 */
@@ -901,10 +1046,14 @@ static inline int ff_sqrt(int a)
  */
 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))
+
+
 void ff_float2fraction(int *nom_arg, int *denom_arg, double f, int max);
 
 
@@ -942,6 +1091,35 @@ if((y)<(x)){\
 }
 #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 < 4*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 */
@@ -949,6 +1127,15 @@ if((y)<(x)){\
 #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 */