diff options
Diffstat (limited to 'src/libffmpeg/libavcodec')
60 files changed, 6454 insertions, 3825 deletions
diff --git a/src/libffmpeg/libavcodec/Makefile.am b/src/libffmpeg/libavcodec/Makefile.am index 457c5f275..f49a345ee 100644 --- a/src/libffmpeg/libavcodec/Makefile.am +++ b/src/libffmpeg/libavcodec/Makefile.am @@ -9,8 +9,8 @@ EXTRA_DIST = motion_est_template.c imgresample.c \ # we need to compile everything in debug mode, including the encoders, # otherwise we get unresolved symbols, because some unsatisfied function calls # are not optimized away with debug optimization -AM_CFLAGS = $(LIBFFMPEG_CFLAGS) `test "$(CFLAGS)" = "$(DEBUG_CFLAGS)" && echo -DCONFIG_ENCODERS` -AM_CPPFLAGS = $(ZLIB_CPPFLAGS) +AM_CFLAGS = $(LIBFFMPEG_CFLAGS) `test "$(CFLAGS)" = "$(DEBUG_CFLAGS)" && echo -DCONFIG_ENCODERS` -I../libavutil +AM_CPPFLAGS = $(ZLIB_CPPFLAGS) -I../libavutil ASFLAGS = noinst_LTLIBRARIES = libavcodec.la @@ -67,6 +67,7 @@ libavcodec_la_SOURCES = \ msvideo1.c \ parser.c \ pcm.c \ + qdm2.c \ qdrw.c \ qpeg.c \ qtrle.c \ @@ -74,7 +75,6 @@ libavcodec_la_SOURCES = \ ra288.c \ rangecoder.c \ ratecontrol.c \ - rational.c \ roqvideo.c \ rpza.c \ rv10.c \ @@ -112,7 +112,6 @@ noinst_HEADERS = \ bitstream.h \ bswap.h \ cabac.h \ - common.h \ dsputil.h \ dvdata.h \ faandct.h \ @@ -132,10 +131,11 @@ noinst_HEADERS = \ mpegaudiotab.h \ mpegvideo.h \ msmpeg4data.h \ + opt.h \ + qdm2data.h \ ra144.h \ ra288.h \ rangecoder.h \ - rational.h \ simple_idct.h \ sp5x.h \ svq1_cb.h \ diff --git a/src/libffmpeg/libavcodec/avcodec.h b/src/libffmpeg/libavcodec/avcodec.h index c14867d34..6864bfba3 100644 --- a/src/libffmpeg/libavcodec/avcodec.h +++ b/src/libffmpeg/libavcodec/avcodec.h @@ -11,21 +11,21 @@ extern "C" { #endif -#include "common.h" -#include "rational.h" +#include "avutil.h" #include <sys/types.h> /* size_t */ +//FIXME the following 2 really dont belong in here #define FFMPEG_VERSION_INT 0x000409 #define FFMPEG_VERSION "CVS" -#define LIBAVCODEC_BUILD 4758 - - -#define LIBAVCODEC_VERSION_INT FFMPEG_VERSION_INT -#define LIBAVCODEC_VERSION FFMPEG_VERSION #define AV_STRINGIFY(s) AV_TOSTRING(s) #define AV_TOSTRING(s) #s -#define LIBAVCODEC_IDENT "FFmpeg" LIBAVCODEC_VERSION "b" AV_STRINGIFY(LIBAVCODEC_BUILD) + +#define LIBAVCODEC_VERSION_INT ((50<<16)+(1<<8)+0) +#define LIBAVCODEC_VERSION 50.1.0 +#define LIBAVCODEC_BUILD LIBAVCODEC_VERSION_INT + +#define LIBAVCODEC_IDENT "Lavc" AV_STRINGIFY(LIBAVCODEC_VERSION) #define AV_NOPTS_VALUE int64_t_C(0x8000000000000000) #define AV_TIME_BASE 1000000 @@ -118,6 +118,7 @@ enum CodecID { CODEC_ID_AASC, CODEC_ID_INDEO2, CODEC_ID_FRAPS, + CODEC_ID_TRUEMOTION2, /* various pcm "codecs" */ CODEC_ID_PCM_S16LE= 0x10000, @@ -128,6 +129,15 @@ enum CodecID { 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, /* various adpcm codecs */ CODEC_ID_ADPCM_IMA_QT= 0x11000, @@ -182,6 +192,7 @@ enum CodecID { CODEC_ID_ALAC, CODEC_ID_WESTWOOD_SND1, CODEC_ID_GSM, + CODEC_ID_QDM2, CODEC_ID_OGGTHEORA= 0x16000, @@ -285,14 +296,6 @@ enum Motion_Est_ID { ME_X1 }; -enum AVRounding { - AV_ROUND_ZERO = 0, ///< round toward zero - AV_ROUND_INF = 1, ///< round away from zero - AV_ROUND_DOWN = 2, ///< round toward -infinity - AV_ROUND_UP = 3, ///< round toward +infinity - AV_ROUND_NEAR_INF = 5, ///< round to nearest and halfway cases away from zero -}; - 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 @@ -687,6 +690,7 @@ struct AVCLASS { or AVFormatContext, which begin with an AVClass. Needed because av_log is in libavcodec and has no visibility of AVIn/OutputFormat */ + struct AVOption *option; }; /** @@ -747,14 +751,17 @@ typedef struct AVCodecContext { void *extradata; int extradata_size; - /* video only */ /** - * time base in which the timestamps are specified. + * 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 lavc. */ AVRational time_base; + /* video only */ /** * picture width / height. * - encoding: MUST be set by user. @@ -1007,7 +1014,7 @@ typedef struct AVCodecContext { * - decoding: set by user */ int error_resilience; -#define FF_ER_CAREFULL 1 +#define FF_ER_CAREFUL 1 #define FF_ER_COMPLIANT 2 #define FF_ER_AGGRESSIVE 3 #define FF_ER_VERY_AGGRESSIVE 4 @@ -1214,6 +1221,7 @@ typedef struct AVCodecContext { #define FF_IDCT_H264 11 #define FF_IDCT_VP3 12 #define FF_IDCT_IPP 13 +#define FF_IDCT_XVIDMMX 14 /** * slice count. @@ -1850,42 +1858,6 @@ typedef struct AVCodecContext { enum AVDiscard skip_frame; } AVCodecContext; - -/** - * AVOption. - */ -typedef struct AVOption { - /** options' name */ - const char *name; /* if name is NULL, it indicates a link to next */ - /** short English text help or const struct AVOption* subpointer */ - const char *help; // const struct AVOption* sub; - /** offset to context structure where the parsed value should be stored */ - int offset; - /** options' type */ - int type; -#define FF_OPT_TYPE_BOOL 1 ///< boolean - true,1,on (or simply presence) -#define FF_OPT_TYPE_DOUBLE 2 ///< double -#define FF_OPT_TYPE_INT 3 ///< integer -#define FF_OPT_TYPE_STRING 4 ///< string (finished with \0) -#define FF_OPT_TYPE_MASK 0x1f ///< mask for types - upper bits are various flags -//#define FF_OPT_TYPE_EXPERT 0x20 // flag for expert option -#define FF_OPT_TYPE_FLAG (FF_OPT_TYPE_BOOL | 0x40) -#define FF_OPT_TYPE_RCOVERRIDE (FF_OPT_TYPE_STRING | 0x80) - /** min value (min == max -> no limits) */ - double min; - /** maximum value for double/int */ - double max; - /** default boo [0,1]l/double/int value */ - double defval; - /** - * default string value (with optional semicolon delimited extra option-list - * i.e. option1;option2;option3 - * defval might select other then first argument as default - */ - const char *defstr; -#define FF_OPT_MAX_DEPTH 10 -} AVOption; - /** * AVCodec. */ @@ -1900,7 +1872,9 @@ typedef struct AVCodec { int (*decode)(AVCodecContext *, void *outdata, int *outdata_size, uint8_t *buf, int buf_size); int capabilities; +#if LIBAVCODEC_VERSION_INT < ((50<<16)+(0<<8)+0) void *dummy; // FIXME remove next time we break binary compatibility +#endif struct AVCodec *next; void (*flush)(AVCodecContext *); const AVRational *supported_framerates; ///array of supported framerates, or NULL if any, array is terminated by {0,0} @@ -2034,6 +2008,7 @@ extern AVCodec mp2_decoder; extern AVCodec mp3_decoder; extern AVCodec mp3adu_decoder; extern AVCodec mp3on4_decoder; +extern AVCodec qdm2_decoder; extern AVCodec mace3_decoder; extern AVCodec mace6_decoder; extern AVCodec huffyuv_decoder; @@ -2074,6 +2049,7 @@ extern AVCodec flic_decoder; extern AVCodec vmdvideo_decoder; extern AVCodec vmdaudio_decoder; extern AVCodec truemotion1_decoder; +extern AVCodec truemotion2_decoder; extern AVCodec mszh_decoder; extern AVCodec zlib_decoder; extern AVCodec ra_144_decoder; @@ -2107,6 +2083,15 @@ extern AVCodec libgsm_decoder; extern AVCodec name ## _decoder; \ extern AVCodec name ## _encoder +PCM_CODEC(CODEC_ID_PCM_S32LE, pcm_s32le); +PCM_CODEC(CODEC_ID_PCM_S32BE, pcm_s32be); +PCM_CODEC(CODEC_ID_PCM_U32LE, pcm_u32le); +PCM_CODEC(CODEC_ID_PCM_U32BE, pcm_u32be); +PCM_CODEC(CODEC_ID_PCM_S24LE, pcm_s24le); +PCM_CODEC(CODEC_ID_PCM_S24BE, pcm_s24be); +PCM_CODEC(CODEC_ID_PCM_U24LE, pcm_u24le); +PCM_CODEC(CODEC_ID_PCM_U24BE, pcm_u24be); +PCM_CODEC(CODEC_ID_PCM_S24DAUD, pcm_s24daud); PCM_CODEC(CODEC_ID_PCM_S16LE, pcm_s16le); PCM_CODEC(CODEC_ID_PCM_S16BE, pcm_s16be); PCM_CODEC(CODEC_ID_PCM_U16LE, pcm_u16le); @@ -2314,30 +2299,6 @@ void avcodec_default_free_buffers(AVCodecContext *s); */ char av_get_pict_type_char(int pict_type); -/** - * reduce a fraction. - * this is usefull for framerate calculations - * @param max the maximum allowed for dst_nom & dst_den - * @return 1 if exact, 0 otherwise - */ -int av_reduce(int *dst_nom, int *dst_den, int64_t nom, int64_t den, int64_t max); - -/** - * rescale a 64bit integer with rounding to nearest. - * a simple a*b/c isn't possible as it can overflow - */ -int64_t av_rescale(int64_t a, int64_t b, int64_t c); - -/** - * rescale a 64bit integer with specified rounding. - * a simple a*b/c isn't possible as it can overflow - */ -int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding); - -/** - * rescale a 64bit integer by 2 rational numbers. - */ -int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq); /* frame parsing */ typedef struct AVCodecParserContext { @@ -2363,6 +2324,9 @@ typedef struct AVCodecParserContext { 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 } AVCodecParserContext; typedef struct AVCodecParser { diff --git a/src/libffmpeg/libavcodec/bitstream.c b/src/libffmpeg/libavcodec/bitstream.c index fcd4fd9cb..a8f456bd2 100755 --- a/src/libffmpeg/libavcodec/bitstream.c +++ b/src/libffmpeg/libavcodec/bitstream.c @@ -37,7 +37,7 @@ void align_put_bits(PutBitContext *s) #endif } -void put_string(PutBitContext * pbc, char *s, int put_zero) +void ff_put_string(PutBitContext * pbc, char *s, int put_zero) { while(*s){ put_bits(pbc, 8, *s); diff --git a/src/libffmpeg/libavcodec/bitstream.h b/src/libffmpeg/libavcodec/bitstream.h index 0e60ea1d4..0182b630b 100644 --- a/src/libffmpeg/libavcodec/bitstream.h +++ b/src/libffmpeg/libavcodec/bitstream.h @@ -53,6 +53,11 @@ typedef struct 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 @@ -95,7 +100,7 @@ static inline void flush_put_bits(PutBitContext *s) } void align_put_bits(PutBitContext *s); -void put_string(PutBitContext * pbc, char *s, int put_zero); +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 */ @@ -672,7 +677,11 @@ static inline void skip_bits1(GetBitContext *s){ static inline void init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size) { - const int buffer_size= (bit_size+7)>>3; + 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; diff --git a/src/libffmpeg/libavcodec/cinepak.c b/src/libffmpeg/libavcodec/cinepak.c index 3b00a1605..d1e1f0ec1 100644 --- a/src/libffmpeg/libavcodec/cinepak.c +++ b/src/libffmpeg/libavcodec/cinepak.c @@ -316,13 +316,22 @@ static int cinepak_decode (CinepakContext *s) uint8_t *eod = (s->data + s->size); int i, result, strip_size, frame_flags, num_strips; int y0 = 0; + int encoded_buf_size; + /* if true, Cinepak data is from a Sega FILM/CPK file */ + int sega_film_data = 0; if (s->size < 10) return -1; frame_flags = s->data[0]; num_strips = BE_16 (&s->data[8]); - s->data += 10; + encoded_buf_size = BE_16 (&s->data[2]); + if (encoded_buf_size != s->size) + sega_film_data = 1; + if (sega_film_data) + s->data += 12; + else + s->data += 10; if (num_strips > MAX_STRIPS) num_strips = MAX_STRIPS; diff --git a/src/libffmpeg/libavcodec/common.h b/src/libffmpeg/libavcodec/common.h deleted file mode 100644 index 3f7ae5081..000000000 --- a/src/libffmpeg/libavcodec/common.h +++ /dev/null @@ -1,555 +0,0 @@ -/** - * @file common.h - * common internal api header. - */ - -#ifndef COMMON_H -#define COMMON_H - -/* xine: disable DEBUG for ffmpeg (too noisy) */ -#ifdef DEBUG -#undef DEBUG -#endif - -#if defined(WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__) -# define CONFIG_WIN32 -#endif - -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - -#ifdef HAVE_AV_CONFIG_H -/* only include the following when compiling package */ -# include "config.h" - -# include <stdlib.h> -# include <stdio.h> -# include <string.h> -# include <ctype.h> -# include <limits.h> -# ifndef __BEOS__ -# include <errno.h> -# else -# include "berrno.h" -# endif -# include <math.h> - -# ifndef ENODATA -# define ENODATA 61 -# endif - -#include <stddef.h> -#ifndef offsetof -# define offsetof(T,F) ((unsigned int)((char *)&((T *)0)->F)) -#endif - -#define AVOPTION_CODEC_BOOL(name, help, field) \ - { name, help, offsetof(AVCodecContext, field), FF_OPT_TYPE_BOOL } -#define AVOPTION_CODEC_DOUBLE(name, help, field, minv, maxv, defval) \ - { name, help, offsetof(AVCodecContext, field), FF_OPT_TYPE_DOUBLE, minv, maxv, defval } -#define AVOPTION_CODEC_FLAG(name, help, field, flag, defval) \ - { name, help, offsetof(AVCodecContext, field), FF_OPT_TYPE_FLAG, flag, 0, defval } -#define AVOPTION_CODEC_INT(name, help, field, minv, maxv, defval) \ - { name, help, offsetof(AVCodecContext, field), FF_OPT_TYPE_INT, minv, maxv, defval } -#define AVOPTION_CODEC_STRING(name, help, field, str, val) \ - { name, help, offsetof(AVCodecContext, field), FF_OPT_TYPE_STRING, .defval = val, .defstr = str } -#define AVOPTION_CODEC_RCOVERRIDE(name, help, field) \ - { name, help, offsetof(AVCodecContext, field), FF_OPT_TYPE_RCOVERRIDE, .defval = 0, .defstr = NULL } -#define AVOPTION_SUB(ptr) { .name = NULL, .help = (const char*)ptr } -#define AVOPTION_END() AVOPTION_SUB(NULL) - -#endif /* HAVE_AV_CONFIG_H */ - -/* Suppress restrict if it was not defined in config.h. */ -#ifndef restrict -# define restrict -#endif - -#ifndef always_inline -#if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 0) -# define always_inline __attribute__((always_inline)) inline -#else -# define always_inline inline -#endif -#endif - -#ifndef attribute_used -#if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 0) -# define attribute_used __attribute__((used)) -#else -# define attribute_used -#endif -#endif - -#ifndef attribute_unused -#if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 0) -# define attribute_unused __attribute__((unused)) -#else -# define attribute_unused -#endif -#endif - -#ifndef EMULATE_INTTYPES -# include <inttypes.h> -#else - typedef signed char int8_t; - typedef signed short int16_t; - typedef signed int int32_t; - typedef unsigned char uint8_t; - typedef unsigned short uint16_t; - typedef unsigned int uint32_t; - -# ifdef CONFIG_WIN32 - typedef signed __int64 int64_t; - typedef unsigned __int64 uint64_t; -# else /* other OS */ - typedef signed long long int64_t; - typedef unsigned long long uint64_t; -# endif /* other OS */ -#endif /* HAVE_INTTYPES_H */ - -#ifndef INT16_MIN -#define INT16_MIN (-0x7fff-1) -#endif - -#ifndef INT16_MAX -#define INT16_MAX 0x7fff -#endif - -#ifndef INT64_MIN -#define INT64_MIN (-0x7fffffffffffffffLL-1) -#endif - -#ifndef INT64_MAX -#define INT64_MAX int64_t_C(9223372036854775807) -#endif - -#ifndef UINT64_MAX -#define UINT64_MAX uint64_t_C(0xFFFFFFFFFFFFFFFF) -#endif - -#ifdef EMULATE_FAST_INT -typedef signed char int_fast8_t; -typedef signed int int_fast16_t; -typedef signed int int_fast32_t; -typedef unsigned char uint_fast8_t; -typedef unsigned int uint_fast16_t; -typedef unsigned int uint_fast32_t; -typedef uint64_t uint_fast64_t; -#endif - -#ifndef INT_BIT -# if INT_MAX != 2147483647 -# define INT_BIT 64 -# else -# define INT_BIT 32 -# endif -#endif - -#if defined(CONFIG_OS2) || defined(CONFIG_SUNOS) -static inline float floorf(float f) { - return floor(f); -} -#endif - -#ifdef CONFIG_WIN32 - -/* windows */ - -# if !defined(__MINGW32__) && !defined(__CYGWIN__) -# define int64_t_C(c) (c ## i64) -# define uint64_t_C(c) (c ## i64) - -# ifdef HAVE_AV_CONFIG_H -# define inline __inline -# endif - -# else -# define int64_t_C(c) (c ## LL) -# define uint64_t_C(c) (c ## ULL) -# endif /* __MINGW32__ */ - -# ifdef HAVE_AV_CONFIG_H -# ifdef _DEBUG -# define DEBUG -# endif - -# define snprintf _snprintf -# define vsnprintf _vsnprintf -# endif - -/* CONFIG_WIN32 end */ -#elif defined (CONFIG_OS2) -/* OS/2 EMX */ - -#ifndef int64_t_C -#define int64_t_C(c) (c ## LL) -#define uint64_t_C(c) (c ## ULL) -#endif - -#ifdef HAVE_AV_CONFIG_H - -#ifdef USE_FASTMEMCPY -#include "fastmemcpy.h" -#endif - -#include <float.h> - -#endif /* HAVE_AV_CONFIG_H */ - -/* CONFIG_OS2 end */ -#else - -/* unix */ - -#ifndef int64_t_C -#define int64_t_C(c) (c ## LL) -#define uint64_t_C(c) (c ## ULL) -#endif - -#ifdef HAVE_AV_CONFIG_H - -# ifdef USE_FASTMEMCPY -# include "fastmemcpy.h" -# endif -# endif /* HAVE_AV_CONFIG_H */ - -#endif /* !CONFIG_WIN32 && !CONFIG_OS2 */ - -#ifdef HAVE_AV_CONFIG_H - -# include "bswap.h" - -// Use rip-relative addressing if compiling PIC code on x86-64. -# if defined(__MINGW32__) || defined(__CYGWIN__) || \ - defined(__OS2__) || (defined (__OpenBSD__) && !defined(__ELF__)) -# if defined(ARCH_X86_64) && defined(PIC) -# define MANGLE(a) "_" #a"(%%rip)" -# else -# define MANGLE(a) "_" #a -# endif -# else -# if defined(ARCH_X86_64) && defined(PIC) -# define MANGLE(a) #a"(%%rip)" -# else -# define MANGLE(a) #a -# endif -# endif - -/* debug stuff */ - -# ifndef DEBUG -# ifndef NDEBUG -# define NDEBUG -# endif -# endif -# include <assert.h> - -/* dprintf macros */ -# if defined(CONFIG_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__) - -inline void dprintf(const char* fmt,...) {} - -# else - -# ifdef DEBUG -# define dprintf(fmt,...) av_log(NULL, AV_LOG_DEBUG, fmt, __VA_ARGS__) -# else -# define dprintf(fmt,...) -# endif - -# endif /* !CONFIG_WIN32 */ - -# define av_abort() do { av_log(NULL, AV_LOG_ERROR, "Abort at %s:%d\n", __FILE__, __LINE__); abort(); } while (0) - -//rounded divison & shift -#define RSHIFT(a,b) ((a) > 0 ? ((a) + ((1<<(b))>>1))>>(b) : ((a) + ((1<<(b))>>1)-1)>>(b)) -/* assume b>0 */ -#define ROUNDED_DIV(a,b) (((a)>0 ? (a) + ((b)>>1) : (a) - ((b)>>1))/(b)) -#define ABS(a) ((a) >= 0 ? (a) : (-(a))) - -#define FFMAX(a,b) ((a) > (b) ? (a) : (b)) -#define FFMIN(a,b) ((a) > (b) ? (b) : (a)) - -extern const uint32_t inverse[256]; - -#if defined(ARCH_X86) || defined(ARCH_X86_64) -# define FASTDIV(a,b) \ - ({\ - int ret,dmy;\ - asm volatile(\ - "mull %3"\ - :"=d"(ret),"=a"(dmy)\ - :"1"(a),"g"(inverse[b])\ - );\ - ret;\ - }) -#elif defined(CONFIG_FASTDIV) -# define FASTDIV(a,b) ((uint32_t)((((uint64_t)a)*inverse[b])>>32)) -#else -# define FASTDIV(a,b) ((a)/(b)) -#endif - -/* define it to include statistics code (useful only for optimizing - codec efficiency */ -//#define STATS - -#ifdef STATS - -enum { - ST_UNKNOWN, - ST_DC, - ST_INTRA_AC, - ST_INTER_AC, - ST_INTRA_MB, - ST_INTER_MB, - ST_MV, - ST_NB, -}; - -extern int st_current_index; -extern unsigned int st_bit_counts[ST_NB]; -extern unsigned int st_out_bit_counts[ST_NB]; - -void print_stats(void); -#endif - -/* misc math functions */ -extern const uint8_t ff_log2_tab[256]; - -static inline int av_log2(unsigned int v) -{ - int n; - - n = 0; - if (v & 0xffff0000) { - v >>= 16; - n += 16; - } - if (v & 0xff00) { - v >>= 8; - n += 8; - } - n += ff_log2_tab[v]; - - return n; -} - -static inline int av_log2_16bit(unsigned int v) -{ - int n; - - n = 0; - if (v & 0xff00) { - v >>= 8; - n += 8; - } - n += ff_log2_tab[v]; - - return n; -} - -/* median of 3 */ -static inline int mid_pred(int a, int b, int c) -{ -#if 0 - int t= (a-b)&((a-b)>>31); - a-=t; - b+=t; - b-= (b-c)&((b-c)>>31); - b+= (a-b)&((a-b)>>31); - - return b; -#else - if(a>b){ - if(c>b){ - if(c>a) b=a; - else b=c; - } - }else{ - if(b>c){ - if(c>a) b=c; - else b=a; - } - } - return b; -#endif -} - -static inline int clip(int a, int amin, int amax) -{ - if (a < amin) - return amin; - else if (a > amax) - return amax; - else - return a; -} - -static inline int clip_uint8(int a) -{ - if (a&(~255)) return (-a)>>31; - else return a; -} - -/* math */ -extern const uint8_t ff_sqrt_tab[128]; - -int64_t ff_gcd(int64_t a, int64_t b); - -static inline int ff_sqrt(int a) -{ - int ret=0; - int s; - int ret_sq=0; - - if(a<128) return ff_sqrt_tab[a]; - - for(s=15; s>=0; s--){ - int b= ret_sq + (1<<(s*2)) + (ret<<s)*2; - if(b<=a){ - ret_sq=b; - ret+= 1<<s; - } - } - return ret; -} - -/** - * converts fourcc string to int - */ -static inline int ff_get_fourcc(const char *s){ - assert( strlen(s)==4 ); - - return (s[0]) + (s[1]<<8) + (s[2]<<16) + (s[3]<<24); -} - -#define MKTAG(a,b,c,d) (a | (b << 8) | (c << 16) | (d << 24)) -#define MKBETAG(a,b,c,d) (d | (c << 8) | (b << 16) | (a << 24)) - - -#if defined(ARCH_X86) || defined(ARCH_X86_64) -#define MASK_ABS(mask, level)\ - asm volatile(\ - "cdq \n\t"\ - "xorl %1, %0 \n\t"\ - "subl %1, %0 \n\t"\ - : "+a" (level), "=&d" (mask)\ - ); -#else -#define MASK_ABS(mask, level)\ - mask= level>>31;\ - level= (level^mask)-mask; -#endif - - -#if __CPU__ >= 686 && !defined(RUNTIME_CPUDETECT) -#define COPY3_IF_LT(x,y,a,b,c,d)\ -asm volatile (\ - "cmpl %0, %3 \n\t"\ - "cmovl %3, %0 \n\t"\ - "cmovl %4, %1 \n\t"\ - "cmovl %5, %2 \n\t"\ - : "+r" (x), "+r" (a), "+r" (c)\ - : "r" (y), "r" (b), "r" (d)\ -); -#else -#define COPY3_IF_LT(x,y,a,b,c,d)\ -if((y)<(x)){\ - (x)=(y);\ - (a)=(b);\ - (c)=(d);\ -} -#endif - -#if defined(ARCH_X86) || defined(ARCH_X86_64) || defined(ARCH_POWERPC) -#if defined(ARCH_X86_64) -static inline uint64_t read_time(void) -{ - uint64_t a, d; - asm volatile( "rdtsc\n\t" - : "=a" (a), "=d" (d) - ); - return (d << 32) | (a & 0xffffffff); -} -#elif defined(ARCH_X86) -static inline long long read_time(void) -{ - long long l; - asm volatile( "rdtsc\n\t" - : "=A" (l) - ); - return l; -} -#else //FIXME check ppc64 -static inline uint64_t read_time(void) -{ - uint32_t tbu, tbl, temp; - - /* from section 2.2.1 of the 32-bit PowerPC PEM */ - __asm__ __volatile__( - "1:\n" - "mftbu %2\n" - "mftb %0\n" - "mftbu %1\n" - "cmpw %2,%1\n" - "bne 1b\n" - : "=r"(tbl), "=r"(tbu), "=r"(temp) - : - : "cc"); - - return (((uint64_t)tbu)<<32) | (uint64_t)tbl; -} -#endif - -#define START_TIMER \ -uint64_t tend;\ -uint64_t tstart= read_time();\ - -#define STOP_TIMER(id) \ -tend= read_time();\ -{\ - static uint64_t tsum=0;\ - static int tcount=0;\ - static int tskip_count=0;\ - if(tcount<2 || tend - tstart < 8*tsum/tcount){\ - tsum+= tend - tstart;\ - tcount++;\ - }else\ - tskip_count++;\ - if(256*256*256*64%(tcount+tskip_count)==0){\ - av_log(NULL, AV_LOG_DEBUG, "%Ld dezicycles in %s, %d runs, %d skips\n", tsum*10/tcount, id, tcount, tskip_count);\ - }\ -} -#else -#define START_TIMER -#define STOP_TIMER(id) {} -#endif - -/* avoid usage of various functions */ -#define malloc please_use_av_malloc -#define free please_use_av_free -#define realloc please_use_av_realloc -#define time time_is_forbidden_due_to_security_issues -#define rand rand_is_forbidden_due_to_state_trashing -#define srand srand_is_forbidden_due_to_state_trashing -#define sprintf sprintf_is_forbidden_due_to_security_issues_use_snprintf -#define strcat strcat_is_forbidden_due_to_security_issues_use_pstrcat -#if !(defined(LIBAVFORMAT_BUILD) || defined(_FRAMEHOOK_H)) -#define printf please_use_av_log -#define fprintf please_use_av_log -#endif - -#define CHECKED_ALLOCZ(p, size)\ -{\ - p= av_mallocz(size);\ - if(p==NULL && (size)!=0){\ - perror("malloc");\ - goto fail;\ - }\ -} - -#endif /* HAVE_AV_CONFIG_H */ - -#endif /* COMMON_H */ diff --git a/src/libffmpeg/libavcodec/cyuv.c b/src/libffmpeg/libavcodec/cyuv.c index 82bc21005..34de8cc04 100644 --- a/src/libffmpeg/libavcodec/cyuv.c +++ b/src/libffmpeg/libavcodec/cyuv.c @@ -51,6 +51,9 @@ static int cyuv_decode_init(AVCodecContext *avctx) s->avctx = avctx; s->width = avctx->width; + /* width needs to be divisible by 4 for this codec to work */ + if (s->width & 0x3) + return -1; s->height = avctx->height; avctx->pix_fmt = PIX_FMT_YUV411P; avctx->has_b_frames = 0; diff --git a/src/libffmpeg/libavcodec/dsputil.c b/src/libffmpeg/libavcodec/dsputil.c index 698b906ea..5a23672a3 100644 --- a/src/libffmpeg/libavcodec/dsputil.c +++ b/src/libffmpeg/libavcodec/dsputil.c @@ -2990,7 +2990,8 @@ static int pix_abs8_xy2_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, return s; } -static int nsse16_c(MpegEncContext *c, uint8_t *s1, uint8_t *s2, int stride, int h){ +static int nsse16_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; @@ -3015,7 +3016,8 @@ static int nsse16_c(MpegEncContext *c, uint8_t *s1, uint8_t *s2, int stride, int else return score1 + ABS(score2)*8; } -static int nsse8_c(MpegEncContext *c, uint8_t *s1, uint8_t *s2, int stride, int h){ +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; diff --git a/src/libffmpeg/libavcodec/dsputil.h b/src/libffmpeg/libavcodec/dsputil.h index a3fbb1f6f..a9b472f86 100644 --- a/src/libffmpeg/libavcodec/dsputil.h +++ b/src/libffmpeg/libavcodec/dsputil.h @@ -597,33 +597,4 @@ static int name16(void /*MpegEncContext*/ *s, uint8_t *dst, uint8_t *src, int st return score;\ } -#ifndef HAVE_LRINTF -/* XXX: add ISOC specific test to avoid specific BSD testing. */ -/* better than nothing implementation. */ -/* btw, rintf() is existing on fbsd too -- alex */ -static always_inline long int lrintf(float x) -{ -#ifdef CONFIG_WIN32 -# ifdef ARCH_X86 - int32_t i; - asm volatile( - "fistpl %0\n\t" - : "=m" (i) : "t" (x) : "st" - ); - return i; -# else - /* XXX: incorrect, but make it compile */ - return (int)(x + (x < 0 ? -0.5 : 0.5)); -# endif -#else - return (int)(rint(x)); -#endif -} -#else -#ifndef _ISOC9X_SOURCE -#define _ISOC9X_SOURCE -#endif -#include <math.h> -#endif - #endif diff --git a/src/libffmpeg/libavcodec/dv.c b/src/libffmpeg/libavcodec/dv.c index bc750bcbc..09fb77299 100644 --- a/src/libffmpeg/libavcodec/dv.c +++ b/src/libffmpeg/libavcodec/dv.c @@ -34,9 +34,13 @@ #include "simple_idct.h" #include "dvdata.h" +//#undef NDEBUG +//#include <assert.h> + typedef struct DVVideoContext { const DVprofile* sys; AVFrame picture; + AVCodecContext *avctx; uint8_t *buf; uint8_t dv_zigzag[2][64]; @@ -54,7 +58,7 @@ typedef struct DVVideoContext { #define DV_VLC_MAP_LEV_SIZE 23 #else #define DV_VLC_MAP_RUN_SIZE 64 -#define DV_VLC_MAP_LEV_SIZE 512 +#define DV_VLC_MAP_LEV_SIZE 512 //FIXME sign was removed so this should be /2 but needs check #endif /* MultiThreading */ @@ -109,14 +113,13 @@ static int dvvideo_init(AVCodecContext *avctx) done = 1; - dv_vlc_map = av_mallocz(DV_VLC_MAP_LEV_SIZE*DV_VLC_MAP_RUN_SIZE*sizeof(struct dv_vlc_pair)); + dv_vlc_map = av_mallocz_static(DV_VLC_MAP_LEV_SIZE*DV_VLC_MAP_RUN_SIZE*sizeof(struct dv_vlc_pair)); if (!dv_vlc_map) return -ENOMEM; /* dv_anchor lets each thread know its Id */ dv_anchor = av_malloc(12*27*sizeof(void*)); if (!dv_anchor) { - av_free(dv_vlc_map); return -ENOMEM; } for (i=0; i<12*27; i++) @@ -149,7 +152,6 @@ static int dvvideo_init(AVCodecContext *avctx) dv_rl_vlc = av_malloc(dv_vlc.table_size * sizeof(RL_VLC_ELEM)); if (!dv_rl_vlc) { av_free(dv_anchor); - av_free(dv_vlc_map); return -ENOMEM; } for(i = 0; i < dv_vlc.table_size; i++){ @@ -226,7 +228,13 @@ static int dvvideo_init(AVCodecContext *avctx) /* 248DCT setup */ s->fdct[1] = dsp.fdct248; s->idct_put[1] = simple_idct248_put; // FIXME: need to add it to DSP - memcpy(s->dv_zigzag[1], ff_zigzag248_direct, 64); + if(avctx->lowres){ + for (i=0; i<64; i++){ + int j= ff_zigzag248_direct[i]; + s->dv_zigzag[1][i] = dsp.idct_permutation[(j&7) + (j&8)*4 + (j&48)/2]; + } + }else + memcpy(s->dv_zigzag[1], ff_zigzag248_direct, 64); /* XXX: do it only for constant case */ dv_build_unquantize_tables(s, dsp.idct_permutation); @@ -235,6 +243,7 @@ static int dvvideo_init(AVCodecContext *avctx) if (dv_codec_profile(avctx)) avctx->pix_fmt = dv_codec_profile(avctx)->pix_fmt; avctx->coded_frame = &s->picture; + s->avctx= avctx; return 0; } @@ -334,10 +343,9 @@ static void dv_decode_ac(GetBitContext *gb, BlockInfo *mb, DCTELEM *block) if (pos >= 64) break; - if (level) { - pos1 = scan_table[pos]; - block[pos1] = level << shift_table[pos1]; - } + assert(level); + pos1 = scan_table[pos]; + block[pos1] = level << shift_table[pos1]; UPDATE_CACHE(re, gb); } @@ -348,9 +356,9 @@ static void dv_decode_ac(GetBitContext *gb, BlockInfo *mb, DCTELEM *block) static inline void bit_copy(PutBitContext *pb, GetBitContext *gb) { int bits_left = get_bits_left(gb); - while (bits_left >= 16) { - put_bits(pb, 16, get_bits(gb, 16)); - bits_left -= 16; + while (bits_left >= MIN_CACHE_BITS) { + put_bits(pb, MIN_CACHE_BITS, get_bits(gb, MIN_CACHE_BITS)); + bits_left -= MIN_CACHE_BITS; } if (bits_left > 0) { put_bits(pb, bits_left, get_bits(gb, bits_left)); @@ -373,9 +381,13 @@ static inline void dv_decode_video_segment(DVVideoContext *s, GetBitContext gb; BlockInfo mb_data[5 * 6], *mb, *mb1; DCTELEM sblock[5*6][64] __align8; - uint8_t mb_bit_buffer[80 + 4]; /* allow some slack */ - uint8_t vs_bit_buffer[5 * 80 + 4]; /* allow some slack */ + uint8_t mb_bit_buffer[80 + 4] __align8; /* allow some slack */ + uint8_t vs_bit_buffer[5 * 80 + 4] __align8; /* allow some slack */ + const int log2_blocksize= 3-s->avctx->lowres; + assert((((int)mb_bit_buffer)&7)==0); + assert((((int)vs_bit_buffer)&7)==0); + memset(sblock, 0, sizeof(sblock)); /* pass 1 : read DC and AC coefficients in blocks */ @@ -477,39 +489,38 @@ static inline void dv_decode_video_segment(DVVideoContext *s, v = *mb_pos_ptr++; mb_x = v & 0xff; mb_y = v >> 8; - y_ptr = s->picture.data[0] + (mb_y * s->picture.linesize[0] * 8) + (mb_x * 8); + y_ptr = s->picture.data[0] + ((mb_y * s->picture.linesize[0] + mb_x)<<log2_blocksize); if (s->sys->pix_fmt == PIX_FMT_YUV411P) - c_offset = (mb_y * s->picture.linesize[1] * 8) + ((mb_x >> 2) * 8); + c_offset = ((mb_y * s->picture.linesize[1] + (mb_x >> 2))<<log2_blocksize); else - c_offset = ((mb_y >> 1) * s->picture.linesize[1] * 8) + ((mb_x >> 1) * 8); + c_offset = (((mb_y >> 1) * s->picture.linesize[1] + (mb_x >> 1))<<log2_blocksize); for(j = 0;j < 6; j++) { - idct_put = s->idct_put[mb->dct_mode]; + idct_put = s->idct_put[mb->dct_mode && log2_blocksize==3]; if (j < 4) { if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x < (704 / 8)) { /* NOTE: at end of line, the macroblock is handled as 420 */ - idct_put(y_ptr + (j * 8), s->picture.linesize[0], block); + idct_put(y_ptr + (j<<log2_blocksize), s->picture.linesize[0], block); } else { - idct_put(y_ptr + ((j & 1) * 8) + ((j >> 1) * 8 * s->picture.linesize[0]), + idct_put(y_ptr + (((j & 1) + (j >> 1) * s->picture.linesize[0])<<log2_blocksize), s->picture.linesize[0], block); } } else { if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) { uint64_t aligned_pixels[64/8]; uint8_t *pixels= (uint8_t*)aligned_pixels; - uint8_t *c_ptr, *c_ptr1, *ptr; - int y, linesize; + uint8_t *c_ptr, *c_ptr1, *ptr, *ptr1; + int x, y, linesize; /* NOTE: at end of line, the macroblock is handled as 420 */ idct_put(pixels, 8, block); linesize = s->picture.linesize[6 - j]; c_ptr = s->picture.data[6 - j] + c_offset; ptr = pixels; - for(y = 0;y < 8; y++) { - /* convert to 411P */ - c_ptr1 = c_ptr + 8*linesize; - c_ptr[0]= ptr[0]; c_ptr1[0]= ptr[4]; - c_ptr[1]= ptr[1]; c_ptr1[1]= ptr[5]; - c_ptr[2]= ptr[2]; c_ptr1[2]= ptr[6]; - c_ptr[3]= ptr[3]; c_ptr1[3]= ptr[7]; + for(y = 0;y < (1<<log2_blocksize); y++) { + ptr1= ptr + (1<<(log2_blocksize-1)); + c_ptr1 = c_ptr + (linesize<<log2_blocksize); + for(x=0; x < (1<<(log2_blocksize-1)); x++){ + c_ptr[x]= ptr[x]; c_ptr1[x]= ptr1[x]; + } c_ptr += linesize; ptr += 8; } @@ -527,14 +538,9 @@ static inline void dv_decode_video_segment(DVVideoContext *s, #ifdef DV_CODEC_TINY_TARGET /* Converts run and level (where level != 0) pair into vlc, returning bit size */ -static always_inline int dv_rl2vlc(int run, int l, uint32_t* vlc) +static always_inline int dv_rl2vlc(int run, int level, int sign, uint32_t* vlc) { - int sign = l >> 8; - int level = (l ^ sign) - sign; int size; - - sign = (sign & 1); - if (run < DV_VLC_MAP_RUN_SIZE && level < DV_VLC_MAP_LEV_SIZE) { *vlc = dv_vlc_map[run][level].vlc | sign; size = dv_vlc_map[run][level].size; @@ -557,9 +563,8 @@ static always_inline int dv_rl2vlc(int run, int l, uint32_t* vlc) return size; } -static always_inline int dv_rl2vlc_size(int run, int l) +static always_inline int dv_rl2vlc_size(int run, int level) { - int level = (l ^ (l >> 8)) - (l >> 8); int size; if (run < DV_VLC_MAP_RUN_SIZE && level < DV_VLC_MAP_LEV_SIZE) { @@ -574,41 +579,43 @@ static always_inline int dv_rl2vlc_size(int run, int l) return size; } #else -static always_inline int dv_rl2vlc(int run, int l, uint32_t* vlc) +static always_inline int dv_rl2vlc(int run, int l, int sign, uint32_t* vlc) { - *vlc = dv_vlc_map[run][((uint16_t)l)&0x1ff].vlc; - return dv_vlc_map[run][((uint16_t)l)&0x1ff].size; + *vlc = dv_vlc_map[run][l].vlc | sign; + return dv_vlc_map[run][l].size; } static always_inline int dv_rl2vlc_size(int run, int l) { - return dv_vlc_map[run][((uint16_t)l)&0x1ff].size; + return dv_vlc_map[run][l].size; } #endif typedef struct EncBlockInfo { int area_q[4]; int bit_size[4]; - int prev_run[4]; + int prev[5]; int cur_ac; int cno; int dct_mode; - DCTELEM *mb; + DCTELEM mb[64]; + uint8_t next[64]; + uint8_t sign[64]; uint8_t partial_bit_count; uint32_t partial_bit_buffer; /* we can't use uint16_t here */ } EncBlockInfo; -static always_inline void dv_encode_ac(EncBlockInfo* bi, PutBitContext* pb_pool, - int pb_size) +static always_inline PutBitContext* dv_encode_ac(EncBlockInfo* bi, PutBitContext* pb_pool, + PutBitContext* pb_end) { - int run; + int prev; int bits_left; PutBitContext* pb = pb_pool; int size = bi->partial_bit_count; uint32_t vlc = bi->partial_bit_buffer; - + bi->partial_bit_count = bi->partial_bit_buffer = 0; -vlc_loop: + for(;;){ /* Find suitable storage space */ for (; size > (bits_left = put_bits_left(pb)); pb++) { if (bits_left) { @@ -616,69 +623,84 @@ vlc_loop: put_bits(pb, bits_left, vlc >> size); vlc = vlc & ((1<<size)-1); } - if (pb_size == 1) { + if (pb + 1 >= pb_end) { bi->partial_bit_count = size; bi->partial_bit_buffer = vlc; - return; + return pb; } - --pb_size; } /* Store VLC */ put_bits(pb, size, vlc); + if(bi->cur_ac>=64) + break; + /* Construct the next VLC */ - run = 0; - for (; bi->cur_ac < 64; bi->cur_ac++, run++) { - if (bi->mb[bi->cur_ac]) { - size = dv_rl2vlc(run, bi->mb[bi->cur_ac], &vlc); - bi->cur_ac++; - goto vlc_loop; - } - } - - if (bi->cur_ac == 64) { + prev= bi->cur_ac; + bi->cur_ac = bi->next[prev]; + if(bi->cur_ac < 64){ + size = dv_rl2vlc(bi->cur_ac - prev - 1, bi->mb[bi->cur_ac], bi->sign[bi->cur_ac], &vlc); + } else { size = 4; vlc = 6; /* End Of Block stamp */ - bi->cur_ac++; - goto vlc_loop; } + } + return pb; } static always_inline void dv_set_class_number(DCTELEM* blk, EncBlockInfo* bi, const uint8_t* zigzag_scan, int bias) { int i, area; - int run; - int classes[] = {12, 24, 36, 0xffff}; + static const int classes[] = {12, 24, 36, 0xffff}; + int max=12; + int prev=0; - run = 0; bi->mb[0] = blk[0]; - bi->cno = 0; + for (area = 0; area < 4; area++) { - bi->prev_run[area] = run; - bi->bit_size[area] = 0; + bi->prev[area] = prev; + bi->bit_size[area] = 1; // 4 areas 4 bits for EOB :) for (i=mb_area_start[area]; i<mb_area_start[area+1]; i++) { - bi->mb[i] = (blk[zigzag_scan[i]] / 16); - while ((bi->mb[i] ^ (bi->mb[i] >> 8)) > classes[bi->cno]) - bi->cno++; + int level = blk[zigzag_scan[i]]; - if (bi->mb[i]) { - bi->bit_size[area] += dv_rl2vlc_size(run, bi->mb[i]); - run = 0; - } else - ++run; + if (level+15 > 30U) { + bi->sign[i] = (level>>31)&1; + bi->mb[i] = level= ABS(level)>>4; + if(level>max) max= level; + bi->bit_size[area] += dv_rl2vlc_size(i - prev - 1, level); + bi->next[prev]= i; + prev= i; + } } } - bi->bit_size[3] += 4; /* EOB marker */ + bi->next[prev]= i; + for(bi->cno = 0; max > classes[bi->cno]; bi->cno++); + bi->cno += bias; - if (bi->cno >= 3) { /* FIXME: we have to recreate bit_size[], prev_run[] */ + if (bi->cno >= 3) { bi->cno = 3; - for (i=1; i<64; i++) - bi->mb[i] /= 2; + prev=0; + i= bi->next[prev]; + for (area = 0; area < 4; area++) { + bi->prev[area] = prev; + bi->bit_size[area] = 1; // 4 areas 4 bits for EOB :) + for (; i<mb_area_start[area+1]; i= bi->next[i]) { + bi->mb[i] >>=1; + + if (bi->mb[i]) { + bi->bit_size[area] += dv_rl2vlc_size(i - prev - 1, bi->mb[i]); + bi->next[prev]= i; + prev= i; + } + } + } + bi->next[prev]= i; } } +//FIXME replace this by dsputil #define SC(x, y) ((s[x] - s[y]) ^ ((s[x] - s[y]) >> 7)) static always_inline int dv_guess_dct_mode(DCTELEM *blk) { DCTELEM *s; @@ -707,9 +729,9 @@ static always_inline int dv_guess_dct_mode(DCTELEM *blk) { static inline void dv_guess_qnos(EncBlockInfo* blks, int* qnos) { int size[5]; - int i, j, k, a, run; + int i, j, k, a, prev; EncBlockInfo* b; - + do { b = blks; for (i=0; i<5; i++) { @@ -721,17 +743,19 @@ static inline void dv_guess_qnos(EncBlockInfo* blks, int* qnos) for (j=0; j<6; j++, b++) { for (a=0; a<4; a++) { if (b->area_q[a] != dv_quant_shifts[qnos[i] + dv_quant_offset[b->cno]][a]) { - b->bit_size[a] = (a==3)?4:0; + b->bit_size[a] = 1; // 4 areas 4 bits for EOB :) b->area_q[a]++; - run = b->prev_run[a]; - for (k=mb_area_start[a]; k<mb_area_start[a+1]; k++) { - b->mb[k] /= 2; + prev= b->prev[a]; + for (k= b->next[prev] ; k<mb_area_start[a+1]; k= b->next[k]) { + b->mb[k] >>= 1; if (b->mb[k]) { - b->bit_size[a] += dv_rl2vlc_size(run, b->mb[k]); - run = 0; - } else - ++run; + b->bit_size[a] += dv_rl2vlc_size(k - prev - 1, b->mb[k]); + prev= k; + } else { + b->next[prev] = b->next[k]; + } } + b->prev[a+1]= prev; } size[i] += b->bit_size[a]; } @@ -757,13 +781,14 @@ static inline void dv_encode_video_segment(DVVideoContext *s, uint8_t* ptr; int do_edge_wrap; DCTELEM block[64] __align8; - DCTELEM sblock[5*6][64] __align8; EncBlockInfo enc_blks[5*6]; PutBitContext pbs[5*6]; PutBitContext* pb; EncBlockInfo* enc_blk; int vs_bit_size = 0; int qnos[5]; + + assert((((int)block) & 7) == 0); enc_blk = &enc_blks[0]; pb = &pbs[0]; @@ -810,21 +835,22 @@ static inline void dv_encode_video_segment(DVVideoContext *s, s->get_pixels(block, data, linesize); } - enc_blk->dct_mode = dv_guess_dct_mode(block); - enc_blk->mb = &sblock[mb_index*6+j][0]; + if(s->avctx->flags & CODEC_FLAG_INTERLACED_DCT) + enc_blk->dct_mode = dv_guess_dct_mode(block); + else + enc_blk->dct_mode = 0; enc_blk->area_q[0] = enc_blk->area_q[1] = enc_blk->area_q[2] = enc_blk->area_q[3] = 0; enc_blk->partial_bit_count = 0; enc_blk->partial_bit_buffer = 0; - enc_blk->cur_ac = 1; + enc_blk->cur_ac = 0; s->fdct[enc_blk->dct_mode](block); dv_set_class_number(block, enc_blk, - enc_blk->dct_mode ? ff_zigzag248_direct : ff_zigzag_direct, - j/4*(j%2)); + enc_blk->dct_mode ? ff_zigzag248_direct : ff_zigzag_direct, j/4); init_put_bits(pb, ptr, block_sizes[j]/8); - put_bits(pb, 9, (uint16_t)(((enc_blk->mb[0] >> 3) - 1024) >> 2)); + put_bits(pb, 9, (uint16_t)(((enc_blk->mb[0] >> 3) - 1024 + 2) >> 2)); put_bits(pb, 1, enc_blk->dct_mode); put_bits(pb, 2, enc_blk->cno); @@ -845,18 +871,22 @@ static inline void dv_encode_video_segment(DVVideoContext *s, /* First pass over individual cells only */ for (j=0; j<5*6; j++) - dv_encode_ac(&enc_blks[j], &pbs[j], 1); + dv_encode_ac(&enc_blks[j], &pbs[j], &pbs[j+1]); /* Second pass over each MB space */ - for (j=0; j<5*6; j++) { - if (enc_blks[j].cur_ac < 65 || enc_blks[j].partial_bit_count) - dv_encode_ac(&enc_blks[j], &pbs[(j/6)*6], 6); + for (j=0; j<5*6; j+=6) { + pb= &pbs[j]; + for (i=0; i<6; i++) { + if (enc_blks[i+j].partial_bit_count) + pb=dv_encode_ac(&enc_blks[i+j], pb, &pbs[j+6]); + } } /* Third and final pass over the whole vides segment space */ + pb= &pbs[0]; for (j=0; j<5*6; j++) { - if (enc_blks[j].cur_ac < 65 || enc_blks[j].partial_bit_count) - dv_encode_ac(&enc_blks[j], &pbs[0], 6*5); + if (enc_blks[j].partial_bit_count) + pb=dv_encode_ac(&enc_blks[j], pb, &pbs[6*5]); } for (j=0; j<5*6; j++) @@ -897,9 +927,10 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, avctx->release_buffer(avctx, &s->picture); s->picture.reference = 0; + s->picture.key_frame = 1; + s->picture.pict_type = FF_I_TYPE; avctx->pix_fmt = s->sys->pix_fmt; - avctx->width = s->sys->width; - avctx->height = s->sys->height; + avcodec_set_dimensions(avctx, s->sys->width, s->sys->height); if(avctx->get_buffer(avctx, &s->picture) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; @@ -933,6 +964,8 @@ static int dvvideo_encode_frame(AVCodecContext *c, uint8_t *buf, int buf_size, c->pix_fmt = s->sys->pix_fmt; s->picture = *((AVFrame *)data); + s->picture.key_frame = 1; + s->picture.pict_type = FF_I_TYPE; s->buf = buf; c->execute(c, dv_encode_mt, (void**)&dv_anchor[0], NULL, diff --git a/src/libffmpeg/libavcodec/flac.c b/src/libffmpeg/libavcodec/flac.c index 17082e432..9be1ac0de 100644 --- a/src/libffmpeg/libavcodec/flac.c +++ b/src/libffmpeg/libavcodec/flac.c @@ -406,7 +406,7 @@ static inline int decode_subframe(FLACContext *s, int channel) if (get_bits1(&s->gb)) { - av_log(s->avctx, AV_LOG_DEBUG, "invalid subframe padding\n"); + av_log(s->avctx, AV_LOG_ERROR, "invalid subframe padding\n"); return -1; } type = get_bits(&s->gb, 6); @@ -462,7 +462,7 @@ static inline int decode_subframe(FLACContext *s, int channel) } else { - av_log(s->avctx, AV_LOG_DEBUG, "invalid coding type\n"); + av_log(s->avctx, AV_LOG_ERROR, "invalid coding type\n"); return -1; } @@ -492,7 +492,7 @@ static int decode_frame(FLACContext *s) decorrelation = LEFT_SIDE + assignment - 8; else { - av_log(s->avctx, AV_LOG_DEBUG, "unsupported channel assignment %d (channels=%d)\n", assignment, s->channels); + av_log(s->avctx, AV_LOG_ERROR, "unsupported channel assignment %d (channels=%d)\n", assignment, s->channels); return -1; } @@ -503,13 +503,13 @@ static int decode_frame(FLACContext *s) bps = sample_size_table[sample_size_code]; else { - av_log(s->avctx, AV_LOG_DEBUG, "invalid sample size code (%d)\n", sample_size_code); + av_log(s->avctx, AV_LOG_ERROR, "invalid sample size code (%d)\n", sample_size_code); return -1; } if (get_bits1(&s->gb)) { - av_log(s->avctx, AV_LOG_DEBUG, "broken stream, invalid padding\n"); + av_log(s->avctx, AV_LOG_ERROR, "broken stream, invalid padding\n"); return -1; } diff --git a/src/libffmpeg/libavcodec/flicvideo.c b/src/libffmpeg/libavcodec/flicvideo.c index 92cb8bd0b..60d1849ef 100644 --- a/src/libffmpeg/libavcodec/flicvideo.c +++ b/src/libffmpeg/libavcodec/flicvideo.c @@ -26,7 +26,8 @@ * variations, visit: * http://www.compuphase.com/flic.htm * - * This decoder outputs PAL8 colorspace data. To use this decoder, be + * This decoder outputs PAL8/RGB555/RGB565 and maybe one day RGB24 + * colorspace data, depending on the FLC. To use this decoder, be * sure that your demuxer sends the FLI file header to the decoder via * the extradata chunk in AVCodecContext. The chunk should be 128 bytes * large. The only exception is for FLI files from the game "Magic Carpet", @@ -50,6 +51,21 @@ #define FLI_BRUN 15 #define FLI_COPY 16 #define FLI_MINI 18 +#define FLI_DTA_BRUN 25 +#define FLI_DTA_COPY 26 +#define FLI_DTA_LC 27 + +#define FLI_TYPE_CODE (0xAF11) +#define FLC_FLX_TYPE_CODE (0xAF12) +#define FLC_DTA_TYPE_CODE (0xAF44) /* Marks an "Extended FLC" comes from Dave's Targa Animator (DTA) */ +#define FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE (0xAF13) + +#define CHECK_PIXEL_PTR(n) \ + if (pixel_ptr + n > pixel_limit) { \ + av_log (s->avctx, AV_LOG_INFO, "Problem: pixel_ptr >= pixel_limit (%d >= %d)\n", \ + pixel_ptr + n, pixel_limit); \ + return -1; \ + } \ typedef struct FlicDecodeContext { AVCodecContext *avctx; @@ -64,30 +80,52 @@ static int flic_decode_init(AVCodecContext *avctx) { FlicDecodeContext *s = (FlicDecodeContext *)avctx->priv_data; unsigned char *fli_header = (unsigned char *)avctx->extradata; + int depth; s->avctx = avctx; - avctx->pix_fmt = PIX_FMT_PAL8; avctx->has_b_frames = 0; + s->fli_type = LE_16(&fli_header[4]); /* Might be overridden if a Magic Carpet FLC */ + depth = LE_16(&fli_header[12]); + + if (depth == 0) { + depth = 8; /* Some FLC generators set depth to zero, when they mean 8Bpp. Fix up here */ + } + if (s->avctx->extradata_size == 12) { /* special case for magic carpet FLIs */ - s->fli_type = 0xAF13; - } else if (s->avctx->extradata_size == 128) { - s->fli_type = LE_16(&fli_header[4]); - } else { + s->fli_type = FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE; + } else if (s->avctx->extradata_size != 128) { av_log(avctx, AV_LOG_ERROR, "Expected extradata of 12 or 128 bytes\n"); return -1; } + if ((s->fli_type == FLC_FLX_TYPE_CODE) && (depth == 16)) { + depth = 15; /* Original Autodesk FLX's say the depth is 16Bpp when it is really 15Bpp */ + } + + switch (depth) { + case 8 : avctx->pix_fmt = PIX_FMT_PAL8; break; + case 15 : avctx->pix_fmt = PIX_FMT_RGB555; break; + case 16 : avctx->pix_fmt = PIX_FMT_RGB565; break; + case 24 : avctx->pix_fmt = PIX_FMT_BGR24; /* Supposedly BGR, but havent any files to test with */ + av_log(avctx, AV_LOG_ERROR, "24Bpp FLC/FLX is unsupported due to no test files.\n"); + return -1; + break; + default : + av_log(avctx, AV_LOG_ERROR, "Unkown FLC/FLX depth of %d Bpp is unsupported.\n",depth); + return -1; + } + s->frame.data[0] = NULL; s->new_palette = 0; return 0; } -static int flic_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - uint8_t *buf, int buf_size) +static int flic_decode_frame_8BPP(AVCodecContext *avctx, + void *data, int *data_size, + uint8_t *buf, int buf_size) { FlicDecodeContext *s = (FlicDecodeContext *)avctx->priv_data; @@ -120,7 +158,8 @@ static int flic_decode_frame(AVCodecContext *avctx, int pixel_skip; int pixel_countdown; unsigned char *pixels; - + int pixel_limit; + s->frame.reference = 1; s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; if (avctx->reget_buffer(avctx, &s->frame) < 0) { @@ -129,6 +168,7 @@ static int flic_decode_frame(AVCodecContext *avctx, } pixels = s->frame.data[0]; + pixel_limit = s->avctx->height * s->frame.linesize[0]; frame_size = LE_32(&buf[stream_ptr]); stream_ptr += 6; /* skip the magic number */ @@ -154,7 +194,7 @@ static int flic_decode_frame(AVCodecContext *avctx, * game and uses 6-bit colors even though it reports 256-color * chunks in a 0xAF12-type file (fli_type is set to 0xAF13 during * initialization) */ - if ((chunk_type == FLI_256_COLOR) && (s->fli_type != 0xAF13)) + if ((chunk_type == FLI_256_COLOR) && (s->fli_type != FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE)) color_shift = 0; else color_shift = 2; @@ -218,11 +258,13 @@ static int flic_decode_frame(AVCodecContext *avctx, byte_run = -byte_run; palette_idx1 = buf[stream_ptr++]; palette_idx2 = buf[stream_ptr++]; + CHECK_PIXEL_PTR(byte_run); for (j = 0; j < byte_run; j++, pixel_countdown -= 2) { pixels[pixel_ptr++] = palette_idx1; pixels[pixel_ptr++] = palette_idx2; } } else { + CHECK_PIXEL_PTR(byte_run * 2); for (j = 0; j < byte_run * 2; j++, pixel_countdown--) { palette_idx1 = buf[stream_ptr++]; pixels[pixel_ptr++] = palette_idx1; @@ -256,6 +298,7 @@ static int flic_decode_frame(AVCodecContext *avctx, pixel_countdown -= pixel_skip; byte_run = buf[stream_ptr++]; if (byte_run > 0) { + CHECK_PIXEL_PTR(byte_run); for (j = 0; j < byte_run; j++, pixel_countdown--) { palette_idx1 = buf[stream_ptr++]; pixels[pixel_ptr++] = palette_idx1; @@ -263,6 +306,7 @@ static int flic_decode_frame(AVCodecContext *avctx, } else { byte_run = -byte_run; palette_idx1 = buf[stream_ptr++]; + CHECK_PIXEL_PTR(byte_run); for (j = 0; j < byte_run; j++, pixel_countdown--) { pixels[pixel_ptr++] = palette_idx1; } @@ -295,6 +339,7 @@ static int flic_decode_frame(AVCodecContext *avctx, byte_run = buf[stream_ptr++]; if (byte_run > 0) { palette_idx1 = buf[stream_ptr++]; + CHECK_PIXEL_PTR(byte_run); for (j = 0; j < byte_run; j++) { pixels[pixel_ptr++] = palette_idx1; pixel_countdown--; @@ -304,6 +349,7 @@ static int flic_decode_frame(AVCodecContext *avctx, } } else { /* copy bytes if byte_run < 0 */ byte_run = -byte_run; + CHECK_PIXEL_PTR(byte_run); for (j = 0; j < byte_run; j++) { palette_idx1 = buf[stream_ptr++]; pixels[pixel_ptr++] = palette_idx1; @@ -369,6 +415,308 @@ static int flic_decode_frame(AVCodecContext *avctx, return buf_size; } +int flic_decode_frame_15_16BPP(AVCodecContext *avctx, + void *data, int *data_size, + uint8_t *buf, int buf_size) +{ + /* Note, the only difference between the 15Bpp and 16Bpp */ + /* Format is the pixel format, the packets are processed the same. */ + FlicDecodeContext *s = (FlicDecodeContext *)avctx->priv_data; + + int stream_ptr = 0; + int pixel_ptr; + unsigned char palette_idx1; + + unsigned int frame_size; + int num_chunks; + + unsigned int chunk_size; + int chunk_type; + + int i, j; + + int lines; + int compressed_lines; + signed short line_packets; + int y_ptr; + signed char byte_run; + int pixel_skip; + int pixel_countdown; + unsigned char *pixels; + int pixel; + int pixel_limit; + + s->frame.reference = 1; + s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; + if (avctx->reget_buffer(avctx, &s->frame) < 0) { + av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); + return -1; + } + + pixels = s->frame.data[0]; + pixel_limit = s->avctx->height * s->frame.linesize[0]; + + frame_size = LE_32(&buf[stream_ptr]); + stream_ptr += 6; /* skip the magic number */ + num_chunks = LE_16(&buf[stream_ptr]); + stream_ptr += 10; /* skip padding */ + + frame_size -= 16; + + /* iterate through the chunks */ + while ((frame_size > 0) && (num_chunks > 0)) { + chunk_size = LE_32(&buf[stream_ptr]); + stream_ptr += 4; + chunk_type = LE_16(&buf[stream_ptr]); + stream_ptr += 2; + + switch (chunk_type) { + case FLI_256_COLOR: + case FLI_COLOR: + /* For some reason, it seems that non-paletised flics do include one of these */ + /* chunks in their first frame. Why i do not know, it seems rather extraneous */ +/* av_log(avctx, AV_LOG_ERROR, "Unexpected Palette chunk %d in non-paletised FLC\n",chunk_type);*/ + stream_ptr = stream_ptr + chunk_size - 6; + break; + + case FLI_DELTA: + case FLI_DTA_LC: + y_ptr = 0; + compressed_lines = LE_16(&buf[stream_ptr]); + stream_ptr += 2; + while (compressed_lines > 0) { + line_packets = LE_16(&buf[stream_ptr]); + stream_ptr += 2; + if (line_packets < 0) { + line_packets = -line_packets; + y_ptr += line_packets * s->frame.linesize[0]; + } else { + compressed_lines--; + pixel_ptr = y_ptr; + pixel_countdown = s->avctx->width; + for (i = 0; i < line_packets; i++) { + /* account for the skip bytes */ + pixel_skip = buf[stream_ptr++]; + pixel_ptr += (pixel_skip*2); /* Pixel is 2 bytes wide */ + pixel_countdown -= pixel_skip; + byte_run = buf[stream_ptr++]; + if (byte_run < 0) { + byte_run = -byte_run; + pixel = LE_16(&buf[stream_ptr]); + stream_ptr += 2; + CHECK_PIXEL_PTR(byte_run); + for (j = 0; j < byte_run; j++, pixel_countdown -= 2) { + *((signed short*)(&pixels[pixel_ptr])) = pixel; + pixel_ptr += 2; + } + } else { + CHECK_PIXEL_PTR(byte_run); + for (j = 0; j < byte_run; j++, pixel_countdown--) { + *((signed short*)(&pixels[pixel_ptr])) = LE_16(&buf[stream_ptr]); + stream_ptr += 2; + pixel_ptr += 2; + } + } + } + + y_ptr += s->frame.linesize[0]; + } + } + break; + + case FLI_LC: + av_log(avctx, AV_LOG_ERROR, "Unexpected FLI_LC chunk in non-paletised FLC\n"); + stream_ptr = stream_ptr + chunk_size - 6; + break; + + case FLI_BLACK: + /* set the whole frame to 0x0000 which is balck in both 15Bpp and 16Bpp modes. */ + memset(pixels, 0x0000, + s->frame.linesize[0] * s->avctx->height * 2); + break; + + case FLI_BRUN: + y_ptr = 0; + for (lines = 0; lines < s->avctx->height; lines++) { + pixel_ptr = y_ptr; + /* disregard the line packets; instead, iterate through all + * pixels on a row */ + stream_ptr++; + pixel_countdown = (s->avctx->width * 2); + + while (pixel_countdown > 0) { + byte_run = buf[stream_ptr++]; + if (byte_run > 0) { + palette_idx1 = buf[stream_ptr++]; + CHECK_PIXEL_PTR(byte_run); + for (j = 0; j < byte_run; j++) { + pixels[pixel_ptr++] = palette_idx1; + pixel_countdown--; + if (pixel_countdown < 0) + av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n", + pixel_countdown); + } + } else { /* copy bytes if byte_run < 0 */ + byte_run = -byte_run; + CHECK_PIXEL_PTR(byte_run); + for (j = 0; j < byte_run; j++) { + palette_idx1 = buf[stream_ptr++]; + pixels[pixel_ptr++] = palette_idx1; + pixel_countdown--; + if (pixel_countdown < 0) + av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n", + pixel_countdown); + } + } + } + + /* Now FLX is strange, in that it is "byte" as opposed to "pixel" run length compressed. + * This doesnt give us any good oportunity to perform word endian conversion + * during decompression. So if its requried (ie, this isnt a LE target, we do + * a second pass over the line here, swapping the bytes. + */ + pixel = 0xFF00; + if (0xFF00 != LE_16(&pixel)) /* Check if its not an LE Target */ + { + pixel_ptr = y_ptr; + pixel_countdown = s->avctx->width; + while (pixel_countdown > 0) { + *((signed short*)(&pixels[pixel_ptr])) = LE_16(&buf[pixel_ptr]); + pixel_ptr += 2; + } + } + y_ptr += s->frame.linesize[0]; + } + break; + + case FLI_DTA_BRUN: + y_ptr = 0; + for (lines = 0; lines < s->avctx->height; lines++) { + pixel_ptr = y_ptr; + /* disregard the line packets; instead, iterate through all + * pixels on a row */ + stream_ptr++; + pixel_countdown = s->avctx->width; /* Width is in pixels, not bytes */ + + while (pixel_countdown > 0) { + byte_run = buf[stream_ptr++]; + if (byte_run > 0) { + pixel = LE_16(&buf[stream_ptr]); + stream_ptr += 2; + CHECK_PIXEL_PTR(byte_run); + for (j = 0; j < byte_run; j++) { + *((signed short*)(&pixels[pixel_ptr])) = pixel; + pixel_ptr += 2; + pixel_countdown--; + if (pixel_countdown < 0) + av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n", + pixel_countdown); + } + } else { /* copy pixels if byte_run < 0 */ + byte_run = -byte_run; + CHECK_PIXEL_PTR(byte_run); + for (j = 0; j < byte_run; j++) { + *((signed short*)(&pixels[pixel_ptr])) = LE_16(&buf[stream_ptr]); + stream_ptr += 2; + pixel_ptr += 2; + pixel_countdown--; + if (pixel_countdown < 0) + av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n", + pixel_countdown); + } + } + } + + y_ptr += s->frame.linesize[0]; + } + break; + + case FLI_COPY: + case FLI_DTA_COPY: + /* copy the chunk (uncompressed frame) */ + if (chunk_size - 6 > (unsigned int)(s->avctx->width * s->avctx->height)*2) { + av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \ + "bigger than image, skipping chunk\n", chunk_size - 6); + stream_ptr += chunk_size - 6; + } else { + + for (y_ptr = 0; y_ptr < s->frame.linesize[0] * s->avctx->height; + y_ptr += s->frame.linesize[0]) { + + pixel_countdown = s->avctx->width; + pixel_ptr = 0; + while (pixel_countdown > 0) { + *((signed short*)(&pixels[y_ptr + pixel_ptr])) = LE_16(&buf[stream_ptr+pixel_ptr]); + pixel_ptr += 2; + pixel_countdown--; + } + stream_ptr += s->avctx->width*2; + } + } + break; + + case FLI_MINI: + /* some sort of a thumbnail? disregard this chunk... */ + stream_ptr += chunk_size - 6; + break; + + default: + av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type); + break; + } + + frame_size -= chunk_size; + num_chunks--; + } + + /* by the end of the chunk, the stream ptr should equal the frame + * size (minus 1, possibly); if it doesn't, issue a warning */ + if ((stream_ptr != buf_size) && (stream_ptr != buf_size - 1)) + av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \ + "and final chunk ptr = %d\n", buf_size, stream_ptr); + + + *data_size=sizeof(AVFrame); + *(AVFrame*)data = s->frame; + + return buf_size; +} + +static int flic_decode_frame_24BPP(AVCodecContext *avctx, + void *data, int *data_size, + uint8_t *buf, int buf_size) +{ + av_log(avctx, AV_LOG_ERROR, "24Bpp FLC Unsupported due to lack of test files.\n"); + return -1; +} + +static int flic_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + uint8_t *buf, int buf_size) +{ + if (avctx->pix_fmt == PIX_FMT_PAL8) { + return flic_decode_frame_8BPP(avctx, data, data_size, + buf, buf_size); + } + else if ((avctx->pix_fmt == PIX_FMT_RGB555) || + (avctx->pix_fmt == PIX_FMT_RGB565)) { + return flic_decode_frame_15_16BPP(avctx, data, data_size, + buf, buf_size); + } + else if (avctx->pix_fmt == PIX_FMT_BGR24) { + return flic_decode_frame_24BPP(avctx, data, data_size, + buf, buf_size); + } + + /* Shouldnt get here, ever as the pix_fmt is processed */ + /* in flic_decode_init and the above if should deal with */ + /* the finite set of possibilites allowable by here. */ + /* but in case we do, just error out. */ + av_log(avctx, AV_LOG_ERROR, "Unknown Format of FLC. My Science cant explain how this happened\n"); + return -1; +} + + static int flic_decode_end(AVCodecContext *avctx) { FlicDecodeContext *s = avctx->priv_data; @@ -389,5 +737,8 @@ AVCodec flic_decoder = { flic_decode_end, flic_decode_frame, CODEC_CAP_DR1, + NULL, + NULL, + NULL, NULL }; diff --git a/src/libffmpeg/libavcodec/golomb.h b/src/libffmpeg/libavcodec/golomb.h index 1204a52e2..4ac74639a 100644 --- a/src/libffmpeg/libavcodec/golomb.h +++ b/src/libffmpeg/libavcodec/golomb.h @@ -391,9 +391,11 @@ static inline void set_te_golomb(PutBitContext *pb, int i, int range){ } /** - * write signed exp golomb code. + * write signed exp golomb code. 16 bits at most. */ static inline void set_se_golomb(PutBitContext *pb, int i){ +// if (i>32767 || i<-32767) +// av_log(NULL,AV_LOG_ERROR,"value out of range %d\n", i); #if 0 if(i<=0) i= -2*i; else i= 2*i-1; diff --git a/src/libffmpeg/libavcodec/h263.c b/src/libffmpeg/libavcodec/h263.c index 415369ee0..8d15461f6 100644 --- a/src/libffmpeg/libavcodec/h263.c +++ b/src/libffmpeg/libavcodec/h263.c @@ -57,12 +57,18 @@ static void h263_encode_block(MpegEncContext * s, DCTELEM * block, int n); static void h263p_encode_umotion(MpegEncContext * s, int val); +static inline void mpeg4_encode_block(MpegEncContext * s, DCTELEM * block, + int n, int dc, uint8_t *scan_table, + PutBitContext *dc_pb, PutBitContext *ac_pb); #endif static int h263_decode_motion(MpegEncContext * s, int pred, int fcode); static int h263p_decode_umotion(MpegEncContext * s, int pred); static int h263_decode_block(MpegEncContext * s, DCTELEM * block, int n, int coded); +static inline int mpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr); +static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block, + int n, int coded, int intra, int rvlc); static int mpeg4_get_block_length(MpegEncContext * s, DCTELEM * block, int n, int intra_dc, uint8_t *scan_table); static int h263_pred_dc(MpegEncContext * s, int n, uint16_t **dc_val_ptr); @@ -71,6 +77,7 @@ static void mpeg4_encode_visual_object_header(MpegEncContext * s); static void mpeg4_encode_vol_header(MpegEncContext * s, int vo_number, int vol_number); #endif //CONFIG_ENCODERS static void mpeg4_decode_sprite_trajectory(MpegEncContext * s, GetBitContext *gb); +static inline int ff_mpeg4_pred_dc(MpegEncContext * s, int n, int level, int *dir_ptr, int encoding); #ifdef CONFIG_ENCODERS static uint8_t uni_DCtab_lum_len[512]; @@ -657,85 +664,6 @@ void ff_h263_update_motion_val(MpegEncContext * s){ } } -/** - * predicts the dc. - * encoding quantized level -> quantized diff - * decoding quantized diff -> quantized level - * @param n block index (0-3 are luma, 4-5 are chroma) - * @param dir_ptr pointer to an integer where the prediction direction will be stored - */ -static inline int ff_mpeg4_pred_dc(MpegEncContext * s, int n, int level, int *dir_ptr, int encoding) -{ - int a, b, c, wrap, pred, scale, ret; - uint16_t *dc_val; - - /* find prediction */ - if (n < 4) { - scale = s->y_dc_scale; - } else { - scale = s->c_dc_scale; - } - if(IS_3IV1) - scale= 8; - - wrap= s->block_wrap[n]; - dc_val = s->dc_val[0] + s->block_index[n]; - - /* B C - * A X - */ - a = dc_val[ - 1]; - b = dc_val[ - 1 - wrap]; - c = dc_val[ - wrap]; - - /* outside slice handling (we can't do that by memset as we need the dc for error resilience) */ - if(s->first_slice_line && n!=3){ - if(n!=2) b=c= 1024; - if(n!=1 && s->mb_x == s->resync_mb_x) b=a= 1024; - } - if(s->mb_x == s->resync_mb_x && s->mb_y == s->resync_mb_y+1){ - if(n==0 || n==4 || n==5) - b=1024; - } - - if (abs(a - b) < abs(b - c)) { - pred = c; - *dir_ptr = 1; /* top */ - } else { - pred = a; - *dir_ptr = 0; /* left */ - } - /* we assume pred is positive */ - pred = FASTDIV((pred + (scale >> 1)), scale); - - if(encoding){ - ret = level - pred; - }else{ - level += pred; - ret= level; - if(s->error_resilience>=3){ - if(level<0){ - av_log(s->avctx, AV_LOG_ERROR, "dc<0 at %dx%d\n", s->mb_x, s->mb_y); - return -1; - } - if(level*scale > 2048 + scale){ - av_log(s->avctx, AV_LOG_ERROR, "dc overflow at %dx%d\n", s->mb_x, s->mb_y); - return -1; - } - } - } - level *=scale; - if(level&(~2047)){ - if(level<0) - level=0; - else if(!(s->workaround_bugs&FF_BUG_DC_CLIP)) - level=2047; - } - dc_val[0]= level; - - return ret; -} - #ifdef CONFIG_ENCODERS static inline int h263_get_motion_length(MpegEncContext * s, int val, int f_code){ @@ -865,179 +793,6 @@ static inline int get_b_cbp(MpegEncContext * s, DCTELEM block[6][64], return cbp; } -/** - * encodes the dc value. - * @param n block index (0-3 are luma, 4-5 are chroma) - */ -static inline void mpeg4_encode_dc(PutBitContext * s, int level, int n) -{ -#if 1 -// if(level<-255 || level>255) printf("dc overflow\n"); - level+=256; - if (n < 4) { - /* luminance */ - put_bits(s, uni_DCtab_lum_len[level], uni_DCtab_lum_bits[level]); - } else { - /* chrominance */ - put_bits(s, uni_DCtab_chrom_len[level], uni_DCtab_chrom_bits[level]); - } -#else - int size, v; - /* find number of bits */ - size = 0; - v = abs(level); - while (v) { - v >>= 1; - size++; - } - - if (n < 4) { - /* luminance */ - put_bits(&s->pb, DCtab_lum[size][1], DCtab_lum[size][0]); - } else { - /* chrominance */ - put_bits(&s->pb, DCtab_chrom[size][1], DCtab_chrom[size][0]); - } - - /* encode remaining bits */ - if (size > 0) { - if (level < 0) - level = (-level) ^ ((1 << size) - 1); - put_bits(&s->pb, size, level); - if (size > 8) - put_bits(&s->pb, 1, 1); - } -#endif -} - -static inline int mpeg4_get_dc_length(int level, int n){ - if (n < 4) { - return uni_DCtab_lum_len[level + 256]; - } else { - return uni_DCtab_chrom_len[level + 256]; - } -} - -/** - * encodes a 8x8 block - * @param n block index (0-3 are luma, 4-5 are chroma) - */ -static inline void mpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n, int intra_dc, - uint8_t *scan_table, PutBitContext *dc_pb, PutBitContext *ac_pb) -{ - int i, last_non_zero; -#if 0 //variables for the outcommented version - int code, sign, last; -#endif - const RLTable *rl; - uint32_t *bits_tab; - uint8_t *len_tab; - const int last_index = s->block_last_index[n]; - - if (s->mb_intra) { //Note gcc (3.2.1 at least) will optimize this away - /* mpeg4 based DC predictor */ - mpeg4_encode_dc(dc_pb, intra_dc, n); - if(last_index<1) return; - i = 1; - rl = &rl_intra; - bits_tab= uni_mpeg4_intra_rl_bits; - len_tab = uni_mpeg4_intra_rl_len; - } else { - if(last_index<0) return; - i = 0; - rl = &rl_inter; - bits_tab= uni_mpeg4_inter_rl_bits; - len_tab = uni_mpeg4_inter_rl_len; - } - - /* AC coefs */ - last_non_zero = i - 1; -#if 1 - for (; i < last_index; i++) { - int level = block[ scan_table[i] ]; - if (level) { - int run = i - last_non_zero - 1; - level+=64; - if((level&(~127)) == 0){ - const int index= UNI_MPEG4_ENC_INDEX(0, run, level); - put_bits(ac_pb, len_tab[index], bits_tab[index]); - }else{ //ESC3 - put_bits(ac_pb, 7+2+1+6+1+12+1, (3<<23)+(3<<21)+(0<<20)+(run<<14)+(1<<13)+(((level-64)&0xfff)<<1)+1); - } - last_non_zero = i; - } - } - /*if(i<=last_index)*/{ - int level = block[ scan_table[i] ]; - int run = i - last_non_zero - 1; - level+=64; - if((level&(~127)) == 0){ - const int index= UNI_MPEG4_ENC_INDEX(1, run, level); - put_bits(ac_pb, len_tab[index], bits_tab[index]); - }else{ //ESC3 - put_bits(ac_pb, 7+2+1+6+1+12+1, (3<<23)+(3<<21)+(1<<20)+(run<<14)+(1<<13)+(((level-64)&0xfff)<<1)+1); - } - } -#else - for (; i <= last_index; i++) { - const int slevel = block[ scan_table[i] ]; - if (slevel) { - int level; - int run = i - last_non_zero - 1; - last = (i == last_index); - sign = 0; - level = slevel; - if (level < 0) { - sign = 1; - level = -level; - } - code = get_rl_index(rl, last, run, level); - put_bits(ac_pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); - if (code == rl->n) { - int level1, run1; - level1 = level - rl->max_level[last][run]; - if (level1 < 1) - goto esc2; - code = get_rl_index(rl, last, run, level1); - if (code == rl->n) { - esc2: - put_bits(ac_pb, 1, 1); - if (level > MAX_LEVEL) - goto esc3; - run1 = run - rl->max_run[last][level] - 1; - if (run1 < 0) - goto esc3; - code = get_rl_index(rl, last, run1, level); - if (code == rl->n) { - esc3: - /* third escape */ - put_bits(ac_pb, 1, 1); - put_bits(ac_pb, 1, last); - put_bits(ac_pb, 6, run); - put_bits(ac_pb, 1, 1); - put_bits(ac_pb, 12, slevel & 0xfff); - put_bits(ac_pb, 1, 1); - } else { - /* second escape */ - put_bits(ac_pb, 1, 0); - put_bits(ac_pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); - put_bits(ac_pb, 1, sign); - } - } else { - /* first escape */ - put_bits(ac_pb, 1, 0); - put_bits(ac_pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); - put_bits(ac_pb, 1, sign); - } - } else { - put_bits(ac_pb, 1, sign); - } - last_non_zero = i; - } - } -#endif -} - static inline void mpeg4_encode_blocks(MpegEncContext * s, DCTELEM block[6][64], int intra_dc[6], uint8_t **scan_table, PutBitContext *dc_pb, PutBitContext *ac_pb){ int i; @@ -2641,7 +2396,7 @@ static void mpeg4_encode_vol_header(MpegEncContext * s, int vo_number, int vol_n if(!(s->flags & CODEC_FLAG_BITEXACT)){ put_bits(&s->pb, 16, 0); put_bits(&s->pb, 16, 0x1B2); /* user_data */ - put_string(&s->pb, LIBAVCODEC_IDENT, 0); + ff_put_string(&s->pb, LIBAVCODEC_IDENT, 0); } } @@ -2724,6 +2479,85 @@ void ff_set_qscale(MpegEncContext * s, int qscale) } /** + * predicts the dc. + * encoding quantized level -> quantized diff + * decoding quantized diff -> quantized level + * @param n block index (0-3 are luma, 4-5 are chroma) + * @param dir_ptr pointer to an integer where the prediction direction will be stored + */ +static inline int ff_mpeg4_pred_dc(MpegEncContext * s, int n, int level, int *dir_ptr, int encoding) +{ + int a, b, c, wrap, pred, scale, ret; + uint16_t *dc_val; + + /* find prediction */ + if (n < 4) { + scale = s->y_dc_scale; + } else { + scale = s->c_dc_scale; + } + if(IS_3IV1) + scale= 8; + + wrap= s->block_wrap[n]; + dc_val = s->dc_val[0] + s->block_index[n]; + + /* B C + * A X + */ + a = dc_val[ - 1]; + b = dc_val[ - 1 - wrap]; + c = dc_val[ - wrap]; + + /* outside slice handling (we can't do that by memset as we need the dc for error resilience) */ + if(s->first_slice_line && n!=3){ + if(n!=2) b=c= 1024; + if(n!=1 && s->mb_x == s->resync_mb_x) b=a= 1024; + } + if(s->mb_x == s->resync_mb_x && s->mb_y == s->resync_mb_y+1){ + if(n==0 || n==4 || n==5) + b=1024; + } + + if (abs(a - b) < abs(b - c)) { + pred = c; + *dir_ptr = 1; /* top */ + } else { + pred = a; + *dir_ptr = 0; /* left */ + } + /* we assume pred is positive */ + pred = FASTDIV((pred + (scale >> 1)), scale); + + if(encoding){ + ret = level - pred; + }else{ + level += pred; + ret= level; + if(s->error_resilience>=3){ + if(level<0){ + av_log(s->avctx, AV_LOG_ERROR, "dc<0 at %dx%d\n", s->mb_x, s->mb_y); + return -1; + } + if(level*scale > 2048 + scale){ + av_log(s->avctx, AV_LOG_ERROR, "dc overflow at %dx%d\n", s->mb_x, s->mb_y); + return -1; + } + } + } + level *=scale; + if(level&(~2047)){ + if(level<0) + level=0; + else if(!(s->workaround_bugs&FF_BUG_DC_CLIP)) + level=2047; + } + dc_val[0]= level; + + return ret; +} + +/** * predicts the ac. * @param n block index (0-3 are luma, 4-5 are chroma) * @param dir the ac prediction direction @@ -2785,6 +2619,179 @@ void mpeg4_pred_ac(MpegEncContext * s, DCTELEM *block, int n, #ifdef CONFIG_ENCODERS +/** + * encodes the dc value. + * @param n block index (0-3 are luma, 4-5 are chroma) + */ +static inline void mpeg4_encode_dc(PutBitContext * s, int level, int n) +{ +#if 1 +// if(level<-255 || level>255) printf("dc overflow\n"); + level+=256; + if (n < 4) { + /* luminance */ + put_bits(s, uni_DCtab_lum_len[level], uni_DCtab_lum_bits[level]); + } else { + /* chrominance */ + put_bits(s, uni_DCtab_chrom_len[level], uni_DCtab_chrom_bits[level]); + } +#else + int size, v; + /* find number of bits */ + size = 0; + v = abs(level); + while (v) { + v >>= 1; + size++; + } + + if (n < 4) { + /* luminance */ + put_bits(&s->pb, DCtab_lum[size][1], DCtab_lum[size][0]); + } else { + /* chrominance */ + put_bits(&s->pb, DCtab_chrom[size][1], DCtab_chrom[size][0]); + } + + /* encode remaining bits */ + if (size > 0) { + if (level < 0) + level = (-level) ^ ((1 << size) - 1); + put_bits(&s->pb, size, level); + if (size > 8) + put_bits(&s->pb, 1, 1); + } +#endif +} + +static inline int mpeg4_get_dc_length(int level, int n){ + if (n < 4) { + return uni_DCtab_lum_len[level + 256]; + } else { + return uni_DCtab_chrom_len[level + 256]; + } +} + +/** + * encodes a 8x8 block + * @param n block index (0-3 are luma, 4-5 are chroma) + */ +static inline void mpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n, int intra_dc, + uint8_t *scan_table, PutBitContext *dc_pb, PutBitContext *ac_pb) +{ + int i, last_non_zero; +#if 0 //variables for the outcommented version + int code, sign, last; +#endif + const RLTable *rl; + uint32_t *bits_tab; + uint8_t *len_tab; + const int last_index = s->block_last_index[n]; + + if (s->mb_intra) { //Note gcc (3.2.1 at least) will optimize this away + /* mpeg4 based DC predictor */ + mpeg4_encode_dc(dc_pb, intra_dc, n); + if(last_index<1) return; + i = 1; + rl = &rl_intra; + bits_tab= uni_mpeg4_intra_rl_bits; + len_tab = uni_mpeg4_intra_rl_len; + } else { + if(last_index<0) return; + i = 0; + rl = &rl_inter; + bits_tab= uni_mpeg4_inter_rl_bits; + len_tab = uni_mpeg4_inter_rl_len; + } + + /* AC coefs */ + last_non_zero = i - 1; +#if 1 + for (; i < last_index; i++) { + int level = block[ scan_table[i] ]; + if (level) { + int run = i - last_non_zero - 1; + level+=64; + if((level&(~127)) == 0){ + const int index= UNI_MPEG4_ENC_INDEX(0, run, level); + put_bits(ac_pb, len_tab[index], bits_tab[index]); + }else{ //ESC3 + put_bits(ac_pb, 7+2+1+6+1+12+1, (3<<23)+(3<<21)+(0<<20)+(run<<14)+(1<<13)+(((level-64)&0xfff)<<1)+1); + } + last_non_zero = i; + } + } + /*if(i<=last_index)*/{ + int level = block[ scan_table[i] ]; + int run = i - last_non_zero - 1; + level+=64; + if((level&(~127)) == 0){ + const int index= UNI_MPEG4_ENC_INDEX(1, run, level); + put_bits(ac_pb, len_tab[index], bits_tab[index]); + }else{ //ESC3 + put_bits(ac_pb, 7+2+1+6+1+12+1, (3<<23)+(3<<21)+(1<<20)+(run<<14)+(1<<13)+(((level-64)&0xfff)<<1)+1); + } + } +#else + for (; i <= last_index; i++) { + const int slevel = block[ scan_table[i] ]; + if (slevel) { + int level; + int run = i - last_non_zero - 1; + last = (i == last_index); + sign = 0; + level = slevel; + if (level < 0) { + sign = 1; + level = -level; + } + code = get_rl_index(rl, last, run, level); + put_bits(ac_pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); + if (code == rl->n) { + int level1, run1; + level1 = level - rl->max_level[last][run]; + if (level1 < 1) + goto esc2; + code = get_rl_index(rl, last, run, level1); + if (code == rl->n) { + esc2: + put_bits(ac_pb, 1, 1); + if (level > MAX_LEVEL) + goto esc3; + run1 = run - rl->max_run[last][level] - 1; + if (run1 < 0) + goto esc3; + code = get_rl_index(rl, last, run1, level); + if (code == rl->n) { + esc3: + /* third escape */ + put_bits(ac_pb, 1, 1); + put_bits(ac_pb, 1, last); + put_bits(ac_pb, 6, run); + put_bits(ac_pb, 1, 1); + put_bits(ac_pb, 12, slevel & 0xfff); + put_bits(ac_pb, 1, 1); + } else { + /* second escape */ + put_bits(ac_pb, 1, 0); + put_bits(ac_pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); + put_bits(ac_pb, 1, sign); + } + } else { + /* first escape */ + put_bits(ac_pb, 1, 0); + put_bits(ac_pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); + put_bits(ac_pb, 1, sign); + } + } else { + put_bits(ac_pb, 1, sign); + } + last_non_zero = i; + } + } +#endif +} + static int mpeg4_get_block_length(MpegEncContext * s, DCTELEM * block, int n, int intra_dc, uint8_t *scan_table) { @@ -3386,53 +3393,6 @@ static inline int get_amv(MpegEncContext *s, int n){ } /** - * decodes the dc value. - * @param n block index (0-3 are luma, 4-5 are chroma) - * @param dir_ptr the prediction direction will be stored here - * @return the quantized dc - */ -static inline int mpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr) -{ - int level, code; - - if (n < 4) - code = get_vlc2(&s->gb, dc_lum.table, DC_VLC_BITS, 1); - else - code = get_vlc2(&s->gb, dc_chrom.table, DC_VLC_BITS, 1); - if (code < 0 || code > 9 /* && s->nbit<9 */){ - av_log(s->avctx, AV_LOG_ERROR, "illegal dc vlc\n"); - return -1; - } - if (code == 0) { - level = 0; - } else { - if(IS_3IV1){ - if(code==1) - level= 2*get_bits1(&s->gb)-1; - else{ - if(get_bits1(&s->gb)) - level = get_bits(&s->gb, code-1) + (1<<(code-1)); - else - level = -get_bits(&s->gb, code-1) - (1<<(code-1)); - } - }else{ - level = get_xbits(&s->gb, code); - } - - if (code > 8){ - if(get_bits1(&s->gb)==0){ /* marker */ - if(s->error_resilience>=2){ - av_log(s->avctx, AV_LOG_ERROR, "dc marker bit missing\n"); - return -1; - } - } - } - } - - return ff_mpeg4_pred_dc(s, n, level, dir_ptr, 0); -} - -/** * decodes first partition. * @return number of MBs decoded or <0 if an error occured */ @@ -3738,261 +3698,6 @@ int ff_mpeg4_decode_partitions(MpegEncContext *s) } /** - * decodes a block. - * @return <0 if an error occured - */ -static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block, - int n, int coded, int intra, int rvlc) -{ - int level, i, last, run; - int dc_pred_dir; - RLTable * rl; - RL_VLC_ELEM * rl_vlc; - const uint8_t * scan_table; - int qmul, qadd; - - //Note intra & rvlc should be optimized away if this is inlined - - if(intra) { - if(s->qscale < s->intra_dc_threshold){ - /* DC coef */ - if(s->partitioned_frame){ - level = s->dc_val[0][ s->block_index[n] ]; - if(n<4) level= FASTDIV((level + (s->y_dc_scale>>1)), s->y_dc_scale); - else level= FASTDIV((level + (s->c_dc_scale>>1)), s->c_dc_scale); - dc_pred_dir= (s->pred_dir_table[s->mb_x + s->mb_y*s->mb_stride]<<n)&32; - }else{ - level = mpeg4_decode_dc(s, n, &dc_pred_dir); - if (level < 0) - return -1; - } - block[0] = level; - i = 0; - }else{ - i = -1; - } - if (!coded) - goto not_coded; - - if(rvlc){ - rl = &rvlc_rl_intra; - rl_vlc = rvlc_rl_intra.rl_vlc[0]; - }else{ - rl = &rl_intra; - rl_vlc = rl_intra.rl_vlc[0]; - } - if (s->ac_pred) { - if (dc_pred_dir == 0) - scan_table = s->intra_v_scantable.permutated; /* left */ - else - scan_table = s->intra_h_scantable.permutated; /* top */ - } else { - scan_table = s->intra_scantable.permutated; - } - qmul=1; - qadd=0; - } else { - i = -1; - if (!coded) { - s->block_last_index[n] = i; - return 0; - } - if(rvlc) rl = &rvlc_rl_inter; - else rl = &rl_inter; - - scan_table = s->intra_scantable.permutated; - - if(s->mpeg_quant){ - qmul=1; - qadd=0; - if(rvlc){ - rl_vlc = rvlc_rl_inter.rl_vlc[0]; - }else{ - rl_vlc = rl_inter.rl_vlc[0]; - } - }else{ - qmul = s->qscale << 1; - qadd = (s->qscale - 1) | 1; - if(rvlc){ - rl_vlc = rvlc_rl_inter.rl_vlc[s->qscale]; - }else{ - rl_vlc = rl_inter.rl_vlc[s->qscale]; - } - } - } - { - OPEN_READER(re, &s->gb); - for(;;) { - UPDATE_CACHE(re, &s->gb); - GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 0); - if (level==0) { - /* escape */ - if(rvlc){ - if(SHOW_UBITS(re, &s->gb, 1)==0){ - av_log(s->avctx, AV_LOG_ERROR, "1. marker bit missing in rvlc esc\n"); - return -1; - }; SKIP_CACHE(re, &s->gb, 1); - - last= SHOW_UBITS(re, &s->gb, 1); SKIP_CACHE(re, &s->gb, 1); - run= SHOW_UBITS(re, &s->gb, 6); LAST_SKIP_CACHE(re, &s->gb, 6); - SKIP_COUNTER(re, &s->gb, 1+1+6); - UPDATE_CACHE(re, &s->gb); - - if(SHOW_UBITS(re, &s->gb, 1)==0){ - av_log(s->avctx, AV_LOG_ERROR, "2. marker bit missing in rvlc esc\n"); - return -1; - }; SKIP_CACHE(re, &s->gb, 1); - - level= SHOW_UBITS(re, &s->gb, 11); SKIP_CACHE(re, &s->gb, 11); - - if(SHOW_UBITS(re, &s->gb, 5)!=0x10){ - av_log(s->avctx, AV_LOG_ERROR, "reverse esc missing\n"); - return -1; - }; SKIP_CACHE(re, &s->gb, 5); - - level= level * qmul + qadd; - level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); LAST_SKIP_CACHE(re, &s->gb, 1); - SKIP_COUNTER(re, &s->gb, 1+11+5+1); - - i+= run + 1; - if(last) i+=192; - }else{ - int cache; - cache= GET_CACHE(re, &s->gb); - - if(IS_3IV1) - cache ^= 0xC0000000; - - if (cache&0x80000000) { - if (cache&0x40000000) { - /* third escape */ - SKIP_CACHE(re, &s->gb, 2); - last= SHOW_UBITS(re, &s->gb, 1); SKIP_CACHE(re, &s->gb, 1); - run= SHOW_UBITS(re, &s->gb, 6); LAST_SKIP_CACHE(re, &s->gb, 6); - SKIP_COUNTER(re, &s->gb, 2+1+6); - UPDATE_CACHE(re, &s->gb); - - if(IS_3IV1){ - level= SHOW_SBITS(re, &s->gb, 12); LAST_SKIP_BITS(re, &s->gb, 12); - }else{ - if(SHOW_UBITS(re, &s->gb, 1)==0){ - av_log(s->avctx, AV_LOG_ERROR, "1. marker bit missing in 3. esc\n"); - return -1; - }; SKIP_CACHE(re, &s->gb, 1); - - level= SHOW_SBITS(re, &s->gb, 12); SKIP_CACHE(re, &s->gb, 12); - - if(SHOW_UBITS(re, &s->gb, 1)==0){ - av_log(s->avctx, AV_LOG_ERROR, "2. marker bit missing in 3. esc\n"); - return -1; - }; LAST_SKIP_CACHE(re, &s->gb, 1); - - SKIP_COUNTER(re, &s->gb, 1+12+1); - } - -#if 0 - if(s->error_resilience >= FF_ER_COMPLIANT){ - const int abs_level= ABS(level); - if(abs_level<=MAX_LEVEL && run<=MAX_RUN){ - const int run1= run - rl->max_run[last][abs_level] - 1; - if(abs_level <= rl->max_level[last][run]){ - av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, vlc encoding possible\n"); - return -1; - } - if(s->error_resilience > FF_ER_COMPLIANT){ - if(abs_level <= rl->max_level[last][run]*2){ - fprintf(stderr, "illegal 3. esc, esc 1 encoding possible\n"); - return -1; - } - if(run1 >= 0 && abs_level <= rl->max_level[last][run1]){ - fprintf(stderr, "illegal 3. esc, esc 2 encoding possible\n"); - return -1; - } - } - } - } -#endif - if (level>0) level= level * qmul + qadd; - else level= level * qmul - qadd; - - if((unsigned)(level + 2048) > 4095){ - if(s->error_resilience > FF_ER_COMPLIANT){ - if(level > 2560 || level<-2560){ - av_log(s->avctx, AV_LOG_ERROR, "|level| overflow in 3. esc, qp=%d\n", s->qscale); - return -1; - } - } - level= level<0 ? -2048 : 2047; - } - - i+= run + 1; - if(last) i+=192; - } else { - /* second escape */ -#if MIN_CACHE_BITS < 20 - LAST_SKIP_BITS(re, &s->gb, 2); - UPDATE_CACHE(re, &s->gb); -#else - SKIP_BITS(re, &s->gb, 2); -#endif - GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 1); - i+= run + rl->max_run[run>>7][level/qmul] +1; //FIXME opt indexing - level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); - LAST_SKIP_BITS(re, &s->gb, 1); - } - } else { - /* first escape */ -#if MIN_CACHE_BITS < 19 - LAST_SKIP_BITS(re, &s->gb, 1); - UPDATE_CACHE(re, &s->gb); -#else - SKIP_BITS(re, &s->gb, 1); -#endif - GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 1); - i+= run; - level = level + rl->max_level[run>>7][(run-1)&63] * qmul;//FIXME opt indexing - level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); - LAST_SKIP_BITS(re, &s->gb, 1); - } - } - } else { - i+= run; - level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); - LAST_SKIP_BITS(re, &s->gb, 1); - } - if (i > 62){ - i-= 192; - if(i&(~63)){ - av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y); - return -1; - } - - block[scan_table[i]] = level; - break; - } - - block[scan_table[i]] = level; - } - CLOSE_READER(re, &s->gb); - } - not_coded: - if (intra) { - if(s->qscale >= s->intra_dc_threshold){ - block[0] = ff_mpeg4_pred_dc(s, n, block[0], &dc_pred_dir, 0); - - if(i == -1) i=0; - } - - mpeg4_pred_ac(s, block, n, dc_pred_dir); - if (s->ac_pred) { - i = 63; /* XXX: not optimal */ - } - } - s->block_last_index[n] = i; - return 0; -} - -/** * decode partition C of one MB. * @return <0 if an error occured */ @@ -4835,7 +4540,7 @@ static int h263p_decode_umotion(MpegEncContext * s, int pred) code = (sign) ? (pred - code) : (pred + code); #ifdef DEBUG - fprintf(stderr,"H.263+ UMV Motion = %d\n", code); + av_log( s->avctx, AV_LOG_DEBUG,"H.263+ UMV Motion = %d\n", code); #endif return code; @@ -4971,6 +4676,308 @@ not_coded: return 0; } +/** + * decodes the dc value. + * @param n block index (0-3 are luma, 4-5 are chroma) + * @param dir_ptr the prediction direction will be stored here + * @return the quantized dc + */ +static inline int mpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr) +{ + int level, code; + + if (n < 4) + code = get_vlc2(&s->gb, dc_lum.table, DC_VLC_BITS, 1); + else + code = get_vlc2(&s->gb, dc_chrom.table, DC_VLC_BITS, 1); + if (code < 0 || code > 9 /* && s->nbit<9 */){ + av_log(s->avctx, AV_LOG_ERROR, "illegal dc vlc\n"); + return -1; + } + if (code == 0) { + level = 0; + } else { + if(IS_3IV1){ + if(code==1) + level= 2*get_bits1(&s->gb)-1; + else{ + if(get_bits1(&s->gb)) + level = get_bits(&s->gb, code-1) + (1<<(code-1)); + else + level = -get_bits(&s->gb, code-1) - (1<<(code-1)); + } + }else{ + level = get_xbits(&s->gb, code); + } + + if (code > 8){ + if(get_bits1(&s->gb)==0){ /* marker */ + if(s->error_resilience>=2){ + av_log(s->avctx, AV_LOG_ERROR, "dc marker bit missing\n"); + return -1; + } + } + } + } + + return ff_mpeg4_pred_dc(s, n, level, dir_ptr, 0); +} + +/** + * decodes a block. + * @return <0 if an error occured + */ +static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block, + int n, int coded, int intra, int rvlc) +{ + int level, i, last, run; + int dc_pred_dir; + RLTable * rl; + RL_VLC_ELEM * rl_vlc; + const uint8_t * scan_table; + int qmul, qadd; + + //Note intra & rvlc should be optimized away if this is inlined + + if(intra) { + if(s->qscale < s->intra_dc_threshold){ + /* DC coef */ + if(s->partitioned_frame){ + level = s->dc_val[0][ s->block_index[n] ]; + if(n<4) level= FASTDIV((level + (s->y_dc_scale>>1)), s->y_dc_scale); + else level= FASTDIV((level + (s->c_dc_scale>>1)), s->c_dc_scale); + dc_pred_dir= (s->pred_dir_table[s->mb_x + s->mb_y*s->mb_stride]<<n)&32; + }else{ + level = mpeg4_decode_dc(s, n, &dc_pred_dir); + if (level < 0) + return -1; + } + block[0] = level; + i = 0; + }else{ + i = -1; + } + if (!coded) + goto not_coded; + + if(rvlc){ + rl = &rvlc_rl_intra; + rl_vlc = rvlc_rl_intra.rl_vlc[0]; + }else{ + rl = &rl_intra; + rl_vlc = rl_intra.rl_vlc[0]; + } + if (s->ac_pred) { + if (dc_pred_dir == 0) + scan_table = s->intra_v_scantable.permutated; /* left */ + else + scan_table = s->intra_h_scantable.permutated; /* top */ + } else { + scan_table = s->intra_scantable.permutated; + } + qmul=1; + qadd=0; + } else { + i = -1; + if (!coded) { + s->block_last_index[n] = i; + return 0; + } + if(rvlc) rl = &rvlc_rl_inter; + else rl = &rl_inter; + + scan_table = s->intra_scantable.permutated; + + if(s->mpeg_quant){ + qmul=1; + qadd=0; + if(rvlc){ + rl_vlc = rvlc_rl_inter.rl_vlc[0]; + }else{ + rl_vlc = rl_inter.rl_vlc[0]; + } + }else{ + qmul = s->qscale << 1; + qadd = (s->qscale - 1) | 1; + if(rvlc){ + rl_vlc = rvlc_rl_inter.rl_vlc[s->qscale]; + }else{ + rl_vlc = rl_inter.rl_vlc[s->qscale]; + } + } + } + { + OPEN_READER(re, &s->gb); + for(;;) { + UPDATE_CACHE(re, &s->gb); + GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 0); + if (level==0) { + /* escape */ + if(rvlc){ + if(SHOW_UBITS(re, &s->gb, 1)==0){ + av_log(s->avctx, AV_LOG_ERROR, "1. marker bit missing in rvlc esc\n"); + return -1; + }; SKIP_CACHE(re, &s->gb, 1); + + last= SHOW_UBITS(re, &s->gb, 1); SKIP_CACHE(re, &s->gb, 1); + run= SHOW_UBITS(re, &s->gb, 6); LAST_SKIP_CACHE(re, &s->gb, 6); + SKIP_COUNTER(re, &s->gb, 1+1+6); + UPDATE_CACHE(re, &s->gb); + + if(SHOW_UBITS(re, &s->gb, 1)==0){ + av_log(s->avctx, AV_LOG_ERROR, "2. marker bit missing in rvlc esc\n"); + return -1; + }; SKIP_CACHE(re, &s->gb, 1); + + level= SHOW_UBITS(re, &s->gb, 11); SKIP_CACHE(re, &s->gb, 11); + + if(SHOW_UBITS(re, &s->gb, 5)!=0x10){ + av_log(s->avctx, AV_LOG_ERROR, "reverse esc missing\n"); + return -1; + }; SKIP_CACHE(re, &s->gb, 5); + + level= level * qmul + qadd; + level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); LAST_SKIP_CACHE(re, &s->gb, 1); + SKIP_COUNTER(re, &s->gb, 1+11+5+1); + + i+= run + 1; + if(last) i+=192; + }else{ + int cache; + cache= GET_CACHE(re, &s->gb); + + if(IS_3IV1) + cache ^= 0xC0000000; + + if (cache&0x80000000) { + if (cache&0x40000000) { + /* third escape */ + SKIP_CACHE(re, &s->gb, 2); + last= SHOW_UBITS(re, &s->gb, 1); SKIP_CACHE(re, &s->gb, 1); + run= SHOW_UBITS(re, &s->gb, 6); LAST_SKIP_CACHE(re, &s->gb, 6); + SKIP_COUNTER(re, &s->gb, 2+1+6); + UPDATE_CACHE(re, &s->gb); + + if(IS_3IV1){ + level= SHOW_SBITS(re, &s->gb, 12); LAST_SKIP_BITS(re, &s->gb, 12); + }else{ + if(SHOW_UBITS(re, &s->gb, 1)==0){ + av_log(s->avctx, AV_LOG_ERROR, "1. marker bit missing in 3. esc\n"); + return -1; + }; SKIP_CACHE(re, &s->gb, 1); + + level= SHOW_SBITS(re, &s->gb, 12); SKIP_CACHE(re, &s->gb, 12); + + if(SHOW_UBITS(re, &s->gb, 1)==0){ + av_log(s->avctx, AV_LOG_ERROR, "2. marker bit missing in 3. esc\n"); + return -1; + }; LAST_SKIP_CACHE(re, &s->gb, 1); + + SKIP_COUNTER(re, &s->gb, 1+12+1); + } + +#if 0 + if(s->error_resilience >= FF_ER_COMPLIANT){ + const int abs_level= ABS(level); + if(abs_level<=MAX_LEVEL && run<=MAX_RUN){ + const int run1= run - rl->max_run[last][abs_level] - 1; + if(abs_level <= rl->max_level[last][run]){ + av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, vlc encoding possible\n"); + return -1; + } + if(s->error_resilience > FF_ER_COMPLIANT){ + if(abs_level <= rl->max_level[last][run]*2){ + av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, esc 1 encoding possible\n"); + return -1; + } + if(run1 >= 0 && abs_level <= rl->max_level[last][run1]){ + av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, esc 2 encoding possible\n"); + return -1; + } + } + } + } +#endif + if (level>0) level= level * qmul + qadd; + else level= level * qmul - qadd; + + if((unsigned)(level + 2048) > 4095){ + if(s->error_resilience > FF_ER_COMPLIANT){ + if(level > 2560 || level<-2560){ + av_log(s->avctx, AV_LOG_ERROR, "|level| overflow in 3. esc, qp=%d\n", s->qscale); + return -1; + } + } + level= level<0 ? -2048 : 2047; + } + + i+= run + 1; + if(last) i+=192; + } else { + /* second escape */ +#if MIN_CACHE_BITS < 20 + LAST_SKIP_BITS(re, &s->gb, 2); + UPDATE_CACHE(re, &s->gb); +#else + SKIP_BITS(re, &s->gb, 2); +#endif + GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 1); + i+= run + rl->max_run[run>>7][level/qmul] +1; //FIXME opt indexing + level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); + LAST_SKIP_BITS(re, &s->gb, 1); + } + } else { + /* first escape */ +#if MIN_CACHE_BITS < 19 + LAST_SKIP_BITS(re, &s->gb, 1); + UPDATE_CACHE(re, &s->gb); +#else + SKIP_BITS(re, &s->gb, 1); +#endif + GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 1); + i+= run; + level = level + rl->max_level[run>>7][(run-1)&63] * qmul;//FIXME opt indexing + level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); + LAST_SKIP_BITS(re, &s->gb, 1); + } + } + } else { + i+= run; + level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); + LAST_SKIP_BITS(re, &s->gb, 1); + } + if (i > 62){ + i-= 192; + if(i&(~63)){ + av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y); + return -1; + } + + block[scan_table[i]] = level; + break; + } + + block[scan_table[i]] = level; + } + CLOSE_READER(re, &s->gb); + } + not_coded: + if (intra) { + if(s->qscale >= s->intra_dc_threshold){ + block[0] = ff_mpeg4_pred_dc(s, n, block[0], &dc_pred_dir, 0); + + if(i == -1) i=0; + } + + mpeg4_pred_ac(s, block, n, dc_pred_dir); + if (s->ac_pred) { + i = 63; /* XXX: not optimal */ + } + } + s->block_last_index[n] = i; + return 0; +} + /* most is hardcoded. should extend to handle all h263 streams */ int h263_decode_picture_header(MpegEncContext *s) { @@ -4996,6 +5003,7 @@ int h263_decode_picture_header(MpegEncContext *s) i = get_bits(&s->gb, 8); /* picture timestamp */ if( (s->picture_number&~0xFF)+i < s->picture_number) i+= 256; + s->current_picture_ptr->pts= s->picture_number= (s->picture_number&~0xFF) + i; /* PTYPE starts here */ @@ -5531,6 +5539,10 @@ static int decode_vol_header(MpegEncContext *s, GetBitContext *gb){ check_marker(gb, "before time_increment_resolution"); s->avctx->time_base.den = get_bits(gb, 16); + if(!s->avctx->time_base.den){ + av_log(s->avctx, AV_LOG_ERROR, "time_base.den==0\n"); + return -1; + } s->time_increment_bits = av_log2(s->avctx->time_base.den - 1) + 1; if (s->time_increment_bits < 1) @@ -5735,13 +5747,11 @@ static int decode_user_data(MpegEncContext *s, GetBitContext *gb){ int ver, build, ver2, ver3; char last; - buf[0]= show_bits(gb, 8); - for(i=1; i<256; i++){ - buf[i]= show_bits(gb, 16)&0xFF; - if(buf[i]==0) break; - skip_bits(gb, 8); + for(i=0; i<255; i++){ + if(show_bits(gb, 23) == 0) break; + buf[i]= get_bits(gb, 8); } - buf[255]=0; + buf[i]=0; /* divx detection */ e=sscanf(buf, "DivX%dBuild%d%c", &ver, &build, &last); @@ -5754,17 +5764,19 @@ static int decode_user_data(MpegEncContext *s, GetBitContext *gb){ } /* ffmpeg detection */ - e=sscanf(buf, "FFmpeg%d.%d.%db%d", &ver, &ver2, &ver3, &build); + e=sscanf(buf, "FFmpe%*[^b]b%d", &build)+3; if(e!=4) e=sscanf(buf, "FFmpeg v%d.%d.%d / libavcodec build: %d", &ver, &ver2, &ver3, &build); if(e!=4){ + e=sscanf(buf, "Lavc%d.%d.%d", &ver, &ver2, &ver3)+1; + build= (ver<<16) + (ver2<<8) + ver3; + } + if(e!=4){ if(strcmp(buf, "ffmpeg")==0){ - s->ffmpeg_version= 0x000406; s->lavc_build= 4600; } } if(e==4){ - s->ffmpeg_version= ver*256*256 + ver2*256 + ver3; s->lavc_build= build; } @@ -5793,10 +5805,6 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){ else s->decode_mb= ff_mpeg4_decode_mb; - if(s->avctx->time_base.den==0){ - s->avctx->time_base.den=1; -// fprintf(stderr, "time_increment_resolution is illegal\n"); - } time_incr=0; while (get_bits1(gb) != 0) time_incr++; @@ -5848,7 +5856,10 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){ } //av_log(s->avctx, AV_LOG_DEBUG, "last nonb %Ld last_base %d time %Ld pp %d pb %d t %d ppf %d pbf %d\n", s->last_non_b_time, s->last_time_base, s->time, s->pp_time, s->pb_time, s->t_frame, s->pp_field_time, s->pb_field_time); - s->current_picture_ptr->pts= (s->time + s->avctx->time_base.num/2) / s->avctx->time_base.num; + if(s->avctx->time_base.num) + s->current_picture_ptr->pts= (s->time + s->avctx->time_base.num/2) / s->avctx->time_base.num; + else + s->current_picture_ptr->pts= AV_NOPTS_VALUE; if(s->avctx->debug&FF_DEBUG_PTS) av_log(s->avctx, AV_LOG_DEBUG, "MPEG4 PTS: %Ld\n", s->current_picture_ptr->pts); diff --git a/src/libffmpeg/libavcodec/h263dec.c b/src/libffmpeg/libavcodec/h263dec.c index b51ce5f0c..87e11794e 100644 --- a/src/libffmpeg/libavcodec/h263dec.c +++ b/src/libffmpeg/libavcodec/h263dec.c @@ -636,9 +636,9 @@ retry: } #endif -#ifdef HAVE_MMX +#if defined(HAVE_MMX) && defined(CONFIG_GPL) if(s->codec_id == CODEC_ID_MPEG4 && s->xvid_build && avctx->idct_algo == FF_IDCT_AUTO && (mm_flags & MM_MMX) && !(s->flags&CODEC_FLAG_BITEXACT)){ - avctx->idct_algo= FF_IDCT_LIBMPEG2MMX; + avctx->idct_algo= FF_IDCT_XVIDMMX; avctx->coded_width= 0; // force reinit } #endif diff --git a/src/libffmpeg/libavcodec/h264.c b/src/libffmpeg/libavcodec/h264.c index 10baf2709..5897738ac 100644 --- a/src/libffmpeg/libavcodec/h264.c +++ b/src/libffmpeg/libavcodec/h264.c @@ -348,6 +348,8 @@ typedef struct H264Context{ uint8_t field_scan[16]; const uint8_t *zigzag_scan_q0; const uint8_t *field_scan_q0; + + int x264_build; }H264Context; static VLC coeff_token_vlc[4]; @@ -1205,6 +1207,7 @@ static inline void pred_direct_motion(H264Context * const h, int *mb_type){ const int b4_xy = 4*s->mb_x + 4*s->mb_y*h->b_stride; const int mb_type_col = h->ref_list[1][0].mb_type[mb_xy]; const int16_t (*l1mv0)[2] = (const int16_t (*)[2]) &h->ref_list[1][0].motion_val[0][b4_xy]; + const int16_t (*l1mv1)[2] = (const int16_t (*)[2]) &h->ref_list[1][0].motion_val[1][b4_xy]; const int8_t *l1ref0 = &h->ref_list[1][0].ref_index[0][b8_xy]; const int8_t *l1ref1 = &h->ref_list[1][0].ref_index[1][b8_xy]; const int is_b8x8 = IS_8X8(*mb_type); @@ -1273,8 +1276,10 @@ static inline void pred_direct_motion(H264Context * const h, int *mb_type){ if(IS_16X16(*mb_type)){ fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, ref[0], 1); fill_rectangle(&h->ref_cache[1][scan8[0]], 4, 4, 8, ref[1], 1); - if(!IS_INTRA(mb_type_col) && l1ref0[0] == 0 && - ABS(l1mv0[0][0]) <= 1 && ABS(l1mv0[0][1]) <= 1){ + if(!IS_INTRA(mb_type_col) + && ( (l1ref0[0] == 0 && ABS(l1mv0[0][0]) <= 1 && ABS(l1mv0[0][1]) <= 1) + || (l1ref0[0] < 0 && l1ref1[0] == 0 && ABS(l1mv1[0][0]) <= 1 && ABS(l1mv1[0][1]) <= 1 + && (h->x264_build>33 || !h->x264_build)))){ if(ref[0] > 0) fill_rectangle(&h->mv_cache[0][scan8[0]], 4, 4, 8, pack16to32(mv[0][0],mv[0][1]), 4); else @@ -1302,9 +1307,12 @@ static inline void pred_direct_motion(H264Context * const h, int *mb_type){ fill_rectangle(&h->ref_cache[1][scan8[i8*4]], 2, 2, 8, ref[1], 1); /* col_zero_flag */ - if(!IS_INTRA(mb_type_col) && l1ref0[x8 + y8*h->b8_stride] == 0){ + if(!IS_INTRA(mb_type_col) && ( l1ref0[x8 + y8*h->b8_stride] == 0 + || (l1ref0[x8 + y8*h->b8_stride] < 0 && l1ref1[x8 + y8*h->b8_stride] == 0 + && (h->x264_build>33 || !h->x264_build)))){ + const int16_t (*l1mv)[2]= l1ref0[x8 + y8*h->b8_stride] == 0 ? l1mv0 : l1mv1; for(i4=0; i4<4; i4++){ - const int16_t *mv_col = l1mv0[x8*2 + (i4&1) + (y8*2 + (i4>>1))*h->b_stride]; + const int16_t *mv_col = l1mv[x8*2 + (i4&1) + (y8*2 + (i4>>1))*h->b_stride]; if(ABS(mv_col[0]) <= 1 && ABS(mv_col[1]) <= 1){ if(ref[0] == 0) *(uint32_t*)h->mv_cache[0][scan8[i8*4+i4]] = 0; @@ -1326,7 +1334,7 @@ static inline void pred_direct_motion(H264Context * const h, int *mb_type){ const int ref0 = l1ref0[0] >= 0 ? h->map_col_to_list0[0][l1ref0[0]] : h->map_col_to_list0[1][l1ref1[0]]; const int dist_scale_factor = h->dist_scale_factor[ref0]; - const int16_t *mv_col = l1mv0[0]; + const int16_t *mv_col = l1ref0[0] >= 0 ? l1mv0[0] : l1mv1[0]; int mv_l0[2]; mv_l0[0] = (dist_scale_factor * mv_col[0] + 128) >> 8; mv_l0[1] = (dist_scale_factor * mv_col[1] + 128) >> 8; @@ -1339,7 +1347,8 @@ static inline void pred_direct_motion(H264Context * const h, int *mb_type){ const int x8 = i8&1; const int y8 = i8>>1; int ref0, dist_scale_factor; - + const int16_t (*l1mv)[2]= l1mv0; + if(is_b8x8 && !IS_DIRECT(h->sub_mb_type[i8])) continue; h->sub_mb_type[i8] = sub_mb_type; @@ -1354,14 +1363,16 @@ static inline void pred_direct_motion(H264Context * const h, int *mb_type){ ref0 = l1ref0[x8 + y8*h->b8_stride]; if(ref0 >= 0) ref0 = h->map_col_to_list0[0][ref0]; - else + else{ ref0 = h->map_col_to_list0[1][l1ref1[x8 + y8*h->b8_stride]]; + l1mv= l1mv1; + } dist_scale_factor = h->dist_scale_factor[ref0]; fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, ref0, 1); fill_rectangle(&h->ref_cache[1][scan8[i8*4]], 2, 2, 8, 0, 1); for(i4=0; i4<4; i4++){ - const int16_t *mv_col = l1mv0[x8*2 + (i4&1) + (y8*2 + (i4>>1))*h->b_stride]; + const int16_t *mv_col = l1mv[x8*2 + (i4&1) + (y8*2 + (i4>>1))*h->b_stride]; int16_t *mv_l0 = h->mv_cache[0][scan8[i8*4+i4]]; mv_l0[0] = (dist_scale_factor * mv_col[0] + 128) >> 8; mv_l0[1] = (dist_scale_factor * mv_col[1] + 128) >> 8; @@ -2316,7 +2327,7 @@ static void pred8x8_plane_c(uint8_t *src, int stride){ const int l0 = ((has_topleft ? SRC(-1,-1) : SRC(-1,0)) \ + 2*SRC(-1,0) + SRC(-1,1) + 2) >> 2; \ PL(1) PL(2) PL(3) PL(4) PL(5) PL(6) \ - const int l7 = (SRC(-1,6) + 3*SRC(-1,7) + 2) >> 2 + const int l7 attribute_unused = (SRC(-1,6) + 3*SRC(-1,7) + 2) >> 2 #define PT(x) \ const int t##x = (SRC(x-1,-1) + 2*SRC(x,-1) + SRC(x+1,-1) + 2) >> 2; @@ -2324,7 +2335,7 @@ static void pred8x8_plane_c(uint8_t *src, int stride){ const int t0 = ((has_topleft ? SRC(-1,-1) : SRC(0,-1)) \ + 2*SRC(0,-1) + SRC(1,-1) + 2) >> 2; \ PT(1) PT(2) PT(3) PT(4) PT(5) PT(6) \ - const int t7 = ((has_topright ? SRC(8,-1) : SRC(7,-1)) \ + const int t7 attribute_unused = ((has_topright ? SRC(8,-1) : SRC(7,-1)) \ + 2*SRC(7,-1) + SRC(6,-1) + 2) >> 2 #define PTR(x) \ @@ -2567,6 +2578,8 @@ static inline void mc_dir_part(H264Context *h, Picture *pic, int n, int square, int emu=0; const int full_mx= mx>>2; const int full_my= my>>2; + const int pic_width = 16*s->mb_width; + const int pic_height = 16*s->mb_height; assert(pic->data[0]); @@ -2575,9 +2588,9 @@ static inline void mc_dir_part(H264Context *h, Picture *pic, int n, int square, if( full_mx < 0-extra_width || full_my < 0-extra_height - || full_mx + 16/*FIXME*/ > s->width + extra_width - || full_my + 16/*FIXME*/ > s->height + extra_height){ - ff_emulated_edge_mc(s->edge_emu_buffer, src_y - 2 - 2*s->linesize, s->linesize, 16+5, 16+5/*FIXME*/, full_mx-2, full_my-2, s->width, s->height); + || full_mx + 16/*FIXME*/ > pic_width + extra_width + || full_my + 16/*FIXME*/ > pic_height + extra_height){ + ff_emulated_edge_mc(s->edge_emu_buffer, src_y - 2 - 2*s->linesize, s->linesize, 16+5, 16+5/*FIXME*/, full_mx-2, full_my-2, pic_width, pic_height); src_y= s->edge_emu_buffer + 2 + 2*s->linesize; emu=1; } @@ -2590,13 +2603,13 @@ static inline void mc_dir_part(H264Context *h, Picture *pic, int n, int square, if(s->flags&CODEC_FLAG_GRAY) return; if(emu){ - ff_emulated_edge_mc(s->edge_emu_buffer, src_cb, s->uvlinesize, 9, 9/*FIXME*/, (mx>>3), (my>>3), s->width>>1, s->height>>1); + ff_emulated_edge_mc(s->edge_emu_buffer, src_cb, s->uvlinesize, 9, 9/*FIXME*/, (mx>>3), (my>>3), pic_width>>1, pic_height>>1); src_cb= s->edge_emu_buffer; } chroma_op(dest_cb, src_cb, s->uvlinesize, chroma_height, mx&7, my&7); if(emu){ - ff_emulated_edge_mc(s->edge_emu_buffer, src_cr, s->uvlinesize, 9, 9/*FIXME*/, (mx>>3), (my>>3), s->width>>1, s->height>>1); + ff_emulated_edge_mc(s->edge_emu_buffer, src_cr, s->uvlinesize, 9, 9/*FIXME*/, (mx>>3), (my>>3), pic_width>>1, pic_height>>1); src_cr= s->edge_emu_buffer; } chroma_op(dest_cr, src_cr, s->uvlinesize, chroma_height, mx&7, my&7); @@ -3108,7 +3121,7 @@ b= t; if(deblock_top){ XCHG(*(uint64_t*)(h->top_borders[0][s->mb_x]+0), *(uint64_t*)(src_y +1), temp64, xchg); XCHG(*(uint64_t*)(h->top_borders[0][s->mb_x]+8), *(uint64_t*)(src_y +9), temp64, 1); - if(s->mb_x < s->mb_width){ + if(s->mb_x+1 < s->mb_width){ XCHG(*(uint64_t*)(h->top_borders[0][s->mb_x+1]), *(uint64_t*)(src_y +17), temp64, 1); } } @@ -3988,7 +4001,7 @@ static int decode_ref_pic_marking(H264Context *h){ if(opcode==MMCO_SHORT2UNUSED || opcode==MMCO_SHORT2LONG){ h->mmco[i].short_frame_num= (h->frame_num - get_ue_golomb(&s->gb) - 1) & ((1<<h->sps.log2_max_frame_num)-1); //FIXME fields /* if(h->mmco[i].short_frame_num >= h->short_ref_count || h->short_ref[ h->mmco[i].short_frame_num ] == NULL){ - fprintf(stderr, "illegal short ref in memory management control operation %d\n", mmco); + av_log(s->avctx, AV_LOG_ERROR, "illegal short ref in memory management control operation %d\n", mmco); return -1; }*/ } @@ -4424,8 +4437,8 @@ static inline int get_dct8x8_allowed(H264Context *h){ static int decode_residual(H264Context *h, GetBitContext *gb, DCTELEM *block, int n, const uint8_t *scantable, const uint16_t *qmul, int max_coeff){ MpegEncContext * const s = &h->s; static const int coeff_token_table_index[17]= {0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3}; - int level[16], run[16]; - int suffix_length, zeros_left, coeff_num, coeff_token, total_coeff, i, trailing_ones; + int level[16]; + int zeros_left, coeff_num, coeff_token, total_coeff, i, j, trailing_ones, run_before; //FIXME put trailing_onex into the context @@ -4458,12 +4471,12 @@ static int decode_residual(H264Context *h, GetBitContext *gb, DCTELEM *block, in level[i]= 1 - 2*get_bits1(gb); } - suffix_length= total_coeff > 10 && trailing_ones < 3; - - for(; i<total_coeff; i++){ - const int prefix= get_level_prefix(gb); + if(i<total_coeff) { int level_code, mask; + int suffix_length = total_coeff > 10 && trailing_ones < 3; + int prefix= get_level_prefix(gb); + //first coefficient has suffix_length equal to 0 or 1 if(prefix<14){ //FIXME try to build a large unified VLC table for all this if(suffix_length) level_code= (prefix<<suffix_length) + get_bits(gb, suffix_length); //part @@ -4482,20 +4495,32 @@ static int decode_residual(H264Context *h, GetBitContext *gb, DCTELEM *block, in return -1; } - if(i==trailing_ones && i<3) level_code+= 2; //FIXME split first iteration + if(trailing_ones < 3) level_code += 2; + suffix_length = 1; + if(level_code > 5) + suffix_length++; mask= -(level_code&1); level[i]= (((2+level_code)>>1) ^ mask) - mask; - - if(suffix_length==0) suffix_length=1; //FIXME split first iteration - -#if 1 - if(ABS(level[i]) > (3<<(suffix_length-1)) && suffix_length<6) suffix_length++; -#else - if((2+level_code)>>1) > (3<<(suffix_length-1)) && suffix_length<6) suffix_length++; - /* ? == prefix > 2 or sth */ -#endif - tprintf("level: %d suffix_length:%d\n", level[i], suffix_length); + i++; + + //remaining coefficients have suffix_length > 0 + for(;i<total_coeff;i++) { + static const int suffix_limit[7] = {0,5,11,23,47,95,INT_MAX }; + prefix = get_level_prefix(gb); + if(prefix<15){ + level_code = (prefix<<suffix_length) + get_bits(gb, suffix_length); + }else if(prefix==15){ + level_code = (prefix<<suffix_length) + get_bits(gb, 12); + }else{ + av_log(h->s.avctx, AV_LOG_ERROR, "prefix too large at %d %d\n", s->mb_x, s->mb_y); + return -1; + } + mask= -(level_code&1); + level[i]= (((2+level_code)>>1) ^ mask) - mask; + if(level_code > suffix_limit[suffix_length]) + suffix_length++; + } } if(total_coeff == max_coeff) @@ -4506,50 +4531,49 @@ static int decode_residual(H264Context *h, GetBitContext *gb, DCTELEM *block, in else zeros_left= get_vlc2(gb, total_zeros_vlc[ total_coeff-1 ].table, TOTAL_ZEROS_VLC_BITS, 1); } - - for(i=0; i<total_coeff-1; i++){ - if(zeros_left <=0) - break; - else if(zeros_left < 7){ - run[i]= get_vlc2(gb, run_vlc[zeros_left-1].table, RUN_VLC_BITS, 1); - }else{ - run[i]= get_vlc2(gb, run7_vlc.table, RUN7_VLC_BITS, 2); - } - zeros_left -= run[i]; - } - if(zeros_left<0){ - av_log(h->s.avctx, AV_LOG_ERROR, "negative number of zero coeffs at %d %d\n", s->mb_x, s->mb_y); - return -1; - } - - for(; i<total_coeff-1; i++){ - run[i]= 0; - } - - run[i]= zeros_left; - - coeff_num=-1; + coeff_num = zeros_left + total_coeff - 1; + j = scantable[coeff_num]; if(n > 24){ - for(i=total_coeff-1; i>=0; i--){ //FIXME merge into rundecode? - int j; - - coeff_num += run[i] + 1; //FIXME add 1 earlier ? + block[j] = level[0]; + for(i=1;i<total_coeff;i++) { + if(zeros_left <= 0) + run_before = 0; + else if(zeros_left < 7){ + run_before= get_vlc2(gb, run_vlc[zeros_left-1].table, RUN_VLC_BITS, 1); + }else{ + run_before= get_vlc2(gb, run7_vlc.table, RUN7_VLC_BITS, 2); + } + zeros_left -= run_before; + coeff_num -= 1 + run_before; j= scantable[ coeff_num ]; block[j]= level[i]; } }else{ - for(i=total_coeff-1; i>=0; i--){ //FIXME merge into rundecode? - int j; - - coeff_num += run[i] + 1; //FIXME add 1 earlier ? + block[j] = level[0] * qmul[j]; + for(i=1;i<total_coeff;i++) { + if(zeros_left <= 0) + run_before = 0; + else if(zeros_left < 7){ + run_before= get_vlc2(gb, run_vlc[zeros_left-1].table, RUN_VLC_BITS, 1); + }else{ + run_before= get_vlc2(gb, run7_vlc.table, RUN7_VLC_BITS, 2); + } + zeros_left -= run_before; + coeff_num -= 1 + run_before; j= scantable[ coeff_num ]; block[j]= level[i] * qmul[j]; // printf("%d %d ", block[j], qmul[j]); } } + + if(zeros_left<0){ + av_log(h->s.avctx, AV_LOG_ERROR, "negative number of zero coeffs at %d %d\n", s->mb_x, s->mb_y); + return -1; + } + return 0; } @@ -5352,6 +5376,8 @@ static int decode_cabac_mb_dqp( H264Context *h) { else ctx = 3; val++; + if(val > 52) //prevent infinite loop + return INT_MIN; } if( val&0x01 ) @@ -5491,9 +5517,6 @@ static int inline decode_cabac_residual( H264Context *h, DCTELEM *block, int cat static const int significant_coeff_flag_offset[6] = { 0, 15, 29, 44, 47, 297 }; static const int last_significant_coeff_flag_offset[6] = { 0, 15, 29, 44, 47, 251 }; static const int coeff_abs_level_m1_offset[6] = { 227+0, 227+10, 227+20, 227+30, 227+39, 426 }; - static const int identity[15] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 - }; static const int significant_coeff_flag_offset_8x8[63] = { 0, 1, 2, 3, 4, 5, 5, 4, 4, 3, 3, 4, 4, 4, 5, 5, 4, 4, 4, 4, 3, 3, 6, 7, 7, 7, 8, 9,10, 9, 8, 7, @@ -5515,12 +5538,9 @@ static int inline decode_cabac_residual( H264Context *h, DCTELEM *block, int cat int abslevel1 = 1; int abslevelgt1 = 0; - const int* significant_coeff_ctx_offset; - const int* last_coeff_ctx_offset; - const int significant_coeff_ctx_base = significant_coeff_flag_offset[cat] - + significant_coeff_flag_field_offset[h->mb_field_decoding_flag]; - const int last_coeff_ctx_base = last_significant_coeff_flag_offset[cat] - + last_significant_coeff_flag_field_offset[h->mb_field_decoding_flag]; + uint8_t *significant_coeff_ctx_base; + uint8_t *last_coeff_ctx_base; + uint8_t *abs_level_m1_ctx_base; /* cat: 0-> DC 16x16 n = 0 * 1-> AC 16x16 n = luma4x4idx @@ -5531,10 +5551,7 @@ static int inline decode_cabac_residual( H264Context *h, DCTELEM *block, int cat */ /* read coded block flag */ - if( cat == 5 ) { - significant_coeff_ctx_offset = significant_coeff_flag_offset_8x8; - last_coeff_ctx_offset = last_coeff_flag_offset_8x8; - } else { + if( cat != 5 ) { if( get_cabac( &h->cabac, &h->cabac_state[85 + get_cabac_cbf_ctx( h, cat, n ) ] ) == 0 ) { if( cat == 1 || cat == 2 ) h->non_zero_count_cache[scan8[n]] = 0; @@ -5543,21 +5560,34 @@ static int inline decode_cabac_residual( H264Context *h, DCTELEM *block, int cat return 0; } - - significant_coeff_ctx_offset = - last_coeff_ctx_offset = identity; } - for(last= 0; last < max_coeff - 1; last++) { - int sig_ctx = significant_coeff_ctx_base + significant_coeff_ctx_offset[last]; - if( get_cabac( &h->cabac, &h->cabac_state[sig_ctx] )) { - int last_ctx = last_coeff_ctx_base + last_coeff_ctx_offset[last]; - index[coeff_count++] = last; - if( get_cabac( &h->cabac, &h->cabac_state[last_ctx] ) ) { - last= max_coeff; - break; - } - } + significant_coeff_ctx_base = h->cabac_state + + significant_coeff_flag_offset[cat] + + significant_coeff_flag_field_offset[h->mb_field_decoding_flag]; + last_coeff_ctx_base = h->cabac_state + + last_significant_coeff_flag_offset[cat] + + last_significant_coeff_flag_field_offset[h->mb_field_decoding_flag]; + abs_level_m1_ctx_base = h->cabac_state + + coeff_abs_level_m1_offset[cat]; + + if( cat == 5 ) { +#define DECODE_SIGNIFICANCE( coefs, sig_off, last_off ) \ + for(last= 0; last < coefs; last++) { \ + uint8_t *sig_ctx = significant_coeff_ctx_base + sig_off; \ + if( get_cabac( &h->cabac, sig_ctx )) { \ + uint8_t *last_ctx = last_coeff_ctx_base + last_off; \ + index[coeff_count++] = last; \ + if( get_cabac( &h->cabac, last_ctx ) ) { \ + last= max_coeff; \ + break; \ + } \ + } \ + } + DECODE_SIGNIFICANCE( 63, significant_coeff_flag_offset_8x8[last], + last_coeff_flag_offset_8x8[last] ); + } else { + DECODE_SIGNIFICANCE( max_coeff - 1, last, last ); } if( last == max_coeff -1 ) { index[coeff_count++] = last; @@ -5578,11 +5608,11 @@ static int inline decode_cabac_residual( H264Context *h, DCTELEM *block, int cat } for( i = coeff_count - 1; i >= 0; i-- ) { - int ctx = (abslevelgt1 != 0 ? 0 : FFMIN( 4, abslevel1 )) + coeff_abs_level_m1_offset[cat]; + uint8_t *ctx = (abslevelgt1 != 0 ? 0 : FFMIN( 4, abslevel1 )) + abs_level_m1_ctx_base; int j= scantable[index[i]]; - if( get_cabac( &h->cabac, &h->cabac_state[ctx] ) == 0 ) { - if( cat == 0 || cat == 3 ) { + if( get_cabac( &h->cabac, ctx ) == 0 ) { + if( !qmul ) { if( get_cabac_bypass( &h->cabac ) ) block[j] = -1; else block[j] = 1; }else{ @@ -5593,8 +5623,8 @@ static int inline decode_cabac_residual( H264Context *h, DCTELEM *block, int cat abslevel1++; } else { int coeff_abs = 2; - ctx = 5 + FFMIN( 4, abslevelgt1 ) + coeff_abs_level_m1_offset[cat]; - while( coeff_abs < 15 && get_cabac( &h->cabac, &h->cabac_state[ctx] ) ) { + ctx = 5 + FFMIN( 4, abslevelgt1 ) + abs_level_m1_ctx_base; + while( coeff_abs < 15 && get_cabac( &h->cabac, ctx ) ) { coeff_abs++; } @@ -5611,7 +5641,7 @@ static int inline decode_cabac_residual( H264Context *h, DCTELEM *block, int cat } } - if( cat == 0 || cat == 3 ) { + if( !qmul ) { if( get_cabac_bypass( &h->cabac ) ) block[j] = -coeff_abs; else block[j] = coeff_abs; }else{ @@ -6029,6 +6059,10 @@ decode_intra_mb: } h->last_qscale_diff = dqp = decode_cabac_mb_dqp( h ); + if( dqp == INT_MIN ){ + av_log(h->s.avctx, AV_LOG_ERROR, "cabac decode of qscale diff failed at %d %d\n", s->mb_x, s->mb_y); + return -1; + } s->qscale += dqp; if(((unsigned)s->qscale) > 51){ if(s->qscale<0) s->qscale+= 52; @@ -6039,7 +6073,7 @@ decode_intra_mb: if( IS_INTRA16x16( mb_type ) ) { int i; //av_log( s->avctx, AV_LOG_ERROR, "INTRA16x16 DC\n" ); - if( decode_cabac_residual( h, h->mb, 0, 0, dc_scan, h->dequant4_coeff[s->qscale], 16) < 0) + if( decode_cabac_residual( h, h->mb, 0, 0, dc_scan, NULL, 16) < 0) return -1; if( cbp&15 ) { for( i = 0; i < 16; i++ ) { @@ -6081,7 +6115,7 @@ decode_intra_mb: int c; for( c = 0; c < 2; c++ ) { //av_log( s->avctx, AV_LOG_ERROR, "INTRA C%d-DC\n",c ); - if( decode_cabac_residual(h, h->mb + 256 + 16*4*c, 3, c, chroma_dc_scan, h->dequant4_coeff[h->chroma_qp], 4) < 0) + if( decode_cabac_residual(h, h->mb + 256 + 16*4*c, 3, c, chroma_dc_scan, NULL, 4) < 0) return -1; } } @@ -6177,7 +6211,7 @@ static void filter_mb_edgev( H264Context *h, uint8_t *pix, int stride, int bS[4] } } static void filter_mb_edgecv( H264Context *h, uint8_t *pix, int stride, int bS[4], int qp ) { - int i, d; + int i; const int index_a = clip( qp + h->slice_alpha_c0_offset, 0, 51 ); const int alpha = alpha_table[index_a]; const int beta = beta_table[clip( qp + h->slice_beta_offset, 0, 51 )]; @@ -6407,7 +6441,7 @@ static void filter_mb_edgeh( H264Context *h, uint8_t *pix, int stride, int bS[4] } static void filter_mb_edgech( H264Context *h, uint8_t *pix, int stride, int bS[4], int qp ) { - int i, d; + int i; const int index_a = clip( qp + h->slice_alpha_c0_offset, 0, 51 ); const int alpha = alpha_table[index_a]; const int beta = beta_table[clip( qp + h->slice_beta_offset, 0, 51 )]; @@ -6537,7 +6571,7 @@ static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8 bS[0] = bS[1] = bS[2] = bS[3] = 3; } else { // TODO - assert(0); + av_log(h->s.avctx, AV_LOG_ERROR, "both non intra (TODO)\n"); } /* Filter edge */ // Do not use s->qscale as luma quantizer because it has not the same @@ -6558,7 +6592,7 @@ static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8 bS[0] = bS[1] = bS[2] = bS[3] = 3; } else { // TODO - assert(0); + av_log(h->s.avctx, AV_LOG_ERROR, "both non intra (TODO)\n"); } /* Filter edge */ // Do not use s->qscale as luma quantizer because it has not the same @@ -6690,7 +6724,7 @@ static int decode_slice(H264Context *h){ if(ret>=0) ret = decode_mb_cabac(h); - hl_decode_mb(h); + if(ret>=0) hl_decode_mb(h); s->mb_y--; } eos = get_cabac_terminate( &h->cabac ); @@ -6823,6 +6857,64 @@ static int decode_slice(H264Context *h){ return -1; //not reached } +static int decode_unregistered_user_data(H264Context *h, int size){ + MpegEncContext * const s = &h->s; + uint8_t user_data[16+256]; + int e, build, i; + + if(size<16) + return -1; + + for(i=0; i<sizeof(user_data)-1 && i<size; i++){ + user_data[i]= get_bits(&s->gb, 8); + } + + user_data[i]= 0; + e= sscanf(user_data+16, "x264 - core %d"/*%s - H.264/MPEG-4 AVC codec - Copyleft 2005 - http://www.videolan.org/x264.html*/, &build); + if(e==1 && build>=0) + h->x264_build= build; + + if(s->avctx->debug & FF_DEBUG_BUGS) + av_log(s->avctx, AV_LOG_DEBUG, "user data:\"%s\"\n", user_data+16); + + for(; i<size; i++) + skip_bits(&s->gb, 8); + + return 0; +} + +static int decode_sei(H264Context *h){ + MpegEncContext * const s = &h->s; + + while(get_bits_count(&s->gb) + 16 < s->gb.size_in_bits){ + int size, type; + + type=0; + do{ + type+= show_bits(&s->gb, 8); + }while(get_bits(&s->gb, 8) == 255); + + size=0; + do{ + size+= show_bits(&s->gb, 8); + }while(get_bits(&s->gb, 8) == 255); + + switch(type){ + case 5: + if(decode_unregistered_user_data(h, size) < 0); + return -1; + break; + default: + skip_bits(&s->gb, 8*size); + } + + //FIXME check bits here + align_get_bits(&s->gb); + } + + return 0; +} + static inline void decode_hrd_parameters(H264Context *h, SPS *sps){ MpegEncContext * const s = &h->s; int cpb_count, i; @@ -7206,8 +7298,8 @@ static int decode_nal_units(H264Context *h, uint8_t *buf, int buf_size){ int buf_index=0; #if 0 int i; - for(i=0; i<32; i++){ - printf("%X ", buf[i]); + for(i=0; i<50; i++){ + av_log(NULL, AV_LOG_ERROR,"%02X ", buf[i]); } #endif h->slice_num = 0; @@ -7250,7 +7342,7 @@ static int decode_nal_units(H264Context *h, uint8_t *buf, int buf_size){ buf_index += consumed; - if( (s->hurry_up == 1 && h->nal_ref_idc == 0) + if( (s->hurry_up == 1 && h->nal_ref_idc == 0) //FIXME dont discard SEI id ||(avctx->skip_frame >= AVDISCARD_NONREF && h->nal_ref_idc == 0)) continue; @@ -7301,6 +7393,8 @@ static int decode_nal_units(H264Context *h, uint8_t *buf, int buf_size){ decode_slice(h); break; case NAL_SEI: + init_get_bits(&s->gb, ptr, bit_length); + decode_sei(h); break; case NAL_SPS: init_get_bits(&s->gb, ptr, bit_length); @@ -7409,7 +7503,7 @@ static int decode_frame(AVCodecContext *avctx, p += 6; for (i = 0; i < cnt; i++) { nalsize = BE_16(p) + 2; - if(decode_nal_units(h, p, nalsize) != nalsize) { + if(decode_nal_units(h, p, nalsize) < 0) { av_log(avctx, AV_LOG_ERROR, "Decoding sps %d from avcC failed\n", i); return -1; } @@ -7728,6 +7822,7 @@ static int decode_end(AVCodecContext *avctx) H264Context *h = avctx->priv_data; MpegEncContext *s = &h->s; + av_freep(&h->rbsp_buffer); free_tables(h); //FIXME cleanup init stuff perhaps MPV_common_end(s); diff --git a/src/libffmpeg/libavcodec/i386/Makefile.am b/src/libffmpeg/libavcodec/i386/Makefile.am index f692ba62b..1a0bf2343 100644 --- a/src/libffmpeg/libavcodec/i386/Makefile.am +++ b/src/libffmpeg/libavcodec/i386/Makefile.am @@ -1,6 +1,6 @@ include $(top_srcdir)/misc/Makefile.common -AM_CFLAGS = $(LIBFFMPEG_CFLAGS) +AM_CFLAGS = $(LIBFFMPEG_CFLAGS) -I../../libavutil # CFLAGS is here to filter out -funroll-loops because it causes bad # behavior of libavcodec CFLAGS = `echo @CFLAGS@ | sed -e 's/-funroll-loops//g'` @@ -15,6 +15,7 @@ libavcodec_mmx_src = \ fdct_mmx.c \ fft_sse.c \ idct_mmx.c \ + idct_mmx_xvid.c \ motion_est_mmx.c \ mpegvideo_mmx.c \ simple_idct_mmx.c \ diff --git a/src/libffmpeg/libavcodec/i386/dsputil_mmx.c b/src/libffmpeg/libavcodec/i386/dsputil_mmx.c index 6bd2b32b9..c1dd2176a 100644 --- a/src/libffmpeg/libavcodec/i386/dsputil_mmx.c +++ b/src/libffmpeg/libavcodec/i386/dsputil_mmx.c @@ -29,6 +29,8 @@ //#include <assert.h> extern const uint8_t ff_h263_loop_filter_strength[32]; +extern void ff_idct_xvid_mmx(short *block); +extern void ff_idct_xvid_mmx2(short *block); int mm_flags; /* multimedia extension flags */ @@ -615,31 +617,32 @@ static void h263_v_loop_filter_mmx(uint8_t *src, int stride, int qscale){ } static inline void transpose4x4(uint8_t *dst, uint8_t *src, int dst_stride, int src_stride){ + void *dst_reg = dst, *src_reg = src; + asm volatile( //FIXME could save 1 instruction if done as 8x4 ... - "movd %4, %%mm0 \n\t" - "movd %5, %%mm1 \n\t" - "movd %6, %%mm2 \n\t" - "movd %7, %%mm3 \n\t" + "movd (%1), %%mm0 \n\t" + "movd (%1,%5), %%mm1 \n\t" + "lea (%1, %5, 2), %1 \n\t" + "movd (%1), %%mm2 \n\t" + "movd (%1,%5), %%mm3 \n\t" "punpcklbw %%mm1, %%mm0 \n\t" "punpcklbw %%mm3, %%mm2 \n\t" "movq %%mm0, %%mm1 \n\t" "punpcklwd %%mm2, %%mm0 \n\t" "punpckhwd %%mm2, %%mm1 \n\t" - "movd %%mm0, %0 \n\t" + "movd %%mm0, (%0) \n\t" "punpckhdq %%mm0, %%mm0 \n\t" - "movd %%mm0, %1 \n\t" - "movd %%mm1, %2 \n\t" + "movd %%mm0, (%0,%4) \n\t" + "lea (%0, %4, 2), %0 \n\t" + "movd %%mm1, (%0) \n\t" "punpckhdq %%mm1, %%mm1 \n\t" - "movd %%mm1, %3 \n\t" - - : "=m" (*(uint32_t*)(dst + 0*dst_stride)), - "=m" (*(uint32_t*)(dst + 1*dst_stride)), - "=m" (*(uint32_t*)(dst + 2*dst_stride)), - "=m" (*(uint32_t*)(dst + 3*dst_stride)) - : "m" (*(uint32_t*)(src + 0*src_stride)), - "m" (*(uint32_t*)(src + 1*src_stride)), - "m" (*(uint32_t*)(src + 2*src_stride)), - "m" (*(uint32_t*)(src + 3*src_stride)) + "movd %%mm1, (%0,%4) \n\t" + : "=&r" (dst_reg), + "=&r" (src_reg) + : "0" (dst_reg), + "1" (src_reg), + "r" (dst_stride), + "r" (src_stride) ); } @@ -742,31 +745,49 @@ static int sse8_mmx(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int int tmp; asm volatile ( "movl %4,%%ecx\n" + "shr $1,%%ecx\n" "pxor %%mm0,%%mm0\n" /* mm0 = 0 */ "pxor %%mm7,%%mm7\n" /* mm7 holds the sum */ "1:\n" - "movq (%0),%%mm1\n" /* mm1 = pix1[0-7] */ - "movq (%1),%%mm2\n" /* mm2 = pix2[0-7] */ + "movq (%0),%%mm1\n" /* mm1 = pix1[0][0-7] */ + "movq (%1),%%mm2\n" /* mm2 = pix2[0][0-7] */ + "movq (%0,%3),%%mm3\n" /* mm3 = pix1[1][0-7] */ + "movq (%1,%3),%%mm4\n" /* mm4 = pix2[1][0-7] */ + /* todo: mm1-mm2, mm3-mm4 */ + /* algo: substract mm1 from mm2 with saturation and vice versa */ + /* OR the results to get absolute difference */ "movq %%mm1,%%mm5\n" + "movq %%mm3,%%mm6\n" "psubusb %%mm2,%%mm1\n" + "psubusb %%mm4,%%mm3\n" "psubusb %%mm5,%%mm2\n" + "psubusb %%mm6,%%mm4\n" "por %%mm1,%%mm2\n" + "por %%mm3,%%mm4\n" + /* now convert to 16-bit vectors so we can square them */ "movq %%mm2,%%mm1\n" + "movq %%mm4,%%mm3\n" "punpckhbw %%mm0,%%mm2\n" + "punpckhbw %%mm0,%%mm4\n" "punpcklbw %%mm0,%%mm1\n" /* mm1 now spread over (mm1,mm2) */ + "punpcklbw %%mm0,%%mm3\n" /* mm4 now spread over (mm3,mm4) */ "pmaddwd %%mm2,%%mm2\n" + "pmaddwd %%mm4,%%mm4\n" "pmaddwd %%mm1,%%mm1\n" + "pmaddwd %%mm3,%%mm3\n" - "add %3,%0\n" - "add %3,%1\n" + "lea (%0,%3,2), %0\n" /* pix1 += 2*line_size */ + "lea (%1,%3,2), %1\n" /* pix2 += 2*line_size */ "paddd %%mm2,%%mm1\n" + "paddd %%mm4,%%mm3\n" "paddd %%mm1,%%mm7\n" + "paddd %%mm3,%%mm7\n" "decl %%ecx\n" "jnz 1b\n" @@ -841,6 +862,68 @@ static int sse16_mmx(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int return tmp; } +static int sse16_sse2(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h) { + int tmp; + asm volatile ( + "shr $1,%2\n" + "pxor %%xmm0,%%xmm0\n" /* mm0 = 0 */ + "pxor %%xmm7,%%xmm7\n" /* mm7 holds the sum */ + "1:\n" + "movdqu (%0),%%xmm1\n" /* mm1 = pix1[0][0-15] */ + "movdqu (%1),%%xmm2\n" /* mm2 = pix2[0][0-15] */ + "movdqu (%0,%4),%%xmm3\n" /* mm3 = pix1[1][0-15] */ + "movdqu (%1,%4),%%xmm4\n" /* mm4 = pix2[1][0-15] */ + + /* todo: mm1-mm2, mm3-mm4 */ + /* algo: substract mm1 from mm2 with saturation and vice versa */ + /* OR the results to get absolute difference */ + "movdqa %%xmm1,%%xmm5\n" + "movdqa %%xmm3,%%xmm6\n" + "psubusb %%xmm2,%%xmm1\n" + "psubusb %%xmm4,%%xmm3\n" + "psubusb %%xmm5,%%xmm2\n" + "psubusb %%xmm6,%%xmm4\n" + + "por %%xmm1,%%xmm2\n" + "por %%xmm3,%%xmm4\n" + + /* now convert to 16-bit vectors so we can square them */ + "movdqa %%xmm2,%%xmm1\n" + "movdqa %%xmm4,%%xmm3\n" + + "punpckhbw %%xmm0,%%xmm2\n" + "punpckhbw %%xmm0,%%xmm4\n" + "punpcklbw %%xmm0,%%xmm1\n" /* mm1 now spread over (mm1,mm2) */ + "punpcklbw %%xmm0,%%xmm3\n" /* mm4 now spread over (mm3,mm4) */ + + "pmaddwd %%xmm2,%%xmm2\n" + "pmaddwd %%xmm4,%%xmm4\n" + "pmaddwd %%xmm1,%%xmm1\n" + "pmaddwd %%xmm3,%%xmm3\n" + + "lea (%0,%4,2), %0\n" /* pix1 += 2*line_size */ + "lea (%1,%4,2), %1\n" /* pix2 += 2*line_size */ + + "paddd %%xmm2,%%xmm1\n" + "paddd %%xmm4,%%xmm3\n" + "paddd %%xmm1,%%xmm7\n" + "paddd %%xmm3,%%xmm7\n" + + "decl %2\n" + "jnz 1b\n" + + "movdqa %%xmm7,%%xmm1\n" + "psrldq $8, %%xmm7\n" /* shift hi qword to lo */ + "paddd %%xmm1,%%xmm7\n" + "movdqa %%xmm7,%%xmm1\n" + "psrldq $4, %%xmm7\n" /* shift hi dword to lo */ + "paddd %%xmm1,%%xmm7\n" + "movd %%xmm7,%3\n" + : "+r" (pix1), "+r" (pix2), "+r"(h), "=r"(tmp) + : "r" ((long)line_size)); + return tmp; +} + static int hf_noise8_mmx(uint8_t * pix1, int line_size, int h) { int tmp; asm volatile ( @@ -1080,7 +1163,8 @@ static int hf_noise16_mmx(uint8_t * pix1, int line_size, int h) { return tmp + hf_noise8_mmx(pix+8, line_size, h); } -static int nsse16_mmx(MpegEncContext *c, uint8_t * pix1, uint8_t * pix2, int line_size, int h) { +static int nsse16_mmx(void *p, uint8_t * pix1, uint8_t * pix2, int line_size, int h) { + MpegEncContext *c = p; int score1= sse16_mmx(c, pix1, pix2, line_size, h); int score2= hf_noise16_mmx(pix1, line_size, h) - hf_noise16_mmx(pix2, line_size, h); @@ -1088,7 +1172,8 @@ static int nsse16_mmx(MpegEncContext *c, uint8_t * pix1, uint8_t * pix2, int lin else return score1 + ABS(score2)*8; } -static int nsse8_mmx(MpegEncContext *c, uint8_t * pix1, uint8_t * pix2, int line_size, int h) { +static int nsse8_mmx(void *p, uint8_t * pix1, uint8_t * pix2, int line_size, int h) { + MpegEncContext *c = p; int score1= sse8_mmx(c, pix1, pix2, line_size, h); int score2= hf_noise8_mmx(pix1, line_size, h) - hf_noise8_mmx(pix2, line_size, h); @@ -1617,11 +1702,9 @@ static int hadamard8_diff_mmx2(void *s, uint8_t *src1, uint8_t *src2, int stride "movq 64(%1), %%mm1 \n\t" MMABS_SUM_MMX2(%%mm1, %%mm7, %%mm0) - "movq %%mm0, %%mm1 \n\t" - "psrlq $32, %%mm0 \n\t" + "pshufw $0x0E, %%mm0, %%mm1 \n\t" "paddusw %%mm1, %%mm0 \n\t" - "movq %%mm0, %%mm1 \n\t" - "psrlq $16, %%mm0 \n\t" + "pshufw $0x01, %%mm0, %%mm1 \n\t" "paddusw %%mm1, %%mm0 \n\t" "movd %%mm0, %0 \n\t" @@ -2455,6 +2538,28 @@ static void ff_vp3_idct_add_mmx(uint8_t *dest, int line_size, DCTELEM *block) ff_vp3_idct_mmx(block); add_pixels_clamped_mmx(block, dest, line_size); } +#ifdef CONFIG_GPL +static void ff_idct_xvid_mmx_put(uint8_t *dest, int line_size, DCTELEM *block) +{ + ff_idct_xvid_mmx (block); + put_pixels_clamped_mmx(block, dest, line_size); +} +static void ff_idct_xvid_mmx_add(uint8_t *dest, int line_size, DCTELEM *block) +{ + ff_idct_xvid_mmx (block); + add_pixels_clamped_mmx(block, dest, line_size); +} +static void ff_idct_xvid_mmx2_put(uint8_t *dest, int line_size, DCTELEM *block) +{ + ff_idct_xvid_mmx2 (block); + put_pixels_clamped_mmx(block, dest, line_size); +} +static void ff_idct_xvid_mmx2_add(uint8_t *dest, int line_size, DCTELEM *block) +{ + ff_idct_xvid_mmx2 (block); + add_pixels_clamped_mmx(block, dest, line_size); +} +#endif void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) { @@ -2527,6 +2632,18 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) c->idct = ff_vp3_idct_mmx; c->idct_permutation_type= FF_PARTTRANS_IDCT_PERM; } +#ifdef CONFIG_GPL + }else if(idct_algo==FF_IDCT_XVIDMMX){ + if(mm_flags & MM_MMXEXT){ + c->idct_put= ff_idct_xvid_mmx2_put; + c->idct_add= ff_idct_xvid_mmx2_add; + c->idct = ff_idct_xvid_mmx2; + }else{ + c->idct_put= ff_idct_xvid_mmx_put; + c->idct_add= ff_idct_xvid_mmx_add; + c->idct = ff_idct_xvid_mmx; + } +#endif } } @@ -2590,7 +2707,7 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) c->hadamard8_diff[1]= hadamard8_diff_mmx; c->pix_norm1 = pix_norm1_mmx; - c->sse[0] = sse16_mmx; + c->sse[0] = (mm_flags & MM_SSE2) ? sse16_sse2 : sse16_mmx; c->sse[1] = sse8_mmx; c->vsad[4]= vsad_intra16_mmx; @@ -2716,6 +2833,24 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) c->h264_v_loop_filter_chroma_intra= h264_v_loop_filter_chroma_intra_mmx2; c->h264_h_loop_filter_chroma_intra= h264_h_loop_filter_chroma_intra_mmx2; + c->weight_h264_pixels_tab[0]= ff_h264_weight_16x16_mmx2; + c->weight_h264_pixels_tab[1]= ff_h264_weight_16x8_mmx2; + c->weight_h264_pixels_tab[2]= ff_h264_weight_8x16_mmx2; + c->weight_h264_pixels_tab[3]= ff_h264_weight_8x8_mmx2; + c->weight_h264_pixels_tab[4]= ff_h264_weight_8x4_mmx2; + c->weight_h264_pixels_tab[5]= ff_h264_weight_4x8_mmx2; + c->weight_h264_pixels_tab[6]= ff_h264_weight_4x4_mmx2; + c->weight_h264_pixels_tab[7]= ff_h264_weight_4x2_mmx2; + + c->biweight_h264_pixels_tab[0]= ff_h264_biweight_16x16_mmx2; + c->biweight_h264_pixels_tab[1]= ff_h264_biweight_16x8_mmx2; + c->biweight_h264_pixels_tab[2]= ff_h264_biweight_8x16_mmx2; + c->biweight_h264_pixels_tab[3]= ff_h264_biweight_8x8_mmx2; + c->biweight_h264_pixels_tab[4]= ff_h264_biweight_8x4_mmx2; + c->biweight_h264_pixels_tab[5]= ff_h264_biweight_4x8_mmx2; + c->biweight_h264_pixels_tab[6]= ff_h264_biweight_4x4_mmx2; + c->biweight_h264_pixels_tab[7]= ff_h264_biweight_4x2_mmx2; + #ifdef CONFIG_ENCODERS c->sub_hfyu_median_prediction= sub_hfyu_median_prediction_mmx2; #endif //CONFIG_ENCODERS diff --git a/src/libffmpeg/libavcodec/i386/dsputil_mmx_rnd.h b/src/libffmpeg/libavcodec/i386/dsputil_mmx_rnd.h index 20ea1b59e..a56374b63 100644 --- a/src/libffmpeg/libavcodec/i386/dsputil_mmx_rnd.h +++ b/src/libffmpeg/libavcodec/i386/dsputil_mmx_rnd.h @@ -55,7 +55,7 @@ static void DEF(put, pixels8_x2)(uint8_t *block, const uint8_t *pixels, int line :REG_a, "memory"); } -static void DEF(put, pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) +static void attribute_unused DEF(put, pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) { MOVQ_BFE(mm6); __asm __volatile( @@ -151,7 +151,7 @@ static void DEF(put, pixels16_x2)(uint8_t *block, const uint8_t *pixels, int lin :REG_a, "memory"); } -static void DEF(put, pixels16_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) +static void attribute_unused DEF(put, pixels16_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) { MOVQ_BFE(mm6); __asm __volatile( @@ -296,7 +296,7 @@ static void DEF(put, pixels8_xy2)(uint8_t *block, const uint8_t *pixels, int lin } // avg_pixels -static void DEF(avg, pixels4)(uint8_t *block, const uint8_t *pixels, int line_size, int h) +static void attribute_unused DEF(avg, pixels4)(uint8_t *block, const uint8_t *pixels, int line_size, int h) { MOVQ_BFE(mm6); JUMPALIGN(); diff --git a/src/libffmpeg/libavcodec/i386/fdct_mmx.c b/src/libffmpeg/libavcodec/i386/fdct_mmx.c index aacbe5743..6a13090a1 100644 --- a/src/libffmpeg/libavcodec/i386/fdct_mmx.c +++ b/src/libffmpeg/libavcodec/i386/fdct_mmx.c @@ -13,7 +13,7 @@ * a page about fdct at http://www.geocities.com/ssavekar/dct.htm * Skal's fdct at http://skal.planet-d.net/coding/dct.html */ -#include "../common.h" +#include "common.h" #include "../dsputil.h" #include "mmx.h" diff --git a/src/libffmpeg/libavcodec/i386/h264dsp_mmx.c b/src/libffmpeg/libavcodec/i386/h264dsp_mmx.c index 47fcf938b..c278affc8 100644 --- a/src/libffmpeg/libavcodec/i386/h264dsp_mmx.c +++ b/src/libffmpeg/libavcodec/i386/h264dsp_mmx.c @@ -162,11 +162,10 @@ void ff_h264_idct_add_mmx2(uint8_t *dst, int16_t *block, int stride) /* delta = (avg(q0, p1>>2) + (d&a)) * - (avg(p0, q1>>2) + (d&~a)) */\ "pavgb %%mm2, %%mm0 \n\t"\ - "movq %%mm5, %%mm6 \n\t"\ - "pand %%mm4, %%mm6 \n\t"\ - "paddusb %%mm6, %%mm0 \n\t"\ + "pand %%mm5, %%mm4 \n\t"\ + "paddusb %%mm4, %%mm0 \n\t"\ "pavgb %%mm1, %%mm3 \n\t"\ - "pandn %%mm5, %%mm4 \n\t"\ + "pxor %%mm5, %%mm4 \n\t"\ "paddusb %%mm4, %%mm3 \n\t"\ /* p0 += clip(delta, -tc0, tc0) * q0 -= clip(delta, -tc0, tc0) */\ @@ -910,3 +909,100 @@ H264_MC(avg_, 16,mmx2) #undef H264_CHROMA_OP #undef H264_CHROMA_MC8_TMPL +/***********************************/ +/* weighted prediction */ + +static inline void ff_h264_weight_WxH_mmx2(uint8_t *dst, int stride, int log2_denom, int weight, int offset, int w, int h) +{ + int x, y; + offset <<= log2_denom; + offset += (1 << log2_denom) >> 1; + asm volatile( + "movd %0, %%mm4 \n\t" + "movd %1, %%mm5 \n\t" + "movd %2, %%mm6 \n\t" + "pshufw $0, %%mm4, %%mm4 \n\t" + "pshufw $0, %%mm5, %%mm5 \n\t" + "pxor %%mm7, %%mm7 \n\t" + :: "g"(weight), "g"(offset), "g"(log2_denom) + ); + for(y=0; y<h; y+=2){ + for(x=0; x<w; x+=4){ + asm volatile( + "movd %0, %%mm0 \n\t" + "movd %1, %%mm1 \n\t" + "punpcklbw %%mm7, %%mm0 \n\t" + "punpcklbw %%mm7, %%mm1 \n\t" + "pmullw %%mm4, %%mm0 \n\t" + "pmullw %%mm4, %%mm1 \n\t" + "paddw %%mm5, %%mm0 \n\t" + "paddw %%mm5, %%mm1 \n\t" + "psraw %%mm6, %%mm0 \n\t" + "psraw %%mm6, %%mm1 \n\t" + "packuswb %%mm7, %%mm0 \n\t" + "packuswb %%mm7, %%mm1 \n\t" + "movd %%mm0, %0 \n\t" + "movd %%mm1, %1 \n\t" + : "+m"(*(uint32_t*)(dst+x)), + "+m"(*(uint32_t*)(dst+x+stride)) + ); + } + dst += 2*stride; + } +} + +static inline void ff_h264_biweight_WxH_mmx2(uint8_t *dst, uint8_t *src, int stride, int log2_denom, int weightd, int weights, int offsetd, int offsets, int w, int h) +{ + int x, y; + int offset = ((offsets + offsetd + 1) | 1) << log2_denom; + asm volatile( + "movd %0, %%mm3 \n\t" + "movd %1, %%mm4 \n\t" + "movd %2, %%mm5 \n\t" + "movd %3, %%mm6 \n\t" + "pshufw $0, %%mm3, %%mm3 \n\t" + "pshufw $0, %%mm4, %%mm4 \n\t" + "pshufw $0, %%mm5, %%mm5 \n\t" + "pxor %%mm7, %%mm7 \n\t" + :: "g"(weightd), "g"(weights), "g"(offset), "g"(log2_denom+1) + ); + for(y=0; y<h; y++){ + for(x=0; x<w; x+=4){ + asm volatile( + "movd %0, %%mm0 \n\t" + "movd %1, %%mm1 \n\t" + "punpcklbw %%mm7, %%mm0 \n\t" + "punpcklbw %%mm7, %%mm1 \n\t" + "pmullw %%mm3, %%mm0 \n\t" + "pmullw %%mm4, %%mm1 \n\t" + "paddw %%mm5, %%mm0 \n\t" + "paddw %%mm1, %%mm0 \n\t" + "psraw %%mm6, %%mm0 \n\t" + "packuswb %%mm0, %%mm0 \n\t" + "movd %%mm0, %0 \n\t" + : "+m"(*(uint32_t*)(dst+x)) + : "m"(*(uint32_t*)(src+x)) + ); + } + src += stride; + dst += stride; + } +} + +#define H264_WEIGHT(W,H) \ +static void ff_h264_biweight_ ## W ## x ## H ## _mmx2(uint8_t *dst, uint8_t *src, int stride, int log2_denom, int weightd, int weights, int offsetd, int offsets){ \ + ff_h264_biweight_WxH_mmx2(dst, src, stride, log2_denom, weightd, weights, offsetd, offsets, W, H); \ +} \ +static void ff_h264_weight_ ## W ## x ## H ## _mmx2(uint8_t *dst, int stride, int log2_denom, int weight, int offset){ \ + ff_h264_weight_WxH_mmx2(dst, stride, log2_denom, weight, offset, W, H); \ +} + +H264_WEIGHT(16,16) +H264_WEIGHT(16, 8) +H264_WEIGHT( 8,16) +H264_WEIGHT( 8, 8) +H264_WEIGHT( 8, 4) +H264_WEIGHT( 4, 8) +H264_WEIGHT( 4, 4) +H264_WEIGHT( 4, 2) + diff --git a/src/libffmpeg/libavcodec/i386/idct_mmx.c b/src/libffmpeg/libavcodec/i386/idct_mmx.c index d9586efc5..d1a84549d 100644 --- a/src/libffmpeg/libavcodec/i386/idct_mmx.c +++ b/src/libffmpeg/libavcodec/i386/idct_mmx.c @@ -22,7 +22,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "../common.h" +#include "common.h" #include "../dsputil.h" #include "mmx.h" @@ -86,7 +86,7 @@ static inline void idct_row (int16_t * row, int offset, c5, -c1, c3, -c1, \ c7, c3, c7, -c5 } -static inline void mmxext_row_head (int16_t * row, int offset, int16_t * table) +static inline void mmxext_row_head (int16_t * row, int offset, const int16_t * table) { movq_m2r (*(row+offset), mm2); // mm2 = x6 x4 x2 x0 @@ -102,7 +102,7 @@ static inline void mmxext_row_head (int16_t * row, int offset, int16_t * table) pshufw_r2r (mm2, mm2, 0x4e); // mm2 = x2 x0 x6 x4 } -static inline void mmxext_row (int16_t * table, int32_t * rounder) +static inline void mmxext_row (const int16_t * table, const int32_t * rounder) { movq_m2r (*(table+8), mm1); // mm1 = -C5 -C1 C3 C1 pmaddwd_r2r (mm2, mm4); // mm4 = C4*x0+C6*x2 C4*x4+C6*x6 @@ -160,7 +160,7 @@ static inline void mmxext_row_tail (int16_t * row, int store) } static inline void mmxext_row_mid (int16_t * row, int store, - int offset, int16_t * table) + int offset, const int16_t * table) { movq_m2r (*(row+offset), mm2); // mm2 = x6 x4 x2 x0 psrad_i2r (ROW_SHIFT, mm0); // mm0 = y3 y2 @@ -198,7 +198,7 @@ static inline void mmxext_row_mid (int16_t * row, int store, c5, -c1, c7, -c5, \ c7, c3, c3, -c1 } -static inline void mmx_row_head (int16_t * row, int offset, int16_t * table) +static inline void mmx_row_head (int16_t * row, int offset, const int16_t * table) { movq_m2r (*(row+offset), mm2); // mm2 = x6 x4 x2 x0 @@ -217,7 +217,7 @@ static inline void mmx_row_head (int16_t * row, int offset, int16_t * table) punpckhdq_r2r (mm2, mm2); // mm2 = x6 x4 x6 x4 } -static inline void mmx_row (int16_t * table, int32_t * rounder) +static inline void mmx_row (const int16_t * table, const int32_t * rounder) { pmaddwd_r2r (mm2, mm4); // mm4 = -C4*x4-C2*x6 C4*x4+C6*x6 punpckldq_r2r (mm5, mm5); // mm5 = x3 x1 x3 x1 @@ -281,7 +281,7 @@ static inline void mmx_row_tail (int16_t * row, int store) } static inline void mmx_row_mid (int16_t * row, int store, - int offset, int16_t * table) + int offset, const int16_t * table) { movq_m2r (*(row+offset), mm2); // mm2 = x6 x4 x2 x0 psrad_i2r (ROW_SHIFT, mm0); // mm0 = y3 y2 @@ -395,10 +395,10 @@ static inline void idct_col (int16_t * col, int offset) #define T3 43790 #define C4 23170 - static short _T1[] ATTR_ALIGN(8) = {T1,T1,T1,T1}; - static short _T2[] ATTR_ALIGN(8) = {T2,T2,T2,T2}; - static short _T3[] ATTR_ALIGN(8) = {T3,T3,T3,T3}; - static short _C4[] ATTR_ALIGN(8) = {C4,C4,C4,C4}; + static const short _T1[] ATTR_ALIGN(8) = {T1,T1,T1,T1}; + static const short _T2[] ATTR_ALIGN(8) = {T2,T2,T2,T2}; + static const short _T3[] ATTR_ALIGN(8) = {T3,T3,T3,T3}; + static const short _C4[] ATTR_ALIGN(8) = {C4,C4,C4,C4}; /* column code adapted from peter gubanov */ /* http://www.elecard.com/peter/idct.shtml */ @@ -536,20 +536,20 @@ static inline void idct_col (int16_t * col, int offset) #undef C4 } -static int32_t rounder0[] ATTR_ALIGN(8) = +static const int32_t rounder0[] ATTR_ALIGN(8) = rounder ((1 << (COL_SHIFT - 1)) - 0.5); -static int32_t rounder4[] ATTR_ALIGN(8) = rounder (0); -static int32_t rounder1[] ATTR_ALIGN(8) = +static const int32_t rounder4[] ATTR_ALIGN(8) = rounder (0); +static const int32_t rounder1[] ATTR_ALIGN(8) = rounder (1.25683487303); /* C1*(C1/C4+C1+C7)/2 */ -static int32_t rounder7[] ATTR_ALIGN(8) = +static const int32_t rounder7[] ATTR_ALIGN(8) = rounder (-0.25); /* C1*(C7/C4+C7-C1)/2 */ -static int32_t rounder2[] ATTR_ALIGN(8) = +static const int32_t rounder2[] ATTR_ALIGN(8) = rounder (0.60355339059); /* C2 * (C6+C2)/2 */ -static int32_t rounder6[] ATTR_ALIGN(8) = +static const int32_t rounder6[] ATTR_ALIGN(8) = rounder (-0.25); /* C2 * (C6-C2)/2 */ -static int32_t rounder3[] ATTR_ALIGN(8) = +static const int32_t rounder3[] ATTR_ALIGN(8) = rounder (0.087788325588); /* C3*(-C3/C4+C3+C5)/2 */ -static int32_t rounder5[] ATTR_ALIGN(8) = +static const int32_t rounder5[] ATTR_ALIGN(8) = rounder (-0.441341716183); /* C3*(-C5/C4+C5-C3)/2 */ #undef COL_SHIFT @@ -558,13 +558,13 @@ static int32_t rounder5[] ATTR_ALIGN(8) = #define declare_idct(idct,table,idct_row_head,idct_row,idct_row_tail,idct_row_mid) \ void idct (int16_t * block) \ { \ - static int16_t table04[] ATTR_ALIGN(16) = \ + static const int16_t table04[] ATTR_ALIGN(16) = \ table (22725, 21407, 19266, 16384, 12873, 8867, 4520); \ - static int16_t table17[] ATTR_ALIGN(16) = \ + static const int16_t table17[] ATTR_ALIGN(16) = \ table (31521, 29692, 26722, 22725, 17855, 12299, 6270); \ - static int16_t table26[] ATTR_ALIGN(16) = \ + static const int16_t table26[] ATTR_ALIGN(16) = \ table (29692, 27969, 25172, 21407, 16819, 11585, 5906); \ - static int16_t table35[] ATTR_ALIGN(16) = \ + static const int16_t table35[] ATTR_ALIGN(16) = \ table (26722, 25172, 22654, 19266, 15137, 10426, 5315); \ \ idct_row_head (block, 0*8, table04); \ diff --git a/src/libffmpeg/libavcodec/i386/idct_mmx_xvid.c b/src/libffmpeg/libavcodec/i386/idct_mmx_xvid.c new file mode 100644 index 000000000..aff57e3fa --- /dev/null +++ b/src/libffmpeg/libavcodec/i386/idct_mmx_xvid.c @@ -0,0 +1,533 @@ +///**************************************************************************** +// * +// * XVID MPEG-4 VIDEO CODEC +// * - MMX and XMM forward discrete cosine transform - +// * +// * Copyright(C) 2001 Peter Ross <pross@xvid.org> +// * +// * This program is free software; you can redistribute it and/or modify it +// * under the terms of the GNU General Public License as published by +// * the Free Software Foundation; either version 2 of the License, or +// * (at your option) any later version. +// * +// * This program 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 General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program; if not, write to the Free Software +// * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// * +// * $Id: idct_mmx_xvid.c,v 1.1 2005/10/23 02:11:44 miguelfreitas Exp $ +// * +// ***************************************************************************/ + +// **************************************************************************** +// +// Originally provided by Intel at AP-922 +// http://developer.intel.com/vtune/cbts/strmsimd/922down.htm +// (See more app notes at http://developer.intel.com/vtune/cbts/strmsimd/appnotes.htm) +// but in a limited edition. +// New macro implements a column part for precise iDCT +// The routine precision now satisfies IEEE standard 1180-1990. +// +// Copyright(C) 2000-2001 Peter Gubanov <peter@elecard.net.ru> +// Rounding trick Copyright(C) 2000 Michel Lespinasse <walken@zoy.org> +// +// http://www.elecard.com/peter/idct.html +// http://www.linuxvideo.org/mpeg2dec/ +// +// ***************************************************************************/ +// +// These examples contain code fragments for first stage iDCT 8x8 +// (for rows) and first stage DCT 8x8 (for columns) +// + +// conversion to gcc syntax by michael niedermayer + + +#include <inttypes.h> +#include "../avcodec.h" + +//============================================================================= +// Macros and other preprocessor constants +//============================================================================= + +#define BITS_INV_ACC 5 // 4 or 5 for IEEE +#define SHIFT_INV_ROW (16 - BITS_INV_ACC) //11 +#define SHIFT_INV_COL (1 + BITS_INV_ACC) //6 +#define RND_INV_ROW (1024 * (6 - BITS_INV_ACC)) +#define RND_INV_COL (16 * (BITS_INV_ACC - 3)) +#define RND_INV_CORR (RND_INV_COL - 1) + +#define BITS_FRW_ACC 3 // 2 or 3 for accuracy +#define SHIFT_FRW_COL BITS_FRW_ACC +#define SHIFT_FRW_ROW (BITS_FRW_ACC + 17) +#define RND_FRW_ROW (262144*(BITS_FRW_ACC - 1)) + + +//----------------------------------------------------------------------------- +// Various memory constants (trigonometric values or rounding values) +//----------------------------------------------------------------------------- + + +static const int16_t tg_1_16[4*4] attribute_used __attribute__ ((aligned(8))) = { + 13036,13036,13036,13036, // tg * (2<<16) + 0.5 + 27146,27146,27146,27146, // tg * (2<<16) + 0.5 + -21746,-21746,-21746,-21746, // tg * (2<<16) + 0.5 + 23170,23170,23170,23170}; // cos * (2<<15) + 0.5 + +static const int32_t rounder_0[2*8] attribute_used __attribute__ ((aligned(8))) = { + 65536,65536, + 3597,3597, + 2260,2260, + 1203,1203, + 0,0, + 120,120, + 512,512, + 512,512}; + +//----------------------------------------------------------------------------- +// +// The first stage iDCT 8x8 - inverse DCTs of rows +// +//----------------------------------------------------------------------------- +// The 8-point inverse DCT direct algorithm +//----------------------------------------------------------------------------- +// +// static const short w[32] = { +// FIX(cos_4_16), FIX(cos_2_16), FIX(cos_4_16), FIX(cos_6_16), +// FIX(cos_4_16), FIX(cos_6_16), -FIX(cos_4_16), -FIX(cos_2_16), +// FIX(cos_4_16), -FIX(cos_6_16), -FIX(cos_4_16), FIX(cos_2_16), +// FIX(cos_4_16), -FIX(cos_2_16), FIX(cos_4_16), -FIX(cos_6_16), +// FIX(cos_1_16), FIX(cos_3_16), FIX(cos_5_16), FIX(cos_7_16), +// FIX(cos_3_16), -FIX(cos_7_16), -FIX(cos_1_16), -FIX(cos_5_16), +// FIX(cos_5_16), -FIX(cos_1_16), FIX(cos_7_16), FIX(cos_3_16), +// FIX(cos_7_16), -FIX(cos_5_16), FIX(cos_3_16), -FIX(cos_1_16) }; +// +// #define DCT_8_INV_ROW(x, y) +// { +// int a0, a1, a2, a3, b0, b1, b2, b3; +// +// a0 =x[0]*w[0]+x[2]*w[1]+x[4]*w[2]+x[6]*w[3]; +// a1 =x[0]*w[4]+x[2]*w[5]+x[4]*w[6]+x[6]*w[7]; +// a2 = x[0] * w[ 8] + x[2] * w[ 9] + x[4] * w[10] + x[6] * w[11]; +// a3 = x[0] * w[12] + x[2] * w[13] + x[4] * w[14] + x[6] * w[15]; +// b0 = x[1] * w[16] + x[3] * w[17] + x[5] * w[18] + x[7] * w[19]; +// b1 = x[1] * w[20] + x[3] * w[21] + x[5] * w[22] + x[7] * w[23]; +// b2 = x[1] * w[24] + x[3] * w[25] + x[5] * w[26] + x[7] * w[27]; +// b3 = x[1] * w[28] + x[3] * w[29] + x[5] * w[30] + x[7] * w[31]; +// +// y[0] = SHIFT_ROUND ( a0 + b0 ); +// y[1] = SHIFT_ROUND ( a1 + b1 ); +// y[2] = SHIFT_ROUND ( a2 + b2 ); +// y[3] = SHIFT_ROUND ( a3 + b3 ); +// y[4] = SHIFT_ROUND ( a3 - b3 ); +// y[5] = SHIFT_ROUND ( a2 - b2 ); +// y[6] = SHIFT_ROUND ( a1 - b1 ); +// y[7] = SHIFT_ROUND ( a0 - b0 ); +// } +// +//----------------------------------------------------------------------------- +// +// In this implementation the outputs of the iDCT-1D are multiplied +// for rows 0,4 - by cos_4_16, +// for rows 1,7 - by cos_1_16, +// for rows 2,6 - by cos_2_16, +// for rows 3,5 - by cos_3_16 +// and are shifted to the left for better accuracy +// +// For the constants used, +// FIX(float_const) = (short) (float_const * (1<<15) + 0.5) +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Tables for mmx processors +//----------------------------------------------------------------------------- + +// Table for rows 0,4 - constants are multiplied by cos_4_16 +static const int16_t tab_i_04_mmx[32*4] attribute_used __attribute__ ((aligned(8))) = { + 16384,16384,16384,-16384, // movq-> w06 w04 w02 w00 + 21407,8867,8867,-21407, // w07 w05 w03 w01 + 16384,-16384,16384,16384, // w14 w12 w10 w08 + -8867,21407,-21407,-8867, // w15 w13 w11 w09 + 22725,12873,19266,-22725, // w22 w20 w18 w16 + 19266,4520,-4520,-12873, // w23 w21 w19 w17 + 12873,4520,4520,19266, // w30 w28 w26 w24 + -22725,19266,-12873,-22725, // w31 w29 w27 w25 +// Table for rows 1,7 - constants are multiplied by cos_1_16 + 22725,22725,22725,-22725, // movq-> w06 w04 w02 w00 + 29692,12299,12299,-29692, // w07 w05 w03 w01 + 22725,-22725,22725,22725, // w14 w12 w10 w08 + -12299,29692,-29692,-12299, // w15 w13 w11 w09 + 31521,17855,26722,-31521, // w22 w20 w18 w16 + 26722,6270,-6270,-17855, // w23 w21 w19 w17 + 17855,6270,6270,26722, // w30 w28 w26 w24 + -31521,26722,-17855,-31521, // w31 w29 w27 w25 +// Table for rows 2,6 - constants are multiplied by cos_2_16 + 21407,21407,21407,-21407, // movq-> w06 w04 w02 w00 + 27969,11585,11585,-27969, // w07 w05 w03 w01 + 21407,-21407,21407,21407, // w14 w12 w10 w08 + -11585,27969,-27969,-11585, // w15 w13 w11 w09 + 29692,16819,25172,-29692, // w22 w20 w18 w16 + 25172,5906,-5906,-16819, // w23 w21 w19 w17 + 16819,5906,5906,25172, // w30 w28 w26 w24 + -29692,25172,-16819,-29692, // w31 w29 w27 w25 +// Table for rows 3,5 - constants are multiplied by cos_3_16 + 19266,19266,19266,-19266, // movq-> w06 w04 w02 w00 + 25172,10426,10426,-25172, // w07 w05 w03 w01 + 19266,-19266,19266,19266, // w14 w12 w10 w08 + -10426,25172,-25172,-10426, // w15 w13 w11 w09 + 26722,15137,22654,-26722, // w22 w20 w18 w16 + 22654,5315,-5315,-15137, // w23 w21 w19 w17 + 15137,5315,5315,22654, // w30 w28 w26 w24 + -26722,22654,-15137,-26722, // w31 w29 w27 w25 +}; +//----------------------------------------------------------------------------- +// Tables for xmm processors +//----------------------------------------------------------------------------- + +// %3 for rows 0,4 - constants are multiplied by cos_4_16 +static const int16_t tab_i_04_xmm[32*4] attribute_used __attribute__ ((aligned(8))) = { + 16384,21407,16384,8867, // movq-> w05 w04 w01 w00 + 16384,8867,-16384,-21407, // w07 w06 w03 w02 + 16384,-8867,16384,-21407, // w13 w12 w09 w08 + -16384,21407,16384,-8867, // w15 w14 w11 w10 + 22725,19266,19266,-4520, // w21 w20 w17 w16 + 12873,4520,-22725,-12873, // w23 w22 w19 w18 + 12873,-22725,4520,-12873, // w29 w28 w25 w24 + 4520,19266,19266,-22725, // w31 w30 w27 w26 +// %3 for rows 1,7 - constants are multiplied by cos_1_16 + 22725,29692,22725,12299, // movq-> w05 w04 w01 w00 + 22725,12299,-22725,-29692, // w07 w06 w03 w02 + 22725,-12299,22725,-29692, // w13 w12 w09 w08 + -22725,29692,22725,-12299, // w15 w14 w11 w10 + 31521,26722,26722,-6270, // w21 w20 w17 w16 + 17855,6270,-31521,-17855, // w23 w22 w19 w18 + 17855,-31521,6270,-17855, // w29 w28 w25 w24 + 6270,26722,26722,-31521, // w31 w30 w27 w26 +// %3 for rows 2,6 - constants are multiplied by cos_2_16 + 21407,27969,21407,11585, // movq-> w05 w04 w01 w00 + 21407,11585,-21407,-27969, // w07 w06 w03 w02 + 21407,-11585,21407,-27969, // w13 w12 w09 w08 + -21407,27969,21407,-11585, // w15 w14 w11 w10 + 29692,25172,25172,-5906, // w21 w20 w17 w16 + 16819,5906,-29692,-16819, // w23 w22 w19 w18 + 16819,-29692,5906,-16819, // w29 w28 w25 w24 + 5906,25172,25172,-29692, // w31 w30 w27 w26 +// %3 for rows 3,5 - constants are multiplied by cos_3_16 + 19266,25172,19266,10426, // movq-> w05 w04 w01 w00 + 19266,10426,-19266,-25172, // w07 w06 w03 w02 + 19266,-10426,19266,-25172, // w13 w12 w09 w08 + -19266,25172,19266,-10426, // w15 w14 w11 w10 + 26722,22654,22654,-5315, // w21 w20 w17 w16 + 15137,5315,-26722,-15137, // w23 w22 w19 w18 + 15137,-26722,5315,-15137, // w29 w28 w25 w24 + 5315,22654,22654,-26722, // w31 w30 w27 w26 +}; +//============================================================================= +// Helper macros for the code +//============================================================================= + +//----------------------------------------------------------------------------- +// DCT_8_INV_ROW_MMX( INP, OUT, TABLE, ROUNDER +//----------------------------------------------------------------------------- + +#define DCT_8_INV_ROW_MMX(A1,A2,A3,A4)\ + "movq " #A1 ",%%mm0 \n\t"/* 0 ; x3 x2 x1 x0*/\ + "movq 8+" #A1 ",%%mm1 \n\t"/* 1 ; x7 x6 x5 x4*/\ + "movq %%mm0,%%mm2 \n\t"/* 2 ; x3 x2 x1 x0*/\ + "movq " #A3 ",%%mm3 \n\t"/* 3 ; w06 w04 w02 w00*/\ + "punpcklwd %%mm1,%%mm0 \n\t"/* x5 x1 x4 x0*/\ + "movq %%mm0,%%mm5 \n\t"/* 5 ; x5 x1 x4 x0*/\ + "punpckldq %%mm0,%%mm0 \n\t"/* x4 x0 x4 x0*/\ + "movq 8+" #A3 ",%%mm4 \n\t"/* 4 ; w07 w05 w03 w01*/\ + "punpckhwd %%mm1,%%mm2 \n\t"/* 1 ; x7 x3 x6 x2*/\ + "pmaddwd %%mm0,%%mm3 \n\t"/* x4*w06+x0*w04 x4*w02+x0*w00*/\ + "movq %%mm2,%%mm6 \n\t"/* 6 ; x7 x3 x6 x2*/\ + "movq 32+" #A3 ",%%mm1 \n\t"/* 1 ; w22 w20 w18 w16*/\ + "punpckldq %%mm2,%%mm2 \n\t"/* x6 x2 x6 x2*/\ + "pmaddwd %%mm2,%%mm4 \n\t"/* x6*w07+x2*w05 x6*w03+x2*w01*/\ + "punpckhdq %%mm5,%%mm5 \n\t"/* x5 x1 x5 x1*/\ + "pmaddwd 16+" #A3 ",%%mm0 \n\t"/* x4*w14+x0*w12 x4*w10+x0*w08*/\ + "punpckhdq %%mm6,%%mm6 \n\t"/* x7 x3 x7 x3*/\ + "movq 40+" #A3 ",%%mm7 \n\t"/* 7 ; w23 w21 w19 w17*/\ + "pmaddwd %%mm5,%%mm1 \n\t"/* x5*w22+x1*w20 x5*w18+x1*w16*/\ + "paddd " #A4 ",%%mm3 \n\t"/* +%4*/\ + "pmaddwd %%mm6,%%mm7 \n\t"/* x7*w23+x3*w21 x7*w19+x3*w17*/\ + "pmaddwd 24+" #A3 ",%%mm2 \n\t"/* x6*w15+x2*w13 x6*w11+x2*w09*/\ + "paddd %%mm4,%%mm3 \n\t"/* 4 ; a1=sum(even1) a0=sum(even0)*/\ + "pmaddwd 48+" #A3 ",%%mm5 \n\t"/* x5*w30+x1*w28 x5*w26+x1*w24*/\ + "movq %%mm3,%%mm4 \n\t"/* 4 ; a1 a0*/\ + "pmaddwd 56+" #A3 ",%%mm6 \n\t"/* x7*w31+x3*w29 x7*w27+x3*w25*/\ + "paddd %%mm7,%%mm1 \n\t"/* 7 ; b1=sum(odd1) b0=sum(odd0)*/\ + "paddd " #A4 ",%%mm0 \n\t"/* +%4*/\ + "psubd %%mm1,%%mm3 \n\t"/* a1-b1 a0-b0*/\ + "psrad $11,%%mm3 \n\t"/* y6=a1-b1 y7=a0-b0*/\ + "paddd %%mm4,%%mm1 \n\t"/* 4 ; a1+b1 a0+b0*/\ + "paddd %%mm2,%%mm0 \n\t"/* 2 ; a3=sum(even3) a2=sum(even2)*/\ + "psrad $11,%%mm1 \n\t"/* y1=a1+b1 y0=a0+b0*/\ + "paddd %%mm6,%%mm5 \n\t"/* 6 ; b3=sum(odd3) b2=sum(odd2)*/\ + "movq %%mm0,%%mm4 \n\t"/* 4 ; a3 a2*/\ + "paddd %%mm5,%%mm0 \n\t"/* a3+b3 a2+b2*/\ + "psubd %%mm5,%%mm4 \n\t"/* 5 ; a3-b3 a2-b2*/\ + "psrad $11,%%mm0 \n\t"/* y3=a3+b3 y2=a2+b2*/\ + "psrad $11,%%mm4 \n\t"/* y4=a3-b3 y5=a2-b2*/\ + "packssdw %%mm0,%%mm1 \n\t"/* 0 ; y3 y2 y1 y0*/\ + "packssdw %%mm3,%%mm4 \n\t"/* 3 ; y6 y7 y4 y5*/\ + "movq %%mm4,%%mm7 \n\t"/* 7 ; y6 y7 y4 y5*/\ + "psrld $16,%%mm4 \n\t"/* 0 y6 0 y4*/\ + "pslld $16,%%mm7 \n\t"/* y7 0 y5 0*/\ + "movq %%mm1," #A2 " \n\t"/* 1 ; save y3 y2 y1 y0*/\ + "por %%mm4,%%mm7 \n\t"/* 4 ; y7 y6 y5 y4*/\ + "movq %%mm7,8 +" #A2 "\n\t"/* 7 ; save y7 y6 y5 y4*/\ + + +//----------------------------------------------------------------------------- +// DCT_8_INV_ROW_XMM( INP, OUT, TABLE, ROUNDER +//----------------------------------------------------------------------------- + +#define DCT_8_INV_ROW_XMM(A1,A2,A3,A4)\ + "movq " #A1 ",%%mm0 \n\t"/* 0 ; x3 x2 x1 x0*/\ + "movq 8+" #A1 ",%%mm1 \n\t"/* 1 ; x7 x6 x5 x4*/\ + "movq %%mm0,%%mm2 \n\t"/* 2 ; x3 x2 x1 x0*/\ + "movq " #A3 ",%%mm3 \n\t"/* 3 ; w05 w04 w01 w00*/\ + "pshufw $0b10001000,%%mm0,%%mm0 \n\t"/* x2 x0 x2 x0*/\ + "movq 8+" #A3 ",%%mm4 \n\t"/* 4 ; w07 w06 w03 w02*/\ + "movq %%mm1,%%mm5 \n\t"/* 5 ; x7 x6 x5 x4*/\ + "pmaddwd %%mm0,%%mm3 \n\t"/* x2*w05+x0*w04 x2*w01+x0*w00*/\ + "movq 32+" #A3 ",%%mm6 \n\t"/* 6 ; w21 w20 w17 w16*/\ + "pshufw $0b10001000,%%mm1,%%mm1 \n\t"/* x6 x4 x6 x4*/\ + "pmaddwd %%mm1,%%mm4 \n\t"/* x6*w07+x4*w06 x6*w03+x4*w02*/\ + "movq 40+" #A3 ",%%mm7 \n\t"/* 7 ; w23 w22 w19 w18*/\ + "pshufw $0b11011101,%%mm2,%%mm2 \n\t"/* x3 x1 x3 x1*/\ + "pmaddwd %%mm2,%%mm6 \n\t"/* x3*w21+x1*w20 x3*w17+x1*w16*/\ + "pshufw $0b11011101,%%mm5,%%mm5 \n\t"/* x7 x5 x7 x5*/\ + "pmaddwd %%mm5,%%mm7 \n\t"/* x7*w23+x5*w22 x7*w19+x5*w18*/\ + "paddd " #A4 ",%%mm3 \n\t"/* +%4*/\ + "pmaddwd 16+" #A3 ",%%mm0 \n\t"/* x2*w13+x0*w12 x2*w09+x0*w08*/\ + "paddd %%mm4,%%mm3 \n\t"/* 4 ; a1=sum(even1) a0=sum(even0)*/\ + "pmaddwd 24+" #A3 ",%%mm1 \n\t"/* x6*w15+x4*w14 x6*w11+x4*w10*/\ + "movq %%mm3,%%mm4 \n\t"/* 4 ; a1 a0*/\ + "pmaddwd 48+" #A3 ",%%mm2 \n\t"/* x3*w29+x1*w28 x3*w25+x1*w24*/\ + "paddd %%mm7,%%mm6 \n\t"/* 7 ; b1=sum(odd1) b0=sum(odd0)*/\ + "pmaddwd 56+" #A3 ",%%mm5 \n\t"/* x7*w31+x5*w30 x7*w27+x5*w26*/\ + "paddd %%mm6,%%mm3 \n\t"/* a1+b1 a0+b0*/\ + "paddd " #A4 ",%%mm0 \n\t"/* +%4*/\ + "psrad $11,%%mm3 \n\t"/* y1=a1+b1 y0=a0+b0*/\ + "paddd %%mm1,%%mm0 \n\t"/* 1 ; a3=sum(even3) a2=sum(even2)*/\ + "psubd %%mm6,%%mm4 \n\t"/* 6 ; a1-b1 a0-b0*/\ + "movq %%mm0,%%mm7 \n\t"/* 7 ; a3 a2*/\ + "paddd %%mm5,%%mm2 \n\t"/* 5 ; b3=sum(odd3) b2=sum(odd2)*/\ + "paddd %%mm2,%%mm0 \n\t"/* a3+b3 a2+b2*/\ + "psrad $11,%%mm4 \n\t"/* y6=a1-b1 y7=a0-b0*/\ + "psubd %%mm2,%%mm7 \n\t"/* 2 ; a3-b3 a2-b2*/\ + "psrad $11,%%mm0 \n\t"/* y3=a3+b3 y2=a2+b2*/\ + "psrad $11,%%mm7 \n\t"/* y4=a3-b3 y5=a2-b2*/\ + "packssdw %%mm0,%%mm3 \n\t"/* 0 ; y3 y2 y1 y0*/\ + "packssdw %%mm4,%%mm7 \n\t"/* 4 ; y6 y7 y4 y5*/\ + "movq %%mm3, " #A2 " \n\t"/* 3 ; save y3 y2 y1 y0*/\ + "pshufw $0b10110001,%%mm7,%%mm7 \n\t"/* y7 y6 y5 y4*/\ + "movq %%mm7,8 +" #A2 "\n\t"/* 7 ; save y7 y6 y5 y4*/\ + + +//----------------------------------------------------------------------------- +// +// The first stage DCT 8x8 - forward DCTs of columns +// +// The %2puts are multiplied +// for rows 0,4 - on cos_4_16, +// for rows 1,7 - on cos_1_16, +// for rows 2,6 - on cos_2_16, +// for rows 3,5 - on cos_3_16 +// and are shifted to the left for rise of accuracy +// +//----------------------------------------------------------------------------- +// +// The 8-point scaled forward DCT algorithm (26a8m) +// +//----------------------------------------------------------------------------- +// +// #define DCT_8_FRW_COL(x, y) +//{ +// short t0, t1, t2, t3, t4, t5, t6, t7; +// short tp03, tm03, tp12, tm12, tp65, tm65; +// short tp465, tm465, tp765, tm765; +// +// t0 = LEFT_SHIFT ( x[0] + x[7] ); +// t1 = LEFT_SHIFT ( x[1] + x[6] ); +// t2 = LEFT_SHIFT ( x[2] + x[5] ); +// t3 = LEFT_SHIFT ( x[3] + x[4] ); +// t4 = LEFT_SHIFT ( x[3] - x[4] ); +// t5 = LEFT_SHIFT ( x[2] - x[5] ); +// t6 = LEFT_SHIFT ( x[1] - x[6] ); +// t7 = LEFT_SHIFT ( x[0] - x[7] ); +// +// tp03 = t0 + t3; +// tm03 = t0 - t3; +// tp12 = t1 + t2; +// tm12 = t1 - t2; +// +// y[0] = tp03 + tp12; +// y[4] = tp03 - tp12; +// +// y[2] = tm03 + tm12 * tg_2_16; +// y[6] = tm03 * tg_2_16 - tm12; +// +// tp65 =(t6 +t5 )*cos_4_16; +// tm65 =(t6 -t5 )*cos_4_16; +// +// tp765 = t7 + tp65; +// tm765 = t7 - tp65; +// tp465 = t4 + tm65; +// tm465 = t4 - tm65; +// +// y[1] = tp765 + tp465 * tg_1_16; +// y[7] = tp765 * tg_1_16 - tp465; +// y[5] = tm765 * tg_3_16 + tm465; +// y[3] = tm765 - tm465 * tg_3_16; +//} +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// DCT_8_INV_COL_4 INP,OUT +//----------------------------------------------------------------------------- + +#define DCT_8_INV_COL(A1,A2)\ + "movq 2*8(%3),%%mm0\n\t"\ + "movq 16*3+" #A1 ",%%mm3\n\t"\ + "movq %%mm0,%%mm1 \n\t"/* tg_3_16*/\ + "movq 16*5+" #A1 ",%%mm5\n\t"\ + "pmulhw %%mm3,%%mm0 \n\t"/* x3*(tg_3_16-1)*/\ + "movq (%3),%%mm4\n\t"\ + "pmulhw %%mm5,%%mm1 \n\t"/* x5*(tg_3_16-1)*/\ + "movq 16*7+" #A1 ",%%mm7\n\t"\ + "movq %%mm4,%%mm2 \n\t"/* tg_1_16*/\ + "movq 16*1+" #A1 ",%%mm6\n\t"\ + "pmulhw %%mm7,%%mm4 \n\t"/* x7*tg_1_16*/\ + "paddsw %%mm3,%%mm0 \n\t"/* x3*tg_3_16*/\ + "pmulhw %%mm6,%%mm2 \n\t"/* x1*tg_1_16*/\ + "paddsw %%mm3,%%mm1 \n\t"/* x3+x5*(tg_3_16-1)*/\ + "psubsw %%mm5,%%mm0 \n\t"/* x3*tg_3_16-x5 = tm35*/\ + "movq 3*8(%3),%%mm3\n\t"\ + "paddsw %%mm5,%%mm1 \n\t"/* x3+x5*tg_3_16 = tp35*/\ + "paddsw %%mm6,%%mm4 \n\t"/* x1+tg_1_16*x7 = tp17*/\ + "psubsw %%mm7,%%mm2 \n\t"/* x1*tg_1_16-x7 = tm17*/\ + "movq %%mm4,%%mm5 \n\t"/* tp17*/\ + "movq %%mm2,%%mm6 \n\t"/* tm17*/\ + "paddsw %%mm1,%%mm5 \n\t"/* tp17+tp35 = b0*/\ + "psubsw %%mm0,%%mm6 \n\t"/* tm17-tm35 = b3*/\ + "psubsw %%mm1,%%mm4 \n\t"/* tp17-tp35 = t1*/\ + "paddsw %%mm0,%%mm2 \n\t"/* tm17+tm35 = t2*/\ + "movq 1*8(%3),%%mm7\n\t"\ + "movq %%mm4,%%mm1 \n\t"/* t1*/\ + "movq %%mm5,3*16 +" #A2 "\n\t"/* save b0*/\ + "paddsw %%mm2,%%mm1 \n\t"/* t1+t2*/\ + "movq %%mm6,5*16 +" #A2 "\n\t"/* save b3*/\ + "psubsw %%mm2,%%mm4 \n\t"/* t1-t2*/\ + "movq 2*16+" #A1 ",%%mm5\n\t"\ + "movq %%mm7,%%mm0 \n\t"/* tg_2_16*/\ + "movq 6*16+" #A1 ",%%mm6\n\t"\ + "pmulhw %%mm5,%%mm0 \n\t"/* x2*tg_2_16*/\ + "pmulhw %%mm6,%%mm7 \n\t"/* x6*tg_2_16*/\ + "pmulhw %%mm3,%%mm1 \n\t"/* ocos_4_16*(t1+t2) = b1/2*/\ + "movq 0*16+" #A1 ",%%mm2\n\t"\ + "pmulhw %%mm3,%%mm4 \n\t"/* ocos_4_16*(t1-t2) = b2/2*/\ + "psubsw %%mm6,%%mm0 \n\t"/* t2*tg_2_16-x6 = tm26*/\ + "movq %%mm2,%%mm3 \n\t"/* x0*/\ + "movq 4*16+" #A1 ",%%mm6\n\t"\ + "paddsw %%mm5,%%mm7 \n\t"/* x2+x6*tg_2_16 = tp26*/\ + "paddsw %%mm6,%%mm2 \n\t"/* x0+x4 = tp04*/\ + "psubsw %%mm6,%%mm3 \n\t"/* x0-x4 = tm04*/\ + "movq %%mm2,%%mm5 \n\t"/* tp04*/\ + "movq %%mm3,%%mm6 \n\t"/* tm04*/\ + "psubsw %%mm7,%%mm2 \n\t"/* tp04-tp26 = a3*/\ + "paddsw %%mm0,%%mm3 \n\t"/* tm04+tm26 = a1*/\ + "paddsw %%mm1,%%mm1 \n\t"/* b1*/\ + "paddsw %%mm4,%%mm4 \n\t"/* b2*/\ + "paddsw %%mm7,%%mm5 \n\t"/* tp04+tp26 = a0*/\ + "psubsw %%mm0,%%mm6 \n\t"/* tm04-tm26 = a2*/\ + "movq %%mm3,%%mm7 \n\t"/* a1*/\ + "movq %%mm6,%%mm0 \n\t"/* a2*/\ + "paddsw %%mm1,%%mm3 \n\t"/* a1+b1*/\ + "paddsw %%mm4,%%mm6 \n\t"/* a2+b2*/\ + "psraw $6,%%mm3 \n\t"/* dst1*/\ + "psubsw %%mm1,%%mm7 \n\t"/* a1-b1*/\ + "psraw $6,%%mm6 \n\t"/* dst2*/\ + "psubsw %%mm4,%%mm0 \n\t"/* a2-b2*/\ + "movq 3*16+" #A2 ",%%mm1 \n\t"/* load b0*/\ + "psraw $6,%%mm7 \n\t"/* dst6*/\ + "movq %%mm5,%%mm4 \n\t"/* a0*/\ + "psraw $6,%%mm0 \n\t"/* dst5*/\ + "movq %%mm3,1*16+" #A2 "\n\t"\ + "paddsw %%mm1,%%mm5 \n\t"/* a0+b0*/\ + "movq %%mm6,2*16+" #A2 "\n\t"\ + "psubsw %%mm1,%%mm4 \n\t"/* a0-b0*/\ + "movq 5*16+" #A2 ",%%mm3 \n\t"/* load b3*/\ + "psraw $6,%%mm5 \n\t"/* dst0*/\ + "movq %%mm2,%%mm6 \n\t"/* a3*/\ + "psraw $6,%%mm4 \n\t"/* dst7*/\ + "movq %%mm0,5*16+" #A2 "\n\t"\ + "paddsw %%mm3,%%mm2 \n\t"/* a3+b3*/\ + "movq %%mm7,6*16+" #A2 "\n\t"\ + "psubsw %%mm3,%%mm6 \n\t"/* a3-b3*/\ + "movq %%mm5,0*16+" #A2 "\n\t"\ + "psraw $6,%%mm2 \n\t"/* dst3*/\ + "movq %%mm4,7*16+" #A2 "\n\t"\ + "psraw $6,%%mm6 \n\t"/* dst4*/\ + "movq %%mm2,3*16+" #A2 "\n\t"\ + "movq %%mm6,4*16+" #A2 "\n\t" + +//============================================================================= +// Code +//============================================================================= + +//----------------------------------------------------------------------------- +// void idct_mmx(uint16_t block[64]); +//----------------------------------------------------------------------------- + + +void ff_idct_xvid_mmx(short *block){ +asm volatile( + //# Process each row + DCT_8_INV_ROW_MMX(0*16(%0), 0*16(%0), 64*0(%2), 8*0(%1)) + DCT_8_INV_ROW_MMX(1*16(%0), 1*16(%0), 64*1(%2), 8*1(%1)) + DCT_8_INV_ROW_MMX(2*16(%0), 2*16(%0), 64*2(%2), 8*2(%1)) + DCT_8_INV_ROW_MMX(3*16(%0), 3*16(%0), 64*3(%2), 8*3(%1)) + DCT_8_INV_ROW_MMX(4*16(%0), 4*16(%0), 64*0(%2), 8*4(%1)) + DCT_8_INV_ROW_MMX(5*16(%0), 5*16(%0), 64*3(%2), 8*5(%1)) + DCT_8_INV_ROW_MMX(6*16(%0), 6*16(%0), 64*2(%2), 8*6(%1)) + DCT_8_INV_ROW_MMX(7*16(%0), 7*16(%0), 64*1(%2), 8*7(%1)) + + //# Process the columns (4 at a time) + DCT_8_INV_COL(0(%0), 0(%0)) + DCT_8_INV_COL(8(%0), 8(%0)) + :: "r"(block), "r"(rounder_0), "r"(tab_i_04_mmx), "r"(tg_1_16)); +} + +//----------------------------------------------------------------------------- +// void idct_xmm(uint16_t block[64]); +//----------------------------------------------------------------------------- + + +void ff_idct_xvid_mmx2(short *block){ +asm volatile( + //# Process each row + DCT_8_INV_ROW_XMM(0*16(%0), 0*16(%0), 64*0(%2), 8*0(%1)) + DCT_8_INV_ROW_XMM(1*16(%0), 1*16(%0), 64*1(%2), 8*1(%1)) + DCT_8_INV_ROW_XMM(2*16(%0), 2*16(%0), 64*2(%2), 8*2(%1)) + DCT_8_INV_ROW_XMM(3*16(%0), 3*16(%0), 64*3(%2), 8*3(%1)) + DCT_8_INV_ROW_XMM(4*16(%0), 4*16(%0), 64*0(%2), 8*4(%1)) + DCT_8_INV_ROW_XMM(5*16(%0), 5*16(%0), 64*3(%2), 8*5(%1)) + DCT_8_INV_ROW_XMM(6*16(%0), 6*16(%0), 64*2(%2), 8*6(%1)) + DCT_8_INV_ROW_XMM(7*16(%0), 7*16(%0), 64*1(%2), 8*7(%1)) + + //# Process the columns (4 at a time) + DCT_8_INV_COL(0(%0), 0(%0)) + DCT_8_INV_COL(8(%0), 8(%0)) + :: "r"(block), "r"(rounder_0), "r"(tab_i_04_xmm), "r"(tg_1_16)); +} + diff --git a/src/libffmpeg/libavcodec/i386/mpegvideo_mmx_template.c b/src/libffmpeg/libavcodec/i386/mpegvideo_mmx_template.c index c9354dc1b..93f156ee5 100644 --- a/src/libffmpeg/libavcodec/i386/mpegvideo_mmx_template.c +++ b/src/libffmpeg/libavcodec/i386/mpegvideo_mmx_template.c @@ -22,7 +22,11 @@ #ifdef HAVE_MMX2 #define SPREADW(a) "pshufw $0, " #a ", " #a " \n\t" #define PMAXW(a,b) "pmaxsw " #a ", " #b " \n\t" - +#define PMAX(a,b) \ + "pshufw $0x0E," #a ", " #b " \n\t"\ + PMAXW(b, a)\ + "pshufw $0x01," #a ", " #b " \n\t"\ + PMAXW(b, a) #else #define SPREADW(a) \ "punpcklwd " #a ", " #a " \n\t"\ @@ -30,6 +34,14 @@ #define PMAXW(a,b) \ "psubusw " #a ", " #b " \n\t"\ "paddw " #a ", " #b " \n\t" +#define PMAX(a,b) \ + "movq " #a ", " #b " \n\t"\ + "psrlq $32, " #a " \n\t"\ + PMAXW(b, a)\ + "movq " #a ", " #b " \n\t"\ + "psrlq $16, " #a " \n\t"\ + PMAXW(b, a) + #endif static int RENAME(dct_quantize)(MpegEncContext *s, @@ -119,12 +131,7 @@ static int RENAME(dct_quantize)(MpegEncContext *s, PMAXW(%%mm0, %%mm3) "add $8, %%"REG_a" \n\t" " js 1b \n\t" - "movq %%mm3, %%mm0 \n\t" - "psrlq $32, %%mm3 \n\t" - PMAXW(%%mm0, %%mm3) - "movq %%mm3, %%mm0 \n\t" - "psrlq $16, %%mm3 \n\t" - PMAXW(%%mm0, %%mm3) + PMAX(%%mm3, %%mm0) "movd %%mm3, %%"REG_a" \n\t" "movzb %%al, %%"REG_a" \n\t" // last_non_zero_p1 : "+a" (last_non_zero_p1) @@ -170,12 +177,7 @@ static int RENAME(dct_quantize)(MpegEncContext *s, PMAXW(%%mm0, %%mm3) "add $8, %%"REG_a" \n\t" " js 1b \n\t" - "movq %%mm3, %%mm0 \n\t" - "psrlq $32, %%mm3 \n\t" - PMAXW(%%mm0, %%mm3) - "movq %%mm3, %%mm0 \n\t" - "psrlq $16, %%mm3 \n\t" - PMAXW(%%mm0, %%mm3) + PMAX(%%mm3, %%mm0) "movd %%mm3, %%"REG_a" \n\t" "movzb %%al, %%"REG_a" \n\t" // last_non_zero_p1 : "+a" (last_non_zero_p1) diff --git a/src/libffmpeg/libavcodec/i386/vp3dsp_sse2.c b/src/libffmpeg/libavcodec/i386/vp3dsp_sse2.c index 97937651a..ed17891bf 100644 --- a/src/libffmpeg/libavcodec/i386/vp3dsp_sse2.c +++ b/src/libffmpeg/libavcodec/i386/vp3dsp_sse2.c @@ -799,7 +799,6 @@ static const unsigned short __align16 SSE2_idct_data[7 * 8] = void ff_vp3_idct_sse2(int16_t *input_data) { unsigned char *input_bytes = (unsigned char *)input_data; - unsigned char *dequant_const_bytes = (unsigned char *)SSE2_dequant_const; unsigned char *output_data_bytes = (unsigned char *)input_data; unsigned char *idct_data_bytes = (unsigned char *)SSE2_idct_data; unsigned char *Eight = (unsigned char *)eight_data; diff --git a/src/libffmpeg/libavcodec/imgresample.c b/src/libffmpeg/libavcodec/imgresample.c index 2c7e1120a..d423f388c 100644 --- a/src/libffmpeg/libavcodec/imgresample.c +++ b/src/libffmpeg/libavcodec/imgresample.c @@ -558,6 +558,9 @@ ImgReSampleContext *img_resample_full_init(int owidth, int oheight, { ImgReSampleContext *s; + if (!owidth || !oheight || !iwidth || !iheight) + return NULL; + s = av_mallocz(sizeof(ImgReSampleContext)); if (!s) return NULL; @@ -643,11 +646,13 @@ uint8_t img2[XSIZE1 * YSIZE1]; void save_pgm(const char *filename, uint8_t *img, int xsize, int ysize) { +#undef fprintf FILE *f; f=fopen(filename,"w"); fprintf(f,"P5\n%d %d\n%d\n", xsize, ysize, 255); fwrite(img,1, xsize * ysize,f); fclose(f); +#define fprintf please_use_av_log } static void dump_filter(int16_t *filter) diff --git a/src/libffmpeg/libavcodec/indeo2.c b/src/libffmpeg/libavcodec/indeo2.c index 5063117ca..7001beb12 100644 --- a/src/libffmpeg/libavcodec/indeo2.c +++ b/src/libffmpeg/libavcodec/indeo2.c @@ -141,7 +141,6 @@ static int ir2_decode_frame(AVCodecContext *avctx, AVFrame *picture = data; AVFrame * const p= (AVFrame*)&s->picture; int start; - int i; if(p->data[0]) avctx->release_buffer(avctx, p); diff --git a/src/libffmpeg/libavcodec/mdec.c b/src/libffmpeg/libavcodec/mdec.c index d6e5d044a..afe122cfe 100644 --- a/src/libffmpeg/libavcodec/mdec.c +++ b/src/libffmpeg/libavcodec/mdec.c @@ -239,6 +239,7 @@ static int decode_init(AVCodecContext *avctx){ */ p->qstride= a->mb_width; p->qscale_table= av_mallocz( p->qstride * a->mb_height); + avctx->pix_fmt= PIX_FMT_YUV420P; return 0; } diff --git a/src/libffmpeg/libavcodec/mjpeg.c b/src/libffmpeg/libavcodec/mjpeg.c index 7aaf1e73a..e8bba0619 100644 --- a/src/libffmpeg/libavcodec/mjpeg.c +++ b/src/libffmpeg/libavcodec/mjpeg.c @@ -380,7 +380,7 @@ static void jpeg_put_comments(MpegEncContext *s) /* JFIF header */ put_marker(p, APP0); put_bits(p, 16, 16); - put_string(p, "JFIF", 1); /* this puts the trailing zero-byte too */ + ff_put_string(p, "JFIF", 1); /* this puts the trailing zero-byte too */ put_bits(p, 16, 0x0201); /* v 1.02 */ put_bits(p, 8, 0); /* units type: 0 - aspect ratio */ put_bits(p, 16, s->avctx->sample_aspect_ratio.num); @@ -395,7 +395,7 @@ static void jpeg_put_comments(MpegEncContext *s) flush_put_bits(p); ptr = pbBufPtr(p); put_bits(p, 16, 0); /* patched later */ - put_string(p, LIBAVCODEC_IDENT, 1); + ff_put_string(p, LIBAVCODEC_IDENT, 1); size = strlen(LIBAVCODEC_IDENT)+3; ptr[0] = size >> 8; ptr[1] = size; @@ -408,7 +408,7 @@ static void jpeg_put_comments(MpegEncContext *s) flush_put_bits(p); ptr = pbBufPtr(p); put_bits(p, 16, 0); /* patched later */ - put_string(p, "CS=ITU601", 1); + ff_put_string(p, "CS=ITU601", 1); size = strlen("CS=ITU601")+3; ptr[0] = size >> 8; ptr[1] = size; @@ -882,6 +882,7 @@ static int mjpeg_decode_init(AVCodecContext *avctx) { MJpegDecodeContext *s = avctx->priv_data; MpegEncContext s2; + memset(s, 0, sizeof(MJpegDecodeContext)); s->avctx = avctx; @@ -1573,6 +1574,7 @@ static int mjpeg_decode_dri(MJpegDecodeContext *s) if (get_bits(&s->gb, 16) != 4) return -1; s->restart_interval = get_bits(&s->gb, 16); + s->restart_count = 0; dprintf("restart interval: %d\n", s->restart_interval); return 0; @@ -1892,6 +1894,7 @@ static int mjpeg_decode_frame(AVCodecContext *avctx, switch(start_code) { case SOI: s->restart_interval = 0; + s->restart_count = 0; /* nothing to do on SOI */ break; case DQT: @@ -2000,6 +2003,7 @@ static int mjpegb_decode_frame(AVCodecContext *avctx, read_header: /* reset on every SOI */ s->restart_interval = 0; + s->restart_count = 0; s->mjpb_skiptosod = 0; init_get_bits(&hgb, buf_ptr, /*buf_size*/(buf_end - buf_ptr)*8); @@ -2179,7 +2183,7 @@ static int sp5x_decode_frame(AVCodecContext *avctx, s->picture.reference = 0; if (avctx->get_buffer(avctx, &s->picture) < 0) { - fprintf(stderr, "get_buffer() failed\n"); + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; } diff --git a/src/libffmpeg/libavcodec/motion_est.c b/src/libffmpeg/libavcodec/motion_est.c index 695111c78..c1779491f 100644 --- a/src/libffmpeg/libavcodec/motion_est.c +++ b/src/libffmpeg/libavcodec/motion_est.c @@ -178,7 +178,7 @@ static always_inline int cmp(MpegEncContext *s, const int x, const int y, const }else d= 256*256*256*32; }else{ - int uvdxy; + int uvdxy; /* no, it might not be used uninitialized */ if(dxy){ if(qpel){ c->qpel_put[size][dxy](c->temp, ref[0] + x + y*stride, stride); //FIXME prototype (add h) @@ -444,7 +444,7 @@ static int log_motion_search(MpegEncContext * s, } while (range >= 1); #ifdef DEBUG - fprintf(stderr, "log - MX: %d\tMY: %d\n", mx, my); + av_log(s->avctx, AV_LOG_DEBUG, "log - MX: %d\tMY: %d\n", mx, my); #endif *mx_ptr = mx; *my_ptr = my; @@ -533,7 +533,7 @@ static int phods_motion_search(MpegEncContext * s, } while (range >= 1); #ifdef DEBUG - fprintf(stderr, "phods - MX: %d\tMY: %d\n", mx, my); + av_log(s->avctx, AV_LOG_DEBUG, "phods - MX: %d\tMY: %d\n", mx, my); #endif /* half pixel search */ @@ -1566,7 +1566,6 @@ static inline int check_bidir_mv(MpegEncContext * s, MotionEstContext * const c= &s->me; uint8_t * const mv_penalty= c->mv_penalty[s->f_code] + MAX_MV; // f_code of the prev frame int stride= c->stride; - int uvstride= c->uvstride; uint8_t *dest_y = c->scratchpad; uint8_t *ptr; int dxy; @@ -1894,11 +1893,16 @@ int ff_get_best_fcode(MpegEncContext * s, int16_t (*mv_table)[2], int type) { if(s->me_method>=ME_EPZS){ int score[8]; - int i, y, range= s->avctx->me_range; + int i, y, range= s->avctx->me_range ? s->avctx->me_range : (INT_MAX/2); uint8_t * fcode_tab= s->fcode_tab; int best_fcode=-1; int best_score=-10000000; + if(s->msmpeg4_version) + range= FFMIN(range, 16); + else if(s->codec_id == CODEC_ID_MPEG2VIDEO && s->avctx->strict_std_compliance >= FF_COMPLIANCE_NORMAL) + range= FFMIN(range, 256); + for(i=0; i<8; i++) score[i]= s->mb_num*(8-i); for(y=0; y<s->mb_height; y++){ @@ -1912,11 +1916,9 @@ int ff_get_best_fcode(MpegEncContext * s, int16_t (*mv_table)[2], int type) fcode_tab[my + MAX_MV]); int j; - if(range){ if(mx >= range || mx < -range || my >= range || my < -range) continue; - } for(j=0; j<fcode && j<8; j++){ if(s->pict_type==B_TYPE || s->current_picture.mc_mb_var[xy] < s->current_picture.mb_var[xy]) @@ -1953,9 +1955,10 @@ void ff_fix_long_p_mvs(MpegEncContext * s) int y, range; assert(s->pict_type==P_TYPE); - range = (((s->out_format == FMT_MPEG1) ? 8 : 16) << f_code); - - if(s->msmpeg4_version) range= 16; + range = (((s->out_format == FMT_MPEG1 || s->msmpeg4_version) ? 8 : 16) << f_code); + + assert(range <= 16 || !s->msmpeg4_version); + assert(range <=256 || !(s->codec_id == CODEC_ID_MPEG2VIDEO && s->avctx->strict_std_compliance >= FF_COMPLIANCE_NORMAL)); if(c->avctx->me_range && range > c->avctx->me_range) range= c->avctx->me_range; @@ -2003,9 +2006,8 @@ void ff_fix_long_mvs(MpegEncContext * s, uint8_t *field_select_table, int field_ int y, h_range, v_range; // RAL: 8 in MPEG-1, 16 in MPEG-4 - int range = (((s->out_format == FMT_MPEG1) ? 8 : 16) << f_code); + int range = (((s->out_format == FMT_MPEG1 || s->msmpeg4_version) ? 8 : 16) << f_code); - if(s->msmpeg4_version) range= 16; if(c->avctx->me_range && range > c->avctx->me_range) range= c->avctx->me_range; h_range= range; diff --git a/src/libffmpeg/libavcodec/motion_est_template.c b/src/libffmpeg/libavcodec/motion_est_template.c index 7113e1ba6..d8101ec33 100644 --- a/src/libffmpeg/libavcodec/motion_est_template.c +++ b/src/libffmpeg/libavcodec/motion_est_template.c @@ -231,7 +231,7 @@ static int no_sub_motion_search(MpegEncContext * s, return dmin; } -int __inline__ ff_get_mb_score(MpegEncContext * s, int mx, int my, int src_index, +int inline ff_get_mb_score(MpegEncContext * s, int mx, int my, int src_index, int ref_index, int size, int h, int add_rate) { // const int check_luma= s->dsp.me_sub_cmp != s->dsp.mb_cmp; @@ -962,7 +962,7 @@ static always_inline int epzs_motion_search_internal(MpegEncContext * s, int *mx } //this function is dedicated to the braindamaged gcc -int __inline__ ff_epzs_motion_search(MpegEncContext * s, int *mx_ptr, int *my_ptr, +inline int ff_epzs_motion_search(MpegEncContext * s, int *mx_ptr, int *my_ptr, int P[10][2], int src_index, int ref_index, int16_t (*last_mv)[2], int ref_mv_scale, int size, int h) { diff --git a/src/libffmpeg/libavcodec/mpeg12.c b/src/libffmpeg/libavcodec/mpeg12.c index f245131dc..8b2b75d4e 100644 --- a/src/libffmpeg/libavcodec/mpeg12.c +++ b/src/libffmpeg/libavcodec/mpeg12.c @@ -65,6 +65,21 @@ static void mpeg1_encode_block(MpegEncContext *s, int component); static void mpeg1_encode_motion(MpegEncContext *s, int val, int f_or_b_code); // RAL: f_code parameter added #endif //CONFIG_ENCODERS +static inline int mpeg1_decode_block_inter(MpegEncContext *s, + DCTELEM *block, + int n); +static inline int mpeg1_decode_block_intra(MpegEncContext *s, + DCTELEM *block, + int n); +static inline int mpeg1_fast_decode_block_inter(MpegEncContext *s, DCTELEM *block, int n); +static inline int mpeg2_decode_block_non_intra(MpegEncContext *s, + DCTELEM *block, + int n); +static inline int mpeg2_decode_block_intra(MpegEncContext *s, + DCTELEM *block, + int n); +static inline int mpeg2_fast_decode_block_non_intra(MpegEncContext *s, DCTELEM *block, int n); +static inline int mpeg2_fast_decode_block_intra(MpegEncContext *s, DCTELEM *block, int n); static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred); static void exchange_uv(MpegEncContext *s); @@ -1039,6 +1054,436 @@ static inline int get_qscale(MpegEncContext *s) #define MT_16X8 2 #define MT_DMV 3 +static int mpeg_decode_mb(MpegEncContext *s, + DCTELEM block[12][64]) +{ + int i, j, k, cbp, val, mb_type, motion_type; + const int mb_block_count = 4 + (1<< s->chroma_format); + + dprintf("decode_mb: x=%d y=%d\n", s->mb_x, s->mb_y); + + assert(s->mb_skipped==0); + + if (s->mb_skip_run-- != 0) { + if(s->pict_type == I_TYPE){ + av_log(s->avctx, AV_LOG_ERROR, "skipped MB in I frame at %d %d\n", s->mb_x, s->mb_y); + return -1; + } + + /* skip mb */ + s->mb_intra = 0; + for(i=0;i<12;i++) + s->block_last_index[i] = -1; + if(s->picture_structure == PICT_FRAME) + s->mv_type = MV_TYPE_16X16; + else + s->mv_type = MV_TYPE_FIELD; + if (s->pict_type == P_TYPE) { + /* if P type, zero motion vector is implied */ + s->mv_dir = MV_DIR_FORWARD; + s->mv[0][0][0] = s->mv[0][0][1] = 0; + s->last_mv[0][0][0] = s->last_mv[0][0][1] = 0; + s->last_mv[0][1][0] = s->last_mv[0][1][1] = 0; + s->field_select[0][0]= s->picture_structure - 1; + s->mb_skipped = 1; + s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride ]= MB_TYPE_SKIP | MB_TYPE_L0 | MB_TYPE_16x16; + } else { + int mb_type; + + if(s->mb_x) + mb_type= s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride - 1]; + else + mb_type= s->current_picture.mb_type[ s->mb_width + (s->mb_y-1)*s->mb_stride - 1]; // FIXME not sure if this is allowed in mpeg at all, + if(IS_INTRA(mb_type)) + return -1; + + /* if B type, reuse previous vectors and directions */ + s->mv[0][0][0] = s->last_mv[0][0][0]; + s->mv[0][0][1] = s->last_mv[0][0][1]; + s->mv[1][0][0] = s->last_mv[1][0][0]; + s->mv[1][0][1] = s->last_mv[1][0][1]; + + s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride ]= + mb_type | MB_TYPE_SKIP; +// assert(s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride - 1]&(MB_TYPE_16x16|MB_TYPE_16x8)); + + if((s->mv[0][0][0]|s->mv[0][0][1]|s->mv[1][0][0]|s->mv[1][0][1])==0) + s->mb_skipped = 1; + } + + return 0; + } + + switch(s->pict_type) { + default: + case I_TYPE: + if (get_bits1(&s->gb) == 0) { + if (get_bits1(&s->gb) == 0){ + av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in I Frame at %d %d\n", s->mb_x, s->mb_y); + return -1; + } + mb_type = MB_TYPE_QUANT | MB_TYPE_INTRA; + } else { + mb_type = MB_TYPE_INTRA; + } + break; + case P_TYPE: + mb_type = get_vlc2(&s->gb, mb_ptype_vlc.table, MB_PTYPE_VLC_BITS, 1); + if (mb_type < 0){ + av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in P Frame at %d %d\n", s->mb_x, s->mb_y); + return -1; + } + mb_type = ptype2mb_type[ mb_type ]; + break; + case B_TYPE: + mb_type = get_vlc2(&s->gb, mb_btype_vlc.table, MB_BTYPE_VLC_BITS, 1); + if (mb_type < 0){ + av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in B Frame at %d %d\n", s->mb_x, s->mb_y); + return -1; + } + mb_type = btype2mb_type[ mb_type ]; + break; + } + dprintf("mb_type=%x\n", mb_type); +// motion_type = 0; /* avoid warning */ + if (IS_INTRA(mb_type)) { + s->dsp.clear_blocks(s->block[0]); + + if(!s->chroma_y_shift){ + s->dsp.clear_blocks(s->block[6]); + } + + /* compute dct type */ + if (s->picture_structure == PICT_FRAME && //FIXME add a interlaced_dct coded var? + !s->frame_pred_frame_dct) { + s->interlaced_dct = get_bits1(&s->gb); + } + + if (IS_QUANT(mb_type)) + s->qscale = get_qscale(s); + + if (s->concealment_motion_vectors) { + /* just parse them */ + if (s->picture_structure != PICT_FRAME) + skip_bits1(&s->gb); /* field select */ + + s->mv[0][0][0]= s->last_mv[0][0][0]= s->last_mv[0][1][0] = + mpeg_decode_motion(s, s->mpeg_f_code[0][0], s->last_mv[0][0][0]); + s->mv[0][0][1]= s->last_mv[0][0][1]= s->last_mv[0][1][1] = + mpeg_decode_motion(s, s->mpeg_f_code[0][1], s->last_mv[0][0][1]); + + skip_bits1(&s->gb); /* marker */ + }else + memset(s->last_mv, 0, sizeof(s->last_mv)); /* reset mv prediction */ + s->mb_intra = 1; +#ifdef HAVE_XVMC + //one 1 we memcpy blocks in xvmcvideo + if(s->avctx->xvmc_acceleration > 1){ + XVMC_pack_pblocks(s,-1);//inter are always full blocks + if(s->swap_uv){ + exchange_uv(s); + } + } +#endif + + if (s->codec_id == CODEC_ID_MPEG2VIDEO) { + if(s->flags2 & CODEC_FLAG2_FAST){ + for(i=0;i<6;i++) { + mpeg2_fast_decode_block_intra(s, s->pblocks[i], i); + } + }else{ + for(i=0;i<mb_block_count;i++) { + if (mpeg2_decode_block_intra(s, s->pblocks[i], i) < 0) + return -1; + } + } + } else { + for(i=0;i<6;i++) { + if (mpeg1_decode_block_intra(s, s->pblocks[i], i) < 0) + return -1; + } + } + } else { + if (mb_type & MB_TYPE_ZERO_MV){ + assert(mb_type & MB_TYPE_CBP); + + /* compute dct type */ + if (s->picture_structure == PICT_FRAME && //FIXME add a interlaced_dct coded var? + !s->frame_pred_frame_dct) { + s->interlaced_dct = get_bits1(&s->gb); + } + + if (IS_QUANT(mb_type)) + s->qscale = get_qscale(s); + + s->mv_dir = MV_DIR_FORWARD; + if(s->picture_structure == PICT_FRAME) + s->mv_type = MV_TYPE_16X16; + else{ + s->mv_type = MV_TYPE_FIELD; + mb_type |= MB_TYPE_INTERLACED; + s->field_select[0][0]= s->picture_structure - 1; + } + s->last_mv[0][0][0] = 0; + s->last_mv[0][0][1] = 0; + s->last_mv[0][1][0] = 0; + s->last_mv[0][1][1] = 0; + s->mv[0][0][0] = 0; + s->mv[0][0][1] = 0; + }else{ + assert(mb_type & MB_TYPE_L0L1); +//FIXME decide if MBs in field pictures are MB_TYPE_INTERLACED + /* get additionnal motion vector type */ + if (s->frame_pred_frame_dct) + motion_type = MT_FRAME; + else{ + motion_type = get_bits(&s->gb, 2); + } + + /* compute dct type */ + if (s->picture_structure == PICT_FRAME && //FIXME add a interlaced_dct coded var? + !s->frame_pred_frame_dct && HAS_CBP(mb_type)) { + s->interlaced_dct = get_bits1(&s->gb); + } + + if (IS_QUANT(mb_type)) + s->qscale = get_qscale(s); + + /* motion vectors */ + s->mv_dir = 0; + for(i=0;i<2;i++) { + if (USES_LIST(mb_type, i)) { + s->mv_dir |= (MV_DIR_FORWARD >> i); + dprintf("motion_type=%d\n", motion_type); + switch(motion_type) { + case MT_FRAME: /* or MT_16X8 */ + if (s->picture_structure == PICT_FRAME) { + /* MT_FRAME */ + mb_type |= MB_TYPE_16x16; + s->mv_type = MV_TYPE_16X16; + s->mv[i][0][0]= s->last_mv[i][0][0]= s->last_mv[i][1][0] = + mpeg_decode_motion(s, s->mpeg_f_code[i][0], s->last_mv[i][0][0]); + s->mv[i][0][1]= s->last_mv[i][0][1]= s->last_mv[i][1][1] = + mpeg_decode_motion(s, s->mpeg_f_code[i][1], s->last_mv[i][0][1]); + /* full_pel: only for mpeg1 */ + if (s->full_pel[i]){ + s->mv[i][0][0] <<= 1; + s->mv[i][0][1] <<= 1; + } + } else { + /* MT_16X8 */ + mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED; + s->mv_type = MV_TYPE_16X8; + for(j=0;j<2;j++) { + s->field_select[i][j] = get_bits1(&s->gb); + for(k=0;k<2;k++) { + val = mpeg_decode_motion(s, s->mpeg_f_code[i][k], + s->last_mv[i][j][k]); + s->last_mv[i][j][k] = val; + s->mv[i][j][k] = val; + } + } + } + break; + case MT_FIELD: + s->mv_type = MV_TYPE_FIELD; + if (s->picture_structure == PICT_FRAME) { + mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED; + for(j=0;j<2;j++) { + s->field_select[i][j] = get_bits1(&s->gb); + val = mpeg_decode_motion(s, s->mpeg_f_code[i][0], + s->last_mv[i][j][0]); + s->last_mv[i][j][0] = val; + s->mv[i][j][0] = val; + dprintf("fmx=%d\n", val); + val = mpeg_decode_motion(s, s->mpeg_f_code[i][1], + s->last_mv[i][j][1] >> 1); + s->last_mv[i][j][1] = val << 1; + s->mv[i][j][1] = val; + dprintf("fmy=%d\n", val); + } + } else { + mb_type |= MB_TYPE_16x16 | MB_TYPE_INTERLACED; + s->field_select[i][0] = get_bits1(&s->gb); + for(k=0;k<2;k++) { + val = mpeg_decode_motion(s, s->mpeg_f_code[i][k], + s->last_mv[i][0][k]); + s->last_mv[i][0][k] = val; + s->last_mv[i][1][k] = val; + s->mv[i][0][k] = val; + } + } + break; + case MT_DMV: + { + int dmx, dmy, mx, my, m; + + mx = mpeg_decode_motion(s, s->mpeg_f_code[i][0], + s->last_mv[i][0][0]); + s->last_mv[i][0][0] = mx; + s->last_mv[i][1][0] = mx; + dmx = get_dmv(s); + my = mpeg_decode_motion(s, s->mpeg_f_code[i][1], + s->last_mv[i][0][1] >> 1); + dmy = get_dmv(s); + s->mv_type = MV_TYPE_DMV; + + + s->last_mv[i][0][1] = my<<1; + s->last_mv[i][1][1] = my<<1; + + s->mv[i][0][0] = mx; + s->mv[i][0][1] = my; + s->mv[i][1][0] = mx;//not used + s->mv[i][1][1] = my;//not used + + if (s->picture_structure == PICT_FRAME) { + mb_type |= MB_TYPE_16x16 | MB_TYPE_INTERLACED; + + //m = 1 + 2 * s->top_field_first; + m = s->top_field_first ? 1 : 3; + + /* top -> top pred */ + s->mv[i][2][0] = ((mx * m + (mx > 0)) >> 1) + dmx; + s->mv[i][2][1] = ((my * m + (my > 0)) >> 1) + dmy - 1; + m = 4 - m; + s->mv[i][3][0] = ((mx * m + (mx > 0)) >> 1) + dmx; + s->mv[i][3][1] = ((my * m + (my > 0)) >> 1) + dmy + 1; + } else { + mb_type |= MB_TYPE_16x16; + + s->mv[i][2][0] = ((mx + (mx > 0)) >> 1) + dmx; + s->mv[i][2][1] = ((my + (my > 0)) >> 1) + dmy; + if(s->picture_structure == PICT_TOP_FIELD) + s->mv[i][2][1]--; + else + s->mv[i][2][1]++; + } + } + break; + default: + av_log(s->avctx, AV_LOG_ERROR, "00 motion_type at %d %d\n", s->mb_x, s->mb_y); + return -1; + } + } + } + } + + s->mb_intra = 0; + if (HAS_CBP(mb_type)) { + s->dsp.clear_blocks(s->block[0]); + + if(!s->chroma_y_shift){ + s->dsp.clear_blocks(s->block[6]); + } + + cbp = get_vlc2(&s->gb, mb_pat_vlc.table, MB_PAT_VLC_BITS, 1); + if (cbp < 0 || ((cbp == 0) && (s->chroma_format < 2)) ){ + av_log(s->avctx, AV_LOG_ERROR, "invalid cbp at %d %d\n", s->mb_x, s->mb_y); + return -1; + } + if(mb_block_count > 6){ + cbp<<= mb_block_count-6; + cbp |= get_bits(&s->gb, mb_block_count-6); + } + +#ifdef HAVE_XVMC + //on 1 we memcpy blocks in xvmcvideo + if(s->avctx->xvmc_acceleration > 1){ + XVMC_pack_pblocks(s,cbp); + if(s->swap_uv){ + exchange_uv(s); + } + } +#endif + + if (s->codec_id == CODEC_ID_MPEG2VIDEO) { + if(s->flags2 & CODEC_FLAG2_FAST){ + for(i=0;i<6;i++) { + if(cbp & 32) { + mpeg2_fast_decode_block_non_intra(s, s->pblocks[i], i); + } else { + s->block_last_index[i] = -1; + } + cbp+=cbp; + } + }else{ + cbp<<= 12-mb_block_count; + + for(i=0;i<mb_block_count;i++) { + if ( cbp & (1<<11) ) { + if (mpeg2_decode_block_non_intra(s, s->pblocks[i], i) < 0) + return -1; + } else { + s->block_last_index[i] = -1; + } + cbp+=cbp; + } + } + } else { + if(s->flags2 & CODEC_FLAG2_FAST){ + for(i=0;i<6;i++) { + if (cbp & 32) { + mpeg1_fast_decode_block_inter(s, s->pblocks[i], i); + } else { + s->block_last_index[i] = -1; + } + cbp+=cbp; + } + }else{ + for(i=0;i<6;i++) { + if (cbp & 32) { + if (mpeg1_decode_block_inter(s, s->pblocks[i], i) < 0) + return -1; + } else { + s->block_last_index[i] = -1; + } + cbp+=cbp; + } + } + } + }else{ + for(i=0;i<6;i++) + s->block_last_index[i] = -1; + } + } + + s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride ]= mb_type; + + return 0; +} + +/* as h263, but only 17 codes */ +static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred) +{ + int code, sign, val, l, shift; + + code = get_vlc2(&s->gb, mv_vlc.table, MV_VLC_BITS, 2); + if (code == 0) { + return pred; + } + if (code < 0) { + return 0xffff; + } + + sign = get_bits1(&s->gb); + shift = fcode - 1; + val = code; + if (shift) { + val = (val - 1) << shift; + val |= get_bits(&s->gb, shift); + val++; + } + if (sign) + val = -val; + val += pred; + + /* modulo decoding */ + l= INT_BIT - 5 - shift; + val = (val<<l)>>l; + return val; +} + static inline int decode_dc(GetBitContext *gb, int component) { int code, diff; @@ -1372,7 +1817,6 @@ static inline int mpeg2_fast_decode_block_non_intra(MpegEncContext *s, RLTable *rl = &rl_mpeg1; uint8_t * const scantable= s->intra_scantable.permutated; const int qscale= s->qscale; - int v; OPEN_READER(re, &s->gb); i = -1; @@ -1578,436 +2022,6 @@ static inline int mpeg2_fast_decode_block_intra(MpegEncContext *s, return 0; } -static int mpeg_decode_mb(MpegEncContext *s, - DCTELEM block[12][64]) -{ - int i, j, k, cbp, val, mb_type, motion_type; - const int mb_block_count = 4 + (1<< s->chroma_format); - - dprintf("decode_mb: x=%d y=%d\n", s->mb_x, s->mb_y); - - assert(s->mb_skipped==0); - - if (s->mb_skip_run-- != 0) { - if(s->pict_type == I_TYPE){ - av_log(s->avctx, AV_LOG_ERROR, "skipped MB in I frame at %d %d\n", s->mb_x, s->mb_y); - return -1; - } - - /* skip mb */ - s->mb_intra = 0; - for(i=0;i<12;i++) - s->block_last_index[i] = -1; - if(s->picture_structure == PICT_FRAME) - s->mv_type = MV_TYPE_16X16; - else - s->mv_type = MV_TYPE_FIELD; - if (s->pict_type == P_TYPE) { - /* if P type, zero motion vector is implied */ - s->mv_dir = MV_DIR_FORWARD; - s->mv[0][0][0] = s->mv[0][0][1] = 0; - s->last_mv[0][0][0] = s->last_mv[0][0][1] = 0; - s->last_mv[0][1][0] = s->last_mv[0][1][1] = 0; - s->field_select[0][0]= s->picture_structure - 1; - s->mb_skipped = 1; - s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride ]= MB_TYPE_SKIP | MB_TYPE_L0 | MB_TYPE_16x16; - } else { - int mb_type; - - if(s->mb_x) - mb_type= s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride - 1]; - else - mb_type= s->current_picture.mb_type[ s->mb_width + (s->mb_y-1)*s->mb_stride - 1]; // FIXME not sure if this is allowed in mpeg at all, - if(IS_INTRA(mb_type)) - return -1; - - /* if B type, reuse previous vectors and directions */ - s->mv[0][0][0] = s->last_mv[0][0][0]; - s->mv[0][0][1] = s->last_mv[0][0][1]; - s->mv[1][0][0] = s->last_mv[1][0][0]; - s->mv[1][0][1] = s->last_mv[1][0][1]; - - s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride ]= - mb_type | MB_TYPE_SKIP; -// assert(s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride - 1]&(MB_TYPE_16x16|MB_TYPE_16x8)); - - if((s->mv[0][0][0]|s->mv[0][0][1]|s->mv[1][0][0]|s->mv[1][0][1])==0) - s->mb_skipped = 1; - } - - return 0; - } - - switch(s->pict_type) { - default: - case I_TYPE: - if (get_bits1(&s->gb) == 0) { - if (get_bits1(&s->gb) == 0){ - av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in I Frame at %d %d\n", s->mb_x, s->mb_y); - return -1; - } - mb_type = MB_TYPE_QUANT | MB_TYPE_INTRA; - } else { - mb_type = MB_TYPE_INTRA; - } - break; - case P_TYPE: - mb_type = get_vlc2(&s->gb, mb_ptype_vlc.table, MB_PTYPE_VLC_BITS, 1); - if (mb_type < 0){ - av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in P Frame at %d %d\n", s->mb_x, s->mb_y); - return -1; - } - mb_type = ptype2mb_type[ mb_type ]; - break; - case B_TYPE: - mb_type = get_vlc2(&s->gb, mb_btype_vlc.table, MB_BTYPE_VLC_BITS, 1); - if (mb_type < 0){ - av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in B Frame at %d %d\n", s->mb_x, s->mb_y); - return -1; - } - mb_type = btype2mb_type[ mb_type ]; - break; - } - dprintf("mb_type=%x\n", mb_type); -// motion_type = 0; /* avoid warning */ - if (IS_INTRA(mb_type)) { - s->dsp.clear_blocks(s->block[0]); - - if(!s->chroma_y_shift){ - s->dsp.clear_blocks(s->block[6]); - } - - /* compute dct type */ - if (s->picture_structure == PICT_FRAME && //FIXME add a interlaced_dct coded var? - !s->frame_pred_frame_dct) { - s->interlaced_dct = get_bits1(&s->gb); - } - - if (IS_QUANT(mb_type)) - s->qscale = get_qscale(s); - - if (s->concealment_motion_vectors) { - /* just parse them */ - if (s->picture_structure != PICT_FRAME) - skip_bits1(&s->gb); /* field select */ - - s->mv[0][0][0]= s->last_mv[0][0][0]= s->last_mv[0][1][0] = - mpeg_decode_motion(s, s->mpeg_f_code[0][0], s->last_mv[0][0][0]); - s->mv[0][0][1]= s->last_mv[0][0][1]= s->last_mv[0][1][1] = - mpeg_decode_motion(s, s->mpeg_f_code[0][1], s->last_mv[0][0][1]); - - skip_bits1(&s->gb); /* marker */ - }else - memset(s->last_mv, 0, sizeof(s->last_mv)); /* reset mv prediction */ - s->mb_intra = 1; -#ifdef HAVE_XVMC - //one 1 we memcpy blocks in xvmcvideo - if(s->avctx->xvmc_acceleration > 1){ - XVMC_pack_pblocks(s,-1);//inter are always full blocks - if(s->swap_uv){ - exchange_uv(s); - } - } -#endif - - if (s->codec_id == CODEC_ID_MPEG2VIDEO) { - if(s->flags2 & CODEC_FLAG2_FAST){ - for(i=0;i<6;i++) { - mpeg2_fast_decode_block_intra(s, s->pblocks[i], i); - } - }else{ - for(i=0;i<mb_block_count;i++) { - if (mpeg2_decode_block_intra(s, s->pblocks[i], i) < 0) - return -1; - } - } - } else { - for(i=0;i<6;i++) { - if (mpeg1_decode_block_intra(s, s->pblocks[i], i) < 0) - return -1; - } - } - } else { - if (mb_type & MB_TYPE_ZERO_MV){ - assert(mb_type & MB_TYPE_CBP); - - /* compute dct type */ - if (s->picture_structure == PICT_FRAME && //FIXME add a interlaced_dct coded var? - !s->frame_pred_frame_dct) { - s->interlaced_dct = get_bits1(&s->gb); - } - - if (IS_QUANT(mb_type)) - s->qscale = get_qscale(s); - - s->mv_dir = MV_DIR_FORWARD; - if(s->picture_structure == PICT_FRAME) - s->mv_type = MV_TYPE_16X16; - else{ - s->mv_type = MV_TYPE_FIELD; - mb_type |= MB_TYPE_INTERLACED; - s->field_select[0][0]= s->picture_structure - 1; - } - s->last_mv[0][0][0] = 0; - s->last_mv[0][0][1] = 0; - s->last_mv[0][1][0] = 0; - s->last_mv[0][1][1] = 0; - s->mv[0][0][0] = 0; - s->mv[0][0][1] = 0; - }else{ - assert(mb_type & MB_TYPE_L0L1); -//FIXME decide if MBs in field pictures are MB_TYPE_INTERLACED - /* get additionnal motion vector type */ - if (s->frame_pred_frame_dct) - motion_type = MT_FRAME; - else{ - motion_type = get_bits(&s->gb, 2); - } - - /* compute dct type */ - if (s->picture_structure == PICT_FRAME && //FIXME add a interlaced_dct coded var? - !s->frame_pred_frame_dct && HAS_CBP(mb_type)) { - s->interlaced_dct = get_bits1(&s->gb); - } - - if (IS_QUANT(mb_type)) - s->qscale = get_qscale(s); - - /* motion vectors */ - s->mv_dir = 0; - for(i=0;i<2;i++) { - if (USES_LIST(mb_type, i)) { - s->mv_dir |= (MV_DIR_FORWARD >> i); - dprintf("motion_type=%d\n", motion_type); - switch(motion_type) { - case MT_FRAME: /* or MT_16X8 */ - if (s->picture_structure == PICT_FRAME) { - /* MT_FRAME */ - mb_type |= MB_TYPE_16x16; - s->mv_type = MV_TYPE_16X16; - s->mv[i][0][0]= s->last_mv[i][0][0]= s->last_mv[i][1][0] = - mpeg_decode_motion(s, s->mpeg_f_code[i][0], s->last_mv[i][0][0]); - s->mv[i][0][1]= s->last_mv[i][0][1]= s->last_mv[i][1][1] = - mpeg_decode_motion(s, s->mpeg_f_code[i][1], s->last_mv[i][0][1]); - /* full_pel: only for mpeg1 */ - if (s->full_pel[i]){ - s->mv[i][0][0] <<= 1; - s->mv[i][0][1] <<= 1; - } - } else { - /* MT_16X8 */ - mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED; - s->mv_type = MV_TYPE_16X8; - for(j=0;j<2;j++) { - s->field_select[i][j] = get_bits1(&s->gb); - for(k=0;k<2;k++) { - val = mpeg_decode_motion(s, s->mpeg_f_code[i][k], - s->last_mv[i][j][k]); - s->last_mv[i][j][k] = val; - s->mv[i][j][k] = val; - } - } - } - break; - case MT_FIELD: - s->mv_type = MV_TYPE_FIELD; - if (s->picture_structure == PICT_FRAME) { - mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED; - for(j=0;j<2;j++) { - s->field_select[i][j] = get_bits1(&s->gb); - val = mpeg_decode_motion(s, s->mpeg_f_code[i][0], - s->last_mv[i][j][0]); - s->last_mv[i][j][0] = val; - s->mv[i][j][0] = val; - dprintf("fmx=%d\n", val); - val = mpeg_decode_motion(s, s->mpeg_f_code[i][1], - s->last_mv[i][j][1] >> 1); - s->last_mv[i][j][1] = val << 1; - s->mv[i][j][1] = val; - dprintf("fmy=%d\n", val); - } - } else { - mb_type |= MB_TYPE_16x16 | MB_TYPE_INTERLACED; - s->field_select[i][0] = get_bits1(&s->gb); - for(k=0;k<2;k++) { - val = mpeg_decode_motion(s, s->mpeg_f_code[i][k], - s->last_mv[i][0][k]); - s->last_mv[i][0][k] = val; - s->last_mv[i][1][k] = val; - s->mv[i][0][k] = val; - } - } - break; - case MT_DMV: - { - int dmx, dmy, mx, my, m; - - mx = mpeg_decode_motion(s, s->mpeg_f_code[i][0], - s->last_mv[i][0][0]); - s->last_mv[i][0][0] = mx; - s->last_mv[i][1][0] = mx; - dmx = get_dmv(s); - my = mpeg_decode_motion(s, s->mpeg_f_code[i][1], - s->last_mv[i][0][1] >> 1); - dmy = get_dmv(s); - s->mv_type = MV_TYPE_DMV; - - - s->last_mv[i][0][1] = my<<1; - s->last_mv[i][1][1] = my<<1; - - s->mv[i][0][0] = mx; - s->mv[i][0][1] = my; - s->mv[i][1][0] = mx;//not used - s->mv[i][1][1] = my;//not used - - if (s->picture_structure == PICT_FRAME) { - mb_type |= MB_TYPE_16x16 | MB_TYPE_INTERLACED; - - //m = 1 + 2 * s->top_field_first; - m = s->top_field_first ? 1 : 3; - - /* top -> top pred */ - s->mv[i][2][0] = ((mx * m + (mx > 0)) >> 1) + dmx; - s->mv[i][2][1] = ((my * m + (my > 0)) >> 1) + dmy - 1; - m = 4 - m; - s->mv[i][3][0] = ((mx * m + (mx > 0)) >> 1) + dmx; - s->mv[i][3][1] = ((my * m + (my > 0)) >> 1) + dmy + 1; - } else { - mb_type |= MB_TYPE_16x16; - - s->mv[i][2][0] = ((mx + (mx > 0)) >> 1) + dmx; - s->mv[i][2][1] = ((my + (my > 0)) >> 1) + dmy; - if(s->picture_structure == PICT_TOP_FIELD) - s->mv[i][2][1]--; - else - s->mv[i][2][1]++; - } - } - break; - default: - av_log(s->avctx, AV_LOG_ERROR, "00 motion_type at %d %d\n", s->mb_x, s->mb_y); - return -1; - } - } - } - } - - s->mb_intra = 0; - if (HAS_CBP(mb_type)) { - s->dsp.clear_blocks(s->block[0]); - - if(!s->chroma_y_shift){ - s->dsp.clear_blocks(s->block[6]); - } - - cbp = get_vlc2(&s->gb, mb_pat_vlc.table, MB_PAT_VLC_BITS, 1); - if (cbp < 0 || ((cbp == 0) && (s->chroma_format < 2)) ){ - av_log(s->avctx, AV_LOG_ERROR, "invalid cbp at %d %d\n", s->mb_x, s->mb_y); - return -1; - } - if(mb_block_count > 6){ - cbp<<= mb_block_count-6; - cbp |= get_bits(&s->gb, mb_block_count-6); - } - -#ifdef HAVE_XVMC - //on 1 we memcpy blocks in xvmcvideo - if(s->avctx->xvmc_acceleration > 1){ - XVMC_pack_pblocks(s,cbp); - if(s->swap_uv){ - exchange_uv(s); - } - } -#endif - - if (s->codec_id == CODEC_ID_MPEG2VIDEO) { - if(s->flags2 & CODEC_FLAG2_FAST){ - for(i=0;i<6;i++) { - if(cbp & 32) { - mpeg2_fast_decode_block_non_intra(s, s->pblocks[i], i); - } else { - s->block_last_index[i] = -1; - } - cbp+=cbp; - } - }else{ - cbp<<= 12-mb_block_count; - - for(i=0;i<mb_block_count;i++) { - if ( cbp & (1<<11) ) { - if (mpeg2_decode_block_non_intra(s, s->pblocks[i], i) < 0) - return -1; - } else { - s->block_last_index[i] = -1; - } - cbp+=cbp; - } - } - } else { - if(s->flags2 & CODEC_FLAG2_FAST){ - for(i=0;i<6;i++) { - if (cbp & 32) { - mpeg1_fast_decode_block_inter(s, s->pblocks[i], i); - } else { - s->block_last_index[i] = -1; - } - cbp+=cbp; - } - }else{ - for(i=0;i<6;i++) { - if (cbp & 32) { - if (mpeg1_decode_block_inter(s, s->pblocks[i], i) < 0) - return -1; - } else { - s->block_last_index[i] = -1; - } - cbp+=cbp; - } - } - } - }else{ - for(i=0;i<6;i++) - s->block_last_index[i] = -1; - } - } - - s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride ]= mb_type; - - return 0; -} - -/* as h263, but only 17 codes */ -static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred) -{ - int code, sign, val, l, shift; - - code = get_vlc2(&s->gb, mv_vlc.table, MV_VLC_BITS, 2); - if (code == 0) { - return pred; - } - if (code < 0) { - return 0xffff; - } - - sign = get_bits1(&s->gb); - shift = fcode - 1; - val = code; - if (shift) { - val = (val - 1) << shift; - val |= get_bits(&s->gb, shift); - val++; - } - if (sign) - val = -val; - val += pred; - - /* modulo decoding */ - l= INT_BIT - 5 - shift; - val = (val<<l)>>l; - return val; -} - typedef struct Mpeg1Context { MpegEncContext mpeg_enc_ctx; int mpeg_enc_ctx_allocated; /* true if decoding context allocated */ @@ -2805,10 +2819,12 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx, s->chroma_intra_matrix[j] = v; } #ifdef DEBUG +/* dprintf("intra matrix present\n"); for(i=0;i<64;i++) dprintf(" %d", s->intra_matrix[s->dsp.idct_permutation[i]]); printf("\n"); +*/ #endif } else { for(i=0;i<64;i++) { @@ -2830,10 +2846,12 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx, s->chroma_inter_matrix[j] = v; } #ifdef DEBUG +/* dprintf("non intra matrix present\n"); for(i=0;i<64;i++) dprintf(" %d", s->inter_matrix[s->dsp.idct_permutation[i]]); printf("\n"); +*/ #endif } else { for(i=0;i<64;i++) { diff --git a/src/libffmpeg/libavcodec/mpegaudio.h b/src/libffmpeg/libavcodec/mpegaudio.h index 072c41bda..2bcf38eac 100644 --- a/src/libffmpeg/libavcodec/mpegaudio.h +++ b/src/libffmpeg/libavcodec/mpegaudio.h @@ -22,8 +22,42 @@ #define SAME_HEADER_MASK \ (0xffe00000 | (3 << 17) | (0xf << 12) | (3 << 10) | (3 << 19)) +/* define USE_HIGHPRECISION to have a bit exact (but slower) mpeg + audio decoder */ + +#ifdef USE_HIGHPRECISION +#define FRAC_BITS 23 /* fractional bits for sb_samples and dct */ +#define WFRAC_BITS 16 /* fractional bits for window */ +#else +#define FRAC_BITS 15 /* fractional bits for sb_samples and dct */ +#define WFRAC_BITS 14 /* fractional bits for window */ +#endif + +#if defined(USE_HIGHPRECISION) && defined(CONFIG_AUDIO_NONSHORT) +typedef int32_t OUT_INT; +#define OUT_MAX INT32_MAX +#define OUT_MIN INT32_MIN +#define OUT_SHIFT (WFRAC_BITS + FRAC_BITS - 31) +#else +typedef int16_t OUT_INT; +#define OUT_MAX INT16_MAX +#define OUT_MIN INT16_MIN +#define OUT_SHIFT (WFRAC_BITS + FRAC_BITS - 15) +#endif + +#if FRAC_BITS <= 15 +typedef int16_t MPA_INT; +#else +typedef int32_t MPA_INT; +#endif + int l2_select_table(int bitrate, int nb_channels, int freq, int lsf); int mpa_decode_header(AVCodecContext *avctx, uint32_t head); +void ff_mpa_synth_init(MPA_INT *window); +void ff_mpa_synth_filter(MPA_INT *synth_buf_ptr, int *synth_buf_offset, + MPA_INT *window, int *dither_state, + OUT_INT *samples, int incr, + int32_t sb_samples[SBLIMIT]); extern const uint16_t mpa_bitrate_tab[2][3][15]; extern const uint16_t mpa_freq_tab[3]; diff --git a/src/libffmpeg/libavcodec/mpegaudiodec.c b/src/libffmpeg/libavcodec/mpegaudiodec.c index 708d35536..32998a6eb 100644 --- a/src/libffmpeg/libavcodec/mpegaudiodec.c +++ b/src/libffmpeg/libavcodec/mpegaudiodec.c @@ -25,7 +25,6 @@ //#define DEBUG #include "avcodec.h" #include "bitstream.h" -#include "mpegaudio.h" #include "dsputil.h" /* @@ -40,25 +39,7 @@ #define USE_HIGHPRECISION #endif -#ifdef USE_HIGHPRECISION -#define FRAC_BITS 23 /* fractional bits for sb_samples and dct */ -#define WFRAC_BITS 16 /* fractional bits for window */ -#else -#define FRAC_BITS 15 /* fractional bits for sb_samples and dct */ -#define WFRAC_BITS 14 /* fractional bits for window */ -#endif - -#if defined(USE_HIGHPRECISION) && defined(CONFIG_AUDIO_NONSHORT) -typedef int32_t OUT_INT; -#define OUT_MAX INT32_MAX -#define OUT_MIN INT32_MIN -#define OUT_SHIFT (WFRAC_BITS + FRAC_BITS - 31) -#else -typedef int16_t OUT_INT; -#define OUT_MAX INT16_MAX -#define OUT_MIN INT16_MIN -#define OUT_SHIFT (WFRAC_BITS + FRAC_BITS - 15) -#endif +#include "mpegaudio.h" #define FRAC_ONE (1 << FRAC_BITS) @@ -75,12 +56,6 @@ static always_inline int MULH(int a, int b){ return ((int64_t)(a) * (int64_t)(b))>>32; } -#if FRAC_BITS <= 15 -typedef int16_t MPA_INT; -#else -typedef int32_t MPA_INT; -#endif - /****************/ #define HEADER_SIZE 4 diff --git a/src/libffmpeg/libavcodec/mpegvideo.c b/src/libffmpeg/libavcodec/mpegvideo.c index 38d8a99b9..847250fff 100644 --- a/src/libffmpeg/libavcodec/mpegvideo.c +++ b/src/libffmpeg/libavcodec/mpegvideo.c @@ -895,7 +895,7 @@ void MPV_common_end(MpegEncContext *s) int MPV_encode_init(AVCodecContext *avctx) { MpegEncContext *s = avctx->priv_data; - int i, dummy; + int i; int chroma_h_shift, chroma_v_shift; MPV_encode_defaults(s); @@ -2334,8 +2334,8 @@ int MPV_encode_picture(AVCodecContext *avctx, int start_y= s->thread_context[i]->start_mb_y; int end_y= s->thread_context[i]-> end_mb_y; int h= s->mb_height; - uint8_t *start= buf + buf_size*start_y/h; - uint8_t *end = buf + buf_size* end_y/h; + uint8_t *start= buf + (size_t)(((int64_t) buf_size)*start_y/h); + uint8_t *end = buf + (size_t)(((int64_t) buf_size)* end_y/h); init_put_bits(&s->thread_context[i]->pb, start, end - start); } @@ -5121,7 +5121,7 @@ static int encode_thread(AVCodecContext *c, void *arg){ motion_y=s->b_direct_mv_table[xy][1]; /* xine: do not need this for decode or MPEG-1 encoding modes */ #if 0 - ff_mpeg4_set_direct_mv(s, mx, my); + ff_mpeg4_set_direct_mv(s, motion_x, motion_y); #endif /* #if 0 */ break; case CANDIDATE_MB_TYPE_BIDIR: diff --git a/src/libffmpeg/libavcodec/mpegvideo.h b/src/libffmpeg/libavcodec/mpegvideo.h index 0605463d2..9e02fdca3 100644 --- a/src/libffmpeg/libavcodec/mpegvideo.h +++ b/src/libffmpeg/libavcodec/mpegvideo.h @@ -609,7 +609,6 @@ typedef struct MpegEncContext { int xvid_build; /* lavc specific stuff, used to workaround bugs in libavcodec */ - int ffmpeg_version; int lavc_build; /* RV10 specific */ @@ -810,10 +809,10 @@ void ff_fix_long_mvs(MpegEncContext * s, uint8_t *field_select_table, int field_ int16_t (*mv_table)[2], int f_code, int type, int truncate); void ff_init_me(MpegEncContext *s); int ff_pre_estimate_p_frame_motion(MpegEncContext * s, int mb_x, int mb_y); -extern __inline__ int ff_epzs_motion_search(MpegEncContext * s, int *mx_ptr, int *my_ptr, +inline int ff_epzs_motion_search(MpegEncContext * s, int *mx_ptr, int *my_ptr, int P[10][2], int src_index, int ref_index, int16_t (*last_mv)[2], int ref_mv_scale, int size, int h); -extern __inline__ int ff_get_mb_score(MpegEncContext * s, int mx, int my, int src_index, +int inline ff_get_mb_score(MpegEncContext * s, int mx, int my, int src_index, int ref_index, int size, int h, int add_rate); /* mpeg12.c */ diff --git a/src/libffmpeg/libavcodec/msmpeg4.c b/src/libffmpeg/libavcodec/msmpeg4.c index 3ac3e0df4..81f147918 100644 --- a/src/libffmpeg/libavcodec/msmpeg4.c +++ b/src/libffmpeg/libavcodec/msmpeg4.c @@ -59,7 +59,9 @@ static uint32_t v2_dc_lum_table[512][2]; static uint32_t v2_dc_chroma_table[512][2]; -static void msmpeg4_encode_dc(MpegEncContext * s, int level, int n, int *dir_ptr); +static inline void msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n); +static inline int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, + int n, int coded, const uint8_t *scantable); static int msmpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr); static int msmpeg4_decode_motion(MpegEncContext * s, int *mx_ptr, int *my_ptr); @@ -177,11 +179,8 @@ static void common_init(MpegEncContext * s) break; #if defined(CONFIG_WMV3_DECODER)||defined(CONFIG_VC9_DECODER) case 6: -/* xine: comment this out as WMV3 support is incomplete */ -#if 0 s->y_dc_scale_table= wmv3_dc_scale_table; s->c_dc_scale_table= wmv3_dc_scale_table; -#endif /* #if 0 */ break; #endif @@ -534,129 +533,6 @@ static inline void handle_slices(MpegEncContext *s){ } } -/* Encoding of a block. Very similar to MPEG4 except for a different - escape coding (same as H263) and more vlc tables. - */ -static inline void msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n) -{ - int level, run, last, i, j, last_index; - int last_non_zero, sign, slevel; - int code, run_diff, dc_pred_dir; - const RLTable *rl; - const uint8_t *scantable; - - if (s->mb_intra) { - set_stat(ST_DC); - msmpeg4_encode_dc(s, block[0], n, &dc_pred_dir); - i = 1; - if (n < 4) { - rl = &rl_table[s->rl_table_index]; - } else { - rl = &rl_table[3 + s->rl_chroma_table_index]; - } - run_diff = 0; - scantable= s->intra_scantable.permutated; - set_stat(ST_INTRA_AC); - } else { - i = 0; - rl = &rl_table[3 + s->rl_table_index]; - if(s->msmpeg4_version<=2) - run_diff = 0; - else - run_diff = 1; - scantable= s->inter_scantable.permutated; - set_stat(ST_INTER_AC); - } - - /* recalculate block_last_index for M$ wmv1 */ - if(s->msmpeg4_version>=4 && s->block_last_index[n]>0){ - for(last_index=63; last_index>=0; last_index--){ - if(block[scantable[last_index]]) break; - } - s->block_last_index[n]= last_index; - }else - last_index = s->block_last_index[n]; - /* AC coefs */ - last_non_zero = i - 1; - for (; i <= last_index; i++) { - j = scantable[i]; - level = block[j]; - if (level) { - run = i - last_non_zero - 1; - last = (i == last_index); - sign = 0; - slevel = level; - if (level < 0) { - sign = 1; - level = -level; - } - - if(level<=MAX_LEVEL && run<=MAX_RUN){ - s->ac_stats[s->mb_intra][n>3][level][run][last]++; - } -#if 0 -else - s->ac_stats[s->mb_intra][n>3][40][63][0]++; //esc3 like -#endif - code = get_rl_index(rl, last, run, level); - put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); - if (code == rl->n) { - int level1, run1; - - level1 = level - rl->max_level[last][run]; - if (level1 < 1) - goto esc2; - code = get_rl_index(rl, last, run, level1); - if (code == rl->n) { - esc2: - put_bits(&s->pb, 1, 0); - if (level > MAX_LEVEL) - goto esc3; - run1 = run - rl->max_run[last][level] - run_diff; - if (run1 < 0) - goto esc3; - code = get_rl_index(rl, last, run1, level); - if (code == rl->n) { - esc3: - /* third escape */ - put_bits(&s->pb, 1, 0); - put_bits(&s->pb, 1, last); - if(s->msmpeg4_version>=4){ - if(s->esc3_level_length==0){ - s->esc3_level_length=8; - s->esc3_run_length= 6; - if(s->qscale<8) - put_bits(&s->pb, 6, 3); - else - put_bits(&s->pb, 8, 3); - } - put_bits(&s->pb, s->esc3_run_length, run); - put_bits(&s->pb, 1, sign); - put_bits(&s->pb, s->esc3_level_length, level); - }else{ - put_bits(&s->pb, 6, run); - put_bits(&s->pb, 8, slevel & 0xff); - } - } else { - /* second escape */ - put_bits(&s->pb, 1, 1); - put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); - put_bits(&s->pb, 1, sign); - } - } else { - /* first escape */ - put_bits(&s->pb, 1, 1); - put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); - put_bits(&s->pb, 1, sign); - } - } else { - put_bits(&s->pb, 1, sign); - } - last_non_zero = i; - } - } -} - void msmpeg4_encode_mb(MpegEncContext * s, DCTELEM block[6][64], int motion_x, int motion_y) @@ -1036,6 +912,129 @@ static void msmpeg4_encode_dc(MpegEncContext * s, int level, int n, int *dir_ptr } } +/* Encoding of a block. Very similar to MPEG4 except for a different + escape coding (same as H263) and more vlc tables. + */ +static inline void msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n) +{ + int level, run, last, i, j, last_index; + int last_non_zero, sign, slevel; + int code, run_diff, dc_pred_dir; + const RLTable *rl; + const uint8_t *scantable; + + if (s->mb_intra) { + set_stat(ST_DC); + msmpeg4_encode_dc(s, block[0], n, &dc_pred_dir); + i = 1; + if (n < 4) { + rl = &rl_table[s->rl_table_index]; + } else { + rl = &rl_table[3 + s->rl_chroma_table_index]; + } + run_diff = 0; + scantable= s->intra_scantable.permutated; + set_stat(ST_INTRA_AC); + } else { + i = 0; + rl = &rl_table[3 + s->rl_table_index]; + if(s->msmpeg4_version<=2) + run_diff = 0; + else + run_diff = 1; + scantable= s->inter_scantable.permutated; + set_stat(ST_INTER_AC); + } + + /* recalculate block_last_index for M$ wmv1 */ + if(s->msmpeg4_version>=4 && s->block_last_index[n]>0){ + for(last_index=63; last_index>=0; last_index--){ + if(block[scantable[last_index]]) break; + } + s->block_last_index[n]= last_index; + }else + last_index = s->block_last_index[n]; + /* AC coefs */ + last_non_zero = i - 1; + for (; i <= last_index; i++) { + j = scantable[i]; + level = block[j]; + if (level) { + run = i - last_non_zero - 1; + last = (i == last_index); + sign = 0; + slevel = level; + if (level < 0) { + sign = 1; + level = -level; + } + + if(level<=MAX_LEVEL && run<=MAX_RUN){ + s->ac_stats[s->mb_intra][n>3][level][run][last]++; + } +#if 0 +else + s->ac_stats[s->mb_intra][n>3][40][63][0]++; //esc3 like +#endif + code = get_rl_index(rl, last, run, level); + put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); + if (code == rl->n) { + int level1, run1; + + level1 = level - rl->max_level[last][run]; + if (level1 < 1) + goto esc2; + code = get_rl_index(rl, last, run, level1); + if (code == rl->n) { + esc2: + put_bits(&s->pb, 1, 0); + if (level > MAX_LEVEL) + goto esc3; + run1 = run - rl->max_run[last][level] - run_diff; + if (run1 < 0) + goto esc3; + code = get_rl_index(rl, last, run1, level); + if (code == rl->n) { + esc3: + /* third escape */ + put_bits(&s->pb, 1, 0); + put_bits(&s->pb, 1, last); + if(s->msmpeg4_version>=4){ + if(s->esc3_level_length==0){ + s->esc3_level_length=8; + s->esc3_run_length= 6; + if(s->qscale<8) + put_bits(&s->pb, 6, 3); + else + put_bits(&s->pb, 8, 3); + } + put_bits(&s->pb, s->esc3_run_length, run); + put_bits(&s->pb, 1, sign); + put_bits(&s->pb, s->esc3_level_length, level); + }else{ + put_bits(&s->pb, 6, run); + put_bits(&s->pb, 8, slevel & 0xff); + } + } else { + /* second escape */ + put_bits(&s->pb, 1, 1); + put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); + put_bits(&s->pb, 1, sign); + } + } else { + /* first escape */ + put_bits(&s->pb, 1, 1); + put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); + put_bits(&s->pb, 1, sign); + } + } else { + put_bits(&s->pb, 1, sign); + } + last_non_zero = i; + } + } +} + /****************************************/ /* decoding stuff */ @@ -1480,6 +1479,185 @@ static int msmpeg4v2_decode_motion(MpegEncContext * s, int pred, int f_code) return val; } +static int msmpeg4v12_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) +{ + int cbp, code, i; + + if (s->pict_type == P_TYPE) { + if (s->use_skip_mb_code) { + if (get_bits1(&s->gb)) { + /* skip mb */ + s->mb_intra = 0; + for(i=0;i<6;i++) + s->block_last_index[i] = -1; + s->mv_dir = MV_DIR_FORWARD; + s->mv_type = MV_TYPE_16X16; + s->mv[0][0][0] = 0; + s->mv[0][0][1] = 0; + s->mb_skipped = 1; + return 0; + } + } + + if(s->msmpeg4_version==2) + code = get_vlc2(&s->gb, v2_mb_type_vlc.table, V2_MB_TYPE_VLC_BITS, 1); + else + code = get_vlc2(&s->gb, v1_inter_cbpc_vlc.table, V1_INTER_CBPC_VLC_BITS, 3); + if(code<0 || code>7){ + av_log(s->avctx, AV_LOG_ERROR, "cbpc %d invalid at %d %d\n", code, s->mb_x, s->mb_y); + return -1; + } + + s->mb_intra = code >>2; + + cbp = code & 0x3; + } else { + s->mb_intra = 1; + if(s->msmpeg4_version==2) + cbp= get_vlc2(&s->gb, v2_intra_cbpc_vlc.table, V2_INTRA_CBPC_VLC_BITS, 1); + else + cbp= get_vlc2(&s->gb, v1_intra_cbpc_vlc.table, V1_INTRA_CBPC_VLC_BITS, 1); + if(cbp<0 || cbp>3){ + av_log(s->avctx, AV_LOG_ERROR, "cbpc %d invalid at %d %d\n", cbp, s->mb_x, s->mb_y); + return -1; + } + } + + if (!s->mb_intra) { + int mx, my, cbpy; + + cbpy= get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1); + if(cbpy<0){ + av_log(s->avctx, AV_LOG_ERROR, "cbpy %d invalid at %d %d\n", cbp, s->mb_x, s->mb_y); + return -1; + } + + cbp|= cbpy<<2; + if(s->msmpeg4_version==1 || (cbp&3) != 3) cbp^= 0x3C; + + h263_pred_motion(s, 0, 0, &mx, &my); + mx= msmpeg4v2_decode_motion(s, mx, 1); + my= msmpeg4v2_decode_motion(s, my, 1); + + s->mv_dir = MV_DIR_FORWARD; + s->mv_type = MV_TYPE_16X16; + s->mv[0][0][0] = mx; + s->mv[0][0][1] = my; + } else { + if(s->msmpeg4_version==2){ + s->ac_pred = get_bits1(&s->gb); + cbp|= get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1)<<2; //FIXME check errors + } else{ + s->ac_pred = 0; + cbp|= get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1)<<2; //FIXME check errors + if(s->pict_type==P_TYPE) cbp^=0x3C; + } + } + + s->dsp.clear_blocks(s->block[0]); + for (i = 0; i < 6; i++) { + if (msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0) + { + av_log(s->avctx, AV_LOG_ERROR, "\nerror while decoding block: %d x %d (%d)\n", s->mb_x, s->mb_y, i); + return -1; + } + } + return 0; +} + +static int msmpeg4v34_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) +{ + int cbp, code, i; + uint8_t *coded_val; + uint32_t * const mb_type_ptr= &s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride ]; + + if (s->pict_type == P_TYPE) { + set_stat(ST_INTER_MB); + if (s->use_skip_mb_code) { + if (get_bits1(&s->gb)) { + /* skip mb */ + s->mb_intra = 0; + for(i=0;i<6;i++) + s->block_last_index[i] = -1; + s->mv_dir = MV_DIR_FORWARD; + s->mv_type = MV_TYPE_16X16; + s->mv[0][0][0] = 0; + s->mv[0][0][1] = 0; + s->mb_skipped = 1; + *mb_type_ptr = MB_TYPE_SKIP | MB_TYPE_L0 | MB_TYPE_16x16; + + return 0; + } + } + + code = get_vlc2(&s->gb, mb_non_intra_vlc[DEFAULT_INTER_INDEX].table, MB_NON_INTRA_VLC_BITS, 3); + if (code < 0) + return -1; + //s->mb_intra = (code & 0x40) ? 0 : 1; + s->mb_intra = (~code & 0x40) >> 6; + + cbp = code & 0x3f; + } else { + set_stat(ST_INTRA_MB); + s->mb_intra = 1; + code = get_vlc2(&s->gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2); + if (code < 0) + return -1; + /* predict coded block pattern */ + cbp = 0; + for(i=0;i<6;i++) { + int val = ((code >> (5 - i)) & 1); + if (i < 4) { + int pred = coded_block_pred(s, i, &coded_val); + val = val ^ pred; + *coded_val = val; + } + cbp |= val << (5 - i); + } + } + + if (!s->mb_intra) { + int mx, my; +//printf("P at %d %d\n", s->mb_x, s->mb_y); + if(s->per_mb_rl_table && cbp){ + s->rl_table_index = decode012(&s->gb); + s->rl_chroma_table_index = s->rl_table_index; + } + set_stat(ST_MV); + h263_pred_motion(s, 0, 0, &mx, &my); + if (msmpeg4_decode_motion(s, &mx, &my) < 0) + return -1; + s->mv_dir = MV_DIR_FORWARD; + s->mv_type = MV_TYPE_16X16; + s->mv[0][0][0] = mx; + s->mv[0][0][1] = my; + *mb_type_ptr = MB_TYPE_L0 | MB_TYPE_16x16; + } else { +//printf("I at %d %d %d %06X\n", s->mb_x, s->mb_y, ((cbp&3)? 1 : 0) +((cbp&0x3C)? 2 : 0), show_bits(&s->gb, 24)); + set_stat(ST_INTRA_MB); + s->ac_pred = get_bits1(&s->gb); + *mb_type_ptr = MB_TYPE_INTRA; + if(s->inter_intra_pred){ + s->h263_aic_dir= get_vlc2(&s->gb, inter_intra_vlc.table, INTER_INTRA_VLC_BITS, 1); +// printf("%d%d %d %d/", s->ac_pred, s->h263_aic_dir, s->mb_x, s->mb_y); + } + if(s->per_mb_rl_table && cbp){ + s->rl_table_index = decode012(&s->gb); + s->rl_chroma_table_index = s->rl_table_index; + } + } + + s->dsp.clear_blocks(s->block[0]); + for (i = 0; i < 6; i++) { + if (msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0) + { + av_log(s->avctx, AV_LOG_ERROR, "\nerror while decoding block: %d x %d (%d)\n", s->mb_x, s->mb_y, i); + return -1; + } + } + + return 0; +} //#define ERROR_DETAILS static inline int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, int n, int coded, const uint8_t *scan_table) @@ -1643,9 +1821,9 @@ static inline int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, if(last) i+=192; #ifdef ERROR_DETAILS if(run==66) - fprintf(stderr, "illegal vlc code in ESC3 level=%d\n", level); + av_log(s->avctx, AV_LOG_ERROR, "illegal vlc code in ESC3 level=%d\n", level); else if((i>62 && i<192) || i>192+63) - fprintf(stderr, "run overflow in ESC3 i=%d run=%d level=%d\n", i, run, level); + av_log(s->avctx, AV_LOG_ERROR, "run overflow in ESC3 i=%d run=%d level=%d\n", i, run, level); #endif } else { /* second escape */ @@ -1661,9 +1839,9 @@ static inline int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, LAST_SKIP_BITS(re, &s->gb, 1); #ifdef ERROR_DETAILS if(run==66) - fprintf(stderr, "illegal vlc code in ESC2 level=%d\n", level); + av_log(s->avctx, AV_LOG_ERROR, "illegal vlc code in ESC2 level=%d\n", level); else if((i>62 && i<192) || i>192+63) - fprintf(stderr, "run overflow in ESC2 i=%d run=%d level=%d\n", i, run, level); + av_log(s->avctx, AV_LOG_ERROR, "run overflow in ESC2 i=%d run=%d level=%d\n", i, run, level); #endif } } else { @@ -1681,9 +1859,9 @@ static inline int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, LAST_SKIP_BITS(re, &s->gb, 1); #ifdef ERROR_DETAILS if(run==66) - fprintf(stderr, "illegal vlc code in ESC1 level=%d\n", level); + av_log(s->avctx, AV_LOG_ERROR, "illegal vlc code in ESC1 level=%d\n", level); else if((i>62 && i<192) || i>192+63) - fprintf(stderr, "run overflow in ESC1 i=%d run=%d level=%d\n", i, run, level); + av_log(s->avctx, AV_LOG_ERROR, "run overflow in ESC1 i=%d run=%d level=%d\n", i, run, level); #endif } } else { @@ -1692,9 +1870,9 @@ static inline int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, LAST_SKIP_BITS(re, &s->gb, 1); #ifdef ERROR_DETAILS if(run==66) - fprintf(stderr, "illegal vlc code level=%d\n", level); + av_log(s->avctx, AV_LOG_ERROR, "illegal vlc code level=%d\n", level); else if((i>62 && i<192) || i>192+63) - fprintf(stderr, "run overflow i=%d run=%d level=%d\n", i, run, level); + av_log(s->avctx, AV_LOG_ERROR, "run overflow i=%d run=%d level=%d\n", i, run, level); #endif } if (i > 62){ @@ -1731,186 +1909,6 @@ static inline int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, return 0; } -static int msmpeg4v12_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) -{ - int cbp, code, i; - - if (s->pict_type == P_TYPE) { - if (s->use_skip_mb_code) { - if (get_bits1(&s->gb)) { - /* skip mb */ - s->mb_intra = 0; - for(i=0;i<6;i++) - s->block_last_index[i] = -1; - s->mv_dir = MV_DIR_FORWARD; - s->mv_type = MV_TYPE_16X16; - s->mv[0][0][0] = 0; - s->mv[0][0][1] = 0; - s->mb_skipped = 1; - return 0; - } - } - - if(s->msmpeg4_version==2) - code = get_vlc2(&s->gb, v2_mb_type_vlc.table, V2_MB_TYPE_VLC_BITS, 1); - else - code = get_vlc2(&s->gb, v1_inter_cbpc_vlc.table, V1_INTER_CBPC_VLC_BITS, 3); - if(code<0 || code>7){ - av_log(s->avctx, AV_LOG_ERROR, "cbpc %d invalid at %d %d\n", code, s->mb_x, s->mb_y); - return -1; - } - - s->mb_intra = code >>2; - - cbp = code & 0x3; - } else { - s->mb_intra = 1; - if(s->msmpeg4_version==2) - cbp= get_vlc2(&s->gb, v2_intra_cbpc_vlc.table, V2_INTRA_CBPC_VLC_BITS, 1); - else - cbp= get_vlc2(&s->gb, v1_intra_cbpc_vlc.table, V1_INTRA_CBPC_VLC_BITS, 1); - if(cbp<0 || cbp>3){ - av_log(s->avctx, AV_LOG_ERROR, "cbpc %d invalid at %d %d\n", cbp, s->mb_x, s->mb_y); - return -1; - } - } - - if (!s->mb_intra) { - int mx, my, cbpy; - - cbpy= get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1); - if(cbpy<0){ - av_log(s->avctx, AV_LOG_ERROR, "cbpy %d invalid at %d %d\n", cbp, s->mb_x, s->mb_y); - return -1; - } - - cbp|= cbpy<<2; - if(s->msmpeg4_version==1 || (cbp&3) != 3) cbp^= 0x3C; - - h263_pred_motion(s, 0, 0, &mx, &my); - mx= msmpeg4v2_decode_motion(s, mx, 1); - my= msmpeg4v2_decode_motion(s, my, 1); - - s->mv_dir = MV_DIR_FORWARD; - s->mv_type = MV_TYPE_16X16; - s->mv[0][0][0] = mx; - s->mv[0][0][1] = my; - } else { - if(s->msmpeg4_version==2){ - s->ac_pred = get_bits1(&s->gb); - cbp|= get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1)<<2; //FIXME check errors - } else{ - s->ac_pred = 0; - cbp|= get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1)<<2; //FIXME check errors - if(s->pict_type==P_TYPE) cbp^=0x3C; - } - } - - s->dsp.clear_blocks(s->block[0]); - for (i = 0; i < 6; i++) { - if (msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0) - { - av_log(s->avctx, AV_LOG_ERROR, "\nerror while decoding block: %d x %d (%d)\n", s->mb_x, s->mb_y, i); - return -1; - } - } - return 0; -} - -static int msmpeg4v34_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) -{ - int cbp, code, i; - uint8_t *coded_val; - uint32_t * const mb_type_ptr= &s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride ]; - - if (s->pict_type == P_TYPE) { - set_stat(ST_INTER_MB); - if (s->use_skip_mb_code) { - if (get_bits1(&s->gb)) { - /* skip mb */ - s->mb_intra = 0; - for(i=0;i<6;i++) - s->block_last_index[i] = -1; - s->mv_dir = MV_DIR_FORWARD; - s->mv_type = MV_TYPE_16X16; - s->mv[0][0][0] = 0; - s->mv[0][0][1] = 0; - s->mb_skipped = 1; - *mb_type_ptr = MB_TYPE_SKIP | MB_TYPE_L0 | MB_TYPE_16x16; - - return 0; - } - } - - code = get_vlc2(&s->gb, mb_non_intra_vlc[DEFAULT_INTER_INDEX].table, MB_NON_INTRA_VLC_BITS, 3); - if (code < 0) - return -1; - //s->mb_intra = (code & 0x40) ? 0 : 1; - s->mb_intra = (~code & 0x40) >> 6; - - cbp = code & 0x3f; - } else { - set_stat(ST_INTRA_MB); - s->mb_intra = 1; - code = get_vlc2(&s->gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2); - if (code < 0) - return -1; - /* predict coded block pattern */ - cbp = 0; - for(i=0;i<6;i++) { - int val = ((code >> (5 - i)) & 1); - if (i < 4) { - int pred = coded_block_pred(s, i, &coded_val); - val = val ^ pred; - *coded_val = val; - } - cbp |= val << (5 - i); - } - } - - if (!s->mb_intra) { - int mx, my; -//printf("P at %d %d\n", s->mb_x, s->mb_y); - if(s->per_mb_rl_table && cbp){ - s->rl_table_index = decode012(&s->gb); - s->rl_chroma_table_index = s->rl_table_index; - } - set_stat(ST_MV); - h263_pred_motion(s, 0, 0, &mx, &my); - if (msmpeg4_decode_motion(s, &mx, &my) < 0) - return -1; - s->mv_dir = MV_DIR_FORWARD; - s->mv_type = MV_TYPE_16X16; - s->mv[0][0][0] = mx; - s->mv[0][0][1] = my; - *mb_type_ptr = MB_TYPE_L0 | MB_TYPE_16x16; - } else { -//printf("I at %d %d %d %06X\n", s->mb_x, s->mb_y, ((cbp&3)? 1 : 0) +((cbp&0x3C)? 2 : 0), show_bits(&s->gb, 24)); - set_stat(ST_INTRA_MB); - s->ac_pred = get_bits1(&s->gb); - *mb_type_ptr = MB_TYPE_INTRA; - if(s->inter_intra_pred){ - s->h263_aic_dir= get_vlc2(&s->gb, inter_intra_vlc.table, INTER_INTRA_VLC_BITS, 1); -// printf("%d%d %d %d/", s->ac_pred, s->h263_aic_dir, s->mb_x, s->mb_y); - } - if(s->per_mb_rl_table && cbp){ - s->rl_table_index = decode012(&s->gb); - s->rl_chroma_table_index = s->rl_table_index; - } - } - - s->dsp.clear_blocks(s->block[0]); - for (i = 0; i < 6; i++) { - if (msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0) - { - av_log(s->avctx, AV_LOG_ERROR, "\nerror while decoding block: %d x %d (%d)\n", s->mb_x, s->mb_y, i); - return -1; - } - } - - return 0; -} - static int msmpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr) { int level, pred; diff --git a/src/libffmpeg/libavcodec/opt.h b/src/libffmpeg/libavcodec/opt.h new file mode 100644 index 000000000..c84db00fe --- /dev/null +++ b/src/libffmpeg/libavcodec/opt.h @@ -0,0 +1,61 @@ +#ifndef AVOPT_H +#define AVOPT_H + +/** + * @file opt.h + * AVOptions + */ + +enum AVOptionType{ + FF_OPT_TYPE_FLAGS, + FF_OPT_TYPE_INT, + FF_OPT_TYPE_INT64, + FF_OPT_TYPE_DOUBLE, + FF_OPT_TYPE_FLOAT, + FF_OPT_TYPE_STRING, + FF_OPT_TYPE_RATIONAL, + FF_OPT_TYPE_CONST=128, +}; + +/** + * AVOption. + */ +typedef struct AVOption { + const char *name; + + /** + * short English text help. + * @fixme what about other languages + */ + const char *help; + int offset; ///< offset to context structure where the parsed value should be stored + enum AVOptionType type; + + double default_val; + double min; + double max; + + int flags; +#define AV_OPT_FLAG_ENCODING_PARAM 1 ///< a generic parameter which can be set by the user for muxing or encoding +#define AV_OPT_FLAG_DECODING_PARAM 2 ///< a generic parameter which can be set by the user for demuxing or decoding +#define AV_OPT_FLAG_METADATA 4 ///< some data extracted or inserted into the file like title, comment, ... +#define AV_OPT_FLAG_AUDIO_PARAM 8 +#define AV_OPT_FLAG_VIDEO_PARAM 16 +#define AV_OPT_FLAG_SUBTITLE_PARAM 32 +//FIXME think about enc-audio, ... style flags + const char *unit; +} AVOption; + + +AVOption *av_set_string(void *obj, const char *name, const char *val); +AVOption *av_set_double(void *obj, const char *name, double n); +AVOption *av_set_q(void *obj, const char *name, AVRational n); +AVOption *av_set_int(void *obj, const char *name, int64_t n); +double av_get_double(void *obj, const char *name, AVOption **o_out); +AVRational av_get_q(void *obj, const char *name, AVOption **o_out); +int64_t av_get_int(void *obj, const char *name, AVOption **o_out); +const char *av_get_string(void *obj, const char *name, AVOption **o_out, char *buf, int buf_len); +AVOption *av_next_option(void *obj, AVOption *last); +int av_opt_show(void *obj, void *av_log_obj); + +#endif diff --git a/src/libffmpeg/libavcodec/parser.c b/src/libffmpeg/libavcodec/parser.c index 280bb45f5..06cb7d177 100644 --- a/src/libffmpeg/libavcodec/parser.c +++ b/src/libffmpeg/libavcodec/parser.c @@ -159,7 +159,8 @@ int av_parser_change(AVCodecParserContext *s, } } - *poutbuf= buf; + /* cast to avoid warning about discarding qualifiers */ + *poutbuf= (uint8_t *) buf; *poutbuf_size= buf_size; if(avctx->extradata){ if( (keyframe && (avctx->flags2 & CODEC_FLAG2_LOCAL_HEADER)) @@ -429,13 +430,18 @@ static int mpegvideo_parse(AVCodecParserContext *s, ParseContext1 *pc1 = s->priv_data; ParseContext *pc= &pc1->pc; int next; - - next= ff_mpeg1_find_frame_end(pc, buf, buf_size); - - if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) { - *poutbuf = NULL; - *poutbuf_size = 0; - return buf_size; + + if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){ + next= buf_size; + }else{ + next= ff_mpeg1_find_frame_end(pc, buf, buf_size); + + if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) { + *poutbuf = NULL; + *poutbuf_size = 0; + return buf_size; + } + } /* we have a full frame : we just parse the first few MPEG headers to have the full timing information. The time take by this @@ -506,6 +512,7 @@ static int av_mpeg4_decode_header(AVCodecParserContext *s1, if (s->width) { avcodec_set_dimensions(avctx, s->width, s->height); } + s1->pict_type= s->pict_type; pc->first_picture = 0; return ret; } @@ -529,12 +536,16 @@ static int mpeg4video_parse(AVCodecParserContext *s, ParseContext *pc = s->priv_data; int next; - next= ff_mpeg4_find_frame_end(pc, buf, buf_size); - - if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) { - *poutbuf = NULL; - *poutbuf_size = 0; - return buf_size; + if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){ + next= buf_size; + }else{ + next= ff_mpeg4_find_frame_end(pc, buf, buf_size); + + if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) { + *poutbuf = NULL; + *poutbuf_size = 0; + return buf_size; + } } av_mpeg4_decode_header(s, avctx, buf, buf_size); @@ -738,8 +749,13 @@ static int mpegaudio_parse(AVCodecParserContext *s1, } #ifdef CONFIG_AC3 +#ifdef CONFIG_A52BIN +extern int ff_a52_syncinfo (AVCodecContext * avctx, const uint8_t * buf, + int * flags, int * sample_rate, int * bit_rate); +#else extern int a52_syncinfo (const uint8_t * buf, int * flags, int * sample_rate, int * bit_rate); +#endif typedef struct AC3ParseContext { uint8_t inbuf[4096]; /* input buffer */ @@ -786,7 +802,11 @@ static int ac3_parse(AVCodecParserContext *s1, s->inbuf_ptr += len; buf_size -= len; if ((s->inbuf_ptr - s->inbuf) == AC3_HEADER_SIZE) { +#ifdef CONFIG_A52BIN + len = ff_a52_syncinfo(avctx, s->inbuf, &s->flags, &sample_rate, &bit_rate); +#else len = a52_syncinfo(s->inbuf, &s->flags, &sample_rate, &bit_rate); +#endif if (len == 0) { /* no sync found : move by one byte (inefficient, but simple!) */ memmove(s->inbuf, s->inbuf + 1, AC3_HEADER_SIZE - 1); diff --git a/src/libffmpeg/libavcodec/pcm.c b/src/libffmpeg/libavcodec/pcm.c index 8e57d11a1..e3a81a590 100644 --- a/src/libffmpeg/libavcodec/pcm.c +++ b/src/libffmpeg/libavcodec/pcm.c @@ -23,6 +23,7 @@ */ #include "avcodec.h" +#include "bitstream.h" // for ff_reverse /* from g711.c by SUN microsystems (unrestricted use) */ @@ -128,6 +129,19 @@ static int pcm_encode_init(AVCodecContext *avctx) } switch(avctx->codec->id) { + case CODEC_ID_PCM_S32LE: + case CODEC_ID_PCM_S32BE: + case CODEC_ID_PCM_U32LE: + case CODEC_ID_PCM_U32BE: + avctx->block_align = 4 * avctx->channels; + break; + case CODEC_ID_PCM_S24LE: + case CODEC_ID_PCM_S24BE: + case CODEC_ID_PCM_U24LE: + case CODEC_ID_PCM_U24BE: + case CODEC_ID_PCM_S24DAUD: + avctx->block_align = 3 * avctx->channels; + break; case CODEC_ID_PCM_S16LE: case CODEC_ID_PCM_S16BE: case CODEC_ID_PCM_U16LE: @@ -170,6 +184,30 @@ static int pcm_encode_close(AVCodecContext *avctx) return 0; } +/** + * \brief convert samples from 16 bit + * \param bps byte per sample for the destination format, must be >= 2 + * \param le 0 for big-, 1 for little-endian + * \param us 0 for signed, 1 for unsigned output + * \param samples input samples + * \param dst output samples + * \param n number of samples in samples buffer. + */ +static inline void encode_from16(int bps, int le, int us, + short **samples, uint8_t **dst, int n) { + if (bps > 2) + memset(*dst, 0, n * bps); + if (le) *dst += bps - 2; + for(;n>0;n--) { + register int v = *(*samples)++; + if (us) v += 0x8000; + (*dst)[le] = v >> 8; + (*dst)[1 - le] = v; + *dst += bps; + } + if (le) *dst -= bps - 2; +} + static int pcm_encode_frame(AVCodecContext *avctx, unsigned char *frame, int buf_size, void *data) { @@ -178,6 +216,19 @@ static int pcm_encode_frame(AVCodecContext *avctx, unsigned char *dst; switch(avctx->codec->id) { + case CODEC_ID_PCM_S32LE: + case CODEC_ID_PCM_S32BE: + case CODEC_ID_PCM_U32LE: + case CODEC_ID_PCM_U32BE: + sample_size = 4; + break; + case CODEC_ID_PCM_S24LE: + case CODEC_ID_PCM_S24BE: + case CODEC_ID_PCM_U24LE: + case CODEC_ID_PCM_U24BE: + case CODEC_ID_PCM_S24DAUD: + sample_size = 3; + break; case CODEC_ID_PCM_S16LE: case CODEC_ID_PCM_S16BE: case CODEC_ID_PCM_U16LE: @@ -193,6 +244,43 @@ static int pcm_encode_frame(AVCodecContext *avctx, dst = frame; switch(avctx->codec->id) { + case CODEC_ID_PCM_S32LE: + encode_from16(4, 1, 0, &samples, &dst, n); + break; + case CODEC_ID_PCM_S32BE: + encode_from16(4, 0, 0, &samples, &dst, n); + break; + case CODEC_ID_PCM_U32LE: + encode_from16(4, 1, 1, &samples, &dst, n); + break; + case CODEC_ID_PCM_U32BE: + encode_from16(4, 0, 1, &samples, &dst, n); + break; + case CODEC_ID_PCM_S24LE: + encode_from16(3, 1, 0, &samples, &dst, n); + break; + case CODEC_ID_PCM_S24BE: + encode_from16(3, 0, 0, &samples, &dst, n); + break; + case CODEC_ID_PCM_U24LE: + encode_from16(3, 1, 1, &samples, &dst, n); + break; + case CODEC_ID_PCM_U24BE: + encode_from16(3, 0, 1, &samples, &dst, n); + break; + case CODEC_ID_PCM_S24DAUD: + for(;n>0;n--) { + uint32_t tmp = ff_reverse[*samples >> 8] + + (ff_reverse[*samples & 0xff] << 8); + tmp <<= 4; // sync flags would go here + dst[2] = tmp & 0xff; + tmp >>= 8; + dst[1] = tmp & 0xff; + dst[0] = tmp >> 8; + samples++; + dst += 3; + } + break; case CODEC_ID_PCM_S16LE: for(;n>0;n--) { v = *samples++; @@ -287,6 +375,27 @@ static int pcm_decode_init(AVCodecContext * avctx) return 0; } +/** + * \brief convert samples to 16 bit + * \param bps byte per sample for the source format, must be >= 2 + * \param le 0 for big-, 1 for little-endian + * \param us 0 for signed, 1 for unsigned input + * \param src input samples + * \param samples output samples + * \param src_len number of bytes in src + */ +static inline void decode_to16(int bps, int le, int us, + uint8_t **src, short **samples, int src_len) +{ + register int n = src_len / bps; + if (le) *src += bps - 2; + for(;n>0;n--) { + *(*samples)++ = ((*src)[le] << 8 | (*src)[1 - le]) - (us?0x8000:0); + *src += bps; + } + if (le) *src -= bps - 2; +} + static int pcm_decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size) @@ -303,6 +412,40 @@ static int pcm_decode_frame(AVCodecContext *avctx, buf_size = AVCODEC_MAX_AUDIO_FRAME_SIZE/2; switch(avctx->codec->id) { + case CODEC_ID_PCM_S32LE: + decode_to16(4, 1, 0, &src, &samples, buf_size); + break; + case CODEC_ID_PCM_S32BE: + decode_to16(4, 0, 0, &src, &samples, buf_size); + break; + case CODEC_ID_PCM_U32LE: + decode_to16(4, 1, 1, &src, &samples, buf_size); + break; + case CODEC_ID_PCM_U32BE: + decode_to16(4, 0, 1, &src, &samples, buf_size); + break; + case CODEC_ID_PCM_S24LE: + decode_to16(3, 1, 0, &src, &samples, buf_size); + break; + case CODEC_ID_PCM_S24BE: + decode_to16(3, 0, 0, &src, &samples, buf_size); + break; + case CODEC_ID_PCM_U24LE: + decode_to16(3, 1, 1, &src, &samples, buf_size); + break; + case CODEC_ID_PCM_U24BE: + decode_to16(3, 0, 1, &src, &samples, buf_size); + break; + case CODEC_ID_PCM_S24DAUD: + n = buf_size / 3; + for(;n>0;n--) { + uint32_t v = src[0] << 16 | src[1] << 8 | src[2]; + v >>= 4; // sync flags are here + *samples++ = ff_reverse[(v >> 8) & 0xff] + + (ff_reverse[v & 0xff] << 8); + src += 3; + } + break; case CODEC_ID_PCM_S16LE: n = buf_size >> 1; for(;n>0;n--) { @@ -382,6 +525,15 @@ AVCodec name ## _decoder = { \ pcm_decode_frame, \ } +PCM_CODEC(CODEC_ID_PCM_S32LE, pcm_s32le); +PCM_CODEC(CODEC_ID_PCM_S32BE, pcm_s32be); +PCM_CODEC(CODEC_ID_PCM_U32LE, pcm_u32le); +PCM_CODEC(CODEC_ID_PCM_U32BE, pcm_u32be); +PCM_CODEC(CODEC_ID_PCM_S24LE, pcm_s24le); +PCM_CODEC(CODEC_ID_PCM_S24BE, pcm_s24be); +PCM_CODEC(CODEC_ID_PCM_U24LE, pcm_u24le); +PCM_CODEC(CODEC_ID_PCM_U24BE, pcm_u24be); +PCM_CODEC(CODEC_ID_PCM_S24DAUD, pcm_s24daud); PCM_CODEC(CODEC_ID_PCM_S16LE, pcm_s16le); PCM_CODEC(CODEC_ID_PCM_S16BE, pcm_s16be); PCM_CODEC(CODEC_ID_PCM_U16LE, pcm_u16le); diff --git a/src/libffmpeg/libavcodec/ppc/fdct_altivec.c b/src/libffmpeg/libavcodec/ppc/fdct_altivec.c index 97333432f..b38b909c6 100644 --- a/src/libffmpeg/libavcodec/ppc/fdct_altivec.c +++ b/src/libffmpeg/libavcodec/ppc/fdct_altivec.c @@ -18,7 +18,7 @@ */ -#include "../common.h" +#include "common.h" #include "../dsputil.h" #include "dsputil_altivec.h" #include "gcc_fixes.h" diff --git a/src/libffmpeg/libavcodec/qdm2.c b/src/libffmpeg/libavcodec/qdm2.c new file mode 100644 index 000000000..211859c46 --- /dev/null +++ b/src/libffmpeg/libavcodec/qdm2.c @@ -0,0 +1,2039 @@ +/* + * QDM2 compatible decoder + * Copyright (c) 2003 Ewald Snel + * Copyright (c) 2005 Benjamin Larsson + * Copyright (c) 2005 Alex Beregszaszi + * Copyright (c) 2005 Roberto Togni + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/** + * @file qdm2.c + * QDM2 decoder + * @author Ewald Snel, Benjamin Larsson, Alex Beregszaszi, Roberto Togni + * The decoder is not perfect yet, there are still some distorions expecially + * on files encoded with 16 or 8 subbands + */ + +#include <math.h> +#include <stddef.h> +#include <stdio.h> + +#define ALT_BITSTREAM_READER_LE +#include "avcodec.h" +#include "bitstream.h" +#include "dsputil.h" + +#ifdef CONFIG_MPEGAUDIO_HP +#define USE_HIGHPRECISION +#endif + +#include "mpegaudio.h" + +#include "qdm2data.h" + +#undef NDEBUG +#include <assert.h> + + +#define SOFTCLIP_THRESHOLD 27600 +#define HARDCLIP_THRESHOLD 35716 + + +#define QDM2_LIST_ADD(list, size, packet) \ +do { \ + if (size > 0) { \ + list[size - 1].next = &list[size]; \ + } \ + list[size].packet = packet; \ + list[size].next = NULL; \ + size++; \ +} while(0) + +// Result is 8, 16 or 30 +#define QDM2_SB_USED(sub_sampling) (((sub_sampling) >= 2) ? 30 : 8 << (sub_sampling)) + +#define FIX_NOISE_IDX(noise_idx) \ + if ((noise_idx) >= 3840) \ + (noise_idx) -= 3840; \ + +#define SB_DITHERING_NOISE(sb,noise_idx) (noise_table[(noise_idx)++] * sb_noise_attenuation[(sb)]) + +#define BITS_LEFT(length,gb) ((length) - get_bits_count ((gb))) + +#define SAMPLES_NEEDED \ + av_log (NULL,AV_LOG_INFO,"This file triggers some untested code. Please contact the developers.\n"); + +#define SAMPLES_NEEDED_2(why) \ + av_log (NULL,AV_LOG_INFO,"This file triggers some missing code. Please contact the developers.\nPosition: %s\n",why); + + +typedef int8_t sb_int8_array[2][30][64]; + +/** + * Subpacket + */ +typedef struct { + int type; ///< subpacket type + unsigned int size; ///< subpacket size + const uint8_t *data; ///< pointer to subpacket data (points to input data buffer, it's not a private copy) +} QDM2SubPacket; + +/** + * A node in subpacket list + */ +typedef struct _QDM2SubPNode { + QDM2SubPacket *packet; ///< packet + struct _QDM2SubPNode *next; ///< pointer to next packet in the list, NULL if leaf node +} QDM2SubPNode; + +typedef struct { + float level; + float *samples_im; + float *samples_re; + float *table; + int phase; + int phase_shift; + int duration; + short time_index; + short cutoff; +} FFTTone; + +typedef struct { + int16_t sub_packet; + uint8_t channel; + int16_t offset; + int16_t exp; + uint8_t phase; +} FFTCoefficient; + +typedef struct { + float re; + float im; +} QDM2Complex; + +typedef struct { + QDM2Complex complex[256 + 1] __attribute__((aligned(16))); + float samples_im[MPA_MAX_CHANNELS][256]; + float samples_re[MPA_MAX_CHANNELS][256]; +} QDM2FFT; + +/** + * QDM2 decoder context + */ +typedef struct { + /// Parameters from codec header, do not change during playback + int nb_channels; ///< number of channels + int channels; ///< number of channels + int group_size; ///< size of frame group (16 frames per group) + int fft_size; ///< size of FFT, in complex numbers + int checksum_size; ///< size of data block, used also for checksum + + /// Parameters built from header parameters, do not change during playback + int group_order; ///< order of frame group + int fft_order; ///< order of FFT (actually fftorder+1) + int fft_frame_size; ///< size of fft frame, in components (1 comples = re + im) + int frame_size; ///< size of data frame + int frequency_range; + int sub_sampling; ///< subsampling: 0=25%, 1=50%, 2=100% */ + int coeff_per_sb_select; ///< selector for "num. of coeffs. per subband" tables. Can be 0, 1, 2 + int cm_table_select; ///< selector for "coding method" tables. Can be 0, 1 (from init: 0-4) + + /// Packets and packet lists + QDM2SubPacket sub_packets[16]; ///< the packets themselves + QDM2SubPNode sub_packet_list_A[16]; ///< list of all packets + QDM2SubPNode sub_packet_list_B[16]; ///< FFT packets B are on list + int sub_packets_B; ///< number of packets on 'B' list + QDM2SubPNode sub_packet_list_C[16]; ///< packets with errors? + QDM2SubPNode sub_packet_list_D[16]; ///< DCT packets + + /// FFT and tones + FFTTone fft_tones[1000]; + int fft_tone_start; + int fft_tone_end; + FFTCoefficient fft_coefs[1000]; + int fft_coefs_index; + int fft_coefs_min_index[5]; + int fft_coefs_max_index[5]; + int fft_level_exp[6]; + FFTContext fft_ctx; + FFTComplex exptab[128]; + QDM2FFT fft; + + /// I/O data + uint8_t *compressed_data; + int compressed_size; + float output_buffer[1024]; + + /// Synthesis filter + MPA_INT synth_buf[MPA_MAX_CHANNELS][512*2] __attribute__((aligned(16))); + int synth_buf_offset[MPA_MAX_CHANNELS]; + int32_t sb_samples[MPA_MAX_CHANNELS][128][SBLIMIT] __attribute__((aligned(16))); + + /// Mixed temporary data used in decoding + float tone_level[MPA_MAX_CHANNELS][30][64]; + int8_t coding_method[MPA_MAX_CHANNELS][30][64]; + int8_t quantized_coeffs[MPA_MAX_CHANNELS][10][8]; + int8_t tone_level_idx_base[MPA_MAX_CHANNELS][30][8]; + int8_t tone_level_idx_hi1[MPA_MAX_CHANNELS][3][8][8]; + int8_t tone_level_idx_mid[MPA_MAX_CHANNELS][26][8]; + int8_t tone_level_idx_hi2[MPA_MAX_CHANNELS][26]; + int8_t tone_level_idx[MPA_MAX_CHANNELS][30][64]; + int8_t tone_level_idx_temp[MPA_MAX_CHANNELS][30][64]; + + // Flags + int has_errors; ///< packet have errors + int superblocktype_2_3; ///< select fft tables and some algorithm based on superblock type + int do_synth_filter; ///< used to perform or skip synthesis filter + + int sub_packet; + int noise_idx; ///< Index for dithering noise table +} QDM2Context; + + +static uint8_t empty_buffer[FF_INPUT_BUFFER_PADDING_SIZE]; + +static VLC vlc_tab_level; +static VLC vlc_tab_diff; +static VLC vlc_tab_run; +static VLC fft_level_exp_alt_vlc; +static VLC fft_level_exp_vlc; +static VLC fft_stereo_exp_vlc; +static VLC fft_stereo_phase_vlc; +static VLC vlc_tab_tone_level_idx_hi1; +static VLC vlc_tab_tone_level_idx_mid; +static VLC vlc_tab_tone_level_idx_hi2; +static VLC vlc_tab_type30; +static VLC vlc_tab_type34; +static VLC vlc_tab_fft_tone_offset[5]; + +static uint16_t softclip_table[HARDCLIP_THRESHOLD - SOFTCLIP_THRESHOLD + 1]; +static float noise_table[4096]; +static uint8_t random_dequant_index[256][5]; +static uint8_t random_dequant_type24[128][3]; +static float noise_samples[128]; + +static MPA_INT mpa_window[512] __attribute__((aligned(16))); + + +static void softclip_table_init() { + int i; + double dfl = SOFTCLIP_THRESHOLD - 32767; + float delta = 1.0 / -dfl; + for (i = 0; i < HARDCLIP_THRESHOLD - SOFTCLIP_THRESHOLD + 1; i++) + softclip_table[i] = SOFTCLIP_THRESHOLD - ((int)(sin((float)i * delta) * dfl) & 0x0000FFFF); +} + + +// random generated table +static void rnd_table_init() { + int i,j; + uint32_t ldw,hdw; + uint64_t tmp64_1; + uint64_t random_seed = 0; + float delta = 1.0 / 16384.0; + for(i = 0; i < 4096 ;i++) { + random_seed = random_seed * 214013 + 2531011; + noise_table[i] = (delta * (float)(((int32_t)random_seed >> 16) & 0x00007FFF)- 1.0) * 1.3; + } + + for (i = 0; i < 256 ;i++) { + random_seed = 81; + ldw = i; + for (j = 0; j < 5 ;j++) { + random_dequant_index[i][j] = (uint8_t)((ldw / random_seed) & 0xFF); + ldw = (uint32_t)ldw % (uint32_t)random_seed; + tmp64_1 = (random_seed * 0x55555556); + hdw = (uint32_t)(tmp64_1 >> 32); + random_seed = (uint64_t)(hdw + (ldw >> 31)); + } + } + for (i = 0; i < 128 ;i++) { + random_seed = 25; + ldw = i; + for (j = 0; j < 3 ;j++) { + random_dequant_type24[i][j] = (uint8_t)((ldw / random_seed) & 0xFF); + ldw = (uint32_t)ldw % (uint32_t)random_seed; + tmp64_1 = (random_seed * 0x66666667); + hdw = (uint32_t)(tmp64_1 >> 33); + random_seed = hdw + (ldw >> 31); + } + } +} + + +static void init_noise_samples() { + int i; + int random_seed = 0; + float delta = 1.0 / 16384.0; + for (i = 0; i < 128;i++) { + random_seed = random_seed * 214013 + 2531011; + noise_samples[i] = (delta * (float)((random_seed >> 16) & 0x00007fff) - 1.0); + } +} + + +static void qdm2_init_vlc() +{ + init_vlc (&vlc_tab_level, 8, 24, + vlc_tab_level_huffbits, 1, 1, + vlc_tab_level_huffcodes, 2, 2, INIT_VLC_USE_STATIC | INIT_VLC_LE); + + init_vlc (&vlc_tab_diff, 8, 37, + vlc_tab_diff_huffbits, 1, 1, + vlc_tab_diff_huffcodes, 2, 2, INIT_VLC_USE_STATIC | INIT_VLC_LE); + + init_vlc (&vlc_tab_run, 5, 6, + vlc_tab_run_huffbits, 1, 1, + vlc_tab_run_huffcodes, 1, 1, INIT_VLC_USE_STATIC | INIT_VLC_LE); + + init_vlc (&fft_level_exp_alt_vlc, 8, 28, + fft_level_exp_alt_huffbits, 1, 1, + fft_level_exp_alt_huffcodes, 2, 2, INIT_VLC_USE_STATIC | INIT_VLC_LE); + + init_vlc (&fft_level_exp_vlc, 8, 20, + fft_level_exp_huffbits, 1, 1, + fft_level_exp_huffcodes, 2, 2, INIT_VLC_USE_STATIC | INIT_VLC_LE); + + init_vlc (&fft_stereo_exp_vlc, 6, 7, + fft_stereo_exp_huffbits, 1, 1, + fft_stereo_exp_huffcodes, 1, 1, INIT_VLC_USE_STATIC | INIT_VLC_LE); + + init_vlc (&fft_stereo_phase_vlc, 6, 9, + fft_stereo_phase_huffbits, 1, 1, + fft_stereo_phase_huffcodes, 1, 1, INIT_VLC_USE_STATIC | INIT_VLC_LE); + + init_vlc (&vlc_tab_tone_level_idx_hi1, 8, 20, + vlc_tab_tone_level_idx_hi1_huffbits, 1, 1, + vlc_tab_tone_level_idx_hi1_huffcodes, 2, 2, INIT_VLC_USE_STATIC | INIT_VLC_LE); + + init_vlc (&vlc_tab_tone_level_idx_mid, 8, 24, + vlc_tab_tone_level_idx_mid_huffbits, 1, 1, + vlc_tab_tone_level_idx_mid_huffcodes, 2, 2, INIT_VLC_USE_STATIC | INIT_VLC_LE); + + init_vlc (&vlc_tab_tone_level_idx_hi2, 8, 24, + vlc_tab_tone_level_idx_hi2_huffbits, 1, 1, + vlc_tab_tone_level_idx_hi2_huffcodes, 2, 2, INIT_VLC_USE_STATIC | INIT_VLC_LE); + + init_vlc (&vlc_tab_type30, 6, 9, + vlc_tab_type30_huffbits, 1, 1, + vlc_tab_type30_huffcodes, 1, 1, INIT_VLC_USE_STATIC | INIT_VLC_LE); + + init_vlc (&vlc_tab_type34, 5, 10, + vlc_tab_type34_huffbits, 1, 1, + vlc_tab_type34_huffcodes, 1, 1, INIT_VLC_USE_STATIC | INIT_VLC_LE); + + init_vlc (&vlc_tab_fft_tone_offset[0], 8, 23, + vlc_tab_fft_tone_offset_0_huffbits, 1, 1, + vlc_tab_fft_tone_offset_0_huffcodes, 2, 2, INIT_VLC_USE_STATIC | INIT_VLC_LE); + + init_vlc (&vlc_tab_fft_tone_offset[1], 8, 28, + vlc_tab_fft_tone_offset_1_huffbits, 1, 1, + vlc_tab_fft_tone_offset_1_huffcodes, 2, 2, INIT_VLC_USE_STATIC | INIT_VLC_LE); + + init_vlc (&vlc_tab_fft_tone_offset[2], 8, 32, + vlc_tab_fft_tone_offset_2_huffbits, 1, 1, + vlc_tab_fft_tone_offset_2_huffcodes, 2, 2, INIT_VLC_USE_STATIC | INIT_VLC_LE); + + init_vlc (&vlc_tab_fft_tone_offset[3], 8, 35, + vlc_tab_fft_tone_offset_3_huffbits, 1, 1, + vlc_tab_fft_tone_offset_3_huffcodes, 2, 2, INIT_VLC_USE_STATIC | INIT_VLC_LE); + + init_vlc (&vlc_tab_fft_tone_offset[4], 8, 38, + vlc_tab_fft_tone_offset_4_huffbits, 1, 1, + vlc_tab_fft_tone_offset_4_huffcodes, 2, 2, INIT_VLC_USE_STATIC | INIT_VLC_LE); +} + + +/* for floating point to fixed point conversion */ +static float f2i_scale = (float) (1 << (FRAC_BITS - 15)); + + +static int qdm2_get_vlc (GetBitContext *gb, VLC *vlc, int flag, int depth) +{ + int value; + + value = get_vlc2(gb, vlc->table, vlc->bits, depth); + + /* stage-2, 3 bits exponent escape sequence */ + if (value-- == 0) + value = get_bits (gb, get_bits (gb, 3) + 1); + + /* stage-3, optional */ + if (flag) { + int tmp = vlc_stage3_values[value]; + + if ((value & ~3) > 0) + tmp += get_bits (gb, (value >> 2)); + value = tmp; + } + + return value; +} + + +static int qdm2_get_se_vlc (VLC *vlc, GetBitContext *gb, int depth) +{ + int value = qdm2_get_vlc (gb, vlc, 0, depth); + + return (value & 1) ? ((value + 1) >> 1) : -(value >> 1); +} + + +/** + * QDM2 checksum + * + * @param data pointer to data to be checksum'ed + * @param length data length + * @param value checksum value + * + * @return 0 if checksum is ok + */ +static uint16_t qdm2_packet_checksum (uint8_t *data, int length, int value) { + int i; + + for (i=0; i < length; i++) + value -= data[i]; + + return (uint16_t)(value & 0xffff); +} + + +/** + * Fills a QDM2SubPacket structure with packet type, size, and data pointer + * + * @param gb bitreader context + * @param sub_packet packet under analysis + */ +static void qdm2_decode_sub_packet_header (GetBitContext *gb, QDM2SubPacket *sub_packet) +{ + sub_packet->type = get_bits (gb, 8); + + if (sub_packet->type == 0) { + sub_packet->size = 0; + sub_packet->data = NULL; + } else { + sub_packet->size = get_bits (gb, 8); + + if (sub_packet->type & 0x80) { + sub_packet->size <<= 8; + sub_packet->size |= get_bits (gb, 8); + sub_packet->type &= 0x7f; + } + + if (sub_packet->type == 0x7f) + sub_packet->type |= (get_bits (gb, 8) << 8); + + sub_packet->data = &gb->buffer[get_bits_count(gb) / 8]; // FIXME: this depends on bitreader internal data + } + + av_log(NULL,AV_LOG_DEBUG,"Sub packet: type=%d size=%d start_offs=%x\n", + sub_packet->type, sub_packet->size, get_bits_count(gb) / 8); +} + + +/** + * Return node pointer to first packet of requested type in list + * + * @param list list of subpacket to be scanned + * @param type type of searched subpacket + * @return node pointer for subpacket if found, else NULL + */ +static QDM2SubPNode* qdm2_search_subpacket_type_in_list (QDM2SubPNode *list, int type) +{ + while (list != NULL && list->packet != NULL) { + if (list->packet->type == type) + return list; + list = list->next; + } + return NULL; +} + + +/** + * Replaces 8 elements with their average value + * Called by qdm2_decode_superblock before starting subblocks decoding + * + * @param q context + */ +static void average_quantized_coeffs (QDM2Context *q) +{ + int i, j, n, ch, sum; + + n = coeff_per_sb_for_avg[q->coeff_per_sb_select][QDM2_SB_USED(q->sub_sampling) - 1] + 1; + + for (ch = 0; ch < q->nb_channels; ch++) + for (i = 0; i < n; i++) { + sum = 0; + + for (j = 0; j < 8; j++) + sum += q->quantized_coeffs[ch][i][j]; + + sum /= 8; + if (sum > 0) + sum--; + + for (j=0; j < 8; j++) + q->quantized_coeffs[ch][i][j] = sum; + } +} + + +/** + * Build subband samples with noise weighted by q->tone_level + * Called by synthfilt_build_sb_samples + * + * @param q context + * @param sb subband index + */ +static void build_sb_samples_from_noise (QDM2Context *q, int sb) +{ + int ch, j; + + FIX_NOISE_IDX(q->noise_idx); + + if (!q->nb_channels) + return; + + for (ch = 0; ch < q->nb_channels; ch++) + for (j = 0; j < 64; j++) { + q->sb_samples[ch][j * 2][sb] = (int32_t)(f2i_scale * SB_DITHERING_NOISE(sb,q->noise_idx) * q->tone_level[ch][sb][j] + .5); + q->sb_samples[ch][j * 2 + 1][sb] = (int32_t)(f2i_scale * SB_DITHERING_NOISE(sb,q->noise_idx) * q->tone_level[ch][sb][j] + .5); + } +} + + +/** + * Called while processing data from subpackets 11 and 12 + * Used after making changes to coding_method array + * + * @param sb subband index + * @param channels number of channels + * @param coding_method q->coding_method[0][0][0] + */ + void fix_coding_method_array (int sb, int channels, sb_int8_array coding_method) +{ + int j,k; + int ch; + int run, case_val; + int switchtable[23] = {0,5,1,5,5,5,5,5,2,5,5,5,5,5,5,5,3,5,5,5,5,5,4}; + + for (ch = 0; ch < channels; ch++) { + for (j = 0; j < 64; ) { + if((coding_method[ch][sb][j] - 8) > 22) { + run = 1; + case_val = 8; + } else { + switch (switchtable[coding_method[ch][sb][j]]) { + case 0: run = 10; case_val = 10; break; + case 1: run = 1; case_val = 16; break; + case 2: run = 5; case_val = 24; break; + case 3: run = 3; case_val = 30; break; + case 4: run = 1; case_val = 30; break; + case 5: run = 1; case_val = 8; break; + default: run = 1; case_val = 8; break; + } + } + for (k = 0; k < run; k++) + if (j + k < 128) + if (coding_method[ch][sb + (j + k) / 64][(j + k) % 64] > coding_method[ch][sb][j]) + if (k > 0) { + SAMPLES_NEEDED + //not debugged, almost never used + memset(&coding_method[ch][sb][j + k], case_val, k * sizeof(int8_t)); + memset(&coding_method[ch][sb][j + k], case_val, 3 * sizeof(int8_t)); + } + j += run; + } + } +} + + +/** + * Related to synthesis filter + * Called by process_subpacket_10 + * + * @param q context + * @param flag 1 if called after getting data from subpacket 10, 0 if no subpacket 10 + */ +static void fill_tone_level_array (QDM2Context *q, int flag) +{ + int i, sb, ch, sb_used; + int tmp, tab; + + // This should never happen + if (q->nb_channels <= 0) + return; + + for (ch = 0; ch < q->nb_channels; ch++) + for (sb = 0; sb < 30; sb++) + for (i = 0; i < 8; i++) { + if ((tab=coeff_per_sb_for_dequant[q->coeff_per_sb_select][sb]) < (last_coeff[q->coeff_per_sb_select] - 1)) + tmp = q->quantized_coeffs[ch][tab + 1][i] * dequant_table[q->coeff_per_sb_select][tab + 1][sb]+ + q->quantized_coeffs[ch][tab][i] * dequant_table[q->coeff_per_sb_select][tab][sb]; + else + tmp = q->quantized_coeffs[ch][tab][i] * dequant_table[q->coeff_per_sb_select][tab][sb]; + if(tmp < 0) + tmp += 0xff; + q->tone_level_idx_base[ch][sb][i] = (tmp / 256) & 0xff; + } + + sb_used = QDM2_SB_USED(q->sub_sampling); + + if ((q->superblocktype_2_3 != 0) && !flag) { + for (sb = 0; sb < sb_used; sb++) + for (ch = 0; ch < q->nb_channels; ch++) + for (i = 0; i < 64; i++) { + q->tone_level_idx[ch][sb][i] = q->tone_level_idx_base[ch][sb][i / 8]; + if (q->tone_level_idx[ch][sb][i] < 0) + q->tone_level[ch][sb][i] = 0; + else + q->tone_level[ch][sb][i] = fft_tone_level_table[0][q->tone_level_idx[ch][sb][i] & 0x3f]; + } + } else { + tab = q->superblocktype_2_3 ? 0 : 1; + for (sb = 0; sb < sb_used; sb++) { + if ((sb >= 4) && (sb <= 23)) { + for (ch = 0; ch < q->nb_channels; ch++) + for (i = 0; i < 64; i++) { + tmp = q->tone_level_idx_base[ch][sb][i / 8] - + q->tone_level_idx_hi1[ch][sb / 8][i / 8][i % 8] - + q->tone_level_idx_mid[ch][sb - 4][i / 8] - + q->tone_level_idx_hi2[ch][sb - 4]; + q->tone_level_idx[ch][sb][i] = tmp & 0xff; + if ((tmp < 0) || (!q->superblocktype_2_3 && !tmp)) + q->tone_level[ch][sb][i] = 0; + else + q->tone_level[ch][sb][i] = fft_tone_level_table[tab][tmp & 0x3f]; + } + } else { + if (sb > 4) { + for (ch = 0; ch < q->nb_channels; ch++) + for (i = 0; i < 64; i++) { + tmp = q->tone_level_idx_base[ch][sb][i / 8] - + q->tone_level_idx_hi1[ch][2][i / 8][i % 8] - + q->tone_level_idx_hi2[ch][sb - 4]; + q->tone_level_idx[ch][sb][i] = tmp & 0xff; + if ((tmp < 0) || (!q->superblocktype_2_3 && !tmp)) + q->tone_level[ch][sb][i] = 0; + else + q->tone_level[ch][sb][i] = fft_tone_level_table[tab][tmp & 0x3f]; + } + } else { + for (ch = 0; ch < q->nb_channels; ch++) + for (i = 0; i < 64; i++) { + tmp = q->tone_level_idx[ch][sb][i] = q->tone_level_idx_base[ch][sb][i / 8]; + if ((tmp < 0) || (!q->superblocktype_2_3 && !tmp)) + q->tone_level[ch][sb][i] = 0; + else + q->tone_level[ch][sb][i] = fft_tone_level_table[tab][tmp & 0x3f]; + } + } + } + } + } + + return; +} + + +/** + * Related to synthesis filter + * Called by process_subpacket_11 + * c is built with data from subpacket 11 + * Most of this function is used only if superblock_type_2_3 == 0, never seen it in samples + * + * @param tone_level_idx + * @param tone_level_idx_temp + * @param coding_method q->coding_method[0][0][0] + * @param nb_channels number of channels + * @param c coming from subpacket 11, passed as 8*c + * @param superblocktype_2_3 flag based on superblock packet type + * @param cm_table_select q->cm_table_select + */ +static void fill_coding_method_array (sb_int8_array tone_level_idx, sb_int8_array tone_level_idx_temp, + sb_int8_array coding_method, int nb_channels, + int c, int superblocktype_2_3, int cm_table_select) +{ + int ch, sb, j; + int tmp, acc, esp_40, comp; + int add1, add2, add3, add4; + int64_t multres; + + // This should never happen + if (nb_channels <= 0) + return; + + if (!superblocktype_2_3) { + /* This case is untested, no samples available */ + SAMPLES_NEEDED + for (ch = 0; ch < nb_channels; ch++) + for (sb = 0; sb < 30; sb++) { + for (j = 1; j < 64; j++) { + add1 = tone_level_idx[ch][sb][j] - 10; + if (add1 < 0) + add1 = 0; + add2 = add3 = add4 = 0; + if (sb > 1) { + add2 = tone_level_idx[ch][sb - 2][j] + tone_level_idx_offset_table[sb][0] - 6; + if (add2 < 0) + add2 = 0; + } + if (sb > 0) { + add3 = tone_level_idx[ch][sb - 1][j] + tone_level_idx_offset_table[sb][1] - 6; + if (add3 < 0) + add3 = 0; + } + if (sb < 29) { + add4 = tone_level_idx[ch][sb + 1][j] + tone_level_idx_offset_table[sb][3] - 6; + if (add4 < 0) + add4 = 0; + } + tmp = tone_level_idx[ch][sb][j + 1] * 2 - add4 - add3 - add2 - add1; + if (tmp < 0) + tmp = 0; + tone_level_idx_temp[ch][sb][j + 1] = tmp & 0xff; + } + tone_level_idx_temp[ch][sb][0] = tone_level_idx_temp[ch][sb][1]; + } + acc = 0; + for (ch = 0; ch < nb_channels; ch++) + for (sb = 0; sb < 30; sb++) + for (j = 0; j < 64; j++) + acc += tone_level_idx_temp[ch][sb][j]; + if (acc) + tmp = c * 256 / (acc & 0xffff); + multres = 0x66666667 * (acc * 10); + esp_40 = (multres >> 32) / 8 + ((multres & 0xffffffff) >> 31); + for (ch = 0; ch < nb_channels; ch++) + for (sb = 0; sb < 30; sb++) + for (j = 0; j < 64; j++) { + comp = tone_level_idx_temp[ch][sb][j]* esp_40 * 10; + if (comp < 0) + comp += 0xff; + comp /= 256; // signed shift + switch(sb) { + case 0: + if (comp < 30) + comp = 30; + comp += 15; + break; + case 1: + if (comp < 24) + comp = 24; + comp += 10; + break; + case 2: + case 3: + case 4: + if (comp < 16) + comp = 16; + } + if (comp <= 5) + tmp = 0; + else if (comp <= 10) + tmp = 10; + else if (comp <= 16) + tmp = 16; + else if (comp <= 24) + tmp = -1; + else + tmp = 0; + coding_method[ch][sb][j] = ((tmp & 0xfffa) + 30 )& 0xff; + } + for (sb = 0; sb < 30; sb++) + fix_coding_method_array(sb, nb_channels, coding_method); + for (ch = 0; ch < nb_channels; ch++) + for (sb = 0; sb < 30; sb++) + for (j = 0; j < 64; j++) + if (sb >= 10) { + if (coding_method[ch][sb][j] < 10) + coding_method[ch][sb][j] = 10; + } else { + if (sb >= 2) { + if (coding_method[ch][sb][j] < 16) + coding_method[ch][sb][j] = 16; + } else { + if (coding_method[ch][sb][j] < 30) + coding_method[ch][sb][j] = 30; + } + } + } else { // superblocktype_2_3 != 0 + for (ch = 0; ch < nb_channels; ch++) + for (sb = 0; sb < 30; sb++) + for (j = 0; j < 64; j++) + coding_method[ch][sb][j] = coding_method_table[cm_table_select][sb]; + } + + return; +} + + +/** + * + * Called by process_subpacket_11 to process more data from subpacket 11 with sb 0-8 + * Called by process_subpacket_12 to process data from subpacket 12 with sb 8-sb_used + * + * @param q context + * @param gb bitreader context + * @param length packet length in bit + * @param sb_min lower subband processed (sb_min included) + * @param sb_max higher subband processed (sb_max excluded) + */ +static void synthfilt_build_sb_samples (QDM2Context *q, GetBitContext *gb, int length, int sb_min, int sb_max) +{ + int sb, j, k, n, ch, run, channels; + int joined_stereo, zero_encoding, chs; + int type34_first; + float type34_div = 0; + float type34_predictor; + float samples[10], sign_bits[16]; + + if (length == 0) { + // If no data use noise + for (sb=sb_min; sb < sb_max; sb++) + build_sb_samples_from_noise (q, sb); + + return; + } + + for (sb = sb_min; sb < sb_max; sb++) { + FIX_NOISE_IDX(q->noise_idx); + + channels = q->nb_channels; + + if (q->nb_channels <= 1 || sb < 12) + joined_stereo = 0; + else if (sb >= 24) + joined_stereo = 1; + else + joined_stereo = (BITS_LEFT(length,gb) >= 1) ? get_bits1 (gb) : 0; + + if (joined_stereo) { + if (BITS_LEFT(length,gb) >= 16) + for (j = 0; j < 16; j++) + sign_bits[j] = get_bits1 (gb); + + for (j = 0; j < 64; j++) + if (q->coding_method[1][sb][j] > q->coding_method[0][sb][j]) + q->coding_method[0][sb][j] = q->coding_method[1][sb][j]; + + fix_coding_method_array(sb, q->nb_channels, q->coding_method); + channels = 1; + } + + for (ch = 0; ch < channels; ch++) { + zero_encoding = (BITS_LEFT(length,gb) >= 1) ? get_bits1(gb) : 0; + type34_predictor = 0.0; + type34_first = 1; + + for (j = 0; j < 128; ) { + switch (q->coding_method[ch][sb][j / 2]) { + case 8: + if (BITS_LEFT(length,gb) >= 10) { + if (zero_encoding) { + for (k = 0; k < 5; k++) { + if ((j + 2 * k) >= 128) + break; + samples[2 * k] = get_bits1(gb) ? dequant_1bit[joined_stereo][2 * get_bits1(gb)] : 0; + } + } else { + n = get_bits(gb, 8); + for (k = 0; k < 5; k++) + samples[2 * k] = dequant_1bit[joined_stereo][random_dequant_index[n][k]]; + } + for (k = 0; k < 5; k++) + samples[2 * k + 1] = SB_DITHERING_NOISE(sb,q->noise_idx); + } else { + for (k = 0; k < 10; k++) + samples[k] = SB_DITHERING_NOISE(sb,q->noise_idx); + } + run = 10; + break; + + case 10: + if (BITS_LEFT(length,gb) >= 1) { + float f = 0.81; + + if (get_bits1(gb)) + f = -f; + f -= noise_samples[((sb + 1) * (j +5 * ch + 1)) & 127] * 9.0 / 40.0; + samples[0] = f; + } else { + samples[0] = SB_DITHERING_NOISE(sb,q->noise_idx); + } + run = 1; + break; + + case 16: + if (BITS_LEFT(length,gb) >= 10) { + if (zero_encoding) { + for (k = 0; k < 5; k++) { + if ((j + k) >= 128) + break; + samples[k] = (get_bits1(gb) == 0) ? 0 : dequant_1bit[joined_stereo][2 * get_bits1(gb)]; + } + } else { + n = get_bits (gb, 8); + for (k = 0; k < 5; k++) + samples[k] = dequant_1bit[joined_stereo][random_dequant_index[n][k]]; + } + } else { + for (k = 0; k < 5; k++) + samples[k] = SB_DITHERING_NOISE(sb,q->noise_idx); + } + run = 5; + break; + + case 24: + if (BITS_LEFT(length,gb) >= 7) { + n = get_bits(gb, 7); + for (k = 0; k < 3; k++) + samples[k] = (random_dequant_type24[n][k] - 2.0) * 0.5; + } else { + for (k = 0; k < 3; k++) + samples[k] = SB_DITHERING_NOISE(sb,q->noise_idx); + } + run = 3; + break; + + case 30: + if (BITS_LEFT(length,gb) >= 4) + samples[0] = type30_dequant[qdm2_get_vlc(gb, &vlc_tab_type30, 0, 1)]; + else + samples[0] = SB_DITHERING_NOISE(sb,q->noise_idx); + + run = 1; + break; + + case 34: + if (BITS_LEFT(length,gb) >= 7) { + if (type34_first) { + type34_div = (float)(1 << get_bits(gb, 2)); + samples[0] = ((float)get_bits(gb, 5) - 16.0) / 15.0; + type34_predictor = samples[0]; + type34_first = 0; + } else { + samples[0] = type34_delta[qdm2_get_vlc(gb, &vlc_tab_type34, 0, 1)] / type34_div + type34_predictor; + type34_predictor = samples[0]; + } + } else { + samples[0] = SB_DITHERING_NOISE(sb,q->noise_idx); + } + run = 1; + break; + + default: + samples[0] = SB_DITHERING_NOISE(sb,q->noise_idx); + run = 1; + break; + } + + if (joined_stereo) { + float tmp[10][MPA_MAX_CHANNELS]; + + for (k = 0; k < run; k++) { + tmp[k][0] = samples[k]; + tmp[k][1] = (sign_bits[(j + k) / 8]) ? -samples[k] : samples[k]; + } + for (chs = 0; chs < q->nb_channels; chs++) + for (k = 0; k < run; k++) + if ((j + k) < 128) + q->sb_samples[chs][j + k][sb] = (int32_t)(f2i_scale * q->tone_level[chs][sb][((j + k)/2)] * tmp[k][chs] + .5); + } else { + for (k = 0; k < run; k++) + if ((j + k) < 128) + q->sb_samples[ch][j + k][sb] = (int32_t)(f2i_scale * q->tone_level[ch][sb][(j + k)/2] * samples[k] + .5); + } + + j += run; + } // j loop + } // channel loop + } // subband loop +} + + +/** + * Init the first element of a channel in quantized_coeffs with data from packet 10 (quantized_coeffs[ch][0]) + * This is similar to process_subpacket_9, but for a single channel and for element [0] + * same VLC tables as process_subpacket_9 are used + * + * @param q context + * @param quantized_coeffs pointer to quantized_coeffs[ch][0] + * @param gb bitreader context + * @param length packet length in bit + */ +static void init_quantized_coeffs_elem0 (int8_t *quantized_coeffs, GetBitContext *gb, int length) +{ + int i, k, run, level, diff; + + if (BITS_LEFT(length,gb) < 16) + return; + level = qdm2_get_vlc(gb, &vlc_tab_level, 0, 2); + + quantized_coeffs[0] = level; + + for (i = 0; i < 7; ) { + if (BITS_LEFT(length,gb) < 16) + break; + run = qdm2_get_vlc(gb, &vlc_tab_run, 0, 1) + 1; + + if (BITS_LEFT(length,gb) < 16) + break; + diff = qdm2_get_se_vlc(&vlc_tab_diff, gb, 2); + + for (k = 1; k <= run; k++) + quantized_coeffs[i + k] = (level + ((k * diff) / run)); + + level += diff; + i += run; + } +} + + +/** + * Related to synthesis filter, process data from packet 10 + * Init part of quantized_coeffs via function init_quantized_coeffs_elem0 + * Init tone_level_idx_hi1, tone_level_idx_hi2, tone_level_idx_mid with data from packet 10 + * + * @param q context + * @param gb bitreader context + * @param length packet length in bit + */ +static void init_tone_level_dequantization (QDM2Context *q, GetBitContext *gb, int length) +{ + int sb, j, k, n, ch; + + for (ch = 0; ch < q->nb_channels; ch++) { + init_quantized_coeffs_elem0(q->quantized_coeffs[ch][0], gb, length); + + if (BITS_LEFT(length,gb) < 16) { + memset(q->quantized_coeffs[ch][0], 0, 8); + break; + } + } + + n = q->sub_sampling + 1; + + for (sb = 0; sb < n; sb++) + for (ch = 0; ch < q->nb_channels; ch++) + for (j = 0; j < 8; j++) { + if (BITS_LEFT(length,gb) < 1) + break; + if (get_bits1(gb)) { + for (k=0; k < 8; k++) { + if (BITS_LEFT(length,gb) < 16) + break; + q->tone_level_idx_hi1[ch][sb][j][k] = qdm2_get_vlc(gb, &vlc_tab_tone_level_idx_hi1, 0, 2); + } + } else { + for (k=0; k < 8; k++) + q->tone_level_idx_hi1[ch][sb][j][k] = 0; + } + } + + n = QDM2_SB_USED(q->sub_sampling) - 4; + + for (sb = 0; sb < n; sb++) + for (ch = 0; ch < q->nb_channels; ch++) { + if (BITS_LEFT(length,gb) < 16) + break; + q->tone_level_idx_hi2[ch][sb] = qdm2_get_vlc(gb, &vlc_tab_tone_level_idx_hi2, 0, 2); + if (sb > 19) + q->tone_level_idx_hi2[ch][sb] -= 16; + else + for (j = 0; j < 8; j++) + q->tone_level_idx_mid[ch][sb][j] = -16; + } + + n = QDM2_SB_USED(q->sub_sampling) - 5; + + for (sb = 0; sb < n; sb++) + for (ch = 0; ch < q->nb_channels; ch++) + for (j = 0; j < 8; j++) { + if (BITS_LEFT(length,gb) < 16) + break; + q->tone_level_idx_mid[ch][sb][j] = qdm2_get_vlc(gb, &vlc_tab_tone_level_idx_mid, 0, 2) - 32; + } +} + +/** + * Process subpacket 9, init quantized_coeffs with data from it + * + * @param q context + * @param node pointer to node with packet + */ +static void process_subpacket_9 (QDM2Context *q, QDM2SubPNode *node) +{ + GetBitContext gb; + int i, j, k, n, ch, run, level, diff; + + init_get_bits(&gb, node->packet->data, node->packet->size*8); + + n = coeff_per_sb_for_avg[q->coeff_per_sb_select][QDM2_SB_USED(q->sub_sampling) - 1] + 1; // same as averagesomething function + + for (i = 1; i < n; i++) + for (ch=0; ch < q->nb_channels; ch++) { + level = qdm2_get_vlc(&gb, &vlc_tab_level, 0, 2); + q->quantized_coeffs[ch][i][0] = level; + + for (j = 0; j < (8 - 1); ) { + run = qdm2_get_vlc(&gb, &vlc_tab_run, 0, 1) + 1; + diff = qdm2_get_se_vlc(&vlc_tab_diff, &gb, 2); + + for (k = 1; k <= run; k++) + q->quantized_coeffs[ch][i][j + k] = (level + ((k*diff) / run)); + + level += diff; + j += run; + } + } + + for (ch = 0; ch < q->nb_channels; ch++) + for (i = 0; i < 8; i++) + q->quantized_coeffs[ch][0][i] = 0; +} + + +/** + * Process subpacket 10 if not null, else + * + * @param q context + * @param node pointer to node with packet + * @param length packet length in bit + */ +static void process_subpacket_10 (QDM2Context *q, QDM2SubPNode *node, int length) +{ + GetBitContext gb; + + init_get_bits(&gb, ((node == NULL) ? empty_buffer : node->packet->data), ((node == NULL) ? 0 : node->packet->size*8)); + + if (length != 0) { + init_tone_level_dequantization(q, &gb, length); + fill_tone_level_array(q, 1); + } else { + fill_tone_level_array(q, 0); + } +} + + +/** + * Process subpacket 11 + * + * @param q context + * @param node pointer to node with packet + * @param length packet length in bit + */ +static void process_subpacket_11 (QDM2Context *q, QDM2SubPNode *node, int length) +{ + GetBitContext gb; + + init_get_bits(&gb, ((node == NULL) ? empty_buffer : node->packet->data), ((node == NULL) ? 0 : node->packet->size*8)); + if (length >= 32) { + int c = get_bits (&gb, 13); + + if (c > 3) + fill_coding_method_array (q->tone_level_idx, q->tone_level_idx_temp, q->coding_method, + q->nb_channels, 8*c, q->superblocktype_2_3, q->cm_table_select); + } + + synthfilt_build_sb_samples(q, &gb, length, 0, 8); +} + + +/** + * Process subpacket 12 + * + * @param q context + * @param node pointer to node with packet + * @param length packet length in bit + */ +static void process_subpacket_12 (QDM2Context *q, QDM2SubPNode *node, int length) +{ + GetBitContext gb; + + init_get_bits(&gb, ((node == NULL) ? empty_buffer : node->packet->data), ((node == NULL) ? 0 : node->packet->size*8)); + synthfilt_build_sb_samples(q, &gb, length, 8, QDM2_SB_USED(q->sub_sampling)); +} + +/* + * Process new subpackets for synthesis filter + * + * @param q context + * @param list list with synthesis filter packets (list D) + */ +static void process_synthesis_subpackets (QDM2Context *q, QDM2SubPNode *list) +{ + QDM2SubPNode *nodes[4]; + + nodes[0] = qdm2_search_subpacket_type_in_list(list, 9); + if (nodes[0] != NULL) + process_subpacket_9(q, nodes[0]); + + nodes[1] = qdm2_search_subpacket_type_in_list(list, 10); + if (nodes[1] != NULL) + process_subpacket_10(q, nodes[1], nodes[1]->packet->size << 3); + else + process_subpacket_10(q, NULL, 0); + + nodes[2] = qdm2_search_subpacket_type_in_list(list, 11); + if (nodes[0] != NULL && nodes[1] != NULL && nodes[2] != NULL) + process_subpacket_11(q, nodes[2], (nodes[2]->packet->size << 3)); + else + process_subpacket_11(q, NULL, 0); + + nodes[3] = qdm2_search_subpacket_type_in_list(list, 12); + if (nodes[0] != NULL && nodes[1] != NULL && nodes[3] != NULL) + process_subpacket_12(q, nodes[3], (nodes[3]->packet->size << 3)); + else + process_subpacket_12(q, NULL, 0); +} + + +/* + * Decode superblock, fill packet lists + * + * @param q context + */ +static void qdm2_decode_super_block (QDM2Context *q) +{ + GetBitContext gb; + QDM2SubPacket header, *packet; + int i, packet_bytes, sub_packet_size, sub_packets_D; + unsigned int next_index = 0; + + memset(q->tone_level_idx_hi1, 0, sizeof(q->tone_level_idx_hi1)); + memset(q->tone_level_idx_mid, 0, sizeof(q->tone_level_idx_mid)); + memset(q->tone_level_idx_hi2, 0, sizeof(q->tone_level_idx_hi2)); + + q->sub_packets_B = 0; + sub_packets_D = 0; + + average_quantized_coeffs(q); // average elements in quantized_coeffs[max_ch][10][8] + + init_get_bits(&gb, q->compressed_data, q->compressed_size*8); + qdm2_decode_sub_packet_header(&gb, &header); + + if (header.type < 2 || header.type >= 8) { + q->has_errors = 1; + av_log(NULL,AV_LOG_ERROR,"bad superblock type\n"); + return; + } + + q->superblocktype_2_3 = (header.type == 2 || header.type == 3); + packet_bytes = (q->compressed_size - get_bits_count(&gb) / 8); + + init_get_bits(&gb, header.data, header.size*8); + + if (header.type == 2 || header.type == 4 || header.type == 5) { + int csum = 257 * get_bits(&gb, 8) + 2 * get_bits(&gb, 8); + + csum = qdm2_packet_checksum(q->compressed_data, q->checksum_size, csum); + + if (csum != 0) { + q->has_errors = 1; + av_log(NULL,AV_LOG_ERROR,"bad packet checksum\n"); + return; + } + } + + q->sub_packet_list_B[0].packet = NULL; + q->sub_packet_list_D[0].packet = NULL; + + for (i = 0; i < 6; i++) + if (--q->fft_level_exp[i] < 0) + q->fft_level_exp[i] = 0; + + for (i = 0; packet_bytes > 0; i++) { + int j; + + q->sub_packet_list_A[i].next = NULL; + + if (i > 0) { + q->sub_packet_list_A[i - 1].next = &q->sub_packet_list_A[i]; + + /* seek to next block */ + init_get_bits(&gb, header.data, header.size*8); + skip_bits(&gb, next_index*8); + + if (next_index >= header.size) + break; + } + + /* decode sub packet */ + packet = &q->sub_packets[i]; + qdm2_decode_sub_packet_header(&gb, packet); + next_index = packet->size + get_bits_count(&gb) / 8; + sub_packet_size = ((packet->size > 0xff) ? 1 : 0) + packet->size + 2; + + if (packet->type == 0) + break; + + if (sub_packet_size > packet_bytes) { + if (packet->type != 10 && packet->type != 11 && packet->type != 12) + break; + packet->size += packet_bytes - sub_packet_size; + } + + packet_bytes -= sub_packet_size; + + /* add sub packet to 'all sub packets' list */ + q->sub_packet_list_A[i].packet = packet; + + /* add sub packet to related list */ + if (packet->type == 8) { + SAMPLES_NEEDED_2("packet type 8"); + return; + } else if (packet->type >= 9 && packet->type <= 12) { + /* packets for MPEG Audio like Synthesis Filter */ + QDM2_LIST_ADD(q->sub_packet_list_D, sub_packets_D, packet); + } else if (packet->type == 13) { + for (j = 0; j < 6; j++) + q->fft_level_exp[j] = get_bits(&gb, 6); + } else if (packet->type == 14) { + for (j = 0; j < 6; j++) + q->fft_level_exp[j] = qdm2_get_vlc(&gb, &fft_level_exp_vlc, 0, 2); + } else if (packet->type == 15) { + SAMPLES_NEEDED_2("packet type 15") + return; + } else if (packet->type >= 16 && packet->type < 48 && !fft_subpackets[packet->type - 16]) { + /* packets for FFT */ + QDM2_LIST_ADD(q->sub_packet_list_B, q->sub_packets_B, packet); + } + } // Packet bytes loop + +/* **************************************************************** */ + if (q->sub_packet_list_D[0].packet != NULL) { + process_synthesis_subpackets(q, q->sub_packet_list_D); + q->do_synth_filter = 1; + } else if (q->do_synth_filter) { + process_subpacket_10(q, NULL, 0); + process_subpacket_11(q, NULL, 0); + process_subpacket_12(q, NULL, 0); + } +/* **************************************************************** */ +} + + +static void qdm2_fft_init_coefficient (QDM2Context *q, int sub_packet, + int offset, int duration, int channel, + int exp, int phase) +{ + if (q->fft_coefs_min_index[duration] < 0) + q->fft_coefs_min_index[duration] = q->fft_coefs_index; + + q->fft_coefs[q->fft_coefs_index].sub_packet = ((sub_packet >= 16) ? (sub_packet - 16) : sub_packet); + q->fft_coefs[q->fft_coefs_index].channel = channel; + q->fft_coefs[q->fft_coefs_index].offset = offset; + q->fft_coefs[q->fft_coefs_index].exp = exp; + q->fft_coefs[q->fft_coefs_index].phase = phase; + q->fft_coefs_index++; +} + + +static void qdm2_fft_decode_tones (QDM2Context *q, int duration, GetBitContext *gb, int b) +{ + int channel, stereo, phase, exp; + int local_int_4, local_int_8, stereo_phase, local_int_10; + int local_int_14, stereo_exp, local_int_20, local_int_28; + int n, offset; + + local_int_4 = 0; + local_int_28 = 0; + local_int_20 = 2; + local_int_8 = (4 - duration); + local_int_10 = 1 << (q->group_order - duration - 1); + offset = 1; + + while (1) { + if (q->superblocktype_2_3) { + while ((n = qdm2_get_vlc(gb, &vlc_tab_fft_tone_offset[local_int_8], 1, 2)) < 2) { + offset = 1; + if (n == 0) { + local_int_4 += local_int_10; + local_int_28 += (1 << local_int_8); + } else { + local_int_4 += 8*local_int_10; + local_int_28 += (8 << local_int_8); + } + } + offset += (n - 2); + } else { + offset += qdm2_get_vlc(gb, &vlc_tab_fft_tone_offset[local_int_8], 1, 2); + while (offset >= (local_int_10 - 1)) { + offset += (1 - (local_int_10 - 1)); + local_int_4 += local_int_10; + local_int_28 += (1 << local_int_8); + } + } + + if (local_int_4 >= q->group_size) + return; + + local_int_14 = (offset >> local_int_8); + + if (q->nb_channels > 1) { + channel = get_bits1(gb); + stereo = get_bits1(gb); + } else { + channel = 0; + stereo = 0; + } + + exp = qdm2_get_vlc(gb, (b ? &fft_level_exp_vlc : &fft_level_exp_alt_vlc), 0, 2); + exp += q->fft_level_exp[fft_level_index_table[local_int_14]]; + exp = (exp < 0) ? 0 : exp; + + phase = get_bits(gb, 3); + stereo_exp = 0; + stereo_phase = 0; + + if (stereo) { + stereo_exp = (exp - qdm2_get_vlc(gb, &fft_stereo_exp_vlc, 0, 1)); + stereo_phase = (phase - qdm2_get_vlc(gb, &fft_stereo_phase_vlc, 0, 1)); + if (stereo_phase < 0) + stereo_phase += 8; + } + + if (q->frequency_range > (local_int_14 + 1)) { + int sub_packet = (local_int_20 + local_int_28); + + qdm2_fft_init_coefficient(q, sub_packet, offset, duration, channel, exp, phase); + if (stereo) + qdm2_fft_init_coefficient(q, sub_packet, offset, duration, (1 - channel), stereo_exp, stereo_phase); + } + + offset++; + } +} + + +static void qdm2_decode_fft_packets (QDM2Context *q) +{ + int i, j, min, max, value, type, unknown_flag; + GetBitContext gb; + + if (q->sub_packet_list_B[0].packet == NULL) + return; + + /* reset minimum indices for FFT coefficients */ + q->fft_coefs_index = 0; + for (i=0; i < 5; i++) + q->fft_coefs_min_index[i] = -1; + + /* process sub packets ordered by type, largest type first */ + for (i = 0, max = 256; i < q->sub_packets_B; i++) { + QDM2SubPacket *packet; + + /* find sub packet with largest type less than max */ + for (j = 0, min = 0, packet = NULL; j < q->sub_packets_B; j++) { + value = q->sub_packet_list_B[j].packet->type; + if (value > min && value < max) { + min = value; + packet = q->sub_packet_list_B[j].packet; + } + } + + max = min; + + /* check for errors (?) */ + if (i == 0 && (packet->type < 16 || packet->type >= 48 || fft_subpackets[packet->type - 16])) + return; + + /* decode FFT tones */ + init_get_bits (&gb, packet->data, packet->size*8); + + if (packet->type >= 32 && packet->type < 48 && !fft_subpackets[packet->type - 16]) + unknown_flag = 1; + else + unknown_flag = 0; + + type = packet->type; + + if ((type >= 17 && type < 24) || (type >= 33 && type < 40)) { + int duration = q->sub_sampling + 5 - (type & 15); + + if (duration >= 0 && duration < 4) + qdm2_fft_decode_tones(q, duration, &gb, unknown_flag); + } else if (type == 31) { + for (i=0; i < 4; i++) + qdm2_fft_decode_tones(q, i, &gb, unknown_flag); + } else if (type == 46) { + for (i=0; i < 6; i++) + q->fft_level_exp[i] = get_bits(&gb, 6); + for (i=0; i < 4; i++) + qdm2_fft_decode_tones(q, i, &gb, unknown_flag); + } + } // Loop on B packets + + /* calculate maximum indices for FFT coefficients */ + for (i = 0, j = -1; i < 5; i++) + if (q->fft_coefs_min_index[i] >= 0) { + if (j >= 0) + q->fft_coefs_max_index[j] = q->fft_coefs_min_index[i]; + j = i; + } + if (j >= 0) + q->fft_coefs_max_index[j] = q->fft_coefs_index; +} + + +static void qdm2_fft_generate_tone (QDM2Context *q, FFTTone *tone) +{ + float level, f[6]; + int i; + QDM2Complex c; + const double iscale = 2.0*M_PI / 512.0; + + tone->phase += tone->phase_shift; + + /* calculate current level (maximum amplitude) of tone */ + level = fft_tone_envelope_table[tone->duration][tone->time_index] * tone->level; + c.im = level * sin(tone->phase*iscale); + c.re = level * cos(tone->phase*iscale); + + /* generate FFT coefficients for tone */ + if (tone->duration >= 3 || tone->cutoff >= 3) { + tone->samples_im[0] += c.im; + tone->samples_re[0] += c.re; + tone->samples_im[1] -= c.im; + tone->samples_re[1] -= c.re; + } else { + f[1] = -tone->table[4]; + f[0] = tone->table[3] - tone->table[0]; + f[2] = 1.0 - tone->table[2] - tone->table[3]; + f[3] = tone->table[1] + tone->table[4] - 1.0; + f[4] = tone->table[0] - tone->table[1]; + f[5] = tone->table[2]; + for (i = 0; i < 2; i++) { + tone->samples_re[fft_cutoff_index_table[tone->cutoff][i]] += c.re * f[i]; + tone->samples_im[fft_cutoff_index_table[tone->cutoff][i]] += c.im *((tone->cutoff <= i) ? -f[i] : f[i]); + } + for (i = 0; i < 4; i++) { + tone->samples_re[i] += c.re * f[i+2]; + tone->samples_im[i] += c.im * f[i+2]; + } + } + + /* copy the tone if it has not yet died out */ + if (++tone->time_index < ((1 << (5 - tone->duration)) - 1)) { + memcpy(&q->fft_tones[q->fft_tone_end], tone, sizeof(FFTTone)); + q->fft_tone_end = (q->fft_tone_end + 1) % 1000; + } +} + + +static void qdm2_fft_tone_synthesizer (QDM2Context *q, int sub_packet) +{ + int i, j, ch; + const double iscale = 0.25 * M_PI; + + for (ch = 0; ch < q->channels; ch++) { + memset(q->fft.samples_im[ch], 0, q->fft_size * sizeof(float)); + memset(q->fft.samples_re[ch], 0, q->fft_size * sizeof(float)); + } + + + /* apply FFT tones with duration 4 (1 FFT period) */ + if (q->fft_coefs_min_index[4] >= 0) + for (i = q->fft_coefs_min_index[4]; i < q->fft_coefs_max_index[4]; i++) { + float level; + QDM2Complex c; + + if (q->fft_coefs[i].sub_packet != sub_packet) + break; + + ch = (q->channels == 1) ? 0 : q->fft_coefs[i].channel; + level = (q->fft_coefs[i].exp < 0) ? 0.0 : fft_tone_level_table[q->superblocktype_2_3 ? 0 : 1][q->fft_coefs[i].exp & 63]; + + c.re = level * cos(q->fft_coefs[i].phase * iscale); + c.im = level * sin(q->fft_coefs[i].phase * iscale); + q->fft.samples_re[ch][q->fft_coefs[i].offset + 0] += c.re; + q->fft.samples_im[ch][q->fft_coefs[i].offset + 0] += c.im; + q->fft.samples_re[ch][q->fft_coefs[i].offset + 1] -= c.re; + q->fft.samples_im[ch][q->fft_coefs[i].offset + 1] -= c.im; + } + + /* generate existing FFT tones */ + for (i = q->fft_tone_end; i != q->fft_tone_start; ) { + qdm2_fft_generate_tone(q, &q->fft_tones[q->fft_tone_start]); + q->fft_tone_start = (q->fft_tone_start + 1) % 1000; + } + + /* create and generate new FFT tones with duration 0 (long) to 3 (short) */ + for (i = 0; i < 4; i++) + if (q->fft_coefs_min_index[i] >= 0) { + for (j = q->fft_coefs_min_index[i]; j < q->fft_coefs_max_index[i]; j++) { + int offset, four_i; + FFTTone tone; + + if (q->fft_coefs[j].sub_packet != sub_packet) + break; + + four_i = (4 - i); + offset = q->fft_coefs[j].offset >> four_i; + ch = (q->channels == 1) ? 0 : q->fft_coefs[j].channel; + + if (offset < q->frequency_range) { + if (offset < 2) + tone.cutoff = offset; + else + tone.cutoff = (offset >= 60) ? 3 : 2; + + tone.level = (q->fft_coefs[j].exp < 0) ? 0.0 : fft_tone_level_table[q->superblocktype_2_3 ? 0 : 1][q->fft_coefs[j].exp & 63]; + tone.samples_im = &q->fft.samples_im[ch][offset]; + tone.samples_re = &q->fft.samples_re[ch][offset]; + tone.table = (float*)fft_tone_sample_table[i][q->fft_coefs[j].offset - (offset << four_i)]; + tone.phase = 64 * q->fft_coefs[j].phase - (offset << 8) - 128; + tone.phase_shift = (2 * q->fft_coefs[j].offset + 1) << (7 - four_i); + tone.duration = i; + tone.time_index = 0; + + qdm2_fft_generate_tone(q, &tone); + } + } + q->fft_coefs_min_index[i] = j; + } +} + + +static void qdm2_calculate_fft (QDM2Context *q, int channel, int sub_packet) +{ + const int n = 1 << (q->fft_order - 1); + const int n2 = n >> 1; + const float gain = (q->channels == 1 && q->nb_channels == 2) ? 0.25f : 0.50f; + float c, s, f0, f1, f2, f3; + int i, j; + + /* pre rotation (or something like that) */ + for (i=1; i < n2; i++) { + j = (n - i); + c = q->exptab[i].re; + s = -q->exptab[i].im; + f0 = (q->fft.samples_re[channel][i] - q->fft.samples_re[channel][j]) * gain; + f1 = (q->fft.samples_im[channel][i] + q->fft.samples_im[channel][j]) * gain; + f2 = (q->fft.samples_re[channel][i] + q->fft.samples_re[channel][j]) * gain; + f3 = (q->fft.samples_im[channel][i] - q->fft.samples_im[channel][j]) * gain; + q->fft.complex[i].re = s * f0 - c * f1 + f2; + q->fft.complex[i].im = c * f0 + s * f1 + f3; + q->fft.complex[j].re = -s * f0 + c * f1 + f2; + q->fft.complex[j].im = c * f0 + s * f1 - f3; + } + + q->fft.complex[ 0].re = q->fft.samples_re[channel][ 0] * gain * 2.0; + q->fft.complex[ 0].im = q->fft.samples_re[channel][ 0] * gain * 2.0; + q->fft.complex[n2].re = q->fft.samples_re[channel][n2] * gain * 2.0; + q->fft.complex[n2].im = -q->fft.samples_im[channel][n2] * gain * 2.0; + + ff_fft_permute(&q->fft_ctx, (FFTComplex *) q->fft.complex); + ff_fft_calc (&q->fft_ctx, (FFTComplex *) q->fft.complex); + /* add samples to output buffer */ + for (i = 0; i < ((q->fft_frame_size + 15) & ~15); i++) + q->output_buffer[q->channels * i + channel] += ((float *) q->fft.complex)[i]; +} + + +/** + * @param q context + * @param index subpacket number + */ +static void qdm2_synthesis_filter (QDM2Context *q, int index) +{ + OUT_INT samples[MPA_MAX_CHANNELS * MPA_FRAME_SIZE]; + int i, k, ch, sb_used, sub_sampling, dither_state = 0; + + /* copy sb_samples */ + sb_used = QDM2_SB_USED(q->sub_sampling); + + for (ch = 0; ch < q->channels; ch++) + for (i = 0; i < 8; i++) + for (k=sb_used; k < SBLIMIT; k++) + q->sb_samples[ch][(8 * index) + i][k] = 0; + + for (ch = 0; ch < q->nb_channels; ch++) { + OUT_INT *samples_ptr = samples + ch; + + for (i = 0; i < 8; i++) { + ff_mpa_synth_filter(q->synth_buf[ch], &(q->synth_buf_offset[ch]), + mpa_window, &dither_state, + samples_ptr, q->nb_channels, + q->sb_samples[ch][(8 * index) + i]); + samples_ptr += 32 * q->nb_channels; + } + } + + /* add samples to output buffer */ + sub_sampling = (4 >> q->sub_sampling); + + for (ch = 0; ch < q->channels; ch++) + for (i = 0; i < q->frame_size; i++) + q->output_buffer[q->channels * i + ch] += (float)(samples[q->nb_channels * sub_sampling * i + ch] >> (sizeof(OUT_INT)*8-16)); +} + + +/** + * Init static data (does not depend on specific file) + * + * @param q context + */ +void qdm2_init(QDM2Context *q) { + static int inited = 0; + + if (inited != 0) + return; + inited = 1; + + qdm2_init_vlc(); + ff_mpa_synth_init(mpa_window); + softclip_table_init(); + rnd_table_init(); + init_noise_samples(); + + av_log(NULL, AV_LOG_DEBUG, "init done\n"); +} + + +#if 0 +static void dump_context(QDM2Context *q) +{ + int i; +#define PRINT(a,b) av_log(NULL,AV_LOG_DEBUG," %s = %d\n", a, b); + PRINT("compressed_data",q->compressed_data); + PRINT("compressed_size",q->compressed_size); + PRINT("frame_size",q->frame_size); + PRINT("checksum_size",q->checksum_size); + PRINT("channels",q->channels); + PRINT("nb_channels",q->nb_channels); + PRINT("fft_frame_size",q->fft_frame_size); + PRINT("fft_size",q->fft_size); + PRINT("sub_sampling",q->sub_sampling); + PRINT("fft_order",q->fft_order); + PRINT("group_order",q->group_order); + PRINT("group_size",q->group_size); + PRINT("sub_packet",q->sub_packet); + PRINT("frequency_range",q->frequency_range); + PRINT("has_errors",q->has_errors); + PRINT("fft_tone_end",q->fft_tone_end); + PRINT("fft_tone_start",q->fft_tone_start); + PRINT("fft_coefs_index",q->fft_coefs_index); + PRINT("coeff_per_sb_select",q->coeff_per_sb_select); + PRINT("cm_table_select",q->cm_table_select); + PRINT("noise_idx",q->noise_idx); + + for (i = q->fft_tone_start; i < q->fft_tone_end; i++) + { + FFTTone *t = &q->fft_tones[i]; + + av_log(NULL,AV_LOG_DEBUG,"Tone (%d) dump:\n", i); + av_log(NULL,AV_LOG_DEBUG," level = %f\n", t->level); +// PRINT(" level", t->level); + PRINT(" phase", t->phase); + PRINT(" phase_shift", t->phase_shift); + PRINT(" duration", t->duration); + PRINT(" samples_im", t->samples_im); + PRINT(" samples_re", t->samples_re); + PRINT(" table", t->table); + } + +} +#endif + + +/** + * Init parameters from codec extradata + */ +static int qdm2_decode_init(AVCodecContext *avctx) +{ + QDM2Context *s = avctx->priv_data; + uint8_t *extradata; + int extradata_size; + int tmp_val, tmp, size; + int i; + float alpha; + + /* extradata parsing + + Structure: + wave { + frma (QDM2) + QDCA + QDCP + } + + 32 size (including this field) + 32 tag (=frma) + 32 type (=QDM2 or QDMC) + + 32 size (including this field, in bytes) + 32 tag (=QDCA) // maybe mandatory parameters + 32 unknown (=1) + 32 channels (=2) + 32 samplerate (=44100) + 32 bitrate (=96000) + 32 block size (=4096) + 32 frame size (=256) (for one channel) + 32 packet size (=1300) + + 32 size (including this field, in bytes) + 32 tag (=QDCP) // maybe some tuneable parameters + 32 float1 (=1.0) + 32 zero ? + 32 float2 (=1.0) + 32 float3 (=1.0) + 32 unknown (27) + 32 unknown (8) + 32 zero ? + */ + + if (!avctx->extradata || (avctx->extradata_size < 48)) { + av_log(avctx, AV_LOG_ERROR, "extradata missing or truncated\n"); + return -1; + } + + extradata = avctx->extradata; + extradata_size = avctx->extradata_size; + + while (extradata_size > 7) { + if (!memcmp(extradata, "frmaQDM", 7)) + break; + extradata++; + extradata_size--; + } + + if (extradata_size < 12) { + av_log(avctx, AV_LOG_ERROR, "not enough extradata (%i)\n", + extradata_size); + return -1; + } + + if (memcmp(extradata, "frmaQDM", 7)) { + av_log(avctx, AV_LOG_ERROR, "invalid headers, QDM? not found\n"); + return -1; + } + + if (extradata[7] == 'C') { +// s->is_qdmc = 1; + av_log(avctx, AV_LOG_ERROR, "stream is QDMC version 1, which is not supported\n"); + return -1; + } + + extradata += 8; + extradata_size -= 8; + + size = BE_32(extradata); + + if(size > extradata_size){ + av_log(avctx, AV_LOG_ERROR, "extradata size too small, %i < %i\n", + extradata_size, size); + return -1; + } + + extradata += 4; + av_log(avctx, AV_LOG_DEBUG, "size: %d\n", size); + if (BE_32(extradata) != MKBETAG('Q','D','C','A')) { + av_log(avctx, AV_LOG_ERROR, "invalid extradata, expecting QDCA\n"); + return -1; + } + + extradata += 8; + + avctx->channels = s->nb_channels = s->channels = BE_32(extradata); + extradata += 4; + + avctx->sample_rate = BE_32(extradata); + extradata += 4; + + avctx->bit_rate = BE_32(extradata); + extradata += 4; + + s->group_size = BE_32(extradata); + extradata += 4; + + s->fft_size = BE_32(extradata); + extradata += 4; + + s->checksum_size = BE_32(extradata); + extradata += 4; + + s->fft_order = av_log2(s->fft_size) + 1; + s->fft_frame_size = 2 * s->fft_size; // complex has two floats + + // something like max decodable tones + s->group_order = av_log2(s->group_size) + 1; + s->frame_size = s->group_size / 16; // 16 iterations per super block + + if (s->fft_order == 8) + s->sub_sampling = 1; + else + s->sub_sampling = 2; + s->frequency_range = 255 / (1 << (2 - s->sub_sampling)); + + switch ((s->sub_sampling * 2 + s->channels - 1)) { + case 0: tmp = 40; break; + case 1: tmp = 48; break; + case 2: tmp = 56; break; + case 3: tmp = 72; break; + case 4: tmp = 80; break; + case 5: tmp = 100;break; + default: tmp=s->sub_sampling; break; + } + tmp_val = 0; + if ((tmp * 1000) < avctx->bit_rate) tmp_val = 1; + if ((tmp * 1440) < avctx->bit_rate) tmp_val = 2; + if ((tmp * 1760) < avctx->bit_rate) tmp_val = 3; + if ((tmp * 2240) < avctx->bit_rate) tmp_val = 4; + s->cm_table_select = tmp_val; + + if (s->sub_sampling == 0) + tmp = 16000; + else + tmp = ((-(s->sub_sampling -1)) & 8000) + 20000; + /* + 0: 16000 -> 1 + 1: 20000 -> 2 + 2: 28000 -> 2 + */ + if (tmp < 8000) + s->coeff_per_sb_select = 0; + else if (tmp <= 16000) + s->coeff_per_sb_select = 1; + else + s->coeff_per_sb_select = 2; + + if (s->fft_order != 8 && s->fft_order != 9) + av_log(avctx, AV_LOG_ERROR, "Unknown FFT order (%d), contact the developers!\n", s->fft_order); + + ff_fft_init(&s->fft_ctx, s->fft_order - 1, 1); + + for (i = 1; i < (1 << (s->fft_order - 2)); i++) { + alpha = 2 * M_PI * (float)i / (float)(1 << (s->fft_order - 1)); + s->exptab[i].re = cos(alpha); + s->exptab[i].im = sin(alpha); + } + + ff_fft_init(&s->fft_ctx, s->fft_order - 1, 1); + qdm2_init(s); + +// dump_context(s); + return 0; +} + + +static int qdm2_decode_close(AVCodecContext *avctx) +{ + QDM2Context *s = avctx->priv_data; + + ff_fft_end(&s->fft_ctx); + + return 0; +} + + +void qdm2_decode (QDM2Context *q, uint8_t *in, int16_t *out) +{ + int ch, i; + const int frame_size = (q->frame_size * q->channels); + + /* select input buffer */ + q->compressed_data = in; + q->compressed_size = q->checksum_size; + +// dump_context(q); + + /* copy old block, clear new block of output samples */ + memmove(q->output_buffer, &q->output_buffer[frame_size], frame_size * sizeof(float)); + memset(&q->output_buffer[frame_size], 0, frame_size * sizeof(float)); + + /* decode block of QDM2 compressed data */ + if (q->sub_packet == 0) { + q->has_errors = 0; // zero it for a new super block + av_log(NULL,AV_LOG_DEBUG,"Super block follows\n"); + qdm2_decode_super_block(q); + } + + /* parse sub packets */ + if (!q->has_errors) { + if (q->sub_packet == 2) + qdm2_decode_fft_packets(q); + + qdm2_fft_tone_synthesizer(q, q->sub_packet); + } + + /* sound synthesis stage 1 (FFT) */ + for (ch = 0; ch < q->channels; ch++) { + qdm2_calculate_fft(q, ch, q->sub_packet); + + if (!q->has_errors && q->sub_packet_list_C[0].packet != NULL) { + SAMPLES_NEEDED_2("has errors, and C list is not empty") + return; + } + } + + /* sound synthesis stage 2 (MPEG audio like synthesis filter) */ + if (!q->has_errors && q->do_synth_filter) + qdm2_synthesis_filter(q, q->sub_packet); + + q->sub_packet = (q->sub_packet + 1) % 16; + + /* clip and convert output float[] to 16bit signed samples */ + for (i = 0; i < frame_size; i++) { + int value = (int)q->output_buffer[i]; + + if (value > SOFTCLIP_THRESHOLD) + value = (value > HARDCLIP_THRESHOLD) ? 32767 : softclip_table[ value - SOFTCLIP_THRESHOLD]; + else if (value < -SOFTCLIP_THRESHOLD) + value = (value < -HARDCLIP_THRESHOLD) ? -32767 : -softclip_table[-value - SOFTCLIP_THRESHOLD]; + + out[i] = value; + } +} + + +static int qdm2_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + uint8_t *buf, int buf_size) +{ + QDM2Context *s = avctx->priv_data; + + if((buf == NULL) || (buf_size < s->checksum_size)) + return 0; + + *data_size = s->channels * s->frame_size * sizeof(int16_t); + + av_log(avctx, AV_LOG_DEBUG, "decode(%d): %p[%d] -> %p[%d]\n", + buf_size, buf, s->checksum_size, data, *data_size); + + qdm2_decode(s, buf, data); + + // reading only when next superblock found + if (s->sub_packet == 0) { + return s->checksum_size; + } + + return 0; +} + +AVCodec qdm2_decoder = +{ + .name = "qdm2", + .type = CODEC_TYPE_AUDIO, + .id = CODEC_ID_QDM2, + .priv_data_size = sizeof(QDM2Context), + .init = qdm2_decode_init, + .close = qdm2_decode_close, + .decode = qdm2_decode_frame, +}; diff --git a/src/libffmpeg/libavcodec/qdm2data.h b/src/libffmpeg/libavcodec/qdm2data.h new file mode 100644 index 000000000..9cc944bdf --- /dev/null +++ b/src/libffmpeg/libavcodec/qdm2data.h @@ -0,0 +1,528 @@ +/* + * QDM2 compatible decoder + * Copyright (c) 2003 Ewald Snel + * Copyright (c) 2005 Benjamin Larsson + * Copyright (c) 2005 Alex Beregszaszi + * Copyright (c) 2005 Roberto Togni + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + /** + * @file qdm2data.h + * Various QDM2 tables. + */ + +#ifndef QDM2DATA_H +#define QDM2DATA_H + +/** VLC TABLES **/ + +/* values in this table range from -1..23; adjust retrieved value by -1 */ +static uint16_t vlc_tab_level_huffcodes[24] = { + 0x037c, 0x0004, 0x003c, 0x004c, 0x003a, 0x002c, 0x001c, 0x001a, + 0x0024, 0x0014, 0x0001, 0x0002, 0x0000, 0x0003, 0x0007, 0x0005, + 0x0006, 0x0008, 0x0009, 0x000a, 0x000c, 0x00fc, 0x007c, 0x017c +}; + +static uint8_t vlc_tab_level_huffbits[24] = { + 10, 6, 7, 7, 6, 6, 6, 6, 6, 5, 4, 4, 4, 3, 3, 3, 3, 4, 4, 5, 7, 8, 9, 10 +}; + +/* values in this table range from -1..36; adjust retrieved value by -1 */ +static uint16_t vlc_tab_diff_huffcodes[37] = { + 0x1c57, 0x0004, 0x0000, 0x0001, 0x0003, 0x0002, 0x000f, 0x000e, + 0x0007, 0x0016, 0x0037, 0x0027, 0x0026, 0x0066, 0x0006, 0x0097, + 0x0046, 0x01c6, 0x0017, 0x0786, 0x0086, 0x0257, 0x00d7, 0x0357, + 0x00c6, 0x0386, 0x0186, 0x0000, 0x0157, 0x0c57, 0x0057, 0x0000, + 0x0b86, 0x0000, 0x1457, 0x0000, 0x0457 +}; + +static uint8_t vlc_tab_diff_huffbits[37] = { + 13, 3, 3, 2, 3, 3, 4, 4, 6, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 8, 11, 9, 10, 8, 10, 9, 12, 10, 0, 10, 13, 11, 0, + 12, 0, 13, 0, 13 +}; + +/* values in this table range from -1..5; adjust retrieved value by -1 */ +static uint8_t vlc_tab_run_huffcodes[6] = { + 0x1f, 0x00, 0x01, 0x03, 0x07, 0x0f +}; + +static uint8_t vlc_tab_run_huffbits[6] = { + 5, 1, 2, 3, 4, 5 +}; + +/* values in this table range from -1..19; adjust retrieved value by -1 */ +static uint16_t vlc_tab_tone_level_idx_hi1_huffcodes[20] = { + 0x5714, 0x000c, 0x0002, 0x0001, 0x0000, 0x0004, 0x0034, 0x0054, + 0x0094, 0x0014, 0x0114, 0x0214, 0x0314, 0x0614, 0x0e14, 0x0f14, + 0x2714, 0x0714, 0x1714, 0x3714 +}; + +static uint8_t vlc_tab_tone_level_idx_hi1_huffbits[20] = { + 15, 4, 2, 1, 3, 5, 6, 7, 8, 10, 10, 11, 11, 12, 12, 12, 14, 14, 15, 14 +}; + +/* values in this table range from -1..23; adjust retrieved value by -1 */ +static uint16_t vlc_tab_tone_level_idx_mid_huffcodes[24] = { + 0x0fea, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x03ea, 0x00ea, 0x002a, 0x001a, + 0x0006, 0x0001, 0x0000, 0x0002, 0x000a, 0x006a, 0x01ea, 0x07ea +}; + +static uint8_t vlc_tab_tone_level_idx_mid_huffbits[24] = { + 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 9, 7, 5, 3, 1, 2, 4, 6, 8, 10, 12 +}; + +/* values in this table range from -1..23; adjust retrieved value by -1 */ +static uint16_t vlc_tab_tone_level_idx_hi2_huffcodes[24] = { + 0x0664, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0064, 0x00e4, + 0x00a4, 0x0068, 0x0004, 0x0008, 0x0014, 0x0018, 0x0000, 0x0001, + 0x0002, 0x0003, 0x000c, 0x0028, 0x0024, 0x0164, 0x0000, 0x0264 +}; + +static uint8_t vlc_tab_tone_level_idx_hi2_huffbits[24] = { + 11, 0, 0, 0, 0, 0, 10, 8, 8, 7, 6, 6, 5, 5, 4, 2, 2, 2, 4, 7, 8, 9, 0, 11 +}; + +/* values in this table range from -1..8; adjust retrieved value by -1 */ +static uint8_t vlc_tab_type30_huffcodes[9] = { + 0x3c, 0x06, 0x00, 0x01, 0x03, 0x02, 0x04, 0x0c, 0x1c +}; + +static uint8_t vlc_tab_type30_huffbits[9] = { + 6, 3, 3, 2, 2, 3, 4, 5, 6 +}; + +/* values in this table range from -1..9; adjust retrieved value by -1 */ +static uint8_t vlc_tab_type34_huffcodes[10] = { + 0x18, 0x00, 0x01, 0x04, 0x05, 0x07, 0x03, 0x02, 0x06, 0x08 +}; + +static uint8_t vlc_tab_type34_huffbits[10] = { + 5, 4, 3, 3, 3, 3, 3, 3, 3, 5 +}; + +/* values in this table range from -1..22; adjust retrieved value by -1 */ +static uint16_t vlc_tab_fft_tone_offset_0_huffcodes[23] = { + 0x038e, 0x0001, 0x0000, 0x0022, 0x000a, 0x0006, 0x0012, 0x0002, + 0x001e, 0x003e, 0x0056, 0x0016, 0x000e, 0x0032, 0x0072, 0x0042, + 0x008e, 0x004e, 0x00f2, 0x002e, 0x0036, 0x00c2, 0x018e +}; + +static uint8_t vlc_tab_fft_tone_offset_0_huffbits[23] = { + 10, 1, 2, 6, 4, 5, 6, 7, 6, 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 6, 6, 8, 10 +}; + +/* values in this table range from -1..27; adjust retrieved value by -1 */ +static uint16_t vlc_tab_fft_tone_offset_1_huffcodes[28] = { + 0x07a4, 0x0001, 0x0020, 0x0012, 0x001c, 0x0008, 0x0006, 0x0010, + 0x0000, 0x0014, 0x0004, 0x0032, 0x0070, 0x000c, 0x0002, 0x003a, + 0x001a, 0x002c, 0x002a, 0x0022, 0x0024, 0x000a, 0x0064, 0x0030, + 0x0062, 0x00a4, 0x01a4, 0x03a4 +}; + +static uint8_t vlc_tab_fft_tone_offset_1_huffbits[28] = { + 11, 1, 6, 6, 5, 4, 3, 6, 6, 5, 6, 6, 7, 6, 6, 6, + 6, 6, 6, 7, 8, 6, 7, 7, 7, 9, 10, 11 +}; + +/* values in this table range from -1..31; adjust retrieved value by -1 */ +static uint16_t vlc_tab_fft_tone_offset_2_huffcodes[32] = { + 0x1760, 0x0001, 0x0000, 0x0082, 0x000c, 0x0006, 0x0003, 0x0007, + 0x0008, 0x0004, 0x0010, 0x0012, 0x0022, 0x001a, 0x0000, 0x0020, + 0x000a, 0x0040, 0x004a, 0x006a, 0x002a, 0x0042, 0x0002, 0x0060, + 0x00aa, 0x00e0, 0x00c2, 0x01c2, 0x0160, 0x0360, 0x0760, 0x0f60 +}; + +static uint8_t vlc_tab_fft_tone_offset_2_huffbits[32] = { + 13, 2, 0, 8, 4, 3, 3, 3, 4, 4, 5, 5, 6, 5, 7, 7, + 7, 7, 7, 7, 8, 8, 8, 9, 8, 8, 9, 9, 10, 11, 13, 12 +}; + +/* values in this table range from -1..34; adjust retrieved value by -1 */ +static uint16_t vlc_tab_fft_tone_offset_3_huffcodes[35] = { + 0x33ea, 0x0005, 0x0000, 0x000c, 0x0000, 0x0006, 0x0003, 0x0008, + 0x0002, 0x0001, 0x0004, 0x0007, 0x001a, 0x000f, 0x001c, 0x002c, + 0x000a, 0x001d, 0x002d, 0x002a, 0x000d, 0x004c, 0x008c, 0x006a, + 0x00cd, 0x004d, 0x00ea, 0x020c, 0x030c, 0x010c, 0x01ea, 0x07ea, + 0x0bea, 0x03ea, 0x13ea +}; + +static uint8_t vlc_tab_fft_tone_offset_3_huffbits[35] = { + 14, 4, 0, 10, 4, 3, 3, 4, 4, 3, 4, 4, 5, 4, 5, 6, + 6, 5, 6, 7, 7, 7, 8, 8, 8, 8, 9, 10, 10, 10, 10, 11, + 12, 13, 14 +}; + +/* values in this table range from -1..37; adjust retrieved value by -1 */ +static uint16_t vlc_tab_fft_tone_offset_4_huffcodes[38] = { + 0x5282, 0x0016, 0x0000, 0x0136, 0x0004, 0x0000, 0x0007, 0x000a, + 0x000e, 0x0003, 0x0001, 0x000d, 0x0006, 0x0009, 0x0012, 0x0005, + 0x0025, 0x0022, 0x0015, 0x0002, 0x0076, 0x0035, 0x0042, 0x00c2, + 0x0182, 0x00b6, 0x0036, 0x03c2, 0x0482, 0x01c2, 0x0682, 0x0882, + 0x0a82, 0x0082, 0x0282, 0x1282, 0x3282, 0x2282 +}; + +static uint8_t vlc_tab_fft_tone_offset_4_huffbits[38] = { + 15, 6, 0, 9, 3, 3, 3, 4, 4, 3, 4, 4, 5, 4, 5, 6, + 6, 6, 6, 8, 7, 6, 8, 9, 9, 8, 9, 10, 11, 10, 11, 12, + 12, 12, 14, 15, 14, 14 +}; + +/** FFT TABLES **/ + +/* values in this table range from -1..27; adjust retrieved value by -1 */ +static uint16_t fft_level_exp_alt_huffcodes[28] = { + 0x1ec6, 0x0006, 0x00c2, 0x0142, 0x0242, 0x0246, 0x00c6, 0x0046, + 0x0042, 0x0146, 0x00a2, 0x0062, 0x0026, 0x0016, 0x000e, 0x0005, + 0x0004, 0x0003, 0x0000, 0x0001, 0x000a, 0x0012, 0x0002, 0x0022, + 0x01c6, 0x02c6, 0x06c6, 0x0ec6 +}; + +static uint8_t fft_level_exp_alt_huffbits[28] = { + 13, 7, 8, 9, 10, 10, 10, 10, 10, 9, 8, 7, 6, 5, 4, 3, + 3, 2, 3, 3, 4, 5, 7, 8, 9, 11, 12, 13 +}; + +/* values in this table range from -1..19; adjust retrieved value by -1 */ +static uint16_t fft_level_exp_huffcodes[20] = { + 0x0f24, 0x0001, 0x0002, 0x0000, 0x0006, 0x0005, 0x0007, 0x000c, + 0x000b, 0x0014, 0x0013, 0x0004, 0x0003, 0x0023, 0x0064, 0x00a4, + 0x0024, 0x0124, 0x0324, 0x0724 +}; + +static uint8_t fft_level_exp_huffbits[20] = { + 12, 3, 3, 3, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 8, 9, 10, 11, 12 +}; + +/* values in this table range from -1..6; adjust retrieved value by -1 */ +static uint8_t fft_stereo_exp_huffcodes[7] = { + 0x3e, 0x01, 0x00, 0x02, 0x06, 0x0e, 0x1e +}; + +static uint8_t fft_stereo_exp_huffbits[7] = { + 6, 1, 2, 3, 4, 5, 6 +}; + +/* values in this table range from -1..8; adjust retrieved value by -1 */ +static uint8_t fft_stereo_phase_huffcodes[9] = { + 0x35, 0x02, 0x00, 0x01, 0x0d, 0x15, 0x05, 0x09, 0x03 +}; + +static uint8_t fft_stereo_phase_huffbits[9] = { + 6, 2, 2, 4, 4, 6, 5, 4, 2 +}; + +static const int fft_cutoff_index_table[4][2] = { + { 1, 2 }, {-1, 0 }, {-1,-2 }, { 0, 0 } +}; + +static const int16_t fft_level_index_table[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 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, + 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, + 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, + 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, +}; + +static uint8_t last_coeff[3] = { + 4, 7, 10 +}; + +static uint8_t coeff_per_sb_for_avg[3][30] = { + { 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, + { 0, 1, 2, 2, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, + { 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9 } +}; + +static uint32_t dequant_table[3][10][30] = { + { { 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 256, 256, 205, 154, 102, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 51, 102, 154, 205, 256, 238, 219, 201, 183, 165, 146, 128, 110, 91, 73, 55, 37, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 18, 37, 55, 73, 91, 110, 128, 146, 165, 183, 201, 219, 238, 256, 228, 199, 171, 142, 114, 85, 57, 28 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, + { { 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 256, 171, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 85, 171, 256, 171, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 85, 171, 256, 219, 183, 146, 110, 73, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 73, 110, 146, 183, 219, 256, 228, 199, 171, 142, 114, 85, 57, 28, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 57, 85, 114, 142, 171, 199, 228, 256, 213, 171, 128, 85, 43 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, + { { 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 256, 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 256, 171, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 85, 171, 256, 192, 128, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 128, 192, 256, 205, 154, 102, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 102, 154, 205, 256, 213, 171, 128, 85, 43, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 85, 128, 171, 213, 256, 213, 171, 128, 85, 43 } } +}; + +static uint8_t coeff_per_sb_for_dequant[3][30] = { + { 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, + { 0, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6 }, + { 0, 1, 2, 3, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9 } +}; + +/* first index is subband, 2nd index is 0, 1 or 3 (2 is unused) */ +static int8_t tone_level_idx_offset_table[30][4] = { + { -50, -50, 0, -50 }, + { -50, -50, 0, -50 }, + { -50, -9, 0, -19 }, + { -16, -6, 0, -12 }, + { -11, -4, 0, -8 }, + { -8, -3, 0, -6 }, + { -7, -3, 0, -5 }, + { -6, -2, 0, -4 }, + { -5, -2, 0, -3 }, + { -4, -1, 0, -3 }, + { -4, -1, 0, -2 }, + { -3, -1, 0, -2 }, + { -3, -1, 0, -2 }, + { -3, -1, 0, -2 }, + { -2, -1, 0, -1 }, + { -2, -1, 0, -1 }, + { -2, -1, 0, -1 }, + { -2, 0, 0, -1 }, + { -2, 0, 0, -1 }, + { -1, 0, 0, -1 }, + { -1, 0, 0, -1 }, + { -1, 0, 0, -1 }, + { -1, 0, 0, -1 }, + { -1, 0, 0, -1 }, + { -1, 0, 0, -1 }, + { -1, 0, 0, -1 }, + { -1, 0, 0, 0 }, + { -1, 0, 0, 0 }, + { -1, 0, 0, 0 }, + { -1, 0, 0, 0 } +}; + +/* all my samples have 1st index 0 or 1 */ +/* second index is subband, only indexes 0-29 seem to be used */ +static int8_t coding_method_table[5][30] = { + { 34, 30, 24, 24, 16, 16, 16, 16, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 + }, + { 34, 30, 24, 24, 16, 16, 16, 16, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 + }, + { 34, 30, 30, 30, 24, 24, 16, 16, 16, 16, 16, 16, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 + }, + { 34, 34, 30, 30, 24, 24, 24, 24, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 10, 10, 10, 10, 10, 10, 10, 10 + }, + { 34, 34, 30, 30, 30, 30, 30, 30, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 + }, +}; + +static const int vlc_stage3_values[60] = { + 0, 1, 2, 3, 4, 6, 8, 10, 12, 16, 20, 24, + 28, 36, 44, 52, 60, 76, 92, 108, 124, 156, 188, 220, + 252, 316, 380, 444, 508, 636, 764, 892, 1020, 1276, 1532, 1788, + 2044, 2556, 3068, 3580, 4092, 5116, 6140, 7164, 8188, 10236, 12284, 14332, + 16380, 20476, 24572, 28668, 32764, 40956, 49148, 57340, 65532, 81916, 98300,114684 +}; + +static const float fft_tone_sample_table[4][16][5] = { + { { .0100000000f,-.0037037037f,-.0020000000f,-.0069444444f,-.0018416207f }, + { .0416666667f, .0000000000f, .0000000000f,-.0208333333f,-.0123456791f }, + { .1250000000f, .0558035709f, .0330687836f,-.0164473690f,-.0097465888f }, + { .1562500000f, .0625000000f, .0370370370f,-.0062500000f,-.0037037037f }, + { .1996007860f, .0781250000f, .0462962948f, .0022727272f, .0013468013f }, + { .2000000000f, .0625000000f, .0370370373f, .0208333333f, .0074074073f }, + { .2127659619f, .0555555556f, .0329218097f, .0208333333f, .0123456791f }, + { .2173913121f, .0473484844f, .0280583613f, .0347222239f, .0205761325f }, + { .2173913121f, .0347222239f, .0205761325f, .0473484844f, .0280583613f }, + { .2127659619f, .0208333333f, .0123456791f, .0555555556f, .0329218097f }, + { .2000000000f, .0208333333f, .0074074073f, .0625000000f, .0370370370f }, + { .1996007860f, .0022727272f, .0013468013f, .0781250000f, .0462962948f }, + { .1562500000f,-.0062500000f,-.0037037037f, .0625000000f, .0370370370f }, + { .1250000000f,-.0164473690f,-.0097465888f, .0558035709f, .0330687836f }, + { .0416666667f,-.0208333333f,-.0123456791f, .0000000000f, .0000000000f }, + { .0100000000f,-.0069444444f,-.0018416207f,-.0037037037f,-.0020000000f } }, + + { { .0050000000f,-.0200000000f, .0125000000f,-.3030303030f, .0020000000f }, + { .1041666642f, .0400000000f,-.0250000000f, .0333333333f,-.0200000000f }, + { .1250000000f, .0100000000f, .0142857144f,-.0500000007f,-.0200000000f }, + { .1562500000f,-.0006250000f,-.00049382716f,-.000625000f,-.00049382716f }, + { .1562500000f,-.0006250000f,-.00049382716f,-.000625000f,-.00049382716f }, + { .1250000000f,-.0500000000f,-.0200000000f, .0100000000f, .0142857144f }, + { .1041666667f, .0333333333f,-.0200000000f, .0400000000f,-.0250000000f }, + { .0050000000f,-.3030303030f, .0020000001f,-.0200000000f, .0125000000f }, + { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, + { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, + { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, + { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, + { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, + { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, + { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, + { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f } }, + + { { .1428571492f, .1250000000f,-.0285714287f,-.0357142873f, .0208333333f }, + { .1818181818f, .0588235296f, .0333333333f, .0212765951f, .0100000000f }, + { .1818181818f, .0212765951f, .0100000000f, .0588235296f, .0333333333f }, + { .1428571492f,-.0357142873f, .0208333333f, .1250000000f,-.0285714287f }, + { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, + { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, + { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, + { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, + { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, + { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, + { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, + { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, + { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, + { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, + { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, + { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f } }, + + { { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, + { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, + { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, + { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, + { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, + { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, + { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, + { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, + { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, + { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, + { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, + { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, + { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, + { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, + { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, + { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f } } +}; + +static const float fft_tone_level_table[2][64] = { { +/* pow ~ (i > 46) ? 0 : (((((i & 1) ? 431 : 304) << (i >> 1))) / 1024.0); */ + 0.17677669f, 0.42677650f, 0.60355347f, 0.85355347f, + 1.20710683f, 1.68359375f, 2.37500000f, 3.36718750f, + 4.75000000f, 6.73437500f, 9.50000000f, 13.4687500f, + 19.0000000f, 26.9375000f, 38.0000000f, 53.8750000f, + 76.0000000f, 107.750000f, 152.000000f, 215.500000f, + 304.000000f, 431.000000f, 608.000000f, 862.000000f, + 1216.00000f, 1724.00000f, 2432.00000f, 3448.00000f, + 4864.00000f, 6896.00000f, 9728.00000f, 13792.0000f, + 19456.0000f, 27584.0000f, 38912.0000f, 55168.0000f, + 77824.0000f, 110336.000f, 155648.000f, 220672.000f, + 311296.000f, 441344.000f, 622592.000f, 882688.000f, + 1245184.00f, 1765376.00f, 2490368.00f, 0.00000000f, + 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, + 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, + 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, + 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, + }, { +/* pow = (i > 45) ? 0 : ((((i & 1) ? 431 : 304) << (i >> 1)) / 512.0); */ + 0.59375000f, 0.84179688f, 1.18750000f, 1.68359375f, + 2.37500000f, 3.36718750f, 4.75000000f, 6.73437500f, + 9.50000000f, 13.4687500f, 19.0000000f, 26.9375000f, + 38.0000000f, 53.8750000f, 76.0000000f, 107.750000f, + 152.000000f, 215.500000f, 304.000000f, 431.000000f, + 608.000000f, 862.000000f, 1216.00000f, 1724.00000f, + 2432.00000f, 3448.00000f, 4864.00000f, 6896.00000f, + 9728.00000f, 13792.0000f, 19456.0000f, 27584.0000f, + 38912.0000f, 55168.0000f, 77824.0000f, 110336.000f, + 155648.000f, 220672.000f, 311296.000f, 441344.000f, + 622592.000f, 882688.000f, 1245184.00f, 1765376.00f, + 2490368.00f, 3530752.00f, 0.00000000f, 0.00000000f, + 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, + 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, + 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, + 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f +} }; + +static const float fft_tone_envelope_table[4][31] = { + { .009607375f, .038060248f, .084265202f, .146446645f, .222214907f, .308658302f, + .402454883f, .500000060f, .597545207f, .691341758f, .777785182f, .853553414f, + .915734828f, .961939812f, .990392685f, 1.00000000f, .990392625f, .961939752f, + .915734768f, .853553295f, .777785063f, .691341639f, .597545087f, .500000000f, + .402454853f, .308658272f, .222214878f, .146446615f, .084265172f, .038060218f, + .009607345f }, + { .038060248f, .146446645f, .308658302f, .500000060f, .691341758f, .853553414f, + .961939812f, 1.00000000f, .961939752f, .853553295f, .691341639f, .500000000f, + .308658272f, .146446615f, .038060218f, .000000000f, .000000000f, .000000000f, + .000000000f, .000000000f, .000000000f, .000000000f, .000000000f, .000000000f, + .000000000f, .000000000f, .000000000f, .000000000f, .000000000f, .000000000f, + .000000000f }, + { .146446645f, .500000060f, .853553414f, 1.00000000f, .853553295f, .500000000f, + .146446615f, .000000000f, .000000000f, .000000000f, .000000000f, .000000000f, + .000000000f, .000000000f, .000000000f, .000000000f, .000000000f, .000000000f, + .000000000f, .000000000f, .000000000f, .000000000f, .000000000f, .000000000f, + .000000000f, .000000000f, .000000000f, .000000000f, .000000000f, .000000000f, + .000000000f }, + { .500000060f, 1.00000000f, .500000000f, .000000000f, .000000000f, .000000000f, + .000000000f, .000000000f, .000000000f, .000000000f, .000000000f, .000000000f, + .000000000f, .000000000f, .000000000f, .000000000f, .000000000f, .000000000f, + .000000000f, .000000000f, .000000000f, .000000000f, .000000000f, .000000000f, + .000000000f, .000000000f, .000000000f, .000000000f, .000000000f, .000000000f, + .000000000f } +}; + +static const float sb_noise_attenuation[32] = { + 0.0f, 0.0f, 0.3f, 0.4f, 0.5f, 0.7f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, +}; + +static const uint8_t fft_subpackets[32] = { + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0 +}; + +/* first index is joined_stereo, second index is 0 or 2 (1 is unused) */ +static float dequant_1bit[2][3] = { + {-0.920000f, 0.000000f, 0.920000f }, + {-0.890000f, 0.000000f, 0.890000f } +}; + +static const float type30_dequant[8] = { + -1.0f,-0.625f,-0.291666656732559f,0.0f, + 0.25f,0.5f,0.75f,1.0f, +}; + +static const float type34_delta[10] = { // FIXME: covers 8 entries.. + -1.0f,-0.60947573184967f,-0.333333343267441f,-0.138071194291115f,0.0f, + 0.138071194291115f,0.333333343267441f,0.60947573184967f,1.0f,0.0f, +}; + +#endif /* QDM2DATA_H */ diff --git a/src/libffmpeg/libavcodec/qpeg.c b/src/libffmpeg/libavcodec/qpeg.c index a2d7e4acc..e4a78bcb3 100644 --- a/src/libffmpeg/libavcodec/qpeg.c +++ b/src/libffmpeg/libavcodec/qpeg.c @@ -40,11 +40,13 @@ static void qpeg_decode_intra(uint8_t *src, uint8_t *dst, int size, int c0, c1; int run, copy; int filled = 0; + int rows_to_go; + rows_to_go = height; height--; dst = dst + height * stride; - while(size > 0) { + while((size > 0) && (rows_to_go > 0)) { code = *src++; size--; run = copy = 0; @@ -85,17 +87,23 @@ static void qpeg_decode_intra(uint8_t *src, uint8_t *dst, int size, if (filled >= width) { filled = 0; dst -= stride; + rows_to_go--; + if(rows_to_go <= 0) + break; } } } else { + size -= copy; for(i = 0; i < copy; i++) { dst[filled++] = *src++; if (filled >= width) { filled = 0; dst -= stride; + rows_to_go--; + if(rows_to_go <= 0) + break; } } - size -= copy; } } } @@ -113,17 +121,19 @@ static void qpeg_decode_inter(uint8_t *src, uint8_t *dst, int size, int i, j; int code; int filled = 0; + int orig_height; uint8_t *blkdata; /* copy prev frame */ for(i = 0; i < height; i++) memcpy(refdata + (i * width), dst + (i * stride), width); + orig_height = height; blkdata = src - 0x86; height--; dst = dst + height * stride; - while(size > 0) { + while((size > 0) && (height >= 0)) { code = *src++; size--; @@ -155,11 +165,19 @@ static void qpeg_decode_inter(uint8_t *src, uint8_t *dst, int size, val -= 16; me_y = val; - /* do motion compensation */ - me_plane = refdata + (filled + me_x) + (height - me_y) * width; - for(j = 0; j < me_h; j++) { - for(i = 0; i < me_w; i++) - dst[filled + i - (j * stride)] = me_plane[i - (j * width)]; + /* check motion vector */ + if ((me_x + filled < 0) || (me_x + me_w + filled > width) || + (height - me_y - me_h < 0) || (height - me_y > orig_height) || + (filled + me_w > width) || (height - me_h < 0)) + av_log(NULL, AV_LOG_ERROR, "Bogus motion vector (%i,%i), block size %ix%i at %i,%i\n", + me_x, me_y, me_w, me_h, filled, height); + else { + /* do motion compensation */ + me_plane = refdata + (filled + me_x) + (height - me_y) * width; + for(j = 0; j < me_h; j++) { + for(i = 0; i < me_w; i++) + dst[filled + i - (j * stride)] = me_plane[i - (j * width)]; + } } } code = *src++; @@ -212,6 +230,8 @@ static void qpeg_decode_inter(uint8_t *src, uint8_t *dst, int size, filled -= width; dst -= stride; height--; + if(height < 0) + break; } } else { /* zero code treated as one-pixel skip */ diff --git a/src/libffmpeg/libavcodec/qtrle.c b/src/libffmpeg/libavcodec/qtrle.c index 41e4120db..0d79c5c9e 100644 --- a/src/libffmpeg/libavcodec/qtrle.c +++ b/src/libffmpeg/libavcodec/qtrle.c @@ -58,8 +58,8 @@ typedef struct QtrleContext { } #define CHECK_PIXEL_PTR(n) \ - if (pixel_ptr + n > pixel_limit) { \ - av_log (s->avctx, AV_LOG_INFO, "Problem: pixel_ptr >= pixel_limit (%d >= %d)\n", \ + if ((pixel_ptr + n > pixel_limit) || (pixel_ptr + n < 0)) { \ + av_log (s->avctx, AV_LOG_INFO, "Problem: pixel_ptr = %d, pixel_limit = %d\n", \ pixel_ptr + n, pixel_limit); \ return; \ } \ @@ -119,6 +119,7 @@ static void qtrle_decode_4bpp(QtrleContext *s) /* there's another skip code in the stream */ CHECK_STREAM_PTR(1); pixel_ptr += (8 * (s->buf[stream_ptr++] - 1)); + CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */ } else if (rle_code < 0) { /* decode the run length code */ rle_code = -rle_code; @@ -209,6 +210,7 @@ static void qtrle_decode_8bpp(QtrleContext *s) /* there's another skip code in the stream */ CHECK_STREAM_PTR(1); pixel_ptr += (4 * (s->buf[stream_ptr++] - 1)); + CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */ } else if (rle_code < 0) { /* decode the run length code */ rle_code = -rle_code; @@ -290,6 +292,7 @@ static void qtrle_decode_16bpp(QtrleContext *s) /* there's another skip code in the stream */ CHECK_STREAM_PTR(1); pixel_ptr += (s->buf[stream_ptr++] - 1) * 2; + CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */ } else if (rle_code < 0) { /* decode the run length code */ rle_code = -rle_code; @@ -367,6 +370,7 @@ static void qtrle_decode_24bpp(QtrleContext *s) /* there's another skip code in the stream */ CHECK_STREAM_PTR(1); pixel_ptr += (s->buf[stream_ptr++] - 1) * 3; + CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */ } else if (rle_code < 0) { /* decode the run length code */ rle_code = -rle_code; @@ -446,6 +450,7 @@ static void qtrle_decode_32bpp(QtrleContext *s) /* there's another skip code in the stream */ CHECK_STREAM_PTR(1); pixel_ptr += (s->buf[stream_ptr++] - 1) * 4; + CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */ } else if (rle_code < 0) { /* decode the run length code */ rle_code = -rle_code; diff --git a/src/libffmpeg/libavcodec/rangecoder.c b/src/libffmpeg/libavcodec/rangecoder.c index ba3022c45..730d5a87c 100644 --- a/src/libffmpeg/libavcodec/rangecoder.c +++ b/src/libffmpeg/libavcodec/rangecoder.c @@ -49,7 +49,8 @@ void ff_init_range_encoder(RangeCoder *c, uint8_t *buf, int buf_size){ } void ff_init_range_decoder(RangeCoder *c, const uint8_t *buf, int buf_size){ - ff_init_range_encoder(c, buf, buf_size); + /* cast to avoid compiler warning */ + ff_init_range_encoder(c, (uint8_t *) buf, buf_size); c->low =(*c->bytestream++)<<8; c->low+= *c->bytestream++; diff --git a/src/libffmpeg/libavcodec/rational.c b/src/libffmpeg/libavcodec/rational.c deleted file mode 100644 index 7ccad9e38..000000000 --- a/src/libffmpeg/libavcodec/rational.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Rational numbers - * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -/** - * @file rational.c - * Rational numbers - * @author Michael Niedermayer <michaelni@gmx.at> - */ - -//#include <math.h> -#include <limits.h> - -#include "common.h" -#include "avcodec.h" -#include "rational.h" - -/** - * returns b*c. - */ -AVRational av_mul_q(AVRational b, AVRational c){ - av_reduce(&b.num, &b.den, b.num * (int64_t)c.num, b.den * (int64_t)c.den, INT_MAX); - return b; -} - -/** - * returns b/c. - */ -AVRational av_div_q(AVRational b, AVRational c){ - av_reduce(&b.num, &b.den, b.num * (int64_t)c.den, b.den * (int64_t)c.num, INT_MAX); - return b; -} - -/** - * returns b+c. - */ -AVRational av_add_q(AVRational b, AVRational c){ - av_reduce(&b.num, &b.den, b.num * (int64_t)c.den + c.num * (int64_t)b.den, b.den * (int64_t)c.den, INT_MAX); - return b; -} - -/** - * returns b-c. - */ -AVRational av_sub_q(AVRational b, AVRational c){ - av_reduce(&b.num, &b.den, b.num * (int64_t)c.den - c.num * (int64_t)b.den, b.den * (int64_t)c.den, INT_MAX); - return b; -} - -/** - * Converts a double precission floating point number to a AVRational. - * @param max the maximum allowed numerator and denominator - */ -AVRational av_d2q(double d, int max){ - AVRational a; - int exponent= FFMAX( (int)(log(ABS(d) + 1e-20)/log(2)), 0); - int64_t den= 1LL << (61 - exponent); - av_reduce(&a.num, &a.den, (int64_t)(d * den + 0.5), den, max); - - return a; -} diff --git a/src/libffmpeg/libavcodec/rational.h b/src/libffmpeg/libavcodec/rational.h deleted file mode 100644 index fcda759c4..000000000 --- a/src/libffmpeg/libavcodec/rational.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Rational numbers - * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -/** - * @file rational.h - * Rational numbers. - * @author Michael Niedermayer <michaelni@gmx.at> - */ - -#ifndef RATIONAL_H -#define RATIONAL_H - -/** - * Rational number num/den. - */ -typedef struct AVRational{ - int num; ///< numerator - int den; ///< denominator -} AVRational; - -/** - * returns 0 if a==b, 1 if a>b and -1 if a<b. - */ -static inline int av_cmp_q(AVRational a, AVRational b){ - const int64_t tmp= a.num * (int64_t)b.den - b.num * (int64_t)a.den; - - if(tmp) return (tmp>>63)|1; - else return 0; -} - -/** - * converts the given AVRational to a double. - */ -static inline double av_q2d(AVRational a){ - return a.num / (double) a.den; -} - -AVRational av_mul_q(AVRational b, AVRational c); -AVRational av_div_q(AVRational b, AVRational c); -AVRational av_add_q(AVRational b, AVRational c); -AVRational av_sub_q(AVRational b, AVRational c); -AVRational av_d2q(double d, int max); - -#endif // RATIONAL_H diff --git a/src/libffmpeg/libavcodec/raw.c b/src/libffmpeg/libavcodec/raw.c index e2614e503..4f829fd02 100644 --- a/src/libffmpeg/libavcodec/raw.c +++ b/src/libffmpeg/libavcodec/raw.c @@ -46,7 +46,8 @@ const PixelFormatTag pixelFormatTags[] = { { PIX_FMT_GRAY8, MKTAG(' ', ' ', 'Y', '8') }, - { PIX_FMT_YUV422, MKTAG('Y', '4', '2', '2') }, /* Packed formats */ + { PIX_FMT_YUV422, MKTAG('Y', 'U', 'Y', '2') }, /* Packed formats */ + { PIX_FMT_YUV422, MKTAG('Y', '4', '2', '2') }, { PIX_FMT_UYVY422, MKTAG('U', 'Y', 'V', 'Y') }, { PIX_FMT_GRAY8, MKTAG('G', 'R', 'E', 'Y') }, diff --git a/src/libffmpeg/libavcodec/roqvideo.c b/src/libffmpeg/libavcodec/roqvideo.c index 7d6b518ee..598765583 100644 --- a/src/libffmpeg/libavcodec/roqvideo.c +++ b/src/libffmpeg/libavcodec/roqvideo.c @@ -143,6 +143,14 @@ static void apply_motion_4x4(RoqContext *ri, int x, int y, unsigned char mv, mx = x + 8 - (mv >> 4) - mean_x; my = y + 8 - (mv & 0xf) - mean_y; + /* check MV against frame boundaries */ + if ((mx < 0) || (mx > ri->avctx->width - 4) || + (my < 0) || (my > ri->avctx->height - 4)) { + av_log(ri->avctx, AV_LOG_ERROR, "motion vector out of bounds: MV = (%d, %d), boundaries = (0, 0, %d, %d)\n", + mx, my, ri->avctx->width, ri->avctx->height); + return; + } + pa = ri->current_frame.data[0] + (y * ri->y_stride) + x; pb = ri->last_frame.data[0] + (my * ri->y_stride) + mx; for(i = 0; i < 4; i++) { @@ -154,25 +162,6 @@ static void apply_motion_4x4(RoqContext *ri, int x, int y, unsigned char mv, pb += ri->y_stride; } -#if 0 - pa = ri->current_frame.data[1] + (y/2) * (ri->c_stride) + x/2; - pb = ri->last_frame.data[1] + (my/2) * (ri->c_stride) + (mx + 1)/2; - for(i = 0; i < 2; i++) { - pa[0] = pb[0]; - pa[1] = pb[1]; - pa += ri->c_stride; - pb += ri->c_stride; - } - - pa = ri->current_frame.data[2] + (y/2) * (ri->c_stride) + x/2; - pb = ri->last_frame.data[2] + (my/2) * (ri->c_stride) + (mx + 1)/2; - for(i = 0; i < 2; i++) { - pa[0] = pb[0]; - pa[1] = pb[1]; - pa += ri->c_stride; - pb += ri->c_stride; - } -#else hw = ri->y_stride/2; pa = ri->current_frame.data[1] + (y * ri->y_stride)/4 + x/2; pb = ri->last_frame.data[1] + (my/2) * (ri->y_stride/2) + (mx + 1)/2; @@ -212,7 +201,6 @@ static void apply_motion_4x4(RoqContext *ri, int x, int y, unsigned char mv, pa = ri->current_frame.data[2] + (y * ri->y_stride)/4 + x/2; pb = ri->last_frame.data[2] + (my/2) * (ri->y_stride/2) + (mx + 1)/2; } -#endif } static void apply_motion_8x8(RoqContext *ri, int x, int y, @@ -224,6 +212,14 @@ static void apply_motion_8x8(RoqContext *ri, int x, int y, mx = x + 8 - (mv >> 4) - mean_x; my = y + 8 - (mv & 0xf) - mean_y; + /* check MV against frame boundaries */ + if ((mx < 0) || (mx > ri->avctx->width - 8) || + (my < 0) || (my > ri->avctx->height - 8)) { + av_log(ri->avctx, AV_LOG_ERROR, "motion vector out of bounds: MV = (%d, %d), boundaries = (0, 0, %d, %d)\n", + mx, my, ri->avctx->width, ri->avctx->height); + return; + } + pa = ri->current_frame.data[0] + (y * ri->y_stride) + x; pb = ri->last_frame.data[0] + (my * ri->y_stride) + mx; for(i = 0; i < 8; i++) { @@ -239,29 +235,6 @@ static void apply_motion_8x8(RoqContext *ri, int x, int y, pb += ri->y_stride; } -#if 0 - pa = ri->current_frame.data[1] + (y/2) * (ri->c_stride) + x/2; - pb = ri->last_frame.data[1] + (my/2) * (ri->c_stride) + (mx + 1)/2; - for(i = 0; i < 4; i++) { - pa[0] = pb[0]; - pa[1] = pb[1]; - pa[2] = pb[2]; - pa[3] = pb[3]; - pa += ri->c_stride; - pb += ri->c_stride; - } - - pa = ri->current_frame.data[2] + (y/2) * (ri->c_stride) + x/2; - pb = ri->last_frame.data[2] + (my/2) * (ri->c_stride) + (mx + 1)/2; - for(i = 0; i < 4; i++) { - pa[0] = pb[0]; - pa[1] = pb[1]; - pa[2] = pb[2]; - pa[3] = pb[3]; - pa += ri->c_stride; - pb += ri->c_stride; - } -#else hw = ri->c_stride; pa = ri->current_frame.data[1] + (y * ri->y_stride)/4 + x/2; pb = ri->last_frame.data[1] + (my/2) * (ri->y_stride/2) + (mx + 1)/2; @@ -304,7 +277,6 @@ static void apply_motion_8x8(RoqContext *ri, int x, int y, pa = ri->current_frame.data[2] + (y * ri->y_stride)/4 + x/2; pb = ri->last_frame.data[2] + (my/2) * (ri->y_stride/2) + (mx + 1)/2; } -#endif } static void roqvideo_decode_frame(RoqContext *ri) @@ -481,7 +453,8 @@ static int roq_decode_end(AVCodecContext *avctx) RoqContext *s = avctx->priv_data; /* release the last frame */ - avctx->release_buffer(avctx, &s->last_frame); + if (s->last_frame.data[0]) + avctx->release_buffer(avctx, &s->last_frame); return 0; } diff --git a/src/libffmpeg/libavcodec/rv10.c b/src/libffmpeg/libavcodec/rv10.c index 8183391e9..06fbde837 100644 --- a/src/libffmpeg/libavcodec/rv10.c +++ b/src/libffmpeg/libavcodec/rv10.c @@ -620,8 +620,14 @@ static int rv10_decode_packet(AVCodecContext *avctx, //if(s->pict_type == P_TYPE) return 0; if ((s->mb_x == 0 && s->mb_y == 0) || s->current_picture_ptr==NULL) { + if(s->current_picture_ptr){ //FIXME write parser so we always have complete frames? + ff_er_frame_end(s); + MPV_frame_end(s); + s->mb_x= s->mb_y = s->resync_mb_x = s->resync_mb_y= 0; + } if(MPV_frame_start(s, avctx) < 0) return -1; + ff_er_frame_start(s); } #ifdef DEBUG @@ -673,7 +679,7 @@ static int rv10_decode_packet(AVCodecContext *avctx, s->mv_type = MV_TYPE_16X16; ret=ff_h263_decode_mb(s, s->block); - if (ret == SLICE_ERROR) { + if (ret == SLICE_ERROR || s->gb.size_in_bits < get_bits_count(&s->gb)) { av_log(s->avctx, AV_LOG_ERROR, "ERROR at MB %d %d\n", s->mb_x, s->mb_y); return -1; } @@ -693,6 +699,8 @@ static int rv10_decode_packet(AVCodecContext *avctx, if(ret == SLICE_END) break; } + ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, AC_END|DC_END|MV_END); + return buf_size; } @@ -723,15 +731,14 @@ static int rv10_decode_frame(AVCodecContext *avctx, else size= avctx->slice_offset[i+1] - offset; - if( rv10_decode_packet(avctx, buf+offset, size) < 0 ) - return -1; + rv10_decode_packet(avctx, buf+offset, size); } }else{ - if( rv10_decode_packet(avctx, buf, buf_size) < 0 ) - return -1; + rv10_decode_packet(avctx, buf, buf_size); } if(s->mb_y>=s->mb_height){ + ff_er_frame_end(s); MPV_frame_end(s); if(s->pict_type==B_TYPE || s->low_delay){ @@ -743,6 +750,7 @@ static int rv10_decode_frame(AVCodecContext *avctx, } if(s->last_picture_ptr || s->low_delay) *data_size = sizeof(AVFrame); + s->current_picture_ptr= NULL; //so we can detect if frame_end wasnt called (find some nicer solution...) } return buf_size; diff --git a/src/libffmpeg/libavcodec/snow.c b/src/libffmpeg/libavcodec/snow.c index 10f0b76ab..21a593f13 100644 --- a/src/libffmpeg/libavcodec/snow.c +++ b/src/libffmpeg/libavcodec/snow.c @@ -500,7 +500,6 @@ static void slice_buffer_init(slice_buffer * buf, int line_count, int max_alloca static DWTELEM * slice_buffer_load_line(slice_buffer * buf, int line) { - int i; int offset; DWTELEM * buffer; @@ -523,7 +522,6 @@ static DWTELEM * slice_buffer_load_line(slice_buffer * buf, int line) static void slice_buffer_release(slice_buffer * buf, int line) { - int i; int offset; DWTELEM * buffer; @@ -933,7 +931,7 @@ static void horizontal_decomposeX(DWTELEM *b, int width){ DWTELEM temp[width]; const int width2= width>>1; const int w2= (width+1)>>1; - int A1,A2,A3,A4, x; + int x; inplace_lift(b, width, COEFFS1, N1, SHIFT1, LX1, 0); inplace_lift(b, width, COEFFS2, N2, SHIFT2, LX0, 0); @@ -952,7 +950,7 @@ static void horizontal_decomposeX(DWTELEM *b, int width){ static void horizontal_composeX(DWTELEM *b, int width){ DWTELEM temp[width]; const int width2= width>>1; - int A1,A2,A3,A4, x; + int x; const int w2= (width+1)>>1; memcpy(temp, b, width*sizeof(int)); @@ -1010,7 +1008,7 @@ static void spatial_composeX(DWTELEM *buffer, int width, int height, int stride) static void horizontal_decompose53i(DWTELEM *b, int width){ DWTELEM temp[width]; const int width2= width>>1; - int A1,A2,A3,A4, x; + int x; const int w2= (width+1)>>1; for(x=0; x<width2; x++){ @@ -1020,6 +1018,8 @@ static void horizontal_decompose53i(DWTELEM *b, int width){ if(width&1) temp[x ]= b[2*x ]; #if 0 + { + int A1,A2,A3,A4; A2= temp[1 ]; A4= temp[0 ]; A1= temp[0+width2]; @@ -1047,6 +1047,7 @@ static void horizontal_decompose53i(DWTELEM *b, int width){ A2 += (A1 + A3 + 2)>>2; b[width -1] = A3; b[width2-1] = A2; + } #else lift(b+w2, temp+w2, temp, 1, 1, 1, width, -1, 0, 1, 1, 0); lift(b , temp , b+w2, 1, 1, 1, width, 1, 2, 2, 0, 0); @@ -1268,9 +1269,10 @@ static void horizontal_compose53i(DWTELEM *b, int width){ DWTELEM temp[width]; const int width2= width>>1; const int w2= (width+1)>>1; - int A1,A2,A3,A4, x; + int x; #if 0 + int A1,A2,A3,A4; A2= temp[1 ]; A4= temp[0 ]; A1= temp[0+width2]; @@ -1452,7 +1454,9 @@ static void vertical_compose97i(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, DWTELEM * int i; for(i=0; i<width; i++){ +#ifndef lift5 int r; +#endif b4[i] -= (W_DM*(b3[i] + b5[i])+W_DO)>>W_DS; #ifdef lift5 b3[i] -= (W_CM*(b2[i] + b4[i])+W_CO)>>W_CS; @@ -1877,7 +1881,7 @@ static inline void unpack_coeffs(SnowContext *s, SubBand *b, SubBand * parent, i static inline void decode_subband_slice_buffered(SnowContext *s, SubBand *b, slice_buffer * sb, int start_y, int h, int save_state[1]){ const int w= b->width; - int x,y; + int y; const int qlog= clip(s->qlog + b->qlog, 0, QROOT*16); int qmul= qexp[qlog&(QROOT-1)]<<(qlog>>QSHIFT); int qadd= (s->qbias*qmul)>>QBIAS_SHIFT; @@ -2474,7 +2478,9 @@ static always_inline void add_yblock_buffered(SnowContext *s, slice_buffer * sb, BlockNode *lb= lt+b_stride; BlockNode *rb= lb+1; uint8_t *block[4]; - uint8_t tmp[src_stride*(b_h+5)]; //FIXME align + int tmp_step= src_stride >= 7*MB_SIZE ? MB_SIZE : MB_SIZE*src_stride; + uint8_t tmp[src_stride*7*MB_SIZE]; //FIXME align + uint8_t *ptmp; int x,y; if(b_x<0){ @@ -2509,18 +2515,21 @@ static always_inline void add_yblock_buffered(SnowContext *s, slice_buffer * sb, if(b_w<=0 || b_h<=0) return; -assert(src_stride > 7*MB_SIZE); +assert(src_stride > 2*MB_SIZE + 5); // old_dst += src_x + src_y*dst_stride; dst8+= src_x + src_y*src_stride; // src += src_x + src_y*src_stride; - block[0]= tmp+3*MB_SIZE; + ptmp= tmp + 3*tmp_step; + block[0]= ptmp; + ptmp+=tmp_step; pred_block(s, block[0], src, tmp, src_stride, src_x, src_y, b_w, b_h, lt, plane_index, w, h); if(same_block(lt, rt)){ block[1]= block[0]; }else{ - block[1]= tmp + 4*MB_SIZE; + block[1]= ptmp; + ptmp+=tmp_step; pred_block(s, block[1], src, tmp, src_stride, src_x, src_y, b_w, b_h, rt, plane_index, w, h); } @@ -2529,7 +2538,8 @@ assert(src_stride > 7*MB_SIZE); }else if(same_block(rt, lb)){ block[2]= block[1]; }else{ - block[2]= tmp+5*MB_SIZE; + block[2]= ptmp; + ptmp+=tmp_step; pred_block(s, block[2], src, tmp, src_stride, src_x, src_y, b_w, b_h, lb, plane_index, w, h); } @@ -2540,7 +2550,7 @@ assert(src_stride > 7*MB_SIZE); }else if(same_block(lb, rb)){ block[3]= block[2]; }else{ - block[3]= tmp+6*MB_SIZE; + block[3]= ptmp; pred_block(s, block[3], src, tmp, src_stride, src_x, src_y, b_w, b_h, rb, plane_index, w, h); } #if 0 @@ -2581,7 +2591,6 @@ assert(src_stride > 7*MB_SIZE); START_TIMER - int block_index = 0; for(y=0; y<b_h; y++){ //FIXME ugly missue of obmc_stride uint8_t *obmc1= obmc + y*obmc_stride; @@ -2627,7 +2636,9 @@ static always_inline void add_yblock(SnowContext *s, DWTELEM *dst, uint8_t *dst8 BlockNode *lb= lt+b_stride; BlockNode *rb= lb+1; uint8_t *block[4]; - uint8_t tmp[src_stride*(b_h+5)]; //FIXME align + int tmp_step= src_stride >= 7*MB_SIZE ? MB_SIZE : MB_SIZE*src_stride; + uint8_t tmp[src_stride*7*MB_SIZE]; //FIXME align + uint8_t *ptmp; int x,y; if(b_x<0){ @@ -2662,18 +2673,21 @@ static always_inline void add_yblock(SnowContext *s, DWTELEM *dst, uint8_t *dst8 if(b_w<=0 || b_h<=0) return; -assert(src_stride > 7*MB_SIZE); +assert(src_stride > 2*MB_SIZE + 5); dst += src_x + src_y*dst_stride; dst8+= src_x + src_y*src_stride; // src += src_x + src_y*src_stride; - block[0]= tmp+3*MB_SIZE; + ptmp= tmp + 3*tmp_step; + block[0]= ptmp; + ptmp+=tmp_step; pred_block(s, block[0], src, tmp, src_stride, src_x, src_y, b_w, b_h, lt, plane_index, w, h); if(same_block(lt, rt)){ block[1]= block[0]; }else{ - block[1]= tmp + 4*MB_SIZE; + block[1]= ptmp; + ptmp+=tmp_step; pred_block(s, block[1], src, tmp, src_stride, src_x, src_y, b_w, b_h, rt, plane_index, w, h); } @@ -2682,7 +2696,8 @@ assert(src_stride > 7*MB_SIZE); }else if(same_block(rt, lb)){ block[2]= block[1]; }else{ - block[2]= tmp+5*MB_SIZE; + block[2]= ptmp; + ptmp+=tmp_step; pred_block(s, block[2], src, tmp, src_stride, src_x, src_y, b_w, b_h, lb, plane_index, w, h); } @@ -2693,7 +2708,7 @@ assert(src_stride > 7*MB_SIZE); }else if(same_block(lb, rb)){ block[3]= block[2]; }else{ - block[3]= tmp+6*MB_SIZE; + block[3]= ptmp; pred_block(s, block[3], src, tmp, src_stride, src_x, src_y, b_w, b_h, rb, plane_index, w, h); } #if 0 @@ -2900,7 +2915,7 @@ static void quantize(SnowContext *s, SubBand *b, DWTELEM *src, int stride, int b const int qlog= clip(s->qlog + b->qlog, 0, QROOT*16); const int qmul= qexp[qlog&(QROOT-1)]<<(qlog>>QSHIFT); int x,y, thres1, thres2; - START_TIMER +// START_TIMER if(s->qlog == LOSSLESS_QLOG) return; @@ -2956,7 +2971,6 @@ static void quantize(SnowContext *s, SubBand *b, DWTELEM *src, int stride, int b static void dequantize_slice_buffered(SnowContext *s, slice_buffer * sb, SubBand *b, DWTELEM *src, int stride, int start_y, int end_y){ const int w= b->width; - const int h= b->height; const int qlog= clip(s->qlog + b->qlog, 0, QROOT*16); const int qmul= qexp[qlog&(QROOT-1)]<<(qlog>>QSHIFT); const int qadd= (s->qbias*qmul)>>QBIAS_SHIFT; @@ -3034,7 +3048,6 @@ static void decorrelate(SnowContext *s, SubBand *b, DWTELEM *src, int stride, in static void correlate_slice_buffered(SnowContext *s, slice_buffer * sb, SubBand *b, DWTELEM *src, int stride, int inverse, int use_median, int start_y, int end_y){ const int w= b->width; - const int h= b->height; int x,y; // START_TIMER diff --git a/src/libffmpeg/libavcodec/svq1.c b/src/libffmpeg/libavcodec/svq1.c index e59f1c731..b94472e34 100644 --- a/src/libffmpeg/libavcodec/svq1.c +++ b/src/libffmpeg/libavcodec/svq1.c @@ -1118,8 +1118,15 @@ static int svq1_encode_plane(SVQ1Context *s, int plane, unsigned char *src_plane s->m.b8_stride= 2*s->m.mb_width+1; s->m.f_code=1; s->m.pict_type= s->picture.pict_type; - s->m.qscale= s->picture.quality/FF_QP2LAMBDA; s->m.me_method= s->avctx->me_method; + s->m.me.scene_change_score=0; + s->m.flags= s->avctx->flags; +// s->m.out_format = FMT_H263; +// s->m.unrestricted_mv= 1; + + s->m.lambda= s->picture.quality; + s->m.qscale= (s->m.lambda*139 + FF_LAMBDA_SCALE*64) >> (FF_LAMBDA_SHIFT + 7); + s->m.lambda2= (s->m.lambda*s->m.lambda + FF_LAMBDA_SCALE/2) >> FF_LAMBDA_SHIFT; if(!s->motion_val8[plane]){ s->motion_val8 [plane]= av_mallocz((s->m.b8_stride*block_height*2 + 2)*2*sizeof(int16_t)); diff --git a/src/libffmpeg/libavcodec/ulti.c b/src/libffmpeg/libavcodec/ulti.c index 1b5853047..1b47bddbd 100755 --- a/src/libffmpeg/libavcodec/ulti.c +++ b/src/libffmpeg/libavcodec/ulti.c @@ -37,7 +37,7 @@ typedef struct UltimotionDecodeContext { AVCodecContext *avctx; int width, height, blocks; AVFrame frame; - uint8_t *ulti_codebook; + const uint8_t *ulti_codebook; } UltimotionDecodeContext; static int ulti_decode_init(AVCodecContext *avctx) diff --git a/src/libffmpeg/libavcodec/utils.c b/src/libffmpeg/libavcodec/utils.c index 0a0971fc3..f68d658e7 100644 --- a/src/libffmpeg/libavcodec/utils.c +++ b/src/libffmpeg/libavcodec/utils.c @@ -28,26 +28,10 @@ #include "dsputil.h" #include "mpegvideo.h" #include "integer.h" +#include "opt.h" #include <stdarg.h> #include <limits.h> - -const uint8_t ff_sqrt_tab[128]={ - 0, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11 -}; - -const uint8_t ff_log2_tab[256]={ - 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, - 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, - 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, - 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 -}; +#include <float.h> const uint8_t ff_reverse[256]={ 0x00,0x80,0x40,0xC0,0x20,0xA0,0x60,0xE0,0x10,0x90,0x50,0xD0,0x30,0xB0,0x70,0xF0, @@ -68,6 +52,8 @@ const uint8_t ff_reverse[256]={ 0x0F,0x8F,0x4F,0xCF,0x2F,0xAF,0x6F,0xEF,0x1F,0x9F,0x5F,0xDF,0x3F,0xBF,0x7F,0xFF, }; +static int volatile entangled_thread_counter=0; + void avcodec_default_free_buffers(AVCodecContext *s); void *av_mallocz(unsigned int size) @@ -160,6 +146,17 @@ void av_free_static(void) } /** + * Call av_free_static automatically before it's too late + */ + +static void do_free() __attribute__ ((destructor)); + +static void do_free() +{ + av_free_static(); +} + +/** * Frees memory and sets the pointer to NULL. * @param arg pointer to the pointer which should be freed */ @@ -439,7 +436,283 @@ static const char* context_to_name(void* ptr) { return "NULL"; } -static AVClass av_codec_context_class = { "AVCodecContext", context_to_name }; +#define OFFSET(x) (int)&((AVCodecContext*)0)->x +#define DEFAULT 0 //should be NAN but it doesnt work as its not a constant in glibc as required by ANSI/ISO C +//these names are too long to be readable +#define V AV_OPT_FLAG_VIDEO_PARAM +#define A AV_OPT_FLAG_AUDIO_PARAM +#define S AV_OPT_FLAG_SUBTITLE_PARAM +#define E AV_OPT_FLAG_ENCODING_PARAM +#define D AV_OPT_FLAG_DECODING_PARAM + +static AVOption options[]={ +{"bit_rate", NULL, OFFSET(bit_rate), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|A|E}, +{"bit_rate_tolerance", NULL, OFFSET(bit_rate_tolerance), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, +{"flags", NULL, OFFSET(flags), FF_OPT_TYPE_FLAGS, DEFAULT, INT_MIN, INT_MAX, V|A|E|D, "flags"}, +{"mv4", "use four motion vector by macroblock (mpeg4)", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_4MV, INT_MIN, INT_MAX, V|E, "flags"}, +{"obmc", "use overlapped block motion compensation (h263+)", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_OBMC, INT_MIN, INT_MAX, V|E, "flags"}, +{"qpel", "use 1/4 pel motion compensation", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_QPEL, INT_MIN, INT_MAX, V|E, "flags"}, +{"loop", "use loop filter", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_LOOP_FILTER, INT_MIN, INT_MAX, V|E, "flags"}, +{"qscale", "use fixed qscale", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_QSCALE, INT_MIN, INT_MAX, 0, "flags"}, +{"gmc", "use gmc", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_GMC, INT_MIN, INT_MAX, V|E, "flags"}, +{"mv0", "always try a mb with mv=<0,0>", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_MV0, INT_MIN, INT_MAX, V|E, "flags"}, +{"part", "use data partitioning", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_PART, INT_MIN, INT_MAX, V|E, "flags"}, +{"input_preserved", NULL, 0, FF_OPT_TYPE_CONST, CODEC_FLAG_INPUT_PRESERVED, INT_MIN, INT_MAX, 0, "flags"}, +{"pass1", "use internal 2pass ratecontrol in first pass mode", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_PASS1, INT_MIN, INT_MAX, 0, "flags"}, +{"pass2", "use internal 2pass ratecontrol in second pass mode", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_PASS2, INT_MIN, INT_MAX, 0, "flags"}, +{"extern_huff", "use external huffman table (for mjpeg)", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_EXTERN_HUFF, INT_MIN, INT_MAX, 0, "flags"}, +{"gray", "only decode/encode grayscale", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_GRAY, INT_MIN, INT_MAX, V|E|D, "flags"}, +{"emu_edge", "don't draw edges", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_EMU_EDGE, INT_MIN, INT_MAX, 0, "flags"}, +{"psnr", "error[?] variables will be set during encoding", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_PSNR, INT_MIN, INT_MAX, V|E, "flags"}, +{"truncated", NULL, 0, FF_OPT_TYPE_CONST, CODEC_FLAG_TRUNCATED, INT_MIN, INT_MAX, 0, "flags"}, +{"naq", "normalize adaptive quantization", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_NORMALIZE_AQP, INT_MIN, INT_MAX, V|E, "flags"}, +{"ildct", "use interlaced dct", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_INTERLACED_DCT, INT_MIN, INT_MAX, V|E, "flags"}, +{"low_delay", "force low delay", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_LOW_DELAY, INT_MIN, INT_MAX, V|D, "flags"}, +{"alt", "enable alternate scantable (mpeg2/mpeg4)", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_ALT_SCAN, INT_MIN, INT_MAX, V|E, "flags"}, +{"trell", "use trellis quantization", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_TRELLIS_QUANT, INT_MIN, INT_MAX, V|E, "flags"}, +{"global_header", "place global headers in extradata instead of every keyframe", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_GLOBAL_HEADER, INT_MIN, INT_MAX, 0, "flags"}, +{"bitexact", "use only bitexact stuff (except (i)dct)", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_BITEXACT, INT_MIN, INT_MAX, A|V|S|D|E, "flags"}, +{"aic", "h263 advanced intra coding / mpeg4 ac prediction", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_AC_PRED, INT_MIN, INT_MAX, V|E, "flags"}, +{"umv", "use unlimited motion vectors", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_H263P_UMV, INT_MIN, INT_MAX, V|E, "flags"}, +{"cbp", "use rate distortion optimization for cbp", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_CBP_RD, INT_MIN, INT_MAX, V|E, "flags"}, +{"qprd", "use rate distortion optimization for qp selection", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_QP_RD, INT_MIN, INT_MAX, V|E, "flags"}, +{"aiv", "h263 alternative inter vlc", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_H263P_AIV, INT_MIN, INT_MAX, V|E, "flags"}, +{"slice", NULL, 0, FF_OPT_TYPE_CONST, CODEC_FLAG_H263P_SLICE_STRUCT, INT_MIN, INT_MAX, V|E, "flags"}, +{"ilme", "interlaced motion estimation", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_INTERLACED_ME, INT_MIN, INT_MAX, V|E, "flags"}, +{"scan_offset", "will reserve space for svcd scan offset user data", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_SVCD_SCAN_OFFSET, INT_MIN, INT_MAX, V|E, "flags"}, +{"cgop", "closed gop", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_CLOSED_GOP, INT_MIN, INT_MAX, V|E, "flags"}, +{"fast", "allow non spec compliant speedup tricks", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_FAST, INT_MIN, INT_MAX, V|E, "flags2"}, +{"sgop", "strictly enforce gop size", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_STRICT_GOP, INT_MIN, INT_MAX, V|E, "flags2"}, +{"noout", "skip bitstream encoding", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_NO_OUTPUT, INT_MIN, INT_MAX, V|E, "flags2"}, +{"local_header", "place global headers at every keyframe instead of in extradata", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_LOCAL_HEADER, INT_MIN, INT_MAX, V|E, "flags2"}, +{"sub_id", NULL, OFFSET(sub_id), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, +{"me_method", NULL, OFFSET(me_method), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E, "me_method"}, +{"extradata_size", NULL, OFFSET(extradata_size), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, +{"time_base", NULL, OFFSET(time_base), FF_OPT_TYPE_RATIONAL, DEFAULT, INT_MIN, INT_MAX}, +{"gop_size", NULL, OFFSET(gop_size), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, +{"rate_emu", NULL, OFFSET(rate_emu), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, +{"sample_rate", NULL, OFFSET(sample_rate), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, +{"channels", NULL, OFFSET(channels), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, +{"frame_size", NULL, OFFSET(frame_size), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, +{"frame_number", NULL, OFFSET(frame_number), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, +{"real_pict_num", NULL, OFFSET(real_pict_num), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, +{"delay", NULL, OFFSET(delay), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, +{"qcompress", NULL, OFFSET(qcompress), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX, V|E}, +{"qblur", NULL, OFFSET(qblur), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX, V|E}, +{"qmin", NULL, OFFSET(qmin), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, +{"qmax", NULL, OFFSET(qmax), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, +{"max_qdiff", NULL, OFFSET(max_qdiff), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, +{"max_b_frames", NULL, OFFSET(max_b_frames), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, +{"b_quant_factor", NULL, OFFSET(b_quant_factor), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX, V|E}, +{"rc_strategy", NULL, OFFSET(rc_strategy), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, +{"b_frame_strategy", NULL, OFFSET(b_frame_strategy), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, +{"hurry_up", NULL, OFFSET(hurry_up), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|D}, +{"rtp_mode", NULL, OFFSET(rtp_mode), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, +{"rtp_payload_size", NULL, OFFSET(rtp_payload_size), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, +{"mv_bits", NULL, OFFSET(mv_bits), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, +{"header_bits", NULL, OFFSET(header_bits), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, +{"i_tex_bits", NULL, OFFSET(i_tex_bits), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, +{"p_tex_bits", NULL, OFFSET(p_tex_bits), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, +{"i_count", NULL, OFFSET(i_count), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, +{"p_count", NULL, OFFSET(p_count), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, +{"skip_count", NULL, OFFSET(skip_count), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, +{"misc_bits", NULL, OFFSET(misc_bits), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, +{"frame_bits", NULL, OFFSET(frame_bits), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, +{"codec_tag", NULL, OFFSET(codec_tag), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, +{"bugs", NULL, OFFSET(workaround_bugs), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|D, "bug"}, +{"autodetect", NULL, 0, FF_OPT_TYPE_CONST, FF_BUG_AUTODETECT, INT_MIN, INT_MAX, V|D, "bug"}, +{"old_msmpeg4", NULL, 0, FF_OPT_TYPE_CONST, FF_BUG_OLD_MSMPEG4, INT_MIN, INT_MAX, V|D, "bug"}, +{"xvid_ilace", NULL, 0, FF_OPT_TYPE_CONST, FF_BUG_XVID_ILACE, INT_MIN, INT_MAX, V|D, "bug"}, +{"ump4", NULL, 0, FF_OPT_TYPE_CONST, FF_BUG_UMP4, INT_MIN, INT_MAX, V|D, "bug"}, +{"no_padding", NULL, 0, FF_OPT_TYPE_CONST, FF_BUG_NO_PADDING, INT_MIN, INT_MAX, V|D, "bug"}, +{"amv", NULL, 0, FF_OPT_TYPE_CONST, FF_BUG_AMV, INT_MIN, INT_MAX, V|D, "bug"}, +{"ac_vlc", NULL, 0, FF_OPT_TYPE_CONST, FF_BUG_AC_VLC, INT_MIN, INT_MAX, V|D, "bug"}, +{"qpel_chroma", NULL, 0, FF_OPT_TYPE_CONST, FF_BUG_QPEL_CHROMA, INT_MIN, INT_MAX, V|D, "bug"}, +{"std_qpel", NULL, 0, FF_OPT_TYPE_CONST, FF_BUG_STD_QPEL, INT_MIN, INT_MAX, V|D, "bug"}, +{"qpel_chroma2", NULL, 0, FF_OPT_TYPE_CONST, FF_BUG_QPEL_CHROMA2, INT_MIN, INT_MAX, V|D, "bug"}, +{"direct_blocksize", NULL, 0, FF_OPT_TYPE_CONST, FF_BUG_DIRECT_BLOCKSIZE, INT_MIN, INT_MAX, V|D, "bug"}, +{"edge", NULL, 0, FF_OPT_TYPE_CONST, FF_BUG_EDGE, INT_MIN, INT_MAX, V|D, "bug"}, +{"hpel_chroma", NULL, 0, FF_OPT_TYPE_CONST, FF_BUG_HPEL_CHROMA, INT_MIN, INT_MAX, V|D, "bug"}, +{"dc_clip", NULL, 0, FF_OPT_TYPE_CONST, FF_BUG_DC_CLIP, INT_MIN, INT_MAX, V|D, "bug"}, +{"ms", NULL, 0, FF_OPT_TYPE_CONST, FF_BUG_MS, INT_MIN, INT_MAX, V|D, "bug"}, +{"lelim", "single coefficient elimination threshold for luminance (negative values also consider dc coefficient)", OFFSET(luma_elim_threshold), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, +{"celim", "single coefficient elimination threshold for chrominance (negative values also consider dc coefficient)", OFFSET(chroma_elim_threshold), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, +{"strict", NULL, OFFSET(strict_std_compliance), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E, "strict"}, +{"very", NULL, 0, FF_OPT_TYPE_CONST, FF_COMPLIANCE_VERY_STRICT, INT_MIN, INT_MAX, V|E, "strict"}, +{"strict", NULL, 0, FF_OPT_TYPE_CONST, FF_COMPLIANCE_STRICT, INT_MIN, INT_MAX, V|E, "strict"}, +{"normal", NULL, 0, FF_OPT_TYPE_CONST, FF_COMPLIANCE_NORMAL, INT_MIN, INT_MAX, V|E, "strict"}, +{"inofficial", NULL, 0, FF_OPT_TYPE_CONST, FF_COMPLIANCE_INOFFICIAL, INT_MIN, INT_MAX, V|E, "strict"}, +{"experimental", NULL, 0, FF_OPT_TYPE_CONST, FF_COMPLIANCE_EXPERIMENTAL, INT_MIN, INT_MAX, V|E, "strict"}, +{"b_quant_offset", NULL, OFFSET(b_quant_offset), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX, V|E}, +{"er", NULL, OFFSET(error_resilience), FF_OPT_TYPE_INT, FF_ER_CAREFUL, INT_MIN, INT_MAX, V|D, "er"}, +{"careful", NULL, 0, FF_OPT_TYPE_CONST, FF_ER_CAREFUL, INT_MIN, INT_MAX, V|D, "er"}, +{"compliant", NULL, 0, FF_OPT_TYPE_CONST, FF_ER_COMPLIANT, INT_MIN, INT_MAX, V|D, "er"}, +{"aggressive", NULL, 0, FF_OPT_TYPE_CONST, FF_ER_AGGRESSIVE, INT_MIN, INT_MAX, V|D, "er"}, +{"very_aggressive", NULL, 0, FF_OPT_TYPE_CONST, FF_ER_VERY_AGGRESSIVE, INT_MIN, INT_MAX, V|D, "er"}, +{"has_b_frames", NULL, OFFSET(has_b_frames), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, +{"block_align", NULL, OFFSET(block_align), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, +{"parse_only", NULL, OFFSET(parse_only), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, +{"mpeg_quant", NULL, OFFSET(mpeg_quant), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, +{"stats_out", NULL, OFFSET(stats_out), FF_OPT_TYPE_STRING, DEFAULT, CHAR_MIN, CHAR_MAX}, +{"stats_in", NULL, OFFSET(stats_in), FF_OPT_TYPE_STRING, DEFAULT, CHAR_MIN, CHAR_MAX}, +{"rc_qsquish", NULL, OFFSET(rc_qsquish), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX, V|E}, +{"rc_qmod_amp", NULL, OFFSET(rc_qmod_amp), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX, V|E}, +{"rc_qmod_freq", NULL, OFFSET(rc_qmod_freq), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, +{"rc_override_count", NULL, OFFSET(rc_override_count), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, +{"rc_eq", NULL, OFFSET(rc_eq), FF_OPT_TYPE_STRING, DEFAULT, CHAR_MIN, CHAR_MAX, V|E}, +{"rc_max_rate", NULL, OFFSET(rc_max_rate), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, +{"rc_min_rate", NULL, OFFSET(rc_min_rate), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, +{"rc_buffer_size", NULL, OFFSET(rc_buffer_size), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, +{"rc_buf_aggressivity", NULL, OFFSET(rc_buffer_aggressivity), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX, V|E}, +{"i_quant_factor", NULL, OFFSET(i_quant_factor), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX, V|E}, +{"i_quant_offset", NULL, OFFSET(i_quant_offset), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX, V|E}, +{"rc_initial_cplx", NULL, OFFSET(rc_initial_cplx), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX, V|E}, +{"dct", NULL, OFFSET(dct_algo), FF_OPT_TYPE_INT, DEFAULT, 0, INT_MAX, V|E, "dct"}, +{"auto", NULL, 0, FF_OPT_TYPE_CONST, FF_DCT_AUTO, INT_MIN, INT_MAX, V|E, "dct"}, +{"fastint", NULL, 0, FF_OPT_TYPE_CONST, FF_DCT_FASTINT, INT_MIN, INT_MAX, V|E, "dct"}, +{"int", NULL, 0, FF_OPT_TYPE_CONST, FF_DCT_INT, INT_MIN, INT_MAX, V|E, "dct"}, +{"mmx", NULL, 0, FF_OPT_TYPE_CONST, FF_DCT_MMX, INT_MIN, INT_MAX, V|E, "dct"}, +{"mlib", NULL, 0, FF_OPT_TYPE_CONST, FF_DCT_MLIB, INT_MIN, INT_MAX, V|E, "dct"}, +{"altivec", NULL, 0, FF_OPT_TYPE_CONST, FF_DCT_ALTIVEC, INT_MIN, INT_MAX, V|E, "dct"}, +{"faan", NULL, 0, FF_OPT_TYPE_CONST, FF_DCT_FAAN, INT_MIN, INT_MAX, V|E, "dct"}, +{"lumi_mask", "lumimasking", OFFSET(lumi_masking), FF_OPT_TYPE_FLOAT, 0, FLT_MIN, FLT_MAX, V|E}, +{"tcplx_mask", "temporal complexity masking", OFFSET(temporal_cplx_masking), FF_OPT_TYPE_FLOAT, 0, FLT_MIN, FLT_MAX, V|E}, +{"scplx_mask", "spatial complexity masking", OFFSET(spatial_cplx_masking), FF_OPT_TYPE_FLOAT, 0, FLT_MIN, FLT_MAX, V|E}, +{"p_mask", "inter masking", OFFSET(p_masking), FF_OPT_TYPE_FLOAT, 0, FLT_MIN, FLT_MAX, V|E}, +{"dark_mask", "darkness masking", OFFSET(dark_masking), FF_OPT_TYPE_FLOAT, 0, FLT_MIN, FLT_MAX, V|E}, +{"unused", NULL, OFFSET(unused), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, +{"idct", NULL, OFFSET(idct_algo), FF_OPT_TYPE_INT, DEFAULT, 0, INT_MAX, V|E|D, "idct"}, +{"auto", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_AUTO, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"int", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_INT, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"simple", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_SIMPLE, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"simplemmx", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_SIMPLEMMX, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"libmpeg2mmx", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_LIBMPEG2MMX, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"ps2", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_PS2, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"mlib", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_MLIB, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"arm", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_ARM, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"altivec", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_ALTIVEC, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"sh4", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_SH4, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"simplearm", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_SIMPLEARM, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"h264", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_H264, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"vp3", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_VP3, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"ipp", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_IPP, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"xvidmmx", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_XVIDMMX, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"slice_count", NULL, OFFSET(slice_count), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, +{"ec", NULL, OFFSET(error_concealment), FF_OPT_TYPE_FLAGS, 3, INT_MIN, INT_MAX, V|D, "ec"}, +{"guess_mvs", NULL, 0, FF_OPT_TYPE_CONST, FF_EC_GUESS_MVS, INT_MIN, INT_MAX, V|D, "ec"}, +{"deblock", NULL, 0, FF_OPT_TYPE_CONST, FF_EC_DEBLOCK, INT_MIN, INT_MAX, V|D, "ec"}, +{"bits_per_sample", NULL, OFFSET(bits_per_sample), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, +{"pred", "prediction method", OFFSET(prediction_method), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E, "pred"}, +{"left", NULL, 0, FF_OPT_TYPE_CONST, FF_PRED_LEFT, INT_MIN, INT_MAX, V|E, "pred"}, +{"plane", NULL, 0, FF_OPT_TYPE_CONST, FF_PRED_PLANE, INT_MIN, INT_MAX, V|E, "pred"}, +{"median", NULL, 0, FF_OPT_TYPE_CONST, FF_PRED_MEDIAN, INT_MIN, INT_MAX, V|E, "pred"}, +{"aspect", NULL, OFFSET(sample_aspect_ratio), FF_OPT_TYPE_RATIONAL, DEFAULT, 0, 10, V|E}, +{"debug", "print specific debug info", OFFSET(debug), FF_OPT_TYPE_FLAGS, DEFAULT, 0, INT_MAX, V|A|S|E|D, "debug"}, +{"pict", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_PICT_INFO, INT_MIN, INT_MAX, V|D, "debug"}, +{"rc", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_RC, INT_MIN, INT_MAX, V|E, "debug"}, +{"bitstream", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_BITSTREAM, INT_MIN, INT_MAX, V|D, "debug"}, +{"mb_type", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_MB_TYPE, INT_MIN, INT_MAX, V|D, "debug"}, +{"qp", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_QP, INT_MIN, INT_MAX, V|D, "debug"}, +{"mv", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_MV, INT_MIN, INT_MAX, V|D, "debug"}, +{"dct_coeff", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_DCT_COEFF, INT_MIN, INT_MAX, V|D, "debug"}, +{"skip", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_SKIP, INT_MIN, INT_MAX, V|D, "debug"}, +{"startcode", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_STARTCODE, INT_MIN, INT_MAX, V|D, "debug"}, +{"pts", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_PTS, INT_MIN, INT_MAX, V|D, "debug"}, +{"er", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_ER, INT_MIN, INT_MAX, V|D, "debug"}, +{"mmco", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_MMCO, INT_MIN, INT_MAX, V|D, "debug"}, +{"bugs", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_BUGS, INT_MIN, INT_MAX, V|D, "debug"}, +{"vis_qp", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_VIS_QP, INT_MIN, INT_MAX, V|D, "debug"}, +{"vis_mb_type", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_VIS_MB_TYPE, INT_MIN, INT_MAX, V|D, "debug"}, +{"vismv", "visualize motion vectors", OFFSET(debug_mv), FF_OPT_TYPE_INT, DEFAULT, 0, INT_MAX, V|D, "debug_mv"}, +{"pf", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_VIS_MV_P_FOR, INT_MIN, INT_MAX, V|D, "debug_mv"}, +{"bf", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_VIS_MV_B_FOR, INT_MIN, INT_MAX, V|D, "debug_mv"}, +{"bb", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_VIS_MV_B_BACK, INT_MIN, INT_MAX, V|D, "debug_mv"}, +{"mb_qmin", NULL, OFFSET(mb_qmin), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, +{"mb_qmax", NULL, OFFSET(mb_qmax), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, +{"cmp", "full pel me compare function", OFFSET(me_cmp), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"subcmp", "sub pel me compare function", OFFSET(me_sub_cmp), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"mbcmp", "macroblock compare function", OFFSET(mb_cmp), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"ildctcmp", "interlaced dct compare function", OFFSET(ildct_cmp), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"dia_size", NULL, OFFSET(dia_size), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, +{"last_pred", NULL, OFFSET(last_predictor_count), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, +{"preme", NULL, OFFSET(pre_me), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, +{"precmp", "pre motion estimation compare function", OFFSET(me_pre_cmp), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"sad", NULL, 0, FF_OPT_TYPE_CONST, FF_CMP_SAD, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"sse", NULL, 0, FF_OPT_TYPE_CONST, FF_CMP_SSE, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"satd", NULL, 0, FF_OPT_TYPE_CONST, FF_CMP_SATD, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"dct", NULL, 0, FF_OPT_TYPE_CONST, FF_CMP_DCT, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"psnr", NULL, 0, FF_OPT_TYPE_CONST, FF_CMP_PSNR, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"bit", NULL, 0, FF_OPT_TYPE_CONST, FF_CMP_BIT, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"rd", NULL, 0, FF_OPT_TYPE_CONST, FF_CMP_RD, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"zero", NULL, 0, FF_OPT_TYPE_CONST, FF_CMP_ZERO, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"vsad", NULL, 0, FF_OPT_TYPE_CONST, FF_CMP_VSAD, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"vsse", NULL, 0, FF_OPT_TYPE_CONST, FF_CMP_VSSE, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"nsse", NULL, 0, FF_OPT_TYPE_CONST, FF_CMP_NSSE, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"w53", NULL, 0, FF_OPT_TYPE_CONST, FF_CMP_W53, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"w97", NULL, 0, FF_OPT_TYPE_CONST, FF_CMP_W97, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"dctmax", NULL, 0, FF_OPT_TYPE_CONST, FF_CMP_DCTMAX, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"chroma", NULL, 0, FF_OPT_TYPE_CONST, FF_CMP_CHROMA, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"pre_dia_size", NULL, OFFSET(pre_dia_size), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, +{"subq", "sub pel motion estimation quality", OFFSET(me_subpel_quality), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, +{"dtg_active_format", NULL, OFFSET(dtg_active_format), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, +{"me_range", NULL, OFFSET(me_range), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, +{"ibias", NULL, OFFSET(intra_quant_bias), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, +{"pbias", NULL, OFFSET(inter_quant_bias), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, +{"color_table_id", NULL, OFFSET(color_table_id), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, +{"internal_buffer_count", NULL, OFFSET(internal_buffer_count), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, +{"global_quality", NULL, OFFSET(global_quality), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, +{"coder", NULL, OFFSET(coder_type), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E, "coder"}, +{"vlc", "variable length coder / huffman coder", 0, FF_OPT_TYPE_CONST, FF_CODER_TYPE_VLC, INT_MIN, INT_MAX, V|E, "coder"}, +{"ac", "arithmetic coder", 0, FF_OPT_TYPE_CONST, FF_CODER_TYPE_AC, INT_MIN, INT_MAX, V|E, "coder"}, +{"context", "context model", OFFSET(context_model), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, +{"slice_flags", NULL, OFFSET(slice_flags), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, +{"xvmc_acceleration", NULL, OFFSET(xvmc_acceleration), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, +{"mbd", NULL, OFFSET(mb_decision), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E, "mbd"}, +{"simple", NULL, 0, FF_OPT_TYPE_CONST, FF_MB_DECISION_SIMPLE, INT_MIN, INT_MAX, V|E, "mbd"}, +{"bits", NULL, 0, FF_OPT_TYPE_CONST, FF_MB_DECISION_BITS, INT_MIN, INT_MAX, V|E, "mbd"}, +{"rd", NULL, 0, FF_OPT_TYPE_CONST, FF_MB_DECISION_RD, INT_MIN, INT_MAX, V|E, "mbd"}, +{"stream_codec_tag", NULL, OFFSET(stream_codec_tag), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, +{"sc_threshold", NULL, OFFSET(scenechange_threshold), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, +{"lmin", "min lagrange factor", OFFSET(lmin), FF_OPT_TYPE_INT, 2*FF_QP2LAMBDA, 0, INT_MAX, V|E}, +{"lmax", "max lagrange factor", OFFSET(lmax), FF_OPT_TYPE_INT, 31*FF_QP2LAMBDA, 0, INT_MAX, V|E}, +{"nr", "noise reduction", OFFSET(noise_reduction), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, +{"rc_init_occupancy", NULL, OFFSET(rc_initial_buffer_occupancy), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, +{"inter_threshold", NULL, OFFSET(inter_threshold), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, +{"flags2", NULL, OFFSET(flags2), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, +{"error_rate", NULL, OFFSET(error_rate), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, +{"antialias", NULL, OFFSET(antialias_algo), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|D, "aa"}, +{"auto", NULL, 0, FF_OPT_TYPE_CONST, FF_AA_AUTO, INT_MIN, INT_MAX, V|D, "aa"}, +{"fastint", NULL, 0, FF_OPT_TYPE_CONST, FF_AA_FASTINT, INT_MIN, INT_MAX, V|D, "aa"}, +{"int", NULL, 0, FF_OPT_TYPE_CONST, FF_AA_INT, INT_MIN, INT_MAX, V|D, "aa"}, +{"float", NULL, 0, FF_OPT_TYPE_CONST, FF_AA_FLOAT, INT_MIN, INT_MAX, V|D, "aa"}, +{"qns", "quantizer noise shaping", OFFSET(quantizer_noise_shaping), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, +{"thread_count", NULL, OFFSET(thread_count), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E|D}, +{"me_threshold", "motion estimaton threshold", OFFSET(me_threshold), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, +{"mb_threshold", NULL, OFFSET(mb_threshold), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, +{"dc", NULL, OFFSET(intra_dc_precision), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, +{"nssew", "nsse weight", OFFSET(nsse_weight), FF_OPT_TYPE_INT, 8, INT_MIN, INT_MAX, V|E}, +{"skip_top", NULL, OFFSET(skip_top), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|D}, +{"skip_bottom", NULL, OFFSET(skip_bottom), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|D}, +{"profile", NULL, OFFSET(profile), FF_OPT_TYPE_INT, FF_PROFILE_UNKNOWN, INT_MIN, INT_MAX, V|A|E, "profile"}, +{"unknown", NULL, 0, FF_OPT_TYPE_CONST, FF_PROFILE_UNKNOWN, INT_MIN, INT_MAX, V|A|E, "profile"}, +{"level", NULL, OFFSET(level), FF_OPT_TYPE_INT, FF_LEVEL_UNKNOWN, INT_MIN, INT_MAX, V|A|E, "level"}, +{"unknown", NULL, 0, FF_OPT_TYPE_CONST, FF_LEVEL_UNKNOWN, INT_MIN, INT_MAX, V|A|E, "level"}, +{"lowres", NULL, OFFSET(lowres), FF_OPT_TYPE_INT, 0, 0, INT_MAX, V|D}, +{"frame_skip_threshold", NULL, OFFSET(frame_skip_threshold), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, +{"frame_skip_factor", NULL, OFFSET(frame_skip_factor), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, +{"frame_skip_exp", NULL, OFFSET(frame_skip_exp), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, +{"skipcmp", "frame skip comapare function", OFFSET(frame_skip_cmp), FF_OPT_TYPE_INT, FF_CMP_DCTMAX, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"border_mask", NULL, OFFSET(border_masking), FF_OPT_TYPE_FLOAT, DEFAULT, FLT_MIN, FLT_MAX, V|E}, +{"mb_lmin", NULL, OFFSET(mb_lmin), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, +{"mb_lmax", NULL, OFFSET(mb_lmax), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, +{"me_penalty_compensation", NULL, OFFSET(me_penalty_compensation), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, +{NULL}, +}; + +#undef A +#undef V + +static AVClass av_codec_context_class = { "AVCodecContext", context_to_name, options }; void avcodec_get_context_defaults(AVCodecContext *s){ memset(s, 0, sizeof(AVCodecContext)); @@ -478,6 +751,8 @@ void avcodec_get_context_defaults(AVCodecContext *s){ s->level= FF_LEVEL_UNKNOWN; s->me_penalty_compensation= 256; s->pix_fmt= PIX_FMT_NONE; + s->frame_skip_cmp= FF_CMP_DCTMAX; + s->nsse_weight= 8; s->intra_quant_bias= FF_DEFAULT_QUANT_BIAS; s->inter_quant_bias= FF_DEFAULT_QUANT_BIAS; @@ -522,10 +797,16 @@ AVFrame *avcodec_alloc_frame(void){ int avcodec_open(AVCodecContext *avctx, AVCodec *codec) { - int ret; + int ret= -1; + + entangled_thread_counter++; + if(entangled_thread_counter != 1){ + av_log(avctx, AV_LOG_ERROR, "insufficient thread locking around avcodec_open/close()\n"); + goto end; + } if(avctx->codec) - return -1; + goto end; avctx->codec = codec; avctx->codec_id = codec->id; @@ -533,7 +814,7 @@ int avcodec_open(AVCodecContext *avctx, AVCodec *codec) if (codec->priv_data_size > 0) { avctx->priv_data = av_mallocz(codec->priv_data_size); if (!avctx->priv_data) - return -ENOMEM; + goto end; } else { avctx->priv_data = NULL; } @@ -545,15 +826,18 @@ int avcodec_open(AVCodecContext *avctx, AVCodec *codec) if((avctx->coded_width||avctx->coded_height) && avcodec_check_dimensions(avctx,avctx->coded_width,avctx->coded_height)){ av_freep(&avctx->priv_data); - return -1; + goto end; } ret = avctx->codec->init(avctx); if (ret < 0) { av_freep(&avctx->priv_data); - return ret; + goto end; } - return 0; + ret=0; +end: + entangled_thread_counter--; + return ret; } int avcodec_encode_audio(AVCodecContext *avctx, uint8_t *buf, int buf_size, @@ -670,11 +954,19 @@ int avcodec_decode_subtitle(AVCodecContext *avctx, AVSubtitle *sub, int avcodec_close(AVCodecContext *avctx) { + entangled_thread_counter++; + if(entangled_thread_counter != 1){ + av_log(avctx, AV_LOG_ERROR, "insufficient thread locking around avcodec_open/close()\n"); + entangled_thread_counter--; + return -1; + } + if (avctx->codec->close) avctx->codec->close(avctx); avcodec_default_free_buffers(avctx); av_freep(&avctx->priv_data); avctx->codec = NULL; + entangled_thread_counter--; return 0; } @@ -755,12 +1047,14 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) codec_name = enc->codec_name; } else { /* output avi tags */ - if (enc->codec_type == CODEC_TYPE_VIDEO) { - snprintf(buf1, sizeof(buf1), "%c%c%c%c", + if( isprint(enc->codec_tag&0xFF) && isprint((enc->codec_tag>>8)&0xFF) + && isprint((enc->codec_tag>>16)&0xFF) && isprint((enc->codec_tag>>24)&0xFF)){ + snprintf(buf1, sizeof(buf1), "%c%c%c%c / 0x%04X", enc->codec_tag & 0xff, (enc->codec_tag >> 8) & 0xff, (enc->codec_tag >> 16) & 0xff, - (enc->codec_tag >> 24) & 0xff); + (enc->codec_tag >> 24) & 0xff, + enc->codec_tag); } else { snprintf(buf1, sizeof(buf1), "0x%04x", enc->codec_tag); } @@ -779,9 +1073,14 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) } if (enc->width) { snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", %dx%d, %0.2f fps", - enc->width, enc->height, - 1/av_q2d(enc->time_base)); + ", %dx%d", + enc->width, enc->height); + if(av_log_get_level() >= AV_LOG_DEBUG){ + int g= ff_gcd(enc->time_base.num, enc->time_base.den); + snprintf(buf + strlen(buf), buf_size - strlen(buf), + ", %d/%d", + enc->time_base.num/g, enc->time_base.den/g); + } } if (encode) { snprintf(buf + strlen(buf), buf_size - strlen(buf), @@ -816,6 +1115,19 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) /* for PCM codecs, compute bitrate directly */ switch(enc->codec_id) { + case CODEC_ID_PCM_S32LE: + case CODEC_ID_PCM_S32BE: + case CODEC_ID_PCM_U32LE: + case CODEC_ID_PCM_U32BE: + bitrate = enc->sample_rate * enc->channels * 32; + break; + case CODEC_ID_PCM_S24LE: + case CODEC_ID_PCM_S24BE: + case CODEC_ID_PCM_U24LE: + case CODEC_ID_PCM_U24BE: + case CODEC_ID_PCM_S24DAUD: + bitrate = enc->sample_rate * enc->channels * 24; + break; case CODEC_ID_PCM_S16LE: case CODEC_ID_PCM_S16BE: case CODEC_ID_PCM_U16LE: @@ -919,79 +1231,6 @@ char av_get_pict_type_char(int pict_type){ } } -int av_reduce(int *dst_nom, int *dst_den, int64_t nom, int64_t den, int64_t max){ - AVRational a0={0,1}, a1={1,0}; - int sign= (nom<0) ^ (den<0); - int64_t gcd= ff_gcd(ABS(nom), ABS(den)); - - nom = ABS(nom)/gcd; - den = ABS(den)/gcd; - if(nom<=max && den<=max){ - a1= (AVRational){nom, den}; - den=0; - } - - while(den){ - int64_t x = nom / den; - int64_t next_den= nom - den*x; - int64_t a2n= x*a1.num + a0.num; - int64_t a2d= x*a1.den + a0.den; - - if(a2n > max || a2d > max) break; - - a0= a1; - a1= (AVRational){a2n, a2d}; - nom= den; - den= next_den; - } - assert(ff_gcd(a1.num, a1.den) == 1); - - *dst_nom = sign ? -a1.num : a1.num; - *dst_den = a1.den; - - return den==0; -} - -int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd){ - AVInteger ai; - int64_t r=0; - assert(c > 0); - assert(b >=0); - assert(rnd >=0 && rnd<=5 && rnd!=4); - - if(a<0 && a != INT64_MIN) return -av_rescale_rnd(-a, b, c, rnd ^ ((rnd>>1)&1)); - - if(rnd==AV_ROUND_NEAR_INF) r= c/2; - else if(rnd&1) r= c-1; - - if(b<=INT_MAX && c<=INT_MAX){ - if(a<=INT_MAX) - return (a * b + r)/c; - else - return a/c*b + (a%c*b + r)/c; - } - - ai= av_mul_i(av_int2i(a), av_int2i(b)); - ai= av_add_i(ai, av_int2i(r)); - - return av_i2int(av_div_i(ai, av_int2i(c))); -} - -int64_t av_rescale(int64_t a, int64_t b, int64_t c){ - return av_rescale_rnd(a, b, c, AV_ROUND_NEAR_INF); -} - -int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq){ - int64_t b= bq.num * (int64_t)cq.den; - int64_t c= cq.num * (int64_t)bq.den; - return av_rescale_rnd(a, b, c, AV_ROUND_NEAR_INF); -} - -int64_t ff_gcd(int64_t a, int64_t b){ - if(b) return ff_gcd(b, a%b); - else return a; -} - /* av_log API */ static int av_log_level = AV_LOG_INFO; @@ -1002,11 +1241,11 @@ static void av_log_default_callback(void* ptr, int level, const char* fmt, va_li AVClass* avc= ptr ? *(AVClass**)ptr : NULL; if(level>av_log_level) return; -#undef fprintf +/* #undef fprintf */ if(print_prefix && avc) { fprintf(stderr, "[%s @ %p]", avc->item_name(ptr), avc); } -#define fprintf please_use_av_log +/* #define fprintf please_use_av_log */ print_prefix= strstr(fmt, "\n") != NULL; diff --git a/src/libffmpeg/libavcodec/vmdav.c b/src/libffmpeg/libavcodec/vmdav.c index 4305f81fd..37b85d7cc 100644 --- a/src/libffmpeg/libavcodec/vmdav.c +++ b/src/libffmpeg/libavcodec/vmdav.c @@ -66,16 +66,18 @@ typedef struct VmdVideoContext { unsigned char palette[PALETTE_COUNT * 4]; unsigned char *unpack_buffer; + int unpack_buffer_size; } VmdVideoContext; #define QUEUE_SIZE 0x1000 #define QUEUE_MASK 0x0FFF -static void lz_unpack(unsigned char *src, unsigned char *dest) +static void lz_unpack(unsigned char *src, unsigned char *dest, int dest_len) { unsigned char *s; unsigned char *d; + unsigned char *d_end; unsigned char queue[QUEUE_SIZE]; unsigned int qpos; unsigned int dataleft; @@ -87,6 +89,7 @@ static void lz_unpack(unsigned char *src, unsigned char *dest) s = src; d = dest; + d_end = d + dest_len; dataleft = LE_32(s); s += 4; memset(queue, QUEUE_SIZE, 0x20); @@ -102,6 +105,8 @@ static void lz_unpack(unsigned char *src, unsigned char *dest) while (dataleft > 0) { tag = *s++; if ((tag == 0xFF) && (dataleft > 8)) { + if (d + 8 > d_end) + return; for (i = 0; i < 8; i++) { queue[qpos++] = *d++ = *s++; qpos &= QUEUE_MASK; @@ -112,6 +117,8 @@ static void lz_unpack(unsigned char *src, unsigned char *dest) if (dataleft == 0) break; if (tag & 0x01) { + if (d + 1 > d_end) + return; queue[qpos++] = *d++ = *s++; qpos &= QUEUE_MASK; dataleft--; @@ -121,6 +128,8 @@ static void lz_unpack(unsigned char *src, unsigned char *dest) chainlen = (*s++ & 0x0F) + 3; if (chainlen == speclen) chainlen = *s++ + 0xF + 3; + if (d + chainlen > d_end) + return; for (j = 0; j < chainlen; j++) { *d = queue[chainofs++ & QUEUE_MASK]; queue[qpos++] = *d++; @@ -134,27 +143,33 @@ static void lz_unpack(unsigned char *src, unsigned char *dest) } } -static int rle_unpack(unsigned char *src, unsigned char *dest, int len) +static int rle_unpack(unsigned char *src, unsigned char *dest, + int src_len, int dest_len) { unsigned char *ps; unsigned char *pd; int i, l; + unsigned char *dest_end = dest + dest_len; ps = src; pd = dest; - if (len & 1) + if (src_len & 1) *pd++ = *ps++; - len >>= 1; + src_len >>= 1; i = 0; do { l = *ps++; if (l & 0x80) { l = (l & 0x7F) * 2; + if (pd + l > dest_end) + return (ps - src); memcpy(pd, ps, l); ps += l; pd += l; } else { + if (pd + i > dest_end) + return (ps - src); for (i = 0; i < l; i++) { *pd++ = ps[0]; *pd++ = ps[1]; @@ -162,7 +177,7 @@ static int rle_unpack(unsigned char *src, unsigned char *dest, int len) ps += 2; } i += l; - } while (i < len); + } while (i < src_len); return (ps - src); } @@ -185,6 +200,7 @@ static void vmd_decode(VmdVideoContext *s) int frame_x, frame_y; int frame_width, frame_height; + int dp_size; frame_x = LE_16(&s->buf[6]); frame_y = LE_16(&s->buf[8]); @@ -217,12 +233,13 @@ static void vmd_decode(VmdVideoContext *s) pb = p; meth = *pb++; if (meth & 0x80) { - lz_unpack(pb, s->unpack_buffer); + lz_unpack(pb, s->unpack_buffer, s->unpack_buffer_size); meth &= 0x7F; pb = s->unpack_buffer; } dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x]; + dp_size = s->frame.linesize[0] * s->avctx->height; pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x]; switch (meth) { case 1: @@ -232,11 +249,15 @@ static void vmd_decode(VmdVideoContext *s) len = *pb++; if (len & 0x80) { len = (len & 0x7F) + 1; + if (ofs + len > frame_width) + return; memcpy(&dp[ofs], pb, len); pb += len; ofs += len; } else { /* interframe pixel copy */ + if (ofs + len + 1 > frame_width) + return; memcpy(&dp[ofs], &pp[ofs], len + 1); ofs += len + 1; } @@ -268,13 +289,15 @@ static void vmd_decode(VmdVideoContext *s) if (len & 0x80) { len = (len & 0x7F) + 1; if (*pb++ == 0xFF) - len = rle_unpack(pb, &dp[ofs], len); + len = rle_unpack(pb, &dp[ofs], len, frame_width - ofs); else memcpy(&dp[ofs], pb, len); pb += len; ofs += len; } else { /* interframe pixel copy */ + if (ofs + len + 1 > frame_width) + return; memcpy(&dp[ofs], &pp[ofs], len + 1); ofs += len + 1; } @@ -314,7 +337,8 @@ static int vmdvideo_decode_init(AVCodecContext *avctx) } vmd_header = (unsigned char *)avctx->extradata; - s->unpack_buffer = av_malloc(LE_32(&vmd_header[800])); + s->unpack_buffer_size = LE_32(&vmd_header[800]); + s->unpack_buffer = av_malloc(s->unpack_buffer_size); if (!s->unpack_buffer) return -1; diff --git a/src/libffmpeg/libavcodec/vp3.c b/src/libffmpeg/libavcodec/vp3.c index 757036d97..9cff50e55 100644 --- a/src/libffmpeg/libavcodec/vp3.c +++ b/src/libffmpeg/libavcodec/vp3.c @@ -75,61 +75,61 @@ #define DEBUG_IDCT 0 #if DEBUG_VP3 -#define debug_vp3 printf +#define debug_vp3(args...) av_log(NULL, AV_LOG_DEBUG, ## args) #else static inline void debug_vp3(const char *format, ...) { } #endif #if DEBUG_INIT -#define debug_init printf +#define debug_init(args...) av_log(NULL, AV_LOG_DEBUG, ## args) #else static inline void debug_init(const char *format, ...) { } #endif #if DEBUG_DEQUANTIZERS -#define debug_dequantizers printf +#define debug_dequantizers(args...) av_log(NULL, AV_LOG_DEBUG, ## args) #else static inline void debug_dequantizers(const char *format, ...) { } #endif #if DEBUG_BLOCK_CODING -#define debug_block_coding printf +#define debug_block_coding(args...) av_log(NULL, AV_LOG_DEBUG, ## args) #else static inline void debug_block_coding(const char *format, ...) { } #endif #if DEBUG_MODES -#define debug_modes printf +#define debug_modes(args...) av_log(NULL, AV_LOG_DEBUG, ## args) #else static inline void debug_modes(const char *format, ...) { } #endif #if DEBUG_VECTORS -#define debug_vectors printf +#define debug_vectors(args...) av_log(NULL, AV_LOG_DEBUG, ## args) #else static inline void debug_vectors(const char *format, ...) { } #endif #if DEBUG_TOKEN -#define debug_token printf +#define debug_token(args...) av_log(NULL, AV_LOG_DEBUG, ## args) #else static inline void debug_token(const char *format, ...) { } #endif #if DEBUG_VLC -#define debug_vlc printf +#define debug_vlc(args...) av_log(NULL, AV_LOG_DEBUG, ## args) #else static inline void debug_vlc(const char *format, ...) { } #endif #if DEBUG_DC_PRED -#define debug_dc_pred printf +#define debug_dc_pred(args...) av_log(NULL, AV_LOG_DEBUG, ## args) #else static inline void debug_dc_pred(const char *format, ...) { } #endif #if DEBUG_IDCT -#define debug_idct printf +#define debug_idct(args...) av_log(NULL, AV_LOG_DEBUG, ## args) #else static inline void debug_idct(const char *format, ...) { } #endif @@ -621,230 +621,6 @@ static int init_block_mapping(Vp3DecodeContext *s) } /* - * This function unpacks a single token (which should be in the range 0..31) - * and returns a zero run (number of zero coefficients in current DCT matrix - * before next non-zero coefficient), the next DCT coefficient, and the - * number of consecutive, non-EOB'd DCT blocks to EOB. - */ -static void unpack_token(GetBitContext *gb, int token, int *zero_run, - DCTELEM *coeff, int *eob_run) -{ - int sign; - - *zero_run = 0; - *eob_run = 0; - *coeff = 0; - - debug_token(" vp3 token %d: ", token); - switch (token) { - - case 0: - debug_token("DCT_EOB_TOKEN, EOB next block\n"); - *eob_run = 1; - break; - - case 1: - debug_token("DCT_EOB_PAIR_TOKEN, EOB next 2 blocks\n"); - *eob_run = 2; - break; - - case 2: - debug_token("DCT_EOB_TRIPLE_TOKEN, EOB next 3 blocks\n"); - *eob_run = 3; - break; - - case 3: - debug_token("DCT_REPEAT_RUN_TOKEN, "); - *eob_run = get_bits(gb, 2) + 4; - debug_token("EOB the next %d blocks\n", *eob_run); - break; - - case 4: - debug_token("DCT_REPEAT_RUN2_TOKEN, "); - *eob_run = get_bits(gb, 3) + 8; - debug_token("EOB the next %d blocks\n", *eob_run); - break; - - case 5: - debug_token("DCT_REPEAT_RUN3_TOKEN, "); - *eob_run = get_bits(gb, 4) + 16; - debug_token("EOB the next %d blocks\n", *eob_run); - break; - - case 6: - debug_token("DCT_REPEAT_RUN4_TOKEN, "); - *eob_run = get_bits(gb, 12); - debug_token("EOB the next %d blocks\n", *eob_run); - break; - - case 7: - debug_token("DCT_SHORT_ZRL_TOKEN, "); - /* note that this token actually indicates that (3 extra bits) + 1 0s - * should be output; this case specifies a run of (3 EBs) 0s and a - * coefficient of 0. */ - *zero_run = get_bits(gb, 3); - *coeff = 0; - debug_token("skip the next %d positions in output matrix\n", *zero_run + 1); - break; - - case 8: - debug_token("DCT_ZRL_TOKEN, "); - /* note that this token actually indicates that (6 extra bits) + 1 0s - * should be output; this case specifies a run of (6 EBs) 0s and a - * coefficient of 0. */ - *zero_run = get_bits(gb, 6); - *coeff = 0; - debug_token("skip the next %d positions in output matrix\n", *zero_run + 1); - break; - - case 9: - debug_token("ONE_TOKEN, output 1\n"); - *coeff = 1; - break; - - case 10: - debug_token("MINUS_ONE_TOKEN, output -1\n"); - *coeff = -1; - break; - - case 11: - debug_token("TWO_TOKEN, output 2\n"); - *coeff = 2; - break; - - case 12: - debug_token("MINUS_TWO_TOKEN, output -2\n"); - *coeff = -2; - break; - - case 13: - case 14: - case 15: - case 16: - debug_token("LOW_VAL_TOKENS, "); - if (get_bits(gb, 1)) - *coeff = -(3 + (token - 13)); - else - *coeff = 3 + (token - 13); - debug_token("output %d\n", *coeff); - break; - - case 17: - debug_token("DCT_VAL_CATEGORY3, "); - sign = get_bits(gb, 1); - *coeff = 7 + get_bits(gb, 1); - if (sign) - *coeff = -(*coeff); - debug_token("output %d\n", *coeff); - break; - - case 18: - debug_token("DCT_VAL_CATEGORY4, "); - sign = get_bits(gb, 1); - *coeff = 9 + get_bits(gb, 2); - if (sign) - *coeff = -(*coeff); - debug_token("output %d\n", *coeff); - break; - - case 19: - debug_token("DCT_VAL_CATEGORY5, "); - sign = get_bits(gb, 1); - *coeff = 13 + get_bits(gb, 3); - if (sign) - *coeff = -(*coeff); - debug_token("output %d\n", *coeff); - break; - - case 20: - debug_token("DCT_VAL_CATEGORY6, "); - sign = get_bits(gb, 1); - *coeff = 21 + get_bits(gb, 4); - if (sign) - *coeff = -(*coeff); - debug_token("output %d\n", *coeff); - break; - - case 21: - debug_token("DCT_VAL_CATEGORY7, "); - sign = get_bits(gb, 1); - *coeff = 37 + get_bits(gb, 5); - if (sign) - *coeff = -(*coeff); - debug_token("output %d\n", *coeff); - break; - - case 22: - debug_token("DCT_VAL_CATEGORY8, "); - sign = get_bits(gb, 1); - *coeff = 69 + get_bits(gb, 9); - if (sign) - *coeff = -(*coeff); - debug_token("output %d\n", *coeff); - break; - - case 23: - case 24: - case 25: - case 26: - case 27: - debug_token("DCT_RUN_CATEGORY1, "); - *zero_run = token - 22; - if (get_bits(gb, 1)) - *coeff = -1; - else - *coeff = 1; - debug_token("output %d 0s, then %d\n", *zero_run, *coeff); - break; - - case 28: - debug_token("DCT_RUN_CATEGORY1B, "); - if (get_bits(gb, 1)) - *coeff = -1; - else - *coeff = 1; - *zero_run = 6 + get_bits(gb, 2); - debug_token("output %d 0s, then %d\n", *zero_run, *coeff); - break; - - case 29: - debug_token("DCT_RUN_CATEGORY1C, "); - if (get_bits(gb, 1)) - *coeff = -1; - else - *coeff = 1; - *zero_run = 10 + get_bits(gb, 3); - debug_token("output %d 0s, then %d\n", *zero_run, *coeff); - break; - - case 30: - debug_token("DCT_RUN_CATEGORY2, "); - sign = get_bits(gb, 1); - *coeff = 2 + get_bits(gb, 1); - if (sign) - *coeff = -(*coeff); - *zero_run = 1; - debug_token("output %d 0s, then %d\n", *zero_run, *coeff); - break; - - case 31: - debug_token("DCT_RUN_CATEGORY2, "); - sign = get_bits(gb, 1); - *coeff = 2 + get_bits(gb, 1); - if (sign) - *coeff = -(*coeff); - *zero_run = 2 + get_bits(gb, 1); - debug_token("output %d 0s, then %d\n", *zero_run, *coeff); - break; - - default: - av_log(NULL, AV_LOG_ERROR, " vp3: help! Got a bad token: %d > 31\n", token); - break; - - } -} - -/* * This function wipes out all of the fragment data. */ static void init_frame(Vp3DecodeContext *s, GetBitContext *gb) @@ -983,213 +759,6 @@ static void init_loop_filter(Vp3DecodeContext *s) } /* - * This function is used to fetch runs of 1s or 0s from the bitstream for - * use in determining which superblocks are fully and partially coded. - * - * Codeword RunLength - * 0 1 - * 10x 2-3 - * 110x 4-5 - * 1110xx 6-9 - * 11110xxx 10-17 - * 111110xxxx 18-33 - * 111111xxxxxxxxxxxx 34-4129 - */ -static int get_superblock_run_length(GetBitContext *gb) -{ - - if (get_bits(gb, 1) == 0) - return 1; - - else if (get_bits(gb, 1) == 0) - return (2 + get_bits(gb, 1)); - - else if (get_bits(gb, 1) == 0) - return (4 + get_bits(gb, 1)); - - else if (get_bits(gb, 1) == 0) - return (6 + get_bits(gb, 2)); - - else if (get_bits(gb, 1) == 0) - return (10 + get_bits(gb, 3)); - - else if (get_bits(gb, 1) == 0) - return (18 + get_bits(gb, 4)); - - else - return (34 + get_bits(gb, 12)); - -} - -/* - * This function is used to fetch runs of 1s or 0s from the bitstream for - * use in determining which particular fragments are coded. - * - * Codeword RunLength - * 0x 1-2 - * 10x 3-4 - * 110x 5-6 - * 1110xx 7-10 - * 11110xx 11-14 - * 11111xxxx 15-30 - */ -static int get_fragment_run_length(GetBitContext *gb) -{ - - if (get_bits(gb, 1) == 0) - return (1 + get_bits(gb, 1)); - - else if (get_bits(gb, 1) == 0) - return (3 + get_bits(gb, 1)); - - else if (get_bits(gb, 1) == 0) - return (5 + get_bits(gb, 1)); - - else if (get_bits(gb, 1) == 0) - return (7 + get_bits(gb, 2)); - - else if (get_bits(gb, 1) == 0) - return (11 + get_bits(gb, 2)); - - else - return (15 + get_bits(gb, 4)); - -} - -/* - * This function decodes a VLC from the bitstream and returns a number - * that ranges from 0..7. The number indicates which of the 8 coding - * modes to use. - * - * VLC Number - * 0 0 - * 10 1 - * 110 2 - * 1110 3 - * 11110 4 - * 111110 5 - * 1111110 6 - * 1111111 7 - * - */ -static int get_mode_code(GetBitContext *gb) -{ - - if (get_bits(gb, 1) == 0) - return 0; - - else if (get_bits(gb, 1) == 0) - return 1; - - else if (get_bits(gb, 1) == 0) - return 2; - - else if (get_bits(gb, 1) == 0) - return 3; - - else if (get_bits(gb, 1) == 0) - return 4; - - else if (get_bits(gb, 1) == 0) - return 5; - - else if (get_bits(gb, 1) == 0) - return 6; - - else - return 7; - -} - -/* - * This function extracts a motion vector from the bitstream using a VLC - * scheme. 3 bits are fetched from the bitstream and 1 of 8 actions is - * taken depending on the value on those 3 bits: - * - * 0: return 0 - * 1: return 1 - * 2: return -1 - * 3: if (next bit is 1) return -2, else return 2 - * 4: if (next bit is 1) return -3, else return 3 - * 5: return 4 + (next 2 bits), next bit is sign - * 6: return 8 + (next 3 bits), next bit is sign - * 7: return 16 + (next 4 bits), next bit is sign - */ -static int get_motion_vector_vlc(GetBitContext *gb) -{ - int bits; - - bits = get_bits(gb, 3); - - switch(bits) { - - case 0: - bits = 0; - break; - - case 1: - bits = 1; - break; - - case 2: - bits = -1; - break; - - case 3: - if (get_bits(gb, 1) == 0) - bits = 2; - else - bits = -2; - break; - - case 4: - if (get_bits(gb, 1) == 0) - bits = 3; - else - bits = -3; - break; - - case 5: - bits = 4 + get_bits(gb, 2); - if (get_bits(gb, 1) == 1) - bits = -bits; - break; - - case 6: - bits = 8 + get_bits(gb, 3); - if (get_bits(gb, 1) == 1) - bits = -bits; - break; - - case 7: - bits = 16 + get_bits(gb, 4); - if (get_bits(gb, 1) == 1) - bits = -bits; - break; - - } - - return bits; -} - -/* - * This function fetches a 5-bit number from the stream followed by - * a sign and calls it a motion vector. - */ -static int get_motion_vector_fixed(GetBitContext *gb) -{ - - int bits; - - bits = get_bits(gb, 5); - - if (get_bits(gb, 1) == 1) - bits = -bits; - - return bits; -} - -/* * This function unpacks all of the superblock/macroblock/fragment coding * information from the bitstream. */ @@ -1222,14 +791,10 @@ static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb) while (current_superblock < s->superblock_count) { if (current_run-- == 0) { bit ^= 1; -#if 1 current_run = get_vlc2(gb, s->superblock_run_length_vlc.table, 6, 2); if (current_run == 33) current_run += get_bits(gb, 12); -#else - current_run = get_superblock_run_length(gb); -#endif debug_block_coding(" setting superblocks %d..%d to %s\n", current_superblock, current_superblock + current_run - 1, @@ -1266,14 +831,10 @@ static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb) if (current_run-- == 0) { bit ^= 1; -#if 1 current_run = get_vlc2(gb, s->superblock_run_length_vlc.table, 6, 2); if (current_run == 33) current_run += get_bits(gb, 12); -#else - current_run = get_superblock_run_length(gb); -#endif } debug_block_coding(" setting superblock %d to %s\n", @@ -1330,12 +891,8 @@ static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb) * that cares about the fragment coding runs */ if (current_run-- == 0) { bit ^= 1; -#if 1 current_run = get_vlc2(gb, s->fragment_run_length_vlc.table, 5, 2); -#else - current_run = get_fragment_run_length(gb); -#endif } if (bit) { @@ -1463,14 +1020,8 @@ static int unpack_modes(Vp3DecodeContext *s, GetBitContext *gb) if (scheme == 7) coding_mode = get_bits(gb, 3); else -{ -#if 1 coding_mode = ModeAlphabet[scheme] [get_vlc2(gb, s->mode_code_vlc.table, 3, 3)]; -#else - coding_mode = ModeAlphabet[scheme][get_mode_code(gb)]; -#endif -} s->macroblock_coding[current_macroblock] = coding_mode; for (k = 0; k < 6; k++) { @@ -1557,21 +1108,11 @@ static int unpack_vectors(Vp3DecodeContext *s, GetBitContext *gb) case MODE_GOLDEN_MV: /* all 6 fragments use the same motion vector */ if (coding_mode == 0) { -#if 1 motion_x[0] = motion_vector_table[get_vlc2(gb, s->motion_vector_vlc.table, 6, 2)]; motion_y[0] = motion_vector_table[get_vlc2(gb, s->motion_vector_vlc.table, 6, 2)]; -#else - motion_x[0] = get_motion_vector_vlc(gb); - motion_y[0] = get_motion_vector_vlc(gb); -#endif } else { -#if 1 motion_x[0] = fixed_motion_vector_table[get_bits(gb, 6)]; motion_y[0] = fixed_motion_vector_table[get_bits(gb, 6)]; -#else - motion_x[0] = get_motion_vector_fixed(gb); - motion_y[0] = get_motion_vector_fixed(gb); -#endif } for (k = 1; k < 6; k++) { @@ -1595,21 +1136,11 @@ static int unpack_vectors(Vp3DecodeContext *s, GetBitContext *gb) motion_x[4] = motion_y[4] = 0; for (k = 0; k < 4; k++) { if (coding_mode == 0) { -#if 1 motion_x[k] = motion_vector_table[get_vlc2(gb, s->motion_vector_vlc.table, 6, 2)]; motion_y[k] = motion_vector_table[get_vlc2(gb, s->motion_vector_vlc.table, 6, 2)]; -#else - motion_x[k] = get_motion_vector_vlc(gb); - motion_y[k] = get_motion_vector_vlc(gb); -#endif } else { -#if 1 motion_x[k] = fixed_motion_vector_table[get_bits(gb, 6)]; motion_y[k] = fixed_motion_vector_table[get_bits(gb, 6)]; -#else - motion_x[k] = get_motion_vector_fixed(gb); - motion_y[k] = get_motion_vector_fixed(gb); -#endif } motion_x[4] += motion_x[k]; motion_y[4] += motion_y[k]; @@ -1744,7 +1275,6 @@ static int unpack_vlcs(Vp3DecodeContext *s, GetBitContext *gb, token = get_vlc2(gb, table->table, 5, 3); debug_vlc(" token = %2d, ", token); /* use the token to get a zero run, a coefficient, and an eob run */ -#if 1 if (token <= 6) { eob_run = eob_run_base[token]; if (eob_run_get_bits[token]) @@ -1761,9 +1291,6 @@ static int unpack_vlcs(Vp3DecodeContext *s, GetBitContext *gb, if (zero_run_get_bits[token]) zero_run += get_bits(gb, zero_run_get_bits[token]); } -#else - unpack_token(gb, token, &zero_run, &coeff, &eob_run); -#endif } if (!eob_run) { @@ -2198,7 +1725,6 @@ static void render_slice(Vp3DecodeContext *s, int slice) int plane_height; int slice_height; int current_macroblock_entry = slice * s->macroblock_width * 6; - int *bounding_values= s->bounding_values_array+127; int fragment_width; if (slice >= s->macroblock_height) @@ -2443,209 +1969,6 @@ static void render_slice(Vp3DecodeContext *s, int slice) emms_c(); } -/* - * This function performs the final rendering of each fragment's data - * onto the output frame. - */ -static void render_fragments(Vp3DecodeContext *s, - int first_fragment, - int width, - int height, - int plane /* 0 = Y, 1 = U, 2 = V */) -{ - int x, y; - int m, n; - int i = first_fragment; - int16_t *dequantizer; - DCTELEM __align16 block[64]; - unsigned char *output_plane; - unsigned char *last_plane; - unsigned char *golden_plane; - int stride; - int motion_x = 0xdeadbeef, motion_y = 0xdeadbeef; - int upper_motion_limit, lower_motion_limit; - int motion_halfpel_index; - uint8_t *motion_source; - - debug_vp3(" vp3: rendering final fragments for %s\n", - (plane == 0) ? "Y plane" : (plane == 1) ? "U plane" : "V plane"); - - /* set up plane-specific parameters */ - if (plane == 0) { - output_plane = s->current_frame.data[0]; - last_plane = s->last_frame.data[0]; - golden_plane = s->golden_frame.data[0]; - stride = s->current_frame.linesize[0]; - if (!s->flipped_image) stride = -stride; - upper_motion_limit = 7 * s->current_frame.linesize[0]; - lower_motion_limit = height * s->current_frame.linesize[0] + width - 8; - } else if (plane == 1) { - output_plane = s->current_frame.data[1]; - last_plane = s->last_frame.data[1]; - golden_plane = s->golden_frame.data[1]; - stride = s->current_frame.linesize[1]; - if (!s->flipped_image) stride = -stride; - upper_motion_limit = 7 * s->current_frame.linesize[1]; - lower_motion_limit = height * s->current_frame.linesize[1] + width - 8; - } else { - output_plane = s->current_frame.data[2]; - last_plane = s->last_frame.data[2]; - golden_plane = s->golden_frame.data[2]; - stride = s->current_frame.linesize[2]; - if (!s->flipped_image) stride = -stride; - upper_motion_limit = 7 * s->current_frame.linesize[2]; - lower_motion_limit = height * s->current_frame.linesize[2] + width - 8; - } - - if(ABS(stride) > 2048) - return; //various tables are fixed size - - /* for each fragment row... */ - for (y = 0; y < height; y += 8) { - - /* for each fragment in a row... */ - for (x = 0; x < width; x += 8, i++) { - - if ((i < 0) || (i >= s->fragment_count)) { - av_log(s->avctx, AV_LOG_ERROR, " vp3:render_fragments(): bad fragment number (%d)\n", i); - return; - } - - /* transform if this block was coded */ - if ((s->all_fragments[i].coding_method != MODE_COPY) && - !((s->avctx->flags & CODEC_FLAG_GRAY) && plane)) { - - if ((s->all_fragments[i].coding_method == MODE_USING_GOLDEN) || - (s->all_fragments[i].coding_method == MODE_GOLDEN_MV)) - motion_source= golden_plane; - else - motion_source= last_plane; - - motion_source += s->all_fragments[i].first_pixel; - motion_halfpel_index = 0; - - /* sort out the motion vector if this fragment is coded - * using a motion vector method */ - if ((s->all_fragments[i].coding_method > MODE_INTRA) && - (s->all_fragments[i].coding_method != MODE_USING_GOLDEN)) { - int src_x, src_y; - motion_x = s->all_fragments[i].motion_x; - motion_y = s->all_fragments[i].motion_y; - if(plane){ - motion_x= (motion_x>>1) | (motion_x&1); - motion_y= (motion_y>>1) | (motion_y&1); - } - - src_x= (motion_x>>1) + x; - src_y= (motion_y>>1) + y; - if ((motion_x == 127) || (motion_y == 127)) - av_log(s->avctx, AV_LOG_ERROR, " help! got invalid motion vector! (%X, %X)\n", motion_x, motion_y); - - motion_halfpel_index = motion_x & 0x01; - motion_source += (motion_x >> 1); - - motion_halfpel_index |= (motion_y & 0x01) << 1; - motion_source += ((motion_y >> 1) * stride); - - if(src_x<0 || src_y<0 || src_x + 9 >= width || src_y + 9 >= height){ - uint8_t *temp= s->edge_emu_buffer; - if(stride<0) temp -= 9*stride; - else temp += 9*stride; - - ff_emulated_edge_mc(temp, motion_source, stride, 9, 9, src_x, src_y, width, height); - motion_source= temp; - } - } - - - /* first, take care of copying a block from either the - * previous or the golden frame */ - if (s->all_fragments[i].coding_method != MODE_INTRA) { - //Note, it is possible to implement all MC cases with put_no_rnd_pixels_l2 which would look more like the VP3 source but this would be slower as put_no_rnd_pixels_tab is better optimzed - if(motion_halfpel_index != 3){ - s->dsp.put_no_rnd_pixels_tab[1][motion_halfpel_index]( - output_plane + s->all_fragments[i].first_pixel, - motion_source, stride, 8); - }else{ - int d= (motion_x ^ motion_y)>>31; // d is 0 if motion_x and _y have the same sign, else -1 - s->dsp.put_no_rnd_pixels_l2[1]( - output_plane + s->all_fragments[i].first_pixel, - motion_source - d, - motion_source + stride + 1 + d, - stride, 8); - } - dequantizer = s->inter_dequant; - }else{ - if (plane == 0) - dequantizer = s->intra_y_dequant; - else - dequantizer = s->intra_c_dequant; - } - - /* dequantize the DCT coefficients */ - debug_idct("fragment %d, coding mode %d, DC = %d, dequant = %d:\n", - i, s->all_fragments[i].coding_method, - DC_COEFF(i), dequantizer[0]); - - if(s->avctx->idct_algo==FF_IDCT_VP3){ - Coeff *coeff= s->coeffs + i; - memset(block, 0, sizeof(block)); - while(coeff->next){ - block[coeff->index]= coeff->coeff * dequantizer[coeff->index]; - coeff= coeff->next; - } - }else{ - Coeff *coeff= s->coeffs + i; - memset(block, 0, sizeof(block)); - while(coeff->next){ - block[coeff->index]= (coeff->coeff * dequantizer[coeff->index] + 2)>>2; - coeff= coeff->next; - } - } - - /* invert DCT and place (or add) in final output */ - - if (s->all_fragments[i].coding_method == MODE_INTRA) { - if(s->avctx->idct_algo!=FF_IDCT_VP3) - block[0] += 128<<3; - s->dsp.idct_put( - output_plane + s->all_fragments[i].first_pixel, - stride, - block); - } else { - s->dsp.idct_add( - output_plane + s->all_fragments[i].first_pixel, - stride, - block); - } - - debug_idct("block after idct_%s():\n", - (s->all_fragments[i].coding_method == MODE_INTRA)? - "put" : "add"); - for (m = 0; m < 8; m++) { - for (n = 0; n < 8; n++) { - debug_idct(" %3d", *(output_plane + - s->all_fragments[i].first_pixel + (m * stride + n))); - } - debug_idct("\n"); - } - debug_idct("\n"); - - } else { - - /* copy directly from the previous frame */ - s->dsp.put_pixels_tab[1][0]( - output_plane + s->all_fragments[i].first_pixel, - last_plane + s->all_fragments[i].first_pixel, - stride, 8); - - } - } - } - - emms_c(); -} - static void horizontal_filter(unsigned char *first_pixel, int stride, int *bounding_values) { @@ -3233,19 +2556,8 @@ if (!s->keyframe) { STOP_TIMER("reverse_dc_prediction")} {START_TIMER -#if 1 for (i = 0; i < s->macroblock_height; i++) render_slice(s, i); -#else - render_fragments(s, 0, s->width, s->height, 0); - if ((avctx->flags & CODEC_FLAG_GRAY) == 0) { - render_fragments(s, s->u_fragment_start, s->width / 2, s->height / 2, 1); - render_fragments(s, s->v_fragment_start, s->width / 2, s->height / 2, 2); - } else { - memset(s->current_frame.data[1], 0x80, s->width * s->height / 4); - memset(s->current_frame.data[2], 0x80, s->width * s->height / 4); - } -#endif STOP_TIMER("render_fragments")} {START_TIMER diff --git a/src/libffmpeg/libavcodec/vp3dsp.c b/src/libffmpeg/libavcodec/vp3dsp.c index 015f57b57..1fa6d094b 100644 --- a/src/libffmpeg/libavcodec/vp3dsp.c +++ b/src/libffmpeg/libavcodec/vp3dsp.c @@ -25,7 +25,6 @@ #include "common.h" #include "avcodec.h" #include "dsputil.h" -#include "vp3data.h" #define IdctAdjustBeforeShift 8 #define xC1S7 64277 @@ -45,7 +44,7 @@ static always_inline void idct(uint8_t *dst, int stride, int16_t *input, int typ int _Ed, _Gd, _Add, _Bdd, _Fd, _Hd; int t1, t2; - int i, j; + int i; /* Inverse DCT on the rows now */ for (i = 0; i < 8; i++) { diff --git a/src/libffmpeg/libavcodec/wmv2.c b/src/libffmpeg/libavcodec/wmv2.c index cbe5de215..75e924cb6 100644 --- a/src/libffmpeg/libavcodec/wmv2.c +++ b/src/libffmpeg/libavcodec/wmv2.c @@ -369,7 +369,7 @@ return -1; s->pict_type = get_bits(&s->gb, 1) + 1; if(s->pict_type == I_TYPE){ code = get_bits(&s->gb, 7); - av_log(s->avctx, AV_LOG_ERROR, "I7:%X/\n", code); + av_log(s->avctx, AV_LOG_DEBUG, "I7:%X/\n", code); } s->chroma_qscale= s->qscale = get_bits(&s->gb, 5); if(s->qscale < 0) @@ -513,9 +513,12 @@ static int16_t *wmv2_pred_motion(Wmv2Context *w, int *px, int *py){ B = s->current_picture.motion_val[0][xy - wrap]; C = s->current_picture.motion_val[0][xy + 2 - wrap]; - diff= FFMAX(ABS(A[0] - B[0]), ABS(A[1] - B[1])); + if(s->mb_x && !s->first_slice_line && !s->mspel && w->top_left_mv_flag) + diff= FFMAX(ABS(A[0] - B[0]), ABS(A[1] - B[1])); + else + diff=0; - if(s->mb_x && !s->first_slice_line && !s->mspel && w->top_left_mv_flag && diff >= 8) + if(diff >= 8) type= get_bits1(&s->gb); else type= 2; diff --git a/src/libffmpeg/libavcodec/xan.c b/src/libffmpeg/libavcodec/xan.c index 377a71ef2..96cc19329 100644 --- a/src/libffmpeg/libavcodec/xan.c +++ b/src/libffmpeg/libavcodec/xan.c @@ -20,12 +20,11 @@ /** * @file xan.c - * Xan video decoder for Wing Commander III & IV computer games + * Xan video decoder for Wing Commander III computer game * by Mario Brito (mbrito@student.dei.uc.pt) * and Mike Melanson (melanson@pcisys.net) * - * The xan_wc3 decoder outputs the following colorspaces natively: - * PAL8 (default), RGB555, RGB565, RGB24, BGR24, RGBA32, YUV444P + * The xan_wc3 decoder outputs PAL8 data. */ #include <stdio.h> @@ -35,77 +34,32 @@ #include "common.h" #include "avcodec.h" -#include "dsputil.h" - -#define PALETTE_COUNT 256 -#define PALETTE_CONTROL_SIZE ((256 * 3) + 1) typedef struct XanContext { AVCodecContext *avctx; - DSPContext dsp; AVFrame last_frame; AVFrame current_frame; unsigned char *buf; int size; - unsigned char palette[PALETTE_COUNT * 4]; - /* scratch space */ unsigned char *buffer1; + int buffer1_size; unsigned char *buffer2; + int buffer2_size; -} XanContext; - -/* RGB -> YUV conversion stuff */ -#define SCALEFACTOR 65536 -#define CENTERSAMPLE 128 - -#define COMPUTE_Y(r, g, b) \ - (unsigned char) \ - ((y_r_table[r] + y_g_table[g] + y_b_table[b]) / SCALEFACTOR) -#define COMPUTE_U(r, g, b) \ - (unsigned char) \ - ((u_r_table[r] + u_g_table[g] + u_b_table[b]) / SCALEFACTOR + CENTERSAMPLE) -#define COMPUTE_V(r, g, b) \ - (unsigned char) \ - ((v_r_table[r] + v_g_table[g] + v_b_table[b]) / SCALEFACTOR + CENTERSAMPLE) - -#define Y_R (SCALEFACTOR * 0.29900) -#define Y_G (SCALEFACTOR * 0.58700) -#define Y_B (SCALEFACTOR * 0.11400) - -#define U_R (SCALEFACTOR * -0.16874) -#define U_G (SCALEFACTOR * -0.33126) -#define U_B (SCALEFACTOR * 0.50000) - -#define V_R (SCALEFACTOR * 0.50000) -#define V_G (SCALEFACTOR * -0.41869) -#define V_B (SCALEFACTOR * -0.08131) + int frame_size; -/* - * Precalculate all of the YUV tables since it requires fewer than - * 10 kilobytes to store them. - */ -static int y_r_table[256]; -static int y_g_table[256]; -static int y_b_table[256]; - -static int u_r_table[256]; -static int u_g_table[256]; -static int u_b_table[256]; - -static int v_r_table[256]; -static int v_g_table[256]; -static int v_b_table[256]; +} XanContext; static int xan_decode_init(AVCodecContext *avctx) { XanContext *s = avctx->priv_data; - int i; s->avctx = avctx; + s->frame_size = 0; if ((avctx->codec->id == CODEC_ID_XAN_WC3) && (s->avctx->palctrl == NULL)) { @@ -115,28 +69,14 @@ static int xan_decode_init(AVCodecContext *avctx) avctx->pix_fmt = PIX_FMT_PAL8; avctx->has_b_frames = 0; - dsputil_init(&s->dsp, avctx); - - /* initialize the RGB -> YUV tables */ - for (i = 0; i < 256; i++) { - y_r_table[i] = Y_R * i; - y_g_table[i] = Y_G * i; - y_b_table[i] = Y_B * i; - - u_r_table[i] = U_R * i; - u_g_table[i] = U_G * i; - u_b_table[i] = U_B * i; - - v_r_table[i] = V_R * i; - v_g_table[i] = V_G * i; - v_b_table[i] = V_B * i; - } if(avcodec_check_dimensions(avctx, avctx->width, avctx->height)) return -1; - s->buffer1 = av_malloc(avctx->width * avctx->height); - s->buffer2 = av_malloc(avctx->width * avctx->height); + s->buffer1_size = avctx->width * avctx->height; + s->buffer1 = av_malloc(s->buffer1_size); + s->buffer2_size = avctx->width * avctx->height; + s->buffer2 = av_malloc(s->buffer2_size); if (!s->buffer1 || !s->buffer2) return -1; @@ -156,13 +96,15 @@ static inline void bytecopy(unsigned char *dest, unsigned char *src, int count) dest[i] = src[i]; } -static int xan_huffman_decode(unsigned char *dest, unsigned char *src) +static int xan_huffman_decode(unsigned char *dest, unsigned char *src, + int dest_len) { unsigned char byte = *src++; unsigned char ival = byte + 0x16; unsigned char * ptr = src + byte*2; unsigned char val = ival; int counter = 0; + unsigned char *dest_end = dest + dest_len; unsigned char bits = *ptr++; @@ -173,6 +115,8 @@ static int xan_huffman_decode(unsigned char *dest, unsigned char *src) val = src[val - 0x17]; if ( val < 0x16 ) { + if (dest + 1 > dest_end) + return 0; *dest++ = val; val = ival; } @@ -186,12 +130,13 @@ static int xan_huffman_decode(unsigned char *dest, unsigned char *src) return 0; } -static void xan_unpack(unsigned char *dest, unsigned char *src) +static void xan_unpack(unsigned char *dest, unsigned char *src, int dest_len) { unsigned char opcode; int size; int offset; int byte1, byte2, byte3; + unsigned char *dest_end = dest + dest_len; for (;;) { opcode = *src++; @@ -201,9 +146,13 @@ static void xan_unpack(unsigned char *dest, unsigned char *src) offset = *src++; size = opcode & 3; + if (dest + size > dest_end) + return; bytecopy(dest, src, size); dest += size; src += size; size = ((opcode & 0x1c) >> 2) + 3; + if (dest + size > dest_end) + return; bytecopy (dest, dest - (((opcode & 0x60) << 3) + offset + 1), size); dest += size; @@ -213,9 +162,13 @@ static void xan_unpack(unsigned char *dest, unsigned char *src) byte2 = *src++; size = byte1 >> 6; + if (dest + size > dest_end) + return; bytecopy (dest, src, size); dest += size; src += size; size = (opcode & 0x3f) + 4; + if (dest + size > dest_end) + return; bytecopy (dest, dest - (((byte1 & 0x3f) << 8) + byte2 + 1), size); dest += size; @@ -226,9 +179,13 @@ static void xan_unpack(unsigned char *dest, unsigned char *src) byte3 = *src++; size = opcode & 3; + if (dest + size > dest_end) + return; bytecopy (dest, src, size); dest += size; src += size; size = byte3 + 5 + ((opcode & 0xc) << 6); + if (dest + size > dest_end) + return; bytecopy (dest, dest - ((((opcode & 0x10) >> 4) << 0x10) + 1 + (byte1 << 8) + byte2), size); @@ -239,6 +196,8 @@ static void xan_unpack(unsigned char *dest, unsigned char *src) if (size > 0x70) break; + if (dest + size > dest_end) + return; bytecopy (dest, src, size); dest += size; src += size; } } @@ -247,105 +206,6 @@ static void xan_unpack(unsigned char *dest, unsigned char *src) bytecopy(dest, src, size); dest += size; src += size; } -static void inline xan_wc3_build_palette(XanContext *s, - unsigned int *palette_data) -{ - int i; - unsigned char r, g, b; - unsigned short *palette16; - unsigned int *palette32; - unsigned int pal_elem; - - /* transform the palette passed through the palette control structure - * into the necessary internal format depending on colorspace */ - - switch (s->avctx->pix_fmt) { - - case PIX_FMT_RGB555: - palette16 = (unsigned short *)s->palette; - for (i = 0; i < PALETTE_COUNT; i++) { - pal_elem = palette_data[i]; - r = (pal_elem >> 16) & 0xff; - g = (pal_elem >> 8) & 0xff; - b = pal_elem & 0xff; - palette16[i] = - ((r >> 3) << 10) | - ((g >> 3) << 5) | - ((b >> 3) << 0); - } - break; - - case PIX_FMT_RGB565: - palette16 = (unsigned short *)s->palette; - for (i = 0; i < PALETTE_COUNT; i++) { - pal_elem = palette_data[i]; - r = (pal_elem >> 16) & 0xff; - g = (pal_elem >> 8) & 0xff; - b = pal_elem & 0xff; - palette16[i] = - ((r >> 3) << 11) | - ((g >> 2) << 5) | - ((b >> 3) << 0); - } - break; - - case PIX_FMT_RGB24: - for (i = 0; i < PALETTE_COUNT; i++) { - pal_elem = palette_data[i]; - r = (pal_elem >> 16) & 0xff; - g = (pal_elem >> 8) & 0xff; - b = pal_elem & 0xff; - s->palette[i * 4 + 0] = r; - s->palette[i * 4 + 1] = g; - s->palette[i * 4 + 2] = b; - } - break; - - case PIX_FMT_BGR24: - for (i = 0; i < PALETTE_COUNT; i++) { - pal_elem = palette_data[i]; - r = (pal_elem >> 16) & 0xff; - g = (pal_elem >> 8) & 0xff; - b = pal_elem & 0xff; - s->palette[i * 4 + 0] = b; - s->palette[i * 4 + 1] = g; - s->palette[i * 4 + 2] = r; - } - break; - - case PIX_FMT_PAL8: - case PIX_FMT_RGBA32: - palette32 = (unsigned int *)s->palette; - memcpy (palette32, palette_data, PALETTE_COUNT * sizeof(unsigned int)); - break; - - case PIX_FMT_YUV444P: - for (i = 0; i < PALETTE_COUNT; i++) { - pal_elem = palette_data[i]; - r = (pal_elem >> 16) & 0xff; - g = (pal_elem >> 8) & 0xff; - b = pal_elem & 0xff; - s->palette[i * 4 + 0] = COMPUTE_Y(r, g, b); - s->palette[i * 4 + 1] = COMPUTE_U(r, g, b); - s->palette[i * 4 + 2] = COMPUTE_V(r, g, b); - } - break; - - default: - av_log(s->avctx, AV_LOG_ERROR, " Xan WC3: Unhandled colorspace\n"); - break; - } -} - -/* advance current_x variable; reset accounting variables if current_x - * moves beyond width */ -#define ADVANCE_CURRENT_X() \ - current_x++; \ - if (current_x >= width) { \ - index += line_inc; \ - current_x = 0; \ - } - static void inline xan_wc3_output_pixel_run(XanContext *s, unsigned char *pixel_buffer, int x, int y, int pixel_count) { @@ -354,124 +214,27 @@ static void inline xan_wc3_output_pixel_run(XanContext *s, int index; int current_x; int width = s->avctx->width; - unsigned char pix; unsigned char *palette_plane; - unsigned char *y_plane; - unsigned char *u_plane; - unsigned char *v_plane; - unsigned char *rgb_plane; - unsigned short *rgb16_plane; - unsigned short *palette16; - unsigned int *rgb32_plane; - unsigned int *palette32; - - switch (s->avctx->pix_fmt) { - - case PIX_FMT_PAL8: - palette_plane = s->current_frame.data[0]; - stride = s->current_frame.linesize[0]; - line_inc = stride - width; - index = y * stride + x; - current_x = x; - while(pixel_count--) { - - /* don't do a memcpy() here; keyframes generally copy an entire - * frame of data and the stride needs to be accounted for */ - palette_plane[index++] = *pixel_buffer++; - - ADVANCE_CURRENT_X(); - } - break; - - case PIX_FMT_RGB555: - case PIX_FMT_RGB565: - rgb16_plane = (unsigned short *)s->current_frame.data[0]; - palette16 = (unsigned short *)s->palette; - stride = s->current_frame.linesize[0] / 2; - line_inc = stride - width; - index = y * stride + x; - current_x = x; - while(pixel_count--) { - rgb16_plane[index++] = palette16[*pixel_buffer++]; - - ADVANCE_CURRENT_X(); - } - break; - - case PIX_FMT_RGB24: - case PIX_FMT_BGR24: - rgb_plane = s->current_frame.data[0]; - stride = s->current_frame.linesize[0]; - line_inc = stride - width * 3; - index = y * stride + x * 3; - current_x = x; - while(pixel_count--) { - pix = *pixel_buffer++; - - rgb_plane[index++] = s->palette[pix * 4 + 0]; - rgb_plane[index++] = s->palette[pix * 4 + 1]; - rgb_plane[index++] = s->palette[pix * 4 + 2]; - - ADVANCE_CURRENT_X(); + palette_plane = s->current_frame.data[0]; + stride = s->current_frame.linesize[0]; + line_inc = stride - width; + index = y * stride + x; + current_x = x; + while((pixel_count--) && (index < s->frame_size)) { + + /* don't do a memcpy() here; keyframes generally copy an entire + * frame of data and the stride needs to be accounted for */ + palette_plane[index++] = *pixel_buffer++; + + current_x++; + if (current_x >= width) { + index += line_inc; + current_x = 0; } - break; - - case PIX_FMT_RGBA32: - rgb32_plane = (unsigned int *)s->current_frame.data[0]; - palette32 = (unsigned int *)s->palette; - stride = s->current_frame.linesize[0] / 4; - line_inc = stride - width; - index = y * stride + x; - current_x = x; - while(pixel_count--) { - - rgb32_plane[index++] = palette32[*pixel_buffer++]; - - ADVANCE_CURRENT_X(); - } - break; - - case PIX_FMT_YUV444P: - y_plane = s->current_frame.data[0]; - u_plane = s->current_frame.data[1]; - v_plane = s->current_frame.data[2]; - stride = s->current_frame.linesize[0]; - line_inc = stride - width; - index = y * stride + x; - current_x = x; - while(pixel_count--) { - pix = *pixel_buffer++; - - y_plane[index] = s->palette[pix * 4 + 0]; - u_plane[index] = s->palette[pix * 4 + 1]; - v_plane[index] = s->palette[pix * 4 + 2]; - - index++; - ADVANCE_CURRENT_X(); - } - break; - - default: - av_log(s->avctx, AV_LOG_ERROR, " Xan WC3: Unhandled colorspace\n"); - break; } } -#define ADVANCE_CURFRAME_X() \ - curframe_x++; \ - if (curframe_x >= width) { \ - curframe_index += line_inc; \ - curframe_x = 0; \ - } - -#define ADVANCE_PREVFRAME_X() \ - prevframe_x++; \ - if (prevframe_x >= width) { \ - prevframe_index += line_inc; \ - prevframe_x = 0; \ - } - static void inline xan_wc3_copy_pixel_run(XanContext *s, int x, int y, int pixel_count, int motion_x, int motion_y) { @@ -481,123 +244,31 @@ static void inline xan_wc3_copy_pixel_run(XanContext *s, int curframe_x, prevframe_x; int width = s->avctx->width; unsigned char *palette_plane, *prev_palette_plane; - unsigned char *y_plane, *u_plane, *v_plane; - unsigned char *prev_y_plane, *prev_u_plane, *prev_v_plane; - unsigned char *rgb_plane, *prev_rgb_plane; - unsigned short *rgb16_plane, *prev_rgb16_plane; - unsigned int *rgb32_plane, *prev_rgb32_plane; - - switch (s->avctx->pix_fmt) { - - case PIX_FMT_PAL8: - palette_plane = s->current_frame.data[0]; - prev_palette_plane = s->last_frame.data[0]; - stride = s->current_frame.linesize[0]; - line_inc = stride - width; - curframe_index = y * stride + x; - curframe_x = x; - prevframe_index = (y + motion_y) * stride + x + motion_x; - prevframe_x = x + motion_x; - while(pixel_count--) { - - palette_plane[curframe_index++] = - prev_palette_plane[prevframe_index++]; - - ADVANCE_CURFRAME_X(); - ADVANCE_PREVFRAME_X(); - } - break; - - case PIX_FMT_RGB555: - case PIX_FMT_RGB565: - rgb16_plane = (unsigned short *)s->current_frame.data[0]; - prev_rgb16_plane = (unsigned short *)s->last_frame.data[0]; - stride = s->current_frame.linesize[0] / 2; - line_inc = stride - width; - curframe_index = y * stride + x; - curframe_x = x; - prevframe_index = (y + motion_y) * stride + x + motion_x; - prevframe_x = x + motion_x; - while(pixel_count--) { - - rgb16_plane[curframe_index++] = - prev_rgb16_plane[prevframe_index++]; - - ADVANCE_CURFRAME_X(); - ADVANCE_PREVFRAME_X(); - } - break; - - case PIX_FMT_RGB24: - case PIX_FMT_BGR24: - rgb_plane = s->current_frame.data[0]; - prev_rgb_plane = s->last_frame.data[0]; - stride = s->current_frame.linesize[0]; - line_inc = stride - width * 3; - curframe_index = y * stride + x * 3; - curframe_x = x; - prevframe_index = (y + motion_y) * stride + - (3 * (x + motion_x)); - prevframe_x = x + motion_x; - while(pixel_count--) { - - rgb_plane[curframe_index++] = prev_rgb_plane[prevframe_index++]; - rgb_plane[curframe_index++] = prev_rgb_plane[prevframe_index++]; - rgb_plane[curframe_index++] = prev_rgb_plane[prevframe_index++]; - - ADVANCE_CURFRAME_X(); - ADVANCE_PREVFRAME_X(); - } - break; - - case PIX_FMT_RGBA32: - rgb32_plane = (unsigned int *)s->current_frame.data[0]; - prev_rgb32_plane = (unsigned int *)s->last_frame.data[0]; - stride = s->current_frame.linesize[0] / 4; - line_inc = stride - width; - curframe_index = y * stride + x; - curframe_x = x; - prevframe_index = (y + motion_y) * stride + x + motion_x; - prevframe_x = x + motion_x; - while(pixel_count--) { - - rgb32_plane[curframe_index++] = - prev_rgb32_plane[prevframe_index++]; - - ADVANCE_CURFRAME_X(); - ADVANCE_PREVFRAME_X(); - } - break; - - case PIX_FMT_YUV444P: - y_plane = s->current_frame.data[0]; - u_plane = s->current_frame.data[1]; - v_plane = s->current_frame.data[2]; - prev_y_plane = s->last_frame.data[0]; - prev_u_plane = s->last_frame.data[1]; - prev_v_plane = s->last_frame.data[2]; - stride = s->current_frame.linesize[0]; - line_inc = stride - width; - curframe_index = y * stride + x; - curframe_x = x; - prevframe_index = (y + motion_y) * stride + x + motion_x; - prevframe_x = x + motion_x; - while(pixel_count--) { - - y_plane[curframe_index] = prev_y_plane[prevframe_index]; - u_plane[curframe_index] = prev_u_plane[prevframe_index]; - v_plane[curframe_index] = prev_v_plane[prevframe_index]; - - curframe_index++; - ADVANCE_CURFRAME_X(); - prevframe_index++; - ADVANCE_PREVFRAME_X(); + + palette_plane = s->current_frame.data[0]; + prev_palette_plane = s->last_frame.data[0]; + stride = s->current_frame.linesize[0]; + line_inc = stride - width; + curframe_index = y * stride + x; + curframe_x = x; + prevframe_index = (y + motion_y) * stride + x + motion_x; + prevframe_x = x + motion_x; + while((pixel_count--) && (curframe_index < s->frame_size)) { + + palette_plane[curframe_index++] = + prev_palette_plane[prevframe_index++]; + + curframe_x++; + if (curframe_x >= width) { + curframe_index += line_inc; + curframe_x = 0; } - break; - default: - av_log(s->avctx, AV_LOG_ERROR, " Xan WC3: Unhandled colorspace\n"); - break; + prevframe_x++; + if (prevframe_x >= width) { + prevframe_index += line_inc; + prevframe_x = 0; + } } } @@ -613,7 +284,9 @@ static void xan_wc3_decode_frame(XanContext *s) { int x, y; unsigned char *opcode_buffer = s->buffer1; + int opcode_buffer_size = s->buffer1_size; unsigned char *imagedata_buffer = s->buffer2; + int imagedata_buffer_size = s->buffer2_size; /* pointers to segments inside the compressed chunk */ unsigned char *huffman_segment; @@ -626,10 +299,11 @@ static void xan_wc3_decode_frame(XanContext *s) { vector_segment = s->buf + LE_16(&s->buf[4]); imagedata_segment = s->buf + LE_16(&s->buf[6]); - xan_huffman_decode(opcode_buffer, huffman_segment); + xan_huffman_decode(opcode_buffer, huffman_segment, opcode_buffer_size); if (imagedata_segment[0] == 2) - xan_unpack(imagedata_buffer, &imagedata_segment[1]); + xan_unpack(imagedata_buffer, &imagedata_segment[1], + imagedata_buffer_size); else imagedata_buffer = &imagedata_segment[1]; @@ -727,13 +401,6 @@ static void xan_wc3_decode_frame(XanContext *s) { } } } - - /* for PAL8, make the palette available on the way out */ - if (s->avctx->pix_fmt == PIX_FMT_PAL8) { - memcpy(s->current_frame.data[1], s->palette, PALETTE_COUNT * 4); - s->current_frame.palette_has_changed = 1; - s->avctx->palctrl->palette_changed = 0; - } } static void xan_wc4_decode_frame(XanContext *s) { @@ -745,16 +412,6 @@ static int xan_decode_frame(AVCodecContext *avctx, { XanContext *s = avctx->priv_data; AVPaletteControl *palette_control = avctx->palctrl; - int keyframe = 0; - - if (palette_control->palette_changed) { - /* load the new palette and reset the palette control */ - xan_wc3_build_palette(s, palette_control->palette); - /* If pal8 we clear flag when we copy palette */ - if (s->avctx->pix_fmt != PIX_FMT_PAL8) - palette_control->palette_changed = 0; - keyframe = 1; - } if (avctx->get_buffer(avctx, &s->current_frame)) { av_log(s->avctx, AV_LOG_ERROR, " Xan Video: get_buffer() failed\n"); @@ -762,6 +419,14 @@ static int xan_decode_frame(AVCodecContext *avctx, } s->current_frame.reference = 3; + if (!s->frame_size) + s->frame_size = s->current_frame.linesize[0] * s->avctx->height; + + palette_control->palette_changed = 0; + memcpy(s->current_frame.data[1], palette_control->palette, + AVPALETTE_SIZE); + s->current_frame.palette_has_changed = 1; + s->buf = buf; s->size = buf_size; @@ -789,7 +454,8 @@ static int xan_decode_end(AVCodecContext *avctx) XanContext *s = avctx->priv_data; /* release the last frame */ - avctx->release_buffer(avctx, &s->last_frame); + if (s->last_frame.data[0]) + avctx->release_buffer(avctx, &s->last_frame); av_free(s->buffer1); av_free(s->buffer2); |