From 7e06e0ede3b798f591634b277e8dfa6507b196de Mon Sep 17 00:00:00 2001 From: Anssi Hannula Date: Fri, 18 Feb 2011 19:49:44 +0000 Subject: [PATCH] dca: use EXT_AUDIO_ID field to determine core extensions This avoids the core substream extensions scan when the EXT_AUDIO_ID field indicates no extensions or only unsupported extensions. The scan is done only if the value of EXT_AUDIO_ID is unknown or indicates a present XCh extension which we can decode. Signed-off-by: Mans Rullgard --- libavcodec/dca.c | 69 ++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 20 deletions(-) diff --git a/libavcodec/dca.c b/libavcodec/dca.c index bdbe018..14b0b2d 100644 --- a/libavcodec/dca.c +++ b/libavcodec/dca.c @@ -99,6 +99,21 @@ enum DCAExtensionMask { DCA_EXT_EXSS_XLL = 0x200, ///< lossless extension in ExSS }; +/* -1 are reserved or unknown */ +static const int dca_ext_audio_descr_mask[] = { + DCA_EXT_XCH, + -1, + DCA_EXT_X96, + DCA_EXT_XCH | DCA_EXT_X96, + -1, + -1, + DCA_EXT_XXCH, + -1, +}; + +/* extensions that reside in core substream */ +#define DCA_CORE_EXTS (DCA_EXT_XCH | DCA_EXT_XXCH | DCA_EXT_X96) + /* Tables for mapping dts channel configurations to libavcodec multichannel api. * Some compromises have been made for special configurations. Most configurations * are never used so complete accuracy is not needed. @@ -327,14 +342,12 @@ typedef struct { int current_subframe; int current_subsubframe; + int core_ext_mask; ///< present extensions in the core substream + /* XCh extension information */ - int xch_present; + int xch_present; ///< XCh extension present and valid int xch_base_channel; ///< index of first (only) channel containing XCH data - /* Other detected extensions in the core substream */ - int xxch_present; - int x96_present; - /* ExSS header parser */ int static_fields; ///< static fields present int mix_metadata; ///< mixing metadata present @@ -1508,12 +1521,9 @@ static int dca_exss_parse_asset_header(DCAContext *s) if (!(extensions_mask & DCA_EXT_CORE)) av_log(s->avctx, AV_LOG_WARNING, "DTS core detection mismatch.\n"); - if (!!(extensions_mask & DCA_EXT_XCH) != s->xch_present) - av_log(s->avctx, AV_LOG_WARNING, "DTS XCh detection mismatch.\n"); - if (!!(extensions_mask & DCA_EXT_XXCH) != s->xxch_present) - av_log(s->avctx, AV_LOG_WARNING, "DTS XXCh detection mismatch.\n"); - if (!!(extensions_mask & DCA_EXT_X96) != s->x96_present) - av_log(s->avctx, AV_LOG_WARNING, "DTS X96 detection mismatch.\n"); + if ((extensions_mask & DCA_CORE_EXTS) != s->core_ext_mask) + av_log(s->avctx, AV_LOG_WARNING, "DTS extensions detection mismatch (%d, %d)\n", + extensions_mask & DCA_CORE_EXTS, s->core_ext_mask); return 0; } @@ -1623,8 +1633,6 @@ static int dca_decode_frame(AVCodecContext * avctx, s->xch_present = 0; - s->x96_present = 0; - s->xxch_present = 0; s->dca_buffer_size = dca_convert_bitstream(buf, buf_size, s->dca_buffer, DCA_MAX_FRAME_SIZE + DCA_MAX_EXSS_HEADER_SIZE); @@ -1652,11 +1660,24 @@ static int dca_decode_frame(AVCodecContext * avctx, /* record number of core channels incase less than max channels are requested */ num_core_channels = s->prim_channels; - /* extensions start at 32-bit boundaries into bitstream */ - skip_bits_long(&s->gb, (-get_bits_count(&s->gb)) & 31); + if (s->ext_coding) + s->core_ext_mask = dca_ext_audio_descr_mask[s->ext_descr]; + else + s->core_ext_mask = 0; core_ss_end = FFMIN(s->frame_size, s->dca_buffer_size) * 8; + /* only scan for extensions if ext_descr was unknown or indicated a + * supported XCh extension */ + if (s->core_ext_mask < 0 || s->core_ext_mask & DCA_EXT_XCH) { + + /* if ext_descr was unknown, clear s->core_ext_mask so that the + * extensions scan can fill it up */ + s->core_ext_mask = FFMAX(s->core_ext_mask, 0); + + /* extensions start at 32-bit boundaries into bitstream */ + skip_bits_long(&s->gb, (-get_bits_count(&s->gb)) & 31); + while(core_ss_end - get_bits_count(&s->gb) >= 32) { uint32_t bits = get_bits_long(&s->gb, 32); @@ -1675,7 +1696,7 @@ static int dca_decode_frame(AVCodecContext * avctx, /* skip length-to-end-of-frame field for the moment */ skip_bits(&s->gb, 10); - s->profile = FFMAX(s->profile, FF_PROFILE_DTS_ES); + s->core_ext_mask |= DCA_EXT_XCH; /* extension amode should == 1, number of channels in extension */ /* AFAIK XCh is not used for more channels */ @@ -1699,8 +1720,7 @@ static int dca_decode_frame(AVCodecContext * avctx, /* XXCh: extended channels */ /* usually found either in core or HD part in DTS-HD HRA streams, * but not in DTS-ES which contains XCh extensions instead */ - s->xxch_present = 1; - s->profile = FFMAX(s->profile, FF_PROFILE_DTS_ES); + s->core_ext_mask |= DCA_EXT_XXCH; break; case 0x1d95f262: { @@ -1713,8 +1733,7 @@ static int dca_decode_frame(AVCodecContext * avctx, av_log(avctx, AV_LOG_DEBUG, "FSIZE96 = %d bytes\n", fsize96); av_log(avctx, AV_LOG_DEBUG, "REVNO = %d\n", get_bits(&s->gb, 4)); - s->x96_present = 1; - s->profile = FFMAX(s->profile, FF_PROFILE_DTS_96_24); + s->core_ext_mask |= DCA_EXT_X96; break; } } @@ -1722,6 +1741,16 @@ static int dca_decode_frame(AVCodecContext * avctx, skip_bits_long(&s->gb, (-get_bits_count(&s->gb)) & 31); } + } else { + /* no supported extensions, skip the rest of the core substream */ + skip_bits_long(&s->gb, core_ss_end - get_bits_count(&s->gb)); + } + + if (s->core_ext_mask & DCA_EXT_X96) + s->profile = FF_PROFILE_DTS_96_24; + else if (s->core_ext_mask & (DCA_EXT_XCH | DCA_EXT_XXCH)) + s->profile = FF_PROFILE_DTS_ES; + /* check for ExSS (HD part) */ if (s->dca_buffer_size - s->frame_size > 32 && get_bits_long(&s->gb, 32) == DCA_HD_MARKER) -- 2.7.4