Merge commit '217e4ff4d1f845b76e44634e29371cd09313d1c2'
authorMichael Niedermayer <michaelni@gmx.at>
Sun, 15 Mar 2015 20:44:06 +0000 (21:44 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Sun, 15 Mar 2015 21:18:41 +0000 (22:18 +0100)
* commit '217e4ff4d1f845b76e44634e29371cd09313d1c2':
  dca: Support for XLL (lossless extension)

Conflicts:
Changelog
doc/general.texi
libavcodec/Makefile
libavcodec/dca.h
libavcodec/dca_exss.c
libavcodec/dcadata.h
libavcodec/dcadec.c
libavcodec/version.h

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
Changelog
doc/general.texi
libavcodec/Makefile
libavcodec/dca.h
libavcodec/dca_exss.c
libavcodec/dca_xll.c
libavcodec/dcadata.c
libavcodec/dcadata.h
libavcodec/dcadec.c
libavcodec/version.h

diff --cc Changelog
+++ b/Changelog
@@@ -2,37 -2,16 +2,38 @@@ Entries are sorted chronologically fro
  releases are sorted from youngest to oldest.
  
  version <next>:
 -- aliases and defaults for Ogg subtypes (opus, spx)
 -- HEVC/H.265 RTP payload format (draft v6) packetizer and depacketizer
 -- avplay now exits by default at the end of playback
 -- XCB-based screen-grabber
 -- creating DASH compatible fragmented MP4, MPEG-DASH segmenting muxer
 -- H.261 RTP payload format (RFC 4587) depacketizer and experimental packetizer
 +- FFT video filter
 +- TDSC decoder
++- DTS lossless extension (XLL) decoding (not lossless, disabled by default)
 +
 +
 +version 2.6:
 +- nvenc encoder
 +- 10bit spp filter
 +- colorlevels filter
 +- RIFX format for *.wav files
  - RTP/mpegts muxer
 -- VP8 in Ogg demuxing
 +- non continuous cache protocol support
 +- tblend filter
 +- cropdetect support for non 8bpp, absolute (if limit >= 1) and relative (if limit < 1.0) threshold
 +- Camellia symmetric block cipher
  - OpenH264 encoder wrapper
 +- VOC seeking support
 +- Closed caption Decoder
 +- fspp, uspp, pp7 MPlayer postprocessing filters ported to native filters
 +- showpalette filter
 +- Twofish symmetric block cipher
  - Support DNx100 (960x720@8)
 +- eq2 filter ported from libmpcodecs as eq filter
 +- removed libmpcodecs
 +- Changed default DNxHD colour range in QuickTime .mov derivatives to mpeg range
 +- ported softpulldown filter from libmpcodecs as repeatfields filter
 +- dcshift filter
 +- RTP depacketizer for loss tolerant payload format for MP3 audio (RFC 5219)
 +- RTP depacketizer for AC3 payload format (RFC 4184)
 +- palettegen and paletteuse filters
 +- VP9 RTP payload format (draft 0) experimental depacketizer
 +- RTP depacketizer for DV (RFC 6469)
  - DXVA2-accelerated HEVC decoding
  - AAC ELD 480 decoding
  - Intel QSV-accelerated H.264 decoding
@@@ -905,9 -827,10 +905,10 @@@ following image formats are supported
  @item Discworld II BMV Audio @tab     @tab  X
  @item COOK                   @tab     @tab  X
      @tab All versions except 5.1 are supported.
 -@item DCA (DTS Coherent Acoustics)  @tab     @tab  X
 +@item DCA (DTS Coherent Acoustics)  @tab  X  @tab  X
+     @tab supported extensions: XCh, XLL (partially)
  @item DPCM id RoQ            @tab  X  @tab  X
 -    @tab Used in Quake III, Jedi Knight 2, other computer games.
 +    @tab Used in Quake III, Jedi Knight 2 and other computer games.
  @item DPCM Interplay         @tab     @tab  X
      @tab Used in various Interplay computer games.
  @item DPCM Sierra Online     @tab     @tab  X
@@@ -193,10 -161,7 +193,10 @@@ OBJS-$(CONFIG_CSCD_DECODER)            
  OBJS-$(CONFIG_CYUV_DECODER)            += cyuv.o
  OBJS-$(CONFIG_DCA_DECODER)             += dcadec.o dca.o dcadsp.o      \
                                            dcadata.o dca_exss.o         \
-                                           synth_filter.o
+                                           dca_xll.o synth_filter.o
 +OBJS-$(CONFIG_DCA_ENCODER)             += dcaenc.o dca.o dcadata.o
 +OBJS-$(CONFIG_DIRAC_DECODER)           += diracdec.o dirac.o diracdsp.o \
 +                                          dirac_arith.o mpeg12data.o dirac_dwt.o
  OBJS-$(CONFIG_DFA_DECODER)             += dfa.o
  OBJS-$(CONFIG_DNXHD_DECODER)           += dnxhddec.o dnxhddata.o
  OBJS-$(CONFIG_DNXHD_ENCODER)           += dnxhdenc.o dnxhddata.o
  #define DCA_SUBFRAMES_MAX     (16)
  #define DCA_BLOCKS_MAX        (16)
  #define DCA_LFE_MAX            (3)
 +#define DCA_CHSETS_MAX         (4)
 +#define DCA_CHSET_CHANS_MAX    (8)
  
+ #define DCA_PRIM_CHANNELS_MAX  (7)
+ #define DCA_ABITS_MAX         (32)      /* Should be 28 */
+ #define DCA_SUBSUBFRAMES_MAX   (4)
+ #define DCA_SUBFRAMES_MAX     (16)
+ #define DCA_BLOCKS_MAX        (16)
+ #define DCA_LFE_MAX            (3)
+ #define DCA_XLL_FBANDS_MAX     (4)
+ #define DCA_XLL_SEGMENTS_MAX  (16)
+ #define DCA_XLL_CHSETS_MAX    (16)
+ #define DCA_XLL_CHANNELS_MAX  (16)
+ #define DCA_XLL_AORDER_MAX    (15)
+ /* Arbitrary limit; not sure what the maximum really is, but much larger. */
+ #define DCA_XLL_DMIX_NCOEFFS_MAX (18)
  #define DCA_MAX_FRAME_SIZE       16384
  #define DCA_MAX_EXSS_HEADER_SIZE  4096
  
@@@ -62,8 -75,63 +77,63 @@@ enum DCAExtensionMask 
      DCA_EXT_EXSS_XLL   = 0x200, ///< lossless extension in ExSS
  };
  
