Index: apps/codecs/libcook/ffmpeg_config.h =================================================================== --- apps/codecs/libcook/ffmpeg_config.h (revision 0) +++ apps/codecs/libcook/ffmpeg_config.h (revision 0) @@ -0,0 +1,14 @@ +/* Automatically generated by configure - do not modify */ +#ifndef _FFMPEG_CONFIG_H +#define _FFMPEG_CONFIG_H +// CHECK THIS : #include "codecs.h" + +#ifdef CPU_ARM +#define CONFIG_ALIGN 1 +#endif + +#ifdef ROCKBOX_BIG_ENDIAN +#define WORDS_BIGENDIAN +#endif + +#endif Index: apps/codecs/libcook/bitstream.h =================================================================== --- apps/codecs/libcook/bitstream.h (revision 0) +++ apps/codecs/libcook/bitstream.h (revision 0) @@ -0,0 +1,993 @@ +/* + * 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 av_always_inline +#define av_always_inline inline +#endif +#ifndef attribute_deprecated +#define attribute_deprecated +#endif + +#include +#include "ffmpeg_config.h" +#include + +#include "bswap.h" + +extern const uint8_t ff_log2_tab[256]; + + +/*misc utility functions added to make it compile */ +/*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; +}*/ + + +//#include "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) +# 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) +// 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 */ + +/* buf and buf_end must be present and used by every alternative writer. */ +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; + +static inline void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size) +{ + if(buffer_size < 0) { + buffer_size = 0; + buffer = NULL; + } + + s->buf = buffer; + s->buf_end = s->buf + buffer_size; +#ifdef ALT_BITSTREAM_WRITER + s->index=0; + ((uint32_t*)(s->buf))[0]=0; +// memset(buffer, 0, buffer_size); +#else + s->buf_ptr = s->buf; + s->bit_left=32; + s->bit_buf=0; +#endif +} + +/* return the number of bits output */ +static inline int put_bits_count(PutBitContext *s) +{ +#ifdef ALT_BITSTREAM_WRITER + return s->index; +#else + return (s->buf_ptr - s->buf) * 8 + 32 - s->bit_left; +#endif +} + +/* pad the end of the output stream with zeros */ +static inline void flush_put_bits(PutBitContext *s) +{ +#ifdef ALT_BITSTREAM_WRITER + align_put_bits(s); +#else + s->bit_buf<<= s->bit_left; + while (s->bit_left < 32) { + /* XXX: should test end of buffer */ + *s->buf_ptr++=s->bit_buf >> 24; + s->bit_buf<<=8; + s->bit_left+=8; + } + s->bit_left=32; + s->bit_buf=0; +#endif +} + +void align_put_bits(PutBitContext *s); +void ff_put_string(PutBitContext * pbc, char *s, int put_zero); + +/* bit input */ +/* buffer, buffer_end and size_in_bits must be present and used by every reader */ +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; + +#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; + +#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(CPU_COLDFIRE) +# 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 /* defined(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; + + // 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 - bit_left); +#ifdef UNALIGNED_STORES_ARE_BAD + if (3 & (intptr_t) 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 +# if defined(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 +# if defined(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 +} + +/** + * + * PutBitContext must be flushed & aligned to a byte boundary before calling this. + */ +static inline void skip_put_bytes(PutBitContext *s, int n){ + // assert((put_bits_count(s)&7)==0); +#ifdef ALT_BITSTREAM_WRITER + FIXME may need some cleaning of the buffer + s->index += n<<3; +#else + // assert(s->bit_left==32); + s->buf_ptr += n; +#endif +} + +/** + * skips the given number of bits. + * must only be used if the actual values in the bitstream dont matter + */ +static inline void skip_put_bits(PutBitContext *s, int n){ +#ifdef ALT_BITSTREAM_WRITER + s->index += n; +#else + s->bit_left -= n; + s->buf_ptr-= s->bit_left>>5; + s->bit_left &= 31; +#endif +} + +/** + * Changes the end of the buffer. + */ +static inline void set_put_bits_buffer_size(PutBitContext *s, int size){ + s->buf_end= s->buf + size; +} + +/* 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 next num bits + +SHOW_SBITS(name, gb, num) + will return the next num bits and do sign extension + +SKIP_BITS(name, gb, num) + will skip over the next num bits + note, this is equivalent 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 equivalent 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 +} + +static inline int unaligned32_le(const void *v) +{ +#ifdef CONFIG_ALIGN + const uint8_t *p=v; + return (((p[3]<<8) | p[2])<<16) | (p[1]<<8) | (p[0]); +#else + return le2me_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;\ + +# ifdef ALT_BITSTREAM_READER_LE +# define UPDATE_CACHE(name, gb)\ + name##_cache= unaligned32_le( ((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);\ + +# define SKIP_CACHE(name, gb, num)\ + name##_cache <<= (num); +# endif + +// 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) ; + +# 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) + +# define SHOW_SBITS(name, gb, num)\ + NEG_SSR32(name##_cache, num) +# endif + +# define GET_CACHE(name, gb)\ + ((uint32_t)name##_cache) + +static inline int get_bits_count(GetBitContext *s){ + return s->index; +} + +static inline void skip_bits_long(GetBitContext *s, int n){ + s->index += n; +} + +#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;\ + 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##_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; +} + +static inline void skip_bits_long(GetBitContext *s, int n){ + OPEN_READER(re, s) + re_bit_count += n; + re_buffer_ptr += 2*(re_bit_count>>4); + re_bit_count &= 15; + re_cache = ((re_buffer_ptr[-2]<<8) + re_buffer_ptr[-1]) << (16+re_bit_count); + UPDATE_CACHE(re, s) + CLOSE_READER(re, s) +} + +#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<buffer_ptr - s->buffer)*8 - 32 + s->bit_count; +} + +static inline void skip_bits_long(GetBitContext *s, int n){ + OPEN_READER(re, s) + re_bit_count += n; + re_buffer_ptr += re_bit_count>>5; + re_bit_count &= 31; + re_cache0 = be2me_32( re_buffer_ptr[-1] ) << re_bit_count; + re_cache1 = 0; + UPDATE_CACHE(re, s) + CLOSE_READER(re, 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 sign; + register int32_t cache; + OPEN_READER(re, s) + UPDATE_CACHE(re, s) + cache = GET_CACHE(re,s); + sign=(~cache)>>31; + LAST_SKIP_BITS(re, s, n) + CLOSE_READER(re, s) + return (NEG_USR32(sign ^ cache, n) ^ sign) - sign; +} + +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 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){ + 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; +} + +/** + * 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){ + register int tmp; + OPEN_READER(re, s) + UPDATE_CACHE(re, s) + tmp= SHOW_UBITS(re, s, n); +// CLOSE_READER(re, s) + return tmp; +} + +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 ]; +#ifdef ALT_BITSTREAM_READER_LE + result>>= (index&0x07); + result&= 1; +#else + result<<= (index&0x07); + result>>= 8 - 1; +#endif + 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); +} + +/** + * reads 0-32 bits. + */ +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 + } +} + +/** + * shows 0-32 bits. + */ +static inline unsigned int show_bits_long(GetBitContext *s, int n){ + if(n<=17) return show_bits(s, n); + else{ + GetBitContext gb= *s; + int ret= get_bits_long(s, n); + *s= gb; + return ret; + } +} + +/* +static inline int check_marker(GetBitContext *s, const char *msg) +{ + int bit= get_bits1(s); + if(!bit) + av_log(NULL, AV_LOG_INFO, "Marker bit missing %s\n", msg); + + return bit; +} +*/ +/** + * init GetBitContext. + * @param buffer bitstream buffer, must be FF_INPUT_BUFFER_PADDING_SIZE bytes larger then the actual read bits + * because some optimized bitstream readers read 32 or 64 bit at once and could read over the end + * @param bit_size the size of the buffer in bits + */ +static inline void init_get_bits(GetBitContext *s, + const uint8_t *buffer, int bit_size) +{ + int buffer_size= (bit_size+7)>>3; + if(buffer_size < 0 || bit_size < 0) { + buffer_size = bit_size = 0; + buffer = NULL; + } + + s->buffer= buffer; + s->size_in_bits= bit_size; + s->buffer_end= buffer + buffer_size; +#ifdef ALT_BITSTREAM_READER + s->index=0; +#elif defined LIBMPEG2_BITSTREAM_READER + s->buffer_ptr = (uint8_t*)((intptr_t)buffer&(~1)); + s->bit_count = 16 + 8*((intptr_t)buffer&1); + skip_bits_long(s, 0); +#elif defined A32_BITSTREAM_READER + s->buffer_ptr = (uint32_t*)((intptr_t)buffer&(~3)); + s->bit_count = 32 + 8*((intptr_t)buffer&3); + skip_bits_long(s, 0); +#endif +} + +static inline void align_get_bits(GetBitContext *s) +{ + int n= (-get_bits_count(s)) & 7; + if(n) skip_bits(s, n); +} + +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, + int flags); +#define INIT_VLC_USE_STATIC 1 +#define INIT_VLC_LE 2 +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, need_update)\ +{\ + 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){\ + SKIP_BITS(name, gb, bits)\ + if(need_update){\ + 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)\ +} + + +/** + * 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 read to completely + * read the longest vlc code + * = (max_vlc_length + bits - 1) / bits + */ +static av_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--){ + av_log(NULL, AV_LOG_DEBUG, "%d", (bits>>i)&1); + } + for(i=n; i<24; i++) + av_log(NULL, AV_LOG_DEBUG, " "); +} + +static inline int get_bits_trace(GetBitContext *s, int n, char *file, const char *func, int line){ + int r= get_bits(s, n); + + print_bin(r, n); + av_log(NULL, AV_LOG_DEBUG, "%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, const 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); + + av_log(NULL, AV_LOG_DEBUG, "%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, const char *func, int line){ + int show= show_bits(s, n); + int r= get_xbits(s, n); + + print_bin(show, n); + av_log(NULL, AV_LOG_DEBUG, "%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(p, ...) av_log(p, AV_LOG_DEBUG, __VA_ARGS__) + +#else //TRACE +#define tprintf(p, ...) {} +#endif + +static inline int decode012(GetBitContext *gb){ + int n; + n = get_bits1(gb); + if (n == 0) + return 0; + else + return get_bits1(gb) + 1; +} + +#endif /* BITSTREAM_H */ Index: apps/codecs/libcook/avcodec.h =================================================================== --- apps/codecs/libcook/avcodec.h (revision 0) +++ apps/codecs/libcook/avcodec.h (revision 0) @@ -0,0 +1,3433 @@ +/* + * copyright (c) 2001 Fabrice Bellard + * + * 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 + */ + +#ifndef AVCODEC_AVCODEC_H +#define AVCODEC_AVCODEC_H + +/** + * @file libavcodec/avcodec.h + * external API header + */ + +#include +#include "libavutil/avutil.h" + +#define LIBAVCODEC_VERSION_MAJOR 52 +#define LIBAVCODEC_VERSION_MINOR 22 +#define LIBAVCODEC_VERSION_MICRO 0 + +#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ + LIBAVCODEC_VERSION_MINOR, \ + LIBAVCODEC_VERSION_MICRO) +#define LIBAVCODEC_VERSION AV_VERSION(LIBAVCODEC_VERSION_MAJOR, \ + LIBAVCODEC_VERSION_MINOR, \ + LIBAVCODEC_VERSION_MICRO) +#define LIBAVCODEC_BUILD LIBAVCODEC_VERSION_INT + +#define LIBAVCODEC_IDENT "Lavc" AV_STRINGIFY(LIBAVCODEC_VERSION) + +#define AV_NOPTS_VALUE INT64_C(0x8000000000000000) +#define AV_TIME_BASE 1000000 +#define AV_TIME_BASE_Q (AVRational){1, AV_TIME_BASE} + +/** + * Identifies the syntax and semantics of the bitstream. + * The principle is roughly: + * Two decoders with the same ID can decode the same streams. + * Two encoders with the same ID can encode compatible streams. + * There may be slight deviations from the principle due to implementation + * details. + * + * If you add a codec ID to this list, add it so that + * 1. no value of a existing codec ID changes (that would break ABI), + * 2. it is as close as possible to similar codecs. + */ +enum CodecID { + CODEC_ID_NONE, + + /* video codecs */ + CODEC_ID_MPEG1VIDEO, + CODEC_ID_MPEG2VIDEO, ///< preferred ID for MPEG-1/2 video decoding + CODEC_ID_MPEG2VIDEO_XVMC, + CODEC_ID_H261, + CODEC_ID_H263, + CODEC_ID_RV10, + CODEC_ID_RV20, + CODEC_ID_MJPEG, + CODEC_ID_MJPEGB, + CODEC_ID_LJPEG, + CODEC_ID_SP5X, + CODEC_ID_JPEGLS, + CODEC_ID_MPEG4, + CODEC_ID_RAWVIDEO, + CODEC_ID_MSMPEG4V1, + CODEC_ID_MSMPEG4V2, + CODEC_ID_MSMPEG4V3, + CODEC_ID_WMV1, + CODEC_ID_WMV2, + CODEC_ID_H263P, + CODEC_ID_H263I, + CODEC_ID_FLV1, + CODEC_ID_SVQ1, + CODEC_ID_SVQ3, + CODEC_ID_DVVIDEO, + CODEC_ID_HUFFYUV, + CODEC_ID_CYUV, + CODEC_ID_H264, + CODEC_ID_INDEO3, + CODEC_ID_VP3, + CODEC_ID_THEORA, + CODEC_ID_ASV1, + CODEC_ID_ASV2, + CODEC_ID_FFV1, + CODEC_ID_4XM, + CODEC_ID_VCR1, + CODEC_ID_CLJR, + CODEC_ID_MDEC, + CODEC_ID_ROQ, + CODEC_ID_INTERPLAY_VIDEO, + CODEC_ID_XAN_WC3, + CODEC_ID_XAN_WC4, + CODEC_ID_RPZA, + CODEC_ID_CINEPAK, + CODEC_ID_WS_VQA, + CODEC_ID_MSRLE, + CODEC_ID_MSVIDEO1, + CODEC_ID_IDCIN, + CODEC_ID_8BPS, + CODEC_ID_SMC, + CODEC_ID_FLIC, + CODEC_ID_TRUEMOTION1, + CODEC_ID_VMDVIDEO, + CODEC_ID_MSZH, + CODEC_ID_ZLIB, + CODEC_ID_QTRLE, + CODEC_ID_SNOW, + CODEC_ID_TSCC, + CODEC_ID_ULTI, + CODEC_ID_QDRAW, + CODEC_ID_VIXL, + CODEC_ID_QPEG, + CODEC_ID_XVID, + CODEC_ID_PNG, + CODEC_ID_PPM, + CODEC_ID_PBM, + CODEC_ID_PGM, + CODEC_ID_PGMYUV, + CODEC_ID_PAM, + CODEC_ID_FFVHUFF, + CODEC_ID_RV30, + CODEC_ID_RV40, + CODEC_ID_VC1, + CODEC_ID_WMV3, + CODEC_ID_LOCO, + CODEC_ID_WNV1, + CODEC_ID_AASC, + CODEC_ID_INDEO2, + CODEC_ID_FRAPS, + CODEC_ID_TRUEMOTION2, + CODEC_ID_BMP, + CODEC_ID_CSCD, + CODEC_ID_MMVIDEO, + CODEC_ID_ZMBV, + CODEC_ID_AVS, + CODEC_ID_SMACKVIDEO, + CODEC_ID_NUV, + CODEC_ID_KMVC, + CODEC_ID_FLASHSV, + CODEC_ID_CAVS, + CODEC_ID_JPEG2000, + CODEC_ID_VMNC, + CODEC_ID_VP5, + CODEC_ID_VP6, + CODEC_ID_VP6F, + CODEC_ID_TARGA, + CODEC_ID_DSICINVIDEO, + CODEC_ID_TIERTEXSEQVIDEO, + CODEC_ID_TIFF, + CODEC_ID_GIF, + CODEC_ID_FFH264, + CODEC_ID_DXA, + CODEC_ID_DNXHD, + CODEC_ID_THP, + CODEC_ID_SGI, + CODEC_ID_C93, + CODEC_ID_BETHSOFTVID, + CODEC_ID_PTX, + CODEC_ID_TXD, + CODEC_ID_VP6A, + CODEC_ID_AMV, + CODEC_ID_VB, + CODEC_ID_PCX, + CODEC_ID_SUNRAST, + CODEC_ID_INDEO4, + CODEC_ID_INDEO5, + CODEC_ID_MIMIC, + CODEC_ID_RL2, + CODEC_ID_8SVX_EXP, + CODEC_ID_8SVX_FIB, + CODEC_ID_ESCAPE124, + CODEC_ID_DIRAC, + CODEC_ID_BFI, + CODEC_ID_CMV, + CODEC_ID_MOTIONPIXELS, + CODEC_ID_TGV, + CODEC_ID_TGQ, + CODEC_ID_TQI, + + /* various PCM "codecs" */ + CODEC_ID_PCM_S16LE= 0x10000, + CODEC_ID_PCM_S16BE, + CODEC_ID_PCM_U16LE, + CODEC_ID_PCM_U16BE, + CODEC_ID_PCM_S8, + CODEC_ID_PCM_U8, + CODEC_ID_PCM_MULAW, + CODEC_ID_PCM_ALAW, + CODEC_ID_PCM_S32LE, + CODEC_ID_PCM_S32BE, + CODEC_ID_PCM_U32LE, + CODEC_ID_PCM_U32BE, + CODEC_ID_PCM_S24LE, + CODEC_ID_PCM_S24BE, + CODEC_ID_PCM_U24LE, + CODEC_ID_PCM_U24BE, + CODEC_ID_PCM_S24DAUD, + CODEC_ID_PCM_ZORK, + CODEC_ID_PCM_S16LE_PLANAR, + CODEC_ID_PCM_DVD, + CODEC_ID_PCM_F32BE, + CODEC_ID_PCM_F32LE, + CODEC_ID_PCM_F64BE, + CODEC_ID_PCM_F64LE, + + /* various ADPCM codecs */ + CODEC_ID_ADPCM_IMA_QT= 0x11000, + CODEC_ID_ADPCM_IMA_WAV, + CODEC_ID_ADPCM_IMA_DK3, + CODEC_ID_ADPCM_IMA_DK4, + CODEC_ID_ADPCM_IMA_WS, + CODEC_ID_ADPCM_IMA_SMJPEG, + CODEC_ID_ADPCM_MS, + CODEC_ID_ADPCM_4XM, + CODEC_ID_ADPCM_XA, + CODEC_ID_ADPCM_ADX, + CODEC_ID_ADPCM_EA, + CODEC_ID_ADPCM_G726, + CODEC_ID_ADPCM_CT, + CODEC_ID_ADPCM_SWF, + CODEC_ID_ADPCM_YAMAHA, + CODEC_ID_ADPCM_SBPRO_4, + CODEC_ID_ADPCM_SBPRO_3, + CODEC_ID_ADPCM_SBPRO_2, + CODEC_ID_ADPCM_THP, + CODEC_ID_ADPCM_IMA_AMV, + CODEC_ID_ADPCM_EA_R1, + CODEC_ID_ADPCM_EA_R3, + CODEC_ID_ADPCM_EA_R2, + CODEC_ID_ADPCM_IMA_EA_SEAD, + CODEC_ID_ADPCM_IMA_EA_EACS, + CODEC_ID_ADPCM_EA_XAS, + CODEC_ID_ADPCM_EA_MAXIS_XA, + CODEC_ID_ADPCM_IMA_ISS, + + /* AMR */ + CODEC_ID_AMR_NB= 0x12000, + CODEC_ID_AMR_WB, + + /* RealAudio codecs*/ + CODEC_ID_RA_144= 0x13000, + CODEC_ID_RA_288, + + /* various DPCM codecs */ + CODEC_ID_ROQ_DPCM= 0x14000, + CODEC_ID_INTERPLAY_DPCM, + CODEC_ID_XAN_DPCM, + CODEC_ID_SOL_DPCM, + + /* audio codecs */ + CODEC_ID_MP2= 0x15000, + CODEC_ID_MP3, ///< preferred ID for decoding MPEG audio layer 1, 2 or 3 + CODEC_ID_AAC, + CODEC_ID_AC3, + CODEC_ID_DTS, + CODEC_ID_VORBIS, + CODEC_ID_DVAUDIO, + CODEC_ID_WMAV1, + CODEC_ID_WMAV2, + CODEC_ID_MACE3, + CODEC_ID_MACE6, + CODEC_ID_VMDAUDIO, + CODEC_ID_SONIC, + CODEC_ID_SONIC_LS, + CODEC_ID_FLAC, + CODEC_ID_MP3ADU, + CODEC_ID_MP3ON4, + CODEC_ID_SHORTEN, + CODEC_ID_ALAC, + CODEC_ID_WESTWOOD_SND1, + CODEC_ID_GSM, ///< as in Berlin toast format + CODEC_ID_QDM2, + CODEC_ID_COOK, + CODEC_ID_TRUESPEECH, + CODEC_ID_TTA, + CODEC_ID_SMACKAUDIO, + CODEC_ID_QCELP, + CODEC_ID_WAVPACK, + CODEC_ID_DSICINAUDIO, + CODEC_ID_IMC, + CODEC_ID_MUSEPACK7, + CODEC_ID_MLP, + CODEC_ID_GSM_MS, /* as found in WAV */ + CODEC_ID_ATRAC3, + CODEC_ID_VOXWARE, + CODEC_ID_APE, + CODEC_ID_NELLYMOSER, + CODEC_ID_MUSEPACK8, + CODEC_ID_SPEEX, + CODEC_ID_WMAVOICE, + CODEC_ID_WMAPRO, + CODEC_ID_WMALOSSLESS, + CODEC_ID_ATRAC3P, + CODEC_ID_EAC3, + CODEC_ID_SIPR, + CODEC_ID_MP1, + CODEC_ID_TWINVQ, + CODEC_ID_TRUEHD, + + /* subtitle codecs */ + CODEC_ID_DVD_SUBTITLE= 0x17000, + CODEC_ID_DVB_SUBTITLE, + CODEC_ID_TEXT, ///< raw UTF-8 text + CODEC_ID_XSUB, + CODEC_ID_SSA, + CODEC_ID_MOV_TEXT, + + /* other specific kind of codecs (generally used for attachments) */ + CODEC_ID_TTF= 0x18000, + + CODEC_ID_PROBE= 0x19000, ///< codec_id is not known (like CODEC_ID_NONE) but lavf should attempt to identify it + + CODEC_ID_MPEG2TS= 0x20000, /**< _FAKE_ codec to indicate a raw MPEG-2 TS + * stream (only used by libavformat) */ +}; + +enum CodecType { + CODEC_TYPE_UNKNOWN = -1, + CODEC_TYPE_VIDEO, + CODEC_TYPE_AUDIO, + CODEC_TYPE_DATA, + CODEC_TYPE_SUBTITLE, + CODEC_TYPE_ATTACHMENT, + CODEC_TYPE_NB +}; + +/** + * all in native-endian format + */ +enum SampleFormat { + SAMPLE_FMT_NONE = -1, + SAMPLE_FMT_U8, ///< unsigned 8 bits + SAMPLE_FMT_S16, ///< signed 16 bits + SAMPLE_FMT_S32, ///< signed 32 bits + SAMPLE_FMT_FLT, ///< float + SAMPLE_FMT_DBL, ///< double + SAMPLE_FMT_NB ///< Number of sample formats. DO NOT USE if dynamically linking to libavcodec +}; + +/* Audio channel masks */ +#define CH_FRONT_LEFT 0x00000001 +#define CH_FRONT_RIGHT 0x00000002 +#define CH_FRONT_CENTER 0x00000004 +#define CH_LOW_FREQUENCY 0x00000008 +#define CH_BACK_LEFT 0x00000010 +#define CH_BACK_RIGHT 0x00000020 +#define CH_FRONT_LEFT_OF_CENTER 0x00000040 +#define CH_FRONT_RIGHT_OF_CENTER 0x00000080 +#define CH_BACK_CENTER 0x00000100 +#define CH_SIDE_LEFT 0x00000200 +#define CH_SIDE_RIGHT 0x00000400 +#define CH_TOP_CENTER 0x00000800 +#define CH_TOP_FRONT_LEFT 0x00001000 +#define CH_TOP_FRONT_CENTER 0x00002000 +#define CH_TOP_FRONT_RIGHT 0x00004000 +#define CH_TOP_BACK_LEFT 0x00008000 +#define CH_TOP_BACK_CENTER 0x00010000 +#define CH_TOP_BACK_RIGHT 0x00020000 +#define CH_STEREO_LEFT 0x20000000 ///< Stereo downmix. +#define CH_STEREO_RIGHT 0x40000000 ///< See CH_STEREO_LEFT. + +/* Audio channel convenience macros */ +#define CH_LAYOUT_MONO (CH_FRONT_CENTER) +#define CH_LAYOUT_STEREO (CH_FRONT_LEFT|CH_FRONT_RIGHT) +#define CH_LAYOUT_SURROUND (CH_LAYOUT_STEREO|CH_FRONT_CENTER) +#define CH_LAYOUT_QUAD (CH_LAYOUT_STEREO|CH_BACK_LEFT|CH_BACK_RIGHT) +#define CH_LAYOUT_5POINT0 (CH_LAYOUT_SURROUND|CH_SIDE_LEFT|CH_SIDE_RIGHT) +#define CH_LAYOUT_5POINT1 (CH_LAYOUT_5POINT0|CH_LOW_FREQUENCY) +#define CH_LAYOUT_7POINT1 (CH_LAYOUT_5POINT1|CH_BACK_LEFT|CH_BACK_RIGHT) +#define CH_LAYOUT_7POINT1_WIDE (CH_LAYOUT_SURROUND|CH_LOW_FREQUENCY|\ + CH_BACK_LEFT|CH_BACK_RIGHT|\ + CH_FRONT_LEFT_OF_CENTER|CH_FRONT_RIGHT_OF_CENTER) +#define CH_LAYOUT_STEREO_DOWNMIX (CH_STEREO_LEFT|CH_STEREO_RIGHT) + +/* in bytes */ +#define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000 // 1 second of 48khz 32bit audio + +/** + * Required number of additionally allocated bytes at the end of the input bitstream for decoding. + * This is mainly needed because some optimized bitstream readers read + * 32 or 64 bit at once and could read over the end.
+ * Note: If the first 23 bits of the additional bytes are not 0, then damaged + * MPEG bitstreams could cause overread and segfault. + */ +#define FF_INPUT_BUFFER_PADDING_SIZE 8 + +/** + * minimum encoding buffer size + * Used to avoid some checks during header writing. + */ +#define FF_MIN_BUFFER_SIZE 16384 + +#if 0/* MT : DELETE THIS LINE.*/ +/** + * motion estimation type. + */ +enum Motion_Est_ID { + ME_ZERO = 1, ///< no search, that is use 0,0 vector whenever one is needed + ME_FULL, + ME_LOG, + ME_PHODS, + ME_EPZS, ///< enhanced predictive zonal search + ME_X1, ///< reserved for experiments + ME_HEX, ///< hexagon based search + ME_UMH, ///< uneven multi-hexagon search + ME_ITER, ///< iterative search + ME_TESA, ///< transformed exhaustive search algorithm +}; + +enum AVDiscard{ + /* We leave some space between them for extensions (drop some + * keyframes for intra-only or drop just some bidir frames). */ + AVDISCARD_NONE =-16, ///< discard nothing + AVDISCARD_DEFAULT= 0, ///< discard useless packets like 0 size packets in avi + AVDISCARD_NONREF = 8, ///< discard all non reference + AVDISCARD_BIDIR = 16, ///< discard all bidirectional frames + AVDISCARD_NONKEY = 32, ///< discard all frames except keyframes + AVDISCARD_ALL = 48, ///< discard all +}; + +typedef struct RcOverride{ + int start_frame; + int end_frame; + int qscale; // If this is 0 then quality_factor will be used instead. + float quality_factor; +} RcOverride; + +#define FF_MAX_B_FRAMES 16 + +/* encoding support + These flags can be passed in AVCodecContext.flags before initialization. + Note: Not everything is supported yet. +*/ + +#define CODEC_FLAG_QSCALE 0x0002 ///< Use fixed qscale. +#define CODEC_FLAG_4MV 0x0004 ///< 4 MV per MB allowed / advanced prediction for H.263. +#define CODEC_FLAG_QPEL 0x0010 ///< Use qpel MC. +#define CODEC_FLAG_GMC 0x0020 ///< Use GMC. +#define CODEC_FLAG_MV0 0x0040 ///< Always try a MB with MV=<0,0>. +#define CODEC_FLAG_PART 0x0080 ///< Use data partitioning. +/** + * The parent program guarantees that the input for B-frames containing + * streams is not written to for at least s->max_b_frames+1 frames, if + * this is not set the input will be copied. + */ +#define CODEC_FLAG_INPUT_PRESERVED 0x0100 +#define CODEC_FLAG_PASS1 0x0200 ///< Use internal 2pass ratecontrol in first pass mode. +#define CODEC_FLAG_PASS2 0x0400 ///< Use internal 2pass ratecontrol in second pass mode. +#define CODEC_FLAG_EXTERN_HUFF 0x1000 ///< Use external Huffman table (for MJPEG). +#define CODEC_FLAG_GRAY 0x2000 ///< Only decode/encode grayscale. +#define CODEC_FLAG_EMU_EDGE 0x4000 ///< Don't draw edges. +#define CODEC_FLAG_PSNR 0x8000 ///< error[?] variables will be set during encoding. +#define CODEC_FLAG_TRUNCATED 0x00010000 /** Input bitstream might be truncated at a random + location instead of only at frame boundaries. */ +#define CODEC_FLAG_NORMALIZE_AQP 0x00020000 ///< Normalize adaptive quantization. +#define CODEC_FLAG_INTERLACED_DCT 0x00040000 ///< Use interlaced DCT. +#define CODEC_FLAG_LOW_DELAY 0x00080000 ///< Force low delay. +#define CODEC_FLAG_ALT_SCAN 0x00100000 ///< Use alternate scan. +#define CODEC_FLAG_GLOBAL_HEADER 0x00400000 ///< Place global headers in extradata instead of every keyframe. +#define CODEC_FLAG_BITEXACT 0x00800000 ///< Use only bitexact stuff (except (I)DCT). +/* Fx : Flag for h263+ extra options */ +#define CODEC_FLAG_AC_PRED 0x01000000 ///< H.263 advanced intra coding / MPEG-4 AC prediction +#define CODEC_FLAG_H263P_UMV 0x02000000 ///< unlimited motion vector +#define CODEC_FLAG_CBP_RD 0x04000000 ///< Use rate distortion optimization for cbp. +#define CODEC_FLAG_QP_RD 0x08000000 ///< Use rate distortion optimization for qp selectioon. +#define CODEC_FLAG_H263P_AIV 0x00000008 ///< H.263 alternative inter VLC +#define CODEC_FLAG_OBMC 0x00000001 ///< OBMC +#define CODEC_FLAG_LOOP_FILTER 0x00000800 ///< loop filter +#define CODEC_FLAG_H263P_SLICE_STRUCT 0x10000000 +#define CODEC_FLAG_INTERLACED_ME 0x20000000 ///< interlaced motion estimation +#define CODEC_FLAG_SVCD_SCAN_OFFSET 0x40000000 ///< Will reserve space for SVCD scan offset user data. +#define CODEC_FLAG_CLOSED_GOP 0x80000000 +#define CODEC_FLAG2_FAST 0x00000001 ///< Allow non spec compliant speedup tricks. +#define CODEC_FLAG2_STRICT_GOP 0x00000002 ///< Strictly enforce GOP size. +#define CODEC_FLAG2_NO_OUTPUT 0x00000004 ///< Skip bitstream encoding. +#define CODEC_FLAG2_LOCAL_HEADER 0x00000008 ///< Place global headers at every keyframe instead of in extradata. +#define CODEC_FLAG2_BPYRAMID 0x00000010 ///< H.264 allow B-frames to be used as references. +#define CODEC_FLAG2_WPRED 0x00000020 ///< H.264 weighted biprediction for B-frames +#define CODEC_FLAG2_MIXED_REFS 0x00000040 ///< H.264 one reference per partition, as opposed to one reference per macroblock +#define CODEC_FLAG2_8X8DCT 0x00000080 ///< H.264 high profile 8x8 transform +#define CODEC_FLAG2_FASTPSKIP 0x00000100 ///< H.264 fast pskip +#define CODEC_FLAG2_AUD 0x00000200 ///< H.264 access unit delimiters +#define CODEC_FLAG2_BRDO 0x00000400 ///< B-frame rate-distortion optimization +#define CODEC_FLAG2_INTRA_VLC 0x00000800 ///< Use MPEG-2 intra VLC table. +#define CODEC_FLAG2_MEMC_ONLY 0x00001000 ///< Only do ME/MC (I frames -> ref, P frame -> ME+MC). +#define CODEC_FLAG2_DROP_FRAME_TIMECODE 0x00002000 ///< timecode is in drop frame format. +#define CODEC_FLAG2_SKIP_RD 0x00004000 ///< RD optimal MB level residual skipping +#define CODEC_FLAG2_CHUNKS 0x00008000 ///< Input bitstream might be truncated at a packet boundaries instead of only at frame boundaries. +#define CODEC_FLAG2_NON_LINEAR_QUANT 0x00010000 ///< Use MPEG-2 nonlinear quantizer. +#define CODEC_FLAG2_BIT_RESERVOIR 0x00020000 ///< Use a bit reservoir when encoding if possible + +/* Unsupported options : + * Syntax Arithmetic coding (SAC) + * Reference Picture Selection + * Independent Segment Decoding */ +/* /Fx */ +/* codec capabilities */ + +#define CODEC_CAP_DRAW_HORIZ_BAND 0x0001 ///< Decoder can use draw_horiz_band callback. +/** + * Codec uses get_buffer() for allocating buffers. + * direct rendering method 1 + */ +#define CODEC_CAP_DR1 0x0002 +/* If 'parse_only' field is true, then avcodec_parse_frame() can be used. */ +#define CODEC_CAP_PARSE_ONLY 0x0004 +#define CODEC_CAP_TRUNCATED 0x0008 +/* Codec can export data for HW decoding (XvMC). */ +#define CODEC_CAP_HWACCEL 0x0010 +/** + * Codec has a nonzero delay and needs to be fed with NULL at the end to get the delayed data. + * If this is not set, the codec is guaranteed to never be fed with NULL data. + */ +#define CODEC_CAP_DELAY 0x0020 +/** + * Codec can be fed a final frame with a smaller size. + * This can be used to prevent truncation of the last audio samples. + */ +#define CODEC_CAP_SMALL_LAST_FRAME 0x0040 +/** + * Codec can export data for HW decoding (VDPAU). + */ +#define CODEC_CAP_HWACCEL_VDPAU 0x0080 + +//The following defines may change, don't expect compatibility if you use them. +#define MB_TYPE_INTRA4x4 0x0001 +#define MB_TYPE_INTRA16x16 0x0002 //FIXME H.264-specific +#define MB_TYPE_INTRA_PCM 0x0004 //FIXME H.264-specific +#define MB_TYPE_16x16 0x0008 +#define MB_TYPE_16x8 0x0010 +#define MB_TYPE_8x16 0x0020 +#define MB_TYPE_8x8 0x0040 +#define MB_TYPE_INTERLACED 0x0080 +#define MB_TYPE_DIRECT2 0x0100 //FIXME +#define MB_TYPE_ACPRED 0x0200 +#define MB_TYPE_GMC 0x0400 +#define MB_TYPE_SKIP 0x0800 +#define MB_TYPE_P0L0 0x1000 +#define MB_TYPE_P1L0 0x2000 +#define MB_TYPE_P0L1 0x4000 +#define MB_TYPE_P1L1 0x8000 +#define MB_TYPE_L0 (MB_TYPE_P0L0 | MB_TYPE_P1L0) +#define MB_TYPE_L1 (MB_TYPE_P0L1 | MB_TYPE_P1L1) +#define MB_TYPE_L0L1 (MB_TYPE_L0 | MB_TYPE_L1) +#define MB_TYPE_QUANT 0x00010000 +#define MB_TYPE_CBP 0x00020000 +//Note bits 24-31 are reserved for codec specific use (h264 ref0, mpeg1 0mv, ...) + +/** + * Pan Scan area. + * This specifies the area which should be displayed. + * Note there may be multiple such areas for one frame. + */ +typedef struct AVPanScan{ + /** + * id + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + int id; + + /** + * width and height in 1/16 pel + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + int width; + int height; + + /** + * position of the top left corner in 1/16 pel for up to 3 fields/frames + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + int16_t position[3][2]; +}AVPanScan; + +#define FF_COMMON_FRAME \ + /**\ + * pointer to the picture planes.\ + * This might be different from the first allocated byte\ + * - encoding: \ + * - decoding: \ + */\ + uint8_t *data[4];\ + int linesize[4];\ + /**\ + * pointer to the first allocated byte of the picture. Can be used in get_buffer/release_buffer.\ + * This isn't used by libavcodec unless the default get/release_buffer() is used.\ + * - encoding: \ + * - decoding: \ + */\ + uint8_t *base[4];\ + /**\ + * 1 -> keyframe, 0-> not\ + * - encoding: Set by libavcodec.\ + * - decoding: Set by libavcodec.\ + */\ + int key_frame;\ +\ + /**\ + * Picture type of the frame, see ?_TYPE below.\ + * - encoding: Set by libavcodec. for coded_picture (and set by user for input).\ + * - decoding: Set by libavcodec.\ + */\ + int pict_type;\ +\ + /**\ + * presentation timestamp in time_base units (time when frame should be shown to user)\ + * If AV_NOPTS_VALUE then frame_rate = 1/time_base will be assumed.\ + * - encoding: MUST be set by user.\ + * - decoding: Set by libavcodec.\ + */\ + int64_t pts;\ +\ + /**\ + * picture number in bitstream order\ + * - encoding: set by\ + * - decoding: Set by libavcodec.\ + */\ + int coded_picture_number;\ + /**\ + * picture number in display order\ + * - encoding: set by\ + * - decoding: Set by libavcodec.\ + */\ + int display_picture_number;\ +\ + /**\ + * quality (between 1 (good) and FF_LAMBDA_MAX (bad)) \ + * - encoding: Set by libavcodec. for coded_picture (and set by user for input).\ + * - decoding: Set by libavcodec.\ + */\ + int quality; \ +\ + /**\ + * buffer age (1->was last buffer and dint change, 2->..., ...).\ + * Set to INT_MAX if the buffer has not been used yet.\ + * - encoding: unused\ + * - decoding: MUST be set by get_buffer().\ + */\ + int age;\ +\ + /**\ + * is this picture used as reference\ + * The values for this are the same as the MpegEncContext.picture_structure\ + * variable, that is 1->top field, 2->bottom field, 3->frame/both fields.\ + * Set to 4 for delayed, non-reference frames.\ + * - encoding: unused\ + * - decoding: Set by libavcodec. (before get_buffer() call)).\ + */\ + int reference;\ +\ + /**\ + * QP table\ + * - encoding: unused\ + * - decoding: Set by libavcodec.\ + */\ + int8_t *qscale_table;\ + /**\ + * QP store stride\ + * - encoding: unused\ + * - decoding: Set by libavcodec.\ + */\ + int qstride;\ +\ + /**\ + * mbskip_table[mb]>=1 if MB didn't change\ + * stride= mb_width = (width+15)>>4\ + * - encoding: unused\ + * - decoding: Set by libavcodec.\ + */\ + uint8_t *mbskip_table;\ +\ + /**\ + * motion vector table\ + * @code\ + * example:\ + * int mv_sample_log2= 4 - motion_subsample_log2;\ + * int mb_width= (width+15)>>4;\ + * int mv_stride= (mb_width << mv_sample_log2) + 1;\ + * motion_val[direction][x + y*mv_stride][0->mv_x, 1->mv_y];\ + * @endcode\ + * - encoding: Set by user.\ + * - decoding: Set by libavcodec.\ + */\ + int16_t (*motion_val[2])[2];\ +\ + /**\ + * macroblock type table\ + * mb_type_base + mb_width + 2\ + * - encoding: Set by user.\ + * - decoding: Set by libavcodec.\ + */\ + uint32_t *mb_type;\ +\ + /**\ + * log2 of the size of the block which a single vector in motion_val represents: \ + * (4->16x16, 3->8x8, 2-> 4x4, 1-> 2x2)\ + * - encoding: unused\ + * - decoding: Set by libavcodec.\ + */\ + uint8_t motion_subsample_log2;\ +\ + /**\ + * for some private data of the user\ + * - encoding: unused\ + * - decoding: Set by user.\ + */\ + void *opaque;\ +\ + /**\ + * error\ + * - encoding: Set by libavcodec. if flags&CODEC_FLAG_PSNR.\ + * - decoding: unused\ + */\ + uint64_t error[4];\ +\ + /**\ + * type of the buffer (to keep track of who has to deallocate data[*])\ + * - encoding: Set by the one who allocates it.\ + * - decoding: Set by the one who allocates it.\ + * Note: User allocated (direct rendering) & internal buffers cannot coexist currently.\ + */\ + int type;\ + \ + /**\ + * When decoding, this signals how much the picture must be delayed.\ + * extra_delay = repeat_pict / (2*fps)\ + * - encoding: unused\ + * - decoding: Set by libavcodec.\ + */\ + int repeat_pict;\ + \ + /**\ + * \ + */\ + int qscale_type;\ + \ + /**\ + * The content of the picture is interlaced.\ + * - encoding: Set by user.\ + * - decoding: Set by libavcodec. (default 0)\ + */\ + int interlaced_frame;\ + \ + /**\ + * If the content is interlaced, is top field displayed first.\ + * - encoding: Set by user.\ + * - decoding: Set by libavcodec.\ + */\ + int top_field_first;\ + \ + /**\ + * Pan scan.\ + * - encoding: Set by user.\ + * - decoding: Set by libavcodec.\ + */\ + AVPanScan *pan_scan;\ + \ + /**\ + * Tell user application that palette has changed from previous frame.\ + * - encoding: ??? (no palette-enabled encoder yet)\ + * - decoding: Set by libavcodec. (default 0).\ + */\ + int palette_has_changed;\ + \ + /**\ + * codec suggestion on buffer type if != 0\ + * - encoding: unused\ + * - decoding: Set by libavcodec. (before get_buffer() call)).\ + */\ + int buffer_hints;\ +\ + /**\ + * DCT coefficients\ + * - encoding: unused\ + * - decoding: Set by libavcodec.\ + */\ + short *dct_coeff;\ +\ + /**\ + * motion referece frame index\ + * - encoding: Set by user.\ + * - decoding: Set by libavcodec.\ + */\ + int8_t *ref_index[2];\ +\ + /**\ + * reordered opaque 64bit number (generally a PTS) from AVCodecContext.reordered_opaque\ + * output in AVFrame.reordered_opaque\ + * - encoding: unused\ + * - decoding: Read by user.\ + */\ + int64_t reordered_opaque;\ +\ + /**\ + * hardware accelerator private data (FFmpeg allocated)\ + * - encoding: unused\ + * - decoding: Set by libavcodec\ + */\ + void *hwaccel_picture_private;\ + + +#define FF_QSCALE_TYPE_MPEG1 0 +#define FF_QSCALE_TYPE_MPEG2 1 +#define FF_QSCALE_TYPE_H264 2 + +#define FF_BUFFER_TYPE_INTERNAL 1 +#define FF_BUFFER_TYPE_USER 2 ///< direct rendering buffers (image is (de)allocated by user) +#define FF_BUFFER_TYPE_SHARED 4 ///< Buffer from somewhere else; don't deallocate image (data/base), all other tables are not shared. +#define FF_BUFFER_TYPE_COPY 8 ///< Just a (modified) copy of some other buffer, don't deallocate anything. + + +#define FF_I_TYPE 1 ///< Intra +#define FF_P_TYPE 2 ///< Predicted +#define FF_B_TYPE 3 ///< Bi-dir predicted +#define FF_S_TYPE 4 ///< S(GMC)-VOP MPEG4 +#define FF_SI_TYPE 5 ///< Switching Intra +#define FF_SP_TYPE 6 ///< Switching Predicted +#define FF_BI_TYPE 7 + +#define FF_BUFFER_HINTS_VALID 0x01 // Buffer hints value is meaningful (if 0 ignore). +#define FF_BUFFER_HINTS_READABLE 0x02 // Codec will read from buffer. +#define FF_BUFFER_HINTS_PRESERVE 0x04 // User must not alter buffer content. +#define FF_BUFFER_HINTS_REUSABLE 0x08 // Codec will reuse the buffer (update). + +/** + * Audio Video Frame. + * New fields can be added to the end of FF_COMMON_FRAME with minor version + * bumps. + * Removal, reordering and changes to existing fields require a major + * version bump. No fields should be added into AVFrame before or after + * FF_COMMON_FRAME! + * sizeof(AVFrame) must not be used outside libav*. + */ +typedef struct AVFrame { + FF_COMMON_FRAME +} AVFrame; +#endif/* MT : DELETE THIS LINE.*/ +/** + * main external API structure. + * New fields can be added to the end with minor version bumps. + * Removal, reordering and changes to existing fields require a major + * version bump. + * sizeof(AVCodecContext) must not be used outside libav*. + */ +typedef struct AVCodecContext { + /** + * information on struct for av_log + * - set by avcodec_alloc_context + */ + const AVClass *av_class; + /** + * the average bitrate + * - encoding: Set by user; unused for constant quantizer encoding. + * - decoding: Set by libavcodec. 0 or some bitrate if this info is available in the stream. + */ + int bit_rate; + + /** + * number of bits the bitstream is allowed to diverge from the reference. + * the reference can be CBR (for CBR pass1) or VBR (for pass2) + * - encoding: Set by user; unused for constant quantizer encoding. + * - decoding: unused + */ +//MT: int bit_rate_tolerance; + + /** + * CODEC_FLAG_*. + * - encoding: Set by user. + * - decoding: Set by user. + */ +//MT: int flags; + + /** + * Some codecs need additional format info. It is stored here. + * If any muxer uses this then ALL demuxers/parsers AND encoders for the + * specific codec MUST set it correctly otherwise stream copy breaks. + * In general use of this field by muxers is not recommanded. + * - encoding: Set by libavcodec. + * - decoding: Set by libavcodec. (FIXME: Is this OK?) + */ +//MT: int sub_id; + + /** + * Motion estimation algorithm used for video coding. + * 1 (zero), 2 (full), 3 (log), 4 (phods), 5 (epzs), 6 (x1), 7 (hex), + * 8 (umh), 9 (iter), 10 (tesa) [7, 8, 10 are x264 specific, 9 is snow specific] + * - encoding: MUST be set by user. + * - decoding: unused + */ +//MT: int me_method; + + /** + * some codecs need / can use extradata like Huffman tables. + * mjpeg: Huffman tables + * rv10: additional flags + * mpeg4: global headers (they can be in the bitstream or here) + * The allocated memory should be FF_INPUT_BUFFER_PADDING_SIZE bytes larger + * than extradata_size to avoid prolems if it is read with the bitstream reader. + * The bytewise contents of extradata must not depend on the architecture or CPU endianness. + * - encoding: Set/allocated/freed by libavcodec. + * - decoding: Set/allocated/freed by user. + */ + uint8_t *extradata; + int extradata_size; + + /** + * This is the fundamental unit of time (in seconds) in terms + * of which frame timestamps are represented. For fixed-fps content, + * timebase should be 1/framerate and timestamp increments should be + * identically 1. + * - encoding: MUST be set by user. + * - decoding: Set by libavcodec. + */ +//MT: AVRational time_base; + + /* video only */ + /** + * picture width / height. + * - encoding: MUST be set by user. + * - decoding: Set by libavcodec. + * Note: For compatibility it is possible to set this instead of + * coded_width/height before decoding. + */ +//MT: int width, height; + +//MT:#define FF_ASPECT_EXTENDED 15 + + /** + * the number of pictures in a group of pictures, or 0 for intra_only + * - encoding: Set by user. + * - decoding: unused + */ +//MT: int gop_size; + + /** + * Pixel format, see PIX_FMT_xxx. + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + //MT: enum PixelFormat pix_fmt; + + /** + * Frame rate emulation. If not zero, the lower layer (i.e. format handler) + * has to read frames at native frame rate. + * - encoding: Set by user. + * - decoding: unused + */ +//MT: int rate_emu; + + /** + * If non NULL, 'draw_horiz_band' is called by the libavcodec + * decoder to draw a horizontal band. It improves cache usage. Not + * all codecs can do that. You must check the codec capabilities + * beforehand. + * The function is also used by hardware acceleration APIs. + * It is called at least once during frame decoding to pass + * the data needed for hardware render. + * In that mode instead of pixel data, AVFrame points to + * a structure specific to the acceleration API. The application + * reads the structure and can change some fields to indicate progress + * or mark state. + * - encoding: unused + * - decoding: Set by user. + * @param height the height of the slice + * @param y the y position of the slice + * @param type 1->top field, 2->bottom field, 3->frame + * @param offset offset into the AVFrame.data from which the slice should be read + */ + //MT: void (*draw_horiz_band)(struct AVCodecContext *s, + //Mt: const AVFrame *src, int offset[4], + //MT: int y, int type, int height); + + /* audio only */ + int sample_rate; ///< samples per second + int channels; ///< number of audio channels + + /** + * audio sample format + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + enum SampleFormat sample_fmt; ///< sample format, currently unused + + /* The following data should not be initialized. */ + /** + * Samples per packet, initialized when calling 'init'. + */ + int frame_size; + int frame_number; ///< audio or video frame number +//MT: int real_pict_num; ///< Returns the real picture number of previous encoded frame. + + /** + * Number of frames the decoded output will be delayed relative to + * the encoded input. + * - encoding: Set by libavcodec. + * - decoding: unused + */ +//MT: int delay; + + /* - encoding parameters */ +//MT: float qcompress; ///< amount of qscale change between easy & hard scenes (0.0-1.0) +//MT: float qblur; ///< amount of qscale smoothing over time (0.0-1.0) + + /** + * minimum quantizer + * - encoding: Set by user. + * - decoding: unused + */ +//MT: int qmin; + + /** + * maximum quantizer + * - encoding: Set by user. + * - decoding: unused + */ +//MT: int qmax; + + /** + * maximum quantizer difference between frames + * - encoding: Set by user. + * - decoding: unused + */ +//MT: int max_qdiff; + + /** + * maximum number of B-frames between non-B-frames + * Note: The output will be delayed by max_b_frames+1 relative to the input. + * - encoding: Set by user. + * - decoding: unused + */ +//MT: int max_b_frames; + + /** + * qscale factor between IP and B-frames + * If > 0 then the last P-frame quantizer will be used (q= lastp_q*factor+offset). + * If < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset). + * - encoding: Set by user. + * - decoding: unused + */ +//MT: float b_quant_factor; + + /** obsolete FIXME remove */ +//MT: int rc_strategy; +//MT:#define FF_RC_STRATEGY_XVID 1 + +//MT: int b_frame_strategy; + + /** + * hurry up amount + * - encoding: unused + * - decoding: Set by user. 1-> Skip B-frames, 2-> Skip IDCT/dequant too, 5-> Skip everything except header + * @deprecated Deprecated in favor of skip_idct and skip_frame. + */ +//MT: int hurry_up; + + struct AVCodec *codec; + + void *priv_data; + +//MT: int rtp_payload_size; /* The size of the RTP payload: the coder will */ + /* do its best to deliver a chunk with size */ + /* below rtp_payload_size, the chunk will start */ + /* with a start code on some codecs like H.263. */ + /* This doesn't take account of any particular */ + /* headers inside the transmitted RTP payload. */ + + + /* The RTP callback: This function is called */ + /* every time the encoder has a packet to send. */ + /* It depends on the encoder if the data starts */ + /* with a Start Code (it should). H.263 does. */ + /* mb_nb contains the number of macroblocks */ + /* encoded in the RTP payload. */ +//MT: void (*rtp_callback)(struct AVCodecContext *avctx, void *data, int size, int mb_nb); + + /* statistics, used for 2-pass encoding */ +//MT: int mv_bits; +//MT: int header_bits; +//MT: int i_tex_bits; + //MT: int p_tex_bits; +//MT: int i_count; + //MT: int p_count; + //MT: int skip_count; + //MT: int misc_bits; + + /** + * number of bits used for the previously encoded frame + * - encoding: Set by libavcodec. + * - decoding: unused + */ +//MT: int frame_bits; + + /** + * Private data of the user, can be used to carry app specific stuff. + * - encoding: Set by user. + * - decoding: Set by user. + */ +//MT: void *opaque; + + char codec_name[32]; + enum CodecType codec_type; /* see CODEC_TYPE_xxx */ + enum CodecID codec_id; /* see CODEC_ID_xxx */ + + /** + * fourcc (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A'). + * This is used to work around some encoder bugs. + * A demuxer should set this to what is stored in the field used to identify the codec. + * If there are multiple such fields in a container then the demuxer should choose the one + * which maximizes the information about the used codec. + * If the codec tag field in a container is larger then 32 bits then the demuxer should + * remap the longer ID to 32 bits with a table or other structure. Alternatively a new + * extra_codec_tag + size could be added but for this a clear advantage must be demonstrated + * first. + * - encoding: Set by user, if not then the default based on codec_id will be used. + * - decoding: Set by user, will be converted to uppercase by libavcodec during init. + */ +//MT: unsigned int codec_tag; + + /** + * Work around bugs in encoders which sometimes cannot be detected automatically. + * - encoding: Set by user + * - decoding: Set by user + */ +//MT: int workaround_bugs; +#define FF_BUG_AUTODETECT 1 ///< autodetection +#define FF_BUG_OLD_MSMPEG4 2 +#define FF_BUG_XVID_ILACE 4 +#define FF_BUG_UMP4 8 +#define FF_BUG_NO_PADDING 16 +#define FF_BUG_AMV 32 +#define FF_BUG_AC_VLC 0 ///< Will be removed, libavcodec can now handle these non-compliant files by default. +#define FF_BUG_QPEL_CHROMA 64 +#define FF_BUG_STD_QPEL 128 +#define FF_BUG_QPEL_CHROMA2 256 +#define FF_BUG_DIRECT_BLOCKSIZE 512 +#define FF_BUG_EDGE 1024 +#define FF_BUG_HPEL_CHROMA 2048 +#define FF_BUG_DC_CLIP 4096 +#define FF_BUG_MS 8192 ///< Work around various bugs in Microsoft's broken decoders. +//#define FF_BUG_FAKE_SCALABILITY 16 //Autodetection should work 100%. + + /** + * luma single coefficient elimination threshold + * - encoding: Set by user. + * - decoding: unused + */ +//MT: int luma_elim_threshold; + + /** + * chroma single coeff elimination threshold + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int chroma_elim_threshold; + + /** + * strictly follow the standard (MPEG4, ...). + * - encoding: Set by user. + * - decoding: Set by user. + * Setting this to STRICT or higher means the encoder and decoder will + * generally do stupid things. While setting it to inofficial or lower + * will mean the encoder might use things that are not supported by all + * spec compliant decoders. Decoders make no difference between normal, + * inofficial and experimental, that is they always try to decode things + * when they can unless they are explicitly asked to behave stupid + * (=strictly conform to the specs) + */ +//MT: int strict_std_compliance; +#define FF_COMPLIANCE_VERY_STRICT 2 ///< Strictly conform to a older more strict version of the spec or reference software. +#define FF_COMPLIANCE_STRICT 1 ///< Strictly conform to all the things in the spec no matter what consequences. +#define FF_COMPLIANCE_NORMAL 0 +#define FF_COMPLIANCE_INOFFICIAL -1 ///< Allow inofficial extensions. +#define FF_COMPLIANCE_EXPERIMENTAL -2 ///< Allow nonstandardized experimental things. + + /** + * qscale offset between IP and B-frames + * - encoding: Set by user. + * - decoding: unused + */ +//MT: float b_quant_offset; + + /** + * Error recognization; higher values will detect more errors but may + * misdetect some more or less valid parts as errors. + * - encoding: unused + * - decoding: Set by user. + */ +//MT: int error_recognition; +#define FF_ER_CAREFUL 1 +#define FF_ER_COMPLIANT 2 +#define FF_ER_AGGRESSIVE 3 +#define FF_ER_VERY_AGGRESSIVE 4 + + /** + * Called at the beginning of each frame to get a buffer for it. + * If pic.reference is set then the frame will be read later by libavcodec. + * avcodec_align_dimensions() should be used to find the required width and + * height, as they normally need to be rounded up to the next multiple of 16. + * - encoding: unused + * - decoding: Set by libavcodec., user can override. + */ + //MT: int (*get_buffer)(struct AVCodecContext *c, AVFrame *pic); + + /** + * Called to release buffers which were allocated with get_buffer. + * A released buffer can be reused in get_buffer(). + * pic.data[*] must be set to NULL. + * - encoding: unused + * - decoding: Set by libavcodec., user can override. + */ +//MT: void (*release_buffer)(struct AVCodecContext *c, AVFrame *pic); + + /** + * Size of the frame reordering buffer in the decoder. + * For MPEG-2 it is 1 IPB or 0 low delay IP. + * - encoding: Set by libavcodec. + * - decoding: Set by libavcodec. + */ +//MT: int has_b_frames; + + /** + * number of bytes per packet if constant and known or 0 + * Used by some WAV based audio codecs. + */ + int block_align; + +//MT: int parse_only; /* - decoding only: If true, only parsing is done + /*(function avcodec_parse_frame()). The frame + data is returned. Only MPEG codecs support this now. */ + + /** + * 0-> h263 quant 1-> mpeg quant + * - encoding: Set by user. + * - decoding: unused + */ +//MT: int mpeg_quant; + + /** + * pass1 encoding statistics output buffer + * - encoding: Set by libavcodec. + * - decoding: unused + */ +//MT: char *stats_out; + + /** + * pass2 encoding statistics input buffer + * Concatenated stuff from stats_out of pass1 should be placed here. + * - encoding: Allocated/set/freed by user. + * - decoding: unused + */ +//MT: char *stats_in; + + /** + * ratecontrol qmin qmax limiting method + * 0-> clipping, 1-> use a nice continous function to limit qscale wthin qmin/qmax. + * - encoding: Set by user. + * - decoding: unused + */ +//MT: float rc_qsquish; + +//MT: float rc_qmod_amp; + //MT: int rc_qmod_freq; + + /** + * ratecontrol override, see RcOverride + * - encoding: Allocated/set/freed by user. + * - decoding: unused + */ + //MT: RcOverride *rc_override; + //MT: int rc_override_count; + + /** + * rate control equation + * - encoding: Set by user + * - decoding: unused + */ +//MT: const char *rc_eq; + + /** + * maximum bitrate + * - encoding: Set by user. + * - decoding: unused + */ +//MT: int rc_max_rate; + + /** + * minimum bitrate + * - encoding: Set by user. + * - decoding: unused + */ +//MT: int rc_min_rate; + + /** + * decoder bitstream buffer size + * - encoding: Set by user. + * - decoding: unused + */ +//MT: int rc_buffer_size; + //MT: float rc_buffer_aggressivity; + + /** + * qscale factor between P and I-frames + * If > 0 then the last p frame quantizer will be used (q= lastp_q*factor+offset). + * If < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset). + * - encoding: Set by user. + * - decoding: unused + */ +//MT: float i_quant_factor; + + /** + * qscale offset between P and I-frames + * - encoding: Set by user. + * - decoding: unused + */ +//MT: float i_quant_offset; + + /** + * initial complexity for pass1 ratecontrol + * - encoding: Set by user. + * - decoding: unused + */ +//MT: float rc_initial_cplx; + + /** + * DCT algorithm, see FF_DCT_* below + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int dct_algo; +#define FF_DCT_AUTO 0 +#define FF_DCT_FASTINT 1 +#define FF_DCT_INT 2 +#define FF_DCT_MMX 3 +#define FF_DCT_MLIB 4 +#define FF_DCT_ALTIVEC 5 +#define FF_DCT_FAAN 6 + + /** + * luminance masking (0-> disabled) + * - encoding: Set by user. + * - decoding: unused + */ + //MT: float lumi_masking; + + /** + * temporary complexity masking (0-> disabled) + * - encoding: Set by user. + * - decoding: unused + */ + //MT: float temporal_cplx_masking; + + /** + * spatial complexity masking (0-> disabled) + * - encoding: Set by user. + * - decoding: unused + */ + //MT: float spatial_cplx_masking; + + /** + * p block masking (0-> disabled) + * - encoding: Set by user. + * - decoding: unused + */ + //MT: float p_masking; + + /** + * darkness masking (0-> disabled) + * - encoding: Set by user. + * - decoding: unused + */ + //MT: float dark_masking; + + /** + * IDCT algorithm, see FF_IDCT_* below. + * - encoding: Set by user. + * - decoding: Set by user. + */ + //MT: int idct_algo; +#define FF_IDCT_AUTO 0 +#define FF_IDCT_INT 1 +#define FF_IDCT_SIMPLE 2 +#define FF_IDCT_SIMPLEMMX 3 +#define FF_IDCT_LIBMPEG2MMX 4 +#define FF_IDCT_PS2 5 +#define FF_IDCT_MLIB 6 +#define FF_IDCT_ARM 7 +#define FF_IDCT_ALTIVEC 8 +#define FF_IDCT_SH4 9 +#define FF_IDCT_SIMPLEARM 10 +#define FF_IDCT_H264 11 +#define FF_IDCT_VP3 12 +#define FF_IDCT_IPP 13 +#define FF_IDCT_XVIDMMX 14 +#define FF_IDCT_CAVS 15 +#define FF_IDCT_SIMPLEARMV5TE 16 +#define FF_IDCT_SIMPLEARMV6 17 +#define FF_IDCT_SIMPLEVIS 18 +#define FF_IDCT_WMV2 19 +#define FF_IDCT_FAAN 20 +#define FF_IDCT_EA 21 +#define FF_IDCT_SIMPLENEON 22 +#define FF_IDCT_SIMPLEALPHA 23 + + /** + * slice count + * - encoding: Set by libavcodec. + * - decoding: Set by user (or 0). + */ +//MT: int slice_count; + /** + * slice offsets in the frame in bytes + * - encoding: Set/allocated by libavcodec. + * - decoding: Set/allocated by user (or NULL). + */ + //MT: int *slice_offset; + + /** + * error concealment flags + * - encoding: unused + * - decoding: Set by user. + */ +//MT: int error_concealment; +#define FF_EC_GUESS_MVS 1 +#define FF_EC_DEBLOCK 2 + + /** + * dsp_mask could be add used to disable unwanted CPU features + * CPU features (i.e. MMX, SSE. ...) + * + * With the FORCE flag you may instead enable given CPU features. + * (Dangerous: Usable in case of misdetection, improper usage however will + * result into program crash.) + */ + //MT: unsigned dsp_mask; +#define FF_MM_FORCE 0x80000000 /* Force usage of selected flags (OR) */ + /* lower 16 bits - CPU features */ +#define FF_MM_MMX 0x0001 ///< standard MMX +#define FF_MM_3DNOW 0x0004 ///< AMD 3DNOW +#define FF_MM_MMXEXT 0x0002 ///< SSE integer functions or AMD MMX ext +#define FF_MM_SSE 0x0008 ///< SSE functions +#define FF_MM_SSE2 0x0010 ///< PIV SSE2 functions +#define FF_MM_3DNOWEXT 0x0020 ///< AMD 3DNowExt +#define FF_MM_SSE3 0x0040 ///< Prescott SSE3 functions +#define FF_MM_SSSE3 0x0080 ///< Conroe SSSE3 functions +#define FF_MM_IWMMXT 0x0100 ///< XScale IWMMXT +#define FF_MM_ALTIVEC 0x0001 ///< standard AltiVec + + /** + * bits per sample/pixel from the demuxer (needed for huffyuv). + * - encoding: Set by libavcodec. + * - decoding: Set by user. + */ + //MT: int bits_per_coded_sample; + + /** + * prediction method (needed for huffyuv) + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int prediction_method; +#define FF_PRED_LEFT 0 +#define FF_PRED_PLANE 1 +#define FF_PRED_MEDIAN 2 + + /** + * sample aspect ratio (0 if unknown) + * That is the width of a pixel divided by the height of the pixel. + * Numerator and denominator must be relatively prime and smaller than 256 for some video standards. + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + //MT: AVRational sample_aspect_ratio; + + /** + * the picture in the bitstream + * - encoding: Set by libavcodec. + * - decoding: Set by libavcodec. + */ + //MT: AVFrame *coded_frame; + + /** + * debug + * - encoding: Set by user. + * - decoding: Set by user. + */ + //MT: int debug; +#define FF_DEBUG_PICT_INFO 1 +#define FF_DEBUG_RC 2 +#define FF_DEBUG_BITSTREAM 4 +#define FF_DEBUG_MB_TYPE 8 +#define FF_DEBUG_QP 16 +#define FF_DEBUG_MV 32 +#define FF_DEBUG_DCT_COEFF 0x00000040 +#define FF_DEBUG_SKIP 0x00000080 +#define FF_DEBUG_STARTCODE 0x00000100 +#define FF_DEBUG_PTS 0x00000200 +#define FF_DEBUG_ER 0x00000400 +#define FF_DEBUG_MMCO 0x00000800 +#define FF_DEBUG_BUGS 0x00001000 +#define FF_DEBUG_VIS_QP 0x00002000 +#define FF_DEBUG_VIS_MB_TYPE 0x00004000 +#define FF_DEBUG_BUFFERS 0x00008000 + + /** + * debug + * - encoding: Set by user. + * - decoding: Set by user. + */ + //MT: int debug_mv; +#define FF_DEBUG_VIS_MV_P_FOR 0x00000001 //visualize forward predicted MVs of P frames +#define FF_DEBUG_VIS_MV_B_FOR 0x00000002 //visualize forward predicted MVs of B frames +#define FF_DEBUG_VIS_MV_B_BACK 0x00000004 //visualize backward predicted MVs of B frames + + /** + * error + * - encoding: Set by libavcodec if flags&CODEC_FLAG_PSNR. + * - decoding: unused + */ + uint64_t error[4]; + + /** + * minimum MB quantizer + * - encoding: unused + * - decoding: unused + */ +//MT: int mb_qmin; + + /** + * maximum MB quantizer + * - encoding: unused + * - decoding: unused + */ +//MT: int mb_qmax; + + /** + * motion estimation comparison function + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int me_cmp; + /** + * subpixel motion estimation comparison function + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int me_sub_cmp; + /** + * macroblock comparison function (not supported yet) + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int mb_cmp; + /** + * interlaced DCT comparison function + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int ildct_cmp; +#define FF_CMP_SAD 0 +#define FF_CMP_SSE 1 +#define FF_CMP_SATD 2 +#define FF_CMP_DCT 3 +#define FF_CMP_PSNR 4 +#define FF_CMP_BIT 5 +#define FF_CMP_RD 6 +#define FF_CMP_ZERO 7 +#define FF_CMP_VSAD 8 +#define FF_CMP_VSSE 9 +#define FF_CMP_NSSE 10 +#define FF_CMP_W53 11 +#define FF_CMP_W97 12 +#define FF_CMP_DCTMAX 13 +#define FF_CMP_DCT264 14 +#define FF_CMP_CHROMA 256 + + /** + * ME diamond size & shape + * - encoding: Set by user. + * - decoding: unused + */ +//MT: int dia_size; + + /** + * amount of previous MV predictors (2a+1 x 2a+1 square) + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int last_predictor_count; + + /** + * prepass for motion estimation + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int pre_me; + + /** + * motion estimation prepass comparison function + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int me_pre_cmp; + + /** + * ME prepass diamond size & shape + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int pre_dia_size; + + /** + * subpel ME quality + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int me_subpel_quality; + + /** + * callback to negotiate the pixelFormat + * @param fmt is the list of formats which are supported by the codec, + * it is terminated by -1 as 0 is a valid format, the formats are ordered by quality. + * The first is always the native one. + * @return the chosen format + * - encoding: unused + * - decoding: Set by user, if not set the native format will be chosen. + */ + //MT: enum PixelFormat (*get_format)(struct AVCodecContext *s, const enum PixelFormat * fmt); + + /** + * DTG active format information (additional aspect ratio + * information only used in DVB MPEG-2 transport streams) + * 0 if not set. + * + * - encoding: unused + * - decoding: Set by decoder. + */ + //MT: int dtg_active_format; +#define FF_DTG_AFD_SAME 8 +#define FF_DTG_AFD_4_3 9 +#define FF_DTG_AFD_16_9 10 +#define FF_DTG_AFD_14_9 11 +#define FF_DTG_AFD_4_3_SP_14_9 13 +#define FF_DTG_AFD_16_9_SP_14_9 14 +#define FF_DTG_AFD_SP_4_3 15 + + /** + * maximum motion estimation search range in subpel units + * If 0 then no limit. + * + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int me_range; + + /** + * intra quantizer bias + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int intra_quant_bias; +#define FF_DEFAULT_QUANT_BIAS 999999 + + /** + * inter quantizer bias + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int inter_quant_bias; + + /** + * color table ID + * - encoding: unused + * - decoding: Which clrtable should be used for 8bit RGB images. + * Tables have to be stored somewhere. FIXME + */ + //MT: int color_table_id; + + /** + * internal_buffer count + * Don't touch, used by libavcodec default_get_buffer(). + */ + //MT: int internal_buffer_count; + + /** + * internal_buffers + * Don't touch, used by libavcodec default_get_buffer(). + */ + void *internal_buffer; + +#define FF_LAMBDA_SHIFT 7 +#define FF_LAMBDA_SCALE (1< ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A'). + * This is used to work around some encoder bugs. + * - encoding: unused + * - decoding: Set by user, will be converted to uppercase by libavcodec during init. + */ + //MT: unsigned int stream_codec_tag; + + /** + * scene change detection threshold + * 0 is default, larger means fewer detected scene changes. + * - encoding: Set by user. + * - decoding: unused + */ +//MT: int scenechange_threshold; + + /** + * minimum Lagrange multipler + * - encoding: Set by user. + * - decoding: unused + */ +//MT: int lmin; + + /** + * maximum Lagrange multipler + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int lmax; + + /** + * palette control structure + * - encoding: ??? (no palette-enabled encoder yet) + * - decoding: Set by user. + */ + //MT: struct AVPaletteControl *palctrl; + + /** + * noise reduction strength + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int noise_reduction; + + /** + * Called at the beginning of a frame to get cr buffer for it. + * Buffer type (size, hints) must be the same. libavcodec won't check it. + * libavcodec will pass previous buffer in pic, function should return + * same buffer or new buffer with old frame "painted" into it. + * If pic.data[0] == NULL must behave like get_buffer(). + * - encoding: unused + * - decoding: Set by libavcodec., user can override + */ +//MT: int (*reget_buffer)(struct AVCodecContext *c, AVFrame *pic); + + /** + * Number of bits which should be loaded into the rc buffer before decoding starts. + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int rc_initial_buffer_occupancy; + + /** + * + * - encoding: Set by user. + * - decoding: unused + */ +//MT: int inter_threshold; + + /** + * CODEC_FLAG2_* + * - encoding: Set by user. + * - decoding: Set by user. + */ + //MT: int flags2; + + /** + * Simulates errors in the bitstream to test error concealment. + * - encoding: Set by user. + * - decoding: unused + */ +//MT: int error_rate; + + /** + * MP3 antialias algorithm, see FF_AA_* below. + * - encoding: unused + * - decoding: Set by user. + */ + //MT: int antialias_algo; +#define FF_AA_AUTO 0 +#define FF_AA_FASTINT 1 //not implemented yet +#define FF_AA_INT 2 +#define FF_AA_FLOAT 3 + /** + * quantizer noise shaping + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int quantizer_noise_shaping; + + /** + * thread count + * is used to decide how many independent tasks should be passed to execute() + * - encoding: Set by user. + * - decoding: Set by user. + */ + //MT: int thread_count; + + /** + * The codec may call this to execute several independent things. + * It will return only after finishing all tasks. + * The user may replace this with some multithreaded implementation, + * the default implementation will execute the parts serially. + * @param count the number of things to execute + * - encoding: Set by libavcodec, user can override. + * - decoding: Set by libavcodec, user can override. + */ + //MT: int (*execute)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg), void *arg2, int *ret, int count, int size); + + /** + * thread opaque + * Can be used by execute() to store some per AVCodecContext stuff. + * - encoding: set by execute() + * - decoding: set by execute() + */ + //MT: void *thread_opaque; + + /** + * Motion estimation threshold below which no motion estimation is + * performed, but instead the user specified motion vectors are used. + * + * - encoding: Set by user. + * - decoding: unused + */ +//MT: int me_threshold; + + /** + * Macroblock threshold below which the user specified macroblock types will be used. + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int mb_threshold; + + /** + * precision of the intra DC coefficient - 8 + * - encoding: Set by user. + * - decoding: unused + */ +//MT: int intra_dc_precision; + + /** + * noise vs. sse weight for the nsse comparsion function + * - encoding: Set by user. + * - decoding: unused + */ +//MT: int nsse_weight; + + /** + * Number of macroblock rows at the top which are skipped. + * - encoding: unused + * - decoding: Set by user. + */ + //MT: int skip_top; + + /** + * Number of macroblock rows at the bottom which are skipped. + * - encoding: unused + * - decoding: Set by user. + */ + //MT: int skip_bottom; + + /** + * profile + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + //MT: int profile; +#define FF_PROFILE_UNKNOWN -99 +#define FF_PROFILE_AAC_MAIN 0 +#define FF_PROFILE_AAC_LOW 1 +#define FF_PROFILE_AAC_SSR 2 +#define FF_PROFILE_AAC_LTP 3 + + /** + * level + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + //MT: int level; +#define FF_LEVEL_UNKNOWN -99 + + /** + * low resolution decoding, 1-> 1/2 size, 2->1/4 size + * - encoding: unused + * - decoding: Set by user. + */ + //MT: int lowres; + + /** + * Bitstream width / height, may be different from width/height if lowres + * or other things are used. + * - encoding: unused + * - decoding: Set by user before init if known. Codec should override / dynamically change if needed. + */ + //MT: int coded_width, coded_height; + + /** + * frame skip threshold + * - encoding: Set by user. + * - decoding: unused + */ +//MT: int frame_skip_threshold; + + /** + * frame skip factor + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int frame_skip_factor; + + /** + * frame skip exponent + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int frame_skip_exp; + + /** + * frame skip comparison function + * - encoding: Set by user. + * - decoding: unused + */ +//MT: int frame_skip_cmp; + + /** + * Border processing masking, raises the quantizer for mbs on the borders + * of the picture. + * - encoding: Set by user. + * - decoding: unused + */ +//MT: float border_masking; + + /** + * minimum MB lagrange multipler + * - encoding: Set by user. + * - decoding: unused + */ +//MT: int mb_lmin; + + /** + * maximum MB lagrange multipler + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int mb_lmax; + + /** + * + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int me_penalty_compensation; + + /** + * + * - encoding: unused + * - decoding: Set by user. + */ + //MT: enum AVDiscard skip_loop_filter; + + /** + * + * - encoding: unused + * - decoding: Set by user. + */ + //MT: enum AVDiscard skip_idct; + + /** + * + * - encoding: unused + * - decoding: Set by user. + */ + //MT: enum AVDiscard skip_frame; + + /** + * + * - encoding: Set by user. + * - decoding: unused + */ +//MT: int bidir_refine; + + /** + * + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int brd_scale; + + /** + * constant rate factor - quality-based VBR - values ~correspond to qps + * - encoding: Set by user. + * - decoding: unused + */ + //MT: float crf; + + /** + * constant quantization parameter rate control method + * - encoding: Set by user. + * - decoding: unused + */ +//MT: int cqp; + + /** + * minimum GOP size + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int keyint_min; + + /** + * number of reference frames + * - encoding: Set by user. + * - decoding: Set by lavc. + */ + //MT: int refs; + + /** + * chroma qp offset from luma + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int chromaoffset; + + /** + * Influences how often B-frames are used. + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int bframebias; + + /** + * trellis RD quantization + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int trellis; + + /** + * Reduce fluctuations in qp (before curve compression). + * - encoding: Set by user. + * - decoding: unused + */ +//MT: float complexityblur; + + /** + * in-loop deblocking filter alphac0 parameter + * alpha is in the range -6...6 + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int deblockalpha; + + /** + * in-loop deblocking filter beta parameter + * beta is in the range -6...6 + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int deblockbeta; + + /** + * macroblock subpartition sizes to consider - p8x8, p4x4, b8x8, i8x8, i4x4 + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int partitions; +#define X264_PART_I4X4 0x001 /* Analyze i4x4 */ +#define X264_PART_I8X8 0x002 /* Analyze i8x8 (requires 8x8 transform) */ +#define X264_PART_P8X8 0x010 /* Analyze p16x8, p8x16 and p8x8 */ +#define X264_PART_P4X4 0x020 /* Analyze p8x4, p4x8, p4x4 */ +#define X264_PART_B8X8 0x100 /* Analyze b16x8, b8x16 and b8x8 */ + + /** + * direct MV prediction mode - 0 (none), 1 (spatial), 2 (temporal), 3 (auto) + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int directpred; + + /** + * Audio cutoff bandwidth (0 means "automatic") + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int cutoff; + + /** + * Multiplied by qscale for each frame and added to scene_change_score. + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int scenechange_factor; + + /** + * + * Note: Value depends upon the compare function used for fullpel ME. + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int mv0_threshold; + + /** + * Adjusts sensitivity of b_frame_strategy 1. + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int b_sensitivity; + + /** + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int compression_level; +#define FF_COMPRESSION_DEFAULT -1 + + /** + * Sets whether to use LPC mode - used by FLAC encoder. + * - encoding: Set by user. + * - decoding: unused + */ +//MT: int use_lpc; + + /** + * LPC coefficient precision - used by FLAC encoder + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int lpc_coeff_precision; + + /** + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int min_prediction_order; + + /** + * - encoding: Set by user. + * - decoding: unused + */ +//MT: int max_prediction_order; + + /** + * search method for selecting prediction order + * - encoding: Set by user. + * - decoding: unused + */ +//MT: int prediction_order_method; + + /** + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int min_partition_order; + + /** + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int max_partition_order; + + /** + * GOP timecode frame start number, in non drop frame format + * - encoding: Set by user. + * - decoding: unused + */ + //MT: int64_t timecode_frame_start; + +#if LIBAVCODEC_VERSION_MAJOR < 53 + /** + * Decoder should decode to this many channels if it can (0 for default) + * - encoding: unused + * - decoding: Set by user. + * @deprecated Deprecated in favor of request_channel_layout. + */ + //MT: int request_channels; +#endif + + /** + * Percentage of dynamic range compression to be applied by the decoder. + * The default value is 1.0, corresponding to full compression. + * - encoding: unused + * - decoding: Set by user. + */ + //MT: float drc_scale; + + /** + * opaque 64bit number (generally a PTS) that will be reordered and + * output in AVFrame.reordered_opaque + * - encoding: unused + * - decoding: Set by user. + */ + //MT: int64_t reordered_opaque; + + /** + * Bits per sample/pixel of internal libavcodec pixel/sample format. + * This field is applicable only when sample_fmt is SAMPLE_FMT_S32. + * - encoding: set by user. + * - decoding: set by libavcodec. + */ + //MT: int bits_per_raw_sample; + + /** + * Audio channel layout. + * - encoding: set by user. + * - decoding: set by libavcodec. + */ + int64_t channel_layout; + + /** + * Request decoder to use this channel layout if it can (0 for default) + * - encoding: unused + * - decoding: Set by user. + */ +//MT: int64_t request_channel_layout; + + /** + * Ratecontrol attempt to use, at maximum, of what can be used without an underflow. + * - encoding: Set by user. + * - decoding: unused. + */ + //MT: float rc_max_available_vbv_use; + + /** + * Ratecontrol attempt to use, at least, times the amount needed to prevent a vbv overflow. + * - encoding: Set by user. + * - decoding: unused. + */ +//MT: float rc_min_vbv_overflow_use; + + /** + * Hardware accelerator in use + * - encoding: unused. + * - decoding: Set by libavcodec + */ +//MT: struct AVHWAccel *hwaccel; + + /** + * For some codecs, the time base is closer to the field rate than the frame rate. + * Most notably, H.264 and MPEG-2 specify time_base as half of frame duration + * if no telecine is used ... + * + * Set to time_base ticks per frame. Default 1, e.g., H.264/MPEG-2 set it to 2. + */ +//MT: int ticks_per_frame; + + /** + * Hardware accelerator context. + * For some hardware accelerators, a global context needs to be + * provided by the user. In that case, this holds display-dependent + * data FFmpeg cannot instantiate itself. Please refer to the + * FFmpeg HW accelerator documentation to know how to fill this + * is. e.g. for VA API, this is a struct vaapi_context. + * - encoding: unused + * - decoding: Set by user + */ + //MT: void *hwaccel_context; +} AVCodecContext; + +/** + * AVCodec. + */ +typedef struct AVCodec { + /** + * Name of the codec implementation. + * The name is globally unique among encoders and among decoders (but an + * encoder and a decoder can share the same name). + * This is the primary way to find a codec from the user perspective. + */ + const char *name; + enum CodecType type; + enum CodecID id; + int priv_data_size; + int (*init)(AVCodecContext *); + int (*encode)(AVCodecContext *, uint8_t *buf, int buf_size, void *data); + int (*close)(AVCodecContext *); + int (*decode)(AVCodecContext *, void *outdata, int *outdata_size, + const uint8_t *buf, int buf_size); + /** + * Codec capabilities. + * see CODEC_CAP_* + */ +//MT: int capabilities; +//MT: struct AVCodec *next; + /** + * Flush buffers. + * Will be called when seeking + */ +//MT: void (*flush)(AVCodecContext *); + //MT: const AVRational *supported_framerates; ///< array of supported framerates, or NULL if any, array is terminated by {0,0} + //MT: const enum PixelFormat *pix_fmts; ///< array of supported pixel formats, or NULL if unknown, array is terminated by -1 + /** + * Descriptive name for the codec, meant to be more human readable than \p name. + * You \e should use the NULL_IF_CONFIG_SMALL() macro to define it. + */ + const char *long_name; + const int *supported_samplerates; ///< array of supported audio samplerates, or NULL if unknown, array is terminated by 0 + const enum SampleFormat *sample_fmts; ///< array of supported sample formats, or NULL if unknown, array is terminated by -1 + const int64_t *channel_layouts; ///< array of support channel layouts, or NULL if unknown. array is terminated by 0 +} AVCodec; + +#if 0 /* MT : DELETE THIS LINE ONLY. */ +/** + * AVHWAccel. + */ +typedef struct AVHWAccel { + /** + * Name of the hardware accelerated codec. + * The name is globally unique among encoders and among decoders (but an + * encoder and a decoder can share the same name). + */ + const char *name; + + /** + * Type of codec implemented by the hardware accelerator. + * + * See CODEC_TYPE_xxx + */ + enum CodecType type; + + /** + * Codec implemented by the hardware accelerator. + * + * See CODEC_ID_xxx + */ + enum CodecID id; + + /** + * Supported pixel format. + * + * Only hardware accelerated formats are supported here. + */ + enum PixelFormat pix_fmt; + + /** + * Hardware accelerated codec capabilities. + * see FF_HWACCEL_CODEC_CAP_* + */ + int capabilities; + + struct AVHWAccel *next; + + /** + * Called at the beginning of each frame or field picture. + * + * Meaningful frame information (codec specific) is guaranteed to + * be parsed at this point. This function is mandatory. + * + * Note that \p buf can be NULL along with \p buf_size set to 0. + * Otherwise, this means the whole frame is available at this point. + * + * @param avctx the codec context + * @param buf the frame data buffer base + * @param buf_size the size of the frame in bytes + * @return zero if successful, a negative value otherwise + */ + int (*start_frame)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size); + + /** + * Callback for each slice. + * + * Meaningful slice information (codec specific) is guaranteed to + * be parsed at this point. This function is mandatory. + * + * @param avctx the codec context + * @param buf the slice data buffer base + * @param buf_size the size of the slice in bytes + * @return zero if successful, a negative value otherwise + */ + int (*decode_slice)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size); + + /** + * Called at the end of each frame or field picture. + * + * The whole picture is parsed at this point and can now be sent + * to the hardware accelerator. This function is mandatory. + * + * @param avctx the codec context + * @return zero if successful, a negative value otherwise + */ + int (*end_frame)(AVCodecContext *avctx); + + /** + * Size of HW accelerator private data. + * + * Private data is allocated with av_mallocz() before + * AVCodecContext.get_buffer() and deallocated after + * AVCodecContext.release_buffer(). + */ + int priv_data_size; +} AVHWAccel; + +/** + * four components are given, that's all. + * the last component is alpha + */ +typedef struct AVPicture { + uint8_t *data[4]; + int linesize[4]; ///< number of bytes per line +} AVPicture; + +/** + * AVPaletteControl + * This structure defines a method for communicating palette changes + * between and demuxer and a decoder. + * + * @deprecated Use AVPacket to send palette changes instead. + * This is totally broken. + */ +#define AVPALETTE_SIZE 1024 +#define AVPALETTE_COUNT 256 +typedef struct AVPaletteControl { + + /* Demuxer sets this to 1 to indicate the palette has changed; + * decoder resets to 0. */ + int palette_changed; + + /* 4-byte ARGB palette entries, stored in native byte order; note that + * the individual palette components should be on a 8-bit scale; if + * the palette data comes from an IBM VGA native format, the component + * data is probably 6 bits in size and needs to be scaled. */ + unsigned int palette[AVPALETTE_COUNT]; + +} AVPaletteControl attribute_deprecated; + +enum AVSubtitleType { + SUBTITLE_NONE, + + SUBTITLE_BITMAP, ///< A bitmap, pict will be set + + /** + * Plain text, the text field must be set by the decoder and is + * authoritative. ass and pict fields may contain approximations. + */ + SUBTITLE_TEXT, + + /** + * Formatted text, the ass field must be set by the decoder and is + * authoritative. pict and text fields may contain approximations. + */ + SUBTITLE_ASS, +}; + +typedef struct AVSubtitleRect { + int x; ///< top left corner of pict, undefined when pict is not set + int y; ///< top left corner of pict, undefined when pict is not set + int w; ///< width of pict, undefined when pict is not set + int h; ///< height of pict, undefined when pict is not set + int nb_colors; ///< number of colors in pict, undefined when pict is not set + + /** + * data+linesize for the bitmap of this subtitle. + * can be set for text/ass as well once they where rendered + */ + AVPicture pict; + enum AVSubtitleType type; + + char *text; ///< 0 terminated plain UTF-8 text + + /** + * 0 terminated ASS/SSA compatible event line. + * The pressentation of this is unaffected by the other values in this + * struct. + */ + char *ass; +} AVSubtitleRect; + +typedef struct AVSubtitle { + uint16_t format; /* 0 = graphics */ + uint32_t start_display_time; /* relative to packet pts, in ms */ + uint32_t end_display_time; /* relative to packet pts, in ms */ + unsigned num_rects; + AVSubtitleRect **rects; +} AVSubtitle; + + +/* resample.c */ + +struct ReSampleContext; +struct AVResampleContext; + +typedef struct ReSampleContext ReSampleContext; + +#if LIBAVCODEC_VERSION_MAJOR < 53 +/** + * @deprecated Use av_audio_resample_init() instead. + */ +attribute_deprecated ReSampleContext *audio_resample_init(int output_channels, int input_channels, + int output_rate, int input_rate); +#endif +/** + * Initializes audio resampling context + * + * @param output_channels number of output channels + * @param input_channels number of input channels + * @param output_rate output sample rate + * @param input_rate input sample rate + * @param sample_fmt_out requested output sample format + * @param sample_fmt_in input sample format + * @param filter_length length of each FIR filter in the filterbank relative to the cutoff freq + * @param log2_phase_count log2 of the number of entries in the polyphase filterbank + * @param linear If 1 then the used FIR filter will be linearly interpolated + between the 2 closest, if 0 the closest will be used + * @param cutoff cutoff frequency, 1.0 corresponds to half the output sampling rate + * @return allocated ReSampleContext, NULL if error occured + */ +ReSampleContext *av_audio_resample_init(int output_channels, int input_channels, + int output_rate, int input_rate, + enum SampleFormat sample_fmt_out, + enum SampleFormat sample_fmt_in, + int filter_length, int log2_phase_count, + int linear, double cutoff); + +int audio_resample(ReSampleContext *s, short *output, short *input, int nb_samples); +void audio_resample_close(ReSampleContext *s); + + +/** + * Initializes an audio resampler. + * Note, if either rate is not an integer then simply scale both rates up so they are. + * @param filter_length length of each FIR filter in the filterbank relative to the cutoff freq + * @param log2_phase_count log2 of the number of entries in the polyphase filterbank + * @param linear If 1 then the used FIR filter will be linearly interpolated + between the 2 closest, if 0 the closest will be used + * @param cutoff cutoff frequency, 1.0 corresponds to half the output sampling rate + */ +struct AVResampleContext *av_resample_init(int out_rate, int in_rate, int filter_length, int log2_phase_count, int linear, double cutoff); + +/** + * resamples. + * @param src an array of unconsumed samples + * @param consumed the number of samples of src which have been consumed are returned here + * @param src_size the number of unconsumed samples available + * @param dst_size the amount of space in samples available in dst + * @param update_ctx If this is 0 then the context will not be modified, that way several channels can be resampled with the same context. + * @return the number of samples written in dst or -1 if an error occurred + */ +int av_resample(struct AVResampleContext *c, short *dst, short *src, int *consumed, int src_size, int dst_size, int update_ctx); + + +/** + * Compensates samplerate/timestamp drift. The compensation is done by changing + * the resampler parameters, so no audible clicks or similar distortions occur + * @param compensation_distance distance in output samples over which the compensation should be performed + * @param sample_delta number of output samples which should be output less + * + * example: av_resample_compensate(c, 10, 500) + * here instead of 510 samples only 500 samples would be output + * + * note, due to rounding the actual compensation might be slightly different, + * especially if the compensation_distance is large and the in_rate used during init is small + */ +void av_resample_compensate(struct AVResampleContext *c, int sample_delta, int compensation_distance); +void av_resample_close(struct AVResampleContext *c); + +/** + * Allocate memory for a picture. Call avpicture_free to free it. + * + * @param picture the picture to be filled in + * @param pix_fmt the format of the picture + * @param width the width of the picture + * @param height the height of the picture + * @return zero if successful, a negative value if not + */ +int avpicture_alloc(AVPicture *picture, int pix_fmt, int width, int height); + +/** + * Free a picture previously allocated by avpicture_alloc(). + * + * @param picture the AVPicture to be freed + */ +void avpicture_free(AVPicture *picture); + +/** + * Fill in the AVPicture fields. + * The fields of the given AVPicture are filled in by using the 'ptr' address + * which points to the image data buffer. Depending on the specified picture + * format, one or multiple image data pointers and line sizes will be set. + * If a planar format is specified, several pointers will be set pointing to + * the different picture planes and the line sizes of the different planes + * will be stored in the lines_sizes array. + * + * @param picture AVPicture whose fields are to be filled in + * @param ptr Buffer which will contain or contains the actual image data + * @param pix_fmt The format in which the picture data is stored. + * @param width the width of the image in pixels + * @param height the height of the image in pixels + * @return size of the image data in bytes + */ +int avpicture_fill(AVPicture *picture, uint8_t *ptr, + int pix_fmt, int width, int height); +int avpicture_layout(const AVPicture* src, int pix_fmt, int width, int height, + unsigned char *dest, int dest_size); + +/** + * Calculate the size in bytes that a picture of the given width and height + * would occupy if stored in the given picture format. + * + * @param pix_fmt the given picture format + * @param width the width of the image + * @param height the height of the image + * @return Image data size in bytes + */ +int avpicture_get_size(int pix_fmt, int width, int height); +void avcodec_get_chroma_sub_sample(int pix_fmt, int *h_shift, int *v_shift); +const char *avcodec_get_pix_fmt_name(int pix_fmt); +void avcodec_set_dimensions(AVCodecContext *s, int width, int height); +enum PixelFormat avcodec_get_pix_fmt(const char* name); +unsigned int avcodec_pix_fmt_to_codec_tag(enum PixelFormat p); + +#define FF_LOSS_RESOLUTION 0x0001 /**< loss due to resolution change */ +#define FF_LOSS_DEPTH 0x0002 /**< loss due to color depth change */ +#define FF_LOSS_COLORSPACE 0x0004 /**< loss due to color space conversion */ +#define FF_LOSS_ALPHA 0x0008 /**< loss of alpha bits */ +#define FF_LOSS_COLORQUANT 0x0010 /**< loss due to color quantization */ +#define FF_LOSS_CHROMA 0x0020 /**< loss of chroma (e.g. RGB to gray conversion) */ + +/** + * Computes what kind of losses will occur when converting from one specific + * pixel format to another. + * When converting from one pixel format to another, information loss may occur. + * For example, when converting from RGB24 to GRAY, the color information will + * be lost. Similarly, other losses occur when converting from some formats to + * other formats. These losses can involve loss of chroma, but also loss of + * resolution, loss of color depth, loss due to the color space conversion, loss + * of the alpha bits or loss due to color quantization. + * avcodec_get_fix_fmt_loss() informs you about the various types of losses + * which will occur when converting from one pixel format to another. + * + * @param[in] dst_pix_fmt destination pixel format + * @param[in] src_pix_fmt source pixel format + * @param[in] has_alpha Whether the source pixel format alpha channel is used. + * @return Combination of flags informing you what kind of losses will occur. + */ +int avcodec_get_pix_fmt_loss(int dst_pix_fmt, int src_pix_fmt, + int has_alpha); + +/** + * Finds the best pixel format to convert to given a certain source pixel + * format. When converting from one pixel format to another, information loss + * may occur. For example, when converting from RGB24 to GRAY, the color + * information will be lost. Similarly, other losses occur when converting from + * some formats to other formats. avcodec_find_best_pix_fmt() searches which of + * the given pixel formats should be used to suffer the least amount of loss. + * The pixel formats from which it chooses one, are determined by the + * \p pix_fmt_mask parameter. + * + * @code + * src_pix_fmt = PIX_FMT_YUV420P; + * pix_fmt_mask = (1 << PIX_FMT_YUV422P) || (1 << PIX_FMT_RGB24); + * dst_pix_fmt = avcodec_find_best_pix_fmt(pix_fmt_mask, src_pix_fmt, alpha, &loss); + * @endcode + * + * @param[in] pix_fmt_mask bitmask determining which pixel format to choose from + * @param[in] src_pix_fmt source pixel format + * @param[in] has_alpha Whether the source pixel format alpha channel is used. + * @param[out] loss_ptr Combination of flags informing you what kind of losses will occur. + * @return The best pixel format to convert to or -1 if none was found. + */ +int avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, int src_pix_fmt, + int has_alpha, int *loss_ptr); + + +/** + * Print in buf the string corresponding to the pixel format with + * number pix_fmt, or an header if pix_fmt is negative. + * + * @param[in] buf the buffer where to write the string + * @param[in] buf_size the size of buf + * @param[in] pix_fmt the number of the pixel format to print the corresponding info string, or + * a negative value to print the corresponding header. + * Meaningful values for obtaining a pixel format info vary from 0 to PIX_FMT_NB -1. + */ +void avcodec_pix_fmt_string (char *buf, int buf_size, int pix_fmt); + +#define FF_ALPHA_TRANSP 0x0001 /* image has some totally transparent pixels */ +#define FF_ALPHA_SEMI_TRANSP 0x0002 /* image has some transparent pixels */ + +/** + * Tell if an image really has transparent alpha values. + * @return ored mask of FF_ALPHA_xxx constants + */ +int img_get_alpha_info(const AVPicture *src, + int pix_fmt, int width, int height); + +/* deinterlace a picture */ +/* deinterlace - if not supported return -1 */ +int avpicture_deinterlace(AVPicture *dst, const AVPicture *src, + int pix_fmt, int width, int height); + +/* external high level API */ + +/** + * If c is NULL, returns the first registered codec, + * if c is non-NULL, returns the next registered codec after c, + * or NULL if c is the last one. + */ +AVCodec *av_codec_next(AVCodec *c); + +/** + * Returns the LIBAVCODEC_VERSION_INT constant. + */ +unsigned avcodec_version(void); + +/** + * Initializes libavcodec. + * + * @warning This function \e must be called before any other libavcodec + * function. + */ +void avcodec_init(void); + +#if LIBAVCODEC_VERSION_MAJOR < 53 +/** + * @deprecated Deprecated in favor of avcodec_register(). + */ +attribute_deprecated void register_avcodec(AVCodec *codec); +#endif + +/** + * Register the codec \p codec and initialize libavcodec. + * + * @see avcodec_init() + */ +void avcodec_register(AVCodec *codec); + +/** + * Finds a registered encoder with a matching codec ID. + * + * @param id CodecID of the requested encoder + * @return An encoder if one was found, NULL otherwise. + */ +AVCodec *avcodec_find_encoder(enum CodecID id); + +/** + * Finds a registered encoder with the specified name. + * + * @param name name of the requested encoder + * @return An encoder if one was found, NULL otherwise. + */ +AVCodec *avcodec_find_encoder_by_name(const char *name); + +/** + * Finds a registered decoder with a matching codec ID. + * + * @param id CodecID of the requested decoder + * @return A decoder if one was found, NULL otherwise. + */ +AVCodec *avcodec_find_decoder(enum CodecID id); + +/** + * Finds a registered decoder with the specified name. + * + * @param name name of the requested decoder + * @return A decoder if one was found, NULL otherwise. + */ +AVCodec *avcodec_find_decoder_by_name(const char *name); +void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode); + +/** + * Sets the fields of the given AVCodecContext to default values. + * + * @param s The AVCodecContext of which the fields should be set to default values. + */ +void avcodec_get_context_defaults(AVCodecContext *s); + +/** THIS FUNCTION IS NOT YET PART OF THE PUBLIC API! + * we WILL change its arguments and name a few times! */ +void avcodec_get_context_defaults2(AVCodecContext *s, enum CodecType); + +/** + * Allocates an AVCodecContext and sets its fields to default values. The + * resulting struct can be deallocated by simply calling av_free(). + * + * @return An AVCodecContext filled with default values or NULL on failure. + * @see avcodec_get_context_defaults + */ +AVCodecContext *avcodec_alloc_context(void); + +/** THIS FUNCTION IS NOT YET PART OF THE PUBLIC API! + * we WILL change its arguments and name a few times! */ +AVCodecContext *avcodec_alloc_context2(enum CodecType); + +/** + * Sets the fields of the given AVFrame to default values. + * + * @param pic The AVFrame of which the fields should be set to default values. + */ +void avcodec_get_frame_defaults(AVFrame *pic); + +/** + * Allocates an AVFrame and sets its fields to default values. The resulting + * struct can be deallocated by simply calling av_free(). + * + * @return An AVFrame filled with default values or NULL on failure. + * @see avcodec_get_frame_defaults + */ +AVFrame *avcodec_alloc_frame(void); + +int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic); +void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic); +int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame *pic); +void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height); + +/** + * Checks if the given dimension of a picture is valid, meaning that all + * bytes of the picture can be addressed with a signed int. + * + * @param[in] w Width of the picture. + * @param[in] h Height of the picture. + * @return Zero if valid, a negative value if invalid. + */ +int avcodec_check_dimensions(void *av_log_ctx, unsigned int w, unsigned int h); +enum PixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum PixelFormat * fmt); + +int avcodec_thread_init(AVCodecContext *s, int thread_count); +void avcodec_thread_free(AVCodecContext *s); +int avcodec_thread_execute(AVCodecContext *s, int (*func)(AVCodecContext *c2, void *arg2),void *arg, int *ret, int count, int size); +int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2),void *arg, int *ret, int count, int size); +//FIXME func typedef + +/** + * Initializes the AVCodecContext to use the given AVCodec. Prior to using this + * function the context has to be allocated. + * + * The functions avcodec_find_decoder_by_name(), avcodec_find_encoder_by_name(), + * avcodec_find_decoder() and avcodec_find_encoder() provide an easy way for + * retrieving a codec. + * + * @warning This function is not thread safe! + * + * @code + * avcodec_register_all(); + * codec = avcodec_find_decoder(CODEC_ID_H264); + * if (!codec) + * exit(1); + * + * context = avcodec_alloc_context(); + * + * if (avcodec_open(context, codec) < 0) + * exit(1); + * @endcode + * + * @param avctx The context which will be set up to use the given codec. + * @param codec The codec to use within the context. + * @return zero on success, a negative value on error + * @see avcodec_alloc_context, avcodec_find_decoder, avcodec_find_encoder + */ +int avcodec_open(AVCodecContext *avctx, AVCodec *codec); + +/** + * Decodes an audio frame from \p buf into \p samples. + * The avcodec_decode_audio2() function decodes an audio frame from the input + * buffer \p buf of size \p buf_size. To decode it, it makes use of the + * audio codec which was coupled with \p avctx using avcodec_open(). The + * resulting decoded frame is stored in output buffer \p samples. If no frame + * could be decompressed, \p frame_size_ptr is zero. Otherwise, it is the + * decompressed frame size in \e bytes. + * + * @warning You \e must set \p frame_size_ptr to the allocated size of the + * output buffer before calling avcodec_decode_audio2(). + * + * @warning The input buffer must be \c FF_INPUT_BUFFER_PADDING_SIZE larger than + * the actual read bytes because some optimized bitstream readers read 32 or 64 + * bits at once and could read over the end. + * + * @warning The end of the input buffer \p buf should be set to 0 to ensure that + * no overreading happens for damaged MPEG streams. + * + * @note You might have to align the input buffer \p buf and output buffer \p + * samples. The alignment requirements depend on the CPU: On some CPUs it isn't + * necessary at all, on others it won't work at all if not aligned and on others + * it will work but it will have an impact on performance. In practice, the + * bitstream should have 4 byte alignment at minimum and all sample data should + * be 16 byte aligned unless the CPU doesn't need it (AltiVec and SSE do). If + * the linesize is not a multiple of 16 then there's no sense in aligning the + * start of the buffer to 16. + * + * @param avctx the codec context + * @param[out] samples the output buffer + * @param[in,out] frame_size_ptr the output buffer size in bytes + * @param[in] buf the input buffer + * @param[in] buf_size the input buffer size in bytes + * @return On error a negative value is returned, otherwise the number of bytes + * used or zero if no frame could be decompressed. + */ +int avcodec_decode_audio2(AVCodecContext *avctx, int16_t *samples, + int *frame_size_ptr, + const uint8_t *buf, int buf_size); + +/** + * Decodes a video frame from \p buf into \p picture. + * The avcodec_decode_video() function decodes a video frame from the input + * buffer \p buf of size \p buf_size. To decode it, it makes use of the + * video codec which was coupled with \p avctx using avcodec_open(). The + * resulting decoded frame is stored in \p picture. + * + * @warning The input buffer must be \c FF_INPUT_BUFFER_PADDING_SIZE larger than + * the actual read bytes because some optimized bitstream readers read 32 or 64 + * bits at once and could read over the end. + * + * @warning The end of the input buffer \p buf should be set to 0 to ensure that + * no overreading happens for damaged MPEG streams. + * + * @note You might have to align the input buffer \p buf and output buffer \p + * samples. The alignment requirements depend on the CPU: on some CPUs it isn't + * necessary at all, on others it won't work at all if not aligned and on others + * it will work but it will have an impact on performance. In practice, the + * bitstream should have 4 byte alignment at minimum and all sample data should + * be 16 byte aligned unless the CPU doesn't need it (AltiVec and SSE do). If + * the linesize is not a multiple of 16 then there's no sense in aligning the + * start of the buffer to 16. + * + * @note Some codecs have a delay between input and output, these need to be + * feeded with buf=NULL, buf_size=0 at the end to return the remaining frames. + * + * @param avctx the codec context + * @param[out] picture The AVFrame in which the decoded video frame will be stored. + * @param[in] buf the input buffer + * @param[in] buf_size the size of the input buffer in bytes + * @param[in,out] got_picture_ptr Zero if no frame could be decompressed, otherwise, it is nonzero. + * @return On error a negative value is returned, otherwise the number of bytes + * used or zero if no frame could be decompressed. + */ +int avcodec_decode_video(AVCodecContext *avctx, AVFrame *picture, + int *got_picture_ptr, + const uint8_t *buf, int buf_size); + +/* Decode a subtitle message. Return -1 if error, otherwise return the + * number of bytes used. If no subtitle could be decompressed, + * got_sub_ptr is zero. Otherwise, the subtitle is stored in *sub. */ +int avcodec_decode_subtitle(AVCodecContext *avctx, AVSubtitle *sub, + int *got_sub_ptr, + const uint8_t *buf, int buf_size); +int avcodec_parse_frame(AVCodecContext *avctx, uint8_t **pdata, + int *data_size_ptr, + uint8_t *buf, int buf_size); + +/** + * Encodes an audio frame from \p samples into \p buf. + * The avcodec_encode_audio() function encodes an audio frame from the input + * buffer \p samples. To encode it, it makes use of the audio codec which was + * coupled with \p avctx using avcodec_open(). The resulting encoded frame is + * stored in output buffer \p buf. + * + * @note The output buffer should be at least \c FF_MIN_BUFFER_SIZE bytes large. + * + * @param avctx the codec context + * @param[out] buf the output buffer + * @param[in] buf_size the output buffer size + * @param[in] samples the input buffer containing the samples + * The number of samples read from this buffer is frame_size*channels, + * both of which are defined in \p avctx. + * For PCM audio the number of samples read from \p samples is equal to + * \p buf_size * input_sample_size / output_sample_size. + * @return On error a negative value is returned, on success zero or the number + * of bytes used to encode the data read from the input buffer. + */ +int avcodec_encode_audio(AVCodecContext *avctx, uint8_t *buf, int buf_size, + const short *samples); + +/** + * Encodes a video frame from \p pict into \p buf. + * The avcodec_encode_video() function encodes a video frame from the input + * \p pict. To encode it, it makes use of the video codec which was coupled with + * \p avctx using avcodec_open(). The resulting encoded bytes representing the + * frame are stored in the output buffer \p buf. The input picture should be + * stored using a specific format, namely \c avctx.pix_fmt. + * + * @param avctx the codec context + * @param[out] buf the output buffer for the bitstream of encoded frame + * @param[in] buf_size the size of the output buffer in bytes + * @param[in] pict the input picture to encode + * @return On error a negative value is returned, on success zero or the number + * of bytes used from the output buffer. + */ +int avcodec_encode_video(AVCodecContext *avctx, uint8_t *buf, int buf_size, + const AVFrame *pict); +int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size, + const AVSubtitle *sub); + +int avcodec_close(AVCodecContext *avctx); + +/** + * Register all the codecs, parsers and bitstream filters which were enabled at + * configuration time. If you do not call this function you can select exactly + * which formats you want to support, by using the individual registration + * functions. + * + * @see avcodec_register + * @see av_register_codec_parser + * @see av_register_bitstream_filter + */ +void avcodec_register_all(void); + +/** + * Flush buffers, should be called when seeking or when switching to a different stream. + */ +void avcodec_flush_buffers(AVCodecContext *avctx); + +void avcodec_default_free_buffers(AVCodecContext *s); + +/* misc useful functions */ + +/** + * Returns a single letter to describe the given picture type \p pict_type. + * + * @param[in] pict_type the picture type + * @return A single character representing the picture type. + */ +char av_get_pict_type_char(int pict_type); + +/** + * Returns codec bits per sample. + * + * @param[in] codec_id the codec + * @return Number of bits per sample or zero if unknown for the given codec. + */ +int av_get_bits_per_sample(enum CodecID codec_id); + +/** + * Returns sample format bits per sample. + * + * @param[in] sample_fmt the sample format + * @return Number of bits per sample or zero if unknown for the given sample format. + */ +int av_get_bits_per_sample_format(enum SampleFormat sample_fmt); + +/* frame parsing */ +typedef struct AVCodecParserContext { + void *priv_data; + struct AVCodecParser *parser; + int64_t frame_offset; /* offset of the current frame */ + int64_t cur_offset; /* current offset + (incremented by each av_parser_parse()) */ + int64_t next_frame_offset; /* offset of the next frame */ + /* video info */ + int pict_type; /* XXX: Put it back in AVCodecContext. */ + /** + * This field is used for proper frame duration computation in lavf. + * It signals, how much longer the frame duration of the current frame + * is compared to normal frame duration. + * + * frame_duration = (1 + repeat_pict) * time_base + * + * It is used by codecs like H.264 to display telecined material. + */ + int repeat_pict; /* XXX: Put it back in AVCodecContext. */ + int64_t pts; /* pts of the current frame */ + int64_t dts; /* dts of the current frame */ + + /* private data */ + int64_t last_pts; + int64_t last_dts; + int fetch_timestamp; + +#define AV_PARSER_PTS_NB 4 + int cur_frame_start_index; + int64_t cur_frame_offset[AV_PARSER_PTS_NB]; + int64_t cur_frame_pts[AV_PARSER_PTS_NB]; + int64_t cur_frame_dts[AV_PARSER_PTS_NB]; + + int flags; +#define PARSER_FLAG_COMPLETE_FRAMES 0x0001 + + int64_t offset; ///< byte offset from starting packet start + int64_t cur_frame_end[AV_PARSER_PTS_NB]; + + /*! + * Set by parser to 1 for key frames and 0 for non-key frames. + * It is initialized to -1, so if the parser doesn't set this flag, + * old-style fallback using FF_I_TYPE picture type as key frames + * will be used. + */ + int key_frame; + + /** + * Time difference in stream time base units from the pts of this + * packet to the point at which the output from the decoder has converged + * independent from the availability of previous frames. That is, the + * frames are virtually identical no matter if decoding started from + * the very first frame or from this keyframe. + * Is AV_NOPTS_VALUE if unknown. + * This field is not the display duration of the current frame. + * + * The purpose of this field is to allow seeking in streams that have no + * keyframes in the conventional sense. It corresponds to the + * recovery point SEI in H.264 and match_time_delta in NUT. It is also + * essential for some types of subtitle streams to ensure that all + * subtitles are correctly displayed after seeking. + */ + int64_t convergence_duration; + + // Timestamp generation support: + /** + * Synchronization point for start of timestamp generation. + * + * Set to >0 for sync point, 0 for no sync point and <0 for undefined + * (default). + * + * For example, this corresponds to presence of H.264 buffering period + * SEI message. + */ + int dts_sync_point; + + /** + * Offset of the current timestamp against last timestamp sync point in + * units of AVCodecContext.time_base. + * + * Set to INT_MIN when dts_sync_point unused. Otherwise, it must + * contain a valid timestamp offset. + * + * Note that the timestamp of sync point has usually a nonzero + * dts_ref_dts_delta, which refers to the previous sync point. Offset of + * the next frame after timestamp sync point will be usually 1. + * + * For example, this corresponds to H.264 cpb_removal_delay. + */ + int dts_ref_dts_delta; + + /** + * Presentation delay of current frame in units of AVCodecContext.time_base. + * + * Set to INT_MIN when dts_sync_point unused. Otherwise, it must + * contain valid non-negative timestamp delta (presentation time of a frame + * must not lie in the past). + * + * This delay represents the difference between decoding and presentation + * time of the frame. + * + * For example, this corresponds to H.264 dpb_output_delay. + */ + int pts_dts_delta; + + /** + * Position of the packet in file. + * + * Analogous to cur_frame_pts/dts + */ + int64_t cur_frame_pos[AV_PARSER_PTS_NB]; + + /** + * Byte position of currently parsed frame in stream. + */ + int64_t pos; + + /** + * Previous frame byte position. + */ + int64_t last_pos; +} AVCodecParserContext; + +typedef struct AVCodecParser { + int codec_ids[5]; /* several codec IDs are permitted */ + int priv_data_size; + int (*parser_init)(AVCodecParserContext *s); + int (*parser_parse)(AVCodecParserContext *s, + AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size); + void (*parser_close)(AVCodecParserContext *s); + int (*split)(AVCodecContext *avctx, const uint8_t *buf, int buf_size); + struct AVCodecParser *next; +} AVCodecParser; + +AVCodecParser *av_parser_next(AVCodecParser *c); + +void av_register_codec_parser(AVCodecParser *parser); +AVCodecParserContext *av_parser_init(int codec_id); + +attribute_deprecated +int av_parser_parse(AVCodecParserContext *s, + AVCodecContext *avctx, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, + int64_t pts, int64_t dts); + +/** + * Parse a packet. + * + * @param s parser context. + * @param avctx codec context. + * @param poutbuf set to pointer to parsed buffer or NULL if not yet finished. + * @param poutbuf_size set to size of parsed buffer or zero if not yet finished. + * @param buf input buffer. + * @param buf_size input length, to signal EOF, this should be 0 (so that the last frame can be output). + * @param pts input presentation timestamp. + * @param dts input decoding timestamp. + * @param pos input byte position in stream. + * @return the number of bytes of the input bitstream used. + * + * Example: + * @code + * while(in_len){ + * len = av_parser_parse2(myparser, AVCodecContext, &data, &size, + * in_data, in_len, + * pts, dts, pos); + * in_data += len; + * in_len -= len; + * + * if(size) + * decode_frame(data, size); + * } + * @endcode + */ +int av_parser_parse2(AVCodecParserContext *s, + AVCodecContext *avctx, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, + int64_t pts, int64_t dts, + int64_t pos); + +int av_parser_change(AVCodecParserContext *s, + AVCodecContext *avctx, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, int keyframe); +void av_parser_close(AVCodecParserContext *s); + + +typedef struct AVBitStreamFilterContext { + void *priv_data; + struct AVBitStreamFilter *filter; + AVCodecParserContext *parser; + struct AVBitStreamFilterContext *next; +} AVBitStreamFilterContext; + + +typedef struct AVBitStreamFilter { + const char *name; + int priv_data_size; + int (*filter)(AVBitStreamFilterContext *bsfc, + AVCodecContext *avctx, const char *args, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, int keyframe); + void (*close)(AVBitStreamFilterContext *bsfc); + struct AVBitStreamFilter *next; +} AVBitStreamFilter; + +void av_register_bitstream_filter(AVBitStreamFilter *bsf); +AVBitStreamFilterContext *av_bitstream_filter_init(const char *name); +int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc, + AVCodecContext *avctx, const char *args, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, int keyframe); +void av_bitstream_filter_close(AVBitStreamFilterContext *bsf); + +AVBitStreamFilter *av_bitstream_filter_next(AVBitStreamFilter *f); + +/* memory */ + +/** + * Reallocates the given block if it is not large enough, otherwise it + * does nothing. + * + * @see av_realloc + */ +void *av_fast_realloc(void *ptr, unsigned int *size, unsigned int min_size); + +/** + * Copy image 'src' to 'dst'. + */ +void av_picture_copy(AVPicture *dst, const AVPicture *src, + int pix_fmt, int width, int height); + +/** + * Crop image top and left side. + */ +int av_picture_crop(AVPicture *dst, const AVPicture *src, + int pix_fmt, int top_band, int left_band); + +/** + * Pad image. + */ +int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width, int pix_fmt, + int padtop, int padbottom, int padleft, int padright, int *color); + +unsigned int av_xiphlacing(unsigned char *s, unsigned int v); + +/** + * Parses \p str and put in \p width_ptr and \p height_ptr the detected values. + * + * @return 0 in case of a successful parsing, a negative value otherwise + * @param[in] str the string to parse: it has to be a string in the format + * x or a valid video frame size abbreviation. + * @param[in,out] width_ptr pointer to the variable which will contain the detected + * frame width value + * @param[in,out] height_ptr pointer to the variable which will contain the detected + * frame height value + */ +int av_parse_video_frame_size(int *width_ptr, int *height_ptr, const char *str); + +/** + * Parses \p str and put in \p frame_rate the detected values. + * + * @return 0 in case of a successful parsing, a negative value otherwise + * @param[in] str the string to parse: it has to be a string in the format + * /, a float number or a valid video rate abbreviation + * @param[in,out] frame_rate pointer to the AVRational which will contain the detected + * frame rate + */ +int av_parse_video_frame_rate(AVRational *frame_rate, const char *str); + +/* error handling */ +#if EINVAL > 0 +#define AVERROR(e) (-(e)) /**< Returns a negative error code from a POSIX error code, to return from library functions. */ +#define AVUNERROR(e) (-(e)) /**< Returns a POSIX error code from a library function error return value. */ +#else +/* Some platforms have E* and errno already negated. */ +#define AVERROR(e) (e) +#define AVUNERROR(e) (e) +#endif +#define AVERROR_UNKNOWN AVERROR(EINVAL) /**< unknown error */ +#define AVERROR_IO AVERROR(EIO) /**< I/O error */ +#define AVERROR_NUMEXPECTED AVERROR(EDOM) /**< Number syntax expected in filename. */ +#define AVERROR_INVALIDDATA AVERROR(EINVAL) /**< invalid data found */ +#define AVERROR_NOMEM AVERROR(ENOMEM) /**< not enough memory */ +#define AVERROR_NOFMT AVERROR(EILSEQ) /**< unknown format */ +#define AVERROR_NOTSUPP AVERROR(ENOSYS) /**< Operation not supported. */ +#define AVERROR_NOENT AVERROR(ENOENT) /**< No such file or directory. */ +#define AVERROR_EOF AVERROR(EPIPE) /**< End of file. */ +#define AVERROR_PATCHWELCOME -MKTAG('P','A','W','E') /**< Not yet implemented in FFmpeg. Patches welcome. */ + +/** + * Registers the hardware accelerator \p hwaccel. + */ +void av_register_hwaccel(AVHWAccel *hwaccel); + +/** + * If hwaccel is NULL, returns the first registered hardware accelerator, + * if hwaccel is non-NULL, returns the next registered hardware accelerator + * after hwaccel, or NULL if hwaccel is the last one. + */ +AVHWAccel *av_hwaccel_next(AVHWAccel *hwaccel); +#endif /* MT : DELETE THIS LINE ONLY. */ +#endif /* AVCODEC_AVCODEC_H */ Index: apps/codecs/libcook/libavutil/mem.c =================================================================== --- apps/codecs/libcook/libavutil/mem.c (revision 0) +++ apps/codecs/libcook/libavutil/mem.c (revision 0) @@ -0,0 +1,159 @@ +/* + * default memory allocator for libavutil + * Copyright (c) 2002 Fabrice Bellard + * + * 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 libavutil/mem.c + * default memory allocator for libavutil + */ + +//#include "ffmpeg_config.h" + +#include +#include +#include +#if HAVE_MALLOC_H +#include +#endif + +#include "mem.h" + +/* here we can use OS-dependent allocation functions */ +#undef free +#undef malloc +#undef realloc + +/* You can redefine av_malloc and av_free in your project to use your + memory allocator. You do not need to suppress this file because the + linker will do it automatically. */ + +void *av_malloc(unsigned int size) +{ + void *ptr = NULL; +#if CONFIG_MEMALIGN_HACK + long diff; +#endif + + /* let's disallow possible ambiguous cases */ + if(size > (INT_MAX-16) ) + return NULL; + +#if CONFIG_MEMALIGN_HACK + ptr = malloc(size+16); + if(!ptr) + return ptr; + diff= ((-(long)ptr - 1)&15) + 1; + ptr = (char*)ptr + diff; + ((char*)ptr)[-1]= diff; +#elif HAVE_POSIX_MEMALIGN + if (posix_memalign(&ptr,16,size)) + ptr = NULL; +#elif HAVE_MEMALIGN + ptr = memalign(16,size); + /* Why 64? + Indeed, we should align it: + on 4 for 386 + on 16 for 486 + on 32 for 586, PPro - K6-III + on 64 for K7 (maybe for P3 too). + Because L1 and L2 caches are aligned on those values. + But I don't want to code such logic here! + */ + /* Why 16? + Because some CPUs need alignment, for example SSE2 on P4, & most RISC CPUs + it will just trigger an exception and the unaligned load will be done in the + exception handler or it will just segfault (SSE2 on P4). + Why not larger? Because I did not see a difference in benchmarks ... + */ + /* benchmarks with P3 + memalign(64)+1 3071,3051,3032 + memalign(64)+2 3051,3032,3041 + memalign(64)+4 2911,2896,2915 + memalign(64)+8 2545,2554,2550 + memalign(64)+16 2543,2572,2563 + memalign(64)+32 2546,2545,2571 + memalign(64)+64 2570,2533,2558 + + BTW, malloc seems to do 8-byte alignment by default here. + */ +#else + ptr = malloc(size); +#endif + return ptr; +} + +void *av_realloc(void *ptr, unsigned int size) +{ +#if CONFIG_MEMALIGN_HACK + int diff; +#endif + + /* let's disallow possible ambiguous cases */ + if(size > (INT_MAX-16) ) + return NULL; + +#if CONFIG_MEMALIGN_HACK + //FIXME this isn't aligned correctly, though it probably isn't needed + if(!ptr) return av_malloc(size); + diff= ((char*)ptr)[-1]; + return (char*)realloc((char*)ptr - diff, size + diff) + diff; +#else + return realloc(ptr, size); +#endif +} + +void av_free(void *ptr) +{ + /* XXX: this test should not be needed on most libcs */ + if (ptr) +#if CONFIG_MEMALIGN_HACK + free((char*)ptr - ((char*)ptr)[-1]); +#else + free(ptr); +#endif +} + +void av_freep(void *arg) +{ + void **ptr= (void**)arg; + av_free(*ptr); + *ptr = NULL; +} + +void *av_mallocz(unsigned int size) +{ + void *ptr = av_malloc(size); + if (ptr) + memset(ptr, 0, size); + return ptr; +} + +char *av_strdup(const char *s) +{ + char *ptr= NULL; + if(s){ + int len = strlen(s) + 1; + ptr = av_malloc(len); + if (ptr) + memcpy(ptr, s, len); + } + return ptr; +} + Index: apps/codecs/libcook/libavutil/log.c =================================================================== --- apps/codecs/libcook/libavutil/log.c (revision 0) +++ apps/codecs/libcook/libavutil/log.c (revision 0) @@ -0,0 +1,89 @@ +/* + * log functions + * Copyright (c) 2003 Michel Bardiaux + * + * 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 libavutil/log.c + * logging functions + */ + +#include "avutil.h" +#include "log.h" + +int av_log_level = AV_LOG_INFO; + +void av_log_default_callback(void* ptr, int level, const char* fmt, va_list vl) +{ + static int print_prefix=1; + static int count; + static char line[1024], prev[1024]; + AVClass* avc= ptr ? *(AVClass**)ptr : NULL; + if(level>av_log_level) + return; +#undef fprintf + if(print_prefix && avc) { + snprintf(line, sizeof(line), "[%s @ %p]", avc->item_name(ptr), ptr); + }else + line[0]=0; + + vsnprintf(line + strlen(line), sizeof(line) - strlen(line), fmt, vl); + + print_prefix= line[strlen(line)-1] == '\n'; + if(print_prefix && !strcmp(line, prev)){ + count++; + return; + } + if(count>0){ + fprintf(stderr, " Last message repeated %d times\n", count); + count=0; + } + fputs(line, stderr); + strcpy(prev, line); +} + +static void (*av_log_callback)(void*, int, const char*, va_list) = av_log_default_callback; + +void av_log(void* avcl, int level, const char *fmt, ...) +{ + va_list vl; + va_start(vl, fmt); + av_vlog(avcl, level, fmt, vl); + va_end(vl); +} + +void av_vlog(void* avcl, int level, const char *fmt, va_list vl) +{ + av_log_callback(avcl, level, fmt, vl); +} + +int av_log_get_level(void) +{ + return av_log_level; +} + +void av_log_set_level(int level) +{ + av_log_level = level; +} + +void av_log_set_callback(void (*callback)(void*, int, const char*, va_list)) +{ + av_log_callback = callback; +} Index: apps/codecs/libcook/libavutil/internal.h =================================================================== --- apps/codecs/libcook/libavutil/internal.h (revision 0) +++ apps/codecs/libcook/libavutil/internal.h (revision 0) @@ -0,0 +1,328 @@ +/* + * copyright (c) 2006 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 libavutil/internal.h + * common internal API header + */ + +#ifndef AVUTIL_INTERNAL_H +#define AVUTIL_INTERNAL_H + +#if !defined(DEBUG) && !defined(NDEBUG) +# define NDEBUG +#endif + +#include +#include +#include +#include +//#include "ffmpeg_config.h" +#include "common.h" +#include "mem.h" +//#include "timer.h" + +#ifndef attribute_align_arg +#if (!defined(__ICC) || __ICC > 1100) && AV_GCC_VERSION_AT_LEAST(4,2) +# define attribute_align_arg __attribute__((force_align_arg_pointer)) +#else +# define attribute_align_arg +#endif +#endif + +#ifndef attribute_used +#if AV_GCC_VERSION_AT_LEAST(3,1) +# define attribute_used __attribute__((used)) +#else +# define attribute_used +#endif +#endif + +#ifndef INT16_MIN +#define INT16_MIN (-0x7fff-1) +#endif + +#ifndef INT16_MAX +#define INT16_MAX 0x7fff +#endif + +#ifndef INT32_MIN +#define INT32_MIN (-0x7fffffff-1) +#endif + +#ifndef INT32_MAX +#define INT32_MAX 0x7fffffff +#endif + +#ifndef UINT32_MAX +#define UINT32_MAX 0xffffffff +#endif + +#ifndef INT64_MIN +#define INT64_MIN (-0x7fffffffffffffffLL-1) +#endif + +#ifndef INT64_MAX +#define INT64_MAX INT64_C(9223372036854775807) +#endif + +#ifndef UINT64_MAX +#define UINT64_MAX UINT64_C(0xFFFFFFFFFFFFFFFF) +#endif + +#ifndef INT_BIT +# define INT_BIT (CHAR_BIT * sizeof(int)) +#endif + +#if ( defined(__PIC__) || defined(__pic__) ) && ! defined(PIC) +# define PIC +#endif + +#ifndef offsetof +# define offsetof(T,F) ((unsigned int)((char *)&((T *)0)->F)) +#endif + +// Use rip-relative addressing if compiling PIC code on x86-64. +#if ARCH_X86_64 && defined(PIC) +# define LOCAL_MANGLE(a) #a "(%%rip)" +#else +# define LOCAL_MANGLE(a) #a +#endif + +#define MANGLE(a) EXTERN_PREFIX LOCAL_MANGLE(a) + +/* debug stuff */ + +/* dprintf macros */ +#ifdef DEBUG +# define dprintf(pctx, ...) av_log(pctx, AV_LOG_DEBUG, __VA_ARGS__) +#else +# define dprintf(pctx, ...) +#endif + +#define av_abort() do { av_log(NULL, AV_LOG_ERROR, "Abort at %s:%d\n", __FILE__, __LINE__); abort(); } while (0) + +/* math */ + +extern const uint32_t ff_inverse[256]; + +#if ARCH_X86 +# define FASTDIV(a,b) \ + ({\ + int ret,dmy;\ + __asm__ volatile(\ + "mull %3"\ + :"=d"(ret),"=a"(dmy)\ + :"1"(a),"g"(ff_inverse[b])\ + );\ + ret;\ + }) +#elif HAVE_ARMV6 && HAVE_INLINE_ASM +static inline av_const int FASTDIV(int a, int b) +{ + int r, t; + __asm__ volatile("cmp %3, #2 \n\t" + "ldr %1, [%4, %3, lsl #2] \n\t" + "lsrle %0, %2, #1 \n\t" + "smmulgt %0, %1, %2 \n\t" + : "=&r"(r), "=&r"(t) : "r"(a), "r"(b), "r"(ff_inverse)); + return r; +} +#elif ARCH_ARM && HAVE_INLINE_ASM +static inline av_const int FASTDIV(int a, int b) +{ + int r, t; + __asm__ volatile ("umull %1, %0, %2, %3" + : "=&r"(r), "=&r"(t) : "r"(a), "r"(ff_inverse[b])); + return r; +} +#elif CONFIG_FASTDIV +# define FASTDIV(a,b) ((uint32_t)((((uint64_t)a)*ff_inverse[b])>>32)) +#else +# define FASTDIV(a,b) ((a)/(b)) +#endif + +extern const uint8_t ff_sqrt_tab[256]; + +static inline av_const unsigned int ff_sqrt(unsigned int a) +{ + unsigned int b; + + if(a<255) return (ff_sqrt_tab[a+1]-1)>>4; + else if(a<(1<<12)) b= ff_sqrt_tab[a>>4 ]>>2; +#if !CONFIG_SMALL + else if(a<(1<<14)) b= ff_sqrt_tab[a>>6 ]>>1; + else if(a<(1<<16)) b= ff_sqrt_tab[a>>8 ] ; +#endif + else{ + int s= av_log2_16bit(a>>16)>>1; + unsigned int c= a>>(s+2); + b= ff_sqrt_tab[c>>(s+8)]; + b= FASTDIV(c,b) + (b<>31;\ + level= (level^mask)-mask; +#endif + +#if HAVE_CMOV +#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 + +/* avoid usage of dangerous/inappropriate system functions */ +#undef malloc +#define malloc please_use_av_malloc +#undef free +#define free please_use_av_free +#undef realloc +#define realloc please_use_av_realloc +#undef time +#define time time_is_forbidden_due_to_security_issues +//#undef rand +//#define rand rand_is_forbidden_due_to_state_trashing_use_av_random +//#undef srand +//#define srand srand_is_forbidden_due_to_state_trashing_use_av_random_init +#undef random +#define random random_is_forbidden_due_to_state_trashing_use_av_random +#undef sprintf +#define sprintf sprintf_is_forbidden_due_to_security_issues_use_snprintf +#undef strcat +#define strcat strcat_is_forbidden_due_to_security_issues_use_av_strlcat +#undef exit +#define exit exit_is_forbidden +#ifndef LIBAVFORMAT_BUILD +#undef printf +#define printf please_use_av_log_instead_of_printf +#undef fprintf +#define fprintf please_use_av_log_instead_of_fprintf +#undef puts +#define puts please_use_av_log_instead_of_puts +#undef perror +#define perror please_use_av_log_instead_of_perror +#endif + +#define CHECKED_ALLOCZ(p, size)\ +{\ + p= av_mallocz(size);\ + if(p==NULL && (size)!=0){\ + av_log(NULL, AV_LOG_ERROR, "Cannot allocate memory.");\ + goto fail;\ + }\ +} + +#if defined(__ICC) || defined(__SUNPRO_C) + #define DECLARE_ALIGNED(n,t,v) t v __attribute__ ((aligned (n))) + #define DECLARE_ASM_CONST(n,t,v) const t __attribute__ ((aligned (n))) v +#elif defined(__GNUC__) + #define DECLARE_ALIGNED(n,t,v) t v __attribute__ ((aligned (n))) + #define DECLARE_ASM_CONST(n,t,v) static const t v attribute_used __attribute__ ((aligned (n))) +#elif defined(_MSC_VER) + #define DECLARE_ALIGNED(n,t,v) __declspec(align(n)) t v + #define DECLARE_ASM_CONST(n,t,v) __declspec(align(n)) static const t v +#elif HAVE_INLINE_ASM + #error The asm code needs alignment, but we do not know how to do it for this compiler. +#else + #define DECLARE_ALIGNED(n,t,v) t v + #define DECLARE_ASM_CONST(n,t,v) static const t v +#endif + + +#if !HAVE_LLRINT +static av_always_inline av_const long long llrint(double x) +{ + return rint(x); +} +#endif /* HAVE_LLRINT */ + +#if !HAVE_LRINT +static av_always_inline av_const long int lrint(double x) +{ + return rint(x); +} +#endif /* HAVE_LRINT */ + +#if !HAVE_LRINTF +static av_always_inline av_const long int lrintf(float x) +{ + return (int)(rint(x)); +} +#endif /* HAVE_LRINTF */ + +#if !HAVE_ROUND +static av_always_inline av_const double round(double x) +{ + return (x > 0) ? floor(x + 0.5) : ceil(x - 0.5); +} +#endif /* HAVE_ROUND */ + +#if !HAVE_ROUNDF +static av_always_inline av_const float roundf(float x) +{ + return (x > 0) ? floor(x + 0.5) : ceil(x - 0.5); +} +#endif /* HAVE_ROUNDF */ + +#if !HAVE_TRUNCF +static av_always_inline av_const float truncf(float x) +{ + return (x > 0) ? floor(x) : ceil(x); +} +#endif /* HAVE_TRUNCF */ + +/** + * Returns NULL if CONFIG_SMALL is true, otherwise the argument + * without modification. Used to disable the definition of strings + * (for example AVCodec long_names). + */ +#if CONFIG_SMALL +# define NULL_IF_CONFIG_SMALL(x) NULL +#else +# define NULL_IF_CONFIG_SMALL(x) x +#endif + +#endif /* AVUTIL_INTERNAL_H */ Index: apps/codecs/libcook/libavutil/bswap.h =================================================================== --- apps/codecs/libcook/libavutil/bswap.h (revision 0) +++ apps/codecs/libcook/libavutil/bswap.h (revision 0) @@ -0,0 +1,99 @@ +/* + * copyright (c) 2006 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 libavutil/bswap.h + * byte swapping routines + */ + +#ifndef AVUTIL_BSWAP_H +#define AVUTIL_BSWAP_H + +#include +//#include "ffmpeg_config.h" +#include "common.h" + +#if ARCH_ARM +# include "arm/bswap.h" +#elif ARCH_BFIN +# include "bfin/bswap.h" +#elif ARCH_SH4 +# include "sh4/bswap.h" +#elif ARCH_X86 +# include "x86/bswap.h" +#endif + +#ifndef bswap_16 +static av_always_inline av_const uint16_t bswap_16(uint16_t x) +{ + x= (x>>8) | (x<<8); + return x; +} +#endif + +#ifndef bswap_32 +static av_always_inline av_const uint32_t bswap_32(uint32_t x) +{ + x= ((x<<8)&0xFF00FF00) | ((x>>8)&0x00FF00FF); + x= (x>>16) | (x<<16); + return x; +} +#endif + +#ifndef bswap_64 +static inline uint64_t av_const 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 + +// be2me ... big-endian to machine-endian +// le2me ... little-endian to machine-endian + +#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 /* AVUTIL_BSWAP_H */ Index: apps/codecs/libcook/libavutil/mem.h =================================================================== --- apps/codecs/libcook/libavutil/mem.h (revision 0) +++ apps/codecs/libcook/libavutil/mem.h (revision 0) @@ -0,0 +1,104 @@ +/* + * copyright (c) 2006 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 libavutil/mem.h + * memory handling functions + */ + +#ifndef AVUTIL_MEM_H +#define AVUTIL_MEM_H + +#include "common.h" + +#if AV_GCC_VERSION_AT_LEAST(3,1) + #define av_malloc_attrib __attribute__((__malloc__)) +#else + #define av_malloc_attrib +#endif + +#if (!defined(__ICC) || __ICC > 1100) && AV_GCC_VERSION_AT_LEAST(4,3) + #define av_alloc_size(n) __attribute__((alloc_size(n))) +#else + #define av_alloc_size(n) +#endif + +/** + * Allocates a block of \p size bytes with alignment suitable for all + * memory accesses (including vectors if available on the CPU). + * @param size Size in bytes for the memory block to be allocated. + * @return Pointer to the allocated block, NULL if the block cannot + * be allocated. + * @see av_mallocz() + */ +void *av_malloc(unsigned int size) av_malloc_attrib av_alloc_size(1); + +/** + * Allocates or reallocates a block of memory. + * If \p ptr is NULL and \p size > 0, allocates a new block. If \p + * size is zero, frees the memory block pointed to by \p ptr. + * @param size Size in bytes for the memory block to be allocated or + * reallocated. + * @param ptr Pointer to a memory block already allocated with + * av_malloc(z)() or av_realloc() or NULL. + * @return Pointer to a newly reallocated block or NULL if the block + * cannot be reallocated or the function is used to free the memory block. + * @see av_fast_realloc() + */ +void *av_realloc(void *ptr, unsigned int size) av_alloc_size(2); + +/** + * Frees a memory block which has been allocated with av_malloc(z)() or + * av_realloc(). + * @param ptr Pointer to the memory block which should be freed. + * @note ptr = NULL is explicitly allowed. + * @note It is recommended that you use av_freep() instead. + * @see av_freep() + */ +void av_free(void *ptr); + +/** + * Allocates a block of \p size bytes with alignment suitable for all + * memory accesses (including vectors if available on the CPU) and + * zeroes all the bytes of the block. + * @param size Size in bytes for the memory block to be allocated. + * @return Pointer to the allocated block, NULL if it cannot be allocated. + * @see av_malloc() + */ +void *av_mallocz(unsigned int size) av_malloc_attrib av_alloc_size(1); + +/** + * Duplicates the string \p s. + * @param s string to be duplicated + * @return Pointer to a newly allocated string containing a + * copy of \p s or NULL if the string cannot be allocated. + */ +char *av_strdup(const char *s) av_malloc_attrib; + +/** + * Frees a memory block which has been allocated with av_malloc(z)() or + * av_realloc() and set the pointer pointing to it to NULL. + * @param ptr Pointer to the pointer to the memory block which should + * be freed. + * @see av_free() + */ +void av_freep(void *ptr); + +#endif /* AVUTIL_MEM_H */ Index: apps/codecs/libcook/libavutil/md5.c =================================================================== --- apps/codecs/libcook/libavutil/md5.c (revision 0) +++ apps/codecs/libcook/libavutil/md5.c (revision 0) @@ -0,0 +1,182 @@ +/* + * Copyright (C) 2006 Michael Niedermayer (michaelni@gmx.at) + * Copyright (C) 2003-2005 by Christopher R. Hertel (crh@ubiqx.mn.org) + * + * References: + * IETF RFC 1321: The MD5 Message-Digest Algorithm + * Ron Rivest. IETF, April, 1992 + * + * based on http://ubiqx.org/libcifs/source/Auth/MD5.c + * from Christopher R. Hertel (crh@ubiqx.mn.org) + * Simplified, cleaned and IMO redundant comments removed by michael. + * + * If you use gcc, then version 4.1 or later and -fomit-frame-pointer is + * strongly recommended. + * + * 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 + */ + +#include +#include "bswap.h" +#include "md5.h" + +typedef struct AVMD5{ + uint64_t len; + uint8_t block[64]; + uint32_t ABCD[4]; +} AVMD5; + +const int av_md5_size= sizeof(AVMD5); + +static const uint8_t S[4][4] = { + { 7, 12, 17, 22 }, /* round 1 */ + { 5, 9, 14, 20 }, /* round 2 */ + { 4, 11, 16, 23 }, /* round 3 */ + { 6, 10, 15, 21 } /* round 4 */ +}; + +static const uint32_t T[64] = { // T[i]= fabs(sin(i+1)<<32) + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, /* round 1 */ + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, /* round 2 */ + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, /* round 3 */ + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, /* round 4 */ + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391, +}; + +#define CORE(i, a, b, c, d) \ + t = S[i>>4][i&3];\ + a += T[i];\ +\ + if(i<32){\ + if(i<16) a += (d ^ (b&(c^d))) + X[ i &15 ];\ + else a += (c ^ (d&(c^b))) + X[ (1+5*i)&15 ];\ + }else{\ + if(i<48) a += (b^c^d) + X[ (5+3*i)&15 ];\ + else a += (c^(b|~d)) + X[ ( 7*i)&15 ];\ + }\ + a = b + (( a << t ) | ( a >> (32 - t) )); + +static void body(uint32_t ABCD[4], uint32_t X[16]){ + + int t; + int i av_unused; + unsigned int a= ABCD[3]; + unsigned int b= ABCD[2]; + unsigned int c= ABCD[1]; + unsigned int d= ABCD[0]; + +#ifdef WORDS_BIGENDIAN + for(i=0; i<16; i++) + X[i]= bswap_32(X[i]); +#endif + +#if CONFIG_SMALL + for( i = 0; i < 64; i++ ){ + CORE(i,a,b,c,d) + t=d; d=c; c=b; b=a; a=t; + } +#else +#define CORE2(i) CORE(i,a,b,c,d) CORE((i+1),d,a,b,c) CORE((i+2),c,d,a,b) CORE((i+3),b,c,d,a) +#define CORE4(i) CORE2(i) CORE2((i+4)) CORE2((i+8)) CORE2((i+12)) +CORE4(0) CORE4(16) CORE4(32) CORE4(48) +#endif + + ABCD[0] += d; + ABCD[1] += c; + ABCD[2] += b; + ABCD[3] += a; +} + +void av_md5_init(AVMD5 *ctx){ + ctx->len = 0; + + ctx->ABCD[0] = 0x10325476; + ctx->ABCD[1] = 0x98badcfe; + ctx->ABCD[2] = 0xefcdab89; + ctx->ABCD[3] = 0x67452301; +} + +void av_md5_update(AVMD5 *ctx, const uint8_t *src, const int len){ + int i, j; + + j= ctx->len & 63; + ctx->len += len; + + for( i = 0; i < len; i++ ){ + ctx->block[j++] = src[i]; + if( 64 == j ){ + body(ctx->ABCD, (uint32_t*) ctx->block); + j = 0; + } + } +} + +void av_md5_final(AVMD5 *ctx, uint8_t *dst){ + int i; + uint64_t finalcount= le2me_64(ctx->len<<3); + + av_md5_update(ctx, "\200", 1); + while((ctx->len & 63)!=56) + av_md5_update(ctx, "", 1); + + av_md5_update(ctx, (uint8_t*)&finalcount, 8); + + for(i=0; i<4; i++) + ((uint32_t*)dst)[i]= le2me_32(ctx->ABCD[3-i]); +} + +void av_md5_sum(uint8_t *dst, const uint8_t *src, const int len){ + AVMD5 ctx[1]; + + av_md5_init(ctx); + av_md5_update(ctx, src, len); + av_md5_final(ctx, dst); +} + +#ifdef TEST +#include +#undef printf +int main(void){ + uint64_t md5val; + int i; + uint8_t in[1000]; + + for(i=0; i<1000; i++) in[i]= i*i; + av_md5_sum( (uint8_t*)&md5val, in, 1000); printf("%"PRId64"\n", md5val); + av_md5_sum( (uint8_t*)&md5val, in, 63); printf("%"PRId64"\n", md5val); + av_md5_sum( (uint8_t*)&md5val, in, 64); printf("%"PRId64"\n", md5val); + av_md5_sum( (uint8_t*)&md5val, in, 65); printf("%"PRId64"\n", md5val); + for(i=0; i<1000; i++) in[i]= i % 127; + av_md5_sum( (uint8_t*)&md5val, in, 999); printf("%"PRId64"\n", md5val); + + return 0; +} +#endif Index: apps/codecs/libcook/libavutil/intreadwrite.h =================================================================== --- apps/codecs/libcook/libavutil/intreadwrite.h (revision 0) +++ apps/codecs/libcook/libavutil/intreadwrite.h (revision 0) @@ -0,0 +1,192 @@ +/* + * 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 + */ + +#ifndef AVUTIL_INTREADWRITE_H +#define AVUTIL_INTREADWRITE_H + +#include +//#include "ffmpeg_config.h" +#include "bswap.h" + +#ifdef __GNUC__ + +struct unaligned_64 { uint64_t l; } __attribute__((packed)); +struct unaligned_32 { uint32_t l; } __attribute__((packed)); +struct unaligned_16 { uint16_t l; } __attribute__((packed)); + +#define AV_RN16(a) (((const struct unaligned_16 *) (a))->l) +#define AV_RN32(a) (((const struct unaligned_32 *) (a))->l) +#define AV_RN64(a) (((const struct unaligned_64 *) (a))->l) + +#define AV_WN16(a, b) (((struct unaligned_16 *) (a))->l) = (b) +#define AV_WN32(a, b) (((struct unaligned_32 *) (a))->l) = (b) +#define AV_WN64(a, b) (((struct unaligned_64 *) (a))->l) = (b) + +#elif defined(__DECC) + +#define AV_RN16(a) (*((const __unaligned uint16_t*)(a))) +#define AV_RN32(a) (*((const __unaligned uint32_t*)(a))) +#define AV_RN64(a) (*((const __unaligned uint64_t*)(a))) + +#define AV_WN16(a, b) *((__unaligned uint16_t*)(a)) = (b) +#define AV_WN32(a, b) *((__unaligned uint32_t*)(a)) = (b) +#define AV_WN64(a, b) *((__unaligned uint64_t*)(a)) = (b) + +#else + +#define AV_RN16(a) (*((const uint16_t*)(a))) +#define AV_RN32(a) (*((const uint32_t*)(a))) +#define AV_RN64(a) (*((const uint64_t*)(a))) + +#define AV_WN16(a, b) *((uint16_t*)(a)) = (b) +#define AV_WN32(a, b) *((uint32_t*)(a)) = (b) +#define AV_WN64(a, b) *((uint64_t*)(a)) = (b) + +#endif /* !__GNUC__ */ + +/* endian macros */ +#define AV_RB8(x) (((const uint8_t*)(x))[0]) +#define AV_WB8(p, d) do { ((uint8_t*)(p))[0] = (d); } while(0) + +#define AV_RL8(x) AV_RB8(x) +#define AV_WL8(p, d) AV_WB8(p, d) + +#if HAVE_FAST_UNALIGNED +# ifdef WORDS_BIGENDIAN +# define AV_RB16(x) AV_RN16(x) +# define AV_WB16(p, d) AV_WN16(p, d) + +# define AV_RL16(x) bswap_16(AV_RN16(x)) +# define AV_WL16(p, d) AV_WN16(p, bswap_16(d)) + +# define AV_RB32(x) AV_RN32(x) +# define AV_WB32(p, d) AV_WN32(p, d) + +# define AV_RL32(x) bswap_32(AV_RN32(x)) +# define AV_WL32(p, d) AV_WN32(p, bswap_32(d)) + +# define AV_RB64(x) AV_RN64(x) +# define AV_WB64(p, d) AV_WN64(p, d) + +# define AV_RL64(x) bswap_64(AV_RN64(x)) +# define AV_WL64(p, d) AV_WN64(p, bswap_64(d)) +# else /* WORDS_BIGENDIAN */ +# define AV_RB16(x) bswap_16(AV_RN16(x)) +# define AV_WB16(p, d) AV_WN16(p, bswap_16(d)) + +# define AV_RL16(x) AV_RN16(x) +# define AV_WL16(p, d) AV_WN16(p, d) + +# define AV_RB32(x) bswap_32(AV_RN32(x)) +# define AV_WB32(p, d) AV_WN32(p, bswap_32(d)) + +# define AV_RL32(x) AV_RN32(x) +# define AV_WL32(p, d) AV_WN32(p, d) + +# define AV_RB64(x) bswap_64(AV_RN64(x)) +# define AV_WB64(p, d) AV_WN64(p, bswap_64(d)) + +# define AV_RL64(x) AV_RN64(x) +# define AV_WL64(p, d) AV_WN64(p, d) +# endif +#else /* HAVE_FAST_UNALIGNED */ +#define AV_RB16(x) ((((const uint8_t*)(x))[0] << 8) | ((const uint8_t*)(x))[1]) +#define AV_WB16(p, d) do { \ + ((uint8_t*)(p))[1] = (d); \ + ((uint8_t*)(p))[0] = (d)>>8; } while(0) + +#define AV_RL16(x) ((((const uint8_t*)(x))[1] << 8) | \ + ((const uint8_t*)(x))[0]) +#define AV_WL16(p, d) do { \ + ((uint8_t*)(p))[0] = (d); \ + ((uint8_t*)(p))[1] = (d)>>8; } while(0) + +#define AV_RB32(x) ((((const uint8_t*)(x))[0] << 24) | \ + (((const uint8_t*)(x))[1] << 16) | \ + (((const uint8_t*)(x))[2] << 8) | \ + ((const uint8_t*)(x))[3]) +#define AV_WB32(p, d) do { \ + ((uint8_t*)(p))[3] = (d); \ + ((uint8_t*)(p))[2] = (d)>>8; \ + ((uint8_t*)(p))[1] = (d)>>16; \ + ((uint8_t*)(p))[0] = (d)>>24; } while(0) + +#define AV_RL32(x) ((((const uint8_t*)(x))[3] << 24) | \ + (((const uint8_t*)(x))[2] << 16) | \ + (((const uint8_t*)(x))[1] << 8) | \ + ((const uint8_t*)(x))[0]) +#define AV_WL32(p, d) do { \ + ((uint8_t*)(p))[0] = (d); \ + ((uint8_t*)(p))[1] = (d)>>8; \ + ((uint8_t*)(p))[2] = (d)>>16; \ + ((uint8_t*)(p))[3] = (d)>>24; } while(0) + +#define AV_RB64(x) (((uint64_t)((const uint8_t*)(x))[0] << 56) | \ + ((uint64_t)((const uint8_t*)(x))[1] << 48) | \ + ((uint64_t)((const uint8_t*)(x))[2] << 40) | \ + ((uint64_t)((const uint8_t*)(x))[3] << 32) | \ + ((uint64_t)((const uint8_t*)(x))[4] << 24) | \ + ((uint64_t)((const uint8_t*)(x))[5] << 16) | \ + ((uint64_t)((const uint8_t*)(x))[6] << 8) | \ + (uint64_t)((const uint8_t*)(x))[7]) +#define AV_WB64(p, d) do { \ + ((uint8_t*)(p))[7] = (d); \ + ((uint8_t*)(p))[6] = (d)>>8; \ + ((uint8_t*)(p))[5] = (d)>>16; \ + ((uint8_t*)(p))[4] = (d)>>24; \ + ((uint8_t*)(p))[3] = (d)>>32; \ + ((uint8_t*)(p))[2] = (d)>>40; \ + ((uint8_t*)(p))[1] = (d)>>48; \ + ((uint8_t*)(p))[0] = (d)>>56; } while(0) + +#define AV_RL64(x) (((uint64_t)((const uint8_t*)(x))[7] << 56) | \ + ((uint64_t)((const uint8_t*)(x))[6] << 48) | \ + ((uint64_t)((const uint8_t*)(x))[5] << 40) | \ + ((uint64_t)((const uint8_t*)(x))[4] << 32) | \ + ((uint64_t)((const uint8_t*)(x))[3] << 24) | \ + ((uint64_t)((const uint8_t*)(x))[2] << 16) | \ + ((uint64_t)((const uint8_t*)(x))[1] << 8) | \ + (uint64_t)((const uint8_t*)(x))[0]) +#define AV_WL64(p, d) do { \ + ((uint8_t*)(p))[0] = (d); \ + ((uint8_t*)(p))[1] = (d)>>8; \ + ((uint8_t*)(p))[2] = (d)>>16; \ + ((uint8_t*)(p))[3] = (d)>>24; \ + ((uint8_t*)(p))[4] = (d)>>32; \ + ((uint8_t*)(p))[5] = (d)>>40; \ + ((uint8_t*)(p))[6] = (d)>>48; \ + ((uint8_t*)(p))[7] = (d)>>56; } while(0) +#endif /* HAVE_FAST_UNALIGNED */ + +#define AV_RB24(x) ((((const uint8_t*)(x))[0] << 16) | \ + (((const uint8_t*)(x))[1] << 8) | \ + ((const uint8_t*)(x))[2]) +#define AV_WB24(p, d) do { \ + ((uint8_t*)(p))[2] = (d); \ + ((uint8_t*)(p))[1] = (d)>>8; \ + ((uint8_t*)(p))[0] = (d)>>16; } while(0) + +#define AV_RL24(x) ((((const uint8_t*)(x))[2] << 16) | \ + (((const uint8_t*)(x))[1] << 8) | \ + ((const uint8_t*)(x))[0]) +#define AV_WL24(p, d) do { \ + ((uint8_t*)(p))[0] = (d); \ + ((uint8_t*)(p))[1] = (d)>>8; \ + ((uint8_t*)(p))[2] = (d)>>16; } while(0) + +#endif /* AVUTIL_INTREADWRITE_H */ Index: apps/codecs/libcook/libavutil/log.h =================================================================== --- apps/codecs/libcook/libavutil/log.h (revision 0) +++ apps/codecs/libcook/libavutil/log.h (revision 0) @@ -0,0 +1,116 @@ +/* + * copyright (c) 2006 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 + */ + +#ifndef AVUTIL_LOG_H +#define AVUTIL_LOG_H + +#include +#include "avutil.h" + +/** + * Describes the class of an AVClass context structure. That is an + * arbitrary struct of which the first field is a pointer to an + * AVClass struct (e.g. AVCodecContext, AVFormatContext etc.). + */ +typedef struct AVCLASS AVClass; +struct AVCLASS { + /** + * The name of the class; usually it is the same name as the + * context structure type to which the AVClass is associated. + */ + const char* class_name; + + /** + * A pointer to a function which returns the name of a context + * instance \p ctx associated with the class. + */ + const char* (*item_name)(void* ctx); + + /** + * a pointer to the first option specified in the class if any or NULL + * + * @see av_set_default_options() + */ + const struct AVOption *option; +}; + +/* av_log API */ + +#define AV_LOG_QUIET -8 + +/** + * Something went really wrong and we will crash now. + */ +#define AV_LOG_PANIC 0 + +/** + * Something went wrong and recovery is not possible. + * For example, no header was found for a format which depends + * on headers or an illegal combination of parameters is used. + */ +#define AV_LOG_FATAL 8 + +/** + * Something went wrong and cannot losslessly be recovered. + * However, not all future data is affected. + */ +#define AV_LOG_ERROR 16 + +/** + * Something somehow does not look correct. This may or may not + * lead to problems. An example would be the use of '-vstrict -2'. + */ +#define AV_LOG_WARNING 24 + +#define AV_LOG_INFO 32 +#define AV_LOG_VERBOSE 40 + +/** + * Stuff which is only useful for libav* developers. + */ +#define AV_LOG_DEBUG 48 + +/** + * Sends the specified message to the log if the level is less than or equal + * to the current av_log_level. By default, all logging messages are sent to + * stderr. This behavior can be altered by setting a different av_vlog callback + * function. + * + * @param avcl A pointer to an arbitrary struct of which the first field is a + * pointer to an AVClass struct. + * @param level The importance level of the message, lower values signifying + * higher importance. + * @param fmt The format string (printf-compatible) that specifies how + * subsequent arguments are converted to output. + * @see av_vlog + */ +#ifdef __GNUC__ +void av_log(void*, int level, const char *fmt, ...) __attribute__ ((__format__ (__printf__, 3, 4))); +#else +void av_log(void*, int level, const char *fmt, ...); +#endif + +void av_vlog(void*, int level, const char *fmt, va_list); +int av_log_get_level(void); +void av_log_set_level(int); +void av_log_set_callback(void (*)(void*, int, const char*, va_list)); +void av_log_default_callback(void* ptr, int level, const char* fmt, va_list vl); + +#endif /* AVUTIL_LOG_H */ Index: apps/codecs/libcook/libavutil/lfg.c =================================================================== --- apps/codecs/libcook/libavutil/lfg.c (revision 0) +++ apps/codecs/libcook/libavutil/lfg.c (revision 0) @@ -0,0 +1,64 @@ +/* + * Lagged Fibonacci PRNG + * Copyright (c) 2008 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 + */ + +#include +#include "lfg.h" +#include "md5.h" +#include "intreadwrite.h" + +void av_lfg_init(AVLFG *c, unsigned int seed){ + uint8_t tmp[16]={0}; + int i; + + for(i=8; i<64; i+=4){ + AV_WL32(tmp, seed); tmp[4]=i; + av_md5_sum(tmp, tmp, 16); + c->state[i ]= AV_RL32(tmp); + c->state[i+1]= AV_RL32(tmp+4); + c->state[i+2]= AV_RL32(tmp+8); + c->state[i+3]= AV_RL32(tmp+12); + } + c->index=0; +} + +#ifdef TEST +#include "log.h" +#include "common.h" + +int main(void) +{ + int x=0; + int i, j; + AVLFG state; + + av_lfg_init(&state, 0xdeadbeef); + for (j = 0; j < 10000; j++) { + START_TIMER + for (i = 0; i < 624; i++) { +// av_log(NULL,AV_LOG_ERROR, "%X\n", av_lfg_get(&state)); + x+=av_lfg_get(&state); + } + STOP_TIMER("624 calls of av_random"); + } + av_log(NULL, AV_LOG_ERROR, "final value:%X\n", x); + return 0; +} +#endif Index: apps/codecs/libcook/libavutil/avutil.h =================================================================== --- apps/codecs/libcook/libavutil/avutil.h (revision 0) +++ apps/codecs/libcook/libavutil/avutil.h (revision 0) @@ -0,0 +1,63 @@ +/* + * copyright (c) 2006 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 + */ + +#ifndef AVUTIL_AVUTIL_H +#define AVUTIL_AVUTIL_H + +/** + * @file libavutil/avutil.h + * external API header + */ + + +#define AV_STRINGIFY(s) AV_TOSTRING(s) +#define AV_TOSTRING(s) #s + +#define AV_VERSION_INT(a, b, c) (a<<16 | b<<8 | c) +#define AV_VERSION_DOT(a, b, c) a ##.## b ##.## c +#define AV_VERSION(a, b, c) AV_VERSION_DOT(a, b, c) + +#define LIBAVUTIL_VERSION_MAJOR 50 +#define LIBAVUTIL_VERSION_MINOR 0 +#define LIBAVUTIL_VERSION_MICRO 0 + +#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ + LIBAVUTIL_VERSION_MINOR, \ + LIBAVUTIL_VERSION_MICRO) +#define LIBAVUTIL_VERSION AV_VERSION(LIBAVUTIL_VERSION_MAJOR, \ + LIBAVUTIL_VERSION_MINOR, \ + LIBAVUTIL_VERSION_MICRO) +#define LIBAVUTIL_BUILD LIBAVUTIL_VERSION_INT + +#define LIBAVUTIL_IDENT "Lavu" AV_STRINGIFY(LIBAVUTIL_VERSION) + +/** + * Returns the LIBAVUTIL_VERSION_INT constant. + */ +unsigned avutil_version(void); + +#include "common.h" +//#include "mathematics.h" +//#include "rational.h" +//#include "intfloat_readwrite.h" +#include "log.h" +//#include "pixfmt.h" + +#endif /* AVUTIL_AVUTIL_H */ Index: apps/codecs/libcook/libavutil/md5.h =================================================================== --- apps/codecs/libcook/libavutil/md5.h (revision 0) +++ apps/codecs/libcook/libavutil/md5.h (revision 0) @@ -0,0 +1,36 @@ +/* + * copyright (c) 2006 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 + */ + +#ifndef AVUTIL_MD5_H +#define AVUTIL_MD5_H + +#include + +extern const int av_md5_size; + +struct AVMD5; + +void av_md5_init(struct AVMD5 *ctx); +void av_md5_update(struct AVMD5 *ctx, const uint8_t *src, const int len); +void av_md5_final(struct AVMD5 *ctx, uint8_t *dst); +void av_md5_sum(uint8_t *dst, const uint8_t *src, const int len); + +#endif /* AVUTIL_MD5_H */ + Index: apps/codecs/libcook/libavutil/common.h =================================================================== --- apps/codecs/libcook/libavutil/common.h (revision 0) +++ apps/codecs/libcook/libavutil/common.h (revision 0) @@ -0,0 +1,286 @@ +/* + * copyright (c) 2006 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 libavutil/common.h + * common internal and external API header + */ + +#ifndef AVUTIL_COMMON_H +#define AVUTIL_COMMON_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __GNUC__ +# define AV_GCC_VERSION_AT_LEAST(x,y) (__GNUC__ > x || __GNUC__ == x && __GNUC_MINOR__ >= y) +#else +# define AV_GCC_VERSION_AT_LEAST(x,y) 0 +#endif + +#ifndef av_always_inline +#if AV_GCC_VERSION_AT_LEAST(3,1) +# define av_always_inline __attribute__((always_inline)) inline +#else +# define av_always_inline inline +#endif +#endif + +#ifndef av_noinline +#if AV_GCC_VERSION_AT_LEAST(3,1) +# define av_noinline __attribute__((noinline)) +#else +# define av_noinline +#endif +#endif + +#ifndef av_pure +#if AV_GCC_VERSION_AT_LEAST(3,1) +# define av_pure __attribute__((pure)) +#else +# define av_pure +#endif +#endif + +#ifndef av_const +#if AV_GCC_VERSION_AT_LEAST(2,6) +# define av_const __attribute__((const)) +#else +# define av_const +#endif +#endif + +#ifndef av_cold +#if (!defined(__ICC) || __ICC > 1100) && AV_GCC_VERSION_AT_LEAST(4,3) +# define av_cold __attribute__((cold)) +#else +# define av_cold +#endif +#endif + +#ifndef av_flatten +#if AV_GCC_VERSION_AT_LEAST(4,1) +# define av_flatten __attribute__((flatten)) +#else +# define av_flatten +#endif +#endif + +#ifndef attribute_deprecated +#if AV_GCC_VERSION_AT_LEAST(3,1) +# define attribute_deprecated __attribute__((deprecated)) +#else +# define attribute_deprecated +#endif +#endif + +#ifndef av_unused +#if defined(__GNUC__) +# define av_unused __attribute__((unused)) +#else +# define av_unused +#endif +#endif + +#ifndef av_uninit +#if defined(__GNUC__) && !defined(__ICC) +# define av_uninit(x) x=x +#else +# define av_uninit(x) x +#endif +#endif + +//rounded division & 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 FFABS(a) ((a) >= 0 ? (a) : (-(a))) +#define FFSIGN(a) ((a) > 0 ? 1 : -1) + +#define FFMAX(a,b) ((a) > (b) ? (a) : (b)) +#define FFMAX3(a,b,c) FFMAX(FFMAX(a,b),c) +#define FFMIN(a,b) ((a) > (b) ? (b) : (a)) +#define FFMIN3(a,b,c) FFMIN(FFMIN(a,b),c) + +#define FFSWAP(type,a,b) do{type SWAP_tmp= b; b= a; a= SWAP_tmp;}while(0) +#define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0])) + +/* misc math functions */ +extern const uint8_t ff_log2_tab[256]; + +static inline av_const int av_log2(unsigned int v) +{ + int 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 av_const int av_log2_16bit(unsigned int v) +{ + int n = 0; + if (v & 0xff00) { + v >>= 8; + n += 8; + } + n += ff_log2_tab[v]; + + return n; +} + +/** + * Clips a signed integer value into the amin-amax range. + * @param a value to clip + * @param amin minimum value of the clip range + * @param amax maximum value of the clip range + * @return clipped value + */ +static inline av_const int av_clip(int a, int amin, int amax) +{ + if (a < amin) return amin; + else if (a > amax) return amax; + else return a; +} + +/** + * Clips a signed integer value into the 0-255 range. + * @param a value to clip + * @return clipped value + */ +static inline av_const uint8_t av_clip_uint8(int a) +{ + if (a&(~255)) return (-a)>>31; + else return a; +} + +/** + * Clips a signed integer value into the -32768,32767 range. + * @param a value to clip + * @return clipped value + */ +static inline av_const int16_t av_clip_int16(int a) +{ + if ((a+32768) & ~65535) return (a>>31) ^ 32767; + else return a; +} + +/** + * Clips a float value into the amin-amax range. + * @param a value to clip + * @param amin minimum value of the clip range + * @param amax maximum value of the clip range + * @return clipped value + */ +static inline av_const float av_clipf(float a, float amin, float amax) +{ + if (a < amin) return amin; + else if (a > amax) return amax; + else return a; +} + +#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)) + +/*! + * \def GET_UTF8(val, GET_BYTE, ERROR) + * Converts a UTF-8 character (up to 4 bytes long) to its 32-bit UCS-4 encoded form + * \param val is the output and should be of type uint32_t. It holds the converted + * UCS-4 character and should be a left value. + * \param GET_BYTE gets UTF-8 encoded bytes from any proper source. It can be + * a function or a statement whose return value or evaluated value is of type + * uint8_t. It will be executed up to 4 times for values in the valid UTF-8 range, + * and up to 7 times in the general case. + * \param ERROR action that should be taken when an invalid UTF-8 byte is returned + * from GET_BYTE. It should be a statement that jumps out of the macro, + * like exit(), goto, return, break, or continue. + */ +#define GET_UTF8(val, GET_BYTE, ERROR)\ + val= GET_BYTE;\ + {\ + int ones= 7 - av_log2(val ^ 255);\ + if(ones==1)\ + ERROR\ + val&= 127>>ones;\ + while(--ones > 0){\ + int tmp= GET_BYTE - 128;\ + if(tmp>>6)\ + ERROR\ + val= (val<<6) + tmp;\ + }\ + } + +/*! + * \def PUT_UTF8(val, tmp, PUT_BYTE) + * Converts a 32-bit Unicode character to its UTF-8 encoded form (up to 4 bytes long). + * \param val is an input-only argument and should be of type uint32_t. It holds + * a UCS-4 encoded Unicode character that is to be converted to UTF-8. If + * val is given as a function it is executed only once. + * \param tmp is a temporary variable and should be of type uint8_t. It + * represents an intermediate value during conversion that is to be + * output by PUT_BYTE. + * \param PUT_BYTE writes the converted UTF-8 bytes to any proper destination. + * It could be a function or a statement, and uses tmp as the input byte. + * For example, PUT_BYTE could be "*output++ = tmp;" PUT_BYTE will be + * executed up to 4 times for values in the valid UTF-8 range and up to + * 7 times in the general case, depending on the length of the converted + * Unicode character. + */ +#define PUT_UTF8(val, tmp, PUT_BYTE)\ + {\ + int bytes, shift;\ + uint32_t in = val;\ + if (in < 0x80) {\ + tmp = in;\ + PUT_BYTE\ + } else {\ + bytes = (av_log2(in) + 4) / 5;\ + shift = (bytes - 1) * 6;\ + tmp = (256 - (256 >> bytes)) | (in >> shift);\ + PUT_BYTE\ + while (shift >= 6) {\ + shift -= 6;\ + tmp = 0x80 | ((in >> shift) & 0x3f);\ + PUT_BYTE\ + }\ + }\ + } + +#include "mem.h" + +//#ifdef HAVE_AV_CONFIG_H +//# include "ffmpeg_config.h" +# include "internal.h" +//#endif /* HAVE_AV_CONFIG_H */ + +#endif /* AVUTIL_COMMON_H */ Index: apps/codecs/libcook/libavutil/lfg.h =================================================================== --- apps/codecs/libcook/libavutil/lfg.h (revision 0) +++ apps/codecs/libcook/libavutil/lfg.h (revision 0) @@ -0,0 +1,54 @@ +/* + * Lagged Fibonacci PRNG + * Copyright (c) 2008 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 + */ + +#ifndef AVUTIL_LFG_H +#define AVUTIL_LFG_H + +typedef struct { + unsigned int state[64]; + int index; +} AVLFG; + +void av_lfg_init(AVLFG *c, unsigned int seed); + +/** + * Gets the next random unsigned 32-bit number using an ALFG. + * + * Please also consider a simple LCG like state= state*1664525+1013904223, + * it may be good enough and faster for your specific use case. + */ +static inline unsigned int av_lfg_get(AVLFG *c){ + c->state[c->index & 63] = c->state[(c->index-24) & 63] + c->state[(c->index-55) & 63]; + return c->state[c->index++ & 63]; +} + +/** + * Gets the next random unsigned 32-bit number using a MLFG. + * + * Please also consider av_lfg_get() above, it is faster. + */ +static inline unsigned int av_mlfg_get(AVLFG *c){ + unsigned int a= c->state[(c->index-55) & 63]; + unsigned int b= c->state[(c->index-24) & 63]; + return c->state[c->index++ & 63] = 2*a*b+a+b; +} + +#endif /* AVUTIL_LFG_H */ Index: apps/codecs/libcook/rm2wav.c =================================================================== --- apps/codecs/libcook/rm2wav.c (revision 0) +++ apps/codecs/libcook/rm2wav.c (revision 0) @@ -0,0 +1,567 @@ + +#include +#include +#include +#include +#include +#include +#include + +#include "id3.h" +#include "rm2wav.h" + +#define MAX_PATH 260 +#define PKT_HEADER_SIZE 12 +#define RAW_AUDIO_DATA packet_length-PKT_HEADER_SIZE + + +#if 0 +#define DEBUG +#define DEBUGF printf +#else +#define DEBUGF(...) +#endif + +/* ASF codec IDs */ +#define CODEC_ID_WMAV1 0x160 +#define CODEC_ID_WMAV2 0x161 + +struct waveformatex_t { + uint16_t codec_id; + uint16_t channels; + uint32_t rate; + uint32_t bitrate; + uint16_t blockalign; + uint16_t bitspersample; + uint16_t datalen; + uint8_t data[6]; +}; + +int open_wav(char* filename) { + int fd; + + fd=open(filename,O_CREAT|O_WRONLY|O_TRUNC,S_IRUSR|S_IWUSR); + if (fd >= 0) { + write(fd,wav_header,sizeof(wav_header)); + } + + return(fd); +} + +void close_wav(int fd, RMContext *rmctx) { + int x; + int filesize; + int bytes_per_sample = 2; + int samples_per_frame = rmctx->samples_pf_pc; + int nb_channels = rmctx->nb_channels; + int frame_size = rmctx->block_align; + int sample_rate = rmctx->sample_rate; + int nb_frames = rmctx->audio_framesize/rmctx->block_align * rmctx->nb_packets - 2; // first 2 frames have no valid audio; skipped in output + + filesize= samples_per_frame*bytes_per_sample*nb_frames +44; + printf("Filesize = %d\n",filesize); + + // ChunkSize + x=filesize-8; + wav_header[4]=(x&0xff); + wav_header[5]=(x&0xff00)>>8; + wav_header[6]=(x&0xff0000)>>16; + wav_header[7]=(x&0xff000000)>>24; + + // Number of channels + wav_header[22]=nb_channels; + + // Samplerate + wav_header[24]=sample_rate&0xff; + wav_header[25]=(sample_rate&0xff00)>>8; + wav_header[26]=(sample_rate&0xff0000)>>16; + wav_header[27]=(sample_rate&0xff000000)>>24; + + // ByteRate + x=sample_rate*bytes_per_sample*nb_channels; + wav_header[28]=(x&0xff); + wav_header[29]=(x&0xff00)>>8; + wav_header[30]=(x&0xff0000)>>16; + wav_header[31]=(x&0xff000000)>>24; + + // BlockAlign + wav_header[32]=rmctx->block_align;//2*rmctx->nb_channels; + + // Bits per sample + wav_header[34]=16; + + // Subchunk2Size + x=filesize-44; + wav_header[40]=(x&0xff); + wav_header[41]=(x&0xff00)>>8; + wav_header[42]=(x&0xff0000)>>16; + wav_header[43]=(x&0xff000000)>>24; + + lseek(fd,0,SEEK_SET); + write(fd,wav_header,sizeof(wav_header)); + close(fd); +} + +/* Some Rockbox-like functions (these should be implemented in metadata_common.[ch] */ +struct cook_extradata { + uint32_t cook_version; + uint16_t samples_pf_pc; /* samples per frame per channel */ + uint16_t nb_subbands; /* number of subbands in the frequency domain */ + + /* extra 8 bytes for stereo data */ + uint32_t unused; + uint16_t js_subband_start; /* joint stereo subband start */ + uint16_t js_vlc_bits; +}; + +static int read_uint8(int fd, uint8_t* buf) +{ + unsigned char tmp[1]; + int res; + + res=read(fd, tmp, 1); + *buf = tmp[0]; + return res; +} + +static int read_uint16be(int fd, uint16_t* buf) +{ + unsigned char tmp[2]; + int res; + + res=read(fd, tmp, 2); + *buf = (tmp[0] << 8) | tmp[1]; + return res; +} + +static int read_uint32be(int fd, uint32_t* buf) +{ + unsigned char tmp[4]; + int res; + + res=read(fd, tmp, 4); + *buf = (tmp[0] << 24) | (tmp[1] << 16) | (tmp[2] << 8) | tmp[3]; + return res; +} + +off_t filesize(int fd) +{ + struct stat buf; + + if (fstat(fd,&buf) == -1) { + return -1; + } else { + return buf.st_size; + } +} + +int read_cook_extradata(int fd, RMContext *rmctx) { + read_uint32be(fd, &rmctx->cook_version); + read_uint16be(fd, &rmctx->samples_pf_pc); + read_uint16be(fd, &rmctx->nb_subbands); + if(rmctx->extradata_size == 16) { + read_uint32be(fd, &rmctx->unused); + read_uint16be(fd, &rmctx->js_subband_start); + read_uint16be(fd, &rmctx->js_vlc_bits); + } + return rmctx->extradata_size; /* for 'skipped' */ +} + +void print_cook_extradata(RMContext *rmctx) { + + printf(" cook_version = 0x%08x\n", rmctx->cook_version); + printf(" samples_per_frame_per_channel = %d\n", rmctx->samples_pf_pc); + printf(" number_of_subbands_in_freq_domain = %d\n", rmctx->nb_subbands); + if(rmctx->extradata_size == 16) { + printf(" joint_stereo_subband_start = %d\n",rmctx->js_subband_start); + printf(" joint_stereo_vlc_bits = %d\n", rmctx->js_vlc_bits); + } +} + + +struct real_object_t +{ + uint32_t fourcc; + uint32_t size; + uint16_t version; +}; + +#define FOURCC(a,b,c,d) (((a)<<24) | ((b) << 16) | ((c) << 8) | (d)) + +static int real_read_object_header(int fd, struct real_object_t* obj) +{ + int n; + + if ((n = read_uint32be(fd, &obj->fourcc)) <= 0) return n; + if ((n = read_uint32be(fd, &obj->size)) <= 0) return n; + if ((n = read_uint16be(fd, &obj->version)) <= 0) return n; + + return 1; +} + +static char* fourcc2str(uint32_t f) +{ + static char res[5]; + + res[0] = (f & 0xff000000) >> 24; + res[1] = (f & 0xff0000) >> 16; + res[2] = (f & 0xff00) >> 8; + res[3] = (f & 0xff); + res[4] = 0; + + return res; +} + +static int read_str(int fd, char* buf) +{ + uint8_t len; + + read(fd, &len, 1); + read(fd, buf, len); + buf[len]=0; + + return len+1; +} + +static int real_read_audio_stream_info(int fd, RMContext *rmctx) +{ + int skipped = 0; + uint32_t version; + struct real_object_t obj; + uint32_t header_size; + uint16_t flavor; + uint32_t coded_framesize; + uint32_t unknown1; + uint32_t unknown2; + uint32_t unknown3; + uint16_t sub_packet_h; + uint16_t frame_size; /* block_align in ffmpeg */ + uint16_t sub_packet_size; + uint16_t unknown4; + uint16_t unknown5; + uint16_t unknown6; + uint16_t unknown7; + uint16_t sample_rate; + uint32_t unknown8; + uint16_t channels; + uint8_t interleaver_id_length; + uint32_t interleaver_id; + uint8_t fourcc_length; + uint32_t fourcc; + uint8_t unknown9; + uint16_t unknown10; + uint8_t unknown11; + uint32_t codec_extradata_length; + struct cook_extradata *ced; + + read_uint32be(fd, &version); + skipped += 4; + + printf(" version=0x%04x\n",((version >> 16) & 0xff)); + if (((version >> 16) & 0xff) == 3) { + /* Very old version */ + } else { + real_read_object_header(fd, &obj); + skipped += 10; + read_uint32be(fd, &header_size); + skipped += 4; + /* obj.size will be filled with an unknown value, replaced with header_size */ + printf(" Object: %s, size: %d bytes, version: 0x%04x\n",fourcc2str(obj.fourcc),header_size,obj.version); + + read_uint16be(fd, &flavor); + read_uint32be(fd, &coded_framesize); + read_uint32be(fd, &unknown1); + read_uint32be(fd, &unknown2); + read_uint32be(fd, &unknown3); + read_uint16be(fd, &rmctx->sub_packet_h); + read_uint16be(fd, &rmctx->block_align); + read_uint16be(fd, &rmctx->sub_packet_size); + read_uint16be(fd, &unknown4); + skipped += 26; + if (((version >> 16) & 0xff) == 5) + { + read_uint16be(fd, &unknown5); + read_uint16be(fd, &unknown6); + read_uint16be(fd, &unknown7); + skipped += 6; + } + read_uint16be(fd, &rmctx->sample_rate); + read_uint32be(fd, &unknown8); + read_uint16be(fd, &rmctx->nb_channels); + skipped += 8; + if (((version >> 16) & 0xff) == 4) + { + read_uint8(fd, &interleaver_id_length); + read_uint32be(fd, &interleaver_id); + read_uint8(fd, &fourcc_length); + read_uint32be(fd, &fourcc); + skipped += 10; + } + if (((version >> 16) & 0xff) == 5) + { + read_uint32be(fd, &interleaver_id); + read_uint32be(fd, &fourcc); + skipped += 8; + } + read_uint8(fd,&unknown9); + read_uint16be(fd,&unknown10); + skipped += 3; + if (((version >> 16) & 0xff) == 5) + { + read_uint8(fd, &unknown11); + skipped += 1; + } + + read_uint32be(fd, &rmctx->extradata_size); + skipped += 4; + if(!strncmp(fourcc2str(fourcc),"cook",4)) + skipped += read_cook_extradata(fd, rmctx); + + + printf(" flavor = %d\n",flavor); + printf(" coded_frame_size = %d\n",coded_framesize); + printf(" sub_packet_h = %d\n",rmctx->sub_packet_h); + printf(" frame_size = %d\n",rmctx->block_align); + printf(" sub_packet_size = %d\n",rmctx->sub_packet_size); + printf(" sample_rate= %d\n",rmctx->sample_rate); + printf(" channels= %d\n",rmctx->nb_channels); + printf(" fourcc = %s\n",fourcc2str(fourcc)); + printf(" codec_extra_data_length = %d\n",rmctx->extradata_size); + printf(" codec_extradata :\n"); + print_cook_extradata(rmctx); + + } + + return skipped; +} + +int real_parse_header(int fd, RMContext *rmctx) +{ + struct real_object_t obj; + int res; + int skipped; + off_t curpos; + + uint32_t unknown1; + uint32_t unknown2; + + uint32_t max_bitrate; + uint32_t avg_bitrate; + uint32_t max_packet_size; + uint32_t avg_packet_size; + uint32_t packet_count; + uint32_t duration; + uint32_t preroll; + uint32_t index_offset; + uint32_t data_offset; + uint16_t num_streams; + uint16_t flags; + + uint16_t stream_id; + uint32_t start_time; + char desc[256]; + char mimetype[256]; + uint32_t codec_data_size; + uint32_t v; + + char title[256]; + char author[256]; + char copyright[256]; + char comment[256]; + + uint32_t data_nb_packets; + uint32_t next_data_off; + uint8_t header_end; + + curpos = lseek(fd, 0, SEEK_SET); + res = real_read_object_header(fd, &obj); + + if (obj.fourcc == FOURCC('.','r','a',0xfd)) + { + /* Very old .ra format - not yet supported */ + return -1; + } + else if (obj.fourcc != FOURCC('.','R','M','F')) + { + return -1; + } + + read_uint32be(fd, &unknown1); + read_uint32be(fd, &unknown2); + + printf("Object: %s, size: %d bytes, version: 0x%04x, pos: %d\n",fourcc2str(obj.fourcc),(int)obj.size,obj.version,(int)curpos); + printf(" unknown1=%d (0x%08x)\n",unknown1,unknown1); + printf(" unknown2=%d (0x%08x)\n",unknown2,unknown2); + + res = real_read_object_header(fd, &obj); + header_end = 0; + while(res) + { + printf("Object: %s, size: %d bytes, version: 0x%04x, pos: %d\n",fourcc2str(obj.fourcc),(int)obj.size,obj.version,(int)curpos); + skipped = 10; + if(obj.fourcc == FOURCC('I','N','D','X')) + break; + switch (obj.fourcc) + { + case FOURCC('P','R','O','P'): /* File properties */ + read_uint32be(fd, &max_bitrate); + read_uint32be(fd, &rmctx->bit_rate); /*avg bitrate*/ + read_uint32be(fd, &max_packet_size); + read_uint32be(fd, &avg_packet_size); + read_uint32be(fd, &packet_count); + read_uint32be(fd, &duration); + read_uint32be(fd, &preroll); + read_uint32be(fd, &index_offset); + read_uint32be(fd, &data_offset); + read_uint16be(fd, &num_streams); + read_uint16be(fd, &rmctx->flags); + skipped += 40; + + printf(" max_bitrate = %d\n",max_bitrate); + printf(" avg_bitrate = %d\n",avg_bitrate); + printf(" max_packet_size = %d\n",max_packet_size); + printf(" avg_packet_size = %d\n",avg_packet_size); + printf(" packet_count = %d\n",packet_count); + printf(" duration = %d\n",duration); + printf(" preroll = %d\n",preroll); + printf(" index_offset = %d\n",index_offset); + printf(" data_offset = %d\n",data_offset); + printf(" num_streams = %d\n",num_streams); + printf(" flags=0x%04x\n",flags); + break; + + case FOURCC('C','O','N','T'): + /* Four strings - Title, Author, Copyright, Comment */ + skipped += read_str(fd,title); + skipped += read_str(fd,author); + skipped += read_str(fd,copyright); + skipped += read_str(fd,comment); + + printf(" title=\"%s\"\n",title); + printf(" author=\"%s\"\n",author); + printf(" copyright=\"%s\"\n",copyright); + printf(" comment=\"%s\"\n",comment); + break; + + case FOURCC('M','D','P','R'): /* Media properties */ + read_uint16be(fd,&stream_id); + skipped += 2; + read_uint32be(fd,&max_bitrate); + skipped += 4; + read_uint32be(fd,&avg_bitrate); + skipped += 4; + read_uint32be(fd,&max_packet_size); + skipped += 4; + read_uint32be(fd,&avg_packet_size); + skipped += 4; + read_uint32be(fd,&start_time); + skipped += 4; + read_uint32be(fd,&preroll); + skipped += 4; + read_uint32be(fd,&duration); + skipped += 4; + skipped += read_str(fd,desc); + skipped += read_str(fd,mimetype); + read_uint32be(fd,&codec_data_size); + skipped += 4; + //From ffmpeg: codec_pos = url_ftell(pb); + read_uint32be(fd,&v); + skipped += 4; + + printf(" stream_id = 0x%04x\n",stream_id); + printf(" max_bitrate = %d\n",max_bitrate); + printf(" avg_bitrate = %d\n",avg_bitrate); + printf(" max_packet_size = %d\n",max_packet_size); + printf(" avg_packet_size = %d\n",avg_packet_size); + printf(" start_time = %d\n",start_time); + printf(" preroll = %d\n",preroll); + printf(" duration = %d\n",duration); + printf(" desc=\"%s\"\n",desc); + printf(" mimetype=\"%s\"\n",mimetype); + printf(" codec_data_size = %d\n",codec_data_size); + printf(" v=\"%s\"\n", fourcc2str(v)); + + if (v == FOURCC('.','r','a',0xfd)) + { + skipped += real_read_audio_stream_info(fd, rmctx); + } + + break; + + case FOURCC('D','A','T','A'): + + read_uint32be(fd,&rmctx->nb_packets); + skipped += 4; + read_uint32be(fd,&next_data_off); + skipped += 4; + if (!rmctx->nb_packets && (rmctx->flags & 4)) + rmctx->nb_packets = 3600 * 25; + printf(" data_nb_packets = %d\n",rmctx->nb_packets); + printf(" next DATA offset = %d\n",next_data_off); + header_end = 1; + break; + } + if(header_end) break; + curpos = lseek(fd, obj.size - skipped, SEEK_CUR); + res = real_read_object_header(fd, &obj); + } + + + return 0; +} + +void rm_get_packet(int fd,RMContext *rmctx, RMPacket *pkt) +{ + uint8_t unknown,packet_group; + uint16_t x, place; + uint16_t sps = rmctx->sub_packet_size; + uint16_t cfs = rmctx->coded_framesize; + uint16_t h = rmctx->sub_packet_h; + uint16_t y = rmctx->sub_packet_cnt; + uint16_t w = rmctx->audio_framesize; + do + { + y = rmctx->sub_packet_cnt; + read_uint16be(fd,&pkt->version); + read_uint16be(fd,&pkt->length); + read_uint16be(fd,&pkt->stream_number); + read_uint32be(fd,&pkt->timestamp); + DEBUGF(" version = %d\n" + " length = %d\n" + " stream = %d\n" + " timestmp= %d\n",pkt->version,pkt->length,pkt->stream_number,pkt->timestamp); + + //getchar(); + if(pkt->version == 0) + { + read_uint8(fd,&packet_group); + read_uint8(fd,&pkt->flags); + } + if(pkt->version == 1) + read_uint8(fd,&unknown); + + if (pkt->flags & 2) /* keyframe */ + y = rmctx->sub_packet_cnt = 0; + if (!y) /* if keyframe update playback elapsed time */ + rmctx->audiotimestamp = pkt->timestamp; + + for(x = 0 ; x < w/sps; x++) + { + place = sps*(h*x+((h+1)/2)*(y&1)+(y>>1)); + read(fd,pkt->data+place, sps); + //DEBUGF("place = %d data[place] = %d\n",place,pkt->data[place]); + } + rmctx->audio_pkt_cnt++; + }while(++(rmctx->sub_packet_cnt) < h); + + //return pkt->data; +} +#ifdef DEBUG +void dump_rm_context(RMContext *rmctx) +{ + DEBUGF("block_align = %d\n", rmctx->block_align); + DEBUGF("nb_channels = %d\n", rmctx->nb_channels); + DEBUGF("sample_rate = %d\n", rmctx->sample_rate); + DEBUGF("bit_rate = %d\n", rmctx->bit_rate ); +} +#endif Index: apps/codecs/libcook/fft.c =================================================================== --- apps/codecs/libcook/fft.c (revision 0) +++ apps/codecs/libcook/fft.c (revision 0) @@ -0,0 +1,374 @@ +/* + * FFT/IFFT transforms + * Copyright (c) 2008 Loren Merritt + * Copyright (c) 2002 Fabrice Bellard + * Partly based on libdjbfft by D. J. Bernstein + * + * 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 libavcodec/fft.c + * FFT/IFFT transforms. + */ + +#include "dsputil.h" + +/* cos(2*pi*x/n) for 0<=x<=n/4, followed by its reverse */ +DECLARE_ALIGNED_16(FFTSample, ff_cos_16[8]); +DECLARE_ALIGNED_16(FFTSample, ff_cos_32[16]); +DECLARE_ALIGNED_16(FFTSample, ff_cos_64[32]); +DECLARE_ALIGNED_16(FFTSample, ff_cos_128[64]); +DECLARE_ALIGNED_16(FFTSample, ff_cos_256[128]); +DECLARE_ALIGNED_16(FFTSample, ff_cos_512[256]); +DECLARE_ALIGNED_16(FFTSample, ff_cos_1024[512]); +DECLARE_ALIGNED_16(FFTSample, ff_cos_2048[1024]); +DECLARE_ALIGNED_16(FFTSample, ff_cos_4096[2048]); +DECLARE_ALIGNED_16(FFTSample, ff_cos_8192[4096]); +DECLARE_ALIGNED_16(FFTSample, ff_cos_16384[8192]); +DECLARE_ALIGNED_16(FFTSample, ff_cos_32768[16384]); +DECLARE_ALIGNED_16(FFTSample, ff_cos_65536[32768]); +FFTSample *ff_cos_tabs[] = { + ff_cos_16, ff_cos_32, ff_cos_64, ff_cos_128, ff_cos_256, ff_cos_512, ff_cos_1024, + ff_cos_2048, ff_cos_4096, ff_cos_8192, ff_cos_16384, ff_cos_32768, ff_cos_65536, +}; + +static int split_radix_permutation(int i, int n, int inverse) +{ + int m; + if(n <= 2) return i&1; + m = n >> 1; + if(!(i&m)) return split_radix_permutation(i, m, inverse)*2; + m >>= 1; + if(inverse == !(i&m)) return split_radix_permutation(i, m, inverse)*4 + 1; + else return split_radix_permutation(i, m, inverse)*4 - 1; +} + +av_cold int ff_fft_init(FFTContext *s, int nbits, int inverse) +{ + int i, j, m, n; + float alpha, c1, s1, s2; + int split_radix = 1; + int av_unused has_vectors; + + if (nbits < 2 || nbits > 16) + goto fail; + s->nbits = nbits; + n = 1 << nbits; + + s->tmp_buf = NULL; + s->exptab = av_malloc((n / 2) * sizeof(FFTComplex)); + if (!s->exptab) + goto fail; + s->revtab = av_malloc(n * sizeof(uint16_t)); + if (!s->revtab) + goto fail; + s->inverse = inverse; + + s2 = inverse ? 1.0 : -1.0; + + s->fft_permute = ff_fft_permute_c; + s->fft_calc = ff_fft_calc_c; + s->imdct_calc = ff_imdct_calc_c; + s->imdct_half = ff_imdct_half_c; + s->exptab1 = NULL; + +#if HAVE_MMX && HAVE_YASM + has_vectors = mm_support(); + if (has_vectors & FF_MM_SSE && HAVE_SSE) { + /* SSE for P3/P4/K8 */ + s->imdct_calc = ff_imdct_calc_sse; + s->imdct_half = ff_imdct_half_sse; + s->fft_permute = ff_fft_permute_sse; + s->fft_calc = ff_fft_calc_sse; + } else if (has_vectors & FF_MM_3DNOWEXT && HAVE_AMD3DNOWEXT) { + /* 3DNowEx for K7 */ + s->imdct_calc = ff_imdct_calc_3dn2; + s->imdct_half = ff_imdct_half_3dn2; + s->fft_calc = ff_fft_calc_3dn2; + } else if (has_vectors & FF_MM_3DNOW && HAVE_AMD3DNOW) { + /* 3DNow! for K6-2/3 */ + s->imdct_calc = ff_imdct_calc_3dn; + s->imdct_half = ff_imdct_half_3dn; + s->fft_calc = ff_fft_calc_3dn; + } +#elif HAVE_ALTIVEC + has_vectors = mm_support(); + if (has_vectors & FF_MM_ALTIVEC) { + s->fft_calc = ff_fft_calc_altivec; + split_radix = 0; + } +#endif + + if (split_radix) { + for(j=4; j<=nbits; j++) { + int m = 1<revtab[-split_radix_permutation(i, n, s->inverse) & (n-1)] = i; + s->tmp_buf = av_malloc(n * sizeof(FFTComplex)); + } else { + int np, nblocks, np2, l; + FFTComplex *q; + + for(i=0; i<(n/2); i++) { + alpha = 2 * M_PI * (float)i / (float)n; + c1 = cos(alpha); + s1 = sin(alpha) * s2; + s->exptab[i].re = c1; + s->exptab[i].im = s1; + } + + np = 1 << nbits; + nblocks = np >> 3; + np2 = np >> 1; + s->exptab1 = av_malloc(np * 2 * sizeof(FFTComplex)); + if (!s->exptab1) + goto fail; + q = s->exptab1; + do { + for(l = 0; l < np2; l += 2 * nblocks) { + *q++ = s->exptab[l]; + *q++ = s->exptab[l + nblocks]; + + q->re = -s->exptab[l].im; + q->im = s->exptab[l].re; + q++; + q->re = -s->exptab[l + nblocks].im; + q->im = s->exptab[l + nblocks].re; + q++; + } + nblocks = nblocks >> 1; + } while (nblocks != 0); + av_freep(&s->exptab); + + /* compute bit reverse table */ + for(i=0;i> j) & 1) << (nbits-j-1); + } + s->revtab[i]=m; + } + } + + return 0; + fail: + av_freep(&s->revtab); + av_freep(&s->exptab); + av_freep(&s->exptab1); + av_freep(&s->tmp_buf); + return -1; +} + +void ff_fft_permute_c(FFTContext *s, FFTComplex *z) +{ + int j, k, np; + FFTComplex tmp; + const uint16_t *revtab = s->revtab; + np = 1 << s->nbits; + + if (s->tmp_buf) { + /* TODO: handle split-radix permute in a more optimal way, probably in-place */ + for(j=0;jtmp_buf[revtab[j]] = z[j]; + memcpy(z, s->tmp_buf, np * sizeof(FFTComplex)); + return; + } + + /* reverse */ + for(j=0;jrevtab); + av_freep(&s->exptab); + av_freep(&s->exptab1); + av_freep(&s->tmp_buf); +} + +#define sqrthalf (float)M_SQRT1_2 + +#define BF(x,y,a,b) {\ + x = a - b;\ + y = a + b;\ +} + +#define BUTTERFLIES(a0,a1,a2,a3) {\ + BF(t3, t5, t5, t1);\ + BF(a2.re, a0.re, a0.re, t5);\ + BF(a3.im, a1.im, a1.im, t3);\ + BF(t4, t6, t2, t6);\ + BF(a3.re, a1.re, a1.re, t4);\ + BF(a2.im, a0.im, a0.im, t6);\ +} + +// force loading all the inputs before storing any. +// this is slightly slower for small data, but avoids store->load aliasing +// for addresses separated by large powers of 2. +#define BUTTERFLIES_BIG(a0,a1,a2,a3) {\ + FFTSample r0=a0.re, i0=a0.im, r1=a1.re, i1=a1.im;\ + BF(t3, t5, t5, t1);\ + BF(a2.re, a0.re, r0, t5);\ + BF(a3.im, a1.im, i1, t3);\ + BF(t4, t6, t2, t6);\ + BF(a3.re, a1.re, r1, t4);\ + BF(a2.im, a0.im, i0, t6);\ +} + +#define TRANSFORM(a0,a1,a2,a3,wre,wim) {\ + t1 = a2.re * wre + a2.im * wim;\ + t2 = a2.im * wre - a2.re * wim;\ + t5 = a3.re * wre - a3.im * wim;\ + t6 = a3.im * wre + a3.re * wim;\ + BUTTERFLIES(a0,a1,a2,a3)\ +} + +#define TRANSFORM_ZERO(a0,a1,a2,a3) {\ + t1 = a2.re;\ + t2 = a2.im;\ + t5 = a3.re;\ + t6 = a3.im;\ + BUTTERFLIES(a0,a1,a2,a3)\ +} + +/* z[0...8n-1], w[1...2n-1] */ +#define PASS(name)\ +static void name(FFTComplex *z, const FFTSample *wre, unsigned int n)\ +{\ + FFTSample t1, t2, t3, t4, t5, t6;\ + int o1 = 2*n;\ + int o2 = 4*n;\ + int o3 = 6*n;\ + const FFTSample *wim = wre+o1;\ + n--;\ +\ + TRANSFORM_ZERO(z[0],z[o1],z[o2],z[o3]);\ + TRANSFORM(z[1],z[o1+1],z[o2+1],z[o3+1],wre[1],wim[-1]);\ + do {\ + z += 2;\ + wre += 2;\ + wim -= 2;\ + TRANSFORM(z[0],z[o1],z[o2],z[o3],wre[0],wim[0]);\ + TRANSFORM(z[1],z[o1+1],z[o2+1],z[o3+1],wre[1],wim[-1]);\ + } while(--n);\ +} + +PASS(pass) +#undef BUTTERFLIES +#define BUTTERFLIES BUTTERFLIES_BIG +PASS(pass_big) + +#define DECL_FFT(n,n2,n4)\ +static void fft##n(FFTComplex *z)\ +{\ + fft##n2(z);\ + fft##n4(z+n4*2);\ + fft##n4(z+n4*3);\ + pass(z,ff_cos_##n,n4/2);\ +} + +static void fft4(FFTComplex *z) +{ + FFTSample t1, t2, t3, t4, t5, t6, t7, t8; + + BF(t3, t1, z[0].re, z[1].re); + BF(t8, t6, z[3].re, z[2].re); + BF(z[2].re, z[0].re, t1, t6); + BF(t4, t2, z[0].im, z[1].im); + BF(t7, t5, z[2].im, z[3].im); + BF(z[3].im, z[1].im, t4, t8); + BF(z[3].re, z[1].re, t3, t7); + BF(z[2].im, z[0].im, t2, t5); +} + +static void fft8(FFTComplex *z) +{ + FFTSample t1, t2, t3, t4, t5, t6, t7, t8; + + fft4(z); + + BF(t1, z[5].re, z[4].re, -z[5].re); + BF(t2, z[5].im, z[4].im, -z[5].im); + BF(t3, z[7].re, z[6].re, -z[7].re); + BF(t4, z[7].im, z[6].im, -z[7].im); + BF(t8, t1, t3, t1); + BF(t7, t2, t2, t4); + BF(z[4].re, z[0].re, z[0].re, t1); + BF(z[4].im, z[0].im, z[0].im, t2); + BF(z[6].re, z[2].re, z[2].re, t7); + BF(z[6].im, z[2].im, z[2].im, t8); + + TRANSFORM(z[1],z[3],z[5],z[7],sqrthalf,sqrthalf); +} + +#if !CONFIG_SMALL +static void fft16(FFTComplex *z) +{ + FFTSample t1, t2, t3, t4, t5, t6; + + fft8(z); + fft4(z+8); + fft4(z+12); + + TRANSFORM_ZERO(z[0],z[4],z[8],z[12]); + TRANSFORM(z[2],z[6],z[10],z[14],sqrthalf,sqrthalf); + TRANSFORM(z[1],z[5],z[9],z[13],ff_cos_16[1],ff_cos_16[3]); + TRANSFORM(z[3],z[7],z[11],z[15],ff_cos_16[3],ff_cos_16[1]); +} +#else +DECL_FFT(16,8,4) +#endif +DECL_FFT(32,16,8) +DECL_FFT(64,32,16) +DECL_FFT(128,64,32) +DECL_FFT(256,128,64) +DECL_FFT(512,256,128) +#if !CONFIG_SMALL +#define pass pass_big +#endif +DECL_FFT(1024,512,256) +DECL_FFT(2048,1024,512) +DECL_FFT(4096,2048,1024) +DECL_FFT(8192,4096,2048) +DECL_FFT(16384,8192,4096) +DECL_FFT(32768,16384,8192) +DECL_FFT(65536,32768,16384) + +static void (*fft_dispatch[])(FFTComplex*) = { + fft4, fft8, fft16, fft32, fft64, fft128, fft256, fft512, fft1024, + fft2048, fft4096, fft8192, fft16384, fft32768, fft65536, +}; + +void ff_fft_calc_c(FFTContext *s, FFTComplex *z) +{ + fft_dispatch[s->nbits-2](z); +} + Index: apps/codecs/libcook/random.c =================================================================== --- apps/codecs/libcook/random.c (revision 0) +++ apps/codecs/libcook/random.c (revision 0) @@ -0,0 +1,119 @@ +/* + A C-program for MT19937, with initialization improved 2002/2/10. + Coded by Takuji Nishimura and Makoto Matsumoto. + This is a faster version by taking Shawn Cokus's optimization, + Matthe Bellew's simplification. + + Before using, initialize the state by using srand(seed). + + Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The names of its contributors may not be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Any feedback is very welcome. + http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html + email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) +*/ + +/* + Adapted to Rockbox by Jens Arnold +*/ + +#include + +/* Period parameters */ +#define N 624 +#define M 397 +#define MATRIX_A 0x9908b0dfUL /* constant vector a */ +#define UMASK 0x80000000UL /* most significant w-r bits */ +#define LMASK 0x7fffffffUL /* least significant r bits */ +#define MIXBITS(u,v) ( ((u) & UMASK) | ((v) & LMASK) ) +#define TWIST(u,v) ((MIXBITS(u,v) >> 1) ^ ((v)&1UL ? MATRIX_A : 0UL)) + +static unsigned long state[N]; /* the array for the state vector */ +static int left = 0; +static unsigned long *next; + +/* initializes state[N] with a seed */ +void srand(unsigned int seed) +{ + unsigned long x = seed & 0xffffffffUL; + unsigned long *s = state; + int j; + + for (*s++ = x, j = 1; j < N; j++) { + x = (1812433253UL * (x ^ (x >> 30)) + j) & 0xffffffffUL; + *s++ = x; + /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ + /* In the previous versions, MSBs of the seed affect */ + /* only MSBs of the array state[]. */ + /* 2002/01/09 modified by Makoto Matsumoto */ + } + left = 1; +} + +static void next_state(void) +{ + unsigned long *p = state; + int j; + + /* if srand() has not been called, */ + /* a default initial seed is used */ + if (left < 0) + srand(5489UL); + + left = N; + next = state; + + for (j = N - M + 1; --j; p++) + *p = p[M] ^ TWIST(p[0], p[1]); + + for (j = M; --j; p++) + *p = p[M-N] ^ TWIST(p[0], p[1]); + + *p = p[M-N] ^ TWIST(p[0], state[0]); +} + +/* generates a random number on [0,RAND_MAX]-interval */ +int rand(void) +{ + unsigned long y; + + if (--left <= 0) + next_state(); + y = *next++; + + /* Tempering */ + y ^= (y >> 11); + y ^= (y << 7) & 0x9d2c5680UL; + y ^= (y << 15) & 0xefc60000UL; + y ^= (y >> 18); + + return ((unsigned int)y) >> 1; +} Index: apps/codecs/libcook/bswap.h =================================================================== --- apps/codecs/libcook/bswap.h (revision 0) +++ apps/codecs/libcook/bswap.h (revision 0) @@ -0,0 +1,150 @@ +/** + * @file bswap.h + * byte swap. + */ + +#ifndef __BSWAP_H__ +#define __BSWAP_H__ + +#ifdef HAVE_BYTESWAP_H +#include +#else + +#ifdef ROCKBOX +#include "codecs.h" + +/* rockbox' optimised inline functions */ +#define bswap_16(x) swap16(x) +#define bswap_32(x) swap32(x) + +static inline uint64_t ByteSwap64(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; +} +#define bswap_64(x) ByteSwap64(x) + +#elif defined(ARCH_X86) +static inline unsigned short ByteSwap16(unsigned short x) +{ + __asm("xchgb %b0,%h0" : + "=q" (x) : + "0" (x)); + return x; +} +#define bswap_16(x) ByteSwap16(x) + +static inline unsigned int ByteSwap32(unsigned int x) +{ +#if __CPU__ > 386 + __asm("bswap %0": + "=r" (x) : +#else + __asm("xchgb %b0,%h0\n" + " rorl $16,%0\n" + " xchgb %b0,%h0": + "=q" (x) : +#endif + "0" (x)); + return x; +} +#define bswap_32(x) ByteSwap32(x) + +static inline unsigned long long int ByteSwap64(unsigned long long int x) +{ + register union { __extension__ uint64_t __ll; + uint32_t __l[2]; } __x; + asm("xchgl %0,%1": + "=r"(__x.__l[0]),"=r"(__x.__l[1]): + "0"(bswap_32((unsigned long)x)),"1"(bswap_32((unsigned long)(x>>32)))); + return __x.__ll; +} +#define bswap_64(x) ByteSwap64(x) + +#elif defined(ARCH_SH4) + +static inline uint16_t ByteSwap16(uint16_t x) { + __asm__("swap.b %0,%0":"=r"(x):"0"(x)); + return x; +} + +static inline uint32_t ByteSwap32(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; +} + +#define bswap_16(x) ByteSwap16(x) +#define bswap_32(x) ByteSwap32(x) + +static inline uint64_t ByteSwap64(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; +} +#define bswap_64(x) ByteSwap64(x) + +#else + +#define bswap_16(x) (((x) & 0x00ff) << 8 | ((x) & 0xff00) >> 8) + + +// code from bits/byteswap.h (C) 1997, 1998 Free Software Foundation, Inc. +#define bswap_32(x) \ + ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ + (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) + +/*static inline uint64_t ByteSwap64(uint64_t x) +{ + 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; +}*/ +#define bswap_64(x) ByteSwap64(x) + +#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__ */ Index: apps/codecs/libcook/rm2wav.h =================================================================== --- apps/codecs/libcook/rm2wav.h (revision 0) +++ apps/codecs/libcook/rm2wav.h (revision 0) @@ -0,0 +1,69 @@ +#include +#include + +typedef struct rm_packet +{ + uint8_t data[30000]; /* Reordered data. No malloc, hence the size */ + uint16_t version; + uint16_t length; + uint32_t timestamp; + uint16_t stream_number; + uint8_t flags; +}RMPacket; + +typedef struct rm_context +{ + /* Demux Context */ + int old_format; + int current_stream; + int remaining_len; + int audio_stream_num; /*< Stream number for audio packets*/ + int audio_pkt_cnt; /* Output packet counter*/ + + /* Stream Variables */ + uint32_t audiotimestamp; /* Audio packet timestamp*/ + uint16_t sub_packet_cnt; /* Subpacket counter, used while reading */ + uint16_t sub_packet_size, sub_packet_h, coded_framesize; /* Descrambling parameters from container */ + uint16_t audio_framesize; /* Audio frame size from container */ + uint16_t sub_packet_lengths[16]; /* Length of each subpacket */ + + /* Codec Context */ + uint16_t block_align; + uint32_t nb_packets; + int frame_number; + uint32_t extradata_size; + uint16_t sample_rate; + uint16_t nb_channels; + uint32_t bit_rate; + uint16_t flags; + + /*cook extradata*/ + uint32_t cook_version; + uint16_t samples_pf_pc; /* samples per frame per channel */ + uint16_t nb_subbands; /* number of subbands in the frequency domain */ + /* extra 8 bytes for stereo data */ + uint32_t unused; + uint16_t js_subband_start; /* joint stereo subband start */ + uint16_t js_vlc_bits; + +} RMContext; + +static unsigned char wav_header[44]={ + 'R','I','F','F',// 0 - ChunkID + 0,0,0,0, // 4 - ChunkSize (filesize-8) + 'W','A','V','E',// 8 - Format + 'f','m','t',' ',// 12 - SubChunkID + 16,0,0,0, // 16 - SubChunk1ID // 16 for PCM + 1,0, // 20 - AudioFormat (1=Uncompressed) + 2,0, // 22 - NumChannels + 0,0,0,0, // 24 - SampleRate in Hz + 0,0,0,0, // 28 - Byte Rate (SampleRate*NumChannels*(BitsPerSample/8) + 4,0, // 32 - BlockAlign (== NumChannels * BitsPerSample/8) + 16,0, // 34 - BitsPerSample + 'd','a','t','a',// 36 - Subchunk2ID + 0,0,0,0 // 40 - Subchunk2Size +}; +int open_wav(char* filename); +void close_wav(int fd, RMContext *rmctx); +int real_parse_header(int fd, RMContext *rmctx); +void rm_get_packet(int fd,RMContext *rmctx, RMPacket *pkt); Index: apps/codecs/libcook/bytestream.h =================================================================== --- apps/codecs/libcook/bytestream.h (revision 0) +++ apps/codecs/libcook/bytestream.h (revision 0) @@ -0,0 +1,71 @@ +/* + * Bytestream functions + * copyright (c) 2006 Baptiste Coudurier + * + * 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 + */ + +#ifndef AVCODEC_BYTESTREAM_H +#define AVCODEC_BYTESTREAM_H + +#include +#include "libavutil/common.h" +#include "libavutil/intreadwrite.h" + +#define DEF_T(type, name, bytes, read, write) \ +static av_always_inline type bytestream_get_ ## name(const uint8_t **b){\ + (*b) += bytes;\ + return read(*b - bytes);\ +}\ +static av_always_inline void bytestream_put_ ##name(uint8_t **b, const type value){\ + write(*b, value);\ + (*b) += bytes;\ +} + +#define DEF(name, bytes, read, write) \ + DEF_T(unsigned int, name, bytes, read, write) +#define DEF64(name, bytes, read, write) \ + DEF_T(uint64_t, name, bytes, read, write) + +DEF64(le64, 8, AV_RL64, AV_WL64) +DEF (le32, 4, AV_RL32, AV_WL32) +DEF (le24, 3, AV_RL24, AV_WL24) +DEF (le16, 2, AV_RL16, AV_WL16) +DEF64(be64, 8, AV_RB64, AV_WB64) +DEF (be32, 4, AV_RB32, AV_WB32) +DEF (be24, 3, AV_RB24, AV_WB24) +DEF (be16, 2, AV_RB16, AV_WB16) +DEF (byte, 1, AV_RB8 , AV_WB8 ) + +#undef DEF +#undef DEF64 +#undef DEF_T + +static av_always_inline unsigned int bytestream_get_buffer(const uint8_t **b, uint8_t *dst, unsigned int size) +{ + memcpy(dst, *b, size); + (*b) += size; + return size; +} + +static av_always_inline void bytestream_put_buffer(uint8_t **b, const uint8_t *src, unsigned int size) +{ + memcpy(*b, src, size); + (*b) += size; +} + +#endif /* AVCODEC_BYTESTREAM_H */ Index: apps/codecs/libcook/dsputil.c =================================================================== --- apps/codecs/libcook/dsputil.c (revision 0) +++ apps/codecs/libcook/dsputil.c (revision 0) @@ -0,0 +1,4701 @@ +/* + * DSP utils + * Copyright (c) 2000, 2001 Fabrice Bellard + * Copyright (c) 2002-2004 Michael Niedermayer + * + * gmc & q-pel & 32/64 bit based MC by 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 libavcodec/dsputil.c + * DSP utils + */ + +#include "avcodec.h" +#include "dsputil.h" +//#include "simple_idct.h" +//#include "faandct.h" +//#include "faanidct.h" +//#include "mathops.h" +//#include "h263.h" +//#include "snow.h" + +#if 0 /* MT : DELETE THIS LINE ONLY. */ +/* snow.c */ +void ff_spatial_dwt(int *buffer, int width, int height, int stride, int type, int decomposition_count); + +/* vorbis.c */ +void vorbis_inverse_coupling(float *mag, float *ang, int blocksize); + +/* ac3dec.c */ +void ff_ac3_downmix_c(float (*samples)[256], float (*matrix)[2], int out_ch, int in_ch, int len); + +/* flacenc.c */ +void ff_flac_compute_autocorr(const int32_t *data, int len, int lag, double *autoc); + +/* pngdec.c */ +void ff_add_png_paeth_prediction(uint8_t *dst, uint8_t *src, uint8_t *top, int w, int bpp); + +/* eaidct.c */ +void ff_ea_idct_put_c(uint8_t *dest, int linesize, DCTELEM *block); +#endif /* MT : DELETE THIS LINE ONLY. */ +//uint8_t ff_cropTbl[256 + 2 * MAX_NEG_CROP] = {0, }; +//uint32_t ff_squareTbl[512] = {0, }; + +// 0x7f7f7f7f or 0x7f7f7f7f7f7f7f7f or whatever, depending on the cpu's native arithmetic size +#define pb_7f (~0UL/255 * 0x7f) +#define pb_80 (~0UL/255 * 0x80) + +const uint8_t ff_zigzag_direct[64] = { + 0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, + 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63 +}; + +/* Specific zigzag scan for 248 idct. NOTE that unlike the + specification, we interleave the fields */ +const uint8_t ff_zigzag248_direct[64] = { + 0, 8, 1, 9, 16, 24, 2, 10, + 17, 25, 32, 40, 48, 56, 33, 41, + 18, 26, 3, 11, 4, 12, 19, 27, + 34, 42, 49, 57, 50, 58, 35, 43, + 20, 28, 5, 13, 6, 14, 21, 29, + 36, 44, 51, 59, 52, 60, 37, 45, + 22, 30, 7, 15, 23, 31, 38, 46, + 53, 61, 54, 62, 39, 47, 55, 63, +}; + +/* not permutated inverse zigzag_direct + 1 for MMX quantizer */ +DECLARE_ALIGNED_8(uint16_t, inv_zigzag_direct16[64]) = {0, }; + +const uint8_t ff_alternate_horizontal_scan[64] = { + 0, 1, 2, 3, 8, 9, 16, 17, + 10, 11, 4, 5, 6, 7, 15, 14, + 13, 12, 19, 18, 24, 25, 32, 33, + 26, 27, 20, 21, 22, 23, 28, 29, + 30, 31, 34, 35, 40, 41, 48, 49, + 42, 43, 36, 37, 38, 39, 44, 45, + 46, 47, 50, 51, 56, 57, 58, 59, + 52, 53, 54, 55, 60, 61, 62, 63, +}; + +const uint8_t ff_alternate_vertical_scan[64] = { + 0, 8, 16, 24, 1, 9, 2, 10, + 17, 25, 32, 40, 48, 56, 57, 49, + 41, 33, 26, 18, 3, 11, 4, 12, + 19, 27, 34, 42, 50, 58, 35, 43, + 51, 59, 20, 28, 5, 13, 6, 14, + 21, 29, 36, 44, 52, 60, 37, 45, + 53, 61, 22, 30, 7, 15, 23, 31, + 38, 46, 54, 62, 39, 47, 55, 63, +}; + +/* a*inverse[b]>>32 == a/b for all 0<=a<=65536 && 2<=b<=255 */ +const uint32_t ff_inverse[256]={ + 0, 4294967295U,2147483648U,1431655766, 1073741824, 858993460, 715827883, 613566757, + 536870912, 477218589, 429496730, 390451573, 357913942, 330382100, 306783379, 286331154, + 268435456, 252645136, 238609295, 226050911, 214748365, 204522253, 195225787, 186737709, + 178956971, 171798692, 165191050, 159072863, 153391690, 148102321, 143165577, 138547333, + 134217728, 130150525, 126322568, 122713352, 119304648, 116080198, 113025456, 110127367, + 107374183, 104755300, 102261127, 99882961, 97612894, 95443718, 93368855, 91382283, + 89478486, 87652394, 85899346, 84215046, 82595525, 81037119, 79536432, 78090315, + 76695845, 75350304, 74051161, 72796056, 71582789, 70409300, 69273667, 68174085, + 67108864, 66076420, 65075263, 64103990, 63161284, 62245903, 61356676, 60492498, + 59652324, 58835169, 58040099, 57266231, 56512728, 55778797, 55063684, 54366675, + 53687092, 53024288, 52377650, 51746594, 51130564, 50529028, 49941481, 49367441, + 48806447, 48258060, 47721859, 47197443, 46684428, 46182445, 45691142, 45210183, + 44739243, 44278014, 43826197, 43383509, 42949673, 42524429, 42107523, 41698712, + 41297763, 40904451, 40518560, 40139882, 39768216, 39403370, 39045158, 38693400, + 38347923, 38008561, 37675152, 37347542, 37025581, 36709123, 36398028, 36092163, + 35791395, 35495598, 35204650, 34918434, 34636834, 34359739, 34087043, 33818641, + 33554432, 33294321, 33038210, 32786010, 32537632, 32292988, 32051995, 31814573, + 31580642, 31350127, 31122952, 30899046, 30678338, 30460761, 30246249, 30034737, + 29826162, 29620465, 29417585, 29217465, 29020050, 28825284, 28633116, 28443493, + 28256364, 28071682, 27889399, 27709467, 27531842, 27356480, 27183338, 27012373, + 26843546, 26676816, 26512144, 26349493, 26188825, 26030105, 25873297, 25718368, + 25565282, 25414008, 25264514, 25116768, 24970741, 24826401, 24683721, 24542671, + 24403224, 24265352, 24129030, 23994231, 23860930, 23729102, 23598722, 23469767, + 23342214, 23216040, 23091223, 22967740, 22845571, 22724695, 22605092, 22486740, + 22369622, 22253717, 22139007, 22025474, 21913099, 21801865, 21691755, 21582751, + 21474837, 21367997, 21262215, 21157475, 21053762, 20951060, 20849356, 20748635, + 20648882, 20550083, 20452226, 20355296, 20259280, 20164166, 20069941, 19976593, + 19884108, 19792477, 19701685, 19611723, 19522579, 19434242, 19346700, 19259944, + 19173962, 19088744, 19004281, 18920561, 18837576, 18755316, 18673771, 18592933, + 18512791, 18433337, 18354562, 18276457, 18199014, 18122225, 18046082, 17970575, + 17895698, 17821442, 17747799, 17674763, 17602325, 17530479, 17459217, 17388532, + 17318417, 17248865, 17179870, 17111424, 17043522, 16976156, 16909321, 16843010, +}; + +/* Input permutation for the simple_idct_mmx */ +static const uint8_t simple_mmx_permutation[64]={ + 0x00, 0x08, 0x04, 0x09, 0x01, 0x0C, 0x05, 0x0D, + 0x10, 0x18, 0x14, 0x19, 0x11, 0x1C, 0x15, 0x1D, + 0x20, 0x28, 0x24, 0x29, 0x21, 0x2C, 0x25, 0x2D, + 0x12, 0x1A, 0x16, 0x1B, 0x13, 0x1E, 0x17, 0x1F, + 0x02, 0x0A, 0x06, 0x0B, 0x03, 0x0E, 0x07, 0x0F, + 0x30, 0x38, 0x34, 0x39, 0x31, 0x3C, 0x35, 0x3D, + 0x22, 0x2A, 0x26, 0x2B, 0x23, 0x2E, 0x27, 0x2F, + 0x32, 0x3A, 0x36, 0x3B, 0x33, 0x3E, 0x37, 0x3F, +}; + +static const uint8_t idct_sse2_row_perm[8] = {0, 4, 1, 5, 2, 6, 3, 7}; + +void ff_init_scantable(uint8_t *permutation, ScanTable *st, const uint8_t *src_scantable){ + int i; + int end; + + st->scantable= src_scantable; + + for(i=0; i<64; i++){ + int j; + j = src_scantable[i]; + st->permutated[i] = permutation[j]; +#if ARCH_PPC + st->inverse[j] = i; +#endif + } + + end=-1; + for(i=0; i<64; i++){ + int j; + j = st->permutated[i]; + if(j>end) end=j; + st->raster_end[i]= end; + } +} + +static int pix_sum_c(uint8_t * pix, int line_size) +{ + int s, i, j; + + s = 0; + for (i = 0; i < 16; i++) { + for (j = 0; j < 16; j += 8) { + s += pix[0]; + s += pix[1]; + s += pix[2]; + s += pix[3]; + s += pix[4]; + s += pix[5]; + s += pix[6]; + s += pix[7]; + pix += 8; + } + pix += line_size - 16; + } + return s; +} + +static int pix_norm1_c(uint8_t * pix, int line_size) +{ + int s, i, j; + uint32_t *sq = ff_squareTbl + 256; + + s = 0; + for (i = 0; i < 16; i++) { + for (j = 0; j < 16; j += 8) { +#if 0 + s += sq[pix[0]]; + s += sq[pix[1]]; + s += sq[pix[2]]; + s += sq[pix[3]]; + s += sq[pix[4]]; + s += sq[pix[5]]; + s += sq[pix[6]]; + s += sq[pix[7]]; +#else +#if LONG_MAX > 2147483647 + register uint64_t x=*(uint64_t*)pix; + s += sq[x&0xff]; + s += sq[(x>>8)&0xff]; + s += sq[(x>>16)&0xff]; + s += sq[(x>>24)&0xff]; + s += sq[(x>>32)&0xff]; + s += sq[(x>>40)&0xff]; + s += sq[(x>>48)&0xff]; + s += sq[(x>>56)&0xff]; +#else + register uint32_t x=*(uint32_t*)pix; + s += sq[x&0xff]; + s += sq[(x>>8)&0xff]; + s += sq[(x>>16)&0xff]; + s += sq[(x>>24)&0xff]; + x=*(uint32_t*)(pix+4); + s += sq[x&0xff]; + s += sq[(x>>8)&0xff]; + s += sq[(x>>16)&0xff]; + s += sq[(x>>24)&0xff]; +#endif +#endif + pix += 8; + } + pix += line_size - 16; + } + return s; +} + +static void bswap_buf(uint32_t *dst, const uint32_t *src, int w){ + int i; + + for(i=0; i+8<=w; i+=8){ + dst[i+0]= bswap_32(src[i+0]); + dst[i+1]= bswap_32(src[i+1]); + dst[i+2]= bswap_32(src[i+2]); + dst[i+3]= bswap_32(src[i+3]); + dst[i+4]= bswap_32(src[i+4]); + dst[i+5]= bswap_32(src[i+5]); + dst[i+6]= bswap_32(src[i+6]); + dst[i+7]= bswap_32(src[i+7]); + } + for(;i>(dec_count-level); + int sx= (ori&1) ? size : 0; + int stride= 32<<(dec_count-level); + int sy= (ori&2) ? stride>>1 : 0; + + for(i=0; i=0); + return s>>9; +} + +static int w53_8_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h){ + return w_c(v, pix1, pix2, line_size, 8, h, 1); +} + +static int w97_8_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h){ + return w_c(v, pix1, pix2, line_size, 8, h, 0); +} + +static int w53_16_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h){ + return w_c(v, pix1, pix2, line_size, 16, h, 1); +} + +static int w97_16_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h){ + return w_c(v, pix1, pix2, line_size, 16, h, 0); +} + +int w53_32_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h){ + return w_c(v, pix1, pix2, line_size, 32, h, 1); +} + +int w97_32_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h){ + return w_c(v, pix1, pix2, line_size, 32, h, 0); +} +#endif + +/* draw the edges of width 'w' of an image of size width, height */ +//FIXME check that this is ok for mpeg4 interlaced +static void draw_edges_c(uint8_t *buf, int wrap, int width, int height, int w) +{ + uint8_t *ptr, *last_line; + int i; + + last_line = buf + (height - 1) * wrap; + for(i=0;i= h){ + src+= (h-1-src_y)*linesize; + src_y=h-1; + }else if(src_y<=-block_h){ + src+= (1-block_h-src_y)*linesize; + src_y=1-block_h; + } + if(src_x>= w){ + src+= (w-1-src_x); + src_x=w-1; + }else if(src_x<=-block_w){ + src+= (1-block_w-src_x); + src_x=1-block_w; + } + + start_y= FFMAX(0, -src_y); + start_x= FFMAX(0, -src_x); + end_y= FFMIN(block_h, h-src_y); + end_x= FFMIN(block_w, w-src_x); + + // copy existing part + for(y=start_y; y 127) + *pixels = 255; + else + *pixels = (uint8_t)(*block + 128); + block++; + pixels++; + } + pixels += (line_size - 8); + } +} + +static void add_pixels_clamped_c(const DCTELEM *block, uint8_t *restrict pixels, + int line_size) +{ + int i; + uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; + + /* read the pixels */ + for(i=0;i<8;i++) { + pixels[0] = cm[pixels[0] + block[0]]; + pixels[1] = cm[pixels[1] + block[1]]; + pixels[2] = cm[pixels[2] + block[2]]; + pixels[3] = cm[pixels[3] + block[3]]; + pixels[4] = cm[pixels[4] + block[4]]; + pixels[5] = cm[pixels[5] + block[5]]; + pixels[6] = cm[pixels[6] + block[6]]; + pixels[7] = cm[pixels[7] + block[7]]; + pixels += line_size; + block += 8; + } +} + +static void add_pixels_clamped4_c(const DCTELEM *block, uint8_t *restrict pixels, + int line_size) +{ + int i; + uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; + + /* read the pixels */ + for(i=0;i<4;i++) { + pixels[0] = cm[pixels[0] + block[0]]; + pixels[1] = cm[pixels[1] + block[1]]; + pixels[2] = cm[pixels[2] + block[2]]; + pixels[3] = cm[pixels[3] + block[3]]; + pixels += line_size; + block += 8; + } +} + +static void add_pixels_clamped2_c(const DCTELEM *block, uint8_t *restrict pixels, + int line_size) +{ + int i; + uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; + + /* read the pixels */ + for(i=0;i<2;i++) { + pixels[0] = cm[pixels[0] + block[0]]; + pixels[1] = cm[pixels[1] + block[1]]; + pixels += line_size; + block += 8; + } +} + +static void add_pixels8_c(uint8_t *restrict pixels, DCTELEM *block, int line_size) +{ + int i; + for(i=0;i<8;i++) { + pixels[0] += block[0]; + pixels[1] += block[1]; + pixels[2] += block[2]; + pixels[3] += block[3]; + pixels[4] += block[4]; + pixels[5] += block[5]; + pixels[6] += block[6]; + pixels[7] += block[7]; + pixels += line_size; + block += 8; + } +} + +static void add_pixels4_c(uint8_t *restrict pixels, DCTELEM *block, int line_size) +{ + int i; + for(i=0;i<4;i++) { + pixels[0] += block[0]; + pixels[1] += block[1]; + pixels[2] += block[2]; + pixels[3] += block[3]; + pixels += line_size; + block += 4; + } +} + +static int sum_abs_dctelem_c(DCTELEM *block) +{ + int sum=0, i; + for(i=0; i<64; i++) + sum+= FFABS(block[i]); + return sum; +} + +#if 0 + +#define PIXOP2(OPNAME, OP) \ +static void OPNAME ## _pixels(uint8_t *block, const uint8_t *pixels, int line_size, int h)\ +{\ + int i;\ + for(i=0; i>1));\ + pixels+=line_size;\ + block +=line_size;\ + }\ +}\ +\ +static void OPNAME ## _pixels_x2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h)\ +{\ + int i;\ + for(i=0; i>1));\ + pixels+=line_size;\ + block +=line_size;\ + }\ +}\ +\ +static void OPNAME ## _no_rnd_pixels_y2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h)\ +{\ + int i;\ + for(i=0; i>1));\ + pixels+=line_size;\ + block +=line_size;\ + }\ +}\ +\ +static void OPNAME ## _pixels_y2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h)\ +{\ + int i;\ + for(i=0; i>1));\ + pixels+=line_size;\ + block +=line_size;\ + }\ +}\ +\ +static void OPNAME ## _pixels_xy2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h)\ +{\ + int i;\ + const uint64_t a= AV_RN64(pixels );\ + const uint64_t b= AV_RN64(pixels+1);\ + uint64_t l0= (a&0x0303030303030303ULL)\ + + (b&0x0303030303030303ULL)\ + + 0x0202020202020202ULL;\ + uint64_t h0= ((a&0xFCFCFCFCFCFCFCFCULL)>>2)\ + + ((b&0xFCFCFCFCFCFCFCFCULL)>>2);\ + uint64_t l1,h1;\ +\ + pixels+=line_size;\ + for(i=0; i>2)\ + + ((b&0xFCFCFCFCFCFCFCFCULL)>>2);\ + OP(*((uint64_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0F0F0F0F0FULL));\ + pixels+=line_size;\ + block +=line_size;\ + a= AV_RN64(pixels );\ + b= AV_RN64(pixels+1);\ + l0= (a&0x0303030303030303ULL)\ + + (b&0x0303030303030303ULL)\ + + 0x0202020202020202ULL;\ + h0= ((a&0xFCFCFCFCFCFCFCFCULL)>>2)\ + + ((b&0xFCFCFCFCFCFCFCFCULL)>>2);\ + OP(*((uint64_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0F0F0F0F0FULL));\ + pixels+=line_size;\ + block +=line_size;\ + }\ +}\ +\ +static void OPNAME ## _no_rnd_pixels_xy2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h)\ +{\ + int i;\ + const uint64_t a= AV_RN64(pixels );\ + const uint64_t b= AV_RN64(pixels+1);\ + uint64_t l0= (a&0x0303030303030303ULL)\ + + (b&0x0303030303030303ULL)\ + + 0x0101010101010101ULL;\ + uint64_t h0= ((a&0xFCFCFCFCFCFCFCFCULL)>>2)\ + + ((b&0xFCFCFCFCFCFCFCFCULL)>>2);\ + uint64_t l1,h1;\ +\ + pixels+=line_size;\ + for(i=0; i>2)\ + + ((b&0xFCFCFCFCFCFCFCFCULL)>>2);\ + OP(*((uint64_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0F0F0F0F0FULL));\ + pixels+=line_size;\ + block +=line_size;\ + a= AV_RN64(pixels );\ + b= AV_RN64(pixels+1);\ + l0= (a&0x0303030303030303ULL)\ + + (b&0x0303030303030303ULL)\ + + 0x0101010101010101ULL;\ + h0= ((a&0xFCFCFCFCFCFCFCFCULL)>>2)\ + + ((b&0xFCFCFCFCFCFCFCFCULL)>>2);\ + OP(*((uint64_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0F0F0F0F0FULL));\ + pixels+=line_size;\ + block +=line_size;\ + }\ +}\ +\ +CALL_2X_PIXELS(OPNAME ## _pixels16_c , OPNAME ## _pixels_c , 8)\ +CALL_2X_PIXELS(OPNAME ## _pixels16_x2_c , OPNAME ## _pixels_x2_c , 8)\ +CALL_2X_PIXELS(OPNAME ## _pixels16_y2_c , OPNAME ## _pixels_y2_c , 8)\ +CALL_2X_PIXELS(OPNAME ## _pixels16_xy2_c, OPNAME ## _pixels_xy2_c, 8)\ +CALL_2X_PIXELS(OPNAME ## _no_rnd_pixels16_x2_c , OPNAME ## _no_rnd_pixels_x2_c , 8)\ +CALL_2X_PIXELS(OPNAME ## _no_rnd_pixels16_y2_c , OPNAME ## _no_rnd_pixels_y2_c , 8)\ +CALL_2X_PIXELS(OPNAME ## _no_rnd_pixels16_xy2_c, OPNAME ## _no_rnd_pixels_xy2_c, 8) + +#define op_avg(a, b) a = ( ((a)|(b)) - ((((a)^(b))&0xFEFEFEFEFEFEFEFEULL)>>1) ) +#else // 64 bit variant + +#define PIXOP2(OPNAME, OP) \ +static void OPNAME ## _pixels2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h){\ + int i;\ + for(i=0; i>2)\ + + ((b&0xFCFCFCFCUL)>>2);\ + l1= (c&0x03030303UL)\ + + (d&0x03030303UL);\ + h1= ((c&0xFCFCFCFCUL)>>2)\ + + ((d&0xFCFCFCFCUL)>>2);\ + OP(*((uint32_t*)&dst[i*dst_stride]), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\ + a= AV_RN32(&src1[i*src_stride1+4]);\ + b= AV_RN32(&src2[i*src_stride2+4]);\ + c= AV_RN32(&src3[i*src_stride3+4]);\ + d= AV_RN32(&src4[i*src_stride4+4]);\ + l0= (a&0x03030303UL)\ + + (b&0x03030303UL)\ + + 0x02020202UL;\ + h0= ((a&0xFCFCFCFCUL)>>2)\ + + ((b&0xFCFCFCFCUL)>>2);\ + l1= (c&0x03030303UL)\ + + (d&0x03030303UL);\ + h1= ((c&0xFCFCFCFCUL)>>2)\ + + ((d&0xFCFCFCFCUL)>>2);\ + OP(*((uint32_t*)&dst[i*dst_stride+4]), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\ + }\ +}\ +\ +static inline void OPNAME ## _pixels4_x2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h){\ + OPNAME ## _pixels4_l2(block, pixels, pixels+1, line_size, line_size, line_size, h);\ +}\ +\ +static inline void OPNAME ## _pixels4_y2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h){\ + OPNAME ## _pixels4_l2(block, pixels, pixels+line_size, line_size, line_size, line_size, h);\ +}\ +\ +static inline void OPNAME ## _pixels2_x2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h){\ + OPNAME ## _pixels2_l2(block, pixels, pixels+1, line_size, line_size, line_size, h);\ +}\ +\ +static inline void OPNAME ## _pixels2_y2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h){\ + OPNAME ## _pixels2_l2(block, pixels, pixels+line_size, line_size, line_size, line_size, h);\ +}\ +\ +static inline void OPNAME ## _no_rnd_pixels8_l4(uint8_t *dst, const uint8_t *src1, uint8_t *src2, uint8_t *src3, uint8_t *src4,\ + int dst_stride, int src_stride1, int src_stride2,int src_stride3,int src_stride4, int h){\ + int i;\ + for(i=0; i>2)\ + + ((b&0xFCFCFCFCUL)>>2);\ + l1= (c&0x03030303UL)\ + + (d&0x03030303UL);\ + h1= ((c&0xFCFCFCFCUL)>>2)\ + + ((d&0xFCFCFCFCUL)>>2);\ + OP(*((uint32_t*)&dst[i*dst_stride]), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\ + a= AV_RN32(&src1[i*src_stride1+4]);\ + b= AV_RN32(&src2[i*src_stride2+4]);\ + c= AV_RN32(&src3[i*src_stride3+4]);\ + d= AV_RN32(&src4[i*src_stride4+4]);\ + l0= (a&0x03030303UL)\ + + (b&0x03030303UL)\ + + 0x01010101UL;\ + h0= ((a&0xFCFCFCFCUL)>>2)\ + + ((b&0xFCFCFCFCUL)>>2);\ + l1= (c&0x03030303UL)\ + + (d&0x03030303UL);\ + h1= ((c&0xFCFCFCFCUL)>>2)\ + + ((d&0xFCFCFCFCUL)>>2);\ + OP(*((uint32_t*)&dst[i*dst_stride+4]), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\ + }\ +}\ +static inline void OPNAME ## _pixels16_l4(uint8_t *dst, const uint8_t *src1, uint8_t *src2, uint8_t *src3, uint8_t *src4,\ + int dst_stride, int src_stride1, int src_stride2,int src_stride3,int src_stride4, int h){\ + OPNAME ## _pixels8_l4(dst , src1 , src2 , src3 , src4 , dst_stride, src_stride1, src_stride2, src_stride3, src_stride4, h);\ + OPNAME ## _pixels8_l4(dst+8, src1+8, src2+8, src3+8, src4+8, dst_stride, src_stride1, src_stride2, src_stride3, src_stride4, h);\ +}\ +static inline void OPNAME ## _no_rnd_pixels16_l4(uint8_t *dst, const uint8_t *src1, uint8_t *src2, uint8_t *src3, uint8_t *src4,\ + int dst_stride, int src_stride1, int src_stride2,int src_stride3,int src_stride4, int h){\ + OPNAME ## _no_rnd_pixels8_l4(dst , src1 , src2 , src3 , src4 , dst_stride, src_stride1, src_stride2, src_stride3, src_stride4, h);\ + OPNAME ## _no_rnd_pixels8_l4(dst+8, src1+8, src2+8, src3+8, src4+8, dst_stride, src_stride1, src_stride2, src_stride3, src_stride4, h);\ +}\ +\ +static inline void OPNAME ## _pixels2_xy2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h)\ +{\ + int i, a0, b0, a1, b1;\ + a0= pixels[0];\ + b0= pixels[1] + 2;\ + a0 += b0;\ + b0 += pixels[2];\ +\ + pixels+=line_size;\ + for(i=0; i>2; /* FIXME non put */\ + block[1]= (b1+b0)>>2;\ +\ + pixels+=line_size;\ + block +=line_size;\ +\ + a0= pixels[0];\ + b0= pixels[1] + 2;\ + a0 += b0;\ + b0 += pixels[2];\ +\ + block[0]= (a1+a0)>>2;\ + block[1]= (b1+b0)>>2;\ + pixels+=line_size;\ + block +=line_size;\ + }\ +}\ +\ +static inline void OPNAME ## _pixels4_xy2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h)\ +{\ + int i;\ + const uint32_t a= AV_RN32(pixels );\ + const uint32_t b= AV_RN32(pixels+1);\ + uint32_t l0= (a&0x03030303UL)\ + + (b&0x03030303UL)\ + + 0x02020202UL;\ + uint32_t h0= ((a&0xFCFCFCFCUL)>>2)\ + + ((b&0xFCFCFCFCUL)>>2);\ + uint32_t l1,h1;\ +\ + pixels+=line_size;\ + for(i=0; i>2)\ + + ((b&0xFCFCFCFCUL)>>2);\ + OP(*((uint32_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\ + pixels+=line_size;\ + block +=line_size;\ + a= AV_RN32(pixels );\ + b= AV_RN32(pixels+1);\ + l0= (a&0x03030303UL)\ + + (b&0x03030303UL)\ + + 0x02020202UL;\ + h0= ((a&0xFCFCFCFCUL)>>2)\ + + ((b&0xFCFCFCFCUL)>>2);\ + OP(*((uint32_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\ + pixels+=line_size;\ + block +=line_size;\ + }\ +}\ +\ +static inline void OPNAME ## _pixels8_xy2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h)\ +{\ + int j;\ + for(j=0; j<2; j++){\ + int i;\ + const uint32_t a= AV_RN32(pixels );\ + const uint32_t b= AV_RN32(pixels+1);\ + uint32_t l0= (a&0x03030303UL)\ + + (b&0x03030303UL)\ + + 0x02020202UL;\ + uint32_t h0= ((a&0xFCFCFCFCUL)>>2)\ + + ((b&0xFCFCFCFCUL)>>2);\ + uint32_t l1,h1;\ +\ + pixels+=line_size;\ + for(i=0; i>2)\ + + ((b&0xFCFCFCFCUL)>>2);\ + OP(*((uint32_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\ + pixels+=line_size;\ + block +=line_size;\ + a= AV_RN32(pixels );\ + b= AV_RN32(pixels+1);\ + l0= (a&0x03030303UL)\ + + (b&0x03030303UL)\ + + 0x02020202UL;\ + h0= ((a&0xFCFCFCFCUL)>>2)\ + + ((b&0xFCFCFCFCUL)>>2);\ + OP(*((uint32_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\ + pixels+=line_size;\ + block +=line_size;\ + }\ + pixels+=4-line_size*(h+1);\ + block +=4-line_size*h;\ + }\ +}\ +\ +static inline void OPNAME ## _no_rnd_pixels8_xy2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h)\ +{\ + int j;\ + for(j=0; j<2; j++){\ + int i;\ + const uint32_t a= AV_RN32(pixels );\ + const uint32_t b= AV_RN32(pixels+1);\ + uint32_t l0= (a&0x03030303UL)\ + + (b&0x03030303UL)\ + + 0x01010101UL;\ + uint32_t h0= ((a&0xFCFCFCFCUL)>>2)\ + + ((b&0xFCFCFCFCUL)>>2);\ + uint32_t l1,h1;\ +\ + pixels+=line_size;\ + for(i=0; i>2)\ + + ((b&0xFCFCFCFCUL)>>2);\ + OP(*((uint32_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\ + pixels+=line_size;\ + block +=line_size;\ + a= AV_RN32(pixels );\ + b= AV_RN32(pixels+1);\ + l0= (a&0x03030303UL)\ + + (b&0x03030303UL)\ + + 0x01010101UL;\ + h0= ((a&0xFCFCFCFCUL)>>2)\ + + ((b&0xFCFCFCFCUL)>>2);\ + OP(*((uint32_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\ + pixels+=line_size;\ + block +=line_size;\ + }\ + pixels+=4-line_size*(h+1);\ + block +=4-line_size*h;\ + }\ +}\ +\ +CALL_2X_PIXELS(OPNAME ## _pixels16_c , OPNAME ## _pixels8_c , 8)\ +CALL_2X_PIXELS(OPNAME ## _pixels16_x2_c , OPNAME ## _pixels8_x2_c , 8)\ +CALL_2X_PIXELS(OPNAME ## _pixels16_y2_c , OPNAME ## _pixels8_y2_c , 8)\ +CALL_2X_PIXELS(OPNAME ## _pixels16_xy2_c, OPNAME ## _pixels8_xy2_c, 8)\ +CALL_2X_PIXELS(OPNAME ## _no_rnd_pixels16_c , OPNAME ## _pixels8_c , 8)\ +CALL_2X_PIXELS(OPNAME ## _no_rnd_pixels16_x2_c , OPNAME ## _no_rnd_pixels8_x2_c , 8)\ +CALL_2X_PIXELS(OPNAME ## _no_rnd_pixels16_y2_c , OPNAME ## _no_rnd_pixels8_y2_c , 8)\ +CALL_2X_PIXELS(OPNAME ## _no_rnd_pixels16_xy2_c, OPNAME ## _no_rnd_pixels8_xy2_c, 8)\ + +#define op_avg(a, b) a = rnd_avg32(a, b) +#endif +#define op_put(a, b) a = b + +PIXOP2(avg, op_avg) +PIXOP2(put, op_put) +#undef op_avg +#undef op_put + +#define avg2(a,b) ((a+b+1)>>1) +#define avg4(a,b,c,d) ((a+b+c+d+2)>>2) + +static void put_no_rnd_pixels16_l2_c(uint8_t *dst, const uint8_t *a, const uint8_t *b, int stride, int h){ + put_no_rnd_pixels16_l2(dst, a, b, stride, stride, stride, h); +} + +static void put_no_rnd_pixels8_l2_c(uint8_t *dst, const uint8_t *a, const uint8_t *b, int stride, int h){ + put_no_rnd_pixels8_l2(dst, a, b, stride, stride, stride, h); +} + +static void gmc1_c(uint8_t *dst, uint8_t *src, int stride, int h, int x16, int y16, int rounder) +{ + const int A=(16-x16)*(16-y16); + const int B=( x16)*(16-y16); + const int C=(16-x16)*( y16); + const int D=( x16)*( y16); + int i; + + for(i=0; i>8; + dst[1]= (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2] + rounder)>>8; + dst[2]= (A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3] + rounder)>>8; + dst[3]= (A*src[3] + B*src[4] + C*src[stride+3] + D*src[stride+4] + rounder)>>8; + dst[4]= (A*src[4] + B*src[5] + C*src[stride+4] + D*src[stride+5] + rounder)>>8; + dst[5]= (A*src[5] + B*src[6] + C*src[stride+5] + D*src[stride+6] + rounder)>>8; + dst[6]= (A*src[6] + B*src[7] + C*src[stride+6] + D*src[stride+7] + rounder)>>8; + dst[7]= (A*src[7] + B*src[8] + C*src[stride+7] + D*src[stride+8] + rounder)>>8; + dst+= stride; + src+= stride; + } +} + +void ff_gmc_c(uint8_t *dst, uint8_t *src, int stride, int h, int ox, int oy, + int dxx, int dxy, int dyx, int dyy, int shift, int r, int width, int height) +{ + int y, vx, vy; + const int s= 1<>16; + src_y= vy>>16; + frac_x= src_x&(s-1); + frac_y= src_y&(s-1); + src_x>>=shift; + src_y>>=shift; + + if((unsigned)src_x < width){ + if((unsigned)src_y < height){ + index= src_x + src_y*stride; + dst[y*stride + x]= ( ( src[index ]*(s-frac_x) + + src[index +1]* frac_x )*(s-frac_y) + + ( src[index+stride ]*(s-frac_x) + + src[index+stride+1]* frac_x )* frac_y + + r)>>(shift*2); + }else{ + index= src_x + av_clip(src_y, 0, height)*stride; + dst[y*stride + x]= ( ( src[index ]*(s-frac_x) + + src[index +1]* frac_x )*s + + r)>>(shift*2); + } + }else{ + if((unsigned)src_y < height){ + index= av_clip(src_x, 0, width) + src_y*stride; + dst[y*stride + x]= ( ( src[index ]*(s-frac_y) + + src[index+stride ]* frac_y )*s + + r)>>(shift*2); + }else{ + index= av_clip(src_x, 0, width) + av_clip(src_y, 0, height)*stride; + dst[y*stride + x]= src[index ]; + } + } + + vx+= dxx; + vy+= dyx; + } + ox += dxy; + oy += dyy; + } +} + +static inline void put_tpel_pixels_mc00_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ + switch(width){ + case 2: put_pixels2_c (dst, src, stride, height); break; + case 4: put_pixels4_c (dst, src, stride, height); break; + case 8: put_pixels8_c (dst, src, stride, height); break; + case 16:put_pixels16_c(dst, src, stride, height); break; + } +} + +static inline void put_tpel_pixels_mc10_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ + int i,j; + for (i=0; i < height; i++) { + for (j=0; j < width; j++) { + dst[j] = (683*(2*src[j] + src[j+1] + 1)) >> 11; + } + src += stride; + dst += stride; + } +} + +static inline void put_tpel_pixels_mc20_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ + int i,j; + for (i=0; i < height; i++) { + for (j=0; j < width; j++) { + dst[j] = (683*(src[j] + 2*src[j+1] + 1)) >> 11; + } + src += stride; + dst += stride; + } +} + +static inline void put_tpel_pixels_mc01_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ + int i,j; + for (i=0; i < height; i++) { + for (j=0; j < width; j++) { + dst[j] = (683*(2*src[j] + src[j+stride] + 1)) >> 11; + } + src += stride; + dst += stride; + } +} + +static inline void put_tpel_pixels_mc11_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ + int i,j; + for (i=0; i < height; i++) { + for (j=0; j < width; j++) { + dst[j] = (2731*(4*src[j] + 3*src[j+1] + 3*src[j+stride] + 2*src[j+stride+1] + 6)) >> 15; + } + src += stride; + dst += stride; + } +} + +static inline void put_tpel_pixels_mc12_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ + int i,j; + for (i=0; i < height; i++) { + for (j=0; j < width; j++) { + dst[j] = (2731*(3*src[j] + 2*src[j+1] + 4*src[j+stride] + 3*src[j+stride+1] + 6)) >> 15; + } + src += stride; + dst += stride; + } +} + +static inline void put_tpel_pixels_mc02_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ + int i,j; + for (i=0; i < height; i++) { + for (j=0; j < width; j++) { + dst[j] = (683*(src[j] + 2*src[j+stride] + 1)) >> 11; + } + src += stride; + dst += stride; + } +} + +static inline void put_tpel_pixels_mc21_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ + int i,j; + for (i=0; i < height; i++) { + for (j=0; j < width; j++) { + dst[j] = (2731*(3*src[j] + 4*src[j+1] + 2*src[j+stride] + 3*src[j+stride+1] + 6)) >> 15; + } + src += stride; + dst += stride; + } +} + +static inline void put_tpel_pixels_mc22_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ + int i,j; + for (i=0; i < height; i++) { + for (j=0; j < width; j++) { + dst[j] = (2731*(2*src[j] + 3*src[j+1] + 3*src[j+stride] + 4*src[j+stride+1] + 6)) >> 15; + } + src += stride; + dst += stride; + } +} + +static inline void avg_tpel_pixels_mc00_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ + switch(width){ + case 2: avg_pixels2_c (dst, src, stride, height); break; + case 4: avg_pixels4_c (dst, src, stride, height); break; + case 8: avg_pixels8_c (dst, src, stride, height); break; + case 16:avg_pixels16_c(dst, src, stride, height); break; + } +} + +static inline void avg_tpel_pixels_mc10_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ + int i,j; + for (i=0; i < height; i++) { + for (j=0; j < width; j++) { + dst[j] = (dst[j] + ((683*(2*src[j] + src[j+1] + 1)) >> 11) + 1) >> 1; + } + src += stride; + dst += stride; + } +} + +static inline void avg_tpel_pixels_mc20_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ + int i,j; + for (i=0; i < height; i++) { + for (j=0; j < width; j++) { + dst[j] = (dst[j] + ((683*(src[j] + 2*src[j+1] + 1)) >> 11) + 1) >> 1; + } + src += stride; + dst += stride; + } +} + +static inline void avg_tpel_pixels_mc01_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ + int i,j; + for (i=0; i < height; i++) { + for (j=0; j < width; j++) { + dst[j] = (dst[j] + ((683*(2*src[j] + src[j+stride] + 1)) >> 11) + 1) >> 1; + } + src += stride; + dst += stride; + } +} + +static inline void avg_tpel_pixels_mc11_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ + int i,j; + for (i=0; i < height; i++) { + for (j=0; j < width; j++) { + dst[j] = (dst[j] + ((2731*(4*src[j] + 3*src[j+1] + 3*src[j+stride] + 2*src[j+stride+1] + 6)) >> 15) + 1) >> 1; + } + src += stride; + dst += stride; + } +} + +static inline void avg_tpel_pixels_mc12_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ + int i,j; + for (i=0; i < height; i++) { + for (j=0; j < width; j++) { + dst[j] = (dst[j] + ((2731*(3*src[j] + 2*src[j+1] + 4*src[j+stride] + 3*src[j+stride+1] + 6)) >> 15) + 1) >> 1; + } + src += stride; + dst += stride; + } +} + +static inline void avg_tpel_pixels_mc02_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ + int i,j; + for (i=0; i < height; i++) { + for (j=0; j < width; j++) { + dst[j] = (dst[j] + ((683*(src[j] + 2*src[j+stride] + 1)) >> 11) + 1) >> 1; + } + src += stride; + dst += stride; + } +} + +static inline void avg_tpel_pixels_mc21_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ + int i,j; + for (i=0; i < height; i++) { + for (j=0; j < width; j++) { + dst[j] = (dst[j] + ((2731*(3*src[j] + 4*src[j+1] + 2*src[j+stride] + 3*src[j+stride+1] + 6)) >> 15) + 1) >> 1; + } + src += stride; + dst += stride; + } +} + +static inline void avg_tpel_pixels_mc22_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ + int i,j; + for (i=0; i < height; i++) { + for (j=0; j < width; j++) { + dst[j] = (dst[j] + ((2731*(2*src[j] + 3*src[j+1] + 3*src[j+stride] + 4*src[j+stride+1] + 6)) >> 15) + 1) >> 1; + } + src += stride; + dst += stride; + } +} +#if 0 +#define TPEL_WIDTH(width)\ +static void put_tpel_pixels ## width ## _mc00_c(uint8_t *dst, const uint8_t *src, int stride, int height){\ + void put_tpel_pixels_mc00_c(dst, src, stride, width, height);}\ +static void put_tpel_pixels ## width ## _mc10_c(uint8_t *dst, const uint8_t *src, int stride, int height){\ + void put_tpel_pixels_mc10_c(dst, src, stride, width, height);}\ +static void put_tpel_pixels ## width ## _mc20_c(uint8_t *dst, const uint8_t *src, int stride, int height){\ + void put_tpel_pixels_mc20_c(dst, src, stride, width, height);}\ +static void put_tpel_pixels ## width ## _mc01_c(uint8_t *dst, const uint8_t *src, int stride, int height){\ + void put_tpel_pixels_mc01_c(dst, src, stride, width, height);}\ +static void put_tpel_pixels ## width ## _mc11_c(uint8_t *dst, const uint8_t *src, int stride, int height){\ + void put_tpel_pixels_mc11_c(dst, src, stride, width, height);}\ +static void put_tpel_pixels ## width ## _mc21_c(uint8_t *dst, const uint8_t *src, int stride, int height){\ + void put_tpel_pixels_mc21_c(dst, src, stride, width, height);}\ +static void put_tpel_pixels ## width ## _mc02_c(uint8_t *dst, const uint8_t *src, int stride, int height){\ + void put_tpel_pixels_mc02_c(dst, src, stride, width, height);}\ +static void put_tpel_pixels ## width ## _mc12_c(uint8_t *dst, const uint8_t *src, int stride, int height){\ + void put_tpel_pixels_mc12_c(dst, src, stride, width, height);}\ +static void put_tpel_pixels ## width ## _mc22_c(uint8_t *dst, const uint8_t *src, int stride, int height){\ + void put_tpel_pixels_mc22_c(dst, src, stride, width, height);} +#endif + +#define H264_CHROMA_MC(OPNAME, OP)\ +static void OPNAME ## h264_chroma_mc2_c(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y){\ + const int A=(8-x)*(8-y);\ + const int B=( x)*(8-y);\ + const int C=(8-x)*( y);\ + const int D=( x)*( y);\ + int i;\ + \ + assert(x<8 && y<8 && x>=0 && y>=0);\ +\ + if(D){\ + for(i=0; i=0 && y>=0);\ +\ + if(D){\ + for(i=0; i=0 && y>=0);\ +\ + if(D){\ + for(i=0; i>6)+1)>>1) +#define op_put(a, b) a = (((b) + 32)>>6) + +H264_CHROMA_MC(put_ , op_put) +H264_CHROMA_MC(avg_ , op_avg) +#undef op_avg +#undef op_put + +static void put_no_rnd_h264_chroma_mc8_c(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y){ + const int A=(8-x)*(8-y); + const int B=( x)*(8-y); + const int C=(8-x)*( y); + const int D=( x)*( y); + int i; + + assert(x<8 && y<8 && x>=0 && y>=0); + + for(i=0; i> 6; + dst[1] = (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2] + 32 - 4) >> 6; + dst[2] = (A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3] + 32 - 4) >> 6; + dst[3] = (A*src[3] + B*src[4] + C*src[stride+3] + D*src[stride+4] + 32 - 4) >> 6; + dst[4] = (A*src[4] + B*src[5] + C*src[stride+4] + D*src[stride+5] + 32 - 4) >> 6; + dst[5] = (A*src[5] + B*src[6] + C*src[stride+5] + D*src[stride+6] + 32 - 4) >> 6; + dst[6] = (A*src[6] + B*src[7] + C*src[stride+6] + D*src[stride+7] + 32 - 4) >> 6; + dst[7] = (A*src[7] + B*src[8] + C*src[stride+7] + D*src[stride+8] + 32 - 4) >> 6; + dst+= stride; + src+= stride; + } +} + +#define QPEL_MC(r, OPNAME, RND, OP) \ +static void OPNAME ## mpeg4_qpel8_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h){\ + uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ + int i;\ + for(i=0; i>5]+1)>>1) +#define op_avg_no_rnd(a, b) a = (((a)+cm[((b) + 15)>>5])>>1) +#define op_put(a, b) a = cm[((b) + 16)>>5] +#define op_put_no_rnd(a, b) a = cm[((b) + 15)>>5] + +QPEL_MC(0, put_ , _ , op_put) +QPEL_MC(1, put_no_rnd_, _no_rnd_, op_put_no_rnd) +QPEL_MC(0, avg_ , _ , op_avg) +//QPEL_MC(1, avg_no_rnd , _ , op_avg) +#undef op_avg +#undef op_avg_no_rnd +#undef op_put +#undef op_put_no_rnd + +#if 1 +#define H264_LOWPASS(OPNAME, OP, OP2) \ +static av_unused void OPNAME ## h264_qpel2_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ + const int h=2;\ + uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ + int i;\ + for(i=0; i>5]+1)>>1) +//#define op_avg2(a, b) a = (((a)*w1+cm[((b) + 16)>>5]*w2 + o + 64)>>7) +#define op_put(a, b) a = cm[((b) + 16)>>5] +#define op2_avg(a, b) a = (((a)+cm[((b) + 512)>>10]+1)>>1) +#define op2_put(a, b) a = cm[((b) + 512)>>10] + +H264_LOWPASS(put_ , op_put, op2_put) +H264_LOWPASS(avg_ , op_avg, op2_avg) +H264_MC(put_, 2) +H264_MC(put_, 4) +H264_MC(put_, 8) +H264_MC(put_, 16) +H264_MC(avg_, 4) +H264_MC(avg_, 8) +H264_MC(avg_, 16) + +#undef op_avg +#undef op_put +#undef op2_avg +#undef op2_put +#endif + +#define op_scale1(x) block[x] = av_clip_uint8( (block[x]*weight + offset) >> log2_denom ) +#define op_scale2(x) dst[x] = av_clip_uint8( (src[x]*weights + dst[x]*weightd + offset) >> (log2_denom+1)) +#define H264_WEIGHT(W,H) \ +static void weight_h264_pixels ## W ## x ## H ## _c(uint8_t *block, int stride, int log2_denom, int weight, int offset){ \ + int y; \ + offset <<= log2_denom; \ + if(log2_denom) offset += 1<<(log2_denom-1); \ + for(y=0; y>4]; + dst[1]= cm[(9*(src[1] + src[2]) - (src[ 0] + src[3]) + 8)>>4]; + dst[2]= cm[(9*(src[2] + src[3]) - (src[ 1] + src[4]) + 8)>>4]; + dst[3]= cm[(9*(src[3] + src[4]) - (src[ 2] + src[5]) + 8)>>4]; + dst[4]= cm[(9*(src[4] + src[5]) - (src[ 3] + src[6]) + 8)>>4]; + dst[5]= cm[(9*(src[5] + src[6]) - (src[ 4] + src[7]) + 8)>>4]; + dst[6]= cm[(9*(src[6] + src[7]) - (src[ 5] + src[8]) + 8)>>4]; + dst[7]= cm[(9*(src[7] + src[8]) - (src[ 6] + src[9]) + 8)>>4]; + dst+=dstStride; + src+=srcStride; + } +} + +#if CONFIG_CAVS_DECODER +/* AVS specific */ +void ff_cavsdsp_init(DSPContext* c, AVCodecContext *avctx); + +void ff_put_cavs_qpel8_mc00_c(uint8_t *dst, uint8_t *src, int stride) { + put_pixels8_c(dst, src, stride, 8); +} +void ff_avg_cavs_qpel8_mc00_c(uint8_t *dst, uint8_t *src, int stride) { + avg_pixels8_c(dst, src, stride, 8); +} +void ff_put_cavs_qpel16_mc00_c(uint8_t *dst, uint8_t *src, int stride) { + put_pixels16_c(dst, src, stride, 16); +} +void ff_avg_cavs_qpel16_mc00_c(uint8_t *dst, uint8_t *src, int stride) { + avg_pixels16_c(dst, src, stride, 16); +} +#endif /* CONFIG_CAVS_DECODER */ + +#if CONFIG_VC1_DECODER || CONFIG_WMV3_DECODER +/* VC-1 specific */ +void ff_vc1dsp_init(DSPContext* c, AVCodecContext *avctx); + +void ff_put_vc1_mspel_mc00_c(uint8_t *dst, uint8_t *src, int stride, int rnd) { + put_pixels8_c(dst, src, stride, 8); +} +#endif /* CONFIG_VC1_DECODER||CONFIG_WMV3_DECODER */ + +void ff_intrax8dsp_init(DSPContext* c, AVCodecContext *avctx); + +/* H264 specific */ +void ff_h264dspenc_init(DSPContext* c, AVCodecContext *avctx); + +#if CONFIG_RV30_DECODER +void ff_rv30dsp_init(DSPContext* c, AVCodecContext *avctx); +#endif /* CONFIG_RV30_DECODER */ + +#if CONFIG_RV40_DECODER +static void put_rv40_qpel16_mc33_c(uint8_t *dst, uint8_t *src, int stride){ + put_pixels16_xy2_c(dst, src, stride, 16); +} +static void avg_rv40_qpel16_mc33_c(uint8_t *dst, uint8_t *src, int stride){ + avg_pixels16_xy2_c(dst, src, stride, 16); +} +static void put_rv40_qpel8_mc33_c(uint8_t *dst, uint8_t *src, int stride){ + put_pixels8_xy2_c(dst, src, stride, 8); +} +static void avg_rv40_qpel8_mc33_c(uint8_t *dst, uint8_t *src, int stride){ + avg_pixels8_xy2_c(dst, src, stride, 8); +} + +void ff_rv40dsp_init(DSPContext* c, AVCodecContext *avctx); +#endif /* CONFIG_RV40_DECODER */ + +static void wmv2_mspel8_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int w){ + uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; + int i; + + for(i=0; i>4]; + dst[1*dstStride]= cm[(9*(src1 + src2) - (src0 + src3) + 8)>>4]; + dst[2*dstStride]= cm[(9*(src2 + src3) - (src1 + src4) + 8)>>4]; + dst[3*dstStride]= cm[(9*(src3 + src4) - (src2 + src5) + 8)>>4]; + dst[4*dstStride]= cm[(9*(src4 + src5) - (src3 + src6) + 8)>>4]; + dst[5*dstStride]= cm[(9*(src5 + src6) - (src4 + src7) + 8)>>4]; + dst[6*dstStride]= cm[(9*(src6 + src7) - (src5 + src8) + 8)>>4]; + dst[7*dstStride]= cm[(9*(src7 + src8) - (src6 + src9) + 8)>>4]; + src++; + dst++; + } +} + +static void put_mspel8_mc00_c (uint8_t *dst, uint8_t *src, int stride){ + put_pixels8_c(dst, src, stride, 8); +} + +static void put_mspel8_mc10_c(uint8_t *dst, uint8_t *src, int stride){ + uint8_t half[64]; + wmv2_mspel8_h_lowpass(half, src, 8, stride, 8); + put_pixels8_l2(dst, src, half, stride, stride, 8, 8); +} + +static void put_mspel8_mc20_c(uint8_t *dst, uint8_t *src, int stride){ + wmv2_mspel8_h_lowpass(dst, src, stride, stride, 8); +} + +static void put_mspel8_mc30_c(uint8_t *dst, uint8_t *src, int stride){ + uint8_t half[64]; + wmv2_mspel8_h_lowpass(half, src, 8, stride, 8); + put_pixels8_l2(dst, src+1, half, stride, stride, 8, 8); +} + +static void put_mspel8_mc02_c(uint8_t *dst, uint8_t *src, int stride){ + wmv2_mspel8_v_lowpass(dst, src, stride, stride, 8); +} + +static void put_mspel8_mc12_c(uint8_t *dst, uint8_t *src, int stride){ + uint8_t halfH[88]; + uint8_t halfV[64]; + uint8_t halfHV[64]; + wmv2_mspel8_h_lowpass(halfH, src-stride, 8, stride, 11); + wmv2_mspel8_v_lowpass(halfV, src, 8, stride, 8); + wmv2_mspel8_v_lowpass(halfHV, halfH+8, 8, 8, 8); + put_pixels8_l2(dst, halfV, halfHV, stride, 8, 8, 8); +} +static void put_mspel8_mc32_c(uint8_t *dst, uint8_t *src, int stride){ + uint8_t halfH[88]; + uint8_t halfV[64]; + uint8_t halfHV[64]; + wmv2_mspel8_h_lowpass(halfH, src-stride, 8, stride, 11); + wmv2_mspel8_v_lowpass(halfV, src+1, 8, stride, 8); + wmv2_mspel8_v_lowpass(halfHV, halfH+8, 8, 8, 8); + put_pixels8_l2(dst, halfV, halfHV, stride, 8, 8, 8); +} +static void put_mspel8_mc22_c(uint8_t *dst, uint8_t *src, int stride){ + uint8_t halfH[88]; + wmv2_mspel8_h_lowpass(halfH, src-stride, 8, stride, 11); + wmv2_mspel8_v_lowpass(dst, halfH+8, stride, 8, 8); +} + +static void h263_v_loop_filter_c(uint8_t *src, int stride, int qscale){ + if(CONFIG_ANY_H263) { + int x; + const int strength= ff_h263_loop_filter_strength[qscale]; + + for(x=0; x<8; x++){ + int d1, d2, ad1; + int p0= src[x-2*stride]; + int p1= src[x-1*stride]; + int p2= src[x+0*stride]; + int p3= src[x+1*stride]; + int d = (p0 - p3 + 4*(p2 - p1)) / 8; + + if (d<-2*strength) d1= 0; + else if(d<- strength) d1=-2*strength - d; + else if(d< strength) d1= d; + else if(d< 2*strength) d1= 2*strength - d; + else d1= 0; + + p1 += d1; + p2 -= d1; + if(p1&256) p1= ~(p1>>31); + if(p2&256) p2= ~(p2>>31); + + src[x-1*stride] = p1; + src[x+0*stride] = p2; + + ad1= FFABS(d1)>>1; + + d2= av_clip((p0-p3)/4, -ad1, ad1); + + src[x-2*stride] = p0 - d2; + src[x+ stride] = p3 + d2; + } + } +} + +static void h263_h_loop_filter_c(uint8_t *src, int stride, int qscale){ + if(CONFIG_ANY_H263) { + int y; + const int strength= ff_h263_loop_filter_strength[qscale]; + + for(y=0; y<8; y++){ + int d1, d2, ad1; + int p0= src[y*stride-2]; + int p1= src[y*stride-1]; + int p2= src[y*stride+0]; + int p3= src[y*stride+1]; + int d = (p0 - p3 + 4*(p2 - p1)) / 8; + + if (d<-2*strength) d1= 0; + else if(d<- strength) d1=-2*strength - d; + else if(d< strength) d1= d; + else if(d< 2*strength) d1= 2*strength - d; + else d1= 0; + + p1 += d1; + p2 -= d1; + if(p1&256) p1= ~(p1>>31); + if(p2&256) p2= ~(p2>>31); + + src[y*stride-1] = p1; + src[y*stride+0] = p2; + + ad1= FFABS(d1)>>1; + + d2= av_clip((p0-p3)/4, -ad1, ad1); + + src[y*stride-2] = p0 - d2; + src[y*stride+1] = p3 + d2; + } + } +} + +static void h261_loop_filter_c(uint8_t *src, int stride){ + int x,y,xy,yz; + int temp[64]; + + for(x=0; x<8; x++){ + temp[x ] = 4*src[x ]; + temp[x + 7*8] = 4*src[x + 7*stride]; + } + for(y=1; y<7; y++){ + for(x=0; x<8; x++){ + xy = y * stride + x; + yz = y * 8 + x; + temp[yz] = src[xy - stride] + 2*src[xy] + src[xy + stride]; + } + } + + for(y=0; y<8; y++){ + src[ y*stride] = (temp[ y*8] + 2)>>2; + src[7+y*stride] = (temp[7+y*8] + 2)>>2; + for(x=1; x<7; x++){ + xy = y * stride + x; + yz = y * 8 + x; + src[xy] = (temp[yz-1] + 2*temp[yz] + temp[yz+1] + 8)>>4; + } + } +} + +static inline void h264_loop_filter_luma_c(uint8_t *pix, int xstride, int ystride, int alpha, int beta, int8_t *tc0) +{ + int i, d; + for( i = 0; i < 4; i++ ) { + if( tc0[i] < 0 ) { + pix += 4*ystride; + continue; + } + for( d = 0; d < 4; d++ ) { + const int p0 = pix[-1*xstride]; + const int p1 = pix[-2*xstride]; + const int p2 = pix[-3*xstride]; + const int q0 = pix[0]; + const int q1 = pix[1*xstride]; + const int q2 = pix[2*xstride]; + + if( FFABS( p0 - q0 ) < alpha && + FFABS( p1 - p0 ) < beta && + FFABS( q1 - q0 ) < beta ) { + + int tc = tc0[i]; + int i_delta; + + if( FFABS( p2 - p0 ) < beta ) { + pix[-2*xstride] = p1 + av_clip( (( p2 + ( ( p0 + q0 + 1 ) >> 1 ) ) >> 1) - p1, -tc0[i], tc0[i] ); + tc++; + } + if( FFABS( q2 - q0 ) < beta ) { + pix[ xstride] = q1 + av_clip( (( q2 + ( ( p0 + q0 + 1 ) >> 1 ) ) >> 1) - q1, -tc0[i], tc0[i] ); + tc++; + } + + i_delta = av_clip( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc ); + pix[-xstride] = av_clip_uint8( p0 + i_delta ); /* p0' */ + pix[0] = av_clip_uint8( q0 - i_delta ); /* q0' */ + } + pix += ystride; + } + } +} +static void h264_v_loop_filter_luma_c(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0) +{ + h264_loop_filter_luma_c(pix, stride, 1, alpha, beta, tc0); +} +static void h264_h_loop_filter_luma_c(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0) +{ + h264_loop_filter_luma_c(pix, 1, stride, alpha, beta, tc0); +} + +static inline void h264_loop_filter_luma_intra_c(uint8_t *pix, int xstride, int ystride, int alpha, int beta) +{ + int d; + for( d = 0; d < 16; d++ ) { + const int p2 = pix[-3*xstride]; + const int p1 = pix[-2*xstride]; + const int p0 = pix[-1*xstride]; + + const int q0 = pix[ 0*xstride]; + const int q1 = pix[ 1*xstride]; + const int q2 = pix[ 2*xstride]; + + if( FFABS( p0 - q0 ) < alpha && + FFABS( p1 - p0 ) < beta && + FFABS( q1 - q0 ) < beta ) { + + if(FFABS( p0 - q0 ) < (( alpha >> 2 ) + 2 )){ + if( FFABS( p2 - p0 ) < beta) + { + const int p3 = pix[-4*xstride]; + /* p0', p1', p2' */ + pix[-1*xstride] = ( p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4 ) >> 3; + pix[-2*xstride] = ( p2 + p1 + p0 + q0 + 2 ) >> 2; + pix[-3*xstride] = ( 2*p3 + 3*p2 + p1 + p0 + q0 + 4 ) >> 3; + } else { + /* p0' */ + pix[-1*xstride] = ( 2*p1 + p0 + q1 + 2 ) >> 2; + } + if( FFABS( q2 - q0 ) < beta) + { + const int q3 = pix[3*xstride]; + /* q0', q1', q2' */ + pix[0*xstride] = ( p1 + 2*p0 + 2*q0 + 2*q1 + q2 + 4 ) >> 3; + pix[1*xstride] = ( p0 + q0 + q1 + q2 + 2 ) >> 2; + pix[2*xstride] = ( 2*q3 + 3*q2 + q1 + q0 + p0 + 4 ) >> 3; + } else { + /* q0' */ + pix[0*xstride] = ( 2*q1 + q0 + p1 + 2 ) >> 2; + } + }else{ + /* p0', q0' */ + pix[-1*xstride] = ( 2*p1 + p0 + q1 + 2 ) >> 2; + pix[ 0*xstride] = ( 2*q1 + q0 + p1 + 2 ) >> 2; + } + } + pix += ystride; + } +} +static void h264_v_loop_filter_luma_intra_c(uint8_t *pix, int stride, int alpha, int beta) +{ + h264_loop_filter_luma_intra_c(pix, stride, 1, alpha, beta); +} +static void h264_h_loop_filter_luma_intra_c(uint8_t *pix, int stride, int alpha, int beta) +{ + h264_loop_filter_luma_intra_c(pix, 1, stride, alpha, beta); +} + +static inline void h264_loop_filter_chroma_c(uint8_t *pix, int xstride, int ystride, int alpha, int beta, int8_t *tc0) +{ + int i, d; + for( i = 0; i < 4; i++ ) { + const int tc = tc0[i]; + if( tc <= 0 ) { + pix += 2*ystride; + continue; + } + for( d = 0; d < 2; d++ ) { + const int p0 = pix[-1*xstride]; + const int p1 = pix[-2*xstride]; + const int q0 = pix[0]; + const int q1 = pix[1*xstride]; + + if( FFABS( p0 - q0 ) < alpha && + FFABS( p1 - p0 ) < beta && + FFABS( q1 - q0 ) < beta ) { + + int delta = av_clip( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc ); + + pix[-xstride] = av_clip_uint8( p0 + delta ); /* p0' */ + pix[0] = av_clip_uint8( q0 - delta ); /* q0' */ + } + pix += ystride; + } + } +} +static void h264_v_loop_filter_chroma_c(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0) +{ + h264_loop_filter_chroma_c(pix, stride, 1, alpha, beta, tc0); +} +static void h264_h_loop_filter_chroma_c(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0) +{ + h264_loop_filter_chroma_c(pix, 1, stride, alpha, beta, tc0); +} + +static inline void h264_loop_filter_chroma_intra_c(uint8_t *pix, int xstride, int ystride, int alpha, int beta) +{ + int d; + for( d = 0; d < 8; d++ ) { + const int p0 = pix[-1*xstride]; + const int p1 = pix[-2*xstride]; + const int q0 = pix[0]; + const int q1 = pix[1*xstride]; + + if( FFABS( p0 - q0 ) < alpha && + FFABS( p1 - p0 ) < beta && + FFABS( q1 - q0 ) < beta ) { + + pix[-xstride] = ( 2*p1 + p0 + q1 + 2 ) >> 2; /* p0' */ + pix[0] = ( 2*q1 + q0 + p1 + 2 ) >> 2; /* q0' */ + } + pix += ystride; + } +} +static void h264_v_loop_filter_chroma_intra_c(uint8_t *pix, int stride, int alpha, int beta) +{ + h264_loop_filter_chroma_intra_c(pix, stride, 1, alpha, beta); +} +static void h264_h_loop_filter_chroma_intra_c(uint8_t *pix, int stride, int alpha, int beta) +{ + h264_loop_filter_chroma_intra_c(pix, 1, stride, alpha, beta); +} + +static inline int pix_abs16_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) +{ + int s, i; + + s = 0; + for(i=0;iavctx->nsse_weight; + else return score1 + FFABS(score2)*8; +} + +static int nsse8_c(void *v, uint8_t *s1, uint8_t *s2, int stride, int h){ + MpegEncContext *c = v; + int score1=0; + int score2=0; + int x,y; + + for(y=0; yavctx->nsse_weight; + else return score1 + FFABS(score2)*8; +} + +static int try_8x8basis_c(int16_t rem[64], int16_t weight[64], int16_t basis[64], int scale){ + int i; + unsigned int sum=0; + + for(i=0; i<8*8; i++){ + int b= rem[i] + ((basis[i]*scale + (1<<(BASIS_SHIFT - RECON_SHIFT-1)))>>(BASIS_SHIFT - RECON_SHIFT)); + int w= weight[i]; + b>>= RECON_SHIFT; + assert(-512>4; + } + return sum>>2; +} + +static void add_8x8basis_c(int16_t rem[64], int16_t basis[64], int scale){ + int i; + + for(i=0; i<8*8; i++){ + rem[i] += (basis[i]*scale + (1<<(BASIS_SHIFT - RECON_SHIFT-1)))>>(BASIS_SHIFT - RECON_SHIFT); + } +} + +/** + * permutes an 8x8 block. + * @param block the block which will be permuted according to the given permutation vector + * @param permutation the permutation vector + * @param last the last non zero coefficient in scantable order, used to speed the permutation up + * @param scantable the used scantable, this is only used to speed the permutation up, the block is not + * (inverse) permutated to scantable order! + */ +void ff_block_permute(DCTELEM *block, uint8_t *permutation, const uint8_t *scantable, int last) +{ + int i; + DCTELEM temp[64]; + + if(last<=0) return; + //if(permutation[1]==1) return; //FIXME it is ok but not clean and might fail for some permutations + + for(i=0; i<=last; i++){ + const int j= scantable[i]; + temp[j]= block[j]; + block[j]=0; + } + + for(i=0; i<=last; i++){ + const int j= scantable[i]; + const int perm_j= permutation[j]; + block[perm_j]= temp[j]; + } +} + +static int zero_cmp(void *s, uint8_t *a, uint8_t *b, int stride, int h){ + return 0; +} + +void ff_set_cmp(DSPContext* c, me_cmp_func *cmp, int type){ + int i; + + memset(cmp, 0, sizeof(void*)*6); + + for(i=0; i<6; i++){ + switch(type&0xFF){ + case FF_CMP_SAD: + cmp[i]= c->sad[i]; + break; + case FF_CMP_SATD: + cmp[i]= c->hadamard8_diff[i]; + break; + case FF_CMP_SSE: + cmp[i]= c->sse[i]; + break; + case FF_CMP_DCT: + cmp[i]= c->dct_sad[i]; + break; + case FF_CMP_DCT264: + cmp[i]= c->dct264_sad[i]; + break; + case FF_CMP_DCTMAX: + cmp[i]= c->dct_max[i]; + break; + case FF_CMP_PSNR: + cmp[i]= c->quant_psnr[i]; + break; + case FF_CMP_BIT: + cmp[i]= c->bit[i]; + break; + case FF_CMP_RD: + cmp[i]= c->rd[i]; + break; + case FF_CMP_VSAD: + cmp[i]= c->vsad[i]; + break; + case FF_CMP_VSSE: + cmp[i]= c->vsse[i]; + break; + case FF_CMP_ZERO: + cmp[i]= zero_cmp; + break; + case FF_CMP_NSSE: + cmp[i]= c->nsse[i]; + break; +#if CONFIG_SNOW_ENCODER + case FF_CMP_W53: + cmp[i]= c->w53[i]; + break; + case FF_CMP_W97: + cmp[i]= c->w97[i]; + break; +#endif + default: + av_log(NULL, AV_LOG_ERROR,"internal error in cmp function selection\n"); + } + } +} + +static void clear_block_c(DCTELEM *block) +{ + memset(block, 0, sizeof(DCTELEM)*64); +} + +/** + * memset(blocks, 0, sizeof(DCTELEM)*6*64) + */ +static void clear_blocks_c(DCTELEM *blocks) +{ + memset(blocks, 0, sizeof(DCTELEM)*6*64); +} + +static void add_bytes_c(uint8_t *dst, uint8_t *src, int w){ + long i; + for(i=0; i<=w-sizeof(long); i+=sizeof(long)){ + long a = *(long*)(src+i); + long b = *(long*)(dst+i); + *(long*)(dst+i) = ((a&pb_7f) + (b&pb_7f)) ^ ((a^b)&pb_80); + } + for(; imaxi){ + maxi=sum; + printf("MAX:%d\n", maxi); +} +#endif + return sum; +} + +static int hadamard8_intra8x8_c(/*MpegEncContext*/ void *s, uint8_t *src, uint8_t *dummy, int stride, int h){ + int i; + int temp[64]; + int sum=0; + + assert(h==8); + + for(i=0; i<8; i++){ + //FIXME try pointer walks + BUTTERFLY2(temp[8*i+0], temp[8*i+1], src[stride*i+0],src[stride*i+1]); + BUTTERFLY2(temp[8*i+2], temp[8*i+3], src[stride*i+2],src[stride*i+3]); + BUTTERFLY2(temp[8*i+4], temp[8*i+5], src[stride*i+4],src[stride*i+5]); + BUTTERFLY2(temp[8*i+6], temp[8*i+7], src[stride*i+6],src[stride*i+7]); + + BUTTERFLY1(temp[8*i+0], temp[8*i+2]); + BUTTERFLY1(temp[8*i+1], temp[8*i+3]); + BUTTERFLY1(temp[8*i+4], temp[8*i+6]); + BUTTERFLY1(temp[8*i+5], temp[8*i+7]); + + BUTTERFLY1(temp[8*i+0], temp[8*i+4]); + BUTTERFLY1(temp[8*i+1], temp[8*i+5]); + BUTTERFLY1(temp[8*i+2], temp[8*i+6]); + BUTTERFLY1(temp[8*i+3], temp[8*i+7]); + } + + for(i=0; i<8; i++){ + BUTTERFLY1(temp[8*0+i], temp[8*1+i]); + BUTTERFLY1(temp[8*2+i], temp[8*3+i]); + BUTTERFLY1(temp[8*4+i], temp[8*5+i]); + BUTTERFLY1(temp[8*6+i], temp[8*7+i]); + + BUTTERFLY1(temp[8*0+i], temp[8*2+i]); + BUTTERFLY1(temp[8*1+i], temp[8*3+i]); + BUTTERFLY1(temp[8*4+i], temp[8*6+i]); + BUTTERFLY1(temp[8*5+i], temp[8*7+i]); + + sum += + BUTTERFLYA(temp[8*0+i], temp[8*4+i]) + +BUTTERFLYA(temp[8*1+i], temp[8*5+i]) + +BUTTERFLYA(temp[8*2+i], temp[8*6+i]) + +BUTTERFLYA(temp[8*3+i], temp[8*7+i]); + } + + sum -= FFABS(temp[8*0] + temp[8*4]); // -mean + + return sum; +} + +static int dct_sad8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){ + MpegEncContext * const s= (MpegEncContext *)c; + DECLARE_ALIGNED_16(uint64_t, aligned_temp[sizeof(DCTELEM)*64/8]); + DCTELEM * const temp= (DCTELEM*)aligned_temp; + + assert(h==8); + + s->dsp.diff_pixels(temp, src1, src2, stride); + s->dsp.fdct(temp); + return s->dsp.sum_abs_dctelem(temp); +} + +#if CONFIG_GPL +#define DCT8_1D {\ + const int s07 = SRC(0) + SRC(7);\ + const int s16 = SRC(1) + SRC(6);\ + const int s25 = SRC(2) + SRC(5);\ + const int s34 = SRC(3) + SRC(4);\ + const int a0 = s07 + s34;\ + const int a1 = s16 + s25;\ + const int a2 = s07 - s34;\ + const int a3 = s16 - s25;\ + const int d07 = SRC(0) - SRC(7);\ + const int d16 = SRC(1) - SRC(6);\ + const int d25 = SRC(2) - SRC(5);\ + const int d34 = SRC(3) - SRC(4);\ + const int a4 = d16 + d25 + (d07 + (d07>>1));\ + const int a5 = d07 - d34 - (d25 + (d25>>1));\ + const int a6 = d07 + d34 - (d16 + (d16>>1));\ + const int a7 = d16 - d25 + (d34 + (d34>>1));\ + DST(0, a0 + a1 ) ;\ + DST(1, a4 + (a7>>2)) ;\ + DST(2, a2 + (a3>>1)) ;\ + DST(3, a5 + (a6>>2)) ;\ + DST(4, a0 - a1 ) ;\ + DST(5, a6 - (a5>>2)) ;\ + DST(6, (a2>>1) - a3 ) ;\ + DST(7, (a4>>2) - a7 ) ;\ +} + +static int dct264_sad8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){ + MpegEncContext * const s= (MpegEncContext *)c; + DCTELEM dct[8][8]; + int i; + int sum=0; + + s->dsp.diff_pixels(dct[0], src1, src2, stride); + +#define SRC(x) dct[i][x] +#define DST(x,v) dct[i][x]= v + for( i = 0; i < 8; i++ ) + DCT8_1D +#undef SRC +#undef DST + +#define SRC(x) dct[x][i] +#define DST(x,v) sum += FFABS(v) + for( i = 0; i < 8; i++ ) + DCT8_1D +#undef SRC +#undef DST + return sum; +} +#endif + +static int dct_max8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){ + MpegEncContext * const s= (MpegEncContext *)c; + DECLARE_ALIGNED_8(uint64_t, aligned_temp[sizeof(DCTELEM)*64/8]); + DCTELEM * const temp= (DCTELEM*)aligned_temp; + int sum=0, i; + + assert(h==8); + + s->dsp.diff_pixels(temp, src1, src2, stride); + s->dsp.fdct(temp); + + for(i=0; i<64; i++) + sum= FFMAX(sum, FFABS(temp[i])); + + return sum; +} + +static int quant_psnr8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){ + MpegEncContext * const s= (MpegEncContext *)c; + DECLARE_ALIGNED_8 (uint64_t, aligned_temp[sizeof(DCTELEM)*64*2/8]); + DCTELEM * const temp= (DCTELEM*)aligned_temp; + DCTELEM * const bak = ((DCTELEM*)aligned_temp)+64; + int sum=0, i; + + assert(h==8); + s->mb_intra=0; + + s->dsp.diff_pixels(temp, src1, src2, stride); + + memcpy(bak, temp, 64*sizeof(DCTELEM)); + + s->block_last_index[0/*FIXME*/]= s->fast_dct_quantize(s, temp, 0/*FIXME*/, s->qscale, &i); + s->dct_unquantize_inter(s, temp, 0, s->qscale); + ff_simple_idct(temp); //FIXME + + for(i=0; i<64; i++) + sum+= (temp[i]-bak[i])*(temp[i]-bak[i]); + + return sum; +} + +static int rd8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){ + MpegEncContext * const s= (MpegEncContext *)c; + const uint8_t *scantable= s->intra_scantable.permutated; + DECLARE_ALIGNED_8 (uint64_t, aligned_temp[sizeof(DCTELEM)*64/8]); + DECLARE_ALIGNED_8 (uint64_t, aligned_bak[stride]); + DCTELEM * const temp= (DCTELEM*)aligned_temp; + uint8_t * const bak= (uint8_t*)aligned_bak; + int i, last, run, bits, level, distortion, start_i; + const int esc_length= s->ac_esc_length; + uint8_t * length; + uint8_t * last_length; + + assert(h==8); + + for(i=0; i<8; i++){ + ((uint32_t*)(bak + i*stride))[0]= ((uint32_t*)(src2 + i*stride))[0]; + ((uint32_t*)(bak + i*stride))[1]= ((uint32_t*)(src2 + i*stride))[1]; + } + + s->dsp.diff_pixels(temp, src1, src2, stride); + + s->block_last_index[0/*FIXME*/]= last= s->fast_dct_quantize(s, temp, 0/*FIXME*/, s->qscale, &i); + + bits=0; + + if (s->mb_intra) { + start_i = 1; + length = s->intra_ac_vlc_length; + last_length= s->intra_ac_vlc_last_length; + bits+= s->luma_dc_vlc_length[temp[0] + 256]; //FIXME chroma + } else { + start_i = 0; + length = s->inter_ac_vlc_length; + last_length= s->inter_ac_vlc_last_length; + } + + if(last>=start_i){ + run=0; + for(i=start_i; i=0){ + if(s->mb_intra) + s->dct_unquantize_intra(s, temp, 0, s->qscale); + else + s->dct_unquantize_inter(s, temp, 0, s->qscale); + } + + s->dsp.idct_add(bak, stride, temp); + + distortion= s->dsp.sse[1](NULL, bak, src1, stride, 8); + + return distortion + ((bits*s->qscale*s->qscale*109 + 64)>>7); +} + +static int bit8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){ + MpegEncContext * const s= (MpegEncContext *)c; + const uint8_t *scantable= s->intra_scantable.permutated; + DECLARE_ALIGNED_8 (uint64_t, aligned_temp[sizeof(DCTELEM)*64/8]); + DCTELEM * const temp= (DCTELEM*)aligned_temp; + int i, last, run, bits, level, start_i; + const int esc_length= s->ac_esc_length; + uint8_t * length; + uint8_t * last_length; + + assert(h==8); + + s->dsp.diff_pixels(temp, src1, src2, stride); + + s->block_last_index[0/*FIXME*/]= last= s->fast_dct_quantize(s, temp, 0/*FIXME*/, s->qscale, &i); + + bits=0; + + if (s->mb_intra) { + start_i = 1; + length = s->intra_ac_vlc_length; + last_length= s->intra_ac_vlc_last_length; + bits+= s->luma_dc_vlc_length[temp[0] + 256]; //FIXME chroma + } else { + start_i = 0; + length = s->inter_ac_vlc_length; + last_length= s->inter_ac_vlc_last_length; + } + + if(last>=start_i){ + run=0; + for(i=start_i; i>31; + // is this faster on some gcc/cpu combinations? +// if(tmp > 0x43c0ffff) tmp = 0xFFFF; +// else tmp = 0; + } + return tmp - 0x8000; +} + +void ff_float_to_int16_c(int16_t *dst, const float *src, long len){ + int i; + for(i=0; i> shift; + + return res; +} + +#define W0 2048 +#define W1 2841 /* 2048*sqrt (2)*cos (1*pi/16) */ +#define W2 2676 /* 2048*sqrt (2)*cos (2*pi/16) */ +#define W3 2408 /* 2048*sqrt (2)*cos (3*pi/16) */ +#define W4 2048 /* 2048*sqrt (2)*cos (4*pi/16) */ +#define W5 1609 /* 2048*sqrt (2)*cos (5*pi/16) */ +#define W6 1108 /* 2048*sqrt (2)*cos (6*pi/16) */ +#define W7 565 /* 2048*sqrt (2)*cos (7*pi/16) */ + +static void wmv2_idct_row(short * b) +{ + int s1,s2; + int a0,a1,a2,a3,a4,a5,a6,a7; + /*step 1*/ + a1 = W1*b[1]+W7*b[7]; + a7 = W7*b[1]-W1*b[7]; + a5 = W5*b[5]+W3*b[3]; + a3 = W3*b[5]-W5*b[3]; + a2 = W2*b[2]+W6*b[6]; + a6 = W6*b[2]-W2*b[6]; + a0 = W0*b[0]+W0*b[4]; + a4 = W0*b[0]-W0*b[4]; + /*step 2*/ + s1 = (181*(a1-a5+a7-a3)+128)>>8;//1,3,5,7, + s2 = (181*(a1-a5-a7+a3)+128)>>8; + /*step 3*/ + b[0] = (a0+a2+a1+a5 + (1<<7))>>8; + b[1] = (a4+a6 +s1 + (1<<7))>>8; + b[2] = (a4-a6 +s2 + (1<<7))>>8; + b[3] = (a0-a2+a7+a3 + (1<<7))>>8; + b[4] = (a0-a2-a7-a3 + (1<<7))>>8; + b[5] = (a4-a6 -s2 + (1<<7))>>8; + b[6] = (a4+a6 -s1 + (1<<7))>>8; + b[7] = (a0+a2-a1-a5 + (1<<7))>>8; +} +static void wmv2_idct_col(short * b) +{ + int s1,s2; + int a0,a1,a2,a3,a4,a5,a6,a7; + /*step 1, with extended precision*/ + a1 = (W1*b[8*1]+W7*b[8*7] + 4)>>3; + a7 = (W7*b[8*1]-W1*b[8*7] + 4)>>3; + a5 = (W5*b[8*5]+W3*b[8*3] + 4)>>3; + a3 = (W3*b[8*5]-W5*b[8*3] + 4)>>3; + a2 = (W2*b[8*2]+W6*b[8*6] + 4)>>3; + a6 = (W6*b[8*2]-W2*b[8*6] + 4)>>3; + a0 = (W0*b[8*0]+W0*b[8*4] )>>3; + a4 = (W0*b[8*0]-W0*b[8*4] )>>3; + /*step 2*/ + s1 = (181*(a1-a5+a7-a3)+128)>>8; + s2 = (181*(a1-a5-a7+a3)+128)>>8; + /*step 3*/ + b[8*0] = (a0+a2+a1+a5 + (1<<13))>>14; + b[8*1] = (a4+a6 +s1 + (1<<13))>>14; + b[8*2] = (a4-a6 +s2 + (1<<13))>>14; + b[8*3] = (a0-a2+a7+a3 + (1<<13))>>14; + + b[8*4] = (a0-a2-a7-a3 + (1<<13))>>14; + b[8*5] = (a4-a6 -s2 + (1<<13))>>14; + b[8*6] = (a4+a6 -s1 + (1<<13))>>14; + b[8*7] = (a0+a2-a1-a5 + (1<<13))>>14; +} +void ff_wmv2_idct_c(short * block){ + int i; + + for(i=0;i<64;i+=8){ + wmv2_idct_row(block+i); + } + for(i=0;i<8;i++){ + wmv2_idct_col(block+i); + } +} +/* XXX: those functions should be suppressed ASAP when all IDCTs are + converted */ +static void ff_wmv2_idct_put_c(uint8_t *dest, int line_size, DCTELEM *block) +{ + ff_wmv2_idct_c(block); + put_pixels_clamped_c(block, dest, line_size); +} +static void ff_wmv2_idct_add_c(uint8_t *dest, int line_size, DCTELEM *block) +{ + ff_wmv2_idct_c(block); + add_pixels_clamped_c(block, dest, line_size); +} +static void ff_jref_idct_put(uint8_t *dest, int line_size, DCTELEM *block) +{ + j_rev_dct (block); + put_pixels_clamped_c(block, dest, line_size); +} +static void ff_jref_idct_add(uint8_t *dest, int line_size, DCTELEM *block) +{ + j_rev_dct (block); + add_pixels_clamped_c(block, dest, line_size); +} + +static void ff_jref_idct4_put(uint8_t *dest, int line_size, DCTELEM *block) +{ + j_rev_dct4 (block); + put_pixels_clamped4_c(block, dest, line_size); +} +static void ff_jref_idct4_add(uint8_t *dest, int line_size, DCTELEM *block) +{ + j_rev_dct4 (block); + add_pixels_clamped4_c(block, dest, line_size); +} + +static void ff_jref_idct2_put(uint8_t *dest, int line_size, DCTELEM *block) +{ + j_rev_dct2 (block); + put_pixels_clamped2_c(block, dest, line_size); +} +static void ff_jref_idct2_add(uint8_t *dest, int line_size, DCTELEM *block) +{ + j_rev_dct2 (block); + add_pixels_clamped2_c(block, dest, line_size); +} + +static void ff_jref_idct1_put(uint8_t *dest, int line_size, DCTELEM *block) +{ + uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; + + dest[0] = cm[(block[0] + 4)>>3]; +} +static void ff_jref_idct1_add(uint8_t *dest, int line_size, DCTELEM *block) +{ + uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; + + dest[0] = cm[dest[0] + ((block[0] + 4)>>3)]; +} + +static void just_return(void *mem av_unused, int stride av_unused, int h av_unused) { return; } + +/* init static data */ +void dsputil_static_init(void) +{ + int i; + + for(i=0;i<256;i++) ff_cropTbl[i + MAX_NEG_CROP] = i; + for(i=0;i= 4.2.\n" + "Do not report crashes to FFmpeg developers.\n"); +#endif + did_fail=1; + } + return -1; + } + return 0; +} + +void dsputil_init(DSPContext* c, AVCodecContext *avctx) +{ + int i; + + ff_check_alignment(); + +#if CONFIG_ENCODERS + if(avctx->dct_algo==FF_DCT_FASTINT) { + c->fdct = fdct_ifast; + c->fdct248 = fdct_ifast248; + } + else if(avctx->dct_algo==FF_DCT_FAAN) { + c->fdct = ff_faandct; + c->fdct248 = ff_faandct248; + } + else { + c->fdct = ff_jpeg_fdct_islow; //slow/accurate/default + c->fdct248 = ff_fdct248_islow; + } +#endif //CONFIG_ENCODERS + + if(avctx->lowres==1){ + if(avctx->idct_algo==FF_IDCT_INT || avctx->idct_algo==FF_IDCT_AUTO || !CONFIG_H264_DECODER){ + c->idct_put= ff_jref_idct4_put; + c->idct_add= ff_jref_idct4_add; + }else{ + c->idct_put= ff_h264_lowres_idct_put_c; + c->idct_add= ff_h264_lowres_idct_add_c; + } + c->idct = j_rev_dct4; + c->idct_permutation_type= FF_NO_IDCT_PERM; + }else if(avctx->lowres==2){ + c->idct_put= ff_jref_idct2_put; + c->idct_add= ff_jref_idct2_add; + c->idct = j_rev_dct2; + c->idct_permutation_type= FF_NO_IDCT_PERM; + }else if(avctx->lowres==3){ + c->idct_put= ff_jref_idct1_put; + c->idct_add= ff_jref_idct1_add; + c->idct = j_rev_dct1; + c->idct_permutation_type= FF_NO_IDCT_PERM; + }else{ + if(avctx->idct_algo==FF_IDCT_INT){ + c->idct_put= ff_jref_idct_put; + c->idct_add= ff_jref_idct_add; + c->idct = j_rev_dct; + c->idct_permutation_type= FF_LIBMPEG2_IDCT_PERM; + }else if((CONFIG_VP3_DECODER || CONFIG_VP5_DECODER || CONFIG_VP6_DECODER || CONFIG_THEORA_DECODER ) && + avctx->idct_algo==FF_IDCT_VP3){ + c->idct_put= ff_vp3_idct_put_c; + c->idct_add= ff_vp3_idct_add_c; + c->idct = ff_vp3_idct_c; + c->idct_permutation_type= FF_NO_IDCT_PERM; + }else if(avctx->idct_algo==FF_IDCT_WMV2){ + c->idct_put= ff_wmv2_idct_put_c; + c->idct_add= ff_wmv2_idct_add_c; + c->idct = ff_wmv2_idct_c; + c->idct_permutation_type= FF_NO_IDCT_PERM; + }else if(avctx->idct_algo==FF_IDCT_FAAN){ + c->idct_put= ff_faanidct_put; + c->idct_add= ff_faanidct_add; + c->idct = ff_faanidct; + c->idct_permutation_type= FF_NO_IDCT_PERM; + }else if(CONFIG_EATGQ_DECODER && avctx->idct_algo==FF_IDCT_EA) { + c->idct_put= ff_ea_idct_put_c; + c->idct_permutation_type= FF_NO_IDCT_PERM; + }else{ //accurate/default + c->idct_put= ff_simple_idct_put; + c->idct_add= ff_simple_idct_add; + c->idct = ff_simple_idct; + c->idct_permutation_type= FF_NO_IDCT_PERM; + } + } + + if (CONFIG_H264_DECODER) { + c->h264_idct_add= ff_h264_idct_add_c; + c->h264_idct8_add= ff_h264_idct8_add_c; + c->h264_idct_dc_add= ff_h264_idct_dc_add_c; + c->h264_idct8_dc_add= ff_h264_idct8_dc_add_c; + c->h264_idct_add16 = ff_h264_idct_add16_c; + c->h264_idct8_add4 = ff_h264_idct8_add4_c; + c->h264_idct_add8 = ff_h264_idct_add8_c; + c->h264_idct_add16intra= ff_h264_idct_add16intra_c; + } + + c->get_pixels = get_pixels_c; + c->diff_pixels = diff_pixels_c; + c->put_pixels_clamped = put_pixels_clamped_c; + c->put_signed_pixels_clamped = put_signed_pixels_clamped_c; + c->add_pixels_clamped = add_pixels_clamped_c; + c->add_pixels8 = add_pixels8_c; + c->add_pixels4 = add_pixels4_c; + c->sum_abs_dctelem = sum_abs_dctelem_c; + c->gmc1 = gmc1_c; + c->gmc = ff_gmc_c; + c->clear_block = clear_block_c; + c->clear_blocks = clear_blocks_c; + c->pix_sum = pix_sum_c; + c->pix_norm1 = pix_norm1_c; + + /* TODO [0] 16 [1] 8 */ + c->pix_abs[0][0] = pix_abs16_c; + c->pix_abs[0][1] = pix_abs16_x2_c; + c->pix_abs[0][2] = pix_abs16_y2_c; + c->pix_abs[0][3] = pix_abs16_xy2_c; + c->pix_abs[1][0] = pix_abs8_c; + c->pix_abs[1][1] = pix_abs8_x2_c; + c->pix_abs[1][2] = pix_abs8_y2_c; + c->pix_abs[1][3] = pix_abs8_xy2_c; + +#define dspfunc(PFX, IDX, NUM) \ + c->PFX ## _pixels_tab[IDX][0] = PFX ## _pixels ## NUM ## _c; \ + c->PFX ## _pixels_tab[IDX][1] = PFX ## _pixels ## NUM ## _x2_c; \ + c->PFX ## _pixels_tab[IDX][2] = PFX ## _pixels ## NUM ## _y2_c; \ + c->PFX ## _pixels_tab[IDX][3] = PFX ## _pixels ## NUM ## _xy2_c + + dspfunc(put, 0, 16); + dspfunc(put_no_rnd, 0, 16); + dspfunc(put, 1, 8); + dspfunc(put_no_rnd, 1, 8); + dspfunc(put, 2, 4); + dspfunc(put, 3, 2); + + dspfunc(avg, 0, 16); + dspfunc(avg_no_rnd, 0, 16); + dspfunc(avg, 1, 8); + dspfunc(avg_no_rnd, 1, 8); + dspfunc(avg, 2, 4); + dspfunc(avg, 3, 2); +#undef dspfunc + + c->put_no_rnd_pixels_l2[0]= put_no_rnd_pixels16_l2_c; + c->put_no_rnd_pixels_l2[1]= put_no_rnd_pixels8_l2_c; + + c->put_tpel_pixels_tab[ 0] = put_tpel_pixels_mc00_c; + c->put_tpel_pixels_tab[ 1] = put_tpel_pixels_mc10_c; + c->put_tpel_pixels_tab[ 2] = put_tpel_pixels_mc20_c; + c->put_tpel_pixels_tab[ 4] = put_tpel_pixels_mc01_c; + c->put_tpel_pixels_tab[ 5] = put_tpel_pixels_mc11_c; + c->put_tpel_pixels_tab[ 6] = put_tpel_pixels_mc21_c; + c->put_tpel_pixels_tab[ 8] = put_tpel_pixels_mc02_c; + c->put_tpel_pixels_tab[ 9] = put_tpel_pixels_mc12_c; + c->put_tpel_pixels_tab[10] = put_tpel_pixels_mc22_c; + + c->avg_tpel_pixels_tab[ 0] = avg_tpel_pixels_mc00_c; + c->avg_tpel_pixels_tab[ 1] = avg_tpel_pixels_mc10_c; + c->avg_tpel_pixels_tab[ 2] = avg_tpel_pixels_mc20_c; + c->avg_tpel_pixels_tab[ 4] = avg_tpel_pixels_mc01_c; + c->avg_tpel_pixels_tab[ 5] = avg_tpel_pixels_mc11_c; + c->avg_tpel_pixels_tab[ 6] = avg_tpel_pixels_mc21_c; + c->avg_tpel_pixels_tab[ 8] = avg_tpel_pixels_mc02_c; + c->avg_tpel_pixels_tab[ 9] = avg_tpel_pixels_mc12_c; + c->avg_tpel_pixels_tab[10] = avg_tpel_pixels_mc22_c; + +#define dspfunc(PFX, IDX, NUM) \ + c->PFX ## _pixels_tab[IDX][ 0] = PFX ## NUM ## _mc00_c; \ + c->PFX ## _pixels_tab[IDX][ 1] = PFX ## NUM ## _mc10_c; \ + c->PFX ## _pixels_tab[IDX][ 2] = PFX ## NUM ## _mc20_c; \ + c->PFX ## _pixels_tab[IDX][ 3] = PFX ## NUM ## _mc30_c; \ + c->PFX ## _pixels_tab[IDX][ 4] = PFX ## NUM ## _mc01_c; \ + c->PFX ## _pixels_tab[IDX][ 5] = PFX ## NUM ## _mc11_c; \ + c->PFX ## _pixels_tab[IDX][ 6] = PFX ## NUM ## _mc21_c; \ + c->PFX ## _pixels_tab[IDX][ 7] = PFX ## NUM ## _mc31_c; \ + c->PFX ## _pixels_tab[IDX][ 8] = PFX ## NUM ## _mc02_c; \ + c->PFX ## _pixels_tab[IDX][ 9] = PFX ## NUM ## _mc12_c; \ + c->PFX ## _pixels_tab[IDX][10] = PFX ## NUM ## _mc22_c; \ + c->PFX ## _pixels_tab[IDX][11] = PFX ## NUM ## _mc32_c; \ + c->PFX ## _pixels_tab[IDX][12] = PFX ## NUM ## _mc03_c; \ + c->PFX ## _pixels_tab[IDX][13] = PFX ## NUM ## _mc13_c; \ + c->PFX ## _pixels_tab[IDX][14] = PFX ## NUM ## _mc23_c; \ + c->PFX ## _pixels_tab[IDX][15] = PFX ## NUM ## _mc33_c + + dspfunc(put_qpel, 0, 16); + dspfunc(put_no_rnd_qpel, 0, 16); + + dspfunc(avg_qpel, 0, 16); + /* dspfunc(avg_no_rnd_qpel, 0, 16); */ + + dspfunc(put_qpel, 1, 8); + dspfunc(put_no_rnd_qpel, 1, 8); + + dspfunc(avg_qpel, 1, 8); + /* dspfunc(avg_no_rnd_qpel, 1, 8); */ + + dspfunc(put_h264_qpel, 0, 16); + dspfunc(put_h264_qpel, 1, 8); + dspfunc(put_h264_qpel, 2, 4); + dspfunc(put_h264_qpel, 3, 2); + dspfunc(avg_h264_qpel, 0, 16); + dspfunc(avg_h264_qpel, 1, 8); + dspfunc(avg_h264_qpel, 2, 4); + +#undef dspfunc + c->put_h264_chroma_pixels_tab[0]= put_h264_chroma_mc8_c; + c->put_h264_chroma_pixels_tab[1]= put_h264_chroma_mc4_c; + c->put_h264_chroma_pixels_tab[2]= put_h264_chroma_mc2_c; + c->avg_h264_chroma_pixels_tab[0]= avg_h264_chroma_mc8_c; + c->avg_h264_chroma_pixels_tab[1]= avg_h264_chroma_mc4_c; + c->avg_h264_chroma_pixels_tab[2]= avg_h264_chroma_mc2_c; + c->put_no_rnd_h264_chroma_pixels_tab[0]= put_no_rnd_h264_chroma_mc8_c; + + c->weight_h264_pixels_tab[0]= weight_h264_pixels16x16_c; + c->weight_h264_pixels_tab[1]= weight_h264_pixels16x8_c; + c->weight_h264_pixels_tab[2]= weight_h264_pixels8x16_c; + c->weight_h264_pixels_tab[3]= weight_h264_pixels8x8_c; + c->weight_h264_pixels_tab[4]= weight_h264_pixels8x4_c; + c->weight_h264_pixels_tab[5]= weight_h264_pixels4x8_c; + c->weight_h264_pixels_tab[6]= weight_h264_pixels4x4_c; + c->weight_h264_pixels_tab[7]= weight_h264_pixels4x2_c; + c->weight_h264_pixels_tab[8]= weight_h264_pixels2x4_c; + c->weight_h264_pixels_tab[9]= weight_h264_pixels2x2_c; + c->biweight_h264_pixels_tab[0]= biweight_h264_pixels16x16_c; + c->biweight_h264_pixels_tab[1]= biweight_h264_pixels16x8_c; + c->biweight_h264_pixels_tab[2]= biweight_h264_pixels8x16_c; + c->biweight_h264_pixels_tab[3]= biweight_h264_pixels8x8_c; + c->biweight_h264_pixels_tab[4]= biweight_h264_pixels8x4_c; + c->biweight_h264_pixels_tab[5]= biweight_h264_pixels4x8_c; + c->biweight_h264_pixels_tab[6]= biweight_h264_pixels4x4_c; + c->biweight_h264_pixels_tab[7]= biweight_h264_pixels4x2_c; + c->biweight_h264_pixels_tab[8]= biweight_h264_pixels2x4_c; + c->biweight_h264_pixels_tab[9]= biweight_h264_pixels2x2_c; + + c->draw_edges = draw_edges_c; + +#if CONFIG_CAVS_DECODER + ff_cavsdsp_init(c,avctx); +#endif +#if CONFIG_VC1_DECODER || CONFIG_WMV3_DECODER + ff_vc1dsp_init(c,avctx); +#endif +#if CONFIG_WMV2_DECODER || CONFIG_VC1_DECODER || CONFIG_WMV3_DECODER + ff_intrax8dsp_init(c,avctx); +#endif +#if CONFIG_RV30_DECODER + ff_rv30dsp_init(c,avctx); +#endif +#if CONFIG_RV40_DECODER + ff_rv40dsp_init(c,avctx); + c->put_rv40_qpel_pixels_tab[0][15] = put_rv40_qpel16_mc33_c; + c->avg_rv40_qpel_pixels_tab[0][15] = avg_rv40_qpel16_mc33_c; + c->put_rv40_qpel_pixels_tab[1][15] = put_rv40_qpel8_mc33_c; + c->avg_rv40_qpel_pixels_tab[1][15] = avg_rv40_qpel8_mc33_c; +#endif + + c->put_mspel_pixels_tab[0]= put_mspel8_mc00_c; + c->put_mspel_pixels_tab[1]= put_mspel8_mc10_c; + c->put_mspel_pixels_tab[2]= put_mspel8_mc20_c; + c->put_mspel_pixels_tab[3]= put_mspel8_mc30_c; + c->put_mspel_pixels_tab[4]= put_mspel8_mc02_c; + c->put_mspel_pixels_tab[5]= put_mspel8_mc12_c; + c->put_mspel_pixels_tab[6]= put_mspel8_mc22_c; + c->put_mspel_pixels_tab[7]= put_mspel8_mc32_c; + +#define SET_CMP_FUNC(name) \ + c->name[0]= name ## 16_c;\ + c->name[1]= name ## 8x8_c; + + SET_CMP_FUNC(hadamard8_diff) + c->hadamard8_diff[4]= hadamard8_intra16_c; + c->hadamard8_diff[5]= hadamard8_intra8x8_c; + SET_CMP_FUNC(dct_sad) + SET_CMP_FUNC(dct_max) +#if CONFIG_GPL + SET_CMP_FUNC(dct264_sad) +#endif + c->sad[0]= pix_abs16_c; + c->sad[1]= pix_abs8_c; + c->sse[0]= sse16_c; + c->sse[1]= sse8_c; + c->sse[2]= sse4_c; + SET_CMP_FUNC(quant_psnr) + SET_CMP_FUNC(rd) + SET_CMP_FUNC(bit) + c->vsad[0]= vsad16_c; + c->vsad[4]= vsad_intra16_c; + c->vsad[5]= vsad_intra8_c; + c->vsse[0]= vsse16_c; + c->vsse[4]= vsse_intra16_c; + c->vsse[5]= vsse_intra8_c; + c->nsse[0]= nsse16_c; + c->nsse[1]= nsse8_c; +#if CONFIG_SNOW_ENCODER + c->w53[0]= w53_16_c; + c->w53[1]= w53_8_c; + c->w97[0]= w97_16_c; + c->w97[1]= w97_8_c; +#endif + + c->ssd_int8_vs_int16 = ssd_int8_vs_int16_c; + + c->add_bytes= add_bytes_c; + c->add_bytes_l2= add_bytes_l2_c; + c->diff_bytes= diff_bytes_c; + c->add_hfyu_median_prediction= add_hfyu_median_prediction_c; + c->sub_hfyu_median_prediction= sub_hfyu_median_prediction_c; + c->bswap_buf= bswap_buf; +#if CONFIG_PNG_DECODER + c->add_png_paeth_prediction= ff_add_png_paeth_prediction; +#endif + + c->h264_v_loop_filter_luma= h264_v_loop_filter_luma_c; + c->h264_h_loop_filter_luma= h264_h_loop_filter_luma_c; + c->h264_v_loop_filter_luma_intra= h264_v_loop_filter_luma_intra_c; + c->h264_h_loop_filter_luma_intra= h264_h_loop_filter_luma_intra_c; + c->h264_v_loop_filter_chroma= h264_v_loop_filter_chroma_c; + c->h264_h_loop_filter_chroma= h264_h_loop_filter_chroma_c; + c->h264_v_loop_filter_chroma_intra= h264_v_loop_filter_chroma_intra_c; + c->h264_h_loop_filter_chroma_intra= h264_h_loop_filter_chroma_intra_c; + c->h264_loop_filter_strength= NULL; + + if (CONFIG_ANY_H263) { + c->h263_h_loop_filter= h263_h_loop_filter_c; + c->h263_v_loop_filter= h263_v_loop_filter_c; + } + + if (CONFIG_VP3_DECODER || CONFIG_THEORA_DECODER) { + c->vp3_h_loop_filter= ff_vp3_h_loop_filter_c; + c->vp3_v_loop_filter= ff_vp3_v_loop_filter_c; + } + if (CONFIG_VP6_DECODER) { + c->vp6_filter_diag4= ff_vp6_filter_diag4_c; + } + + c->h261_loop_filter= h261_loop_filter_c; + + c->try_8x8basis= try_8x8basis_c; + c->add_8x8basis= add_8x8basis_c; + +#if CONFIG_SNOW_DECODER + c->vertical_compose97i = ff_snow_vertical_compose97i; + c->horizontal_compose97i = ff_snow_horizontal_compose97i; + c->inner_add_yblock = ff_snow_inner_add_yblock; +#endif + +#if CONFIG_VORBIS_DECODER + c->vorbis_inverse_coupling = vorbis_inverse_coupling; +#endif +#if CONFIG_AC3_DECODER + c->ac3_downmix = ff_ac3_downmix_c; +#endif +#if CONFIG_FLAC_ENCODER + c->flac_compute_autocorr = ff_flac_compute_autocorr; +#endif + c->vector_fmul = vector_fmul_c; + c->vector_fmul_reverse = vector_fmul_reverse_c; + c->vector_fmul_add_add = ff_vector_fmul_add_add_c; + c->vector_fmul_window = ff_vector_fmul_window_c; + c->int32_to_float_fmul_scalar = int32_to_float_fmul_scalar_c; + c->float_to_int16 = ff_float_to_int16_c; + c->float_to_int16_interleave = ff_float_to_int16_interleave_c; + c->add_int16 = add_int16_c; + c->sub_int16 = sub_int16_c; + c->scalarproduct_int16 = scalarproduct_int16_c; + + c->shrink[0]= ff_img_copy_plane; + c->shrink[1]= ff_shrink22; + c->shrink[2]= ff_shrink44; + c->shrink[3]= ff_shrink88; + + c->prefetch= just_return; + + memset(c->put_2tap_qpel_pixels_tab, 0, sizeof(c->put_2tap_qpel_pixels_tab)); + memset(c->avg_2tap_qpel_pixels_tab, 0, sizeof(c->avg_2tap_qpel_pixels_tab)); + + if (HAVE_MMX) dsputil_init_mmx (c, avctx); + if (ARCH_ARM) dsputil_init_arm (c, avctx); + if (CONFIG_MLIB) dsputil_init_mlib (c, avctx); + if (HAVE_VIS) dsputil_init_vis (c, avctx); + if (ARCH_ALPHA) dsputil_init_alpha (c, avctx); + if (ARCH_PPC) dsputil_init_ppc (c, avctx); + if (HAVE_MMI) dsputil_init_mmi (c, avctx); + if (ARCH_SH4) dsputil_init_sh4 (c, avctx); + if (ARCH_BFIN) dsputil_init_bfin (c, avctx); + + for(i=0; i<64; i++){ + if(!c->put_2tap_qpel_pixels_tab[0][i]) + c->put_2tap_qpel_pixels_tab[0][i]= c->put_h264_qpel_pixels_tab[0][i]; + if(!c->avg_2tap_qpel_pixels_tab[0][i]) + c->avg_2tap_qpel_pixels_tab[0][i]= c->avg_h264_qpel_pixels_tab[0][i]; + } + + switch(c->idct_permutation_type){ + case FF_NO_IDCT_PERM: + for(i=0; i<64; i++) + c->idct_permutation[i]= i; + break; + case FF_LIBMPEG2_IDCT_PERM: + for(i=0; i<64; i++) + c->idct_permutation[i]= (i & 0x38) | ((i & 6) >> 1) | ((i & 1) << 2); + break; + case FF_SIMPLE_IDCT_PERM: + for(i=0; i<64; i++) + c->idct_permutation[i]= simple_mmx_permutation[i]; + break; + case FF_TRANSPOSE_IDCT_PERM: + for(i=0; i<64; i++) + c->idct_permutation[i]= ((i&7)<<3) | (i>>3); + break; + case FF_PARTTRANS_IDCT_PERM: + for(i=0; i<64; i++) + c->idct_permutation[i]= (i&0x24) | ((i&3)<<3) | ((i>>3)&3); + break; + case FF_SSE2_IDCT_PERM: + for(i=0; i<64; i++) + c->idct_permutation[i]= (i&0x38) | idct_sse2_row_perm[i&7]; + break; + default: + av_log(avctx, AV_LOG_ERROR, "Internal error, IDCT permutation not set\n"); + } +} + Index: apps/codecs/libcook/id3.h =================================================================== --- apps/codecs/libcook/id3.h (revision 0) +++ apps/codecs/libcook/id3.h (revision 0) @@ -0,0 +1,153 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: id3.h 13730 2007-06-28 20:28:43Z nicolasp $ + * + * Copyright (C) 2002 by Daniel Stenberg + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#ifndef ID3_H +#define ID3_H + +#include + +#define ID3V2_BUF_SIZE 300 +#define MAX_PATH 260 +/* Audio file types. */ +/* NOTE: The values of the AFMT_* items are used for the %fc tag in the WPS + - so new entries MUST be added to the end to maintain compatibility. + */ +enum +{ + AFMT_UNKNOWN = 0, /* Unknown file format */ + + /* start formats */ + + AFMT_MPA_L1, /* MPEG Audio layer 1 */ + AFMT_MPA_L2, /* MPEG Audio layer 2 */ + AFMT_MPA_L3, /* MPEG Audio layer 3 */ + + AFMT_AIFF, /* Audio Interchange File Format */ + AFMT_PCM_WAV, /* Uncompressed PCM in a WAV file */ + AFMT_OGG_VORBIS, /* Ogg Vorbis */ + AFMT_FLAC, /* FLAC */ + AFMT_MPC, /* Musepack */ + AFMT_A52, /* A/52 (aka AC3) audio */ + AFMT_WAVPACK, /* WavPack */ + AFMT_ALAC, /* Apple Lossless Audio Codec */ + AFMT_AAC, /* Advanced Audio Coding (AAC) in M4A container */ + AFMT_SHN, /* Shorten */ + AFMT_SID, /* SID File Format */ + AFMT_ADX, /* ADX File Format */ + AFMT_NSF, /* NESM (NES Sound Format) */ + AFMT_SPEEX, /* Ogg Speex speech */ + AFMT_SPC, /* SPC700 save state */ + AFMT_APE, /* Monkey's Audio (APE) */ + + /* add new formats at any index above this line to have a sensible order - + specified array index inits are used */ + /* format arrays defined in id3.c */ + + AFMT_NUM_CODECS +}; + +struct mp3entry { + char path[MAX_PATH]; + char* title; + char* artist; + char* album; + char* genre_string; + char* track_string; + char* year_string; + char* composer; + char* comment; + char* albumartist; + int tracknum; + int version; + int layer; + int year; + unsigned char id3version; + unsigned int codectype; + unsigned int bitrate; + unsigned long frequency; + unsigned long id3v2len; + unsigned long id3v1len; + unsigned long first_frame_offset; /* Byte offset to first real MP3 frame. + Used for skipping leading garbage to + avoid gaps between tracks. */ + unsigned long vbr_header_pos; + unsigned long filesize; /* without headers; in bytes */ + unsigned long length; /* song length in ms */ + unsigned long elapsed; /* ms played */ + + int lead_trim; /* Number of samples to skip at the beginning */ + int tail_trim; /* Number of samples to remove from the end */ + + /* Added for Vorbis */ + unsigned long samples; /* number of samples in track */ + + /* MP3 stream specific info */ + unsigned long frame_count; /* number of frames in the file (if VBR) */ + + /* Used for A52/AC3 */ + unsigned long bytesperframe; /* number of bytes per frame (if CBR) */ + + /* Xing VBR fields */ + bool vbr; + bool has_toc; /* True if there is a VBR header in the file */ + unsigned char toc[100]; /* table of contents */ + + /* these following two fields are used for local buffering */ + char id3v2buf[ID3V2_BUF_SIZE]; + char id3v1buf[4][92]; + + /* resume related */ + unsigned long offset; /* bytes played */ + int index; /* playlist index */ + + /* FileEntry fields */ + long fileentryoffset; + long filehash; + long songentryoffset; + long rundbentryoffset; + + /* runtime database fields */ + short rating; + short score; + long playcount; + long lastplayed; + + /* replaygain support */ + +#if CONFIG_CODEC == SWCODEC + char* track_gain_string; + char* album_gain_string; + long track_gain; /* 7.24 signed fixed point. 0 for no gain. */ + long album_gain; + long track_peak; /* 7.24 signed fixed point. 0 for no peak. */ + long album_peak; +#endif + + /* Cuesheet support */ + int cuesheet_type; /* 0: none, 1: external, 2: embedded */ +}; + +enum { + ID3_VER_1_0 = 1, + ID3_VER_1_1, + ID3_VER_2_2, + ID3_VER_2_3, + ID3_VER_2_4 +}; + +#endif Index: apps/codecs/libcook/random.h =================================================================== --- apps/codecs/libcook/random.h (revision 0) +++ apps/codecs/libcook/random.h (revision 0) @@ -0,0 +1,26 @@ +/* + * Mersenne Twister PRNG algorithm + * Copyright (c) 2006 Ryan Martell + * Based on a C program for MT19937, with initialization improved 2002/1/26. + * Coded by Takuji Nishimura and Makoto Matsumoto. + * + * 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 + */ +#undef srand +#undef rand +void srand(unsigned int seed); +int rand(void); Index: apps/codecs/libcook/mdct.c =================================================================== --- apps/codecs/libcook/mdct.c (revision 0) +++ apps/codecs/libcook/mdct.c (revision 0) @@ -0,0 +1,245 @@ +/* + * MDCT/IMDCT transforms + * Copyright (c) 2002 Fabrice Bellard + * + * 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 + */ +#include "dsputil.h" + +#ifndef M_E +#define M_E 2.7182818284590452354 /* e */ +#endif +#ifndef M_LN2 +#define M_LN2 0.69314718055994530942 /* log_e 2 */ +#endif +#ifndef M_LN10 +#define M_LN10 2.30258509299404568402 /* log_e 10 */ +#endif +#ifndef M_PI +#define M_PI 3.14159265358979323846 /* pi */ +#endif +#ifndef M_SQRT1_2 +#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */ +#endif + +/** + * @file libavcodec/mdct.c + * MDCT/IMDCT transforms. + */ + +// Generate a Kaiser-Bessel Derived Window. +#define BESSEL_I0_ITER 50 // default: 50 iterations of Bessel I0 approximation +av_cold void ff_kbd_window_init(float *window, float alpha, int n) +{ + int i, j; + double sum = 0.0, bessel, tmp; + double local_window[n]; + double alpha2 = (alpha * M_PI / n) * (alpha * M_PI / n); + + for (i = 0; i < n; i++) { + tmp = i * (n - i) * alpha2; + bessel = 1.0; + for (j = BESSEL_I0_ITER; j > 0; j--) + bessel = bessel * tmp / (j * j) + 1; + sum += bessel; + local_window[i] = sum; + } + + sum++; + for (i = 0; i < n; i++) + window[i] = sqrt(local_window[i] / sum); +} + +DECLARE_ALIGNED(16, float, ff_sine_128 [ 128]); +DECLARE_ALIGNED(16, float, ff_sine_256 [ 256]); +DECLARE_ALIGNED(16, float, ff_sine_512 [ 512]); +DECLARE_ALIGNED(16, float, ff_sine_1024[1024]); +DECLARE_ALIGNED(16, float, ff_sine_2048[2048]); +DECLARE_ALIGNED(16, float, ff_sine_4096[4096]); +float *ff_sine_windows[6] = { + ff_sine_128, ff_sine_256, ff_sine_512, ff_sine_1024, ff_sine_2048, ff_sine_4096 +}; + +// Generate a sine window. +av_cold void ff_sine_window_init(float *window, int n) { + int i; + for(i = 0; i < n; i++) + window[i] = sinf((i + 0.5) * (M_PI / (2.0 * n))); +} + +/** + * init MDCT or IMDCT computation. + */ +av_cold int ff_mdct_init(MDCTContext *s, int nbits, int inverse) +{ + int n, n4, i; + double alpha; + + memset(s, 0, sizeof(*s)); + n = 1 << nbits; + s->nbits = nbits; + s->n = n; + n4 = n >> 2; + s->tcos = av_malloc(n4 * sizeof(FFTSample)); + if (!s->tcos) + goto fail; + s->tsin = av_malloc(n4 * sizeof(FFTSample)); + if (!s->tsin) + goto fail; + + for(i=0;itcos[i] = -cos(alpha); + s->tsin[i] = -sin(alpha); + } + if (ff_fft_init(&s->fft, s->nbits - 2, inverse) < 0) + goto fail; + return 0; + fail: + av_freep(&s->tcos); + av_freep(&s->tsin); + return -1; +} + +/* complex multiplication: p = a * b */ +#define CMUL(pre, pim, are, aim, bre, bim) \ +{\ + FFTSample _are = (are);\ + FFTSample _aim = (aim);\ + FFTSample _bre = (bre);\ + FFTSample _bim = (bim);\ + (pre) = _are * _bre - _aim * _bim;\ + (pim) = _are * _bim + _aim * _bre;\ +} + +/** + * Compute the middle half of the inverse MDCT of size N = 2^nbits, + * thus excluding the parts that can be derived by symmetry + * @param output N/2 samples + * @param input N/2 samples + */ +void ff_imdct_half_c(MDCTContext *s, FFTSample *output, const FFTSample *input) +{ + int k, n8, n4, n2, n, j; + const uint16_t *revtab = s->fft.revtab; + const FFTSample *tcos = s->tcos; + const FFTSample *tsin = s->tsin; + const FFTSample *in1, *in2; + FFTComplex *z = (FFTComplex *)output; + + n = 1 << s->nbits; + n2 = n >> 1; + n4 = n >> 2; + n8 = n >> 3; + + /* pre rotation */ + in1 = input; + in2 = input + n2 - 1; + for(k = 0; k < n4; k++) { + j=revtab[k]; + CMUL(z[j].re, z[j].im, *in2, *in1, tcos[k], tsin[k]); + in1 += 2; + in2 -= 2; + } + ff_fft_calc(&s->fft, z); + + /* post rotation + reordering */ + output += n4; + for(k = 0; k < n8; k++) { + FFTSample r0, i0, r1, i1; + CMUL(r0, i1, z[n8-k-1].im, z[n8-k-1].re, tsin[n8-k-1], tcos[n8-k-1]); + CMUL(r1, i0, z[n8+k ].im, z[n8+k ].re, tsin[n8+k ], tcos[n8+k ]); + z[n8-k-1].re = r0; + z[n8-k-1].im = i0; + z[n8+k ].re = r1; + z[n8+k ].im = i1; + } +} + +/** + * Compute inverse MDCT of size N = 2^nbits + * @param output N samples + * @param input N/2 samples + */ +void ff_imdct_calc_c(MDCTContext *s, FFTSample *output, const FFTSample *input) +{ + int k; + int n = 1 << s->nbits; + int n2 = n >> 1; + int n4 = n >> 2; + + ff_imdct_half_c(s, output+n4, input); + + for(k = 0; k < n4; k++) { + output[k] = -output[n2-k-1]; + output[n-k-1] = output[n2+k]; + } +} + +/** + * Compute MDCT of size N = 2^nbits + * @param input N samples + * @param out N/2 samples + */ +void ff_mdct_calc(MDCTContext *s, FFTSample *out, const FFTSample *input) +{ + int i, j, n, n8, n4, n2, n3; + FFTSample re, im; + const uint16_t *revtab = s->fft.revtab; + const FFTSample *tcos = s->tcos; + const FFTSample *tsin = s->tsin; + FFTComplex *x = (FFTComplex *)out; + + n = 1 << s->nbits; + n2 = n >> 1; + n4 = n >> 2; + n8 = n >> 3; + n3 = 3 * n4; + + /* pre rotation */ + for(i=0;ifft, x); + + /* post rotation */ + for(i=0;itcos); + av_freep(&s->tsin); + ff_fft_end(&s->fft); +} Index: apps/codecs/libcook/dsputil.h =================================================================== --- apps/codecs/libcook/dsputil.h (revision 0) +++ apps/codecs/libcook/dsputil.h (revision 0) @@ -0,0 +1,909 @@ +/* + * DSP utils + * Copyright (c) 2000, 2001, 2002 Fabrice Bellard + * Copyright (c) 2002-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 libavcodec/dsputil.h + * DSP utils. + * note, many functions in here may use MMX which trashes the FPU state, it is + * absolutely necessary to call emms_c() between dsp & float/double code + */ + +#ifndef AVCODEC_DSPUTIL_H +#define AVCODEC_DSPUTIL_H + +#include "libavutil/intreadwrite.h" +#include "avcodec.h" + + +//#define DEBUG +/* dct code */ + +#if 0 /*MT : DELETE THIS LINE.*/ + +typedef short DCTELEM; +typedef int DWTELEM; +typedef short IDWTELEM; + +void fdct_ifast (DCTELEM *data); +void fdct_ifast248 (DCTELEM *data); +void ff_jpeg_fdct_islow (DCTELEM *data); +void ff_fdct248_islow (DCTELEM *data); + +void j_rev_dct (DCTELEM *data); +void j_rev_dct4 (DCTELEM *data); +void j_rev_dct2 (DCTELEM *data); +void j_rev_dct1 (DCTELEM *data); +void ff_wmv2_idct_c(DCTELEM *data); + +void ff_fdct_mmx(DCTELEM *block); +void ff_fdct_mmx2(DCTELEM *block); +void ff_fdct_sse2(DCTELEM *block); + +void ff_h264_idct8_add_c(uint8_t *dst, DCTELEM *block, int stride); +void ff_h264_idct_add_c(uint8_t *dst, DCTELEM *block, int stride); +void ff_h264_idct8_dc_add_c(uint8_t *dst, DCTELEM *block, int stride); +void ff_h264_idct_dc_add_c(uint8_t *dst, DCTELEM *block, int stride); +void ff_h264_lowres_idct_add_c(uint8_t *dst, int stride, DCTELEM *block); +void ff_h264_lowres_idct_put_c(uint8_t *dst, int stride, DCTELEM *block); +void ff_h264_idct_add16_c(uint8_t *dst, const int *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]); +void ff_h264_idct_add16intra_c(uint8_t *dst, const int *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]); +void ff_h264_idct8_add4_c(uint8_t *dst, const int *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]); +void ff_h264_idct_add8_c(uint8_t **dest, const int *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]); + +void ff_vector_fmul_add_add_c(float *dst, const float *src0, const float *src1, + const float *src2, int src3, int blocksize, int step); +void ff_vector_fmul_window_c(float *dst, const float *src0, const float *src1, + const float *win, float add_bias, int len); +void ff_float_to_int16_c(int16_t *dst, const float *src, long len); +void ff_float_to_int16_interleave_c(int16_t *dst, const float **src, long len, int channels); + +/* encoding scans */ +extern const uint8_t ff_alternate_horizontal_scan[64]; +extern const uint8_t ff_alternate_vertical_scan[64]; +extern const uint8_t ff_zigzag_direct[64]; +extern const uint8_t ff_zigzag248_direct[64]; + +/* pixel operations */ +#define MAX_NEG_CROP 1024 + +/* temporary */ +extern uint32_t ff_squareTbl[512]; +extern uint8_t ff_cropTbl[256 + 2 * MAX_NEG_CROP]; + +/* VP3 DSP functions */ +void ff_vp3_idct_c(DCTELEM *block/* align 16*/); +void ff_vp3_idct_put_c(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/); +void ff_vp3_idct_add_c(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/); + +void ff_vp3_v_loop_filter_c(uint8_t *src, int stride, int *bounding_values); +void ff_vp3_h_loop_filter_c(uint8_t *src, int stride, int *bounding_values); + +/* VP6 DSP functions */ +void ff_vp6_filter_diag4_c(uint8_t *dst, uint8_t *src, int stride, + const int16_t *h_weights, const int16_t *v_weights); + +/* 1/2^n downscaling functions from imgconvert.c */ +void ff_img_copy_plane(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height); +void ff_shrink22(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height); +void ff_shrink44(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height); +void ff_shrink88(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height); + +void ff_gmc_c(uint8_t *dst, uint8_t *src, int stride, int h, int ox, int oy, + int dxx, int dxy, int dyx, int dyy, int shift, int r, int width, int height); + +/* minimum alignment rules ;) +If you notice errors in the align stuff, need more alignment for some ASM code +for some CPU or need to use a function with less aligned data then send a mail +to the ffmpeg-devel mailing list, ... + +!warning These alignments might not match reality, (missing attribute((align)) +stuff somewhere possible). +I (Michael) did not check them, these are just the alignments which I think +could be reached easily ... + +!future video codecs might need functions with less strict alignment +*/ + +/* +void get_pixels_c(DCTELEM *block, const uint8_t *pixels, int line_size); +void diff_pixels_c(DCTELEM *block, const uint8_t *s1, const uint8_t *s2, int stride); +void put_pixels_clamped_c(const DCTELEM *block, uint8_t *pixels, int line_size); +void add_pixels_clamped_c(const DCTELEM *block, uint8_t *pixels, int line_size); +void clear_blocks_c(DCTELEM *blocks); +*/ + +/* add and put pixel (decoding) */ +// blocksizes for op_pixels_func are 8x4,8x8 16x8 16x16 +//h for op_pixels_func is limited to {width/2, width} but never larger than 16 and never smaller then 4 +typedef void (*op_pixels_func)(uint8_t *block/*align width (8 or 16)*/, const uint8_t *pixels/*align 1*/, int line_size, int h); +typedef void (*tpel_mc_func)(uint8_t *block/*align width (8 or 16)*/, const uint8_t *pixels/*align 1*/, int line_size, int w, int h); +typedef void (*qpel_mc_func)(uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, int stride); +typedef void (*h264_chroma_mc_func)(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int srcStride, int h, int x, int y); +typedef void (*h264_weight_func)(uint8_t *block, int stride, int log2_denom, int weight, int offset); +typedef void (*h264_biweight_func)(uint8_t *dst, uint8_t *src, int stride, int log2_denom, int weightd, int weights, int offset); + +#define DEF_OLD_QPEL(name)\ +void ff_put_ ## name (uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, int stride);\ +void ff_put_no_rnd_ ## name (uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, int stride);\ +void ff_avg_ ## name (uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, int stride); + +DEF_OLD_QPEL(qpel16_mc11_old_c) +DEF_OLD_QPEL(qpel16_mc31_old_c) +DEF_OLD_QPEL(qpel16_mc12_old_c) +DEF_OLD_QPEL(qpel16_mc32_old_c) +DEF_OLD_QPEL(qpel16_mc13_old_c) +DEF_OLD_QPEL(qpel16_mc33_old_c) +DEF_OLD_QPEL(qpel8_mc11_old_c) +DEF_OLD_QPEL(qpel8_mc31_old_c) +DEF_OLD_QPEL(qpel8_mc12_old_c) +DEF_OLD_QPEL(qpel8_mc32_old_c) +DEF_OLD_QPEL(qpel8_mc13_old_c) +DEF_OLD_QPEL(qpel8_mc33_old_c) + +#define CALL_2X_PIXELS(a, b, n)\ +static void a(uint8_t *block, const uint8_t *pixels, int line_size, int h){\ + b(block , pixels , line_size, h);\ + b(block+n, pixels+n, line_size, h);\ +} + +/* motion estimation */ +// h is limited to {width/2, width, 2*width} but never larger than 16 and never smaller then 2 +// although currently h<4 is not used as functions with width <8 are neither used nor implemented +typedef int (*me_cmp_func)(void /*MpegEncContext*/ *s, uint8_t *blk1/*align width (8 or 16)*/, uint8_t *blk2/*align 1*/, int line_size, int h)/* __attribute__ ((const))*/; + + +// for snow slices +typedef struct slice_buffer_s slice_buffer; + +/** + * Scantable. + */ +typedef struct ScanTable{ + const uint8_t *scantable; + uint8_t permutated[64]; + uint8_t raster_end[64]; + + +#if ARCH_PPC + /** Used by dct_quantize_altivec to find last-non-zero */ + DECLARE_ALIGNED(16, uint8_t, inverse[64]); +#endif +} ScanTable; + +void ff_init_scantable(uint8_t *, ScanTable *st, const uint8_t *src_scantable); + +void ff_emulated_edge_mc(uint8_t *buf, uint8_t *src, int linesize, + int block_w, int block_h, + int src_x, int src_y, int w, int h); + +/** + * DSPContext. + */ +typedef struct DSPContext { + /* pixel ops : interface with DCT */ + void (*get_pixels)(DCTELEM *block/*align 16*/, const uint8_t *pixels/*align 8*/, int line_size); + void (*diff_pixels)(DCTELEM *block/*align 16*/, const uint8_t *s1/*align 8*/, const uint8_t *s2/*align 8*/, int stride); + void (*put_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size); + void (*put_signed_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size); + void (*add_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size); + void (*add_pixels8)(uint8_t *pixels, DCTELEM *block, int line_size); + void (*add_pixels4)(uint8_t *pixels, DCTELEM *block, int line_size); + int (*sum_abs_dctelem)(DCTELEM *block/*align 16*/); + /** + * translational global motion compensation. + */ + void (*gmc1)(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int srcStride, int h, int x16, int y16, int rounder); + /** + * global motion compensation. + */ + void (*gmc )(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int ox, int oy, + int dxx, int dxy, int dyx, int dyy, int shift, int r, int width, int height); + void (*clear_block)(DCTELEM *block/*align 16*/); + void (*clear_blocks)(DCTELEM *blocks/*align 16*/); + int (*pix_sum)(uint8_t * pix, int line_size); + int (*pix_norm1)(uint8_t * pix, int line_size); +// 16x16 8x8 4x4 2x2 16x8 8x4 4x2 8x16 4x8 2x4 + + me_cmp_func sad[6]; /* identical to pix_absAxA except additional void * */ + me_cmp_func sse[6]; + me_cmp_func hadamard8_diff[6]; + me_cmp_func dct_sad[6]; + me_cmp_func quant_psnr[6]; + me_cmp_func bit[6]; + me_cmp_func rd[6]; + me_cmp_func vsad[6]; + me_cmp_func vsse[6]; + me_cmp_func nsse[6]; + me_cmp_func w53[6]; + me_cmp_func w97[6]; + me_cmp_func dct_max[6]; + me_cmp_func dct264_sad[6]; + + me_cmp_func me_pre_cmp[6]; + me_cmp_func me_cmp[6]; + me_cmp_func me_sub_cmp[6]; + me_cmp_func mb_cmp[6]; + me_cmp_func ildct_cmp[6]; //only width 16 used + me_cmp_func frame_skip_cmp[6]; //only width 8 used + + int (*ssd_int8_vs_int16)(const int8_t *pix1, const int16_t *pix2, + int size); + + /** + * Halfpel motion compensation with rounding (a+b+1)>>1. + * this is an array[4][4] of motion compensation functions for 4 + * horizontal blocksizes (8,16) and the 4 halfpel positions
+ * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ] + * @param block destination where the result is stored + * @param pixels source + * @param line_size number of bytes in a horizontal line of block + * @param h height + */ + op_pixels_func put_pixels_tab[4][4]; + + /** + * Halfpel motion compensation with rounding (a+b+1)>>1. + * This is an array[4][4] of motion compensation functions for 4 + * horizontal blocksizes (8,16) and the 4 halfpel positions
+ * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ] + * @param block destination into which the result is averaged (a+b+1)>>1 + * @param pixels source + * @param line_size number of bytes in a horizontal line of block + * @param h height + */ + op_pixels_func avg_pixels_tab[4][4]; + + /** + * Halfpel motion compensation with no rounding (a+b)>>1. + * this is an array[2][4] of motion compensation functions for 2 + * horizontal blocksizes (8,16) and the 4 halfpel positions
+ * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ] + * @param block destination where the result is stored + * @param pixels source + * @param line_size number of bytes in a horizontal line of block + * @param h height + */ + op_pixels_func put_no_rnd_pixels_tab[4][4]; + + /** + * Halfpel motion compensation with no rounding (a+b)>>1. + * this is an array[2][4] of motion compensation functions for 2 + * horizontal blocksizes (8,16) and the 4 halfpel positions
+ * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ] + * @param block destination into which the result is averaged (a+b)>>1 + * @param pixels source + * @param line_size number of bytes in a horizontal line of block + * @param h height + */ + op_pixels_func avg_no_rnd_pixels_tab[4][4]; + + void (*put_no_rnd_pixels_l2[2])(uint8_t *block/*align width (8 or 16)*/, const uint8_t *a/*align 1*/, const uint8_t *b/*align 1*/, int line_size, int h); + + /** + * Thirdpel motion compensation with rounding (a+b+1)>>1. + * this is an array[12] of motion compensation functions for the 9 thirdpe + * positions
+ * *pixels_tab[ xthirdpel + 4*ythirdpel ] + * @param block destination where the result is stored + * @param pixels source + * @param line_size number of bytes in a horizontal line of block + * @param h height + */ + tpel_mc_func put_tpel_pixels_tab[11]; //FIXME individual func ptr per width? + tpel_mc_func avg_tpel_pixels_tab[11]; //FIXME individual func ptr per width? + + qpel_mc_func put_qpel_pixels_tab[2][16]; + qpel_mc_func avg_qpel_pixels_tab[2][16]; + qpel_mc_func put_no_rnd_qpel_pixels_tab[2][16]; + qpel_mc_func avg_no_rnd_qpel_pixels_tab[2][16]; + qpel_mc_func put_mspel_pixels_tab[8]; + + /** + * h264 Chroma MC + */ + h264_chroma_mc_func put_h264_chroma_pixels_tab[3]; + /* This is really one func used in VC-1 decoding */ + h264_chroma_mc_func put_no_rnd_h264_chroma_pixels_tab[3]; + h264_chroma_mc_func avg_h264_chroma_pixels_tab[3]; + + qpel_mc_func put_h264_qpel_pixels_tab[4][16]; + qpel_mc_func avg_h264_qpel_pixels_tab[4][16]; + + qpel_mc_func put_2tap_qpel_pixels_tab[4][16]; + qpel_mc_func avg_2tap_qpel_pixels_tab[4][16]; + + h264_weight_func weight_h264_pixels_tab[10]; + h264_biweight_func biweight_h264_pixels_tab[10]; + + /* AVS specific */ + qpel_mc_func put_cavs_qpel_pixels_tab[2][16]; + qpel_mc_func avg_cavs_qpel_pixels_tab[2][16]; + void (*cavs_filter_lv)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2); + void (*cavs_filter_lh)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2); + void (*cavs_filter_cv)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2); + void (*cavs_filter_ch)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2); + void (*cavs_idct8_add)(uint8_t *dst, DCTELEM *block, int stride); + + me_cmp_func pix_abs[2][4]; + + /* huffyuv specific */ + void (*add_bytes)(uint8_t *dst/*align 16*/, uint8_t *src/*align 16*/, int w); + void (*add_bytes_l2)(uint8_t *dst/*align 16*/, uint8_t *src1/*align 16*/, uint8_t *src2/*align 16*/, int w); + void (*diff_bytes)(uint8_t *dst/*align 16*/, uint8_t *src1/*align 16*/, uint8_t *src2/*align 1*/,int w); + /** + * subtract huffyuv's variant of median prediction + * note, this might read from src1[-1], src2[-1] + */ + void (*sub_hfyu_median_prediction)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w, int *left, int *left_top); + void (*add_hfyu_median_prediction)(uint8_t *dst, uint8_t *top, uint8_t *diff, int w, int *left, int *left_top); + /* this might write to dst[w] */ + void (*add_png_paeth_prediction)(uint8_t *dst, uint8_t *src, uint8_t *top, int w, int bpp); + void (*bswap_buf)(uint32_t *dst, const uint32_t *src, int w); + + void (*h264_v_loop_filter_luma)(uint8_t *pix/*align 16*/, int stride, int alpha, int beta, int8_t *tc0); + void (*h264_h_loop_filter_luma)(uint8_t *pix/*align 4 */, int stride, int alpha, int beta, int8_t *tc0); + /* v/h_loop_filter_luma_intra: align 16 */ + void (*h264_v_loop_filter_luma_intra)(uint8_t *pix, int stride, int alpha, int beta); + void (*h264_h_loop_filter_luma_intra)(uint8_t *pix, int stride, int alpha, int beta); + void (*h264_v_loop_filter_chroma)(uint8_t *pix/*align 8*/, int stride, int alpha, int beta, int8_t *tc0); + void (*h264_h_loop_filter_chroma)(uint8_t *pix/*align 4*/, int stride, int alpha, int beta, int8_t *tc0); + void (*h264_v_loop_filter_chroma_intra)(uint8_t *pix/*align 8*/, int stride, int alpha, int beta); + void (*h264_h_loop_filter_chroma_intra)(uint8_t *pix/*align 8*/, int stride, int alpha, int beta); + // h264_loop_filter_strength: simd only. the C version is inlined in h264.c + void (*h264_loop_filter_strength)(int16_t bS[2][4][4], uint8_t nnz[40], int8_t ref[2][40], int16_t mv[2][40][2], + int bidir, int edges, int step, int mask_mv0, int mask_mv1, int field); + + void (*h263_v_loop_filter)(uint8_t *src, int stride, int qscale); + void (*h263_h_loop_filter)(uint8_t *src, int stride, int qscale); + + void (*h261_loop_filter)(uint8_t *src, int stride); + + void (*x8_v_loop_filter)(uint8_t *src, int stride, int qscale); + void (*x8_h_loop_filter)(uint8_t *src, int stride, int qscale); + + void (*vp3_v_loop_filter)(uint8_t *src, int stride, int *bounding_values); + void (*vp3_h_loop_filter)(uint8_t *src, int stride, int *bounding_values); + + void (*vp6_filter_diag4)(uint8_t *dst, uint8_t *src, int stride, + const int16_t *h_weights,const int16_t *v_weights); + + /* assume len is a multiple of 4, and arrays are 16-byte aligned */ + void (*vorbis_inverse_coupling)(float *mag, float *ang, int blocksize); + void (*ac3_downmix)(float (*samples)[256], float (*matrix)[2], int out_ch, int in_ch, int len); + /* no alignment needed */ + void (*flac_compute_autocorr)(const int32_t *data, int len, int lag, double *autoc); + /* assume len is a multiple of 8, and arrays are 16-byte aligned */ + void (*vector_fmul)(float *dst, const float *src, int len); + void (*vector_fmul_reverse)(float *dst, const float *src0, const float *src1, int len); + /* assume len is a multiple of 8, and src arrays are 16-byte aligned */ + void (*vector_fmul_add_add)(float *dst, const float *src0, const float *src1, const float *src2, int src3, int len, int step); + /* assume len is a multiple of 4, and arrays are 16-byte aligned */ + void (*vector_fmul_window)(float *dst, const float *src0, const float *src1, const float *win, float add_bias, int len); + /* assume len is a multiple of 8, and arrays are 16-byte aligned */ + void (*int32_to_float_fmul_scalar)(float *dst, const int *src, float mul, int len); + + /* C version: convert floats from the range [384.0,386.0] to ints in [-32768,32767] + * simd versions: convert floats from [-32768.0,32767.0] without rescaling and arrays are 16byte aligned */ + void (*float_to_int16)(int16_t *dst, const float *src, long len); + void (*float_to_int16_interleave)(int16_t *dst, const float **src, long len, int channels); + + /* (I)DCT */ + void (*fdct)(DCTELEM *block/* align 16*/); + void (*fdct248)(DCTELEM *block/* align 16*/); + + /* IDCT really*/ + void (*idct)(DCTELEM *block/* align 16*/); + + /** + * block -> idct -> clip to unsigned 8 bit -> dest. + * (-1392, 0, 0, ...) -> idct -> (-174, -174, ...) -> put -> (0, 0, ...) + * @param line_size size in bytes of a horizontal line of dest + */ + void (*idct_put)(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/); + + /** + * block -> idct -> add dest -> clip to unsigned 8 bit -> dest. + * @param line_size size in bytes of a horizontal line of dest + */ + void (*idct_add)(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/); + + /** + * idct input permutation. + * several optimized IDCTs need a permutated input (relative to the normal order of the reference + * IDCT) + * this permutation must be performed before the idct_put/add, note, normally this can be merged + * with the zigzag/alternate scan
+ * an example to avoid confusion: + * - (->decode coeffs -> zigzag reorder -> dequant -> reference idct ->...) + * - (x -> referece dct -> reference idct -> x) + * - (x -> referece dct -> simple_mmx_perm = idct_permutation -> simple_idct_mmx -> x) + * - (->decode coeffs -> zigzag reorder -> simple_mmx_perm -> dequant -> simple_idct_mmx ->...) + */ + uint8_t idct_permutation[64]; + int idct_permutation_type; +#define FF_NO_IDCT_PERM 1 +#define FF_LIBMPEG2_IDCT_PERM 2 +#define FF_SIMPLE_IDCT_PERM 3 +#define FF_TRANSPOSE_IDCT_PERM 4 +#define FF_PARTTRANS_IDCT_PERM 5 +#define FF_SSE2_IDCT_PERM 6 + + int (*try_8x8basis)(int16_t rem[64], int16_t weight[64], int16_t basis[64], int scale); + void (*add_8x8basis)(int16_t rem[64], int16_t basis[64], int scale); +#define BASIS_SHIFT 16 +#define RECON_SHIFT 6 + + void (*draw_edges)(uint8_t *buf, int wrap, int width, int height, int w); +#define EDGE_WIDTH 16 + + /* h264 functions */ + /* NOTE!!! if you implement any of h264_idct8_add, h264_idct8_add4 then you must implement all of them + NOTE!!! if you implement any of h264_idct_add, h264_idct_add16, h264_idct_add16intra, h264_idct_add8 then you must implement all of them + The reason for above, is that no 2 out of one list may use a different permutation. + */ + void (*h264_idct_add)(uint8_t *dst/*align 4*/, DCTELEM *block/*align 16*/, int stride); + void (*h264_idct8_add)(uint8_t *dst/*align 8*/, DCTELEM *block/*align 16*/, int stride); + void (*h264_idct_dc_add)(uint8_t *dst/*align 4*/, DCTELEM *block/*align 16*/, int stride); + void (*h264_idct8_dc_add)(uint8_t *dst/*align 8*/, DCTELEM *block/*align 16*/, int stride); + void (*h264_dct)(DCTELEM block[4][4]); + void (*h264_idct_add16)(uint8_t *dst/*align 16*/, const int *blockoffset, DCTELEM *block/*align 16*/, int stride, const uint8_t nnzc[6*8]); + void (*h264_idct8_add4)(uint8_t *dst/*align 16*/, const int *blockoffset, DCTELEM *block/*align 16*/, int stride, const uint8_t nnzc[6*8]); + void (*h264_idct_add8)(uint8_t **dst/*align 16*/, const int *blockoffset, DCTELEM *block/*align 16*/, int stride, const uint8_t nnzc[6*8]); + void (*h264_idct_add16intra)(uint8_t *dst/*align 16*/, const int *blockoffset, DCTELEM *block/*align 16*/, int stride, const uint8_t nnzc[6*8]); + + /* snow wavelet */ + void (*vertical_compose97i)(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5, int width); + void (*horizontal_compose97i)(IDWTELEM *b, int width); + void (*inner_add_yblock)(const uint8_t *obmc, const int obmc_stride, uint8_t * * block, int b_w, int b_h, int src_x, int src_y, int src_stride, slice_buffer * sb, int add, uint8_t * dst8); + + void (*prefetch)(void *mem, int stride, int h); + + void (*shrink[4])(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height); + + /* vc1 functions */ + void (*vc1_inv_trans_8x8)(DCTELEM *b); + void (*vc1_inv_trans_8x4)(uint8_t *dest, int line_size, DCTELEM *block); + void (*vc1_inv_trans_4x8)(uint8_t *dest, int line_size, DCTELEM *block); + void (*vc1_inv_trans_4x4)(uint8_t *dest, int line_size, DCTELEM *block); + void (*vc1_v_overlap)(uint8_t* src, int stride); + void (*vc1_h_overlap)(uint8_t* src, int stride); + /* put 8x8 block with bicubic interpolation and quarterpel precision + * last argument is actually round value instead of height + */ + op_pixels_func put_vc1_mspel_pixels_tab[16]; + + /* intrax8 functions */ + void (*x8_spatial_compensation[12])(uint8_t *src , uint8_t *dst, int linesize); + void (*x8_setup_spatial_compensation)(uint8_t *src, uint8_t *dst, int linesize, + int * range, int * sum, int edges); + + /* ape functions */ + /** + * Add contents of the second vector to the first one. + * @param len length of vectors, should be multiple of 16 + */ + void (*add_int16)(int16_t *v1/*align 16*/, int16_t *v2, int len); + /** + * Add contents of the second vector to the first one. + * @param len length of vectors, should be multiple of 16 + */ + void (*sub_int16)(int16_t *v1/*align 16*/, int16_t *v2, int len); + /** + * Calculate scalar product of two vectors. + * @param len length of vectors, should be multiple of 16 + * @param shift number of bits to discard from product + */ + int32_t (*scalarproduct_int16)(int16_t *v1, int16_t *v2/*align 16*/, int len, int shift); + + /* rv30 functions */ + qpel_mc_func put_rv30_tpel_pixels_tab[4][16]; + qpel_mc_func avg_rv30_tpel_pixels_tab[4][16]; + + /* rv40 functions */ + qpel_mc_func put_rv40_qpel_pixels_tab[4][16]; + qpel_mc_func avg_rv40_qpel_pixels_tab[4][16]; + h264_chroma_mc_func put_rv40_chroma_pixels_tab[3]; + h264_chroma_mc_func avg_rv40_chroma_pixels_tab[3]; +} DSPContext; + +void dsputil_static_init(void); +void dsputil_init(DSPContext* p, AVCodecContext *avctx); + +int ff_check_alignment(void); + +/** + * permute block according to permuatation. + * @param last last non zero element in scantable order + */ +void ff_block_permute(DCTELEM *block, uint8_t *permutation, const uint8_t *scantable, int last); + +void ff_set_cmp(DSPContext* c, me_cmp_func *cmp, int type); + +#define BYTE_VEC32(c) ((c)*0x01010101UL) + +static inline uint32_t rnd_avg32(uint32_t a, uint32_t b) +{ + return (a | b) - (((a ^ b) & ~BYTE_VEC32(0x01)) >> 1); +} + +static inline uint32_t no_rnd_avg32(uint32_t a, uint32_t b) +{ + return (a & b) + (((a ^ b) & ~BYTE_VEC32(0x01)) >> 1); +} + +static inline int get_penalty_factor(int lambda, int lambda2, int type){ + switch(type&0xFF){ + default: + case FF_CMP_SAD: + return lambda>>FF_LAMBDA_SHIFT; + case FF_CMP_DCT: + return (3*lambda)>>(FF_LAMBDA_SHIFT+1); + case FF_CMP_W53: + return (4*lambda)>>(FF_LAMBDA_SHIFT); + case FF_CMP_W97: + return (2*lambda)>>(FF_LAMBDA_SHIFT); + case FF_CMP_SATD: + case FF_CMP_DCT264: + return (2*lambda)>>FF_LAMBDA_SHIFT; + case FF_CMP_RD: + case FF_CMP_PSNR: + case FF_CMP_SSE: + case FF_CMP_NSSE: + return lambda2>>FF_LAMBDA_SHIFT; + case FF_CMP_BIT: + return 1; + } +} + +/** + * Empty mmx state. + * this must be called between any dsp function and float/double code. + * for example sin(); dsp->idct_put(); emms_c(); cos() + */ +#define emms_c() + +/* should be defined by architectures supporting + one or more MultiMedia extension */ +int mm_support(void); + +void dsputil_init_alpha(DSPContext* c, AVCodecContext *avctx); +void dsputil_init_arm(DSPContext* c, AVCodecContext *avctx); +void dsputil_init_bfin(DSPContext* c, AVCodecContext *avctx); +void dsputil_init_mlib(DSPContext* c, AVCodecContext *avctx); +void dsputil_init_mmi(DSPContext* c, AVCodecContext *avctx); +void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx); +void dsputil_init_ppc(DSPContext* c, AVCodecContext *avctx); +void dsputil_init_sh4(DSPContext* c, AVCodecContext *avctx); +void dsputil_init_vis(DSPContext* c, AVCodecContext *avctx); +#endif /*MT : DELETE THIS LINE ONLY. */ +#define DECLARE_ALIGNED_16(t, v) DECLARE_ALIGNED(16, t, v) +#if 0 /*MT : DELETE THIS LINE ONLY. */ +#if HAVE_MMX + +#undef emms_c + +extern int mm_flags; + +void add_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size); +void put_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size); +void put_signed_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size); + +static inline void emms(void) +{ + __asm__ volatile ("emms;":::"memory"); +} + + +#define emms_c() \ +{\ + if (mm_flags & FF_MM_MMX)\ + emms();\ +} + +void dsputil_init_pix_mmx(DSPContext* c, AVCodecContext *avctx); + +#elif ARCH_ARM + +extern int mm_flags; + +#if HAVE_NEON +# define DECLARE_ALIGNED_8(t, v) DECLARE_ALIGNED(16, t, v) +# define STRIDE_ALIGN 16 +#endif + +#elif ARCH_PPC + +extern int mm_flags; + +#define DECLARE_ALIGNED_8(t, v) DECLARE_ALIGNED(16, t, v) +#define STRIDE_ALIGN 16 + +#elif HAVE_MMI + +#define DECLARE_ALIGNED_8(t, v) DECLARE_ALIGNED(16, t, v) +#define STRIDE_ALIGN 16 + +#else + +#define mm_flags 0 +#define mm_support() 0 + +#endif +#endif /* MT : DELETE THIS LINE ONLY */ +#ifndef DECLARE_ALIGNED_8 +# define DECLARE_ALIGNED_8(t, v) DECLARE_ALIGNED(8, t, v) +#endif +#if 0 /* MT : DELETE THIS LINE ONLY */ +#ifndef STRIDE_ALIGN +# define STRIDE_ALIGN 8 +#endif + +/* PSNR */ +void get_psnr(uint8_t *orig_image[3], uint8_t *coded_image[3], + int orig_linesize[3], int coded_linesize, + AVCodecContext *avctx); + +#endif /*MT : DELETE THIS LINE.*/ + +/* FFT computation */ + +/* NOTE: soon integer code will be added, so you must use the + FFTSample type */ +typedef float FFTSample; + +struct MDCTContext; + +typedef struct FFTComplex { + FFTSample re, im; +} FFTComplex; + +typedef struct FFTContext { + int nbits; + int inverse; + uint16_t *revtab; + FFTComplex *exptab; + FFTComplex *exptab1; /* only used by SSE code */ + FFTComplex *tmp_buf; + void (*fft_permute)(struct FFTContext *s, FFTComplex *z); + void (*fft_calc)(struct FFTContext *s, FFTComplex *z); + void (*imdct_calc)(struct MDCTContext *s, FFTSample *output, const FFTSample *input); + void (*imdct_half)(struct MDCTContext *s, FFTSample *output, const FFTSample *input); +} FFTContext; + +extern FFTSample* ff_cos_tabs[13]; + +/** + * Sets up a complex FFT. + * @param nbits log2 of the length of the input array + * @param inverse if 0 perform the forward transform, if 1 perform the inverse + */ +int ff_fft_init(FFTContext *s, int nbits, int inverse); +void ff_fft_permute_c(FFTContext *s, FFTComplex *z); +void ff_fft_permute_sse(FFTContext *s, FFTComplex *z); +void ff_fft_calc_c(FFTContext *s, FFTComplex *z); +void ff_fft_calc_sse(FFTContext *s, FFTComplex *z); +void ff_fft_calc_3dn(FFTContext *s, FFTComplex *z); +void ff_fft_calc_3dn2(FFTContext *s, FFTComplex *z); +void ff_fft_calc_altivec(FFTContext *s, FFTComplex *z); + +/** + * Do the permutation needed BEFORE calling ff_fft_calc(). + */ +static inline void ff_fft_permute(FFTContext *s, FFTComplex *z) +{ + s->fft_permute(s, z); +} +/** + * Do a complex FFT with the parameters defined in ff_fft_init(). The + * input data must be permuted before. No 1.0/sqrt(n) normalization is done. + */ +static inline void ff_fft_calc(FFTContext *s, FFTComplex *z) +{ + s->fft_calc(s, z); +} +void ff_fft_end(FFTContext *s); + +#endif /*MT : DELETE THIS LINE.*/ + +/* MDCT computation */ + +typedef struct MDCTContext { + int n; /* size of MDCT (i.e. number of input data * 2) */ + int nbits; /* n = 2^nbits */ + /* pre/post rotation tables */ + FFTSample *tcos; + FFTSample *tsin; + FFTContext fft; +} MDCTContext; + +static inline void ff_imdct_calc(MDCTContext *s, FFTSample *output, const FFTSample *input) +{ + s->fft.imdct_calc(s, output, input); +} +static inline void ff_imdct_half(MDCTContext *s, FFTSample *output, const FFTSample *input) +{ + s->fft.imdct_half(s, output, input); +} +#if 0 /* MT : DELETE THIS LINE. */ +/** + * Generate a Kaiser-Bessel Derived Window. + * @param window pointer to half window + * @param alpha determines window shape + * @param n size of half window + */ +void ff_kbd_window_init(float *window, float alpha, int n); +#endif /* MT : DELETE THIS LINE.*/ +/** + * Generate a sine window. + * @param window pointer to half window + * @param n size of half window + */ +void ff_sine_window_init(float *window, int n); +extern float ff_sine_128 [ 128]; +extern float ff_sine_256 [ 256]; +extern float ff_sine_512 [ 512]; +extern float ff_sine_1024[1024]; +extern float ff_sine_2048[2048]; +extern float ff_sine_4096[4096]; +extern float *ff_sine_windows[6]; + +int ff_mdct_init(MDCTContext *s, int nbits, int inverse); +void ff_imdct_calc_c(MDCTContext *s, FFTSample *output, const FFTSample *input); +void ff_imdct_half_c(MDCTContext *s, FFTSample *output, const FFTSample *input); +void ff_imdct_calc_3dn(MDCTContext *s, FFTSample *output, const FFTSample *input); +void ff_imdct_half_3dn(MDCTContext *s, FFTSample *output, const FFTSample *input); +void ff_imdct_calc_3dn2(MDCTContext *s, FFTSample *output, const FFTSample *input); +void ff_imdct_half_3dn2(MDCTContext *s, FFTSample *output, const FFTSample *input); +void ff_imdct_calc_sse(MDCTContext *s, FFTSample *output, const FFTSample *input); +void ff_imdct_half_sse(MDCTContext *s, FFTSample *output, const FFTSample *input); +void ff_mdct_calc(MDCTContext *s, FFTSample *out, const FFTSample *input); +void ff_mdct_end(MDCTContext *s); + +#if 0 /* MT : DELETE THIS LINE.*/ + +/* Real Discrete Fourier Transform */ + +enum RDFTransformType { + RDFT, + IRDFT, + RIDFT, + IRIDFT, +}; + +typedef struct { + int nbits; + int inverse; + int sign_convention; + + /* pre/post rotation tables */ + FFTSample *tcos; + FFTSample *tsin; + FFTContext fft; +} RDFTContext; + +/** + * Sets up a real FFT. + * @param nbits log2 of the length of the input array + * @param trans the type of transform + */ +int ff_rdft_init(RDFTContext *s, int nbits, enum RDFTransformType trans); +void ff_rdft_calc(RDFTContext *s, FFTSample *data); +void ff_rdft_end(RDFTContext *s); + +#define WRAPPER8_16(name8, name16)\ +static int name16(void /*MpegEncContext*/ *s, uint8_t *dst, uint8_t *src, int stride, int h){\ + return name8(s, dst , src , stride, h)\ + +name8(s, dst+8 , src+8 , stride, h);\ +} + +#define WRAPPER8_16_SQ(name8, name16)\ +static int name16(void /*MpegEncContext*/ *s, uint8_t *dst, uint8_t *src, int stride, int h){\ + int score=0;\ + score +=name8(s, dst , src , stride, 8);\ + score +=name8(s, dst+8 , src+8 , stride, 8);\ + if(h==16){\ + dst += 8*stride;\ + src += 8*stride;\ + score +=name8(s, dst , src , stride, 8);\ + score +=name8(s, dst+8 , src+8 , stride, 8);\ + }\ + return score;\ +} + + +static inline void copy_block2(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h) +{ + int i; + for(i=0; i + +/* various data tables */ + +static const int expbits_tab[8] = { + 52,47,43,37,29,22,16,0, +}; + +static const float dither_tab[8] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.176777, 0.25, 0.707107, +}; + +static const float quant_centroid_tab[7][14] = { + { 0.000, 0.392, 0.761, 1.120, 1.477, 1.832, 2.183, 2.541, 2.893, 3.245, 3.598, 3.942, 4.288, 4.724 }, + { 0.000, 0.544, 1.060, 1.563, 2.068, 2.571, 3.072, 3.562, 4.070, 4.620, 0.000, 0.000, 0.000, 0.000 }, + { 0.000, 0.746, 1.464, 2.180, 2.882, 3.584, 4.316, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000 }, + { 0.000, 1.006, 2.000, 2.993, 3.985, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000 }, + { 0.000, 1.321, 2.703, 3.983, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000 }, + { 0.000, 1.657, 3.491, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000 }, + { 0.000, 1.964, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000 } +}; + +static const int invradix_tab[7] = { + 74899, 104858, 149797, 209716, 262144, 349526, 524288, +}; + +static const int kmax_tab[7] = { + 13, 9, 6, 4, 3, 2, 1, +}; + +static const int vd_tab[7] = { + 2, 2, 2, 4, 4, 5, 5, +}; + +static const int vpr_tab[7] = { + 10, 10, 10, 5, 5, 4, 4, +}; + + + +/* VLC data */ + +static const int vhsize_tab[7] = { + 191, 97, 48, 607, 246, 230, 32, +}; + +static const int vhvlcsize_tab[7] = { + 8, 7, 7, 10, 9, 9, 6, +}; + +static const uint8_t envelope_quant_index_huffbits[13][24] = { + { 4, 6, 5, 5, 4, 4, 4, 4, 4, 4, 3, 3, 3, 4, 5, 7, 8, 9, 11, 11, 12, 12, 12, 12 }, + { 10, 8, 6, 5, 5, 4, 3, 3, 3, 3, 3, 3, 4, 5, 7, 9, 11, 12, 13, 15, 15, 15, 16, 16 }, + { 12, 10, 8, 6, 5, 4, 4, 4, 4, 4, 4, 3, 3, 3, 4, 4, 5, 5, 7, 9, 11, 13, 14, 14 }, + { 13, 10, 9, 9, 7, 7, 5, 5, 4, 3, 3, 3, 3, 3, 4, 4, 4, 5, 7, 9, 11, 13, 13, 13 }, + { 12, 13, 10, 8, 6, 6, 5, 5, 4, 4, 3, 3, 3, 3, 3, 4, 5, 5, 6, 7, 9, 11, 14, 14 }, + { 12, 11, 9, 8, 8, 7, 5, 4, 4, 3, 3, 3, 3, 3, 4, 4, 5, 5, 7, 8, 10, 13, 14, 14 }, + { 15, 16, 15, 12, 10, 8, 6, 5, 4, 3, 3, 3, 2, 3, 4, 5, 5, 7, 9, 11, 13, 16, 16, 16 }, + { 14, 14, 11, 10, 9, 7, 7, 5, 5, 4, 3, 3, 2, 3, 3, 4, 5, 7, 9, 9, 12, 14, 15, 15 }, + { 9, 9, 9, 8, 7, 6, 5, 4, 3, 3, 3, 3, 3, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 13 }, + { 14, 12, 10, 8, 6, 6, 5, 4, 3, 3, 3, 3, 3, 3, 4, 5, 6, 8, 8, 9, 11, 14, 14, 14 }, + { 13, 10, 9, 8, 6, 6, 5, 4, 4, 4, 3, 3, 2, 3, 4, 5, 6, 8, 9, 9, 11, 12, 14, 14 }, + { 16, 13, 12, 11, 9, 6, 5, 5, 4, 4, 4, 3, 2, 3, 3, 4, 5, 7, 8, 10, 14, 16, 16, 16 }, + { 13, 14, 14, 14, 10, 8, 7, 7, 5, 4, 3, 3, 2, 3, 3, 4, 5, 5, 7, 9, 11, 14, 14, 14 }, +}; + +static const uint16_t envelope_quant_index_huffcodes[13][24] = { + {0x0006, 0x003e, 0x001c, 0x001d, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x0000, 0x0001, + 0x0002, 0x000d, 0x001e, 0x007e, 0x00fe, 0x01fe, 0x07fc, 0x07fd, 0x0ffc, 0x0ffd, 0x0ffe, 0x0fff}, + {0x03fe, 0x00fe, 0x003e, 0x001c, 0x001d, 0x000c, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, + 0x000d, 0x001e, 0x007e, 0x01fe, 0x07fe, 0x0ffe, 0x1ffe, 0x7ffc, 0x7ffd, 0x7ffe, 0xfffe, 0xffff}, + {0x0ffe, 0x03fe, 0x00fe, 0x003e, 0x001c, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x0000, + 0x0001, 0x0002, 0x000c, 0x000d, 0x001d, 0x001e, 0x007e, 0x01fe, 0x07fe, 0x1ffe, 0x3ffe, 0x3fff}, + {0x1ffc, 0x03fe, 0x01fc, 0x01fd, 0x007c, 0x007d, 0x001c, 0x001d, 0x000a, 0x0000, 0x0001, 0x0002, + 0x0003, 0x0004, 0x000b, 0x000c, 0x000d, 0x001e, 0x007e, 0x01fe, 0x07fe, 0x1ffd, 0x1ffe, 0x1fff}, + {0x0ffe, 0x1ffe, 0x03fe, 0x00fe, 0x003c, 0x003d, 0x001a, 0x001b, 0x000a, 0x000b, 0x0000, 0x0001, + 0x0002, 0x0003, 0x0004, 0x000c, 0x001c, 0x001d, 0x003e, 0x007e, 0x01fe, 0x07fe, 0x3ffe, 0x3fff}, + {0x0ffe, 0x07fe, 0x01fe, 0x00fc, 0x00fd, 0x007c, 0x001c, 0x000a, 0x000b, 0x0000, 0x0001, 0x0002, + 0x0003, 0x0004, 0x000c, 0x000d, 0x001d, 0x001e, 0x007d, 0x00fe, 0x03fe, 0x1ffe, 0x3ffe, 0x3fff}, + {0x7ffc, 0xfffc, 0x7ffd, 0x0ffe, 0x03fe, 0x00fe, 0x003e, 0x001c, 0x000c, 0x0002, 0x0003, 0x0004, + 0x0000, 0x0005, 0x000d, 0x001d, 0x001e, 0x007e, 0x01fe, 0x07fe, 0x1ffe, 0xfffd, 0xfffe, 0xffff}, + {0x3ffc, 0x3ffd, 0x07fe, 0x03fe, 0x01fc, 0x007c, 0x007d, 0x001c, 0x001d, 0x000c, 0x0002, 0x0003, + 0x0000, 0x0004, 0x0005, 0x000d, 0x001e, 0x007e, 0x01fd, 0x01fe, 0x0ffe, 0x3ffe, 0x7ffe, 0x7fff}, + {0x01fc, 0x01fd, 0x01fe, 0x00fc, 0x007c, 0x003c, 0x001c, 0x000c, 0x0000, 0x0001, 0x0002, 0x0003, + 0x0004, 0x0005, 0x000d, 0x001d, 0x003d, 0x007d, 0x00fd, 0x03fe, 0x07fe, 0x0ffe, 0x1ffe, 0x1fff}, + {0x3ffc, 0x0ffe, 0x03fe, 0x00fc, 0x003c, 0x003d, 0x001c, 0x000c, 0x0000, 0x0001, 0x0002, 0x0003, + 0x0004, 0x0005, 0x000d, 0x001d, 0x003e, 0x00fd, 0x00fe, 0x01fe, 0x07fe, 0x3ffd, 0x3ffe, 0x3fff}, + {0x1ffe, 0x03fe, 0x01fc, 0x00fc, 0x003c, 0x003d, 0x001c, 0x000a, 0x000b, 0x000c, 0x0002, 0x0003, + 0x0000, 0x0004, 0x000d, 0x001d, 0x003e, 0x00fd, 0x01fd, 0x01fe, 0x07fe, 0x0ffe, 0x3ffe, 0x3fff}, + {0xfffc, 0x1ffe, 0x0ffe, 0x07fe, 0x01fe, 0x003e, 0x001c, 0x001d, 0x000a, 0x000b, 0x000c, 0x0002, + 0x0000, 0x0003, 0x0004, 0x000d, 0x001e, 0x007e, 0x00fe, 0x03fe, 0x3ffe, 0xfffd, 0xfffe, 0xffff}, + {0x1ffc, 0x3ffa, 0x3ffb, 0x3ffc, 0x03fe, 0x00fe, 0x007c, 0x007d, 0x001c, 0x000c, 0x0002, 0x0003, + 0x0000, 0x0004, 0x0005, 0x000d, 0x001d, 0x001e, 0x007e, 0x01fe, 0x07fe, 0x3ffd, 0x3ffe, 0x3fff}, +}; + + +static const uint8_t cvh_huffbits0[191] = { + 1, 4, 6, 6, 7, 7, 8, 8, 8, 9, 9, 10, + 11, 11, 4, 5, 6, 7, 7, 8, 8, 9, 9, 9, + 9, 10, 11, 11, 5, 6, 7, 8, 8, 9, 9, 9, + 9, 10, 10, 10, 11, 12, 6, 7, 8, 9, 9, 9, + 9, 10, 10, 10, 10, 11, 12, 13, 7, 7, 8, 9, + 9, 9, 10, 10, 10, 10, 11, 11, 12, 13, 8, 8, + 9, 9, 9, 10, 10, 10, 10, 11, 11, 12, 13, 14, + 8, 8, 9, 9, 10, 10, 11, 11, 11, 12, 12, 13, + 13, 15, 8, 8, 9, 9, 10, 10, 11, 11, 11, 12, + 12, 13, 14, 15, 9, 9, 9, 10, 10, 10, 11, 11, + 12, 13, 12, 14, 15, 16, 9, 9, 10, 10, 10, 10, + 11, 12, 12, 14, 14, 16, 16, 0, 9, 9, 10, 10, + 11, 11, 12, 13, 13, 14, 14, 15, 0, 0, 10, 10, + 10, 11, 11, 12, 12, 13, 15, 15, 16, 0, 0, 0, + 11, 11, 11, 12, 13, 13, 13, 15, 16, 16, 0, 0, + 0, 0, 11, 11, 12, 13, 13, 14, 15, 16, 16, +}; + +static const uint16_t cvh_huffcodes0[191] = { + 0x0000,0x0008,0x002c,0x002d,0x0062,0x0063,0x00d4,0x00d5,0x00d6,0x01c6,0x01c7,0x03ca, + 0x07d6,0x07d7,0x0009,0x0014,0x002e,0x0064,0x0065,0x00d7,0x00d8,0x01c8,0x01c9,0x01ca, + 0x01cb,0x03cb,0x07d8,0x07d9,0x0015,0x002f,0x0066,0x00d9,0x00da,0x01cc,0x01cd,0x01ce, + 0x01cf,0x03cc,0x03cd,0x03ce,0x07da,0x0fe4,0x0030,0x0067,0x00db,0x01d0,0x01d1,0x01d2, + 0x01d3,0x03cf,0x03d0,0x03d1,0x03d2,0x07db,0x0fe5,0x1fea,0x0068,0x0069,0x00dc,0x01d4, + 0x01d5,0x01d6,0x03d3,0x03d4,0x03d5,0x03d6,0x07dc,0x07dd,0x0fe6,0x1feb,0x00dd,0x00de, + 0x01d7,0x01d8,0x01d9,0x03d7,0x03d8,0x03d9,0x03da,0x07de,0x07df,0x0fe7,0x1fec,0x3ff2, + 0x00df,0x00e0,0x01da,0x01db,0x03db,0x03dc,0x07e0,0x07e1,0x07e2,0x0fe8,0x0fe9,0x1fed, + 0x1fee,0x7ff4,0x00e1,0x00e2,0x01dc,0x01dd,0x03dd,0x03de,0x07e3,0x07e4,0x07e5,0x0fea, + 0x0feb,0x1fef,0x3ff3,0x7ff5,0x01de,0x01df,0x01e0,0x03df,0x03e0,0x03e1,0x07e6,0x07e7, + 0x0fec,0x1ff0,0x0fed,0x3ff4,0x7ff6,0xfff8,0x01e1,0x01e2,0x03e2,0x03e3,0x03e4,0x03e5, + 0x07e8,0x0fee,0x0fef,0x3ff5,0x3ff6,0xfff9,0xfffa,0xfffa,0x01e3,0x01e4,0x03e6,0x03e7, + 0x07e9,0x07ea,0x0ff0,0x1ff1,0x1ff2,0x3ff7,0x3ff8,0x7ff7,0x7ff7,0xfffa,0x03e8,0x03e9, + 0x03ea,0x07eb,0x07ec,0x0ff1,0x0ff2,0x1ff3,0x7ff8,0x7ff9,0xfffb,0x3ff8,0x7ff7,0x7ff7, + 0x07ed,0x07ee,0x07ef,0x0ff3,0x1ff4,0x1ff5,0x1ff6,0x7ffa,0xfffc,0xfffd,0xfffb,0xfffb, + 0x3ff8,0x7ff7,0x07f0,0x07f1,0x0ff4,0x1ff7,0x1ff8,0x3ff9,0x7ffb,0xfffe,0xffff, +}; + + +static const uint8_t cvh_huffbits1[97] = { + 1, 4, 5, 6, 7, 8, 8, 9, 10, 10, 4, 5, + 6, 7, 7, 8, 8, 9, 9, 11, 5, 5, 6, 7, + 8, 8, 9, 9, 10, 11, 6, 6, 7, 8, 8, 9, + 9, 10, 11, 12, 7, 7, 8, 8, 9, 9, 10, 11, + 11, 13, 8, 8, 8, 9, 9, 10, 10, 11, 12, 14, + 8, 8, 8, 9, 10, 11, 11, 12, 13, 15, 9, 9, + 9, 10, 11, 12, 12, 14, 14, 0, 9, 9, 9, 10, + 11, 12, 14, 16, 0, 0, 10, 10, 11, 12, 13, 14, + 16, +}; + + +static const uint16_t cvh_huffcodes1[97] = { + 0x0000,0x0008,0x0014,0x0030,0x006a,0x00e2,0x00e3,0x01e4,0x03ec,0x03ed,0x0009,0x0015, + 0x0031,0x006b,0x006c,0x00e4,0x00e5,0x01e5,0x01e6,0x07f0,0x0016,0x0017,0x0032,0x006d, + 0x00e6,0x00e7,0x01e7,0x01e8,0x03ee,0x07f1,0x0033,0x0034,0x006e,0x00e8,0x00e9,0x01e9, + 0x01ea,0x03ef,0x07f2,0x0ff6,0x006f,0x0070,0x00ea,0x00eb,0x01eb,0x01ec,0x03f0,0x07f3, + 0x07f4,0x1ffa,0x00ec,0x00ed,0x00ee,0x01ed,0x01ee,0x03f1,0x03f2,0x07f5,0x0ff7,0x3ffa, + 0x00ef,0x00f0,0x00f1,0x01ef,0x03f3,0x07f6,0x07f7,0x0ff8,0x1ffb,0x7ffe,0x01f0,0x01f1, + 0x01f2,0x03f4,0x07f8,0x0ff9,0x0ffa,0x3ffb,0x3ffc,0x0000,0x01f3,0x01f4,0x01f5,0x03f5, + 0x07f9,0x0ffb,0x3ffd,0xfffe,0x0000,0x0000,0x03f6,0x03f7,0x07fa,0x0ffc,0x1ffc,0x3ffe, + 0xffff, +}; + +static const uint8_t cvh_huffbits2[48] = { + 1, 4, 5, 7, 8, 9, 10, 3, 4, 5, 7, 8, + 9, 10, 5, 5, 6, 7, 8, 10, 10, 7, 6, 7, + 8, 9, 10, 12, 8, 8, 8, 9, 10, 12, 14, 8, + 9, 9, 10, 11, 15, 16, 9, 10, 11, 12, 13, 16, +}; + +static const uint16_t cvh_huffcodes2[48] = { + 0x0000,0x000a,0x0018,0x0074,0x00f2,0x01f4,0x03f6,0x0004,0x000b,0x0019,0x0075,0x00f3, + 0x01f5,0x03f7,0x001a,0x001b,0x0038,0x0076,0x00f4,0x03f8,0x03f9,0x0077,0x0039,0x0078, + 0x00f5,0x01f6,0x03fa,0x0ffc,0x00f6,0x00f7,0x00f8,0x01f7,0x03fb,0x0ffd,0x3ffe,0x00f9, + 0x01f8,0x01f9,0x03fc,0x07fc,0x7ffe,0xfffe,0x01fa,0x03fd,0x07fd,0x0ffe,0x1ffe,0xffff, +}; + +static const uint8_t cvh_huffbits3[607] = { + 2, 4, 6, 8, 10, 5, 5, 6, 8, 10, 7, 8, + 8, 10, 12, 9, 9, 10, 12, 15, 10, 11, 13, 16, + 16, 5, 6, 8, 10, 11, 5, 6, 8, 10, 12, 7, + 7, 8, 10, 13, 9, 9, 10, 12, 15, 12, 11, 13, + 16, 16, 7, 9, 10, 12, 15, 7, 8, 10, 12, 13, + 9, 9, 11, 13, 16, 11, 11, 12, 14, 16, 12, 12, + 14, 16, 0, 9, 11, 12, 16, 16, 9, 10, 13, 15, + 16, 10, 11, 12, 16, 16, 13, 13, 16, 16, 16, 16, + 16, 15, 16, 0, 11, 13, 16, 16, 15, 11, 13, 15, + 16, 16, 13, 13, 16, 16, 0, 14, 16, 16, 16, 0, + 16, 16, 0, 0, 0, 4, 6, 8, 10, 13, 6, 6, + 8, 10, 13, 9, 8, 10, 12, 16, 10, 10, 11, 15, + 16, 13, 12, 14, 16, 16, 5, 6, 8, 11, 13, 6, + 6, 8, 10, 13, 8, 8, 9, 11, 14, 10, 10, 12, + 12, 16, 13, 12, 13, 15, 16, 7, 8, 9, 12, 16, + 7, 8, 10, 12, 14, 9, 9, 10, 13, 16, 11, 10, + 12, 15, 16, 13, 13, 16, 16, 0, 9, 11, 13, 16, + 16, 9, 10, 12, 15, 16, 10, 11, 13, 16, 16, 13, + 12, 16, 16, 16, 16, 16, 16, 16, 0, 11, 13, 16, + 16, 16, 11, 13, 16, 16, 16, 12, 13, 15, 16, 0, + 16, 16, 16, 16, 0, 16, 16, 0, 0, 0, 6, 8, + 11, 13, 16, 8, 8, 10, 12, 16, 11, 10, 11, 13, + 16, 12, 13, 13, 15, 16, 16, 16, 14, 16, 0, 6, + 8, 10, 13, 16, 8, 8, 10, 12, 16, 10, 10, 11, + 13, 16, 13, 12, 13, 16, 16, 14, 14, 14, 16, 0, + 8, 9, 11, 13, 16, 8, 9, 11, 16, 14, 10, 10, + 12, 15, 16, 12, 12, 13, 16, 16, 15, 16, 16, 16, + 0, 10, 12, 15, 16, 16, 10, 12, 12, 14, 16, 12, + 12, 13, 16, 16, 14, 15, 16, 16, 0, 16, 16, 16, + 0, 0, 12, 15, 15, 16, 0, 13, 13, 16, 16, 0, + 14, 16, 16, 16, 0, 16, 16, 16, 0, 0, 0, 0, + 0, 0, 0, 8, 10, 13, 15, 16, 10, 11, 13, 16, + 16, 13, 13, 14, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 0, 8, 10, 11, 15, 16, 9, 10, 12, + 16, 16, 12, 12, 15, 16, 16, 16, 14, 16, 16, 16, + 16, 16, 16, 16, 0, 9, 11, 14, 16, 16, 10, 11, + 13, 16, 16, 14, 13, 14, 16, 16, 16, 15, 15, 16, + 0, 16, 16, 16, 0, 0, 11, 13, 16, 16, 16, 11, + 13, 15, 16, 16, 13, 16, 16, 16, 0, 16, 16, 16, + 16, 0, 16, 16, 0, 0, 0, 15, 16, 16, 16, 0, + 14, 16, 16, 16, 0, 16, 16, 16, 0, 0, 16, 16, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 13, 16, 16, + 16, 11, 13, 16, 16, 16, 14, 15, 16, 16, 0, 15, + 16, 16, 16, 0, 16, 16, 0, 0, 0, 9, 13, 15, + 15, 16, 12, 13, 14, 16, 16, 16, 15, 16, 16, 0, + 16, 16, 16, 16, 0, 16, 16, 0, 0, 0, 11, 13, + 15, 16, 0, 12, 14, 16, 16, 0, 16, 16, 16, 16, + 0, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 16, + 16, 16, 16, 0, 16, 16, 16, 16, 0, 16, 16, 16, + 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, + 16, 16, 0, 0, 0, 16, 16, +}; + + +static const uint16_t cvh_huffcodes3[607] = { + 0x0000,0x0004,0x0022,0x00c6,0x03b0,0x000c,0x000d,0x0023,0x00c7,0x03b1,0x005c,0x00c8, + 0x00c9,0x03b2,0x0fa4,0x01c2,0x01c3,0x03b3,0x0fa5,0x7f72,0x03b4,0x07b2,0x1f9a,0xff24, + 0xff25,0x000e,0x0024,0x00ca,0x03b5,0x07b3,0x000f,0x0025,0x00cb,0x03b6,0x0fa6,0x005d, + 0x005e,0x00cc,0x03b7,0x1f9b,0x01c4,0x01c5,0x03b8,0x0fa7,0x7f73,0x0fa8,0x07b4,0x1f9c, + 0xff26,0xff27,0x005f,0x01c6,0x03b9,0x0fa9,0x7f74,0x0060,0x00cd,0x03ba,0x0faa,0x1f9d, + 0x01c7,0x01c8,0x07b5,0x1f9e,0xff28,0x07b6,0x07b7,0x0fab,0x3fa2,0xff29,0x0fac,0x0fad, + 0x3fa3,0xff2a,0x3fa2,0x01c9,0x07b8,0x0fae,0xff2b,0xff2c,0x01ca,0x03bb,0x1f9f,0x7f75, + 0xff2d,0x03bc,0x07b9,0x0faf,0xff2e,0xff2f,0x1fa0,0x1fa1,0xff30,0xff31,0xff32,0xff33, + 0xff34,0x7f76,0xff35,0xff31,0x07ba,0x1fa2,0xff36,0xff37,0x7f77,0x07bb,0x1fa3,0x7f78, + 0xff38,0xff39,0x1fa4,0x1fa5,0xff3a,0xff3b,0xff2e,0x3fa4,0xff3c,0xff3d,0xff3e,0xff31, + 0xff3f,0xff40,0xff30,0xff31,0xff31,0x0005,0x0026,0x00ce,0x03bd,0x1fa6,0x0027,0x0028, + 0x00cf,0x03be,0x1fa7,0x01cb,0x00d0,0x03bf,0x0fb0,0xff41,0x03c0,0x03c1,0x07bc,0x7f79, + 0xff42,0x1fa8,0x0fb1,0x3fa5,0xff43,0xff44,0x0010,0x0029,0x00d1,0x07bd,0x1fa9,0x002a, + 0x002b,0x00d2,0x03c2,0x1faa,0x00d3,0x00d4,0x01cc,0x07be,0x3fa6,0x03c3,0x03c4,0x0fb2, + 0x0fb3,0xff45,0x1fab,0x0fb4,0x1fac,0x7f7a,0xff46,0x0061,0x00d5,0x01cd,0x0fb5,0xff47, + 0x0062,0x00d6,0x03c5,0x0fb6,0x3fa7,0x01ce,0x01cf,0x03c6,0x1fad,0xff48,0x07bf,0x03c7, + 0x0fb7,0x7f7b,0xff49,0x1fae,0x1faf,0xff4a,0xff4b,0x7f7b,0x01d0,0x07c0,0x1fb0,0xff4c, + 0xff4d,0x01d1,0x03c8,0x0fb8,0x7f7c,0xff4e,0x03c9,0x07c1,0x1fb1,0xff4f,0xff50,0x1fb2, + 0x0fb9,0xff51,0xff52,0xff53,0xff54,0xff55,0xff56,0xff57,0xff52,0x07c2,0x1fb3,0xff58, + 0xff59,0xff5a,0x07c3,0x1fb4,0xff5b,0xff5c,0xff5d,0x0fba,0x1fb5,0x7f7d,0xff5e,0xff4f, + 0xff5f,0xff60,0xff61,0xff62,0xff52,0xff63,0xff64,0xff51,0xff52,0xff52,0x002c,0x00d7, + 0x07c4,0x1fb6,0xff65,0x00d8,0x00d9,0x03ca,0x0fbb,0xff66,0x07c5,0x03cb,0x07c6,0x1fb7, + 0xff67,0x0fbc,0x1fb8,0x1fb9,0x7f7e,0xff68,0xff69,0xff6a,0x3fa8,0xff6b,0x7f7e,0x002d, + 0x00da,0x03cc,0x1fba,0xff6c,0x00db,0x00dc,0x03cd,0x0fbd,0xff6d,0x03ce,0x03cf,0x07c7, + 0x1fbb,0xff6e,0x1fbc,0x0fbe,0x1fbd,0xff6f,0xff70,0x3fa9,0x3faa,0x3fab,0xff71,0xff6f, + 0x00dd,0x01d2,0x07c8,0x1fbe,0xff72,0x00de,0x01d3,0x07c9,0xff73,0x3fac,0x03d0,0x03d1, + 0x0fbf,0x7f7f,0xff74,0x0fc0,0x0fc1,0x1fbf,0xff75,0xff76,0x7f80,0xff77,0xff78,0xff79, + 0xff75,0x03d2,0x0fc2,0x7f81,0xff7a,0xff7b,0x03d3,0x0fc3,0x0fc4,0x3fad,0xff7c,0x0fc5, + 0x0fc6,0x1fc0,0xff7d,0xff7e,0x3fae,0x7f82,0xff7f,0xff80,0xff80,0xff81,0xff82,0xff83, + 0xff80,0xff80,0x0fc7,0x7f83,0x7f84,0xff84,0xff7a,0x1fc1,0x1fc2,0xff85,0xff86,0x3fad, + 0x3faf,0xff87,0xff88,0xff89,0xff7d,0xff8a,0xff8b,0xff8c,0xff80,0xff80,0x3fae,0x7f82, + 0xff7f,0xff80,0xff80,0x00df,0x03d4,0x1fc3,0x7f85,0xff8d,0x03d5,0x07ca,0x1fc4,0xff8e, + 0xff8f,0x1fc5,0x1fc6,0x3fb0,0xff90,0xff91,0xff92,0xff93,0xff94,0xff95,0xff96,0xff97, + 0xff98,0xff99,0xff9a,0xff95,0x00e0,0x03d6,0x07cb,0x7f86,0xff9b,0x01d4,0x03d7,0x0fc8, + 0xff9c,0xff9d,0x0fc9,0x0fca,0x7f87,0xff9e,0xff9f,0xffa0,0x3fb1,0xffa1,0xffa2,0xffa3, + 0xffa4,0xffa5,0xffa6,0xffa7,0xffa2,0x01d5,0x07cc,0x3fb2,0xffa8,0xffa9,0x03d8,0x07cd, + 0x1fc7,0xffaa,0xffab,0x3fb3,0x1fc8,0x3fb4,0xffac,0xffad,0xffae,0x7f88,0x7f89,0xffaf, + 0xffaf,0xffb0,0xffb1,0xffb2,0xffaf,0xffaf,0x07ce,0x1fc9,0xffb3,0xffb4,0xffb5,0x07cf, + 0x1fca,0x7f8a,0xffb6,0xffb7,0x1fcb,0xffb8,0xffb9,0xffba,0xffba,0xffbb,0xffbc,0xffbd, + 0xffbe,0xffbe,0xffbf,0xffc0,0xffbd,0xffbe,0xffbe,0x7f8b,0xffc1,0xffc2,0xffc3,0xffb4, + 0x3fb5,0xffc4,0xffc5,0xffc6,0xffb6,0xffc7,0xffc8,0xffc9,0xffba,0xffba,0xffca,0xffcb, + 0xffbd,0xffbe,0xffbe,0xffbb,0xffbc,0xffbd,0xffbe,0xffbe,0x01d6,0x1fcc,0xffcc,0xffcd, + 0xffce,0x07d0,0x1fcd,0xffcf,0xffd0,0xffd1,0x3fb6,0x7f8c,0xffd2,0xffd3,0xff90,0x7f8d, + 0xffd4,0xffd5,0xffd6,0xff95,0xffd7,0xffd8,0xff94,0xff95,0xff95,0x01d7,0x1fce,0x7f8e, + 0x7f8f,0xffd9,0x0fcb,0x1fcf,0x3fb7,0xffda,0xffdb,0xffdc,0x7f90,0xffdd,0xffde,0xff9e, + 0xffdf,0xffe0,0xffe1,0xffe2,0xffa2,0xffe3,0xffe4,0xffa1,0xffa2,0xffa2,0x07d1,0x1fd0, + 0x7f91,0xffe5,0xffa8,0x0fcc,0x3fb8,0xffe6,0xffe7,0xffaa,0xffe8,0xffe9,0xffea,0xffeb, + 0xffac,0xffec,0xffed,0xffee,0xffaf,0xffaf,0xffae,0x7f88,0x7f89,0xffaf,0xffaf,0xffef, + 0xfff0,0xfff1,0xfff2,0xffb4,0xfff3,0xfff4,0xfff5,0xfff6,0xffb6,0xfff7,0xfff8,0xfff9, + 0xffba,0xffba,0xfffa,0xfffb,0xffbd,0xffbe,0xffbe,0xffbb,0xffbc,0xffbd,0xffbe,0xffbe, + 0xfffc,0xfffd,0xffb3,0xffb4,0xffb4,0xfffe,0xffff, +}; + +static const uint8_t cvh_huffbits4[246] = { + 2, 4, 7, 10, 4, 5, 7, 10, 7, 8, 10, 14, + 11, 11, 15, 15, 4, 5, 9, 12, 5, 5, 8, 12, + 8, 7, 10, 15, 11, 11, 15, 15, 7, 9, 12, 15, + 8, 8, 12, 15, 10, 10, 13, 15, 14, 14, 15, 0, + 11, 13, 15, 15, 11, 13, 15, 15, 14, 15, 15, 0, + 15, 15, 0, 0, 4, 5, 9, 13, 5, 6, 9, 13, + 9, 9, 11, 15, 14, 13, 15, 15, 4, 6, 9, 12, + 5, 6, 9, 13, 9, 8, 11, 15, 13, 12, 15, 15, + 7, 9, 12, 15, 7, 8, 11, 15, 10, 10, 14, 15, + 14, 15, 15, 0, 10, 12, 15, 15, 11, 13, 15, 15, + 15, 15, 15, 0, 15, 15, 0, 0, 6, 9, 13, 14, + 8, 9, 12, 15, 12, 12, 15, 15, 15, 15, 15, 0, + 7, 9, 13, 15, 8, 9, 12, 15, 11, 12, 15, 15, + 15, 15, 15, 0, 9, 11, 15, 15, 9, 11, 15, 15, + 14, 14, 15, 0, 15, 15, 0, 0, 14, 15, 15, 0, + 14, 15, 15, 0, 15, 15, 0, 0, 0, 0, 0, 0, + 9, 12, 15, 15, 12, 13, 15, 15, 15, 15, 15, 0, + 15, 15, 0, 0, 10, 12, 15, 15, 12, 14, 15, 15, + 15, 15, 15, 0, 15, 15, 0, 0, 14, 15, 15, 0, + 15, 15, 15, 0, 15, 15, 0, 0, 0, 0, 0, 0, + 15, 15, 0, 0, 15, 15, +}; + + +static const uint16_t cvh_huffcodes4[246] = { + 0x0000,0x0004,0x006c,0x03e6,0x0005,0x0012,0x006d,0x03e7,0x006e,0x00e8,0x03e8,0x3fc4, + 0x07e0,0x07e1,0x7fa4,0x7fa5,0x0006,0x0013,0x01e2,0x0fda,0x0014,0x0015,0x00e9,0x0fdb, + 0x00ea,0x006f,0x03e9,0x7fa6,0x07e2,0x07e3,0x7fa7,0x7fa8,0x0070,0x01e3,0x0fdc,0x7fa9, + 0x00eb,0x00ec,0x0fdd,0x7faa,0x03ea,0x03eb,0x1fd6,0x7fab,0x3fc5,0x3fc6,0x7fac,0x1fd6, + 0x07e4,0x1fd7,0x7fad,0x7fae,0x07e5,0x1fd8,0x7faf,0x7fb0,0x3fc7,0x7fb1,0x7fb2,0x1fd6, + 0x7fb3,0x7fb4,0x1fd6,0x1fd6,0x0007,0x0016,0x01e4,0x1fd9,0x0017,0x0032,0x01e5,0x1fda, + 0x01e6,0x01e7,0x07e6,0x7fb5,0x3fc8,0x1fdb,0x7fb6,0x7fb7,0x0008,0x0033,0x01e8,0x0fde, + 0x0018,0x0034,0x01e9,0x1fdc,0x01ea,0x00ed,0x07e7,0x7fb8,0x1fdd,0x0fdf,0x7fb9,0x7fba, + 0x0071,0x01eb,0x0fe0,0x7fbb,0x0072,0x00ee,0x07e8,0x7fbc,0x03ec,0x03ed,0x3fc9,0x7fbd, + 0x3fca,0x7fbe,0x7fbf,0x3fc9,0x03ee,0x0fe1,0x7fc0,0x7fc1,0x07e9,0x1fde,0x7fc2,0x7fc3, + 0x7fc4,0x7fc5,0x7fc6,0x3fc9,0x7fc7,0x7fc8,0x3fc9,0x3fc9,0x0035,0x01ec,0x1fdf,0x3fcb, + 0x00ef,0x01ed,0x0fe2,0x7fc9,0x0fe3,0x0fe4,0x7fca,0x7fcb,0x7fcc,0x7fcd,0x7fce,0x7fca, + 0x0073,0x01ee,0x1fe0,0x7fcf,0x00f0,0x01ef,0x0fe5,0x7fd0,0x07ea,0x0fe6,0x7fd1,0x7fd2, + 0x7fd3,0x7fd4,0x7fd5,0x7fd1,0x01f0,0x07eb,0x7fd6,0x7fd7,0x01f1,0x07ec,0x7fd8,0x7fd9, + 0x3fcc,0x3fcd,0x7fda,0x7fda,0x7fdb,0x7fdc,0x7fda,0x7fda,0x3fce,0x7fdd,0x7fde,0x7fd6, + 0x3fcf,0x7fdf,0x7fe0,0x7fd8,0x7fe1,0x7fe2,0x7fda,0x7fda,0x3fcc,0x3fcd,0x7fda,0x7fda, + 0x01f2,0x0fe7,0x7fe3,0x7fe4,0x0fe8,0x1fe1,0x7fe5,0x7fe6,0x7fe7,0x7fe8,0x7fe9,0x7fca, + 0x7fea,0x7feb,0x7fca,0x7fca,0x03ef,0x0fe9,0x7fec,0x7fed,0x0fea,0x3fd0,0x7fee,0x7fef, + 0x7ff0,0x7ff1,0x7ff2,0x7fd1,0x7ff3,0x7ff4,0x7fd1,0x7fd1,0x3fd1,0x7ff5,0x7ff6,0x7fd6, + 0x7ff7,0x7ff8,0x7ff9,0x7fd8,0x7ffa,0x7ffb,0x7fda,0x7fda,0x3fcc,0x3fcd,0x7fda,0x7fda, + 0x7ffc,0x7ffd,0x7fd6,0x7fd6,0x7ffe,0x7fff, +}; + + +static const uint8_t cvh_huffbits5[230] = { + 2, 4, 8, 4, 5, 9, 9, 10, 14, 4, 6, 11, + 5, 6, 12, 10, 11, 15, 9, 11, 15, 10, 13, 15, + 14, 15, 0, 4, 6, 12, 6, 7, 12, 12, 12, 15, + 5, 7, 13, 6, 7, 13, 12, 13, 15, 10, 12, 15, + 11, 13, 15, 15, 15, 0, 8, 13, 15, 11, 12, 15, + 15, 15, 0, 10, 13, 15, 12, 15, 15, 15, 15, 0, + 15, 15, 0, 15, 15, 0, 0, 0, 0, 4, 5, 11, + 5, 7, 12, 11, 12, 15, 6, 7, 13, 7, 8, 14, + 12, 14, 15, 11, 13, 15, 12, 13, 15, 15, 15, 0, + 5, 6, 13, 7, 8, 15, 12, 14, 15, 6, 8, 14, + 7, 8, 15, 14, 15, 15, 12, 12, 15, 12, 13, 15, + 15, 15, 0, 9, 13, 15, 12, 13, 15, 15, 15, 0, + 11, 13, 15, 13, 13, 15, 15, 15, 0, 14, 15, 0, + 15, 15, 0, 0, 0, 0, 8, 10, 15, 11, 12, 15, + 15, 15, 0, 10, 12, 15, 12, 13, 15, 15, 15, 0, + 14, 15, 0, 15, 15, 0, 0, 0, 0, 8, 12, 15, + 12, 13, 15, 15, 15, 0, 11, 13, 15, 13, 15, 15, + 15, 15, 0, 15, 15, 0, 15, 15, 0, 0, 0, 0, + 14, 15, 0, 15, 15, 0, 0, 0, 0, 15, 15, 0, + 15, 15, +}; + + + +static const uint16_t cvh_huffcodes5[230] = { + 0x0000,0x0004,0x00f0,0x0005,0x0012,0x01f0,0x01f1,0x03e8,0x3fce,0x0006,0x0030,0x07de, + 0x0013,0x0031,0x0fd2,0x03e9,0x07df,0x7fb0,0x01f2,0x07e0,0x7fb1,0x03ea,0x1fd2,0x7fb2, + 0x3fcf,0x7fb3,0x0031,0x0007,0x0032,0x0fd3,0x0033,0x0070,0x0fd4,0x0fd5,0x0fd6,0x7fb4, + 0x0014,0x0071,0x1fd3,0x0034,0x0072,0x1fd4,0x0fd7,0x1fd5,0x7fb5,0x03eb,0x0fd8,0x7fb6, + 0x07e1,0x1fd6,0x7fb7,0x7fb8,0x7fb9,0x0072,0x00f1,0x1fd7,0x7fba,0x07e2,0x0fd9,0x7fbb, + 0x7fbc,0x7fbd,0x0070,0x03ec,0x1fd8,0x7fbe,0x0fda,0x7fbf,0x7fc0,0x7fc1,0x7fc2,0x0072, + 0x7fc3,0x7fc4,0x0071,0x7fc5,0x7fc6,0x0072,0x0034,0x0072,0x0072,0x0008,0x0015,0x07e3, + 0x0016,0x0073,0x0fdb,0x07e4,0x0fdc,0x7fc7,0x0035,0x0074,0x1fd9,0x0075,0x00f2,0x3fd0, + 0x0fdd,0x3fd1,0x7fc8,0x07e5,0x1fda,0x7fc9,0x0fde,0x1fdb,0x7fca,0x7fcb,0x7fcc,0x00f2, + 0x0017,0x0036,0x1fdc,0x0076,0x00f3,0x7fcd,0x0fdf,0x3fd2,0x7fce,0x0037,0x00f4,0x3fd3, + 0x0077,0x00f5,0x7fcf,0x3fd4,0x7fd0,0x7fd1,0x0fe0,0x0fe1,0x7fd2,0x0fe2,0x1fdd,0x7fd3, + 0x7fd4,0x7fd5,0x00f5,0x01f3,0x1fde,0x7fd6,0x0fe3,0x1fdf,0x7fd7,0x7fd8,0x7fd9,0x00f3, + 0x07e6,0x1fe0,0x7fda,0x1fe1,0x1fe2,0x7fdb,0x7fdc,0x7fdd,0x00f5,0x3fd5,0x7fde,0x00f4, + 0x7fdf,0x7fe0,0x00f5,0x0077,0x00f5,0x00f5,0x00f6,0x03ed,0x7fe1,0x07e7,0x0fe4,0x7fe2, + 0x7fe3,0x7fe4,0x0073,0x03ee,0x0fe5,0x7fe5,0x0fe6,0x1fe3,0x7fe6,0x7fe7,0x7fe8,0x00f2, + 0x3fd6,0x7fe9,0x0074,0x7fea,0x7feb,0x00f2,0x0075,0x00f2,0x00f2,0x00f7,0x0fe7,0x7fec, + 0x0fe8,0x1fe4,0x7fed,0x7fee,0x7fef,0x00f3,0x07e8,0x1fe5,0x7ff0,0x1fe6,0x7ff1,0x7ff2, + 0x7ff3,0x7ff4,0x00f5,0x7ff5,0x7ff6,0x00f4,0x7ff7,0x7ff8,0x00f5,0x0077,0x00f5,0x00f5, + 0x3fd7,0x7ff9,0x0036,0x7ffa,0x7ffb,0x00f3,0x0076,0x00f3,0x00f3,0x7ffc,0x7ffd,0x0000, + 0x7ffe,0x7fff, +}; + + +static const uint8_t cvh_huffbits6[32] = { + 1, 4, 4, 6, 4, 6, 6, 8, 4, 6, 6, 8, + 6, 9, 8, 10, 4, 6, 7, 8, 6, 9, 8, 11, + 6, 9, 8, 10, 8, 10, 9, 11, +}; + +static const uint16_t cvh_huffcodes6[32] = { + 0x0000,0x0008,0x0009,0x0034,0x000a,0x0035,0x0036,0x00f6,0x000b,0x0037,0x0038,0x00f7, + 0x0039,0x01fa,0x00f8,0x03fc,0x000c,0x003a,0x007a,0x00f9,0x003b,0x01fb,0x00fa,0x07fe, + 0x003c,0x01fc,0x00fb,0x03fd,0x00fc,0x03fe,0x01fd,0x07ff, +}; + +static const uint16_t* const cvh_huffcodes[7] = { + cvh_huffcodes0, cvh_huffcodes1, cvh_huffcodes2, cvh_huffcodes3, + cvh_huffcodes4, cvh_huffcodes5, cvh_huffcodes6, +}; + +static const uint8_t* const cvh_huffbits[7] = { + cvh_huffbits0, cvh_huffbits1, cvh_huffbits2, cvh_huffbits3, + cvh_huffbits4, cvh_huffbits5, cvh_huffbits6, +}; + + +static const uint16_t ccpl_huffcodes2[3] = { + 0x02,0x00,0x03, +}; + +static const uint16_t ccpl_huffcodes3[7] = { + 0x3e,0x1e,0x02,0x00,0x06,0x0e,0x3f, +}; + +static const uint16_t ccpl_huffcodes4[15] = { + 0xfc,0xfd,0x7c,0x3c,0x1c,0x0c,0x04,0x00,0x05,0x0d,0x1d,0x3d, + 0x7d,0xfe,0xff, +}; + +static const uint16_t ccpl_huffcodes5[31] = { + 0x03f8,0x03f9,0x03fa,0x03fb,0x01f8,0x01f9,0x00f8,0x00f9,0x0078,0x0079,0x0038,0x0039, + 0x0018,0x0019,0x0004,0x0000,0x0005,0x001a,0x001b,0x003a,0x003b,0x007a,0x007b,0x00fa, + 0x00fb,0x01fa,0x01fb,0x03fc,0x03fd,0x03fe,0x03ff, +}; + +static const uint16_t ccpl_huffcodes6[63] = { + 0x0004,0x0005,0x0005,0x0006,0x0006,0x0007,0x0007,0x0007,0x0007,0x0008,0x0008,0x0008, + 0x0008,0x0009,0x0009,0x0009,0x0009,0x000a,0x000a,0x000a,0x000a,0x000a,0x000b,0x000b, + 0x000b,0x000b,0x000c,0x000d,0x000e,0x000e,0x0010,0x0000,0x000a,0x0018,0x0019,0x0036, + 0x0037,0x0074,0x0075,0x0076,0x0077,0x00f4,0x00f5,0x00f6,0x00f7,0x01f5,0x01f6,0x01f7, + 0x01f8,0x03f6,0x03f7,0x03f8,0x03f9,0x03fa,0x07fa,0x07fb,0x07fc,0x07fd,0x0ffd,0x1ffd, + 0x3ffd,0x3ffe,0xffff, +}; + +static const uint8_t ccpl_huffbits2[3] = { + 2,1,2, +}; + +static const uint8_t ccpl_huffbits3[7] = { + 6,5,2,1,3,4,6, +}; + +static const uint8_t ccpl_huffbits4[15] = { + 8,8,7,6,5,4,3,1,3,4,5,6,7,8,8, +}; + +static const uint8_t ccpl_huffbits5[31] = { + 10,10,10,10,9,9,8,8,7,7,6,6, + 5,5,3,1,3,5,5,6,6,7,7,8, + 8,9,9,10,10,10,10, +}; + +static const uint8_t ccpl_huffbits6[63] = { + 16,15,14,13,12,11,11,11,11,10,10,10, + 10,9,9,9,9,9,8,8,8,8,7,7, + 7,7,6,6,5,5,3,1,4,5,5,6, + 6,7,7,7,7,8,8,8,8,9,9,9, + 9,10,10,10,10,10,11,11,11,11,12,13, + 14,14,16, +}; + +static const uint16_t* const ccpl_huffcodes[5] = { + ccpl_huffcodes2,ccpl_huffcodes3, + ccpl_huffcodes4,ccpl_huffcodes5,ccpl_huffcodes6 +}; + +static const uint8_t* const ccpl_huffbits[5] = { + ccpl_huffbits2,ccpl_huffbits3, + ccpl_huffbits4,ccpl_huffbits5,ccpl_huffbits6 +}; + + +//Coupling tables + +static const int cplband[51] = { + 0,1,2,3,4,5,6,7,8,9, + 10,11,11,12,12,13,13,14,14,14, + 15,15,15,15,16,16,16,16,16,17, + 17,17,17,17,17,18,18,18,18,18, + 18,18,19,19,19,19,19,19,19,19, + 19, +}; + +static const float cplscale2[3] = { +0.953020632266998,0.70710676908493,0.302905440330505, +}; + +static const float cplscale3[7] = { +0.981279790401459,0.936997592449188,0.875934481620789,0.70710676908493, +0.482430040836334,0.349335819482803,0.192587479948997, +}; + +static const float cplscale4[15] = { +0.991486728191376,0.973249018192291,0.953020632266998,0.930133521556854, +0.903453230857849,0.870746195316315,0.826180458068848,0.70710676908493, +0.563405573368073,0.491732746362686,0.428686618804932,0.367221474647522, +0.302905440330505,0.229752898216248,0.130207896232605, +}; + +static const float cplscale5[31] = { +0.995926380157471,0.987517595291138,0.978726446628571,0.969505727291107, +0.95979779958725,0.949531257152557,0.938616216182709,0.926936149597168, +0.914336204528809,0.900602877140045,0.885426938533783,0.868331849575043, +0.84851086139679,0.824381768703461,0.791833400726318,0.70710676908493, +0.610737144947052,0.566034197807312,0.529177963733673,0.495983630418777, +0.464778542518616,0.434642940759659,0.404955863952637,0.375219136476517, +0.344963222742081,0.313672333955765,0.280692428350449,0.245068684220314, +0.205169528722763,0.157508864998817,0.0901700109243393, +}; + +static const float cplscale6[63] = { +0.998005926609039,0.993956744670868,0.989822506904602,0.985598564147949, +0.981279790401459,0.976860702037811,0.972335040569305,0.967696130275726, +0.962936460971832,0.958047747612000,0.953020632266998,0.947844684123993, +0.942508161067963,0.936997592449188,0.931297719478607,0.925390899181366, +0.919256627559662,0.912870943546295,0.906205296516418,0.899225592613220, +0.891890347003937,0.884148240089417,0.875934481620789,0.867165684700012, +0.857730865478516,0.847477376461029,0.836184680461884,0.823513329029083, +0.808890223503113,0.791194140911102,0.767520070075989,0.707106769084930, +0.641024887561798,0.611565053462982,0.587959706783295,0.567296981811523, +0.548448026180267,0.530831515789032,0.514098942279816,0.498019754886627, +0.482430040836334,0.467206478118896,0.452251672744751,0.437485188245773, +0.422837972640991,0.408248275518417,0.393658757209778,0.379014074802399, +0.364258885383606,0.349335819482803,0.334183186292648,0.318732559680939, +0.302905440330505,0.286608695983887,0.269728302955627,0.252119421958923, +0.233590632677078,0.213876649737358,0.192587479948997,0.169101938605309, +0.142307326197624,0.109772264957428,0.0631198287010193, +}; + +static const float* const cplscales[5] = { + cplscale2, cplscale3, cplscale4, cplscale5, cplscale6, +}; + +#endif /* AVCODEC_COOKDATA_H */ Index: apps/codecs/libcook/bitstream.c =================================================================== --- apps/codecs/libcook/bitstream.c (revision 0) +++ apps/codecs/libcook/bitstream.c (revision 0) @@ -0,0 +1,295 @@ +/* + * Common bit i/o utils + * Copyright (c) 2000, 2001 Fabrice Bellard. + * Copyright (c) 2002-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 + * + * alternative bitstream reader & writer by Michael Niedermayer + */ + +/** + * @file bitstream.c + * bitstream api. + */ + +#include "bitstream.h" +#define DEBUGF printf + +/** + * Same as av_mallocz_static(), but does a realloc. + * + * @param[in] ptr The block of memory to reallocate. + * @param[in] size The requested size. + * @return Block of memory of requested size. + * @deprecated. Code which uses ff_realloc_static is broken/missdesigned + * and should correctly use static arrays + */ +attribute_deprecated void *ff_realloc_static(void *ptr, unsigned int size); + + +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 +}; + + +void align_put_bits(PutBitContext *s) +{ +#ifdef ALT_BITSTREAM_WRITER + put_bits(s,( - s->index) & 7,0); +#else + put_bits(s,s->bit_left & 7,0); +#endif +} + +void ff_put_string(PutBitContext * pbc, char *s, int put_zero) +{ + while(*s){ + put_bits(pbc, 8, *s); + s++; + } + if(put_zero) + put_bits(pbc, 8, 0); +} + +/* VLC decoding */ + +//#define DEBUG_VLC + +#define GET_DATA(v, table, i, wrap, size) \ +{\ + const uint8_t *ptr = (const uint8_t *)table + i * wrap;\ + switch(size) {\ + case 1:\ + v = *(const uint8_t *)ptr;\ + break;\ + case 2:\ + v = *(const uint16_t *)ptr;\ + break;\ + default:\ + v = *(const uint32_t *)ptr;\ + break;\ + }\ +} + + +/*static int alloc_table(VLC *vlc, int size) +{ + int index; + index = vlc->table_size; + vlc->table_size += size; + if (vlc->table_size > vlc->table_allocated) { + DEBUGF("Tried to allocate past the end of a Huffman table: %d/%d\n", + vlc->table_allocated, vlc->table_allocated+(1 << vlc->bits)); + vlc->table_allocated += (1 << vlc->bits); + if (!vlc->table) + return -1; + } +DEBUGF("index = %d\n",index); + return index; +}*/ + +static int alloc_table(VLC *vlc, int size) +{ + int index; + index = vlc->table_size; + vlc->table_size += size; + if (vlc->table_size > vlc->table_allocated) { + + vlc->table_allocated += (1 << vlc->bits); + /*if(use_static) + vlc->table = ff_realloc_static(vlc->table, + sizeof(VLC_TYPE) * 2 * vlc->table_allocated); + else*/ + vlc->table = av_realloc(vlc->table, + sizeof(VLC_TYPE) * 2 * vlc->table_allocated); + if (!vlc->table) + return -1; + } + return index; +} + +static int build_table(VLC *vlc, int table_nb_bits, + int nb_codes, + const void *bits, int bits_wrap, int bits_size, + const void *codes, int codes_wrap, int codes_size, + uint32_t code_prefix, int n_prefix) +{ + int i, j, k, n, table_size, table_index, nb, n1, index, code_prefix2; + uint32_t code; + int flags = 0; + VLC_TYPE (*table)[2]; + + table_size = 1 << table_nb_bits; + table_index = alloc_table(vlc, table_size); +#ifdef DEBUG_VLC + printf("new table index=%d size=%d code_prefix=%x n=%d\n", + table_index, table_size, code_prefix, n_prefix); +#endif + if (table_index < 0) + return -1; + table = &vlc->table[table_index]; + + for(i=0;i=32 ? 0xffffffff : (uint32_t)(1 << n_prefix)-1); + else + code_prefix2= code >> n; + if (n > 0 && (int)code_prefix2 == (int)code_prefix) { + if (n <= table_nb_bits) { + /* no need to add another table */ + j = (code << (table_nb_bits - n)) & (table_size - 1); + nb = 1 << (table_nb_bits - n); + for(k=0;k> n_prefix) + (k<> ((flags & INIT_VLC_LE) ? n_prefix : n)) & ((1 << table_nb_bits) - 1); +#ifdef DEBUG_VLC + av_log(NULL, 0,"%4x: n=%d (subtable)\n", + j, n); +#endif + /* compute table size */ + n1 = -table[j][1]; //bits + if (n > n1) + n1 = n; + table[j][1] = -n1; //bits + } + } + } + + /* second pass : fill auxillary tables recursively */ + for(i=0;i table_nb_bits) { + n = table_nb_bits; + table[i][1] = -n; //bits + } + index = build_table(vlc, n, nb_codes, + bits, bits_wrap, bits_size, + codes, codes_wrap, codes_size, + (flags & INIT_VLC_LE) ? (code_prefix | (i << n_prefix)) : ((code_prefix << table_nb_bits) | i), + n_prefix + table_nb_bits); + if (index < 0) + return -1; + /* note: realloc has been done, so reload tables */ + table = &vlc->table[table_index]; + table[i][0] = index; //code + } + } + return table_index; +} + + +/* Build VLC decoding tables suitable for use with get_vlc(). + + 'nb_bits' set thee decoding table size (2^nb_bits) entries. The + bigger it is, the faster is the decoding. But it should not be too + big to save memory and L1 cache. '9' is a good compromise. + + 'nb_codes' : number of vlcs codes + + 'bits' : table which gives the size (in bits) of each vlc code. + + 'codes' : table which gives the bit pattern of of each vlc code. + + 'xxx_wrap' : give the number of bytes between each entry of the + 'bits' or 'codes' tables. + + 'xxx_size' : gives the number of bytes of each entry of the 'bits' + or 'codes' tables. + + 'wrap' and 'size' allows to use any memory configuration and types + (byte/word/long) to store the 'bits' and 'codes' tables. + + 'use_static' should be set to 1 for tables, which should be freed + with av_free_static(), 0 if free_vlc() will be used. +*/ +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, + int flags) +{ + + vlc->bits = nb_bits; + vlc->table_size = 0; + +#ifdef DEBUG_VLC + printf("build table nb_codes=%d\n", nb_codes); +#endif + + if (build_table(vlc, nb_bits, nb_codes, + bits, bits_wrap, bits_size, + codes, codes_wrap, codes_size, + 0, 0) < 0) { + //av_free(vlc->table); + return -1; + } + /* return flags to block gcc warning while allowing us to keep + * consistent with ffmpeg's function parameters + */ + return flags; +} + +void free_vlc(VLC *vlc) +{ + av_freep(&vlc->table); +} Index: apps/codecs/libcook/cook.c =================================================================== --- apps/codecs/libcook/cook.c (revision 0) +++ apps/codecs/libcook/cook.c (revision 0) @@ -0,0 +1,1277 @@ +/* + * COOK compatible decoder + * Copyright (c) 2003 Sascha Sommer + * Copyright (c) 2005 Benjamin Larsson + * + * 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 libavcodec/cook.c + * Cook compatible decoder. Bastardization of the G.722.1 standard. + * This decoder handles RealNetworks, RealAudio G2 data. + * Cook is identified by the codec name cook in RM files. + * + * To use this decoder, a calling application must supply the extradata + * bytes provided from the RM container; 8+ bytes for mono streams and + * 16+ for stereo streams (maybe more). + * + * Codec technicalities (all this assume a buffer length of 1024): + * Cook works with several different techniques to achieve its compression. + * In the timedomain the buffer is divided into 8 pieces and quantized. If + * two neighboring pieces have different quantization index a smooth + * quantization curve is used to get a smooth overlap between the different + * pieces. + * To get to the transformdomain Cook uses a modulated lapped transform. + * The transform domain has 50 subbands with 20 elements each. This + * means only a maximum of 50*20=1000 coefficients are used out of the 1024 + * available. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "libavutil/lfg.h" +#include "random.h" +#include "bitstream.h" +#include "dsputil.h" +#include "bytestream.h" + +#include "cookdata.h" +#include "rm2wav.h" + +/* the different Cook versions */ +#define MONO 0x1000001 +#define STEREO 0x1000002 +#define JOINT_STEREO 0x1000003 +#define MC_COOK 0x2000000 //multichannel Cook, not supported + +#define SUBBAND_SIZE 20 +#define MAX_SUBPACKETS 5 +#define COOKDEBUG +#define DEBUGF(message,args ...) av_log(NULL,AV_LOG_ERROR,message,## args) +typedef struct { + int *now; + int *previous; +} cook_gains; + + + +typedef struct cook { + /* + * The following 5 functions provide the lowlevel arithmetic on + * the internal audio buffers. + */ + void (* scalar_dequant)(struct cook *q, int index, int quant_index, + int* subband_coef_index, int* subband_coef_sign, + float* mlt_p); + + void (* decouple) (struct cook *q, + int subband, + float f1, float f2, + float *decode_buffer, + float *mlt_buffer1, float *mlt_buffer2); + + void (* imlt_window) (struct cook *q, float *buffer1, + cook_gains *gains_ptr, float *previous_buffer); + + void (* interpolate) (struct cook *q, float* buffer, + int gain_index, int gain_index_next); + + void (* saturate_output) (struct cook *q, int chan, int16_t *out); + + GetBitContext gb; + AVCodecContext avctx; + int frame_number; + int block_align; + int extradata_size; + /* stream data */ + int nb_channels; + int joint_stereo; + int bit_rate; + int sample_rate; + int samples_per_channel; + int samples_per_frame; + int subbands; + int log2_numvector_size; + int numvector_size; //1 << log2_numvector_size; + int js_subband_start; + int total_subbands; + int num_vectors; + int bits_per_subpacket; + int cookversion; + /* states */ + //AVRandomState random_state; + AVLFG random_state; + /* transform data */ + MDCTContext mdct_ctx; + float* mlt_window; + + /* gain buffers */ + cook_gains gains1; + cook_gains gains2; + int gain_1[9]; + int gain_2[9]; + int gain_3[9]; + int gain_4[9]; + + /* VLC data */ + int js_vlc_bits; + VLC envelope_quant_index[13]; + VLC sqvh[7]; //scalar quantization + VLC ccpl; //channel coupling + + /* generatable tables and related variables */ + int gain_size_factor; + float gain_table[23]; + + /* data buffers */ + + uint8_t* decoded_bytes_buffer; + float mono_mdct_output[2048] __attribute__ ((aligned(16))); //DECLARE_ALIGNED_16(float,mono_mdct_output[2048]); + float mono_previous_buffer1[1024]; + float mono_previous_buffer2[1024]; + float decode_buffer_1[1024]; + float decode_buffer_2[1024]; + float decode_buffer_0[1060]; /* static allocation for joint decode */ + + const float *cplscales[5]; +} COOKContext; +static float pow2tab[127]; +static float rootpow2tab[127]; + +/* debug functions */ + +#ifdef COOKDEBUG +static void dump_float_table(float* table, int size, int delimiter) { + int i=0; + av_log(NULL,AV_LOG_ERROR,"\n[%d]: ",i); + for (i=0 ; igain_size_factor = q->samples_per_channel/8; + for (i=0 ; i<23 ; i++) { + q->gain_table[i] = pow(pow2tab[i+52] , + (1.0/(double)q->gain_size_factor)); + } +} + + +static av_cold int init_cook_vlc_tables(COOKContext *q) { + int i, result; + + result = 0; + for (i=0 ; i<13 ; i++) { + result |= init_vlc (&q->envelope_quant_index[i], 9, 24, + envelope_quant_index_huffbits[i], 1, 1, + envelope_quant_index_huffcodes[i], 2, 2, 0); + } + av_log(NULL,AV_LOG_DEBUG,"sqvh VLC init\n"); + for (i=0 ; i<7 ; i++) { + result |= init_vlc (&q->sqvh[i], vhvlcsize_tab[i], vhsize_tab[i], + cvh_huffbits[i], 1, 1, + cvh_huffcodes[i], 2, 2, 0); + } + + if (q->nb_channels==2 && q->joint_stereo==1){ + result |= init_vlc (&q->ccpl, 6, (1<js_vlc_bits)-1, + ccpl_huffbits[q->js_vlc_bits-2], 1, 1, + ccpl_huffcodes[q->js_vlc_bits-2], 2, 2, 0); + av_log(NULL,AV_LOG_DEBUG,"Joint-stereo VLC used.\n"); + } + + av_log(NULL,AV_LOG_ERROR,"VLC tables initialized. Result = %d\n",result); + return result; +} + +static av_cold int init_cook_mlt(COOKContext *q) { + int j; + int mlt_size = q->samples_per_channel; + if ((q->mlt_window = av_malloc(sizeof(float)*mlt_size)) == 0) + return -1; + + /* Initialize the MLT window: simple sine window. */ + ff_sine_window_init(q->mlt_window, mlt_size); + for(j=0 ; jmlt_window[j] *= sqrt(2.0 / q->samples_per_channel); + + /* Initialize the MDCT. */ + if (ff_mdct_init(&q->mdct_ctx, av_log2(mlt_size)+1, 1)) { + av_free(q->mlt_window); + return -1; + } + av_log(NULL,AV_LOG_ERROR,"MDCT initialized, order = %d. mlt_window = %d\n", + av_log2(mlt_size)+1,sizeof(q->mlt_window)*mlt_size); + + return 0; +} + +static const float *maybe_reformat_buffer32 (COOKContext *q, const float *ptr, int n) +{ + if (1) + return ptr; +} + +static av_cold void init_cplscales_table (COOKContext *q) { + int i; + for (i=0;i<5;i++) + q->cplscales[i] = maybe_reformat_buffer32 (q, cplscales[i], (1<<(i+2))-1); +} + +/*************** init functions end ***********/ + +/** + * Cook indata decoding, every 32 bits are XORed with 0x37c511f2. + * Why? No idea, some checksum/error detection method maybe. + * + * Out buffer size: extra bytes are needed to cope with + * padding/misalignment. + * Subpackets passed to the decoder can contain two, consecutive + * half-subpackets, of identical but arbitrary size. + * 1234 1234 1234 1234 extraA extraB + * Case 1: AAAA BBBB 0 0 + * Case 2: AAAA ABBB BB-- 3 3 + * Case 3: AAAA AABB BBBB 2 2 + * Case 4: AAAA AAAB BBBB BB-- 1 5 + * + * Nice way to waste CPU cycles. + * + * @param inbuffer pointer to byte array of indata + * @param out pointer to byte array of outdata + * @param bytes number of bytes + */ +#define DECODE_BYTES_PAD1(bytes) (3 - ((bytes)+3) % 4) +#define DECODE_BYTES_PAD2(bytes) ((bytes) % 4 + DECODE_BYTES_PAD1(2 * (bytes))) + +static inline int decode_bytes(const uint8_t* inbuffer, uint8_t* out, int bytes){ + int i, off; + uint32_t c; + const uint32_t* buf; + uint32_t* obuf = (uint32_t*) out; + /* FIXME: 64 bit platforms would be able to do 64 bits at a time. + * I'm too lazy though, should be something like + * for(i=0 ; i> (off*8)) | (0x37c511f2 << (32-(off*8)))); + bytes += 3 + off; + for (i = 0; i < bytes/4; i++) + obuf[i] = c ^ buf[i]; + + return off; +} + +/** + * Cook uninit + */ + +static av_cold int cook_decode_close(COOKContext *q)//AVCodecContext *avctx) +{ + int i; + //COOKContext *q = avctx->priv_data; + av_log(NULL,AV_LOG_ERROR, "Deallocating memory.\n"); + + /* Free allocated memory buffers. */ + av_free(q->mlt_window); + av_free(q->decoded_bytes_buffer); + + /* Free the transform. */ + ff_mdct_end(&q->mdct_ctx); + + /* Free the VLC tables. */ + for (i=0 ; i<13 ; i++) { + free_vlc(&q->envelope_quant_index[i]); + } + for (i=0 ; i<7 ; i++) { + free_vlc(&q->sqvh[i]); + } + if(q->nb_channels==2 && q->joint_stereo==1 ){ + free_vlc(&q->ccpl); + } + + av_log(NULL,AV_LOG_ERROR,"Memory deallocated.\n"); + + return 0; +} + +/** + * Fill the gain array for the timedomain quantization. + * + * @param q pointer to the COOKContext + * @param gaininfo[9] array of gain indexes + */ + +static void decode_gain_info(GetBitContext *gb, int *gaininfo) +{ + int i, n; + + while (get_bits1(gb)) {} + n = get_bits_count(gb) - 1; //amount of elements*2 to update + + i = 0; + while (n--) { + int index = get_bits(gb, 3); + int gain = get_bits1(gb) ? get_bits(gb, 4) - 7 : -1; + + while (i <= index) gaininfo[i++] = gain; + } + while (i <= 8) gaininfo[i++] = 0; +} + +/** + * Create the quant index table needed for the envelope. + * + * @param q pointer to the COOKContext + * @param quant_index_table pointer to the array + */ + +static void decode_envelope(COOKContext *q, int* quant_index_table) { + int i,j, vlc_index; + + quant_index_table[0]= get_bits(&q->gb,6) - 6; //This is used later in categorize + + for (i=1 ; i < q->total_subbands ; i++){ + vlc_index=i; + if (i >= q->js_subband_start * 2) { + vlc_index-=q->js_subband_start; + } else { + vlc_index/=2; + if(vlc_index < 1) vlc_index = 1; + } + if (vlc_index>13) vlc_index = 13; //the VLC tables >13 are identical to No. 13 + + j = get_vlc2(&q->gb, q->envelope_quant_index[vlc_index-1].table, + q->envelope_quant_index[vlc_index-1].bits,2); + quant_index_table[i] = quant_index_table[i-1] + j - 12; //differential encoding + } +} + +/** + * Calculate the category and category_index vector. + * + * @param q pointer to the COOKContext + * @param quant_index_table pointer to the array + * @param category pointer to the category array + * @param category_index pointer to the category_index array + */ + +static void categorize(COOKContext *q, int* quant_index_table, + int* category, int* category_index){ + int exp_idx, bias, tmpbias1, tmpbias2, bits_left, num_bits, index, v, i, j; + int exp_index2[102]; + int exp_index1[102]; + + int tmp_categorize_array[128*2]; + int tmp_categorize_array1_idx=q->numvector_size; + int tmp_categorize_array2_idx=q->numvector_size; + + bits_left = q->bits_per_subpacket - get_bits_count(&q->gb); + + if(bits_left > q->samples_per_channel) { + bits_left = q->samples_per_channel + + ((bits_left - q->samples_per_channel)*5)/8; + //av_log(q->avctx, AV_LOG_ERROR, "bits_left = %d\n",bits_left); + } + + memset(&exp_index1,0,102*sizeof(int)); + memset(&exp_index2,0,102*sizeof(int)); + memset(&tmp_categorize_array,0,128*2*sizeof(int)); + + bias=-32; + + /* Estimate bias. */ + for (i=32 ; i>0 ; i=i/2){ + num_bits = 0; + index = 0; + for (j=q->total_subbands ; j>0 ; j--){ + exp_idx = av_clip((i - quant_index_table[index] + bias) / 2, 0, 7); + index++; + num_bits+=expbits_tab[exp_idx]; + } + if(num_bits >= bits_left - 32){ + bias+=i; + } + } + + /* Calculate total number of bits. */ + num_bits=0; + for (i=0 ; itotal_subbands ; i++) { + exp_idx = av_clip((bias - quant_index_table[i]) / 2, 0, 7); + num_bits += expbits_tab[exp_idx]; + exp_index1[i] = exp_idx; + exp_index2[i] = exp_idx; + } + tmpbias1 = tmpbias2 = num_bits; + + for (j = 1 ; j < q->numvector_size ; j++) { + if (tmpbias1 + tmpbias2 > 2*bits_left) { /* ---> */ + int max = -999999; + index=-1; + for (i=0 ; itotal_subbands ; i++){ + if (exp_index1[i] < 7) { + v = (-2*exp_index1[i]) - quant_index_table[i] + bias; + if ( v >= max) { + max = v; + index = i; + } + } + } + if(index==-1)break; + tmp_categorize_array[tmp_categorize_array1_idx++] = index; + tmpbias1 -= expbits_tab[exp_index1[index]] - + expbits_tab[exp_index1[index]+1]; + ++exp_index1[index]; + } else { /* <--- */ + int min = 999999; + index=-1; + for (i=0 ; itotal_subbands ; i++){ + if(exp_index2[i] > 0){ + v = (-2*exp_index2[i])-quant_index_table[i]+bias; + if ( v < min) { + min = v; + index = i; + } + } + } + if(index == -1)break; + tmp_categorize_array[--tmp_categorize_array2_idx] = index; + tmpbias2 -= expbits_tab[exp_index2[index]] - + expbits_tab[exp_index2[index]-1]; + --exp_index2[index]; + } + } + + for(i=0 ; itotal_subbands ; i++) + category[i] = exp_index2[i]; + + for(i=0 ; inumvector_size-1 ; i++) + category_index[i] = tmp_categorize_array[tmp_categorize_array2_idx++]; + +} + + +/** + * Expand the category vector. + * + * @param q pointer to the COOKContext + * @param category pointer to the category array + * @param category_index pointer to the category_index array + */ + +static inline void expand_category(COOKContext *q, int* category, + int* category_index){ + int i; + for(i=0 ; inum_vectors ; i++){ + ++category[category_index[i]]; + } +} + +/** + * The real requantization of the mltcoefs + * + * @param q pointer to the COOKContext + * @param index index + * @param quant_index quantisation index + * @param subband_coef_index array of indexes to quant_centroid_tab + * @param subband_coef_sign signs of coefficients + * @param mlt_p pointer into the mlt buffer + */ + +static void scalar_dequant_float(COOKContext *q, int index, int quant_index, + int* subband_coef_index, int* subband_coef_sign, + float* mlt_p){ + int i; + float f1; + + for(i=0 ; irandom_state)*/av_lfg_get(&q->random_state) < 0x80000000) f1 = -f1; + } + mlt_p[i] = f1 * rootpow2tab[quant_index+63]; + } +} +/** + * Unpack the subband_coef_index and subband_coef_sign vectors. + * + * @param q pointer to the COOKContext + * @param category pointer to the category array + * @param subband_coef_index array of indexes to quant_centroid_tab + * @param subband_coef_sign signs of coefficients + */ + +static int unpack_SQVH(COOKContext *q, int category, int* subband_coef_index, + int* subband_coef_sign) { + int i,j; + int vlc, vd ,tmp, result; + + vd = vd_tab[category]; + result = 0; + for(i=0 ; igb, q->sqvh[category].table, q->sqvh[category].bits, 3); + if (q->bits_per_subpacket < get_bits_count(&q->gb)){ + vlc = 0; + result = 1; + } + for(j=vd-1 ; j>=0 ; j--){ + tmp = (vlc * invradix_tab[category])/0x100000; + subband_coef_index[vd*i+j] = vlc - tmp * (kmax_tab[category]+1); + vlc = tmp; + } + for(j=0 ; jgb) < q->bits_per_subpacket){ + subband_coef_sign[i*vd+j] = get_bits1(&q->gb); + } else { + result=1; + subband_coef_sign[i*vd+j]=0; + } + } else { + subband_coef_sign[i*vd+j]=0; + } + } + } + return result; +} + + +/** + * Fill the mlt_buffer with mlt coefficients. + * + * @param q pointer to the COOKContext + * @param category pointer to the category array + * @param quant_index_table pointer to the array + * @param mlt_buffer pointer to mlt coefficients + */ + + +static void decode_vectors(COOKContext* q, int* category, + int *quant_index_table, float* mlt_buffer){ + /* A zero in this table means that the subband coefficient is + random noise coded. */ + int subband_coef_index[SUBBAND_SIZE]; + /* A zero in this table means that the subband coefficient is a + positive multiplicator. */ + int subband_coef_sign[SUBBAND_SIZE]; + int band, j; + int index=0; + + for(band=0 ; bandtotal_subbands ; band++){ + index = category[band]; + if(category[band] < 7){ + if(unpack_SQVH(q, category[band], subband_coef_index, subband_coef_sign)){ + index=7; + for(j=0 ; jtotal_subbands ; j++) category[band+j]=7; + } + } + if(index>=7) { + memset(subband_coef_index, 0, sizeof(subband_coef_index)); + memset(subband_coef_sign, 0, sizeof(subband_coef_sign)); + } + q->scalar_dequant(q, index, quant_index_table[band], + subband_coef_index, subband_coef_sign, + &mlt_buffer[band * SUBBAND_SIZE]); + } + + if(q->total_subbands*SUBBAND_SIZE >= q->samples_per_channel){ + return; + } /* FIXME: should this be removed, or moved into loop above? */ +} + + +/** + * function for decoding mono data + * + * @param q pointer to the COOKContext + * @param mlt_buffer pointer to mlt coefficients + */ + +static void mono_decode(COOKContext *q, float* mlt_buffer) { + + int category_index[128]; + int quant_index_table[102]; + int category[128]; + + memset(&category, 0, 128*sizeof(int)); + memset(&category_index, 0, 128*sizeof(int)); + + decode_envelope(q, quant_index_table); + q->num_vectors = get_bits(&q->gb,q->log2_numvector_size); + categorize(q, quant_index_table, category, category_index); + expand_category(q, category, category_index); + decode_vectors(q, category, quant_index_table, mlt_buffer); +} + + +/** + * the actual requantization of the timedomain samples + * + * @param q pointer to the COOKContext + * @param buffer pointer to the timedomain buffer + * @param gain_index index for the block multiplier + * @param gain_index_next index for the next block multiplier + */ + +static void interpolate_float(COOKContext *q, float* buffer, + int gain_index, int gain_index_next){ + int i; + float fc1, fc2; + fc1 = pow2tab[gain_index+63]; + + if(gain_index == gain_index_next){ //static gain + for(i=0 ; igain_size_factor ; i++){ + buffer[i]*=fc1; + } + return; + } else { //smooth gain + fc2 = q->gain_table[11 + (gain_index_next-gain_index)]; + for(i=0 ; igain_size_factor ; i++){ + buffer[i]*=fc1; + fc1*=fc2; + } + return; + } +} + +/** + * Apply transform window, overlap buffers. + * + * @param q pointer to the COOKContext + * @param inbuffer pointer to the mltcoefficients + * @param gains_ptr current and previous gains + * @param previous_buffer pointer to the previous buffer to be used for overlapping + */ + +static void imlt_window_float (COOKContext *q, float *buffer1, + cook_gains *gains_ptr, float *previous_buffer) +{ + const float fc = pow2tab[gains_ptr->previous[0] + 63]; + int i; + /* The weird thing here, is that the two halves of the time domain + * buffer are swapped. Also, the newest data, that we save away for + * next frame, has the wrong sign. Hence the subtraction below. + * Almost sounds like a complex conjugate/reverse data/FFT effect. + */ + + /* Apply window and overlap */ + for(i = 0; i < q->samples_per_channel; i++){ + buffer1[i] = buffer1[i] * fc * q->mlt_window[i] - + previous_buffer[i] * q->mlt_window[q->samples_per_channel - 1 - i]; + } +} + +/** + * The modulated lapped transform, this takes transform coefficients + * and transforms them into timedomain samples. + * Apply transform window, overlap buffers, apply gain profile + * and buffer management. + * + * @param q pointer to the COOKContext + * @param inbuffer pointer to the mltcoefficients + * @param gains_ptr current and previous gains + * @param previous_buffer pointer to the previous buffer to be used for overlapping + */ + +static void imlt_gain(COOKContext *q, float *inbuffer, + cook_gains *gains_ptr, float* previous_buffer) +{ + float *buffer0 = q->mono_mdct_output; + float *buffer1 = q->mono_mdct_output + q->samples_per_channel; + int i; + + /* Inverse modified discrete cosine transform */ + ff_imdct_calc(&q->mdct_ctx, q->mono_mdct_output, inbuffer); + + q->imlt_window (q, buffer1, gains_ptr, previous_buffer); + + /* Apply gain profile */ + for (i = 0; i < 8; i++) { + if (gains_ptr->now[i] || gains_ptr->now[i + 1]) + q->interpolate(q, &buffer1[q->gain_size_factor * i], + gains_ptr->now[i], gains_ptr->now[i + 1]); + } + + /* Save away the current to be previous block. */ + memcpy(previous_buffer, buffer0, sizeof(float)*q->samples_per_channel); +} + + +/** + * function for getting the jointstereo coupling information + * + * @param q pointer to the COOKContext + * @param decouple_tab decoupling array + * + */ + +static void decouple_info(COOKContext *q, int* decouple_tab){ + int length, i; + + if(get_bits1(&q->gb)) { + if(cplband[q->js_subband_start] > cplband[q->subbands-1]) return; + + length = cplband[q->subbands-1] - cplband[q->js_subband_start] + 1; + for (i=0 ; ijs_subband_start] + i] = get_vlc2(&q->gb, q->ccpl.table, q->ccpl.bits, 2); + } + return; + } + + if(cplband[q->js_subband_start] > cplband[q->subbands-1]) return; + + length = cplband[q->subbands-1] - cplband[q->js_subband_start] + 1; + for (i=0 ; ijs_subband_start] + i] = get_bits(&q->gb, q->js_vlc_bits); + } + return; +} + +/* + * function decouples a pair of signals from a single signal via multiplication. + * + * @param q pointer to the COOKContext + * @param subband index of the current subband + * @param f1 multiplier for channel 1 extraction + * @param f2 multiplier for channel 2 extraction + * @param decode_buffer input buffer + * @param mlt_buffer1 pointer to left channel mlt coefficients + * @param mlt_buffer2 pointer to right channel mlt coefficients + */ +static void decouple_float (COOKContext *q, + int subband, + float f1, float f2, + float *decode_buffer, + float *mlt_buffer1, float *mlt_buffer2) +{ + int j, tmp_idx; + for (j=0 ; jjs_subband_start + subband)*SUBBAND_SIZE)+j; + mlt_buffer1[SUBBAND_SIZE*subband + j] = f1 * decode_buffer[tmp_idx]; + mlt_buffer2[SUBBAND_SIZE*subband + j] = f2 * decode_buffer[tmp_idx]; + } +} + +/** + * function for decoding joint stereo data + * + * @param q pointer to the COOKContext + * @param mlt_buffer1 pointer to left channel mlt coefficients + * @param mlt_buffer2 pointer to right channel mlt coefficients + */ + +static void joint_decode(COOKContext *q, float* mlt_buffer1, + float* mlt_buffer2) { + int i,j; + int decouple_tab[SUBBAND_SIZE]; + float *decode_buffer = q->decode_buffer_0; + int idx, cpl_tmp; + float f1,f2; + const float* cplscale; + + memset(decouple_tab, 0, sizeof(decouple_tab)); + memset(decode_buffer, 0, sizeof(decode_buffer)); + + /* Make sure the buffers are zeroed out. */ + memset(mlt_buffer1,0, 1024*sizeof(float)); + memset(mlt_buffer2,0, 1024*sizeof(float)); + decouple_info(q, decouple_tab); + mono_decode(q, decode_buffer); + + /* The two channels are stored interleaved in decode_buffer. */ + for (i=0 ; ijs_subband_start ; i++) { + for (j=0 ; jjs_vlc_bits) - 1; + for (i=q->js_subband_start ; isubbands ; i++) { + cpl_tmp = cplband[i]; + idx -=decouple_tab[cpl_tmp]; + cplscale = q->cplscales[q->js_vlc_bits-2]; //choose decoupler table + f1 = cplscale[decouple_tab[cpl_tmp]]; + f2 = cplscale[idx-1]; + q->decouple (q, i, f1, f2, decode_buffer, mlt_buffer1, mlt_buffer2); + idx = (1 << q->js_vlc_bits) - 1; + } +} + +/** + * First part of subpacket decoding: + * decode raw stream bytes and read gain info. + * + * @param q pointer to the COOKContext + * @param inbuffer pointer to raw stream data + * @param gain_ptr array of current/prev gain pointers + */ + +#define FFSWAP(type,a,b) do{type SWAP_tmp= b; b= a; a= SWAP_tmp;}while(0) + +static inline void +decode_bytes_and_gain(COOKContext *q, const uint8_t *inbuffer, + cook_gains *gains_ptr) +{ + int offset; + + offset = decode_bytes(inbuffer, q->decoded_bytes_buffer, + q->bits_per_subpacket/8); + init_get_bits(&q->gb, q->decoded_bytes_buffer + offset, + q->bits_per_subpacket); + decode_gain_info(&q->gb, gains_ptr->now); + + + /* Swap current and previous gains */ + FFSWAP(int *, gains_ptr->now, gains_ptr->previous); +} + + /** + * Saturate the output signal to signed 16bit integers. + * + * @param q pointer to the COOKContext + * @param chan channel to saturate + * @param out pointer to the output vector + */ +static void +saturate_output_float (COOKContext *q, int chan, int16_t *out) +{ + int j; + float *output = q->mono_mdct_output + q->samples_per_channel; + /* Clip and convert floats to 16 bits. + */ + for (j = 0; j < q->samples_per_channel; j++) { + out[chan + q->nb_channels * j] = + av_clip_int16(lrintf(output[j])); + } +} + +/** + * Final part of subpacket decoding: + * Apply modulated lapped transform, gain compensation, + * clip and convert to integer. + * + * @param q pointer to the COOKContext + * @param decode_buffer pointer to the mlt coefficients + * @param gain_ptr array of current/prev gain pointers + * @param previous_buffer pointer to the previous buffer to be used for overlapping + * @param out pointer to the output buffer + * @param chan 0: left or single channel, 1: right channel + */ + +static inline void +mlt_compensate_output(COOKContext *q, float *decode_buffer, + cook_gains *gains, float *previous_buffer, + int16_t *out, int chan) +{ + imlt_gain(q, decode_buffer, gains, previous_buffer); + q->saturate_output (q, chan, out); +} + + +/** + * Cook subpacket decoding. This function returns one decoded subpacket, + * usually 1024 samples per channel. + * + * @param q pointer to the COOKContext + * @param inbuffer pointer to the inbuffer + * @param sub_packet_size subpacket size + * @param outbuffer pointer to the outbuffer + */ + + +static int decode_subpacket(COOKContext *q, const uint8_t *inbuffer, + int sub_packet_size, int16_t *outbuffer) { + /* packet dump */ + //int i; + //for (i=0 ; igains1); + + if (q->joint_stereo) { + joint_decode(q, q->decode_buffer_1, q->decode_buffer_2); + } else { + mono_decode(q, q->decode_buffer_1); + + if (q->nb_channels == 2) { + decode_bytes_and_gain(q, inbuffer + sub_packet_size/2, &q->gains2); + mono_decode(q, q->decode_buffer_2); + } + } + + mlt_compensate_output(q, q->decode_buffer_1, &q->gains1, + q->mono_previous_buffer1, outbuffer, 0); + + if (q->nb_channels == 2) { + if (q->joint_stereo) { + mlt_compensate_output(q, q->decode_buffer_2, &q->gains1, + q->mono_previous_buffer2, outbuffer, 1); + } else { + mlt_compensate_output(q, q->decode_buffer_2, &q->gains2, + q->mono_previous_buffer2, outbuffer, 1); + } + } + return q->samples_per_frame * sizeof(int16_t); +} + + +/** + * Cook frame decoding + * + * @param avctx pointer to the AVCodecContext + */ + +/*static int cook_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + const uint8_t *buf, int buf_size) {*/ + +static int cook_decode_frame(RMContext *rmctx,COOKContext *q, + int16_t *outbuffer, int *data_size, + const uint8_t *inbuffer, int buf_size) { + //COOKContext *q = avctx->priv_data; + //COOKContext *q; + + if (buf_size < rmctx->block_align) + return buf_size; + + *data_size = decode_subpacket(q, inbuffer, rmctx->block_align, outbuffer); + + /* Discard the first two frames: no valid audio. */ + if (rmctx->frame_number < 2) *data_size = 0; + + return rmctx->block_align; +} + +#ifdef COOKDEBUG +static void dump_cook_context(COOKContext *q) +{ + //int i=0; +#define PRINT(a,b) av_log(NULL,AV_LOG_ERROR," %s = %d\n", a, b); + av_log(NULL,AV_LOG_ERROR,"COOKextradata\n"); + av_log(NULL,AV_LOG_ERROR,"cookversion=%x\n",q->cookversion); + if (q->cookversion > STEREO) { + PRINT("js_subband_start",q->js_subband_start); + PRINT("js_vlc_bits",q->js_vlc_bits); + } + PRINT("nb_channels",q->nb_channels); + PRINT("bit_rate",q->bit_rate); + PRINT("sample_rate",q->sample_rate); + PRINT("samples_per_channel",q->samples_per_channel); + PRINT("samples_per_frame",q->samples_per_frame); + PRINT("subbands",q->subbands); + PRINT("random_state",q->random_state); + PRINT("js_subband_start",q->js_subband_start); + PRINT("log2_numvector_size",q->log2_numvector_size); + PRINT("numvector_size",q->numvector_size); + PRINT("total_subbands",q->total_subbands); +} +#endif + +static av_cold int cook_count_channels(unsigned int mask){ + int i; + int channels = 0; + for(i = 0;i<32;i++){ + if(mask & (1<cookversion = rmctx->cook_version; + q->samples_per_frame = rmctx->samples_pf_pc; + q->subbands = rmctx->nb_subbands; + q->extradata_size = rmctx->extradata_size; + if (q->extradata_size >= 16){ + q->js_subband_start = rmctx->js_subband_start; + q->js_vlc_bits = rmctx->js_vlc_bits; + } + + /* Take data from the RMContext (RM container). */ + q->sample_rate = rmctx->sample_rate; + q->nb_channels = rmctx->nb_channels; + q->bit_rate = rmctx->bit_rate; + + /* Initialize RNG. */ + av_lfg_init(&q->random_state, 1);//rand()); + + /* Initialize extradata related variables. */ + q->samples_per_channel = q->samples_per_frame / q->nb_channels; + q->bits_per_subpacket = rmctx->block_align * 8; + + /* Initialize default data states. */ + q->log2_numvector_size = 5; + q->total_subbands = q->subbands; + + /* Initialize version-dependent variables */ + av_log(NULL,AV_LOG_DEBUG,"q->cookversion=%x\n",q->cookversion); + q->joint_stereo = 0; + switch (q->cookversion) { + case MONO: + if (q->nb_channels != 1) { + av_log(NULL,AV_LOG_ERROR,"Container channels != 1, report sample!\n"); + return -1; + } + av_log(NULL,AV_LOG_DEBUG,"MONO\n"); + break; + case STEREO: + if (q->nb_channels != 1) { + q->bits_per_subpacket = q->bits_per_subpacket/2; + } + av_log(NULL,AV_LOG_DEBUG,"STEREO\n"); + break; + case JOINT_STEREO: + if (q->nb_channels != 2) { + av_log(NULL,AV_LOG_ERROR,"Container channels != 2, report sample!\n"); + return -1; + } + av_log(NULL,AV_LOG_ERROR,"JOINT_STEREO\n"); + if (q->extradata_size >= 16){ + q->total_subbands = q->subbands + q->js_subband_start; + q->joint_stereo = 1; + } + if (q->samples_per_channel > 256) { + q->log2_numvector_size = 6; + } + if (q->samples_per_channel > 512) { + q->log2_numvector_size = 7; + } + break; + case MC_COOK: + av_log(NULL,AV_LOG_ERROR,"MC_COOK not supported!\n"); + return -1; + break; + default: + av_log(NULL,AV_LOG_ERROR,"Unknown Cook version, report sample!\n"); + return -1; + break; + } + + /* Initialize variable relations */ + q->numvector_size = (1 << q->log2_numvector_size); + + /* Generate tables */ + init_pow2table(); + init_gain_table(q); + init_cplscales_table(q); + + if (init_cook_vlc_tables(q) != 0) + return -1; + + + if(q->block_align >= UINT_MAX/2) + return -1; + + /* Pad the databuffer with: + DECODE_BYTES_PAD1 or DECODE_BYTES_PAD2 for decode_bytes(), + INPUT_BUFFER_PADDING_SIZE, for the bitstreamreader. */ + +#define INPUT_BUFFER_PADDING_SIZE 8 + if (q->nb_channels==2 && q->joint_stereo==0) { + q->decoded_bytes_buffer = + av_mallocz(rmctx->block_align/2 + + DECODE_BYTES_PAD2(q->block_align/2) + + INPUT_BUFFER_PADDING_SIZE); + } else { + q->decoded_bytes_buffer = + av_mallocz(rmctx->block_align + + DECODE_BYTES_PAD1(q->block_align) + + INPUT_BUFFER_PADDING_SIZE); + } + if (q->decoded_bytes_buffer == NULL) + return -1; + + q->gains1.now = q->gain_1; + q->gains1.previous = q->gain_2; + q->gains2.now = q->gain_3; + q->gains2.previous = q->gain_4; + + /* Initialize transform. */ + if ( init_cook_mlt(q) != 0 ) + return -1; + + /* Initialize COOK signal arithmetic handling */ + if (1) { + q->scalar_dequant = scalar_dequant_float; + q->decouple = decouple_float; + q->imlt_window = imlt_window_float; + q->interpolate = interpolate_float; + q->saturate_output = saturate_output_float; + } + + /* Try to catch some obviously faulty streams, othervise it might be exploitable */ + if (q->total_subbands > 53) { + av_log(NULL,AV_LOG_ERROR,"total_subbands > 53, report sample!\n"); + return -1; + } + if (q->subbands > 50) { + av_log(NULL,AV_LOG_ERROR,"subbands > 50, report sample!\n"); + return -1; + } + if ((q->samples_per_channel == 256) || (q->samples_per_channel == 512) || (q->samples_per_channel == 1024)) { + } else { + av_log(NULL,AV_LOG_ERROR,"unknown amount of samples_per_channel = %d, report sample!\n",q->samples_per_channel); + return -1; + } + if ((q->js_vlc_bits > 6) || (q->js_vlc_bits < 0)) { + av_log(NULL,AV_LOG_ERROR,"q->js_vlc_bits = %d, only >= 0 and <= 6 allowed!\n",q->js_vlc_bits); + return -1; + } + + +#ifdef COOKDEBUG + dump_cook_context(q); +#endif + return 0; +} + + +int main(int argc, char *argv[]) { + int fd, fd_out, fd_dec; + int res, h,datasize, nb_frames,packet_count,x,y,i,fs,sps; + char filename[15]; + int8_t outbuf[4096]; + uint8_t inbuf[1024]; + COOKContext q; + RMContext rmctx; + RMPacket pkt; + memset(&q,0,sizeof(COOKContext)); + memset(&rmctx,0,sizeof(RMContext)); + memset(&pkt,0,sizeof(RMPacket)); + if (argc != 2) { + av_log(NULL,AV_LOG_ERROR,"Incorrect number of arguments\n"); + return -1; + } + + fd = open(argv[1],O_RDONLY); + if (fd < 0) { + av_log(NULL,AV_LOG_ERROR,"Error opening file %s\n", argv[1]); + return -1; + } + + fd_dec = open_wav("output.wav"); + if (fd_dec < 0) { + av_log(NULL,AV_LOG_ERROR,"Error creating output file\n"); + return -1; + } + res = real_parse_header(fd, &rmctx); + packet_count = (int) rmctx.nb_packets; + rmctx.audio_framesize = rmctx.block_align; + rmctx.block_align = rmctx.sub_packet_size; + fs = (int) rmctx.audio_framesize; + sps= (int) rmctx.block_align; + h = (int) rmctx.sub_packet_h; + cook_decode_init(&rmctx,&q); + av_log(NULL,AV_LOG_ERROR,"nb_frames = %d\n",nb_frames); + x = 0; y = 0; + if(packet_count % h) + { + packet_count += h - (packet_count % h); + rmctx.nb_packets = packet_count; + } + while(packet_count )//>= h || packet_count >= -1*h ) + { + + memset(pkt.data,0,sizeof(pkt.data)); + rm_get_packet(fd, &rmctx, &pkt); + DEBUGF("total frames = %d packet count = %d output counter = %d \n",rmctx.audio_pkt_cnt*(fs/sps), packet_count,rmctx.audio_pkt_cnt); + //getchar(); + for(i = 0; i < rmctx.audio_pkt_cnt*(fs/sps) ; i++) + { + //snprintf(filename,sizeof(filename),"dump%d.raw",++x); + //fd_out = open(filename,O_WRONLY|O_CREAT|O_APPEND); + //write(fd_out,pkt.data+i*sps,sps); + memcpy(inbuf,pkt.data+i*sps,sps); + nb_frames = cook_decode_frame(&rmctx,&q, outbuf, &datasize, inbuf , rmctx.block_align); + //av_log(NULL,AV_LOG_ERROR,"nb_frames = %d frame number = %d datasize = %d\n",nb_frames,rmctx.frame_number,datasize); + rmctx.frame_number++; + //write(fd_out,outbuf,datasize); + write(fd_dec,outbuf,datasize); + //getchar(); + //av_log(NULL,AV_LOG_ERROR,"Wrote frame %d nb_frames = %d datasize = %d\n",++x,nb_frames,datasize); + //close(fd_out); + } + packet_count -= rmctx.audio_pkt_cnt; + rmctx.audio_pkt_cnt = 0; + } + //if(packet_count < h) rmctx.nb_packets += (h % (packet_count > 0 ? packet_count: h+packet_count)) - packet_count; + cook_decode_close(&q); + close_wav(fd_dec,&rmctx); + close(fd); + + + return 0; +} Index: apps/codecs/libcook/Makefile =================================================================== --- apps/codecs/libcook/Makefile (revision 0) +++ apps/codecs/libcook/Makefile (revision 0) @@ -0,0 +1,11 @@ +CFLAGS = -Wall -O3 +#INC=-Ilibasf +OBJS = bitstream.o cook.o fft.o libavutil/log.o mdct.o libavutil/mem.o random.o libavutil/lfg.o libavutil/md5.o rm2wav.o +cooktest.o: $(OBJS) + gcc -o cooktest.o $(OBJS) -lm + +.c.o : + $(CC) $(CFLAGS) -c -o $@ $< + +clean: + rm -f cooktest.o $(OBJS) *~