[FFmpeg-devel] [PATCH] dca: use EXT_AUDIO_ID field to determine core extensions

Kostya kostya.shishkov
Fri Feb 18 21:03:49 CET 2011


On Fri, Feb 18, 2011 at 09:49:44PM +0200, Anssi Hannula wrote:
> 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.
> ---
>  libavcodec/dca.c |   69 ++++++++++++++++++++++++++++++++++++++---------------
>  1 files changed, 49 insertions(+), 20 deletions(-)
> 
> diff --git a/libavcodec/dca.c b/libavcodec/dca.c
> index bdbe018..9888b56 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)
> -- 
> 1.7.3

looks reasonable



More information about the ffmpeg-devel mailing list