diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 0645114772..75775a3693 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -1584,12 +1584,15 @@ typedef struct AVCodecContext { #define FF_PROFILE_DNXHR_HQX 4 #define FF_PROFILE_DNXHR_444 5 -#define FF_PROFILE_DTS 20 -#define FF_PROFILE_DTS_ES 30 -#define FF_PROFILE_DTS_96_24 40 -#define FF_PROFILE_DTS_HD_HRA 50 -#define FF_PROFILE_DTS_HD_MA 60 -#define FF_PROFILE_DTS_EXPRESS 70 +#define FF_PROFILE_DTS 20 +#define FF_PROFILE_DTS_ES 30 +#define FF_PROFILE_DTS_96_24 40 +#define FF_PROFILE_DTS_HD_HRA 50 +#define FF_PROFILE_DTS_HD_MA 60 +#define FF_PROFILE_DTS_EXPRESS 70 +#define FF_PROFILE_DTS_HD_MA_X 61 +#define FF_PROFILE_DTS_HD_MA_X_IMAX 62 + #define FF_PROFILE_EAC3_DDP_ATMOS 30 diff --git a/libavcodec/dca_syncwords.h b/libavcodec/dca_syncwords.h index 4d2cd5f56d..649bbd90dc 100644 --- a/libavcodec/dca_syncwords.h +++ b/libavcodec/dca_syncwords.h @@ -33,4 +33,7 @@ #define DCA_SYNCWORD_SUBSTREAM_CORE 0x02B09261U #define DCA_SYNCWORD_REV1AUX 0x9A1105A0U +#define DCA_SYNCWORD_XLL_X 0x02000850U +#define DCA_SYNCWORD_XLL_X_IMAX 0xF14000D0U + #endif /* AVCODEC_DCA_SYNCWORDS_H */ diff --git a/libavcodec/dca_xll.c b/libavcodec/dca_xll.c index fe2c766d98..b8cf37a35f 100644 --- a/libavcodec/dca_xll.c +++ b/libavcodec/dca_xll.c @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "avcodec.h" #include "libavutil/channel_layout.h" #include "dcadec.h" #include "dcadata.h" @@ -1054,6 +1055,22 @@ static int parse_frame(DCAXllDecoder *s, const uint8_t *data, int size, DCAExssA return ret; if ((ret = parse_band_data(s)) < 0) return ret; + + if (s->frame_size * 8 > FFALIGN(get_bits_count(&s->gb), 32)) { + unsigned int extradata_syncword; + + // Align to dword + skip_bits_long(&s->gb, -get_bits_count(&s->gb) & 31); + + extradata_syncword = show_bits_long(&s->gb, 32); + + if (extradata_syncword == DCA_SYNCWORD_XLL_X) { + s->x_syncword_present = 1; + } else if ((extradata_syncword >> 1) == (DCA_SYNCWORD_XLL_X_IMAX >> 1)) { + s->x_imax_syncword_present = 1; + } + } + if (ff_dca_seek_bits(&s->gb, s->frame_size * 8)) { av_log(s->avctx, AV_LOG_ERROR, "Read past end of XLL frame\n"); return AVERROR_INVALIDDATA; @@ -1428,8 +1445,15 @@ int ff_dca_xll_filter_frame(DCAXllDecoder *s, AVFrame *frame) return AVERROR(EINVAL); } + if (s->x_imax_syncword_present) { + avctx->profile = FF_PROFILE_DTS_HD_MA_X_IMAX; + } else if (s->x_syncword_present) { + avctx->profile = FF_PROFILE_DTS_HD_MA_X; + } else { + avctx->profile = FF_PROFILE_DTS_HD_MA; + } + avctx->bits_per_raw_sample = p->storage_bit_res; - avctx->profile = FF_PROFILE_DTS_HD_MA; avctx->bit_rate = 0; frame->nb_samples = nsamples = s->nframesamples << (s->nfreqbands - 1); diff --git a/libavcodec/dca_xll.h b/libavcodec/dca_xll.h index d7c1a13ec8..a22bbb8d77 100644 --- a/libavcodec/dca_xll.h +++ b/libavcodec/dca_xll.h @@ -135,6 +135,9 @@ typedef struct DCAXllDecoder { DCADSPContext *dcadsp; + int x_syncword_present; ///< Syncword for extension data at end of frame (DTS:X) is present + int x_imax_syncword_present; ///< Syncword for extension data at end of frame (DTS:X IMAX) is present + int output_mask; int32_t *output_samples[DCA_SPEAKER_COUNT]; } DCAXllDecoder; diff --git a/libavcodec/profiles.c b/libavcodec/profiles.c index ec5d646344..545626337c 100644 --- a/libavcodec/profiles.c +++ b/libavcodec/profiles.c @@ -36,12 +36,14 @@ const AVProfile ff_aac_profiles[] = { }; const AVProfile ff_dca_profiles[] = { - { FF_PROFILE_DTS, "DTS" }, - { FF_PROFILE_DTS_ES, "DTS-ES" }, - { FF_PROFILE_DTS_96_24, "DTS 96/24" }, - { FF_PROFILE_DTS_HD_HRA, "DTS-HD HRA" }, - { FF_PROFILE_DTS_HD_MA, "DTS-HD MA" }, - { FF_PROFILE_DTS_EXPRESS, "DTS Express" }, + { FF_PROFILE_DTS, "DTS" }, + { FF_PROFILE_DTS_ES, "DTS-ES" }, + { FF_PROFILE_DTS_96_24, "DTS 96/24" }, + { FF_PROFILE_DTS_HD_HRA, "DTS-HD HRA" }, + { FF_PROFILE_DTS_HD_MA, "DTS-HD MA" }, + { FF_PROFILE_DTS_HD_MA_X, "DTS-HD MA + DTS:X" }, + { FF_PROFILE_DTS_HD_MA_X_IMAX, "DTS-HD MA + DTS:X IMAX" }, + { FF_PROFILE_DTS_EXPRESS, "DTS Express" }, { FF_PROFILE_UNKNOWN }, };