QDM2 compatible decoder

Originally committed as revision 4649 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
Roberto Togni 2005-10-18 20:16:43 +00:00
parent ea7e68b1e2
commit d9b1c197e5
9 changed files with 67 additions and 30 deletions

View File

@ -23,6 +23,7 @@ Zdenek Kabelac
Robin Kay Robin Kay
Todd Kirby Todd Kirby
Nick Kurshev Nick Kurshev
Benjamin Larsson
Loïc Le Loarer Loïc Le Loarer
Mike Melanson Mike Melanson
Loren Merritt Loren Merritt

View File

@ -851,6 +851,8 @@ other implementations.
@tab QuickTime fourcc 'alac' @tab QuickTime fourcc 'alac'
@item FFmpeg Sonic @tab X @tab X @item FFmpeg Sonic @tab X @tab X
@tab experimental lossy/lossless codec @tab experimental lossy/lossless codec
@item Qdesign QDM2 @tab @tab X
@tab there are still some distortions
@end multitable @end multitable
@code{X} means that encoding (resp. decoding) is supported. @code{X} means that encoding (resp. decoding) is supported.

View File

@ -18,7 +18,7 @@ OBJS= bitstream.o utils.o mem.o allcodecs.o \
fft.o mdct.o raw.o golomb.o cabac.o\ fft.o mdct.o raw.o golomb.o cabac.o\
dpcm.o adx.o faandct.o parser.o g726.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\ 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) ifeq ($(CONFIG_AASC_DECODER),yes)
OBJS+= aasc.o OBJS+= aasc.o

View File

@ -491,6 +491,9 @@ void avcodec_register_all(void)
#ifdef CONFIG_LIBGSM #ifdef CONFIG_LIBGSM
register_avcodec(&libgsm_decoder); register_avcodec(&libgsm_decoder);
#endif //CONFIG_LIBGSM #endif //CONFIG_LIBGSM
#ifdef CONFIG_QDM2_DECODER
register_avcodec(&qdm2_decoder);
#endif //CONFIG_QDM2_DECODER
#endif /* CONFIG_DECODERS */ #endif /* CONFIG_DECODERS */
#ifdef AMR_NB #ifdef AMR_NB

View File

@ -185,6 +185,7 @@ enum CodecID {
CODEC_ID_ALAC, CODEC_ID_ALAC,
CODEC_ID_WESTWOOD_SND1, CODEC_ID_WESTWOOD_SND1,
CODEC_ID_GSM, CODEC_ID_GSM,
CODEC_ID_QDM2,
CODEC_ID_OGGTHEORA= 0x16000, CODEC_ID_OGGTHEORA= 0x16000,
@ -2000,6 +2001,7 @@ extern AVCodec mp2_decoder;
extern AVCodec mp3_decoder; extern AVCodec mp3_decoder;
extern AVCodec mp3adu_decoder; extern AVCodec mp3adu_decoder;
extern AVCodec mp3on4_decoder; extern AVCodec mp3on4_decoder;
extern AVCodec qdm2_decoder;
extern AVCodec mace3_decoder; extern AVCodec mace3_decoder;
extern AVCodec mace6_decoder; extern AVCodec mace6_decoder;
extern AVCodec huffyuv_decoder; extern AVCodec huffyuv_decoder;

View File

@ -28,8 +28,6 @@
/* currently, cannot change these constants (need to modify /* currently, cannot change these constants (need to modify
quantization stage) */ quantization stage) */
#define FRAC_BITS 15
#define WFRAC_BITS 14
#define MUL(a,b) (((int64_t)(a) * (int64_t)(b)) >> FRAC_BITS) #define MUL(a,b) (((int64_t)(a) * (int64_t)(b)) >> FRAC_BITS)
#define FIX(a) ((int)((a) * (1 << FRAC_BITS))) #define FIX(a) ((int)((a) * (1 << FRAC_BITS)))

View File

@ -22,8 +22,42 @@
#define SAME_HEADER_MASK \ #define SAME_HEADER_MASK \
(0xffe00000 | (3 << 17) | (0xf << 12) | (3 << 10) | (3 << 19)) (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 l2_select_table(int bitrate, int nb_channels, int freq, int lsf);
int mpa_decode_header(AVCodecContext *avctx, uint32_t head); 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_bitrate_tab[2][3][15];
extern const uint16_t mpa_freq_tab[3]; extern const uint16_t mpa_freq_tab[3];

View File

@ -25,7 +25,6 @@
//#define DEBUG //#define DEBUG
#include "avcodec.h" #include "avcodec.h"
#include "bitstream.h" #include "bitstream.h"
#include "mpegaudio.h"
#include "dsputil.h" #include "dsputil.h"
/* /*
@ -40,25 +39,7 @@
#define USE_HIGHPRECISION #define USE_HIGHPRECISION
#endif #endif
#ifdef USE_HIGHPRECISION #include "mpegaudio.h"
#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
#define FRAC_ONE (1 << FRAC_BITS) #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; 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 #define HEADER_SIZE 4

View File

@ -145,6 +145,7 @@ static const CodecTag mov_audio_tags[] = {
{ CODEC_ID_AMR_WB, MKTAG('s', 'a', 'w', 'b') }, /* AMR-WB 3gp */ { 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_AC3, MKTAG('m', 's', 0x20, 0x00) }, /* Dolby AC-3 */
{ CODEC_ID_ALAC,MKTAG('a', 'l', 'a', 'c') }, /* Apple Lossless */ { CODEC_ID_ALAC,MKTAG('a', 'l', 'a', 'c') }, /* Apple Lossless */
{ CODEC_ID_QDM2,MKTAG('Q', 'D', 'M', '2') }, /* QDM2 */
{ CODEC_ID_NONE, 0 }, { CODEC_ID_NONE, 0 },
}; };
@ -709,6 +710,27 @@ static int mov_read_smi(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
return 0; 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) static int mov_read_avcC(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
{ {
AVStream *st = c->fc->streams[c->fc->nb_streams-1]; 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', 'r', 'n', ' ' ), mov_read_leaf },
{ MKTAG( 'u', 'u', 'i', 'd' ), mov_read_leaf }, { MKTAG( 'u', 'u', 'i', 'd' ), mov_read_leaf },
{ MKTAG( 'v', 'm', 'h', 'd' ), mov_read_leaf }, /* video media info header */ { 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 */ /* extra mp4 */
{ MKTAG( 'M', 'D', 'E', 'S' ), mov_read_leaf }, { MKTAG( 'M', 'D', 'E', 'S' ), mov_read_leaf },
/* QT atoms */ /* QT atoms */