+ typedef struct XllChSetSubHeader {
+     int channels;               ///< number of channels in channel set, at most 16
+     int residual_encode;        ///< residual channel encoding
+     int bit_resolution;         ///< input sample bit-width
+     int bit_width;              ///< original input sample bit-width
+     int sampling_frequency;     ///< sampling frequency
+     int samp_freq_interp;       ///< sampling frequency interpolation multiplier
+     int replacement_set;        ///< replacement channel set group
+     int active_replace_set;     ///< current channel set is active channel set
+     int primary_ch_set;
+     int downmix_coeff_code_embedded;
+     int downmix_embedded;
+     int downmix_type;
+     int hier_chset;             ///< hierarchical channel set
+     int downmix_ncoeffs;
+     int downmix_coeffs[DCA_XLL_DMIX_NCOEFFS_MAX];
+     int ch_mask_enabled;
+     int ch_mask;
+     int mapping_coeffs_present;
+     int num_freq_bands;
+     /* m_nOrigChanOrder */
+     uint8_t orig_chan_order[DCA_XLL_FBANDS_MAX][DCA_XLL_CHANNELS_MAX];
+     uint8_t orig_chan_order_inv[DCA_XLL_FBANDS_MAX][DCA_XLL_CHANNELS_MAX];
+     /* Coefficients for channel pairs (at most 8), m_anPWChPairsCoeffs */
+     int8_t pw_ch_pairs_coeffs[DCA_XLL_FBANDS_MAX][DCA_XLL_CHANNELS_MAX/2];
+     /* m_nCurrHighestLPCOrder */
+     uint8_t adapt_order_max[DCA_XLL_FBANDS_MAX];
+     /* m_pnAdaptPredOrder */
+     uint8_t adapt_order[DCA_XLL_FBANDS_MAX][DCA_XLL_CHANNELS_MAX];
+     /* m_pnFixedPredOrder */
+     uint8_t fixed_order[DCA_XLL_FBANDS_MAX][DCA_XLL_CHANNELS_MAX];
+     /* m_pnLPCReflCoeffsQInd, unsigned version */
+     uint8_t lpc_refl_coeffs_q_ind[DCA_XLL_FBANDS_MAX]
+                                  [DCA_XLL_CHANNELS_MAX][DCA_XLL_AORDER_MAX];
+     int lsb_fsize[DCA_XLL_FBANDS_MAX];
+     int8_t scalable_lsbs[DCA_XLL_FBANDS_MAX][DCA_XLL_CHANNELS_MAX];
+     int8_t bit_width_adj_per_ch[DCA_XLL_FBANDS_MAX][DCA_XLL_CHANNELS_MAX];
+ } XllChSetSubHeader;
+ typedef struct XllNavi {
+     GetBitContext gb;  // Context for parsing the data segments
+     unsigned band_size[DCA_XLL_FBANDS_MAX];
+     unsigned segment_size[DCA_XLL_FBANDS_MAX][DCA_XLL_SEGMENTS_MAX];
+     unsigned chset_size[DCA_XLL_FBANDS_MAX][DCA_XLL_SEGMENTS_MAX][DCA_XLL_CHSETS_MAX];
+ } XllNavi;
+ typedef struct QMF64_table {
+     float dct4_coeff[32][32];
+     float dct2_coeff[32][32];
+     float rcos[32];
+     float rsin[32];
+ } QMF64_table;
  typedef struct DCAContext {
 -    AVClass *class;             ///< class for AVOptions
 +    const AVClass *class;       ///< class for AVOptions
      AVCodecContext *avctx;
      /* Frame header */
      int frame_type;             ///< type of the current frame
      int xch_base_channel;       ///< index of first (only) channel containing XCH data
      int xch_disable;            ///< whether the XCh extension should be decoded or not
  
 +    /* XXCH extension information */
 +    int xxch_chset;
 +    int xxch_nbits_spk_mask;
 +    uint32_t xxch_core_spkmask;
 +    uint32_t xxch_spk_masks[4]; /* speaker masks, last element is core mask */
 +    int xxch_chset_nch[4];
 +    float xxch_dmix_sf[DCA_CHSETS_MAX];
 +
 +    uint32_t xxch_dmix_embedded;  /* lower layer has mix pre-embedded, per chset */
 +    float xxch_dmix_coeff[DCA_PRIM_CHANNELS_MAX][32]; /* worst case sizing */
 +
 +    int8_t xxch_order_tab[32];
 +    int8_t lfe_index;
 +
+     /* XLL extension information */
+     int xll_disable;
+     int xll_nch_sets;           ///< number of channel sets per frame
+     int xll_channels;           ///< total number of channels (in all channel sets)
+     int xll_residual_channels;  ///< number of residual channels
+     int xll_segments;           ///< number of segments per frame
+     int xll_log_smpl_in_seg;    ///< supposedly this is "nBits4SamplLoci"
+     int xll_smpl_in_seg;        ///< samples in segment per one frequency band for the first channel set
+     int xll_bits4seg_size;      ///< number of bits used to read segment size
+     int xll_banddata_crc;       ///< presence of CRC16 within each frequency band
+     int xll_scalable_lsb;
+     int xll_bits4ch_mask;       ///< channel position mask
+     int xll_fixed_lsb_width;
+     XllChSetSubHeader xll_chsets[DCA_XLL_CHSETS_MAX];
+     XllNavi xll_navi;
+     int *xll_sample_buf;
+     unsigned int xll_sample_buf_size;
      /* ExSS header parser */
      int static_fields;          ///< static fields present
      int mix_metadata;           ///< mixing metadata present
      int mix_config_num_ch[4];   ///< number of channels in each mix out configuration
  
      int profile;
+     int one2one_map_chtospkr;
  
      int debug_flag;             ///< used for suppressing repeated error messages output
 -    AVFloatDSPContext fdsp;
 +    AVFloatDSPContext *fdsp;
      FFTContext imdct;
      SynthFilterContext synth;
      DCADSPContext dcadsp;
@@@ -198,12 -275,13 +291,16 @@@ extern av_export const uint32_t avpriv_
  /**
   * Convert bitstream to one representation based on sync marker
   */
 -int ff_dca_convert_bitstream(const uint8_t *src, int src_size, uint8_t *dst,
 +int avpriv_dca_convert_bitstream(const uint8_t *src, int src_size, uint8_t *dst,
                               int max_size);
  
 +int ff_dca_xbr_parse_frame(DCAContext *s);
 +int ff_dca_xxch_decode_frame(DCAContext *s);
 +
  void ff_dca_exss_parse_header(DCAContext *s);
  
+ int ff_dca_xll_decode_header(DCAContext *s);
+ int ff_dca_xll_decode_navi(DCAContext *s, int asset_end);
+ int ff_dca_xll_decode_audio(DCAContext *s, AVFrame *frame);
  #endif /* AVCODEC_DCA_H */
@@@ -314,41 -316,53 +316,58 @@@ void ff_dca_exss_parse_header(DCAContex
          }
      }
  
 +    av_assert0(num_assets > 0); // silence a warning
 +
      for (i = 0; i < num_assets; i++)
-         asset_size[i] = get_bits_long(&s->gb, 16 + 4 * blownup);
+         asset_size[i] = get_bits_long(&s->gb, 16 + 4 * blownup) + 1;
  
      for (i = 0; i < num_assets; i++) {
          if (dca_exss_parse_asset_header(s))
              return;
      }
  
-     /* not parsed further, we were only interested in the extensions mask
-      * from the asset header */
 -    if (num_assets > 0) {
          j = get_bits_count(&s->gb);
-         if (start_posn + hdrsize * 8 > j)
-             skip_bits_long(&s->gb, start_posn + hdrsize * 8 - j);
+         if (start_pos + hdrsize * 8 > j)
+             skip_bits_long(&s->gb, start_pos + hdrsize * 8 - j);
  
          for (i = 0; i < num_assets; i++) {
-             start_posn = get_bits_count(&s->gb);
-             mkr        = get_bits_long(&s->gb, 32);
+             int end_pos;
+             start_pos = get_bits_count(&s->gb);
+             end_pos   = start_pos + asset_size[i] * 8;
+             mkr       = get_bits_long(&s->gb, 32);
  
              /* parse extensions that we know about */
-             if (mkr == 0x655e315e) {
+             switch (mkr) {
++            case DCA_SYNCWORD_XBR:
 +                ff_dca_xbr_parse_frame(s);
-             } else if (mkr == 0x47004a03) {
++                break;
++            case DCA_SYNCWORD_XXCH:
 +                ff_dca_xxch_decode_frame(s);
 +                s->core_ext_mask |= DCA_EXT_XXCH; /* xxx use for chan reordering */
-             } else {
++                break;
+             case DCA_SYNCWORD_XLL:
+                 if (s->xll_disable) {
+                     av_log(s->avctx, AV_LOG_DEBUG,
+                            "DTS-XLL: ignoring XLL extension\n");
+                     break;
+                 }
+                 av_log(s->avctx, AV_LOG_DEBUG,
+                        "DTS-XLL: decoding XLL extension\n");
+                 if (ff_dca_xll_decode_header(s)        == 0 &&
+                     ff_dca_xll_decode_navi(s, end_pos) == 0)
+                     s->exss_ext_mask |= DCA_EXT_EXSS_XLL;
+                 break;
 -            case DCA_SYNCWORD_XBR:
 -            case DCA_SYNCWORD_XXCH:
+             default:
 -                av_log(s->avctx, AV_LOG_VERBOSE,
 -                       "DTS-ExSS: unknown marker = 0x%08"PRIx32"\n", mkr);
 +                av_log(s->avctx, AV_LOG_DEBUG,
 +                       "DTS-ExSS: unknown marker = 0x%08x\n", mkr);
              }
  
              /* skip to end of block */
              j = get_bits_count(&s->gb);
-             if (start_posn + asset_size[i] * 8 > j)
-                 skip_bits_long(&s->gb, start_posn + asset_size[i] * 8 - j);
+             if (j > end_pos)
+                 av_log(s->avctx, AV_LOG_ERROR,
+                        "DTS-ExSS: Processed asset too long.\n");
+             if (j < end_pos)
+                 skip_bits_long(&s->gb, end_pos - j);
          }
 -    }
  }
index 0000000,0c32d6e..036b713
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,747 +1,747 @@@
 - * This file is part of Libav.
+ /*
+  * DCA XLL extension
+  *
+  * Copyright (C) 2012 Paul B Mahol
+  * Copyright (C) 2014 Niels Möller
+  *
 - * Libav is free software; you can redistribute it and/or
++ * This file is part of FFmpeg.
+  *
 - * Libav is distributed in the hope that it will be useful,
++ * FFmpeg 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.1 of the License, or (at your option) any later version.
+  *
 - * License along with Libav; if not, write to the Free Software
++ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
+ #include "libavutil/attributes.h"
+ #include "libavutil/common.h"
+ #include "libavutil/internal.h"
+ #include "avcodec.h"
+ #include "dca.h"
+ #include "dcadata.h"
+ #include "get_bits.h"
+ #include "unary.h"
+ /* Sign as bit 0 */
+ static inline int get_bits_sm(GetBitContext *s, unsigned n)
+ {
+     int x = get_bits(s, n);
+     if (x & 1)
+         return -(x >> 1) - 1;
+     else
+         return x >> 1;
+ }
+ /* Return -1 on error. */
+ static int32_t get_dmix_coeff(DCAContext *s, int inverse)
+ {
+     unsigned code = get_bits(&s->gb, 9);
+     int32_t sign = (int32_t) (code >> 8) - 1;
+     unsigned idx = code & 0xff;
+     int inv_offset = FF_DCA_DMIXTABLE_SIZE -FF_DCA_INV_DMIXTABLE_SIZE;
+     if (idx >= FF_DCA_DMIXTABLE_SIZE) {
+         av_log(s->avctx, AV_LOG_ERROR,
+                "XLL: Invalid channel set downmix code %x\n", code);
+         return -1;
+     } else if (!inverse) {
+         return (ff_dca_dmixtable[idx] ^ sign) - sign;
+     } else if (idx < inv_offset) {
+         av_log(s->avctx, AV_LOG_ERROR,
+                "XLL: Invalid channel set inverse downmix code %x\n", code);
+         return -1;
+     } else {
+         return (ff_dca_inv_dmixtable[idx - inv_offset] ^ sign) - sign;
+     }
+ }
+ static int32_t dca_get_dmix_coeff(DCAContext *s)
+ {
+     return get_dmix_coeff(s, 0);
+ }
+ static int32_t dca_get_inv_dmix_coeff(DCAContext *s)
+ {
+     return get_dmix_coeff(s, 1);
+ }
+ /* parse XLL header */
+ int ff_dca_xll_decode_header(DCAContext *s)
+ {
+     int hdr_pos, hdr_size;
+     av_unused int version, frame_size;
+     int i, chset_index;
+     /* get bit position of sync header */
+     hdr_pos    = get_bits_count(&s->gb) - 32;
+     version    = get_bits(&s->gb, 4) + 1;
+     hdr_size   = get_bits(&s->gb, 8) + 1;
+     frame_size = get_bits_long(&s->gb, get_bits(&s->gb, 5) + 1) + 1;
+     s->xll_channels          =
+     s->xll_residual_channels = 0;
+     s->xll_nch_sets          = get_bits(&s->gb, 4) + 1;
+     s->xll_segments          = 1 << get_bits(&s->gb, 4);
+     s->xll_log_smpl_in_seg   = get_bits(&s->gb, 4);
+     s->xll_smpl_in_seg       = 1 << s->xll_log_smpl_in_seg;
+     s->xll_bits4seg_size     = get_bits(&s->gb, 5) + 1;
+     s->xll_banddata_crc      = get_bits(&s->gb, 2);
+     s->xll_scalable_lsb      = get_bits1(&s->gb);
+     s->xll_bits4ch_mask      = get_bits(&s->gb, 5) + 1;
+     if (s->xll_scalable_lsb) {
+         s->xll_fixed_lsb_width = get_bits(&s->gb, 4);
+         if (s->xll_fixed_lsb_width)
+             av_log(s->avctx, AV_LOG_WARNING,
+                    "XLL: fixed lsb width = %d, non-zero not supported.\n",
+                    s->xll_fixed_lsb_width);
+     }
+     /* skip to the end of the common header */
+     i = get_bits_count(&s->gb);
+     if (hdr_pos + hdr_size * 8 > i)
+         skip_bits_long(&s->gb, hdr_pos + hdr_size * 8 - i);
+     for (chset_index = 0; chset_index < s->xll_nch_sets; chset_index++) {
+         XllChSetSubHeader *chset = &s->xll_chsets[chset_index];
+         hdr_pos  = get_bits_count(&s->gb);
+         hdr_size = get_bits(&s->gb, 10) + 1;
+         chset->channels           = get_bits(&s->gb, 4) + 1;
+         chset->residual_encode    = get_bits(&s->gb, chset->channels);
+         chset->bit_resolution     = get_bits(&s->gb, 5) + 1;
+         chset->bit_width          = get_bits(&s->gb, 5) + 1;
+         chset->sampling_frequency = ff_dca_sampling_freqs[get_bits(&s->gb, 4)];
+         chset->samp_freq_interp   = get_bits(&s->gb, 2);
+         chset->replacement_set    = get_bits(&s->gb, 2);
+         if (chset->replacement_set)
+             chset->active_replace_set = get_bits(&s->gb, 1);
+         if (s->one2one_map_chtospkr) {
+             chset->primary_ch_set              = get_bits(&s->gb, 1);
+             chset->downmix_coeff_code_embedded = get_bits(&s->gb, 1);
+             if (chset->downmix_coeff_code_embedded) {
+                 chset->downmix_embedded = get_bits(&s->gb, 1);
+                 if (chset->primary_ch_set) {
+                     chset->downmix_type = get_bits(&s->gb, 3);
+                     if (chset->downmix_type > 6) {
+                         av_log(s->avctx, AV_LOG_ERROR,
+                                "XLL: Invalid channel set downmix type\n");
+                         return AVERROR_INVALIDDATA;
+                     }
+                 }
+             }
+             chset->hier_chset = get_bits(&s->gb, 1);
+             if (chset->downmix_coeff_code_embedded) {
+                 /* nDownmixCoeffs is specified as N * M. For a primary
+                  * channel set, it appears that N = number of
+                  * channels, and M is the number of downmix channels.
+                  *
+                  * For a non-primary channel set, N is specified as
+                  * number of channels + 1, and M is derived from the
+                  * channel set hierarchy, and at least in simple cases
+                  * M is the number of channels in preceding channel
+                  * sets. */
+                 if (chset->primary_ch_set) {
+                     static const char dmix_table[7] = { 1, 2, 2, 3, 3, 4, 4 };
+                     chset->downmix_ncoeffs = chset->channels * dmix_table[chset->downmix_type];
+                 } else
+                     chset->downmix_ncoeffs = (chset->channels + 1) * s->xll_channels;
+                 if (chset->downmix_ncoeffs > DCA_XLL_DMIX_NCOEFFS_MAX) {
+                     avpriv_request_sample(s->avctx,
+                                           "XLL: More than %d downmix coefficients",
+                                           DCA_XLL_DMIX_NCOEFFS_MAX);
+                     return AVERROR_PATCHWELCOME;
+                 } else if (chset->primary_ch_set) {
+                     for (i = 0; i < chset->downmix_ncoeffs; i++)
+                         if ((chset->downmix_coeffs[i] = dca_get_dmix_coeff(s)) == -1)
+                             return AVERROR_INVALIDDATA;
+                 } else {
+                     unsigned c, r;
+                     for (c = 0, i = 0; c < s->xll_channels; c++, i += chset->channels + 1) {
+                         if ((chset->downmix_coeffs[i] = dca_get_inv_dmix_coeff(s)) == -1)
+                             return AVERROR_INVALIDDATA;
+                         for (r = 1; r <= chset->channels; r++) {
+                             int32_t coeff = dca_get_dmix_coeff(s);
+                             if (coeff == -1)
+                                 return AVERROR_INVALIDDATA;
+                             chset->downmix_coeffs[i + r] =
+                                 (chset->downmix_coeffs[i] * (int64_t) coeff + (1 << 15)) >> 16;
+                         }
+                     }
+                 }
+             }
+             chset->ch_mask_enabled = get_bits(&s->gb, 1);
+             if (chset->ch_mask_enabled)
+                 chset->ch_mask = get_bits(&s->gb, s->xll_bits4ch_mask);
+             else
+                 /* Skip speaker configuration bits */
+                 skip_bits_long(&s->gb, 25 * chset->channels);
+         } else {
+             chset->primary_ch_set              = 1;
+             chset->downmix_coeff_code_embedded = 0;
+             /* Spec: NumChHierChSet = 0, NumDwnMixCodeCoeffs = 0, whatever that means. */
+             chset->mapping_coeffs_present = get_bits(&s->gb, 1);
+             if (chset->mapping_coeffs_present) {
+                 avpriv_report_missing_feature(s->avctx, "XLL: mapping coefficients");
+                 return AVERROR_PATCHWELCOME;
+             }
+         }
+         if (chset->sampling_frequency > 96000)
+             chset->num_freq_bands = 2 * (1 + get_bits(&s->gb, 1));
+         else
+             chset->num_freq_bands = 1;
+         if (chset->num_freq_bands > 1) {
+             avpriv_report_missing_feature(s->avctx, "XLL: num_freq_bands > 1");
+             return AVERROR_PATCHWELCOME;
+         }
+         if (get_bits(&s->gb, 1)) { /* pw_ch_decor_enabled */
+             int bits = av_ceil_log2(chset->channels);
+             for (i = 0; i < chset->channels; i++) {
+                 unsigned j = get_bits(&s->gb, bits);
+                 if (j >= chset->channels) {
+                     av_log(s->avctx, AV_LOG_ERROR,
+                            "Original channel order value %u too large, only %d channels.\n",
+                            j, chset->channels);
+                     return AVERROR_INVALIDDATA;
+                 }
+                 chset->orig_chan_order[0][i]     = j;
+                 chset->orig_chan_order_inv[0][j] = i;
+             }
+             for (i = 0; i < chset->channels / 2; i++) {
+                 if (get_bits(&s->gb, 1)) /* bChPFlag */
+                     chset->pw_ch_pairs_coeffs[0][i] = get_bits_sm(&s->gb, 7);
+                 else
+                     chset->pw_ch_pairs_coeffs[0][i] = 0;
+             }
+         } else {
+             for (i = 0; i < chset->channels; i++)
+                 chset->orig_chan_order[0][i]     =
+                 chset->orig_chan_order_inv[0][i] = i;
+             for (i = 0; i < chset->channels / 2; i++)
+                 chset->pw_ch_pairs_coeffs[0][i] = 0;
+         }
+         /* Adaptive prediction order */
+         chset->adapt_order_max[0] = 0;
+         for (i = 0; i < chset->channels; i++) {
+             chset->adapt_order[0][i] = get_bits(&s->gb, 4);
+             if (chset->adapt_order_max[0] < chset->adapt_order[0][i])
+                 chset->adapt_order_max[0] = chset->adapt_order[0][i];
+         }
+         /* Fixed prediction order, used in case the adaptive order
+          * above is zero */
+         for (i = 0; i < chset->channels; i++)
+             chset->fixed_order[0][i] =
+                 chset->adapt_order[0][i] ? 0 : get_bits(&s->gb, 2);
+         for (i = 0; i < chset->channels; i++) {
+             unsigned j;
+             for (j = 0; j < chset->adapt_order[0][i]; j++)
+                 chset->lpc_refl_coeffs_q_ind[0][i][j] = get_bits(&s->gb, 8);
+         }
+         if (s->xll_scalable_lsb) {
+             chset->lsb_fsize[0] = get_bits(&s->gb, s->xll_bits4seg_size);
+             for (i = 0; i < chset->channels; i++)
+                 chset->scalable_lsbs[0][i] = get_bits(&s->gb, 4);
+             for (i = 0; i < chset->channels; i++)
+                 chset->bit_width_adj_per_ch[0][i] = get_bits(&s->gb, 4);
+         } else {
+             memset(chset->scalable_lsbs[0], 0,
+                    chset->channels * sizeof(chset->scalable_lsbs[0][0]));
+             memset(chset->bit_width_adj_per_ch[0], 0,
+                    chset->channels * sizeof(chset->bit_width_adj_per_ch[0][0]));
+         }
+         s->xll_channels          += chset->channels;
+         s->xll_residual_channels += chset->channels -
+                                     av_popcount(chset->residual_encode);
+         /* FIXME: Parse header data for extra frequency bands. */
+         /* Skip to end of channel set sub header. */
+         i = get_bits_count(&s->gb);
+         if (hdr_pos + 8 * hdr_size < i) {
+             av_log(s->avctx, AV_LOG_ERROR,
+                    "chset header too large, %d bits, should be <= %d bits\n",
+                    i - hdr_pos, 8 * hdr_size);
+             return AVERROR_INVALIDDATA;
+         }
+         if (hdr_pos + 8 * hdr_size > i)
+             skip_bits_long(&s->gb, hdr_pos + 8 * hdr_size - i);
+     }
+     return 0;
+ }
+ /* parse XLL navigation table */
+ int ff_dca_xll_decode_navi(DCAContext *s, int asset_end)
+ {
+     int nbands, band, chset, seg, data_start;
+     /* FIXME: Supports only a single frequency band */
+     nbands = 1;
+     for (band = 0; band < nbands; band++) {
+         s->xll_navi.band_size[band] = 0;
+         for (seg = 0; seg < s->xll_segments; seg++) {
+             /* Note: The spec, ETSI TS 102 114 V1.4.1 (2012-09), says
+              * we should read a base value for segment_size from the
+              * stream, before reading the sizes of the channel sets.
+              * But that's apparently incorrect. */
+             s->xll_navi.segment_size[band][seg] = 0;
+             for (chset = 0; chset < s->xll_nch_sets; chset++)
+                 if (band < s->xll_chsets[chset].num_freq_bands) {
+                     s->xll_navi.chset_size[band][seg][chset] =
+                         get_bits(&s->gb, s->xll_bits4seg_size) + 1;
+                     s->xll_navi.segment_size[band][seg] +=
+                         s->xll_navi.chset_size[band][seg][chset];
+                 }
+             s->xll_navi.band_size[band] += s->xll_navi.segment_size[band][seg];
+         }
+     }
+     /* Align to 8 bits and skip 16-bit CRC. */
+     skip_bits_long(&s->gb, 16 + ((-get_bits_count(&s->gb)) & 7));
+     data_start = get_bits_count(&s->gb);
+     if (data_start + 8 * s->xll_navi.band_size[0] > asset_end) {
+         av_log(s->avctx, AV_LOG_ERROR,
+                "XLL: Data in NAVI table exceeds containing asset\n"
+                "start: %d (bit), size %u (bytes), end %d (bit), error %u\n",
+                data_start, s->xll_navi.band_size[0], asset_end,
+                data_start + 8 * s->xll_navi.band_size[0] - asset_end);
+         return AVERROR_INVALIDDATA;
+     }
+     init_get_bits(&s->xll_navi.gb, s->gb.buffer + data_start / 8,
+                   8 * s->xll_navi.band_size[0]);
+     return 0;
+ }
+ static void dca_xll_inv_adapt_pred(int *samples, int nsamples, unsigned order,
+                                    const int *prev, const uint8_t *q_ind)
+ {
+     static const uint16_t table[0x81] = {
+             0,  3070,  5110,  7140,  9156, 11154, 13132, 15085,
+         17010, 18904, 20764, 22588, 24373, 26117, 27818, 29474,
+         31085, 32648, 34164, 35631, 37049, 38418, 39738, 41008,
+         42230, 43404, 44530, 45609, 46642, 47630, 48575, 49477,
+         50337, 51157, 51937, 52681, 53387, 54059, 54697, 55302,
+         55876, 56421, 56937, 57426, 57888, 58326, 58741, 59132,
+         59502, 59852, 60182, 60494, 60789, 61066, 61328, 61576,
+         61809, 62029, 62236, 62431, 62615, 62788, 62951, 63105,
+         63250, 63386, 63514, 63635, 63749, 63855, 63956, 64051,
+         64140, 64224, 64302, 64376, 64446, 64512, 64573, 64631,
+         64686, 64737, 64785, 64830, 64873, 64913, 64950, 64986,
+         65019, 65050, 65079, 65107, 65133, 65157, 65180, 65202,
+         65222, 65241, 65259, 65275, 65291, 65306, 65320, 65333,
+         65345, 65357, 65368, 65378, 65387, 65396, 65405, 65413,
+         65420, 65427, 65434, 65440, 65446, 65451, 65456, 65461,
+         65466, 65470, 65474, 65478, 65481, 65485, 65488, 65491,
+         65535, /* Final value is for the -128 corner case, see below. */
+     };
+     int c[DCA_XLL_AORDER_MAX];
+     int64_t s;
+     unsigned i, j;
+     for (i = 0; i < order; i++) {
+         if (q_ind[i] & 1)
+             /* The index value 0xff corresponds to a lookup of entry 0x80 in
+              * the table, and no value is provided in the specification. */
+             c[i] = -table[(q_ind[i] >> 1) + 1];
+         else
+             c[i] = table[q_ind[i] >> 1];
+     }
+     /* The description in the spec is a bit convoluted. We can convert
+      * the reflected values to direct values in place, using a
+      * sequence of reflections operating on two values. */
+     for (i = 1; i < order; i++) {
+         /* i = 1: scale c[0]
+          * i = 2: reflect c[0] <-> c[1]
+          * i = 3: scale c[1], reflect c[0] <-> c[2]
+          * i = 4: reflect c[0] <-> c[3] reflect c[1] <-> c[2]
+          * ... */
+         if (i & 1)
+             c[i / 2] += ((int64_t) c[i] * c[i / 2] + 0x8000) >> 16;
+         for (j = 0; j < i / 2; j++) {
+             int r0 = c[j];
+             int r1 = c[i - j - 1];
+             c[j]         += ((int64_t) c[i] * r1 + 0x8000) >> 16;
+             c[i - j - 1] += ((int64_t) c[i] * r0 + 0x8000) >> 16;
+         }
+     }
+     /* Apply predictor. */
+     /* NOTE: Processing samples in this order means that the
+      * predictor is applied to the newly reconstructed samples. */
+     if (prev) {
+         for (i = 0; i < order; i++) {
+             for (j = s = 0; j < i; j++)
+                 s += (int64_t) c[j] * samples[i - 1 - j];
+             for (; j < order; j++)
+                 s += (int64_t) c[j] * prev[DCA_XLL_AORDER_MAX + i - 1 - j];
+             samples[i] -= av_clip((s + 0x8000) >> 16, -0x1000000, 0xffffff);
+         }
+     }
+     for (i = order; i < nsamples; i++) {
+         for (j = s = 0; j < order; j++)
+             s += (int64_t) c[j] * samples[i - 1 - j];
+         /* NOTE: Equations seem to imply addition, while the
+          * pseudocode seems to use subtraction.*/
+         samples[i] -= av_clip((s + 0x8000) >> 16, -0x1000000, 0xffffff);
+     }
+ }
+ int ff_dca_xll_decode_audio(DCAContext *s, AVFrame *frame)
+ {
+     /* FIXME: Decodes only the first frequency band. */
+     int seg, chset_i;
+     /* Coding parameters for each channel set. */
+     struct coding_params {
+         int seg_type;
+         int rice_code_flag[16];
+         int pancAuxABIT[16];
+         int pancABIT0[16];  /* Not sure what this is */
+         int pancABIT[16];   /* Not sure what this is */
+         int nSamplPart0[16];
+     } param_state[16];
+     GetBitContext *gb = &s->xll_navi.gb;
+     int *history;
+     /* Layout: First the sample buffer for one segment per channel,
+      * followed by history buffers of DCA_XLL_AORDER_MAX samples for
+      * each channel. */
+     av_fast_malloc(&s->xll_sample_buf, &s->xll_sample_buf_size,
+                    (s->xll_smpl_in_seg + DCA_XLL_AORDER_MAX) *
+                    s->xll_channels * sizeof(*s->xll_sample_buf));
+     if (!s->xll_sample_buf)
+         return AVERROR(ENOMEM);
+     history = s->xll_sample_buf + s->xll_smpl_in_seg * s->xll_channels;
+     for (seg = 0; seg < s->xll_segments; seg++) {
+         unsigned in_channel;
+         for (chset_i = in_channel = 0; chset_i < s->xll_nch_sets; chset_i++) {
+             /* The spec isn't very explicit, but I think the NAVI sizes are in bytes. */
+             int end_pos = get_bits_count(gb) +
+                           8 * s->xll_navi.chset_size[0][seg][chset_i];
+             int i, j;
+             struct coding_params *params = &param_state[chset_i];
+             /* I think this flag means that we should keep seg_type and
+              * other parameters from the previous segment. */
+             int use_seg_state_code_param;
+             XllChSetSubHeader *chset = &s->xll_chsets[chset_i];
+             if (in_channel >= s->avctx->channels)
+                 /* FIXME: Could go directly to next segment */
+                 goto next_chset;
+             if (s->avctx->sample_rate != chset->sampling_frequency) {
+                 av_log(s->avctx, AV_LOG_WARNING,
+                        "XLL: unexpected chset sample rate %d, expected %d\n",
+                        chset->sampling_frequency, s->avctx->sample_rate);
+                 goto next_chset;
+             }
+             if (seg != 0)
+                 use_seg_state_code_param = get_bits(gb, 1);
+             else
+                 use_seg_state_code_param = 0;
+             if (!use_seg_state_code_param) {
+                 int num_param_sets, i;
+                 unsigned bits4ABIT;
+                 params->seg_type = get_bits(gb, 1);
+                 num_param_sets   = params->seg_type ? 1 : chset->channels;
+                 if (chset->bit_width > 16) {
+                     bits4ABIT = 5;
+                 } else {
+                     if (chset->bit_width > 8)
+                         bits4ABIT = 4;
+                     else
+                         bits4ABIT = 3;
+                     if (s->xll_nch_sets > 1)
+                         bits4ABIT++;
+                 }
+                 for (i = 0; i < num_param_sets; i++) {
+                     params->rice_code_flag[i] = get_bits(gb, 1);
+                     if (!params->seg_type && params->rice_code_flag[i] && get_bits(gb, 1))
+                         params->pancAuxABIT[i] = get_bits(gb, bits4ABIT) + 1;
+                     else
+                         params->pancAuxABIT[i] = 0;
+                 }
+                 for (i = 0; i < num_param_sets; i++) {
+                     if (!seg) {
+                         /* Parameters for part 1 */
+                         params->pancABIT0[i] = get_bits(gb, bits4ABIT);
+                         if (params->rice_code_flag[i] == 0 && params->pancABIT0[i] > 0)
+                             /* For linear code */
+                             params->pancABIT0[i]++;
+                         /* NOTE: In the spec, not indexed by band??? */
+                         if (params->seg_type == 0)
+                             params->nSamplPart0[i] = chset->adapt_order[0][i];
+                         else
+                             params->nSamplPart0[i] = chset->adapt_order_max[0];
+                     } else
+                         params->nSamplPart0[i] = 0;
+                     /* Parameters for part 2 */
+                     params->pancABIT[i] = get_bits(gb, bits4ABIT);
+                     if (params->rice_code_flag[i] == 0 && params->pancABIT[i] > 0)
+                         /* For linear code */
+                         params->pancABIT[i]++;
+                 }
+             }
+             for (i = 0; i < chset->channels; i++) {
+                 int param_index = params->seg_type ? 0 : i;
+                 int bits        = params->pancABIT0[param_index];
+                 int part0       = params->nSamplPart0[param_index];
+                 int *sample_buf = s->xll_sample_buf +
+                                   (in_channel + i) * s->xll_smpl_in_seg;
+                 if (!params->rice_code_flag[param_index]) {
+                     /* Linear code */
+                     if (bits)
+                         for (j = 0; j < part0; j++)
+                             sample_buf[j] = get_bits_sm(gb, bits);
+                     else
+                         memset(sample_buf, 0, part0 * sizeof(sample_buf[0]));
+                     /* Second part */
+                     bits = params->pancABIT[param_index];
+                     if (bits)
+                         for (j = part0; j < s->xll_smpl_in_seg; j++)
+                             sample_buf[j] = get_bits_sm(gb, bits);
+                     else
+                         memset(sample_buf + part0, 0,
+                                (s->xll_smpl_in_seg - part0) * sizeof(sample_buf[0]));
+                 } else {
+                     int aux_bits = params->pancAuxABIT[param_index];
+                     for (j = 0; j < part0; j++) {
+                         /* FIXME: Is this identical to Golomb code? */
+                         int t = get_unary(gb, 1, 33) << bits;
+                         /* FIXME: Could move this test outside of the loop, for efficiency. */
+                         if (bits)
+                             t |= get_bits(gb, bits);
+                         sample_buf[j] = (t & 1) ? -(t >> 1) - 1 : (t >> 1);
+                     }
+                     /* Second part */
+                     bits = params->pancABIT[param_index];
+                     /* Follow the spec's suggestion of using the
+                      * buffer also to store the hybrid-rice flags. */
+                     memset(sample_buf + part0, 0,
+                            (s->xll_smpl_in_seg - part0) * sizeof(sample_buf[0]));
+                     if (aux_bits > 0) {
+                         /* For hybrid rice encoding, some samples are linearly
+                          * coded. According to the spec, "nBits4SamplLoci" bits
+                          * are used for each index, but this value is not
+                          * defined. I guess we should use log2(xll_smpl_in_seg)
+                          * bits. */
+                         int count = get_bits(gb, s->xll_log_smpl_in_seg);
+                         av_log(s->avctx, AV_LOG_DEBUG, "aux count %d (bits %d)\n",
+                                count, s->xll_log_smpl_in_seg);
+                         for (j = 0; j < count; j++)
+                             sample_buf[get_bits(gb, s->xll_log_smpl_in_seg)] = 1;
+                     }
+                     for (j = part0; j < s->xll_smpl_in_seg; j++) {
+                         if (!sample_buf[j]) {
+                             int t = get_unary(gb, 1, 33);
+                             if (bits)
+                                 t = (t << bits) | get_bits(gb, bits);
+                             sample_buf[j] = (t & 1) ? -(t >> 1) - 1 : (t >> 1);
+                         } else
+                             sample_buf[j] = get_bits_sm(gb, aux_bits);
+                     }
+                 }
+             }
+             for (i = 0; i < chset->channels; i++) {
+                 unsigned adapt_order = chset->adapt_order[0][i];
+                 int *sample_buf = s->xll_sample_buf +
+                                   (in_channel + i) * s->xll_smpl_in_seg;
+                 int *prev = history + (in_channel + i) * DCA_XLL_AORDER_MAX;
+                 if (!adapt_order) {
+                     unsigned order;
+                     for (order = chset->fixed_order[0][i]; order > 0; order--) {
+                         unsigned j;
+                         for (j = 1; j < s->xll_smpl_in_seg; j++)
+                             sample_buf[j] += sample_buf[j - 1];
+                     }
+                 } else
+                     /* Inverse adaptive prediction, in place. */
+                     dca_xll_inv_adapt_pred(sample_buf, s->xll_smpl_in_seg,
+                                            adapt_order, seg ? prev : NULL,
+                                            chset->lpc_refl_coeffs_q_ind[0][i]);
+                 memcpy(prev, sample_buf + s->xll_smpl_in_seg - DCA_XLL_AORDER_MAX,
+                        DCA_XLL_AORDER_MAX * sizeof(*prev));
+             }
+             for (i = 1; i < chset->channels; i += 2) {
+                 int coeff = chset->pw_ch_pairs_coeffs[0][i / 2];
+                 if (coeff != 0) {
+                     int *sample_buf = s->xll_sample_buf +
+                                       (in_channel + i) * s->xll_smpl_in_seg;
+                     int *prev = sample_buf - s->xll_smpl_in_seg;
+                     unsigned j;
+                     for (j = 0; j < s->xll_smpl_in_seg; j++)
+                         /* Shift is unspecified, but should apparently be 3. */
+                         sample_buf[j] += ((int64_t) coeff * prev[j] + 4) >> 3;
+                 }
+             }
+             if (s->xll_scalable_lsb) {
+                 int lsb_start = end_pos - 8 * chset->lsb_fsize[0] -
+                                 8 * (s->xll_banddata_crc & 2);
+                 int done;
+                 i = get_bits_count(gb);
+                 if (i > lsb_start) {
+                     av_log(s->avctx, AV_LOG_ERROR,
+                            "chset data lsb exceeds NAVI size, end_pos %d, lsb_start %d, pos %d\n",
+                            end_pos, lsb_start, i);
+                     return AVERROR_INVALIDDATA;
+                 }
+                 if (i < lsb_start)
+                     skip_bits_long(gb, lsb_start - i);
+                 for (i = done = 0; i < chset->channels; i++) {
+                     int bits = chset->scalable_lsbs[0][i];
+                     if (bits > 0) {
+                         /* The channel reordering is conceptually done
+                          * before adding the lsb:s, so we need to do
+                          * the inverse permutation here. */
+                         unsigned pi = chset->orig_chan_order_inv[0][i];
+                         int *sample_buf = s->xll_sample_buf +
+                                           (in_channel + pi) * s->xll_smpl_in_seg;
+                         int adj = chset->bit_width_adj_per_ch[0][i];
+                         int msb_shift = bits;
+                         unsigned j;
+                         if (adj > 0)
+                             msb_shift += adj - 1;
+                         for (j = 0; j < s->xll_smpl_in_seg; j++)
+                             sample_buf[j] = (sample_buf[j] << msb_shift) +
+                                             (get_bits(gb, bits) << adj);
+                         done += bits * s->xll_smpl_in_seg;
+                     }
+                 }
+                 if (done > 8 * chset->lsb_fsize[0]) {
+                     av_log(s->avctx, AV_LOG_ERROR,
+                            "chset lsb exceeds lsb_size\n");
+                     return AVERROR_INVALIDDATA;
+                 }
+             }
+             /* Store output. */
+             for (i = 0; i < chset->channels; i++) {
+                 int *sample_buf = s->xll_sample_buf +
+                                   (in_channel + i) * s->xll_smpl_in_seg;
+                 int shift = 1 - chset->bit_resolution;
+                 int out_channel = chset->orig_chan_order[0][i];
+                 float *out;
+                 /* XLL uses the channel order C, L, R, and we want L,
+                  * R, C. FIXME: Generalize. */
+                 if (chset->ch_mask_enabled &&
+                     (chset->ch_mask & 7) == 7 && out_channel < 3)
+                     out_channel = out_channel ? out_channel - 1 : 2;
+                 out_channel += in_channel;
+                 if (out_channel >= s->avctx->channels)
+                     continue;
+                 out  = (float *) frame->extended_data[out_channel];
+                 out += seg * s->xll_smpl_in_seg;
+                 /* NOTE: A one bit means residual encoding is *not* used. */
+                 if ((chset->residual_encode >> i) & 1) {
+                     /* Replace channel samples.
+                      * FIXME: Most likely not the right thing to do. */
+                     for (j = 0; j < s->xll_smpl_in_seg; j++)
+                         out[j] = ldexpf(sample_buf[j], shift);
+                 } else {
+                     /* Add residual signal to core channel */
+                     for (j = 0; j < s->xll_smpl_in_seg; j++)
+                         out[j] += ldexpf(sample_buf[j], shift);
+                 }
+             }
+             if (chset->downmix_coeff_code_embedded &&
+                 !chset->primary_ch_set && chset->hier_chset) {
+                 /* Undo hierarchical downmix of earlier channels. */
+                 unsigned mix_channel;
+                 for (mix_channel = 0; mix_channel < in_channel; mix_channel++) {
+                     float *mix_buf;
+                     const int *col;
+                     float coeff;
+                     unsigned row;
+                     /* Similar channel reorder C, L, R vs L, R, C reorder. */
+                     if (chset->ch_mask_enabled &&
+                         (chset->ch_mask & 7) == 7 && mix_channel < 3)
+                         mix_buf = (float *) frame->extended_data[mix_channel ? mix_channel - 1 : 2];
+                     else
+                         mix_buf = (float *) frame->extended_data[mix_channel];
+                     mix_buf += seg * s->xll_smpl_in_seg;
+                     col = &chset->downmix_coeffs[mix_channel * (chset->channels + 1)];
+                     /* Scale */
+                     coeff = ldexpf(col[0], -16);
+                     for (j = 0; j < s->xll_smpl_in_seg; j++)
+                         mix_buf[j] *= coeff;
+                     for (row = 0;
+                          row < chset->channels && in_channel + row < s->avctx->channels;
+                          row++)
+                         if (col[row + 1]) {
+                             const float *new_channel =
+                                 (const float *) frame->extended_data[in_channel + row];
+                             new_channel += seg * s->xll_smpl_in_seg;
+                             coeff        = ldexpf(col[row + 1], -15);
+                             for (j = 0; j < s->xll_smpl_in_seg; j++)
+                                 mix_buf[j] -= coeff * new_channel[j];
+                         }
+                 }
+             }
+ next_chset:
+             in_channel += chset->channels;
+             /* Skip to next channel set using the NAVI info. */
+             i = get_bits_count(gb);
+             if (i > end_pos) {
+                 av_log(s->avctx, AV_LOG_ERROR,
+                        "chset data exceeds NAVI size\n");
+                 return AVERROR_INVALIDDATA;
+             }
+             if (i < end_pos)
+                 skip_bits_long(gb, end_pos - i);
+         }
+     }
+     return 0;
+ }
Simple merge
@@@ -52,11 -58,8 +58,13 @@@ extern const uint32_t ff_dca_inv_dmixta
  
  extern const float ff_dca_default_coeffs[10][6][2];
  
 +extern const uint32_t ff_dca_map_xxch_to_native[28];
 +extern const int ff_dca_ext_audio_descr_mask[8];
 +
 +extern const uint64_t ff_dca_core_channel_layout[16];
 +
+ extern const int32_t ff_dca_sampling_freqs[16];
  extern const int8_t ff_dca_lfe_index[16];
  
  extern const int8_t ff_dca_channel_reorder_lfe[16][9];
@@@ -4,10 -4,12 +4,12 @@@
   * Copyright (C) 2004 Benjamin Zores
   * Copyright (C) 2006 Benjamin Larsson
   * Copyright (C) 2007 Konstantin Shishkov
+  * Copyright (C) 2012 Paul B Mahol
+  * Copyright (C) 2014 Niels Möller
   *
 - * This file is part of Libav.
 + * This file is part of FFmpeg.
   *
 - * Libav is free software; you can redistribute it and/or
 + * FFmpeg 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.1 of the License, or (at your option) any later version.
@@@ -932,12 -962,24 +1030,24 @@@ static int dca_filter_channels(DCAConte
  
      /* Generate LFE samples for this subsubframe FIXME!!! */
      if (s->lfe) {
-         lfe_interpolation_fir(s, s->lfe, 2 * s->lfe,
 -        float *samples = s->samples_chanptr[ff_dca_lfe_index[s->amode]];
++        float *samples = s->samples_chanptr[s->lfe_index];
+         lfe_interpolation_fir(s,
                                s->lfe_data + 2 * s->lfe * (block_index + 4),
-                               s->samples_chanptr[s->lfe_index]);
-         /* Outputs 20bits pcm samples */
+                               samples);
+         if (upsample) {
+             unsigned i;
+             /* Should apply the filter in Table 6-11 when upsampling. For
+              * now, just duplicate. */
+             for (i = 511; i > 0; i--) {
+                 samples[2 * i]     =
+                 samples[2 * i + 1] = samples[i];
+             }
+             samples[1] = samples[0];
+         }
      }
  
+     /* FIXME: This downmixing is probably broken with upsample.
+      * Probably totally broken also with XLL in general. */
      /* Downmixing to Stereo */
      if (s->prim_channels + !!s->lfe > 2 &&
          s->avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) {
@@@ -1330,24 -1156,16 +1440,26 @@@ static int dca_decode_frame(AVCodecCont
      int lfe_samples;
      int num_core_channels = 0;
      int i, ret;
 -    float  **samples_flt;
 +    float **samples_flt;
 +    float *src_chan;
 +    float *dst_chan;
      DCAContext *s = avctx->priv_data;
 -    int channels, full_channels;
      int core_ss_end;
 +    int channels, full_channels;
 +    float scale;
 +    int achan;
 +    int chset;
 +    int mask;
 +    int lavc;
 +    int posn;
 +    int j, k;
 +    int endch;
+     int upsample = 0;
  
-     s->xch_present = 0;
+     s->exss_ext_mask = 0;
+     s->xch_present   = 0;
  
 -    s->dca_buffer_size = ff_dca_convert_bitstream(buf, buf_size, s->dca_buffer,
 +    s->dca_buffer_size = avpriv_dca_convert_bitstream(buf, buf_size, s->dca_buffer,
                                                    DCA_MAX_FRAME_SIZE + DCA_MAX_EXSS_HEADER_SIZE);
      if (s->dca_buffer_size == AVERROR_INVALIDDATA) {
          av_log(avctx, AV_LOG_ERROR, "Not a valid DCA frame\n");
  
  #if FF_API_REQUEST_CHANNELS
  FF_DISABLE_DEPRECATION_WARNINGS
 -        if (s->xch_present && !s->xch_disable &&
 -            (!avctx->request_channels ||
 -             avctx->request_channels > num_core_channels + !!s->lfe)) {
 +            if (s->xch_present && !s->xch_disable &&
 +                (!avctx->request_channels ||
 +                 avctx->request_channels > num_core_channels + !!s->lfe)) {
  FF_ENABLE_DEPRECATION_WARNINGS
  #else
 -        if (s->xch_present && !s->xch_disable) {
 +            if (s->xch_present && !s->xch_disable) {
  #endif
 -            avctx->channel_layout |= AV_CH_BACK_CENTER;
 -            if (s->lfe) {
 -                avctx->channel_layout |= AV_CH_LOW_FREQUENCY;
 -                s->channel_order_tab = ff_dca_channel_reorder_lfe_xch[s->amode];
 +                if (avctx->channel_layout & AV_CH_BACK_CENTER) {
 +                    avpriv_request_sample(avctx, "XCh with Back center channel");
 +                    return AVERROR_INVALIDDATA;
 +                }
 +                avctx->channel_layout |= AV_CH_BACK_CENTER;
 +                if (s->lfe) {
 +                    avctx->channel_layout |= AV_CH_LOW_FREQUENCY;
 +                    s->channel_order_tab = ff_dca_channel_reorder_lfe_xch[s->amode];
 +                } else {
 +                    s->channel_order_tab = ff_dca_channel_reorder_nolfe_xch[s->amode];
 +                }
 +                if (s->channel_order_tab[s->xch_base_channel] < 0)
 +                    return AVERROR_INVALIDDATA;
              } else {
 -                s->channel_order_tab = ff_dca_channel_reorder_nolfe_xch[s->amode];
 +                channels       = num_core_channels + !!s->lfe;
 +                s->xch_present = 0; /* disable further xch processing */
 +                if (s->lfe) {
 +                    avctx->channel_layout |= AV_CH_LOW_FREQUENCY;
 +                    s->channel_order_tab = ff_dca_channel_reorder_lfe[s->amode];
 +                } else
 +                    s->channel_order_tab = ff_dca_channel_reorder_nolfe[s->amode];
 +            }
 +
 +            if (channels > !!s->lfe &&
 +                s->channel_order_tab[channels - 1 - !!s->lfe] < 0)
 +                return AVERROR_INVALIDDATA;
 +
 +            if (av_get_channel_layout_nb_channels(avctx->channel_layout) != channels) {
 +                av_log(avctx, AV_LOG_ERROR, "Number of channels %d mismatches layout %d\n", channels, av_get_channel_layout_nb_channels(avctx->channel_layout));
 +                return AVERROR_INVALIDDATA;
              }
 +
 +            if (num_core_channels + !!s->lfe > 2 &&
 +                avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) {
 +                channels              = 2;
 +                s->output             = s->prim_channels == 2 ? s->amode : DCA_STEREO;
 +                avctx->channel_layout = AV_CH_LAYOUT_STEREO;
 +            }
 +            else if (avctx->request_channel_layout & AV_CH_LAYOUT_NATIVE) {
 +                static const int8_t dca_channel_order_native[9] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
 +                s->channel_order_tab = dca_channel_order_native;
 +            }
 +            s->lfe_index = ff_dca_lfe_index[s->amode];
          } else {
 -            channels       = num_core_channels + !!s->lfe;
 -            s->xch_present = 0; /* disable further xch processing */
 -            if (s->lfe) {
 -                avctx->channel_layout |= AV_CH_LOW_FREQUENCY;
 -                s->channel_order_tab = ff_dca_channel_reorder_lfe[s->amode];
 -            } else
 -                s->channel_order_tab = ff_dca_channel_reorder_nolfe[s->amode];
 +            av_log(avctx, AV_LOG_ERROR,
 +                   "Non standard configuration %d !\n", s->amode);
 +            return AVERROR_INVALIDDATA;
          }
  
 -        if (channels > !!s->lfe &&
 -            s->channel_order_tab[channels - 1 - !!s->lfe] < 0)
 -            return AVERROR_INVALIDDATA;
 +        s->xxch_dmix_embedded = 0;
 +    } else {
 +        /* we only get here if an XXCH channel set can be added to the mix */
 +        channel_mask = s->xxch_core_spkmask;
 +
 +        if (avctx->request_channels > 0
 +            && avctx->request_channels < s->prim_channels) {
 +            channels = num_core_channels + !!s->lfe;
 +            for (i = 0; i < s->xxch_chset && channels + s->xxch_chset_nch[i]
 +                                              <= avctx->request_channels; i++) {
 +                channels += s->xxch_chset_nch[i];
 +                channel_mask |= s->xxch_spk_masks[i];
 +            }
 +        } else {
 +            channels = s->prim_channels + !!s->lfe;
 +            for (i = 0; i < s->xxch_chset; i++) {
 +                channel_mask |= s->xxch_spk_masks[i];
 +            }
 +        }
  
 -        if (num_core_channels + !!s->lfe > 2 &&
 -            avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) {
 -            channels              = 2;
 -            s->output             = s->prim_channels == 2 ? s->amode : DCA_STEREO;
 -            avctx->channel_layout = AV_CH_LAYOUT_STEREO;
 +        /* Given the DTS spec'ed channel mask, generate an avcodec version */
 +        channel_layout = 0;
 +        for (i = 0; i < s->xxch_nbits_spk_mask; ++i) {
 +            if (channel_mask & (1 << i)) {
 +                channel_layout |= ff_dca_map_xxch_to_native[i];
 +            }
 +        }
  
 -            /* Stereo downmix coefficients
 -             *
 -             * The decoder can only downmix to 2-channel, so we need to ensure
 -             * embedded downmix coefficients are actually targeting 2-channel.
 -             */
 -            if (s->core_downmix && (s->core_downmix_amode == DCA_STEREO ||
 -                                    s->core_downmix_amode == DCA_STEREO_TOTAL)) {
 -                for (i = 0; i < num_core_channels + !!s->lfe; i++) {
 -                    /* Range checked earlier */
 -                    s->downmix_coef[i][0] = dca_dmix_code(s->core_downmix_codes[i][0]);
 -                    s->downmix_coef[i][1] = dca_dmix_code(s->core_downmix_codes[i][1]);
 -                }
 -                s->output = s->core_downmix_amode;
 -            } else {
 -                int am = s->amode & DCA_CHANNEL_MASK;
 -                if (am >= FF_ARRAY_ELEMS(ff_dca_default_coeffs)) {
 -                    av_log(s->avctx, AV_LOG_ERROR,
 -                           "Invalid channel mode %d\n", am);
 -                    return AVERROR_INVALIDDATA;
 -                }
 -                if (num_core_channels + !!s->lfe >
 -                    FF_ARRAY_ELEMS(ff_dca_default_coeffs[0])) {
 -                    avpriv_request_sample(s->avctx, "Downmixing %d channels",
 -                                          s->prim_channels + !!s->lfe);
 -                    return AVERROR_PATCHWELCOME;
 -                }
 -                for (i = 0; i < num_core_channels + !!s->lfe; i++) {
 -                    s->downmix_coef[i][0] = ff_dca_default_coeffs[am][i][0];
 -                    s->downmix_coef[i][1] = ff_dca_default_coeffs[am][i][1];
 +        /* make sure that we have managed to get equivalent dts/avcodec channel
 +         * masks in some sense -- unfortunately some channels could overlap */
 +        if (av_popcount(channel_mask) != av_popcount(channel_layout)) {
 +            av_log(avctx, AV_LOG_DEBUG,
 +                   "DTS-XXCH: Inconsistent avcodec/dts channel layouts\n");
 +            return AVERROR_INVALIDDATA;
 +        }
 +
 +        avctx->channel_layout = channel_layout;
 +
 +        if (!(avctx->request_channel_layout & AV_CH_LAYOUT_NATIVE)) {
 +            /* Estimate DTS --> avcodec ordering table */
 +            for (chset = -1, j = 0; chset < s->xxch_chset; ++chset) {
 +                mask = chset >= 0 ? s->xxch_spk_masks[chset]
 +                                  : s->xxch_core_spkmask;
 +                for (i = 0; i < s->xxch_nbits_spk_mask; i++) {
 +                    if (mask & ~(DCA_XXCH_LFE1 | DCA_XXCH_LFE2) & (1 << i)) {
 +                        lavc = ff_dca_map_xxch_to_native[i];
 +                        posn = av_popcount(channel_layout & (lavc - 1));
 +                        s->xxch_order_tab[j++] = posn;
 +                    }
                  }
 +
              }
 -            av_dlog(s->avctx, "Stereo downmix coeffs:\n");
 -            for (i = 0; i < num_core_channels + !!s->lfe; i++) {
 -                av_dlog(s->avctx, "L, input channel %d = %f\n", i,
 -                        s->downmix_coef[i][0]);
 -                av_dlog(s->avctx, "R, input channel %d = %f\n", i,
 -                        s->downmix_coef[i][1]);
 -            }
 -            av_dlog(s->avctx, "\n");
 +
 +            s->lfe_index = av_popcount(channel_layout & (AV_CH_LOW_FREQUENCY-1));
 +        } else { /* native ordering */
 +            for (i = 0; i < channels; i++)
 +                s->xxch_order_tab[i] = i;
 +
 +            s->lfe_index = channels - 1;
          }
 -    } else {
 -        av_log(avctx, AV_LOG_ERROR, "Non standard configuration %d !\n", s->amode);
 -        return AVERROR_INVALIDDATA;
 +
 +        s->channel_order_tab = s->xxch_order_tab;
      }
 -    avctx->channels = channels;
  
 -                avctx->channels += s->xll_channels - s->xll_residual_channels;
+     /* get output buffer */
+     frame->nb_samples = 256 * (s->sample_blocks / 8);
+     if (s->exss_ext_mask & DCA_EXT_EXSS_XLL) {
+         int xll_nb_samples = s->xll_segments * s->xll_smpl_in_seg;
+         /* Check for invalid/unsupported conditions first */
+         if (s->xll_residual_channels > channels) {
+             av_log(s->avctx, AV_LOG_WARNING,
+                    "DCA: too many residual channels (%d, core channels %d). Disabling XLL\n",
+                    s->xll_residual_channels, channels);
+             s->exss_ext_mask &= ~DCA_EXT_EXSS_XLL;
+         } else if (xll_nb_samples != frame->nb_samples &&
+                    2 * frame->nb_samples != xll_nb_samples) {
+             av_log(s->avctx, AV_LOG_WARNING,
+                    "DCA: unsupported upsampling (%d XLL samples, %d core samples). Disabling XLL\n",
+                    xll_nb_samples, frame->nb_samples);
+             s->exss_ext_mask &= ~DCA_EXT_EXSS_XLL;
+         } else {
+             if (2 * frame->nb_samples == xll_nb_samples) {
+                 av_log(s->avctx, AV_LOG_INFO,
+                        "XLL: upsampling core channels by a factor of 2\n");
+                 upsample = 1;
+                 frame->nb_samples = xll_nb_samples;
+                 // FIXME: Is it good enough to copy from the first channel set?
+                 avctx->sample_rate = s->xll_chsets[0].sampling_frequency;
+             }
+             /* If downmixing to stereo, don't decode additional channels.
+              * FIXME: Using the xch_disable flag for this doesn't seem right. */
+             if (!s->xch_disable)
-     /* get output buffer */
-     frame->nb_samples = 256 * (s->sample_blocks / 8);
++                channels += s->xll_channels - s->xll_residual_channels;
+         }
+     }
 +    if (avctx->channels != channels) {
 +        if (avctx->channels)
 +            av_log(avctx, AV_LOG_INFO, "Number of channels changed in DCA decoder (%d -> %d)\n", avctx->channels, channels);
 +        avctx->channels = channels;
 +    }
 +
 -     * channel masks to libav channel_layout mask. */
+     /* FIXME: This is an ugly hack, to just revert to the default
+      * layout if we have additional channels. Need to convert the XLL
 -    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
 -        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
++     * channel masks to ffmpeg channel_layout mask. */
+     if (av_get_channel_layout_nb_channels(avctx->channel_layout) != avctx->channels)
+         avctx->channel_layout = 0;
 +    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
          return ret;
 -    }
      samples_flt = (float **) frame->extended_data;
  
      /* allocate buffer for extra channels if downmixing */
@@@ -1831,7 -1541,8 +1985,9 @@@ static av_cold int dca_decode_end(AVCod
      DCAContext *s = avctx->priv_data;
      ff_mdct_end(&s->imdct);
      av_freep(&s->extra_channels_buffer);
 +    av_freep(&s->fdsp);
+     av_freep(&s->xll_sample_buf);
+     av_freep(&s->qmf64_table);
      return 0;
  }
  
@@@ -29,8 -29,8 +29,8 @@@
  #include "libavutil/version.h"
  
  #define LIBAVCODEC_VERSION_MAJOR 56
- #define LIBAVCODEC_VERSION_MINOR  27
 -#define LIBAVCODEC_VERSION_MINOR 19
 -#define LIBAVCODEC_VERSION_MICRO  0
++#define LIBAVCODEC_VERSION_MINOR  28
 +#define LIBAVCODEC_VERSION_MICRO 100
  
  #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
                                                 LIBAVCODEC_VERSION_MINOR, \