QDM2 compatible decoder

Originally committed as revision 4649 to svn://svn.ffmpeg.org/ffmpeg/trunk
pull/126/head
Roberto Togni 19 years ago
parent ea7e68b1e2
commit d9b1c197e5
  1. 1
      CREDITS
  2. 2
      doc/ffmpeg-doc.texi
  3. 2
      libavcodec/Makefile
  4. 3
      libavcodec/allcodecs.c
  5. 2
      libavcodec/avcodec.h
  6. 2
      libavcodec/mpegaudio.c
  7. 34
      libavcodec/mpegaudio.h
  8. 27
      libavcodec/mpegaudiodec.c
  9. 24
      libavformat/mov.c

@ -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

@ -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.

@ -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

@ -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

@ -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;

@ -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)))

@ -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];

@ -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

@ -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 */

Loading…
Cancel
Save