diff --git a/configure b/configure index 6df06c8bd1..7b86f31b11 100755 --- a/configure +++ b/configure @@ -22,6 +22,7 @@ echo " --enable-faac enable faac support via libfaac [default=no]" echo " --enable-mingw32 enable mingw32 native/cross windows compile" echo " --enable-a52 enable GPL'ed A52 support [default=no]" echo " --enable-a52bin open liba52.so.0 at runtime [default=no]" +echo " --enable-dts enable GPL'ed DTS support [default=no]" echo " --enable-pp enable GPL'ed post processing support [default=no]" echo " --enable-shared-pp use libpostproc.so [default=no]" echo " --enable-shared build shared libraries [default=no]" @@ -143,6 +144,7 @@ faadbin="no" faac="no" a52="no" a52bin="no" +dts="no" pp="no" shared_pp="no" mingw32="no" @@ -381,6 +383,8 @@ for opt do ;; --enable-a52bin) a52bin="yes" ; extralibs="$ldl $extralibs" ;; + --enable-dts) dts="yes" ; extralibs="$extralibs -ldts" + ;; --enable-pp) pp="yes" ;; --enable-shared-pp) shared_pp="yes" @@ -444,6 +448,11 @@ if test "$gpl" != "yes"; then echo "liba52 is under GPL and --enable-gpl is not specified" fail="yes" fi + + if test "$dts" != "no"; then + echo "libdts is under GPL and --enable-gpl is not specified" + fail="yes" + fi if test "$faad" != "no" -o "$faadbin" != "no"; then cat > $TMPC << EOF @@ -973,6 +982,7 @@ echo "faadbin enabled $faadbin" echo "faac enabled $faac" echo "a52 support $a52" echo "a52 dlopened $a52bin" +echo "dts support $dts" echo "pp support $pp" echo "debug symbols $debug" echo "optimize $optimize" @@ -1169,6 +1179,12 @@ if test "$a52" = "yes" ; then fi fi +# DTS +if test "$dts" = "yes" ; then + echo "#define CONFIG_DTS 1" >> $TMPH + echo "CONFIG_DTS=yes" >> config.mak +fi + # PP if test "$pp" = "yes" ; then echo "#define CONFIG_PP 1" >> $TMPH diff --git a/ffmpeg.c b/ffmpeg.c index 08bd3e6608..903ad34b00 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -1502,8 +1502,9 @@ static int av_encode(AVFormatContext **output_files, ost->audio_resample = 0; } else { if (codec->channels != icodec->channels && - icodec->codec_id == CODEC_ID_AC3) { - /* Special case for 5:1 AC3 input */ + (icodec->codec_id == CODEC_ID_AC3 || + icodec->codec_id == CODEC_ID_DTS)) { + /* Special case for 5:1 AC3 and DTS input */ /* and mono or stereo output */ /* Request specific number of channels */ icodec->channels = codec->channels; @@ -3144,9 +3145,10 @@ static void opt_output_file(const char *filename) audio_enc->bit_rate = audio_bit_rate; audio_enc->strict_std_compliance = strict; audio_enc->thread_count = thread_count; - /* For audio codecs other than AC3 we limit */ + /* For audio codecs other than AC3 or DTS we limit */ /* the number of coded channels to stereo */ - if (audio_channels > 2 && codec_id != CODEC_ID_AC3) { + if (audio_channels > 2 && codec_id != CODEC_ID_AC3 + && codec_id != CODEC_ID_DTS) { audio_enc->channels = 2; } else audio_enc->channels = audio_channels; diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 278fc26116..cee949ed28 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -73,6 +73,11 @@ OBJS+= liba52/bit_allocate.o liba52/bitstream.o liba52/downmix.o \ endif endif +# currently using libdts for dts decoding +ifeq ($(CONFIG_DTS),yes) +OBJS+= dtsdec.o +endif + ifeq ($(CONFIG_FAAD),yes) OBJS+= faad.o ifeq ($(CONFIG_FAADBIN),yes) diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index f3b3533c1d..4454a86197 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -150,6 +150,9 @@ void avcodec_register_all(void) register_avcodec(&zlib_decoder); #ifdef CONFIG_AC3 register_avcodec(&ac3_decoder); +#endif +#ifdef CONFIG_DTS + register_avcodec(&dts_decoder); #endif register_avcodec(&ra_144_decoder); register_avcodec(&ra_288_decoder); diff --git a/libavcodec/avcodec.c b/libavcodec/avcodec.c index 4f687568b7..f9dd692bdb 100644 --- a/libavcodec/avcodec.c +++ b/libavcodec/avcodec.c @@ -38,6 +38,7 @@ static AVCodec* avcodec_find_by_fcc(uint32_t fcc) { CODEC_ID_MJPEG, { MKTAG('M', 'J', 'P', 'G'), 0 } }, { CODEC_ID_MPEG1VIDEO, { MKTAG('P', 'I', 'M', '1'), 0 } }, { CODEC_ID_AC3, { 0x2000, 0 } }, + { CODEC_ID_DTS, { 0x10, 0 } }, { CODEC_ID_MP2, { 0x50, 0x55, 0 } }, { CODEC_ID_FLV1, { MKTAG('F', 'L', 'V', '1'), 0 } }, diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 03269207ee..241d14d1dc 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -140,6 +140,8 @@ enum CodecID { CODEC_ID_MPEG2TS, /* _FAKE_ codec to indicate a raw MPEG2 transport stream (only used by libavformat) */ + + CODEC_ID_DTS, }; /* CODEC_ID_MP3LAME is absolete */ @@ -1858,6 +1860,7 @@ extern AVCodec rawvideo_decoder; /* the following codecs use external GPL libs */ extern AVCodec ac3_decoder; +extern AVCodec dts_decoder; /* resample.c */ diff --git a/libavcodec/dts_internal.h b/libavcodec/dts_internal.h new file mode 100644 index 0000000000..e834e96a89 --- /dev/null +++ b/libavcodec/dts_internal.h @@ -0,0 +1,203 @@ +/* + * dts_internal.h + * Copyright (C) 2004 Gildas Bazin + * Copyright (C) 2000-2003 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of dtsdec, a free DTS Coherent Acoustics stream decoder. + * See http://www.videolan.org/dtsdec.html for updates. + * + * dtsdec 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. + * + * dtsdec 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 + */ + +#define DTS_SUBFRAMES_MAX (16) +#define DTS_PRIM_CHANNELS_MAX (5) +#define DTS_SUBBANDS (32) +#define DTS_ABITS_MAX (32) /* Should be 28 */ +#define DTS_SUBSUBFAMES_MAX (4) +#define DTS_LFE_MAX (3) + +struct dts_state_s { + + /* Frame header */ + int frame_type; /* type of the current frame */ + int samples_deficit; /* deficit sample count */ + int crc_present; /* crc is present in the bitstream */ + int sample_blocks; /* number of PCM sample blocks */ + int frame_size; /* primary frame byte size */ + int amode; /* audio channels arrangement */ + int sample_rate; /* audio sampling rate */ + int bit_rate; /* transmission bit rate */ + + int downmix; /* embedded downmix enabled */ + int dynrange; /* embedded dynamic range flag */ + int timestamp; /* embedded time stamp flag */ + int aux_data; /* auxiliary data flag */ + int hdcd; /* source material is mastered in HDCD */ + int ext_descr; /* extension audio descriptor flag */ + int ext_coding; /* extended coding flag */ + int aspf; /* audio sync word insertion flag */ + int lfe; /* low frequency effects flag */ + int predictor_history; /* predictor history flag */ + int header_crc; /* header crc check bytes */ + int multirate_inter; /* multirate interpolator switch */ + int version; /* encoder software revision */ + int copy_history; /* copy history */ + int source_pcm_res; /* source pcm resolution */ + int front_sum; /* front sum/difference flag */ + int surround_sum; /* surround sum/difference flag */ + int dialog_norm; /* dialog normalisation parameter */ + + /* Primary audio coding header */ + int subframes; /* number of subframes */ + int prim_channels; /* number of primary audio channels */ + /* subband activity count */ + int subband_activity[DTS_PRIM_CHANNELS_MAX]; + /* high frequency vq start subband */ + int vq_start_subband[DTS_PRIM_CHANNELS_MAX]; + /* joint intensity coding index */ + int joint_intensity[DTS_PRIM_CHANNELS_MAX]; + /* transient mode code book */ + int transient_huffman[DTS_PRIM_CHANNELS_MAX]; + /* scale factor code book */ + int scalefactor_huffman[DTS_PRIM_CHANNELS_MAX]; + /* bit allocation quantizer select */ + int bitalloc_huffman[DTS_PRIM_CHANNELS_MAX]; + /* quantization index codebook select */ + int quant_index_huffman[DTS_PRIM_CHANNELS_MAX][DTS_ABITS_MAX]; + /* scale factor adjustment */ + float scalefactor_adj[DTS_PRIM_CHANNELS_MAX][DTS_ABITS_MAX]; + + /* Primary audio coding side information */ + int subsubframes; /* number of subsubframes */ + int partial_samples; /* partial subsubframe samples count */ + /* prediction mode (ADPCM used or not) */ + int prediction_mode[DTS_PRIM_CHANNELS_MAX][DTS_SUBBANDS]; + /* prediction VQ coefs */ + int prediction_vq[DTS_PRIM_CHANNELS_MAX][DTS_SUBBANDS]; + /* bit allocation index */ + int bitalloc[DTS_PRIM_CHANNELS_MAX][DTS_SUBBANDS]; + /* transition mode (transients) */ + int transition_mode[DTS_PRIM_CHANNELS_MAX][DTS_SUBBANDS]; + /* scale factors (2 if transient)*/ + int scale_factor[DTS_PRIM_CHANNELS_MAX][DTS_SUBBANDS][2]; + /* joint subband scale factors codebook */ + int joint_huff[DTS_PRIM_CHANNELS_MAX]; + /* joint subband scale factors */ + int joint_scale_factor[DTS_PRIM_CHANNELS_MAX][DTS_SUBBANDS]; + /* stereo downmix coefficients */ + int downmix_coef[DTS_PRIM_CHANNELS_MAX][2]; + /* dynamic range coefficient */ + int dynrange_coef; + + /* VQ encoded high frequency subbands */ + int high_freq_vq[DTS_PRIM_CHANNELS_MAX][DTS_SUBBANDS]; + + /* Low frequency effect data */ + double lfe_data[2*DTS_SUBSUBFAMES_MAX*DTS_LFE_MAX * 2 /*history*/]; + int lfe_scale_factor; + + /* Subband samples history (for ADPCM) */ + double subband_samples_hist[DTS_PRIM_CHANNELS_MAX][DTS_SUBBANDS][4]; + double subband_fir_hist[DTS_PRIM_CHANNELS_MAX][512]; + double subband_fir_noidea[DTS_PRIM_CHANNELS_MAX][64]; + + /* Audio output */ + level_t clev; /* centre channel mix level */ + level_t slev; /* surround channels mix level */ + + int output; /* type of output */ + level_t level; /* output level */ + sample_t bias; /* output bias */ + + sample_t * samples; /* pointer to the internal audio samples buffer */ + int downmixed; + + int dynrnge; /* apply dynamic range */ + level_t dynrng; /* dynamic range */ + void * dynrngdata; /* dynamic range callback funtion and data */ + level_t (* dynrngcall) (level_t range, void * dynrngdata); + + /* Bitstream handling */ + uint32_t * buffer_start; + uint32_t bits_left; + uint32_t current_word; + int word_mode; /* 16/14 bits word format (1 -> 16, 0 -> 14) */ + int bigendian_mode; /* endianness (1 -> be, 0 -> le) */ + + /* Current position in DTS frame */ + int current_subframe; + int current_subsubframe; + + /* Pre-calculated cosine modulation coefs for the QMF */ + double cos_mod[544]; + + /* Debug flag */ + int debug_flag; +}; + +#define LEVEL_PLUS6DB 2.0 +#define LEVEL_PLUS3DB 1.4142135623730951 +#define LEVEL_3DB 0.7071067811865476 +#define LEVEL_45DB 0.5946035575013605 +#define LEVEL_6DB 0.5 + +int dts_downmix_init (int input, int flags, level_t * level, + level_t clev, level_t slev); +int dts_downmix_coeff (level_t * coeff, int acmod, int output, level_t level, + level_t clev, level_t slev); +void dts_downmix (sample_t * samples, int acmod, int output, sample_t bias, + level_t clev, level_t slev); +void dts_upmix (sample_t * samples, int acmod, int output); + +#define ROUND(x) ((int)((x) + ((x) > 0 ? 0.5 : -0.5))) + +#ifndef LIBDTS_FIXED + +typedef sample_t quantizer_t; +#define SAMPLE(x) (x) +#define LEVEL(x) (x) +#define MUL(a,b) ((a) * (b)) +#define MUL_L(a,b) ((a) * (b)) +#define MUL_C(a,b) ((a) * (b)) +#define DIV(a,b) ((a) / (b)) +#define BIAS(x) ((x) + bias) + +#else /* LIBDTS_FIXED */ + +typedef int16_t quantizer_t; +#define SAMPLE(x) (sample_t)((x) * (1 << 30)) +#define LEVEL(x) (level_t)((x) * (1 << 26)) + +#if 0 +#define MUL(a,b) ((int)(((int64_t)(a) * (b) + (1 << 29)) >> 30)) +#define MUL_L(a,b) ((int)(((int64_t)(a) * (b) + (1 << 25)) >> 26)) +#elif 1 +#define MUL(a,b) \ +({ int32_t _ta=(a), _tb=(b), _tc; \ + _tc=(_ta & 0xffff)*(_tb >> 16)+(_ta >> 16)*(_tb & 0xffff); (int32_t)(((_tc >> 14))+ (((_ta >> 16)*(_tb >> 16)) << 2 )); }) +#define MUL_L(a,b) \ +({ int32_t _ta=(a), _tb=(b), _tc; \ + _tc=(_ta & 0xffff)*(_tb >> 16)+(_ta >> 16)*(_tb & 0xffff); (int32_t)((_tc >> 10) + (((_ta >> 16)*(_tb >> 16)) << 6)); }) +#else +#define MUL(a,b) (((a) >> 15) * ((b) >> 15)) +#define MUL_L(a,b) (((a) >> 13) * ((b) >> 13)) +#endif + +#define MUL_C(a,b) MUL_L (a, LEVEL (b)) +#define DIV(a,b) ((((int64_t)LEVEL (a)) << 26) / (b)) +#define BIAS(x) (x) + +#endif diff --git a/libavcodec/dtsdec.c b/libavcodec/dtsdec.c new file mode 100644 index 0000000000..d683a08e61 --- /dev/null +++ b/libavcodec/dtsdec.c @@ -0,0 +1,349 @@ +/* + * dtsdec.c : free DTS Coherent Acoustics stream decoder. + * Copyright (C) 2004 Benjamin Zores + * + * This file is part of libavcodec. + * + * 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 + */ + +#ifdef HAVE_AV_CONFIG_H +#undef HAVE_AV_CONFIG_H +#endif + +#include "avcodec.h" +#include +#include "dts_internal.h" + +#include +#include +#include +#include + +#define INBUF_SIZE 4096 +#define BUFFER_SIZE 4096 +#define HEADER_SIZE 14 + +#ifdef LIBDTS_FIXED +#define CONVERT_LEVEL (1 << 26) +#define CONVERT_BIAS 0 +#else +#define CONVERT_LEVEL 1 +#define CONVERT_BIAS 384 +#endif + +static void +pre_calc_cosmod (dts_state_t * state) +{ + int i, j, k; + + for (j=0,k=0;k<16;k++) + for (i=0;i<16;i++) + state->cos_mod[j++] = cos((2*i+1)*(2*k+1)*M_PI/64); + + for (k=0;k<16;k++) + for (i=0;i<16;i++) + state->cos_mod[j++] = cos((i)*(2*k+1)*M_PI/32); + + for (k=0;k<16;k++) + state->cos_mod[j++] = 0.25/(2*cos((2*k+1)*M_PI/128)); + + for (k=0;k<16;k++) + state->cos_mod[j++] = -0.25/(2.0*sin((2*k+1)*M_PI/128)); +} + +static inline +int16_t convert (int32_t i) +{ +#ifdef LIBDTS_FIXED + i >>= 15; +#else + i -= 0x43c00000; +#endif + return (i > 32767) ? 32767 : ((i < -32768) ? -32768 : i); +} + +void +convert2s16_2 (sample_t * _f, int16_t * s16) +{ + int i; + int32_t * f = (int32_t *) _f; + + for (i = 0; i < 256; i++) + { + s16[2*i] = convert (f[i]); + s16[2*i+1] = convert (f[i+256]); + } +} + +void +convert2s16_4 (sample_t * _f, int16_t * s16) +{ + int i; + int32_t * f = (int32_t *) _f; + + for (i = 0; i < 256; i++) + { + s16[4*i] = convert (f[i]); + s16[4*i+1] = convert (f[i+256]); + s16[4*i+2] = convert (f[i+512]); + s16[4*i+3] = convert (f[i+768]); + } +} + +void +convert2s16_5 (sample_t * _f, int16_t * s16) +{ + int i; + int32_t * f = (int32_t *) _f; + + for (i = 0; i < 256; i++) + { + s16[5*i] = convert (f[i]); + s16[5*i+1] = convert (f[i+256]); + s16[5*i+2] = convert (f[i+512]); + s16[5*i+3] = convert (f[i+768]); + s16[5*i+4] = convert (f[i+1024]); + } +} + +static void +convert2s16_multi (sample_t * _f, int16_t * s16, int flags) +{ + int i; + int32_t * f = (int32_t *) _f; + + switch (flags) + { + case DTS_MONO: + for (i = 0; i < 256; i++) + { + s16[5*i] = s16[5*i+1] = s16[5*i+2] = s16[5*i+3] = 0; + s16[5*i+4] = convert (f[i]); + } + break; + case DTS_CHANNEL: + case DTS_STEREO: + case DTS_DOLBY: + convert2s16_2 (_f, s16); + break; + case DTS_3F: + for (i = 0; i < 256; i++) + { + s16[5*i] = convert (f[i]); + s16[5*i+1] = convert (f[i+512]); + s16[5*i+2] = s16[5*i+3] = 0; + s16[5*i+4] = convert (f[i+256]); + } + break; + case DTS_2F2R: + convert2s16_4 (_f, s16); + break; + case DTS_3F2R: + convert2s16_5 (_f, s16); + break; + case DTS_MONO | DTS_LFE: + for (i = 0; i < 256; i++) + { + s16[6*i] = s16[6*i+1] = s16[6*i+2] = s16[6*i+3] = 0; + s16[6*i+4] = convert (f[i+256]); + s16[6*i+5] = convert (f[i]); + } + break; + case DTS_CHANNEL | DTS_LFE: + case DTS_STEREO | DTS_LFE: + case DTS_DOLBY | DTS_LFE: + for (i = 0; i < 256; i++) + { + s16[6*i] = convert (f[i+256]); + s16[6*i+1] = convert (f[i+512]); + s16[6*i+2] = s16[6*i+3] = s16[6*i+4] = 0; + s16[6*i+5] = convert (f[i]); + } + break; + case DTS_3F | DTS_LFE: + for (i = 0; i < 256; i++) + { + s16[6*i] = convert (f[i+256]); + s16[6*i+1] = convert (f[i+768]); + s16[6*i+2] = s16[6*i+3] = 0; + s16[6*i+4] = convert (f[i+512]); + s16[6*i+5] = convert (f[i]); + } + break; + case DTS_2F2R | DTS_LFE: + for (i = 0; i < 256; i++) + { + s16[6*i] = convert (f[i+256]); + s16[6*i+1] = convert (f[i+512]); + s16[6*i+2] = convert (f[i+768]); + s16[6*i+3] = convert (f[i+1024]); + s16[6*i+4] = 0; + s16[6*i+5] = convert (f[i]); + } + break; + case DTS_3F2R | DTS_LFE: + for (i = 0; i < 256; i++) + { + s16[6*i] = convert (f[i+256]); + s16[6*i+1] = convert (f[i+768]); + s16[6*i+2] = convert (f[i+1024]); + s16[6*i+3] = convert (f[i+1280]); + s16[6*i+4] = convert (f[i+512]); + s16[6*i+5] = convert (f[i]); + } + break; + } +} + +static int +channels_multi (int flags) +{ + if (flags & DTS_LFE) + return 6; + else if (flags & 1) /* center channel */ + return 5; + else if ((flags & DTS_CHANNEL_MASK) == DTS_2F2R) + return 4; + else + return 2; +} + +static int +dts_decode_frame (AVCodecContext *avctx, void *data, int *data_size, + uint8_t *buff, int buff_size) +{ + uint8_t * start = buff; + uint8_t * end = buff + buff_size; + *data_size = 0; + + static uint8_t buf[BUFFER_SIZE]; + static uint8_t * bufptr = buf; + static uint8_t * bufpos = buf + HEADER_SIZE; + + static int sample_rate; + static int frame_length; + static int flags; + int bit_rate; + int len; + dts_state_t *state = avctx->priv_data; + + while (1) + { + len = end - start; + if (!len) + break; + if (len > bufpos - bufptr) + len = bufpos - bufptr; + memcpy (bufptr, start, len); + bufptr += len; + start += len; + if (bufptr == bufpos) + { + if (bufpos == buf + HEADER_SIZE) + { + int length; + + length = dts_syncinfo (state, buf, &flags, &sample_rate, + &bit_rate, &frame_length); + if (!length) + { + av_log (NULL, AV_LOG_INFO, "skip\n"); + for (bufptr = buf; bufptr < buf + HEADER_SIZE-1; bufptr++) + bufptr[0] = bufptr[1]; + continue; + } + bufpos = buf + length; + } + else + { + level_t level; + sample_t bias; + int i; + + flags = 2; /* ???????????? */ + level = CONVERT_LEVEL; + bias = CONVERT_BIAS; + + flags |= DTS_ADJUST_LEVEL; + if (dts_frame (state, buf, &flags, &level, bias)) + goto error; + for (i = 0; i < dts_blocks_num (state); i++) + { + if (dts_block (state)) + goto error; + { + int chans; + chans = channels_multi (flags); + convert2s16_multi (dts_samples (state), data, + flags & (DTS_CHANNEL_MASK | DTS_LFE)); + + data += 256 * sizeof (int16_t) * chans; + *data_size += 256 * sizeof (int16_t) * chans; + } + } + bufptr = buf; + bufpos = buf + HEADER_SIZE; + continue; + error: + av_log (NULL, AV_LOG_ERROR, "error\n"); + bufptr = buf; + bufpos = buf + HEADER_SIZE; + } + } + } + + return buff_size; +} + +static int +dts_decode_init (AVCodecContext *avctx) +{ + dts_state_t * state; + int i; + + state = avctx->priv_data; + memset (state, 0, sizeof (dts_state_t)); + + state->samples = (sample_t *) memalign (16, 256 * 12 * sizeof (sample_t)); + if (state->samples == NULL) + return 1; + + for (i = 0; i < 256 * 12; i++) + state->samples[i] = 0; + + /* Pre-calculate cosine modulation coefficients */ + pre_calc_cosmod (state); + state->downmixed = 1; + + return 0; +} + +static int +dts_decode_end (AVCodecContext *s) +{ + return 0; +} + +AVCodec dts_decoder = { + "dts", + CODEC_TYPE_AUDIO, + CODEC_ID_DTS, + sizeof (dts_state_t), + dts_decode_init, + NULL, + dts_decode_end, + dts_decode_frame, +}; diff --git a/libavformat/matroska.c b/libavformat/matroska.c index edd5342816..9d80302f2c 100644 --- a/libavformat/matroska.c +++ b/libavformat/matroska.c @@ -2228,6 +2228,9 @@ matroska_read_header (AVFormatContext *s, else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_AUDIO_AC3)) codec_id = CODEC_ID_AC3; + else if (!strcmp(track->codec_id, + MATROSKA_CODEC_ID_AUDIO_DTS)) + codec_id = CODEC_ID_DTS; /* No such codec id so far. */ /* else if (!strcmp(track->codec_id, */ /* MATROSKA_CODEC_ID_AUDIO_DTS)) */ diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c index dd4e524111..adf871a669 100644 --- a/libavformat/mpeg.c +++ b/libavformat/mpeg.c @@ -77,6 +77,7 @@ typedef struct { #define AUDIO_ID 0xc0 #define VIDEO_ID 0xe0 #define AC3_ID 0x80 +#define DTS_ID 0x8a #define LPCM_ID 0xa0 static const int lpcm_freq_tab[4] = { 48000, 96000, 44100, 32000 }; @@ -235,7 +236,7 @@ static int get_system_header_size(AVFormatContext *ctx) static int mpeg_mux_init(AVFormatContext *ctx) { MpegMuxContext *s = ctx->priv_data; - int bitrate, i, mpa_id, mpv_id, ac3_id, lpcm_id, j; + int bitrate, i, mpa_id, mpv_id, ac3_id, dts_id, lpcm_id, j; AVStream *st; StreamInfo *stream; int audio_bitrate; @@ -258,6 +259,7 @@ static int mpeg_mux_init(AVFormatContext *ctx) s->video_bound = 0; mpa_id = AUDIO_ID; ac3_id = AC3_ID; + dts_id = DTS_ID; mpv_id = VIDEO_ID; lpcm_id = LPCM_ID; s->scr_stream_index = -1; @@ -272,6 +274,8 @@ static int mpeg_mux_init(AVFormatContext *ctx) case CODEC_TYPE_AUDIO: if (st->codec.codec_id == CODEC_ID_AC3) { stream->id = ac3_id++; + } else if (st->codec.codec_id == CODEC_ID_DTS) { + stream->id = dts_id++; } else if (st->codec.codec_id == CODEC_ID_PCM_S16BE) { stream->id = lpcm_id++; for(j = 0; j < 4; j++) { @@ -1304,9 +1308,12 @@ static int mpegps_read_packet(AVFormatContext *s, } else if (startcode >= 0x1c0 && startcode <= 0x1df) { type = CODEC_TYPE_AUDIO; codec_id = CODEC_ID_MP2; - } else if (startcode >= 0x80 && startcode <= 0x9f) { + } else if (startcode >= 0x80 && startcode <= 0x89) { type = CODEC_TYPE_AUDIO; codec_id = CODEC_ID_AC3; + } else if (startcode >= 0x8a && startcode <= 0x9f) { + type = CODEC_TYPE_AUDIO; + codec_id = CODEC_ID_DTS; } else if (startcode >= 0xa0 && startcode <= 0xbf) { type = CODEC_TYPE_AUDIO; codec_id = CODEC_ID_PCM_S16BE; diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index 7da6aed9e6..3dbd9478e2 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -431,6 +431,7 @@ static void pmt_cb(void *opaque, const uint8_t *section, int section_len) case STREAM_TYPE_VIDEO_H264: case STREAM_TYPE_AUDIO_AAC: case STREAM_TYPE_AUDIO_AC3: + case STREAM_TYPE_AUDIO_DTS: add_pes_stream(ts, pid, stream_type); break; default: @@ -753,6 +754,10 @@ static void mpegts_push_data(void *opaque, codec_type = CODEC_TYPE_AUDIO; codec_id = CODEC_ID_AC3; break; + case STREAM_TYPE_AUDIO_DTS: + codec_type = CODEC_TYPE_AUDIO; + codec_id = CODEC_ID_DTS; + break; default: if (code >= 0x1c0 && code <= 0x1df) { codec_type = CODEC_TYPE_AUDIO; diff --git a/libavformat/mpegts.h b/libavformat/mpegts.h index e0bfd4f004..5dfa7b20cc 100644 --- a/libavformat/mpegts.h +++ b/libavformat/mpegts.h @@ -42,6 +42,7 @@ #define STREAM_TYPE_VIDEO_H264 0x1b #define STREAM_TYPE_AUDIO_AC3 0x81 +#define STREAM_TYPE_AUDIO_DTS 0x8a unsigned int mpegts_crc32(const uint8_t *data, int len); extern AVOutputFormat mpegts_mux; diff --git a/libavformat/raw.c b/libavformat/raw.c index 9a79ac7b06..9c1bd929c9 100644 --- a/libavformat/raw.c +++ b/libavformat/raw.c @@ -184,6 +184,23 @@ static int ac3_read_header(AVFormatContext *s, return 0; } +/* dts read */ +static int dts_read_header(AVFormatContext *s, + AVFormatParameters *ap) +{ + AVStream *st; + + st = av_new_stream(s, 0); + if (!st) + return AVERROR_NOMEM; + + st->codec.codec_type = CODEC_TYPE_AUDIO; + st->codec.codec_id = CODEC_ID_DTS; + st->need_parsing = 1; + /* the parameters will be extracted from the compressed bitstream */ + return 0; +} + /* mpeg1/h263 input */ static int video_read_header(AVFormatContext *s, AVFormatParameters *ap) @@ -300,6 +317,17 @@ AVOutputFormat ac3_oformat = { }; #endif //CONFIG_ENCODERS +AVInputFormat dts_iformat = { + "dts", + "raw dts", + 0, + NULL, + dts_read_header, + raw_read_partial_packet, + raw_read_close, + .extensions = "dts", +}; + AVInputFormat h261_iformat = { "h261", "raw h261", @@ -613,6 +641,8 @@ int raw_init(void) av_register_input_format(&ac3_iformat); av_register_output_format(&ac3_oformat); + av_register_input_format(&dts_iformat); + av_register_input_format(&h261_iformat); av_register_input_format(&h263_iformat); diff --git a/libavformat/wav.c b/libavformat/wav.c index 474799a519..1030cb8809 100644 --- a/libavformat/wav.c +++ b/libavformat/wav.c @@ -348,6 +348,7 @@ static int wav_read_seek(AVFormatContext *s, case CODEC_ID_MP2: case CODEC_ID_MP3: case CODEC_ID_AC3: + case CODEC_ID_DTS: /* use generic seeking with dynamically generated indexes */ return -1; default: