From d9b1c197e5f99655328b713b7100e3125139546a Mon Sep 17 00:00:00 2001 From: Roberto Togni Date: Tue, 18 Oct 2005 20:16:43 +0000 Subject: [PATCH] QDM2 compatible decoder Originally committed as revision 4649 to svn://svn.ffmpeg.org/ffmpeg/trunk --- CREDITS | 1 + doc/ffmpeg-doc.texi | 2 ++ libavcodec/Makefile | 2 +- libavcodec/allcodecs.c | 3 +++ libavcodec/avcodec.h | 2 ++ libavcodec/mpegaudio.c | 2 -- libavcodec/mpegaudio.h | 34 ++++++++++++++++++++++++++++++++++ libavcodec/mpegaudiodec.c | 27 +-------------------------- libavformat/mov.c | 24 +++++++++++++++++++++++- 9 files changed, 67 insertions(+), 30 deletions(-) diff --git a/CREDITS b/CREDITS index f28c49ca25..a80f04f051 100644 --- a/CREDITS +++ b/CREDITS @@ -23,6 +23,7 @@ Zdenek Kabelac Robin Kay Todd Kirby Nick Kurshev +Benjamin Larsson Loïc Le Loarer Mike Melanson Loren Merritt diff --git a/doc/ffmpeg-doc.texi b/doc/ffmpeg-doc.texi index 0b2560af52..900768a86e 100644 --- a/doc/ffmpeg-doc.texi +++ b/doc/ffmpeg-doc.texi @@ -851,6 +851,8 @@ other implementations. @tab QuickTime fourcc 'alac' @item FFmpeg Sonic @tab X @tab X @tab experimental lossy/lossless codec +@item Qdesign QDM2 @tab @tab X +@tab there are still some distortions @end multitable @code{X} means that encoding (resp. decoding) is supported. diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 63b696708d..2b4fdd226c 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -18,7 +18,7 @@ OBJS= bitstream.o utils.o mem.o allcodecs.o \ fft.o mdct.o raw.o golomb.o cabac.o\ dpcm.o adx.o faandct.o parser.o g726.o \ vp3dsp.o h264idct.o rangecoder.o pnm.o h263.o msmpeg4.o h263dec.o dvdsub.o dvbsub.o dvbsubdec.o\ - opt.o truemotion2.o + opt.o qdm2.o truemotion2.o ifeq ($(CONFIG_AASC_DECODER),yes) OBJS+= aasc.o diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 5dd771b1b4..5aa2564d00 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -491,6 +491,9 @@ void avcodec_register_all(void) #ifdef CONFIG_LIBGSM register_avcodec(&libgsm_decoder); #endif //CONFIG_LIBGSM +#ifdef CONFIG_QDM2_DECODER + register_avcodec(&qdm2_decoder); +#endif //CONFIG_QDM2_DECODER #endif /* CONFIG_DECODERS */ #ifdef AMR_NB diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 7ca36f5771..10c26c47b5 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -185,6 +185,7 @@ enum CodecID { CODEC_ID_ALAC, CODEC_ID_WESTWOOD_SND1, CODEC_ID_GSM, + CODEC_ID_QDM2, CODEC_ID_OGGTHEORA= 0x16000, @@ -2000,6 +2001,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; diff --git a/libavcodec/mpegaudio.c b/libavcodec/mpegaudio.c index 190aa1590c..7a0b0a31ce 100644 --- a/libavcodec/mpegaudio.c +++ b/libavcodec/mpegaudio.c @@ -28,8 +28,6 @@ /* currently, cannot change these constants (need to modify quantization stage) */ -#define FRAC_BITS 15 -#define WFRAC_BITS 14 #define MUL(a,b) (((int64_t)(a) * (int64_t)(b)) >> FRAC_BITS) #define FIX(a) ((int)((a) * (1 << FRAC_BITS))) diff --git a/libavcodec/mpegaudio.h b/libavcodec/mpegaudio.h index 072c41bda7..2bcf38eac2 100644 --- a/libavcodec/mpegaudio.h +++ b/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/libavcodec/mpegaudiodec.c b/libavcodec/mpegaudiodec.c index 708d355360..32998a6ebc 100644 --- a/libavcodec/mpegaudiodec.c +++ b/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/libavformat/mov.c b/libavformat/mov.c index 09552a48d7..71cd5113b0 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -145,6 +145,7 @@ static const CodecTag mov_audio_tags[] = { { CODEC_ID_AMR_WB, MKTAG('s', 'a', 'w', 'b') }, /* AMR-WB 3gp */ { CODEC_ID_AC3, MKTAG('m', 's', 0x20, 0x00) }, /* Dolby AC-3 */ { CODEC_ID_ALAC,MKTAG('a', 'l', 'a', 'c') }, /* Apple Lossless */ + { CODEC_ID_QDM2,MKTAG('Q', 'D', 'M', '2') }, /* QDM2 */ { CODEC_ID_NONE, 0 }, }; @@ -709,6 +710,27 @@ static int mov_read_smi(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom) return 0; } +static int mov_read_wave(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom) +{ + AVStream *st = c->fc->streams[c->fc->nb_streams-1]; + + if((uint64_t)atom.size > (1<<30)) + return -1; + + // pass all frma atom to codec, needed at least for QDM2 + av_free(st->codec->extradata); + st->codec->extradata_size = atom.size; + st->codec->extradata = (uint8_t*) av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); + + if (st->codec->extradata) { + get_buffer(pb, st->codec->extradata, atom.size); + //av_log(NULL, AV_LOG_DEBUG, "Reading frma %Ld %s\n", atom.size, (char*)st->codec->extradata); + } else + url_fskip(pb, atom.size); + + return 0; +} + static int mov_read_avcC(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom) { AVStream *st = c->fc->streams[c->fc->nb_streams-1]; @@ -1605,7 +1627,7 @@ static const MOVParseTableEntry mov_default_parse_table[] = { { MKTAG( 'u', 'r', 'n', ' ' ), mov_read_leaf }, { MKTAG( 'u', 'u', 'i', 'd' ), mov_read_leaf }, { MKTAG( 'v', 'm', 'h', 'd' ), mov_read_leaf }, /* video media info header */ -{ MKTAG( 'w', 'a', 'v', 'e' ), mov_read_default }, +{ MKTAG( 'w', 'a', 'v', 'e' ), mov_read_wave }, /* extra mp4 */ { MKTAG( 'M', 'D', 'E', 'S' ), mov_read_leaf }, /* QT atoms */