diff options
author | Alexander Strasser <eclipse7@gmx.net> | 2005-08-01 20:07:05 +0000 |
---|---|---|
committer | Alexander Strasser <eclipse7@gmx.net> | 2005-08-01 20:07:05 +0000 |
commit | c11c2bc20b0d2ca85ac4aed937daf5d65316cf7b (patch) | |
tree | 7a668be611b0443382d380a55f4404d12ff44b9c /libavutil | |
parent | 0cc64d3d1c9d95e0549b2c1baac59ab576837abb (diff) | |
download | ffmpeg-c11c2bc20b0d2ca85ac4aed937daf5d65316cf7b.tar.gz |
libavutil: Utility code from libavcodec moved to a separate library.
Originally committed as revision 4489 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavutil')
-rw-r--r-- | libavutil/Makefile | 92 | ||||
-rw-r--r-- | libavutil/avutil.h | 34 | ||||
-rw-r--r-- | libavutil/bswap.h | 155 | ||||
-rw-r--r-- | libavutil/common.h | 548 | ||||
-rw-r--r-- | libavutil/integer.c | 221 | ||||
-rw-r--r-- | libavutil/integer.h | 47 | ||||
-rw-r--r-- | libavutil/intfloat_readwrite.c | 54 | ||||
-rw-r--r-- | libavutil/intfloat_readwrite.h | 11 | ||||
-rw-r--r-- | libavutil/mathematics.c | 84 | ||||
-rw-r--r-- | libavutil/mathematics.h | 31 | ||||
-rw-r--r-- | libavutil/rational.c | 110 | ||||
-rw-r--r-- | libavutil/rational.h | 69 |
12 files changed, 1456 insertions, 0 deletions
diff --git a/libavutil/Makefile b/libavutil/Makefile new file mode 100644 index 0000000000..1dd01c9786 --- /dev/null +++ b/libavutil/Makefile @@ -0,0 +1,92 @@ +# +# libavutil Makefile +# +include ../config.mak + +VPATH=$(SRC_PATH)/libavutil + +# NOTE: -I.. is needed to include config.h +CFLAGS=$(OPTFLAGS) -DHAVE_AV_CONFIG_H -I.. -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE + +OBJS= mathematics.o \ + integer.o \ + rational.o \ + intfloat_readwrite.o \ + + +ifeq ($(TARGET_ARCH_SPARC64),yes) +CFLAGS+= -mcpu=ultrasparc -mtune=ultrasparc +endif + +SRCS := $(OBJS:.o=.c) + +LIB= $(LIBPREF)avutil$(LIBSUF) +ifeq ($(BUILD_SHARED),yes) +SLIB= $(SLIBPREF)avutil$(SLIBSUF) +endif + +all: $(LIB) $(SLIB) + +$(LIB): $(OBJS) + rm -f $@ + $(AR) rc $@ $(OBJS) + $(RANLIB) $@ + +$(SLIB): $(OBJS) +ifeq ($(CONFIG_WIN32),yes) + $(CC) $(SHFLAGS) -Wl,--output-def,$(@:.dll=.def) -o $@ $(OBJS) $(EXTRALIBS) $(AMREXTRALIBS) + -lib /machine:i386 /def:$(@:.dll=.def) +else + $(CC) $(SHFLAGS) -o $@ $(OBJS) $(EXTRALIBS) $(AMREXTRALIBS) $(LDFLAGS) +endif + +%.o: %.c + $(CC) $(CFLAGS) $(LIBOBJFLAGS) -c -o $@ $< + +depend: $(SRCS) + $(CC) -MM $(CFLAGS) $^ 1>.depend + +dep: depend + +clean: + rm -f *.o *.d *~ .depend $(LIB) $(SLIB) *.so + +distclean: clean + rm -f Makefile.bak .depend + + +ifeq ($(BUILD_SHARED),yes) +install: all install-headers +ifeq ($(CONFIG_WIN32),yes) + install $(INSTALLSTRIP) -m 755 $(SLIB) "$(prefix)" +else + install -d $(libdir) + install $(INSTALLSTRIP) -m 755 $(SLIB) $(libdir)/libavutil-$(VERSION).so + ln -sf libavutil-$(VERSION).so $(libdir)/libavutil.so + $(LDCONFIG) || true +endif +else +install: +endif + +installlib: all install-headers + install -m 644 $(LIB) "$(libdir)" + +install-headers: + mkdir -p "$(prefix)/include/ffmpeg" + install -m 644 $(SRC_PATH)/libavutil/avutil.h \ + $(SRC_PATH)/libavutil/common.h \ + $(SRC_PATH)/libavutil/mathematics.h \ + $(SRC_PATH)/libavutil/integer.h \ + $(SRC_PATH)/libavutil/rational.h \ + $(SRC_PATH)/libavutil/intfloat_readwrite.h \ + "$(prefix)/include/ffmpeg" +# install -d $(libdir)/pkgconfig +# install -m 644 ../libavutil.pc $(libdir)/pkgconfig + +# +# include dependency files if they exist +# +ifneq ($(wildcard .depend),) +include .depend +endif diff --git a/libavutil/avutil.h b/libavutil/avutil.h new file mode 100644 index 0000000000..b9f930a561 --- /dev/null +++ b/libavutil/avutil.h @@ -0,0 +1,34 @@ +#ifndef AVUTIL_H +#define AVUTIL_H + +/** + * @file avutil.h + * external api header. + */ + + +#ifdef __cplusplus +extern "C" { +#endif + +#define AV_STRINGIFY(s) AV_TOSTRING(s) +#define AV_TOSTRING(s) #s + +#define LIBAVUTIL_VERSION_INT ((49<<16)+(0<<8)+0) +#define LIBAVUTIL_VERSION 49.0.0 +#define LIBAVUTIL_BUILD LIBAVUTIL_VERSION_INT + +#define LIBAVUTIL_IDENT "Lavu" AV_STRINGIFY(LIBAVUTIL_VERSION) + + +#include "common.h" +#include "mathematics.h" +#include "rational.h" +#include "integer.h" +#include "intfloat_readwrite.h" + +#ifdef __cplusplus +} +#endif + +#endif /* AVUTIL_H */ diff --git a/libavutil/bswap.h b/libavutil/bswap.h new file mode 100644 index 0000000000..50fd571787 --- /dev/null +++ b/libavutil/bswap.h @@ -0,0 +1,155 @@ +/** + * @file bswap.h + * byte swap. + */ + +#ifndef __BSWAP_H__ +#define __BSWAP_H__ + +#ifdef HAVE_BYTESWAP_H +#include <byteswap.h> +#else + +#ifdef ARCH_X86_64 +# define LEGACY_REGS "=Q" +#else +# define LEGACY_REGS "=q" +#endif + +#if defined(ARCH_X86) || defined(ARCH_X86_64) +static always_inline uint16_t bswap_16(uint16_t x) +{ + __asm("rorw $8, %0" : + LEGACY_REGS (x) : + "0" (x)); + return x; +} + +static always_inline uint32_t bswap_32(uint32_t x) +{ +#if __CPU__ > 386 + __asm("bswap %0": + "=r" (x) : +#else + __asm("xchgb %b0,%h0\n" + " rorl $16,%0\n" + " xchgb %b0,%h0": + LEGACY_REGS (x) : +#endif + "0" (x)); + return x; +} + +static inline uint64_t bswap_64(uint64_t x) +{ +#ifdef ARCH_X86_64 + __asm("bswap %0": + "=r" (x) : + "0" (x)); + return x; +#else + union { + uint64_t ll; + struct { + uint32_t l,h; + } l; + } r; + r.l.l = bswap_32 (x); + r.l.h = bswap_32 (x>>32); + return r.ll; +#endif +} + +#elif defined(ARCH_SH4) + +static always_inline uint16_t bswap_16(uint16_t x) { + __asm__("swap.b %0,%0":"=r"(x):"0"(x)); + return x; +} + +static always_inline uint32_t bswap_32(uint32_t x) { + __asm__( + "swap.b %0,%0\n" + "swap.w %0,%0\n" + "swap.b %0,%0\n" + :"=r"(x):"0"(x)); + return x; +} + +static inline uint64_t bswap_64(uint64_t x) +{ + union { + uint64_t ll; + struct { + uint32_t l,h; + } l; + } r; + r.l.l = bswap_32 (x); + r.l.h = bswap_32 (x>>32); + return r.ll; +} +#else + +static always_inline uint16_t bswap_16(uint16_t x){ + return (x>>8) | (x<<8); +} + +#ifdef ARCH_ARM +static always_inline uint32_t bswap_32(uint32_t x){ + uint32_t t; + __asm__ ( + "eor %1, %0, %0, ror #16 \n\t" + "bic %1, %1, #0xFF0000 \n\t" + "mov %0, %0, ror #8 \n\t" + "eor %0, %0, %1, lsr #8 \n\t" + : "+r"(x), "+r"(t)); + return x; +} +#else +static always_inline uint32_t bswap_32(uint32_t x){ + x= ((x<<8)&0xFF00FF00) | ((x>>8)&0x00FF00FF); + return (x>>16) | (x<<16); +} +#endif + +static inline uint64_t bswap_64(uint64_t x) +{ +#if 0 + x= ((x<< 8)&0xFF00FF00FF00FF00ULL) | ((x>> 8)&0x00FF00FF00FF00FFULL); + x= ((x<<16)&0xFFFF0000FFFF0000ULL) | ((x>>16)&0x0000FFFF0000FFFFULL); + return (x>>32) | (x<<32); +#else + union { + uint64_t ll; + uint32_t l[2]; + } w, r; + w.ll = x; + r.l[0] = bswap_32 (w.l[1]); + r.l[1] = bswap_32 (w.l[0]); + return r.ll; +#endif +} +#endif /* !ARCH_X86 */ + +#endif /* !HAVE_BYTESWAP_H */ + +// be2me ... BigEndian to MachineEndian +// le2me ... LittleEndian to MachineEndian + +#ifdef WORDS_BIGENDIAN +#define be2me_16(x) (x) +#define be2me_32(x) (x) +#define be2me_64(x) (x) +#define le2me_16(x) bswap_16(x) +#define le2me_32(x) bswap_32(x) +#define le2me_64(x) bswap_64(x) +#else +#define be2me_16(x) bswap_16(x) +#define be2me_32(x) bswap_32(x) +#define be2me_64(x) bswap_64(x) +#define le2me_16(x) (x) +#define le2me_32(x) (x) +#define le2me_64(x) (x) +#endif + +#endif /* __BSWAP_H__ */ diff --git a/libavutil/common.h b/libavutil/common.h new file mode 100644 index 0000000000..7d5edb4a7d --- /dev/null +++ b/libavutil/common.h @@ -0,0 +1,548 @@ +/** + * @file common.h + * common internal api header. + */ + +#ifndef COMMON_H +#define COMMON_H + +#if defined(WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__) +# define CONFIG_WIN32 +#endif + +#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> +# include <limits.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) + +#endif /* HAVE_AV_CONFIG_H */ + +/* Suppress restrict if it was not defined in config.h. */ +#ifndef restrict +# define restrict +#endif + +#ifndef always_inline +#if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 0) +# define always_inline __attribute__((always_inline)) inline +#else +# define always_inline inline +#endif +#endif + +#ifndef attribute_used +#if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 0) +# define attribute_used __attribute__((used)) +#else +# define attribute_used +#endif +#endif + +#ifndef attribute_unused +#if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 0) +# define attribute_unused __attribute__((unused)) +#else +# define attribute_unused +#endif +#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 INT16_MIN +#define INT16_MIN (-0x7fff-1) +#endif + +#ifndef INT16_MAX +#define INT16_MAX 0x7fff +#endif + +#ifndef INT64_MIN +#define INT64_MIN (-0x7fffffffffffffffLL-1) +#endif + +#ifndef INT64_MAX +#define INT64_MAX int64_t_C(9223372036854775807) +#endif + +#ifndef UINT64_MAX +#define UINT64_MAX uint64_t_C(0xFFFFFFFFFFFFFFFF) +#endif + +#ifdef EMULATE_FAST_INT +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; +typedef uint64_t uint_fast64_t; +#endif + +#ifndef INT_BIT +# if INT_MAX != 2147483647 +# define INT_BIT 64 +# else +# define INT_BIT 32 +# endif +#endif + +#if defined(CONFIG_OS2) || defined(CONFIG_SUNOS) +static inline float floorf(float f) { + return floor(f); +} +#endif + +#ifdef CONFIG_WIN32 + +/* windows */ + +# if !defined(__MINGW32__) && !defined(__CYGWIN__) +# 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" + +// Use rip-relative addressing if compiling PIC code on x86-64. +# if defined(__MINGW32__) || defined(__CYGWIN__) || \ + defined(__OS2__) || (defined (__OpenBSD__) && !defined(__ELF__)) +# if defined(ARCH_X86_64) && defined(PIC) +# define MANGLE(a) "_" #a"(%%rip)" +# else +# define MANGLE(a) "_" #a +# endif +# else +# if defined(ARCH_X86_64) && defined(PIC) +# define MANGLE(a) #a"(%%rip)" +# else +# define MANGLE(a) #a +# endif +# endif + +/* debug stuff */ + +# ifndef DEBUG +# define NDEBUG +# endif +# include <assert.h> + +/* dprintf macros */ +# if defined(CONFIG_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__) + +inline void dprintf(const char* fmt,...) {} + +# else + +# ifdef DEBUG +# define dprintf(fmt,...) av_log(NULL, AV_LOG_DEBUG, 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]; + +#if defined(ARCH_X86) || defined(ARCH_X86_64) +# 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 + +/* 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; +} + +static inline int clip_uint8(int a) +{ + if (a&(~255)) return (-a)>>31; + 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)) + + +#if defined(ARCH_X86) || defined(ARCH_X86_64) +#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 + +#if defined(ARCH_X86) || defined(ARCH_X86_64) || defined(ARCH_POWERPC) +#if defined(ARCH_X86_64) +static inline uint64_t read_time(void) +{ + uint64_t a, d; + asm volatile( "rdtsc\n\t" + : "=a" (a), "=d" (d) + ); + return (d << 32) | (a & 0xffffffff); +} +#elif defined(ARCH_X86) +static inline long long read_time(void) +{ + long long l; + asm volatile( "rdtsc\n\t" + : "=A" (l) + ); + return l; +} +#else //FIXME check ppc64 +static inline uint64_t read_time(void) +{ + uint32_t tbu, tbl, temp; + + /* from section 2.2.1 of the 32-bit PowerPC PEM */ + __asm__ __volatile__( + "1:\n" + "mftbu %2\n" + "mftb %0\n" + "mftbu %1\n" + "cmpw %2,%1\n" + "bne 1b\n" + : "=r"(tbl), "=r"(tbu), "=r"(temp) + : + : "cc"); + + return (((uint64_t)tbu)<<32) | (uint64_t)tbl; +} +#endif + +#define START_TIMER \ +uint64_t tend;\ +uint64_t tstart= read_time();\ + +#define STOP_TIMER(id) \ +tend= read_time();\ +{\ + static uint64_t tsum=0;\ + static int tcount=0;\ + static int tskip_count=0;\ + if(tcount<2 || tend - tstart < 8*tsum/tcount){\ + tsum+= tend - tstart;\ + tcount++;\ + }else\ + tskip_count++;\ + if(256*256*256*64%(tcount+tskip_count)==0){\ + av_log(NULL, AV_LOG_DEBUG, "%Ld dezicycles in %s, %d runs, %d skips\n", tsum*10/tcount, id, tcount, tskip_count);\ + }\ +} +#else +#define START_TIMER +#define STOP_TIMER(id) {} +#endif + +/* avoid usage of various functions */ +#define malloc please_use_av_malloc +#define free please_use_av_free +#define realloc please_use_av_realloc +#define time time_is_forbidden_due_to_security_issues +#define rand rand_is_forbidden_due_to_state_trashing +#define srand srand_is_forbidden_due_to_state_trashing +#define sprintf sprintf_is_forbidden_due_to_security_issues_use_snprintf +#define strcat strcat_is_forbidden_due_to_security_issues_use_pstrcat +#if !(defined(LIBAVFORMAT_BUILD) || defined(_FRAMEHOOK_H)) +#define printf please_use_av_log +#define fprintf please_use_av_log +#endif + +#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 */ diff --git a/libavutil/integer.c b/libavutil/integer.c new file mode 100644 index 0000000000..38a826f861 --- /dev/null +++ b/libavutil/integer.c @@ -0,0 +1,221 @@ +/* + * arbitrary precision integers + * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at> + * + * This library 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 of the License, or (at your option) any later version. + * + * This library 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 this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/** + * @file integer.c + * arbitrary precision integers. + * @author Michael Niedermayer <michaelni@gmx.at> + */ + +#include "common.h" +#include "integer.h" + +AVInteger av_add_i(AVInteger a, AVInteger b){ + int i, carry=0; + + for(i=0; i<AV_INTEGER_SIZE; i++){ + carry= (carry>>16) + a.v[i] + b.v[i]; + a.v[i]= carry; + } + return a; +} + +AVInteger av_sub_i(AVInteger a, AVInteger b){ + int i, carry=0; + + for(i=0; i<AV_INTEGER_SIZE; i++){ + carry= (carry>>16) + a.v[i] - b.v[i]; + a.v[i]= carry; + } + return a; +} + +/** + * returns the rounded down value of the logarithm of base 2 of the given AVInteger. + * this is simply the index of the most significant bit which is 1. Or 0 of all bits are 0 + */ +int av_log2_i(AVInteger a){ + int i; + + for(i=AV_INTEGER_SIZE-1; i>=0; i--){ + if(a.v[i]) + return av_log2_16bit(a.v[i]) + 16*i; + } + return -1; +} + +AVInteger av_mul_i(AVInteger a, AVInteger b){ + AVInteger out; + int i, j; + int na= (av_log2_i(a)+16) >> 4; + int nb= (av_log2_i(b)+16) >> 4; + + memset(&out, 0, sizeof(out)); + + for(i=0; i<na; i++){ + unsigned int carry=0; + + if(a.v[i]) + for(j=i; j<AV_INTEGER_SIZE && j-i<=nb; j++){ + carry= (carry>>16) + out.v[j] + a.v[i]*b.v[j-i]; + out.v[j]= carry; + } + } + + return out; +} + +/** + * returns 0 if a==b, 1 if a>b and -1 if a<b. + */ +int av_cmp_i(AVInteger a, AVInteger b){ + int i; + int v= (int16_t)a.v[AV_INTEGER_SIZE-1] - (int16_t)b.v[AV_INTEGER_SIZE-1]; + if(v) return (v>>16)|1; + + for(i=AV_INTEGER_SIZE-2; i>=0; i--){ + int v= a.v[i] - b.v[i]; + if(v) return (v>>16)|1; + } + return 0; +} + +/** + * bitwise shift. + * @param s the number of bits by which the value should be shifted right, may be negative for shifting left + */ +AVInteger av_shr_i(AVInteger a, int s){ + AVInteger out; + int i; + + for(i=0; i<AV_INTEGER_SIZE; i++){ + int index= i + (s>>4); + unsigned int v=0; + if(index+1<AV_INTEGER_SIZE && index+1>=0) v = a.v[index+1]<<16; + if(index <AV_INTEGER_SIZE && index >=0) v+= a.v[index ]; + out.v[i]= v >> (s&15); + } + return out; +} + +/** + * returns a % b. + * @param quot a/b will be stored here + */ +AVInteger av_mod_i(AVInteger *quot, AVInteger a, AVInteger b){ + int i= av_log2_i(a) - av_log2_i(b); + AVInteger quot_temp; + if(!quot) quot = "_temp; + + assert((int16_t)a[AV_INTEGER_SIZE-1] >= 0 && (int16_t)b[AV_INTEGER_SIZE-1] >= 0); + assert(av_log2(b)>=0); + + if(i > 0) + b= av_shr_i(b, -i); + + memset(quot, 0, sizeof(AVInteger)); + + while(i-- >= 0){ + *quot= av_shr_i(*quot, -1); + if(av_cmp_i(a, b) >= 0){ + a= av_sub_i(a, b); + quot->v[0] += 1; + } + b= av_shr_i(b, 1); + } + return a; +} + +/** + * returns a/b. + */ +AVInteger av_div_i(AVInteger a, AVInteger b){ + AVInteger quot; + av_mod_i(", a, b); + return quot; +} + +/** + * converts the given int64_t to an AVInteger. + */ +AVInteger av_int2i(int64_t a){ + AVInteger out; + int i; + + for(i=0; i<AV_INTEGER_SIZE; i++){ + out.v[i]= a; + a>>=16; + } + return out; +} + +/** + * converts the given AVInteger to an int64_t. + * if the AVInteger is too large to fit into an int64_t, + * then only the least significant 64bit will be used + */ +int64_t av_i2int(AVInteger a){ + int i; + int64_t out=(int8_t)a.v[AV_INTEGER_SIZE-1]; + + for(i= AV_INTEGER_SIZE-2; i>=0; i--){ + out = (out<<16) + a.v[i]; + } + return out; +} + +#if 0 +#undef NDEBUG +#include <assert.h> + +const uint8_t ff_log2_tab[256]={ + 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 +}; + +main(){ + int64_t a,b; + + for(a=7; a<256*256*256; a+=13215){ + for(b=3; b<256*256*256; b+=27118){ + AVInteger ai= av_int2i(a); + AVInteger bi= av_int2i(b); + + assert(av_i2int(ai) == a); + assert(av_i2int(bi) == b); + assert(av_i2int(av_add_i(ai,bi)) == a+b); + assert(av_i2int(av_sub_i(ai,bi)) == a-b); + assert(av_i2int(av_mul_i(ai,bi)) == a*b); + assert(av_i2int(av_shr_i(ai, 9)) == a>>9); + assert(av_i2int(av_shr_i(ai,-9)) == a<<9); + assert(av_i2int(av_shr_i(ai, 17)) == a>>17); + assert(av_i2int(av_shr_i(ai,-17)) == a<<17); + assert(av_log2_i(ai) == av_log2(a)); + assert(av_i2int(av_div_i(ai,bi)) == a/b); + } + } +} +#endif diff --git a/libavutil/integer.h b/libavutil/integer.h new file mode 100644 index 0000000000..ef1b2a089e --- /dev/null +++ b/libavutil/integer.h @@ -0,0 +1,47 @@ +/* + * arbitrary precision integers + * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at> + * + * This library 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 of the License, or (at your option) any later version. + * + * This library 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 this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/** + * @file integer.h + * arbitrary precision integers + * @author Michael Niedermayer <michaelni@gmx.at> + */ + +#ifndef INTEGER_H +#define INTEGER_H + +#define AV_INTEGER_SIZE 8 + +typedef struct AVInteger{ + uint16_t v[AV_INTEGER_SIZE]; +} AVInteger; + +AVInteger av_add_i(AVInteger a, AVInteger b); +AVInteger av_sub_i(AVInteger a, AVInteger b); +int av_log2_i(AVInteger a); +AVInteger av_mul_i(AVInteger a, AVInteger b); +int av_cmp_i(AVInteger a, AVInteger b); +AVInteger av_shr_i(AVInteger a, int s); +AVInteger av_mod_i(AVInteger *quot, AVInteger a, AVInteger b); +AVInteger av_div_i(AVInteger a, AVInteger b); +AVInteger av_int2i(int64_t a); +int64_t av_i2int(AVInteger a); + +#endif // INTEGER_H diff --git a/libavutil/intfloat_readwrite.c b/libavutil/intfloat_readwrite.c new file mode 100644 index 0000000000..cf4d495e59 --- /dev/null +++ b/libavutil/intfloat_readwrite.c @@ -0,0 +1,54 @@ +/* + * portable IEEE float/double read/write functions + * + * Copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at> + * + * This library 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 of the License, or (at your option) any later version. + * + * This library 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 this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/** + * @file intfloat_readwrite.c + * Portable IEEE float/double read/write functions. + */ + +#include "common.h" + +double av_int2dbl(int64_t v){ + if(v+v > 0xFFELLU<<52) + return 0.0/0.0; + return ldexp(((v&(1LL<<52)-1) + (1LL<<52)) * (v>>63|1), (v>>52&0x7FF)-1075); +} + +float av_int2flt(int32_t v){ + if(v+v > 0xFF000000U) + return 0.0/0.0; + return ldexp(((v&0x7FFFFF) + (1<<23)) * (v>>31|1), (v>>23&0xFF)-150); +} + +int64_t av_dbl2int(double d){ + int e; + if ( !d) return 0; + else if(d-d) return 0x7FF0000000000000LL + ((int64_t)(d<0)<<63) + (d!=d); + d= frexp(d, &e); + return (int64_t)(d<0)<<63 | (e+1022LL)<<52 | (int64_t)((fabs(d)-0.5)*(1LL<<53)); +} + +int32_t av_flt2int(float d){ + int e; + if ( !d) return 0; + else if(d-d) return 0x7F800000 + ((d<0)<<31) + (d!=d); + d= frexp(d, &e); + return (d<0)<<31 | (e+126)<<23 | (int64_t)((fabs(d)-0.5)*(1<<24)); +} diff --git a/libavutil/intfloat_readwrite.h b/libavutil/intfloat_readwrite.h new file mode 100644 index 0000000000..22f40bb665 --- /dev/null +++ b/libavutil/intfloat_readwrite.h @@ -0,0 +1,11 @@ +#ifndef INTFLOAT_READWRITE_H +#define INTFLOAT_READWRITE_H + +#include "common.h" + +double av_int2dbl(int64_t v); +float av_int2flt(int32_t v); +int64_t av_dbl2int(double d); +int32_t av_flt2int(float d); + +#endif /* INTFLOAT_READWRITE_H */ diff --git a/libavutil/mathematics.c b/libavutil/mathematics.c new file mode 100644 index 0000000000..aa3fd74e0c --- /dev/null +++ b/libavutil/mathematics.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at> + * + * This library 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 of the License, or (at your option) any later version. + * + * This library 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 this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/** + * @file mathematics.c + * Miscellaneous math routines and tables. + */ + +#include "common.h" +#include "integer.h" +#include "mathematics.h" + +const uint8_t ff_sqrt_tab[128]={ + 0, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11 +}; + +const uint8_t ff_log2_tab[256]={ + 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 +}; + +int64_t ff_gcd(int64_t a, int64_t b){ + if(b) return ff_gcd(b, a%b); + else return a; +} + +int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd){ + AVInteger ai; + int64_t r=0; + assert(c > 0); + assert(b >=0); + assert(rnd >=0 && rnd<=5 && rnd!=4); + + if(a<0 && a != INT64_MIN) return -av_rescale_rnd(-a, b, c, rnd ^ ((rnd>>1)&1)); + + if(rnd==AV_ROUND_NEAR_INF) r= c/2; + else if(rnd&1) r= c-1; + + if(b<=INT_MAX && c<=INT_MAX){ + if(a<=INT_MAX) + return (a * b + r)/c; + else + return a/c*b + (a%c*b + r)/c; + } + + ai= av_mul_i(av_int2i(a), av_int2i(b)); + ai= av_add_i(ai, av_int2i(r)); + + return av_i2int(av_div_i(ai, av_int2i(c))); +} + +int64_t av_rescale(int64_t a, int64_t b, int64_t c){ + return av_rescale_rnd(a, b, c, AV_ROUND_NEAR_INF); +} + +int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq){ + int64_t b= bq.num * (int64_t)cq.den; + int64_t c= cq.num * (int64_t)bq.den; + return av_rescale_rnd(a, b, c, AV_ROUND_NEAR_INF); +} diff --git a/libavutil/mathematics.h b/libavutil/mathematics.h new file mode 100644 index 0000000000..0cf726cbe9 --- /dev/null +++ b/libavutil/mathematics.h @@ -0,0 +1,31 @@ +#ifndef MATHEMATICS_H +#define MATHEMATICS_H + +#include "rational.h" + +enum AVRounding { + AV_ROUND_ZERO = 0, ///< round toward zero + AV_ROUND_INF = 1, ///< round away from zero + AV_ROUND_DOWN = 2, ///< round toward -infinity + AV_ROUND_UP = 3, ///< round toward +infinity + AV_ROUND_NEAR_INF = 5, ///< round to nearest and halfway cases away from zero +}; + +/** + * rescale a 64bit integer with rounding to nearest. + * a simple a*b/c isn't possible as it can overflow + */ +int64_t av_rescale(int64_t a, int64_t b, int64_t c); + +/** + * rescale a 64bit integer with specified rounding. + * a simple a*b/c isn't possible as it can overflow + */ +int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding); + +/** + * rescale a 64bit integer by 2 rational numbers. + */ +int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq); + +#endif /* MATHEMATICS_H */ diff --git a/libavutil/rational.c b/libavutil/rational.c new file mode 100644 index 0000000000..1044999291 --- /dev/null +++ b/libavutil/rational.c @@ -0,0 +1,110 @@ +/* + * Rational numbers + * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> + * + * This library 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 of the License, or (at your option) any later version. + * + * This library 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 this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/** + * @file rational.c + * Rational numbers + * @author Michael Niedermayer <michaelni@gmx.at> + */ + +//#include <math.h> +#include <limits.h> + +#include "common.h" +#include "mathematics.h" +#include "rational.h" + +int av_reduce(int *dst_nom, int *dst_den, int64_t nom, int64_t den, int64_t max){ + AVRational a0={0,1}, a1={1,0}; + int sign= (nom<0) ^ (den<0); + int64_t gcd= ff_gcd(ABS(nom), ABS(den)); + + nom = ABS(nom)/gcd; + den = ABS(den)/gcd; + if(nom<=max && den<=max){ + a1= (AVRational){nom, den}; + den=0; + } + + while(den){ + int64_t x = nom / den; + int64_t next_den= nom - den*x; + int64_t a2n= x*a1.num + a0.num; + int64_t a2d= x*a1.den + a0.den; + + if(a2n > max || a2d > max) break; + + a0= a1; + a1= (AVRational){a2n, a2d}; + nom= den; + den= next_den; + } + assert(ff_gcd(a1.num, a1.den) == 1); + + *dst_nom = sign ? -a1.num : a1.num; + *dst_den = a1.den; + + return den==0; +} + +/** + * returns b*c. + */ +AVRational av_mul_q(AVRational b, AVRational c){ + av_reduce(&b.num, &b.den, b.num * (int64_t)c.num, b.den * (int64_t)c.den, INT_MAX); + return b; +} + +/** + * returns b/c. + */ +AVRational av_div_q(AVRational b, AVRational c){ + av_reduce(&b.num, &b.den, b.num * (int64_t)c.den, b.den * (int64_t)c.num, INT_MAX); + return b; +} + +/** + * returns b+c. + */ +AVRational av_add_q(AVRational b, AVRational c){ + av_reduce(&b.num, &b.den, b.num * (int64_t)c.den + c.num * (int64_t)b.den, b.den * (int64_t)c.den, INT_MAX); + return b; +} + +/** + * returns b-c. + */ +AVRational av_sub_q(AVRational b, AVRational c){ + av_reduce(&b.num, &b.den, b.num * (int64_t)c.den - c.num * (int64_t)b.den, b.den * (int64_t)c.den, INT_MAX); + return b; +} + +/** + * Converts a double precission floating point number to a AVRational. + * @param max the maximum allowed numerator and denominator + */ +AVRational av_d2q(double d, int max){ + AVRational a; + int exponent= FFMAX( (int)(log(ABS(d) + 1e-20)/log(2)), 0); + int64_t den= 1LL << (61 - exponent); + av_reduce(&a.num, &a.den, (int64_t)(d * den + 0.5), den, max); + + return a; +} diff --git a/libavutil/rational.h b/libavutil/rational.h new file mode 100644 index 0000000000..e4bfe5f7a6 --- /dev/null +++ b/libavutil/rational.h @@ -0,0 +1,69 @@ +/* + * Rational numbers + * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> + * + * This library 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 of the License, or (at your option) any later version. + * + * This library 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 this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/** + * @file rational.h + * Rational numbers. + * @author Michael Niedermayer <michaelni@gmx.at> + */ + +#ifndef RATIONAL_H +#define RATIONAL_H + +/** + * Rational number num/den. + */ +typedef struct AVRational{ + int num; ///< numerator + int den; ///< denominator +} AVRational; + +/** + * returns 0 if a==b, 1 if a>b and -1 if a<b. + */ +static inline int av_cmp_q(AVRational a, AVRational b){ + const int64_t tmp= a.num * (int64_t)b.den - b.num * (int64_t)a.den; + + if(tmp) return (tmp>>63)|1; + else return 0; +} + +/** + * converts the given AVRational to a double. + */ +static inline double av_q2d(AVRational a){ + return a.num / (double) a.den; +} + +/** + * reduce a fraction. + * this is usefull for framerate calculations + * @param max the maximum allowed for dst_nom & dst_den + * @return 1 if exact, 0 otherwise + */ +int av_reduce(int *dst_nom, int *dst_den, int64_t nom, int64_t den, int64_t max); + +AVRational av_mul_q(AVRational b, AVRational c); +AVRational av_div_q(AVRational b, AVRational c); +AVRational av_add_q(AVRational b, AVRational c); +AVRational av_sub_q(AVRational b, AVRational c); +AVRational av_d2q(double d, int max); + +#endif // RATIONAL_H |