[FFmpeg-cvslog] dca: Support for XLL (lossless extension)

Niels Möller git at videolan.org
Sun Mar 15 22:40:18 CET 2015


ffmpeg | branch: master | Niels Möller <nisse at lysator.liu.se> | Tue Feb 11 11:45:27 2014 +0100| [217e4ff4d1f845b76e44634e29371cd09313d1c2] | committer: Diego Biurrun

dca: Support for XLL (lossless extension)

Cleanup and integration by Diego Biurrun.

Signed-off-by: Diego Biurrun <diego at biurrun.de>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=217e4ff4d1f845b76e44634e29371cd09313d1c2
---

 Changelog             |    1 +
 doc/general.texi      |    1 +
 libavcodec/Makefile   |    2 +-
 libavcodec/dca.h      |  101 ++++++-
 libavcodec/dca_exss.c |   57 +++-
 libavcodec/dca_xll.c  |  747 +++++++++++++++++++++++++++++++++++++++++++++++++
 libavcodec/dcadata.c  |  630 ++++++++++++++++++++++++++++++++++++++++-
 libavcodec/dcadata.h  |   10 +-
 libavcodec/dcadec.c   |  199 +++++++++++--
 libavcodec/version.h  |    2 +-
 10 files changed, 1718 insertions(+), 32 deletions(-)

diff --git a/Changelog b/Changelog
index 7dc4d7c..b9fd45b 100644
--- a/Changelog
+++ b/Changelog
@@ -23,6 +23,7 @@ version <next>:
 - RTP depacketization of T.140 text (RFC 4103)
 - VP9 RTP payload format (draft 0) experimental depacketizer
 - TDSC decoder
+- DTS lossless extension (XLL) decoding (not lossless, disabled by default)
 
 
 version 11:
diff --git a/doc/general.texi b/doc/general.texi
index 58ce1dc..3ea8e60 100644
--- a/doc/general.texi
+++ b/doc/general.texi
@@ -828,6 +828,7 @@ following image formats are supported:
 @item COOK                   @tab     @tab  X
     @tab All versions except 5.1 are supported.
 @item DCA (DTS Coherent Acoustics)  @tab     @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.
 @item DPCM Interplay         @tab     @tab  X
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index b132021..71ebdb8 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -161,7 +161,7 @@ OBJS-$(CONFIG_CSCD_DECODER)            += cscd.o
 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_DFA_DECODER)             += dfa.o
 OBJS-$(CONFIG_DNXHD_DECODER)           += dnxhddec.o dnxhddata.o
 OBJS-$(CONFIG_DNXHD_ENCODER)           += dnxhdenc.o dnxhddata.o
diff --git a/libavcodec/dca.h b/libavcodec/dca.h
index 54643c9..887eb37 100644
--- a/libavcodec/dca.h
+++ b/libavcodec/dca.h
@@ -42,6 +42,21 @@
 #define DCA_BLOCKS_MAX        (16)
 #define DCA_LFE_MAX            (3)
 
+#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
 
@@ -60,6 +75,61 @@ 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
     AVCodecContext *avctx;
@@ -132,8 +202,10 @@ typedef struct DCAContext {
 
     /* Subband samples history (for ADPCM) */
     DECLARE_ALIGNED(16, float, subband_samples_hist)[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][4];
-    DECLARE_ALIGNED(32, float, subband_fir_hist)[DCA_PRIM_CHANNELS_MAX][512];
-    DECLARE_ALIGNED(32, float, subband_fir_noidea)[DCA_PRIM_CHANNELS_MAX][32];
+    /* Half size is sufficient for core decoding, but for 96 kHz data
+     * we need QMF with 64 subbands and 1024 samples. */
+    DECLARE_ALIGNED(32, float, subband_fir_hist)[DCA_PRIM_CHANNELS_MAX][1024];
+    DECLARE_ALIGNED(32, float, subband_fir_noidea)[DCA_PRIM_CHANNELS_MAX][64];
     int hist_index[DCA_PRIM_CHANNELS_MAX];
     DECLARE_ALIGNED(32, float, raXin)[32];
 
@@ -155,12 +227,31 @@ typedef struct DCAContext {
     int current_subsubframe;
 
     int core_ext_mask;          ///< present extensions in the core substream
+    int exss_ext_mask;          ///< Non-core extensions
 
     /* XCh extension information */
     int xch_present;            ///< XCh extension present and valid
     int xch_base_channel;       ///< index of first (only) channel containing XCH data
     int xch_disable;            ///< whether the XCh extension should be decoded or not
 
+    /* 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
@@ -168,12 +259,14 @@ typedef struct DCAContext {
     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;
     FFTContext imdct;
     SynthFilterContext synth;
     DCADSPContext dcadsp;
+    QMF64_table *qmf64_table;
     FmtConvertContext fmt_conv;
 } DCAContext;
 
@@ -187,4 +280,8 @@ int ff_dca_convert_bitstream(const uint8_t *src, int src_size, uint8_t *dst,
 
 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 */
diff --git a/libavcodec/dca_exss.c b/libavcodec/dca_exss.c
index 0f022e4..2895e20 100644
--- a/libavcodec/dca_exss.c
+++ b/libavcodec/dca_exss.c
@@ -22,6 +22,7 @@
 #include "libavutil/log.h"
 
 #include "dca.h"
+#include "dca_syncwords.h"
 #include "get_bits.h"
 
 /* extensions that reside in core substream */
@@ -121,7 +122,8 @@ static int dca_exss_parse_asset_header(DCAContext *s)
         skip_bits(&s->gb, 4); // max sample rate code
         channels = get_bits(&s->gb, 8) + 1;
 
-        if (get_bits1(&s->gb)) { // 1-to-1 channels to speakers
+        s->one2one_map_chtospkr = get_bits1(&s->gb);
+        if (s->one2one_map_chtospkr) {
             int spkr_remap_sets;
             int spkr_mask_size = 16;
             int num_spkrs[7];
@@ -242,21 +244,27 @@ static int dca_exss_parse_asset_header(DCAContext *s)
  */
 void ff_dca_exss_parse_header(DCAContext *s)
 {
+    int asset_size[8];
     int ss_index;
     int blownup;
     int num_audiop = 1;
     int num_assets = 1;
     int active_ss_mask[8];
     int i, j;
+    int start_pos;
+    int hdrsize;
+    uint32_t mkr;
 
     if (get_bits_left(&s->gb) < 52)
         return;
 
+    start_pos = get_bits_count(&s->gb) - 32;
+
     skip_bits(&s->gb, 8); // user data
     ss_index = get_bits(&s->gb, 2);
 
     blownup = get_bits1(&s->gb);
-    skip_bits(&s->gb,  8 + 4 * blownup); // header_size
+    hdrsize = get_bits(&s->gb,  8 + 4 * blownup) + 1; // header_size
     skip_bits(&s->gb, 16 + 4 * blownup); // hd_size
 
     s->static_fields = get_bits1(&s->gb);
@@ -309,13 +317,52 @@ void ff_dca_exss_parse_header(DCAContext *s)
     }
 
     for (i = 0; i < num_assets; i++)
-        skip_bits_long(&s->gb, 16 + 4 * blownup);  // asset size
+        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_pos + hdrsize * 8 > j)
+            skip_bits_long(&s->gb, start_pos + hdrsize * 8 - j);
+
+        for (i = 0; i < num_assets; i++) {
+            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 */
+            switch (mkr) {
+            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);
+            }
+
+            /* skip to end of block */
+            j = get_bits_count(&s->gb);
+            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);
+        }
+    }
 }
diff --git a/libavcodec/dca_xll.c b/libavcodec/dca_xll.c
new file mode 100644
index 0000000..0c32d6e
--- /dev/null
+++ b/libavcodec/dca_xll.c
@@ -0,0 +1,747 @@
+/*
+ * DCA XLL extension
+ *
+ * Copyright (C) 2012 Paul B Mahol
+ * Copyright (C) 2014 Niels Möller
+ *
+ * This file is part of Libav.
+ *
+ * Libav 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.
+ *
+ * Libav 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 Libav; 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;
+}
diff --git a/libavcodec/dcadata.c b/libavcodec/dcadata.c
index 47fb9c5..1db1938 100644
--- a/libavcodec/dcadata.c
+++ b/libavcodec/dcadata.c
@@ -7522,6 +7522,600 @@ DECLARE_ALIGNED(16, const float, ff_dca_lfe_fir_128)[256] = {
 };
 #undef SCALE
 
+
+#define SCALE(c) ((float)(c) / (256.0f * 32768.0f * 8388608.0f))
+DECLARE_ALIGNED(16, const float, ff_dca_lfe_xll_fir_64)[256] = {
+    SCALE(   6103), SCALE(  52170), SCALE(-558064), SCALE(1592440),
+    SCALE(6290049), SCALE(1502534), SCALE(-546669), SCALE(  53047),
+    SCALE(   1930), SCALE(  51089), SCALE(-568920), SCALE(1683709),
+    SCALE(6286575), SCALE(1414057), SCALE(-534782), SCALE(  53729),
+    SCALE(   2228), SCALE(  49794), SCALE(-579194), SCALE(1776276),
+    SCALE(6279634), SCALE(1327070), SCALE(-522445), SCALE(  54228),
+    SCALE(   2552), SCALE(  48275), SCALE(-588839), SCALE(1870070),
+    SCALE(6269231), SCALE(1241632), SCALE(-509702), SCALE(  54550),
+    SCALE(   2904), SCALE(  46523), SCALE(-597808), SCALE(1965017),
+    SCALE(6255380), SCALE(1157798), SCALE(-496595), SCALE(  54708),
+    SCALE(   3287), SCALE(  44529), SCALE(-606054), SCALE(2061044),
+    SCALE(6238099), SCALE(1075621), SCALE(-483164), SCALE(  54710),
+    SCALE(   3704), SCALE(  42282), SCALE(-613529), SCALE(2158071),
+    SCALE(6217408), SCALE( 995149), SCALE(-469451), SCALE(  54566),
+    SCALE(   4152), SCALE(  39774), SCALE(-620186), SCALE(2256019),
+    SCALE(6193332), SCALE( 916430), SCALE(-455494), SCALE(  54285),
+    SCALE(   4631), SCALE(  36995), SCALE(-625976), SCALE(2354805),
+    SCALE(6165900), SCALE( 839507), SCALE(-441330), SCALE(  53876),
+    SCALE(   5139), SCALE(  33937), SCALE(-630850), SCALE(2454343),
+    SCALE(6135146), SCALE( 764419), SCALE(-426998), SCALE(  53348),
+    SCALE(   5682), SCALE(  30591), SCALE(-634759), SCALE(2554547),
+    SCALE(6101107), SCALE( 691203), SCALE(-412531), SCALE(  52711),
+    SCALE(   6264), SCALE(  26948), SCALE(-637655), SCALE(2655326),
+    SCALE(6063824), SCALE( 619894), SCALE(-397966), SCALE(  51972),
+    SCALE(   6886), SCALE(  23001), SCALE(-639488), SCALE(2756591),
+    SCALE(6023343), SCALE( 550521), SCALE(-383335), SCALE(  51140),
+    SCALE(   7531), SCALE(  18741), SCALE(-640210), SCALE(2858248),
+    SCALE(5979711), SCALE( 483113), SCALE(-368671), SCALE(  50224),
+    SCALE(   8230), SCALE(  14162), SCALE(-639772), SCALE(2960201),
+    SCALE(5932981), SCALE( 417692), SCALE(-354003), SCALE(  49231),
+    SCALE(   8959), SCALE(   9257), SCALE(-638125), SCALE(3062355),
+    SCALE(5883210), SCALE( 354281), SCALE(-339362), SCALE(  48168),
+    SCALE(   9727), SCALE(   4018), SCALE(-635222), SCALE(3164612),
+    SCALE(5830457), SCALE( 292897), SCALE(-324777), SCALE(  47044),
+    SCALE(  10535), SCALE(  -1558), SCALE(-631014), SCALE(3266872),
+    SCALE(5774785), SCALE( 233555), SCALE(-310273), SCALE(  45866),
+    SCALE(  11381), SCALE(  -7480), SCALE(-625455), SCALE(3369035),
+    SCALE(5716260), SCALE( 176267), SCALE(-295877), SCALE(  44640),
+    SCALE(  12267), SCALE( -13750), SCALE(-618499), SCALE(3471000),
+    SCALE(5654952), SCALE( 121042), SCALE(-281613), SCALE(  43373),
+    SCALE(  13190), SCALE( -20372), SCALE(-610098), SCALE(3572664),
+    SCALE(5590933), SCALE(  67886), SCALE(-267505), SCALE(  42072),
+    SCALE(  14152), SCALE( -27352), SCALE(-600209), SCALE(3673924),
+    SCALE(5524280), SCALE(  16800), SCALE(-253574), SCALE(  40743),
+    SCALE(  15153), SCALE( -34691), SCALE(-588788), SCALE(3774676),
+    SCALE(5455069), SCALE( -32214), SCALE(-239840), SCALE(  39391),
+    SCALE(  16192), SCALE( -42390), SCALE(-575791), SCALE(3874816),
+    SCALE(5383383), SCALE( -79159), SCALE(-226323), SCALE(  38022),
+    SCALE(  17267), SCALE( -50453), SCALE(-561178), SCALE(3974239),
+    SCALE(5309305), SCALE(-124041), SCALE(-213041), SCALE(  36642),
+    SCALE(  18377), SCALE( -58879), SCALE(-544906), SCALE(4072841),
+    SCALE(5232922), SCALE(-166869), SCALE(-200010), SCALE(  35256),
+    SCALE(  19525), SCALE( -67667), SCALE(-526937), SCALE(4170517),
+    SCALE(5154321), SCALE(-207653), SCALE(-187246), SCALE(  33866),
+    SCALE(  20704), SCALE( -76817), SCALE(-507233), SCALE(4267162),
+    SCALE(5073593), SCALE(-246406), SCALE(-174764), SCALE(  32480),
+    SCALE(  21915), SCALE( -86327), SCALE(-485757), SCALE(4362672),
+    SCALE(4990831), SCALE(-283146), SCALE(-162575), SCALE(  31101),
+    SCALE(  23157), SCALE( -96193), SCALE(-462476), SCALE(4456942),
+    SCALE(4906129), SCALE(-317890), SCALE(-150692), SCALE(  29732),
+    SCALE(  24426), SCALE(-106412), SCALE(-437356), SCALE(4549871),
+    SCALE(4819584), SCALE(-350658), SCALE(-139125), SCALE(  28376),
+    SCALE(  25721), SCALE(-116977), SCALE(-410365), SCALE(4641355),
+    SCALE(4731293), SCALE(-381475), SCALE(-127884), SCALE(  27038),
+};
+#undef SCALE
+
+DECLARE_ALIGNED(16, const float, ff_dca_fir_64bands)[1024] = {
+    /* Bank 0 */
+    -7.1279389866041690e-8, -7.0950903150874990e-8,
+    -7.9525034321375090e-8, -8.9326871281374790e-8,
+    -9.7483190494874640e-8, -1.0586659510721950e-7,
+    -1.1527363411865760e-7, -1.2523109645615350e-7,
+    -1.3555636137971380e-7, -1.4640931821191640e-7,
+    -1.5787424998123710e-7, -1.6994592926571220e-7,
+    -1.8264184311018150e-7, -1.9600594587757850e-7,
+    -2.1007899706006800e-7, -2.2489759047553620e-7,
+    -2.4050245877923400e-7, -2.5693874615777660e-7,
+    -2.7425370308549580e-7, -2.9249662541757600e-7,
+    -3.1171981968268900e-7, -3.3197864040473180e-7,
+    -3.5333134588843600e-7, -3.7583910465412180e-7,
+    -3.9956628121669190e-7, -4.2458045296159330e-7,
+    -4.5095249563698380e-7, -4.7875659112606760e-7,
+    -5.0807031294631050e-7, -5.3897464223335550e-7,
+    -5.7155423388793000e-7, -6.0589741192019800e-7,
+    -6.4209580087853050e-7, -6.8024432849991400e-7,
+    -7.2044165259013450e-7, -7.6279018172077200e-7,
+    -8.0739610368280600e-7, -8.5436937020293650e-7,
+    -9.0382333224895500e-7, -9.5587472540498280e-7,
+    -1.0106437128213760e-6, -1.0682538906146330e-6,
+    -1.1288323637155430e-6, -1.1925097184646100e-6,
+    -1.2594193438633260e-6, -1.3296974052300520e-6,
+    -1.4034829433780260e-6, -1.4809178634979940e-6,
+    -1.5621465913980060e-6, -1.6473160377545360e-6,
+    -1.7365751553971340e-6, -1.8300749104526120e-6,
+    -1.9279680902322050e-6, -2.0304092660990760e-6,
+    -2.1375541686662320e-6, -2.2495596253776460e-6,
+    -2.3665828120950560e-6, -2.4887811970856540e-6,
+    -2.6163120571644820e-6, -2.7493324266391140e-6,
+    -2.8879984579501380e-6, -3.0324653639203880e-6,
+    -3.1828867865974640e-6, -3.3394147240855820e-6,
+    -3.5021985520037540e-6, -3.6713849262294680e-6,
+    -3.8471166218015830e-6, -4.0295324657699800e-6,
+    -4.2187670209852250e-6, -4.4149505043312320e-6,
+    -4.6182073040543900e-6, -4.8286558658894680e-6,
+    -5.0464076705003400e-6, -5.2715671455405850e-6,
+    -5.5042307535458100e-6, -5.7444868785028750e-6,
+    -5.9924142424804800e-6, -6.2480817863072800e-6,
+    -6.5115476278604000e-6, -6.7828589565804950e-6,
+    -7.0620507545154100e-6, -7.3491456697144900e-6,
+    -7.6441525098592000e-6, -7.9470661364365490e-6,
+    -8.2578666429227760e-6, -8.5765192154768100e-6,
+    -8.9029718900122000e-6, -9.2371554195468400e-6,
+    -9.5789825988253100e-6, -9.9283481667264540e-6,
+    -1.0285127334608450e-5, -1.0649175634328590e-5,
+    -1.1020327046334650e-5, -1.1398393880881060e-5,
+    -1.1783166036693560e-5, -1.2174410889256530e-5,
+    -1.2571871574469220e-5, -1.2975266858030310e-5,
+    -1.3384289978242060e-5, -1.3798608540965960e-5,
+    -1.4217863365843780e-5, -1.4641668383496450e-5,
+    -1.5069609527679710e-5, -1.5501244597782600e-5,
+    -1.5936101341640500e-5, -1.6373677426466900e-5,
+    -1.6813441716539560e-5, -1.7254834143068570e-5,
+    -1.7697261563607500e-5, -1.8140097714618200e-5,
+    -1.8582686308483550e-5, -1.9024340970099240e-5,
+    -1.9464340744880170e-5, -1.9901930030141080e-5,
+    -2.0336321557464510e-5, -2.0766696417773940e-5,
+    -2.1192201630574280e-5, -2.1611950084231910e-5,
+    -2.2025021652894630e-5, -2.2430463239517170e-5,
+    -2.2827288605503470e-5, -2.3214478371918170e-5,
+    -2.3590980216497750e-5, -2.3955708939763280e-5,
+    -2.4307547722489910e-5, -2.4645348200903720e-5,
+    -2.4967930863542620e-5, -2.5274085082324960e-5,
+    /* Bank 1 */
+     2.5562569399199020e-5,  2.5832111724562040e-5,
+     2.6081413415833200e-5,  2.6309149390520640e-5,
+     2.6513966535124460e-5,  2.6694483850464800e-5,
+     2.6849297239997120e-5,  2.6976979753245170e-5,
+     2.7076082153012070e-5,  2.7145133103663890e-5,
+     2.7182642746157720e-5,  2.7187102980536760e-5,
+     2.7156990105794550e-5,  2.7090765064735940e-5,
+     2.6986876191054700e-5,  2.6843759539035120e-5,
+     2.6659843389908530e-5,  2.6433548592482960e-5,
+     2.6163291550639320e-5,  2.5847484577439320e-5,
+     2.5484540698002960e-5,  2.5072874052447260e-5,
+     2.4610903957661350e-5,  2.4097055300584120e-5,
+     2.3529763128539150e-5,  2.2907473117403740e-5,
+     2.2228647280994560e-5,  2.1491764461832140e-5,
+     2.0695325418576370e-5,  1.9837853265502040e-5,
+    /* NOTE: The spec has a duplicated row "160 | 1.7934037335534700e-5" ! */
+     1.8917898053528080e-5,  1.7934037335534700e-5,
+     1.6884884022311310e-5,  1.5769086921577900e-5,
+     1.4585334740507920e-5,  1.3332356590263080e-5,
+     1.2008929083235120e-5,  1.0613876973541650e-5,
+     9.1460801506922300e-6,  7.6044740757265500e-6,
+     5.9880523825897000e-6,  4.2958677847708840e-6,
+     2.5270494199802070e-6,  6.8080315386959900e-7,
+    -1.2435990827839660e-6, -3.2468187066945930e-6,
+    -5.3294268968052800e-6, -7.4919036559427900e-6,
+    -9.7346407524871100e-6, -1.2057941408635810e-5,
+    -1.4462010500550970e-5, -1.6946953848107710e-5,
+    -1.9512772389215240e-5, -2.2159361597292710e-5,
+    -2.4886504491416160e-5, -2.7693871041862060e-5,
+    -3.0581012081916960e-5, -3.3547358765259040e-5,
+    -3.6592216716540970e-5, -3.9714765485539260e-5,
+    -4.2914052387856640e-5, -4.6188991961724560e-5,
+    -4.9538360176954340e-5, -5.2960794000140600e-5,
+    -5.6454787620185350e-5, -6.0018691972791050e-5,
+    -6.3650708053788550e-5, -6.7348886525882700e-5,
+    -7.1111125753722860e-5, -7.4935171411178040e-5,
+    -7.8818609806320000e-5, -8.2758867628623800e-5,
+    -8.6753213062403400e-5, -9.0798755482139240e-5,
+    -9.4892437636254000e-5, -9.9031035415475500e-5,
+    -1.0321116057304920e-4, -1.0742926070674010e-4,
+    -1.1168161614264270e-4, -1.1596433966772030e-4,
+    -1.2027337376184880e-4, -1.2460449089034750e-4,
+    -1.2895330270761850e-4, -1.3331525983885840e-4,
+    -1.3768563787408340e-4, -1.4205953760578120e-4,
+    -1.4643190426323540e-4, -1.5079752791692290e-4,
+    -1.5515103314094370e-4, -1.5948687909058970e-4,
+    -1.6379937154642740e-4, -1.6808266356446820e-4,
+    -1.7233075773584680e-4, -1.7653750646560020e-4,
+    -1.8069661584612290e-4, -1.8480164638953740e-4,
+    -1.8884602526638050e-4, -1.9282304696531290e-4,
+    -1.9672587556804270e-4, -2.0054754547108610e-4,
+    -2.0428097498957360e-4, -2.0791896735659270e-4,
+    -2.1145421910491280e-4, -2.1487932080488700e-4,
+    -2.1818676491655660e-4, -2.2136894706917190e-4,
+    -2.2441818635854840e-4, -2.2732672676686290e-4,
+    -2.3008674810081220e-4, -2.3269036653525150e-4,
+    -2.3512963563507800e-4, -2.3739654799291240e-4,
+    -2.3948307023621970e-4, -2.4138114593372380e-4,
+    -2.4308272452941820e-4, -2.4457975717687980e-4,
+    -2.4586407616017000e-4, -2.4692741569938220e-4,
+    -2.4776199025177680e-4, -2.4836046092637280e-4,
+    -2.4871461830381660e-4, -2.4881540457247040e-4,
+    -2.4865471770248810e-4, -2.4822543333608940e-4,
+    -2.4752008219951220e-4, -2.4653081794176570e-4,
+    -2.4525003217524440e-4, -2.4367037437341020e-4,
+    /* Bank 2 */
+     2.4178457457919800e-4,  2.3958543985834340e-4,
+     2.3706595356421380e-4,  2.3421928008696620e-4,
+     2.3103877007019660e-4,  2.2751796132972940e-4,
+     2.2365059385031200e-4,  2.1943061159567880e-4,
+     2.1485218733324290e-4,  2.0990972538755550e-4,
+     2.0459789739171640e-4,  1.9891164424316180e-4,
+     1.9284618337957900e-4,  1.8639701070854740e-4,
+     1.7955993578371750e-4,  1.7233108395155490e-4,
+     1.6470690840351980e-4,  1.5668419239382670e-4,
+     1.4826008597798460e-4,  1.3943210818407590e-4,
+     1.3019815804235450e-4,  1.2055651618705740e-4,
+     1.1050586906665980e-4,  1.0004531116378850e-4,
+     8.9174369623037550e-5,  7.7893006105444910e-5,
+     6.6201632959158800e-5,  5.4101115008963200e-5,
+     4.1592792755171040e-5,  2.8678484003389880e-5,
+     1.5360496520469550e-5,  1.6416297019304470e-6,
+    -1.2474801400564880e-5, -2.6984964757674160e-5,
+    -4.1884506316022560e-5, -5.7168548169515050e-5,
+    -7.2831653374563650e-5, -8.8867825335203200e-5,
+    -1.0527052946041040e-4, -1.2203269185287530e-4,
+    -1.3914664880465400e-4, -1.5660414556657680e-4,
+    -1.7439635977956720e-4, -1.9251390142613000e-4,
+    -2.1094678833176480e-4, -2.2968444457655940e-4,
+    -2.4871569004884240e-4, -2.6802874127778880e-4,
+    -2.8761124019708440e-4, -3.0745025297166030e-4,
+    -3.2753221542219500e-4, -3.4784293347385130e-4,
+    -3.6836764760397900e-4, -3.8909103335715320e-4,
+    -4.0999714822829530e-4, -4.3106943097409840e-4,
+    -4.5229073958127750e-4, -4.7364335350426610e-4,
+    -4.9510898492628230e-4, -5.1666877822680600e-4,
+    -5.3830328700499900e-4, -5.5999247625413450e-4,
+    -5.8171579317559550e-4, -6.0345216810040500e-4,
+    -6.2517996394886800e-4, -6.4687697763330650e-4,
+    -6.6852052145861900e-4, -6.9008742526480550e-4,
+    -7.1155400216196750e-4, -7.3289605035434600e-4,
+    -7.5408892753413600e-4, -7.7510755325530950e-4,
+    -7.9592638676398950e-4, -8.1651942936660300e-4,
+    -8.3686029869896850e-4, -8.5692223230171550e-4,
+    -8.7667809201044900e-4, -8.9610036547340950e-4,
+    -9.1516119514986000e-4, -9.3383238324995840e-4,
+    -9.5208547141354700e-4, -9.6989174214394400e-4,
+    -9.8722217067251400e-4, -1.0040474297445790e-3,
+    -1.0203380430448350e-3, -1.0360643900964910e-3,
+    -1.0511966606168980e-3, -1.0657048556038330e-3,
+    -1.0795588568782010e-3, -1.0927284332850520e-3,
+    -1.1051833075734240e-3, -1.1168931605293980e-3,
+    -1.1278276550234160e-3, -1.1379564405661050e-3,
+    -1.1472492294891640e-3, -1.1556758000499310e-3,
+    -1.1632059885511800e-3, -1.1698096960154200e-3,
+    -1.1754570428998680e-3, -1.1801183720212010e-3,
+    -1.1837641581852870e-3, -1.1863650153060240e-3,
+    -1.1878919433902330e-3, -1.1883163316843900e-3,
+    -1.1876097809178440e-3, -1.1857441072376680e-3,
+    -1.1826916065321440e-3, -1.1784250628415020e-3,
+    -1.1729176690707690e-3, -1.1661430294353880e-3,
+    -1.1580752925519680e-3, -1.1486891568700730e-3,
+    -1.1379598570807350e-3, -1.1258631690530700e-3,
+    -1.1123755320313420e-3, -1.0974740543942100e-3,
+    -1.0811365181610850e-3, -1.0633413819325920e-3,
+    -1.0440678410743190e-3, -1.0232958338441730e-3,
+    -1.0010061160103870e-3, -9.7718026613602800e-4,
+    -9.5180072722007060e-4, -9.2485080945546600e-4,
+    -8.9631470926558100e-4, -8.6617751390929650e-4,
+    -8.3442528375666700e-4, -8.0104505655578600e-4,
+    /* Bank 3 */
+     7.6602485902806300e-4,  7.2935371157849700e-4,
+     6.9102172032639350e-4,  6.5102007948960100e-4,
+     6.0934103180698750e-4,  5.6597787244591100e-4,
+     5.2092507454409450e-4,  4.7417829303612970e-4,
+     4.2573432329476060e-4,  3.7559110239316400e-4,
+     3.2374777823389440e-4,  2.7020471361387040e-4,
+     2.1496350652513040e-4,  1.5802699163104190e-4,
+     9.9399252442146460e-5,  3.9085623279149610e-5,
+    -2.2907279717153710e-5, -8.6571556658577800e-5,
+    -1.5189801251884410e-4, -2.1887615668780720e-4,
+    -2.8749420455512610e-4, -3.5773907519488100e-4,
+    -4.2959633884346400e-4, -5.0305021853266900e-4,
+    -5.7808367853976800e-4, -6.5467842279709950e-4,
+    -7.3281477145293300e-4, -8.1247166091487090e-4,
+    -8.9362676824381250e-4, -9.7625651350435400e-4,
+    -1.0603359870796300e-3, -1.1458389497708370e-3,
+    -1.2327379076720450e-3, -1.3210041125919850e-3,
+    -1.4106074964587530e-3, -1.5015166759080980e-3,
+    -1.5936991188210680e-3, -1.6871211446584360e-3,
+    -1.7817477652804130e-3, -1.8775426862784720e-3,
+    -1.9744684954557180e-3, -2.0724866717198650e-3,
+    -2.1715575922482770e-3, -2.2716405301701940e-3,
+    -2.3726935964105480e-3, -2.4746737418493600e-3,
+    -2.5775368629845300e-3, -2.6812378156433060e-3,
+    -2.7857306109716460e-3, -2.8909684129992950e-3,
+    -2.9969032890820140e-3, -3.1034862132032660e-3,
+    -3.2106673881690480e-3, -3.3183962566563890e-3,
+    -3.4266214220855450e-3, -3.5352906520539890e-3,
+    -3.6443510330122110e-3, -3.7537489709635930e-3,
+    -3.8634300521859240e-3, -3.9733390588103910e-3,
+    -4.0834204508378470e-3, -4.1936183686073460e-3,
+    -4.3038762050876900e-3, -4.4141366059086620e-3,
+    -4.5243418977567100e-3, -4.6344341075783170e-3,
+    -4.7443549566589130e-3, -4.8540458565358850e-3,
+    -4.9634478250060780e-3, -5.0725014978718950e-3,
+    -5.1811474713480250e-3, -5.2893263173827950e-3,
+    -5.3969785783205650e-3, -5.5040447592375600e-3,
+    -5.6104651646665850e-3, -5.7161799140263450e-3,
+    -5.8211294443412250e-3, -5.9252545216101900e-3,
+    -6.0284959882028950e-3, -6.1307947602360250e-3,
+    -6.2320920224565700e-3, -6.3323292492425800e-3,
+    -6.4314484717364400e-3, -6.5293922762311450e-3,
+    -6.6261035015351700e-3, -6.7215252466922100e-3,
+    -6.8156013434509950e-3, -6.9082763630156450e-3,
+    -6.9994952920827200e-3, -7.0892035490577050e-3,
+    -7.1773476647806300e-3, -7.2638752839566550e-3,
+    -7.3487345159041400e-3, -7.4318739341000500e-3,
+    -7.5132432154309250e-3, -7.5927931627681400e-3,
+    -7.6704755623721500e-3, -7.7462431738117650e-3,
+    -7.8200496507836000e-3, -7.8918495587816850e-3,
+    -7.9615988430090790e-3, -8.0292548409052500e-3,
+    -8.0947760898363200e-3, -8.1581223027535600e-3,
+    -8.2192540249893810e-3, -8.2781326752680240e-3,
+    -8.3347217911436610e-3, -8.3889870206274740e-3,
+    -8.4408946925453690e-3, -8.4904118087845760e-3,
+    -8.5375073033623590e-3, -8.5821520672029750e-3,
+    -8.6243182341614300e-3, -8.6639791627160300e-3,
+    -8.7011097471794110e-3, -8.7356864659172800e-3,
+    -8.7676881309490440e-3, -8.7970958152554810e-3,
+    -8.8238905039462850e-3, -8.8480531477483150e-3,
+    -8.8695681885783190e-3, -8.8884235927356400e-3,
+    -8.9046080555685600e-3, -8.9181109318560050e-3,
+    -8.9289234995380550e-3, -8.9370390010903460e-3,
+    -8.9424522900292110e-3, -8.9451598223763610e-3,
+    /* Bank 4 */
+     8.9451598223763610e-3,  8.9424522900292110e-3,
+     8.9370390010903460e-3,  8.9289234995380550e-3,
+     8.9181109318560050e-3,  8.9046080555685600e-3,
+     8.8884235927356400e-3,  8.8695681885783190e-3,
+     8.8480531477483150e-3,  8.8238905039462850e-3,
+     8.7970958152554810e-3,  8.7676881309490440e-3,
+     8.7356864659172800e-3,  8.7011097471794110e-3,
+     8.6639791627160300e-3,  8.6243182341614300e-3,
+     8.5821520672029750e-3,  8.5375073033623590e-3,
+     8.4904118087845760e-3,  8.4408946925453690e-3,
+     8.3889870206274740e-3,  8.3347217911436610e-3,
+     8.2781326752680240e-3,  8.2192540249893810e-3,
+     8.1581223027535600e-3,  8.0947760898363200e-3,
+     8.0292548409052500e-3,  7.9615988430090790e-3,
+     7.8918495587816850e-3,  7.8200496507836000e-3,
+     7.7462431738117650e-3,  7.6704755623721500e-3,
+     7.5927931627681400e-3,  7.5132432154309250e-3,
+     7.4318739341000500e-3,  7.3487345159041400e-3,
+     7.2638752839566550e-3,  7.1773476647806300e-3,
+     7.0892035490577050e-3,  6.9994952920827200e-3,
+     6.9082763630156450e-3,  6.8156013434509950e-3,
+     6.7215252466922100e-3,  6.6261035015351700e-3,
+     6.5293922762311450e-3,  6.4314484717364400e-3,
+     6.3323292492425800e-3,  6.2320920224565700e-3,
+     6.1307947602360250e-3,  6.0284959882028950e-3,
+     5.9252545216101900e-3,  5.8211294443412250e-3,
+     5.7161799140263450e-3,  5.6104651646665850e-3,
+     5.5040447592375600e-3,  5.3969785783205650e-3,
+     5.2893263173827950e-3,  5.1811474713480250e-3,
+     5.0725014978718950e-3,  4.9634478250060780e-3,
+     4.8540458565358850e-3,  4.7443549566589130e-3,
+     4.6344341075783170e-3,  4.5243418977567100e-3,
+     4.4141366059086620e-3,  4.3038762050876900e-3,
+     4.1936183686073460e-3,  4.0834204508378470e-3,
+     3.9733390588103910e-3,  3.8634300521859240e-3,
+     3.7537489709635930e-3,  3.6443510330122110e-3,
+     3.5352906520539890e-3,  3.4266214220855450e-3,
+     3.3183962566563890e-3,  3.2106673881690480e-3,
+     3.1034862132032660e-3,  2.9969032890820140e-3,
+     2.8909684129992950e-3,  2.7857306109716460e-3,
+     2.6812378156433060e-3,  2.5775368629845300e-3,
+     2.4746737418493600e-3,  2.3726935964105480e-3,
+     2.2716405301701940e-3,  2.1715575922482770e-3,
+     2.0724866717198650e-3,  1.9744684954557180e-3,
+     1.8775426862784720e-3,  1.7817477652804130e-3,
+     1.6871211446584360e-3,  1.5936991188210680e-3,
+     1.5015166759080980e-3,  1.4106074964587530e-3,
+     1.3210041125919850e-3,  1.2327379076720450e-3,
+     1.1458389497708370e-3,  1.0603359870796300e-3,
+     9.7625651350435400e-4,  8.9362676824381250e-4,
+     8.1247166091487090e-4,  7.3281477145293300e-4,
+     6.5467842279709950e-4,  5.7808367853976800e-4,
+     5.0305021853266900e-4,  4.2959633884346400e-4,
+     3.5773907519488100e-4,  2.8749420455512610e-4,
+     2.1887615668780720e-4,  1.5189801251884410e-4,
+     8.6571556658577800e-5,  2.2907279717153710e-5,
+    -3.9085623279149610e-5, -9.9399252442146460e-5,
+    -1.5802699163104190e-4, -2.1496350652513040e-4,
+    -2.7020471361387040e-4, -3.2374777823389440e-4,
+    -3.7559110239316400e-4, -4.2573432329476060e-4,
+    -4.7417829303612970e-4, -5.2092507454409450e-4,
+    -5.6597787244591100e-4, -6.0934103180698750e-4,
+    -6.5102007948960100e-4, -6.9102172032639350e-4,
+    -7.2935371157849700e-4, -7.6602485902806300e-4,
+    /* Bank 5 */
+     8.0104505655578600e-4,  8.3442528375666700e-4,
+     8.6617751390929650e-4,  8.9631470926558100e-4,
+     9.2485080945546600e-4,  9.5180072722007060e-4,
+     9.7718026613602800e-4,  1.0010061160103870e-3,
+     1.0232958338441730e-3,  1.0440678410743190e-3,
+     1.0633413819325920e-3,  1.0811365181610850e-3,
+     1.0974740543942100e-3,  1.1123755320313420e-3,
+     1.1258631690530700e-3,  1.1379598570807350e-3,
+     1.1486891568700730e-3,  1.1580752925519680e-3,
+     1.1661430294353880e-3,  1.1729176690707690e-3,
+     1.1784250628415020e-3,  1.1826916065321440e-3,
+     1.1857441072376680e-3,  1.1876097809178440e-3,
+     1.1883163316843900e-3,  1.1878919433902330e-3,
+     1.1863650153060240e-3,  1.1837641581852870e-3,
+     1.1801183720212010e-3,  1.1754570428998680e-3,
+     1.1698096960154200e-3,  1.1632059885511800e-3,
+     1.1556758000499310e-3,  1.1472492294891640e-3,
+     1.1379564405661050e-3,  1.1278276550234160e-3,
+     1.1168931605293980e-3,  1.1051833075734240e-3,
+     1.0927284332850520e-3,  1.0795588568782010e-3,
+     1.0657048556038330e-3,  1.0511966606168980e-3,
+     1.0360643900964910e-3,  1.0203380430448350e-3,
+     1.0040474297445790e-3,  9.8722217067251400e-4,
+     9.6989174214394400e-4,  9.5208547141354700e-4,
+     9.3383238324995840e-4,  9.1516119514986000e-4,
+     8.9610036547340950e-4,  8.7667809201044900e-4,
+     8.5692223230171550e-4,  8.3686029869896850e-4,
+     8.1651942936660300e-4,  7.9592638676398950e-4,
+     7.7510755325530950e-4,  7.5408892753413600e-4,
+     7.3289605035434600e-4,  7.1155400216196750e-4,
+     6.9008742526480550e-4,  6.6852052145861900e-4,
+     6.4687697763330650e-4,  6.2517996394886800e-4,
+     6.0345216810040500e-4,  5.8171579317559550e-4,
+     5.5999247625413450e-4,  5.3830328700499900e-4,
+     5.1666877822680600e-4,  4.9510898492628230e-4,
+     4.7364335350426610e-4,  4.5229073958127750e-4,
+     4.3106943097409840e-4,  4.0999714822829530e-4,
+     3.8909103335715320e-4,  3.6836764760397900e-4,
+     3.4784293347385130e-4,  3.2753221542219500e-4,
+     3.0745025297166030e-4,  2.8761124019708440e-4,
+     2.6802874127778880e-4,  2.4871569004884240e-4,
+     2.2968444457655940e-4,  2.1094678833176480e-4,
+     1.9251390142613000e-4,  1.7439635977956720e-4,
+     1.5660414556657680e-4,  1.3914664880465400e-4,
+     1.2203269185287530e-4,  1.0527052946041040e-4,
+     8.8867825335203200e-5,  7.2831653374563650e-5,
+     5.7168548169515050e-5,  4.1884506316022560e-5,
+     2.6984964757674160e-5,  1.2474801400564880e-5,
+    -1.6416297019304470e-6, -1.5360496520469550e-5,
+    -2.8678484003389880e-5, -4.1592792755171040e-5,
+    -5.4101115008963200e-5, -6.6201632959158800e-5,
+    -7.7893006105444910e-5, -8.9174369623037550e-5,
+    -1.0004531116378850e-4, -1.1050586906665980e-4,
+    -1.2055651618705740e-4, -1.3019815804235450e-4,
+    -1.3943210818407590e-4, -1.4826008597798460e-4,
+    -1.5668419239382670e-4, -1.6470690840351980e-4,
+    -1.7233108395155490e-4, -1.7955993578371750e-4,
+    -1.8639701070854740e-4, -1.9284618337957900e-4,
+    -1.9891164424316180e-4, -2.0459789739171640e-4,
+    -2.0990972538755550e-4, -2.1485218733324290e-4,
+    -2.1943061159567880e-4, -2.2365059385031200e-4,
+    -2.2751796132972940e-4, -2.3103877007019660e-4,
+    -2.3421928008696620e-4, -2.3706595356421380e-4,
+    -2.3958543985834340e-4, -2.4178457457919800e-4,
+    /* Bank 6 */
+     2.4367037437341020e-4,  2.4525003217524440e-4,
+     2.4653081794176570e-4,  2.4752008219951220e-4,
+     2.4822543333608940e-4,  2.4865471770248810e-4,
+     2.4881540457247040e-4,  2.4871461830381660e-4,
+     2.4836046092637280e-4,  2.4776199025177680e-4,
+     2.4692741569938220e-4,  2.4586407616017000e-4,
+     2.4457975717687980e-4,  2.4308272452941820e-4,
+     2.4138114593372380e-4,  2.3948307023621970e-4,
+     2.3739654799291240e-4,  2.3512963563507800e-4,
+     2.3269036653525150e-4,  2.3008674810081220e-4,
+     2.2732672676686290e-4,  2.2441818635854840e-4,
+     2.2136894706917190e-4,  2.1818676491655660e-4,
+     2.1487932080488700e-4,  2.1145421910491280e-4,
+     2.0791896735659270e-4,  2.0428097498957360e-4,
+     2.0054754547108610e-4,  1.9672587556804270e-4,
+     1.9282304696531290e-4,  1.8884602526638050e-4,
+     1.8480164638953740e-4,  1.8069661584612290e-4,
+     1.7653750646560020e-4,  1.7233075773584680e-4,
+     1.6808266356446820e-4,  1.6379937154642740e-4,
+     1.5948687909058970e-4,  1.5515103314094370e-4,
+     1.5079752791692290e-4,  1.4643190426323540e-4,
+     1.4205953760578120e-4,  1.3768563787408340e-4,
+     1.3331525983885840e-4,  1.2895330270761850e-4,
+     1.2460449089034750e-4,  1.2027337376184880e-4,
+     1.1596433966772030e-4,  1.1168161614264270e-4,
+     1.0742926070674010e-4,  1.0321116057304920e-4,
+     9.9031035415475500e-5,  9.4892437636254000e-5,
+     9.0798755482139240e-5,  8.6753213062403400e-5,
+     8.2758867628623800e-5,  7.8818609806320000e-5,
+     7.4935171411178040e-5,  7.1111125753722860e-5,
+     6.7348886525882700e-5,  6.3650708053788550e-5,
+     6.0018691972791050e-5,  5.6454787620185350e-5,
+     5.2960794000140600e-5,  4.9538360176954340e-5,
+     4.6188991961724560e-5,  4.2914052387856640e-5,
+     3.9714765485539260e-5,  3.6592216716540970e-5,
+     3.3547358765259040e-5,  3.0581012081916960e-5,
+     2.7693871041862060e-5,  2.4886504491416160e-5,
+     2.2159361597292710e-5,  1.9512772389215240e-5,
+     1.6946953848107710e-5,  1.4462010500550970e-5,
+     1.2057941408635810e-5,  9.7346407524871100e-6,
+     7.4919036559427900e-6,  5.3294268968052800e-6,
+     3.2468187066945930e-6,  1.2435990827839660e-6,
+    -6.8080315386959900e-7, -2.5270494199802070e-6,
+    -4.2958677847708840e-6, -5.9880523825897000e-6,
+    -7.6044740757265500e-6, -9.1460801506922300e-6,
+    -1.0613876973541650e-5, -1.2008929083235120e-5,
+    -1.3332356590263080e-5, -1.4585334740507920e-5,
+    -1.5769086921577900e-5, -1.6884884022311310e-5,
+    -1.7934037335534700e-5, -1.8917898053528080e-5,
+    -1.9837853265502040e-5, -2.0695325418576370e-5,
+    -2.1491764461832140e-5, -2.2228647280994560e-5,
+    -2.2907473117403740e-5, -2.3529763128539150e-5,
+    -2.4097055300584120e-5, -2.4610903957661350e-5,
+    -2.5072874052447260e-5, -2.5484540698002960e-5,
+    -2.5847484577439320e-5, -2.6163291550639320e-5,
+    -2.6433548592482960e-5, -2.6659843389908530e-5,
+    -2.6843759539035120e-5, -2.6986876191054700e-5,
+    -2.7090765064735940e-5, -2.7156990105794550e-5,
+    -2.7187102980536760e-5, -2.7182642746157720e-5,
+    -2.7145133103663890e-5, -2.7076082153012070e-5,
+    -2.6976979753245170e-5, -2.6849297239997120e-5,
+    -2.6694483850464800e-5, -2.6513966535124460e-5,
+    -2.6309149390520640e-5, -2.6081413415833200e-5,
+    -2.5832111724562040e-5, -2.5562569399199020e-5,
+    /* Bank 7 */
+     2.5274085082324960e-5,  2.4967930863542620e-5,
+     2.4645348200903720e-5,  2.4307547722489910e-5,
+     2.3955708939763280e-5,  2.3590980216497750e-5,
+     2.3214478371918170e-5,  2.2827288605503470e-5,
+     2.2430463239517170e-5,  2.2025021652894630e-5,
+     2.1611950084231910e-5,  2.1192201630574280e-5,
+     2.0766696417773940e-5,  2.0336321557464510e-5,
+     1.9901930030141080e-5,  1.9464340744880170e-5,
+     1.9024340970099240e-5,  1.8582686308483550e-5,
+     1.8140097714618200e-5,  1.7697261563607500e-5,
+     1.7254834143068570e-5,  1.6813441716539560e-5,
+     1.6373677426466900e-5,  1.5936101341640500e-5,
+     1.5501244597782600e-5,  1.5069609527679710e-5,
+     1.4641668383496450e-5,  1.4217863365843780e-5,
+     1.3798608540965960e-5,  1.3384289978242060e-5,
+     1.2975266858030310e-5,  1.2571871574469220e-5,
+     1.2174410889256530e-5,  1.1783166036693560e-5,
+     1.1398393880881060e-5,  1.1020327046334650e-5,
+     1.0649175634328590e-5,  1.0285127334608450e-5,
+     9.9283481667264540e-6,  9.5789825988253100e-6,
+     9.2371554195468400e-6,  8.9029718900122000e-6,
+     8.5765192154768100e-6,  8.2578666429227760e-6,
+     7.9470661364365490e-6,  7.6441525098592000e-6,
+     7.3491456697144900e-6,  7.0620507545154100e-6,
+     6.7828589565804950e-6,  6.5115476278604000e-6,
+     6.2480817863072800e-6,  5.9924142424804800e-6,
+     5.7444868785028750e-6,  5.5042307535458100e-6,
+     5.2715671455405850e-6,  5.0464076705003400e-6,
+     4.8286558658894680e-6,  4.6182073040543900e-6,
+     4.4149505043312320e-6,  4.2187670209852250e-6,
+     4.0295324657699800e-6,  3.8471166218015830e-6,
+     3.6713849262294680e-6,  3.5021985520037540e-6,
+     3.3394147240855820e-6,  3.1828867865974640e-6,
+     3.0324653639203880e-6,  2.8879984579501380e-6,
+     2.7493324266391140e-6,  2.6163120571644820e-6,
+     2.4887811970856540e-6,  2.3665828120950560e-6,
+     2.2495596253776460e-6,  2.1375541686662320e-6,
+     2.0304092660990760e-6,  1.9279680902322050e-6,
+     1.8300749104526120e-6,  1.7365751553971340e-6,
+     1.6473160377545360e-6,  1.5621465913980060e-6,
+     1.4809178634979940e-6,  1.4034829433780260e-6,
+     1.3296974052300520e-6,  1.2594193438633260e-6,
+     1.1925097184646100e-6,  1.1288323637155430e-6,
+     1.0682538906146330e-6,  1.0106437128213760e-6,
+     9.5587472540498280e-7,  9.0382333224895500e-7,
+     8.5436937020293650e-7,  8.0739610368280600e-7,
+     7.6279018172077200e-7,  7.2044165259013450e-7,
+     6.8024432849991400e-7,  6.4209580087853050e-7,
+     6.0589741192019800e-7,  5.7155423388793000e-7,
+     5.3897464223335550e-7,  5.0807031294631050e-7,
+     4.7875659112606760e-7,  4.5095249563698380e-7,
+     4.2458045296159330e-7,  3.9956628121669190e-7,
+     3.7583910465412180e-7,  3.5333134588843600e-7,
+     3.3197864040473180e-7,  3.1171981968268900e-7,
+     2.9249662541757600e-7,  2.7425370308549580e-7,
+     2.5693874615777660e-7,  2.4050245877923400e-7,
+     2.2489759047553620e-7,  2.1007899706006800e-7,
+     1.9600594587757850e-7,  1.8264184311018150e-7,
+     1.6994592926571220e-7,  1.5787424998123710e-7,
+     1.4640931821191640e-7,  1.3555636137971380e-7,
+     1.2523109645615350e-7,  1.1527363411865760e-7,
+     1.0586659510721950e-7,  9.7483190494874640e-8,
+     8.9326871281374790e-8,  7.9525034321375090e-8,
+     7.0950903150874990e-8,  7.1279389866041690e-8,
+};
+
 /*
  * D.11 Look-up Table for Downmix Scale Factors
  *
@@ -7534,7 +8128,7 @@ DECLARE_ALIGNED(16, const float, ff_dca_lfe_fir_128)[256] = {
  * 2) [-29.750 to -15] with resolution of 0.250 dB
  * 3) [-14.875 to   0] with resolution of 0.125 dB
  */
-const uint16_t ff_dca_dmixtable[242] = {
+const uint16_t ff_dca_dmixtable[FF_DCA_DMIXTABLE_SIZE] = {
         0,    33,    35,    37,    39,    41,    44,    46,
        49,    52,    55,    58,    62,    65,    69,    73,
        78,    82,    87,    92,    98,   104,   110,   116,
@@ -7568,6 +8162,35 @@ const uint16_t ff_dca_dmixtable[242] = {
     32300, 32768,
 };
 
+const uint32_t ff_dca_inv_dmixtable[FF_DCA_INV_DMIXTABLE_SIZE] = {
+    6553600, 6186997, 5840902, 5514167, 5205710, 4914507, 4639593, 4380059,
+    4135042, 3903731, 3685360, 3479204, 3284581, 3100844, 2927386, 2763630,
+    2609035, 2463088, 2325305, 2195230, 2072430, 2013631, 1956500, 1900990,
+    1847055, 1794651, 1743733, 1694260, 1646190, 1599484, 1554103, 1510010,
+    1467168, 1425542, 1385096, 1345798, 1307615, 1270515, 1234468, 1199444,
+    1165413, 1132348, 1100221, 1069005, 1038676, 1009206,  980573,  952752,
+     925721,  899456,  873937,  849141,  825049,  801641,  778897,  756798,
+     735326,  714463,  694193,  674497,  655360,  636766,  618700,  601146,
+     584090,  567518,  551417,  535772,  520571,  505801,  491451,  477507,
+     463959,  450796,  438006,  425579,  413504,  401772,  390373,  379297,
+     368536,  363270,  358080,  352964,  347920,  342949,  338049,  333219,
+     328458,  323765,  319139,  314579,  310084,  305654,  301287,  296982,
+     292739,  288556,  284433,  280369,  276363,  272414,  268522,  264685,
+     260904,  257176,  253501,  249879,  246309,  242790,  239321,  235901,
+     232531,  229208,  225933,  222705,  219523,  216386,  213295,  210247,
+     207243,  204282,  201363,  198486,  195650,  192855,  190099,  187383,
+     184706,  182066,  179465,  176901,  174373,  171882,  169426,  167005,
+     164619,  162267,  159948,  157663,  155410,  153190,  151001,  148844,
+     146717,  144621,  142554,  140517,  138510,  136531,  134580,  132657,
+     130762,  128893,  127052,  125236,  123447,  121683,  119944,  118231,
+     116541,  114876,  113235,  111617,  110022,  108450,  106901,  105373,
+     103868,  102383,  100921,   99479,   98057,   96656,   95275,   93914,
+      92682,   91249,   89946,   88660,   87394,   86145,   84914,   83701,
+      82505,   81326,   80164,   79019,   77890,   76777,   75680,   74598,
+      73533,   72482,   71446,   70425,   69419,   68427,   67450,   66486,
+      65536,
+};
+
 const float ff_dca_default_coeffs[10][6][2] = {
     { { 0.707107, 0.707107 }, { 0.000000, 0.000000 },                                                                                                 }, // A [LFE]
     { { 1.000000, 0.000000 }, { 0.000000, 1.000000 }, { 0.000000, 0.000000 },                                                                         }, // A + B (dual mono) [LFE]
@@ -7581,6 +8204,11 @@ const float ff_dca_default_coeffs[10][6][2] = {
     { { 0.501187, 0.501187 }, { 0.707107, 0.000000 }, { 0.000000, 0.707107 }, { 0.501187, 0.000000 }, { 0.000000, 0.501187 }, { 0.000000, 0.000000 }, }, // C + L + R + SL + SR [LFE]
 };
 
+const int32_t ff_dca_sampling_freqs[16] = {
+      8000,  16000, 32000, 64000, 128000, 22050,  44100,  88200,
+    176400, 352800, 12000, 24000,  48000, 96000, 192000, 384000,
+};
+
 /* downmix coeffs
  *
  * TABLE 9
diff --git a/libavcodec/dcadata.h b/libavcodec/dcadata.h
index b59b524..7a9d994 100644
--- a/libavcodec/dcadata.h
+++ b/libavcodec/dcadata.h
@@ -47,11 +47,19 @@ extern const float ff_dca_fir_32bands_nonperfect[512];
 
 extern const float ff_dca_lfe_fir_64[256];
 extern const float ff_dca_lfe_fir_128[256];
+extern const float ff_dca_lfe_xll_fir_64[256];
+extern const float ff_dca_fir_64bands[1024];
 
-extern const uint16_t ff_dca_dmixtable[242];
+#define FF_DCA_DMIXTABLE_SIZE      242
+#define FF_DCA_INV_DMIXTABLE_SIZE  201
+
+extern const uint16_t ff_dca_dmixtable[FF_DCA_DMIXTABLE_SIZE];
+extern const uint32_t ff_dca_inv_dmixtable[FF_DCA_INV_DMIXTABLE_SIZE];
 
 extern const float ff_dca_default_coeffs[10][6][2];
 
+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];
diff --git a/libavcodec/dcadec.c b/libavcodec/dcadec.c
index 316affb..57198b0 100644
--- a/libavcodec/dcadec.c
+++ b/libavcodec/dcadec.c
@@ -4,6 +4,8 @@
  * 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.
  *
@@ -26,6 +28,7 @@
 #include <stddef.h>
 #include <stdio.h>
 
+#include "libavutil/attributes.h"
 #include "libavutil/channel_layout.h"
 #include "libavutil/common.h"
 #include "libavutil/float_dsp.h"
@@ -555,8 +558,83 @@ static void qmf_32_subbands(DCAContext *s, int chans,
                               samples_out, s->raXin, scale);
 }
 
-static void lfe_interpolation_fir(DCAContext *s, int decimation_select,
-                                  int num_deci_sample, float *samples_in,
+static QMF64_table *qmf64_precompute(void)
+{
+    unsigned i, j;
+    QMF64_table *table = av_malloc(sizeof(*table));
+    if (!table)
+        return NULL;
+
+    for (i = 0; i < 32; i++)
+        for (j = 0; j < 32; j++)
+            table->dct4_coeff[i][j] = cos((2 * i + 1) * (2 * j + 1) * M_PI / 128);
+    for (i = 0; i < 32; i++)
+        for (j = 0; j < 32; j++)
+            table->dct2_coeff[i][j] = cos((2 * i + 1) *      j      * M_PI /  64);
+
+    /* FIXME: Is the factor 0.125 = 1/8 right? */
+    for (i = 0; i < 32; i++)
+        table->rcos[i] =  0.125 / cos((2 * i + 1) * M_PI / 256);
+    for (i = 0; i < 32; i++)
+        table->rsin[i] = -0.125 / sin((2 * i + 1) * M_PI / 256);
+
+    return table;
+}
+
+/* FIXME: Totally unoptimized. Based on the reference code and
+ * http://multimedia.cx/mirror/dca-transform.pdf, with guessed tweaks
+ * for doubling the size. */
+static void qmf_64_subbands(DCAContext *s, int chans, float samples_in[64][8],
+                            float *samples_out, float scale)
+{
+    float raXin[64];
+    float A[32], B[32];
+    float *raX = s->subband_fir_hist[chans];
+    float *raZ = s->subband_fir_noidea[chans];
+    unsigned i, j, k, subindex;
+
+    for (i = s->subband_activity[chans]; i < 64; i++)
+        raXin[i] = 0.0;
+    for (subindex = 0; subindex < 8; subindex++) {
+        for (i = 0; i < s->subband_activity[chans]; i++)
+            raXin[i] = samples_in[i][subindex];
+
+        for (k = 0; k < 32; k++) {
+            A[k] = 0.0;
+            for (i = 0; i < 32; i++)
+                A[k] += (raXin[2 * i] + raXin[2 * i + 1]) * s->qmf64_table->dct4_coeff[k][i];
+        }
+        for (k = 0; k < 32; k++) {
+            B[k] = raXin[0] * s->qmf64_table->dct2_coeff[k][0];
+            for (i = 1; i < 32; i++)
+                B[k] += (raXin[2 * i] + raXin[2 * i - 1]) * s->qmf64_table->dct2_coeff[k][i];
+        }
+        for (k = 0; k < 32; k++) {
+            raX[k]      = s->qmf64_table->rcos[k] * (A[k] + B[k]);
+            raX[63 - k] = s->qmf64_table->rsin[k] * (A[k] - B[k]);
+        }
+
+        for (i = 0; i < 64; i++) {
+            float out = raZ[i];
+            for (j = 0; j < 1024; j += 128)
+                out += ff_dca_fir_64bands[j + i] * (raX[j + i] - raX[j + 63 - i]);
+            *samples_out++ = out * scale;
+        }
+
+        for (i = 0; i < 64; i++) {
+            float hist = 0.0;
+            for (j = 0; j < 1024; j += 128)
+                hist += ff_dca_fir_64bands[64 + j + i] * (-raX[i + j] - raX[j + 63 - i]);
+
+            raZ[i] = hist;
+        }
+
+        /* FIXME: Make buffer circular, to avoid this move. */
+        memmove(raX + 64, raX, (1024 - 64) * sizeof(*raX));
+    }
+}
+
+static void lfe_interpolation_fir(DCAContext *s, const float *samples_in,
                                   float *samples_out)
 {
     /* samples_in: An array holding decimated samples.
@@ -572,15 +650,18 @@ static void lfe_interpolation_fir(DCAContext *s, int decimation_select,
     int deciindex;
 
     /* Select decimation filter */
-    if (decimation_select == 1) {
+    if (s->lfe == 1) {
         idx     = 1;
         prCoeff = ff_dca_lfe_fir_128;
     } else {
-        idx     = 0;
-        prCoeff = ff_dca_lfe_fir_64;
+        idx = 0;
+        if (s->exss_ext_mask & DCA_EXT_EXSS_XLL)
+            prCoeff = ff_dca_lfe_xll_fir_64;
+        else
+            prCoeff = ff_dca_lfe_fir_64;
     }
     /* Interpolation */
-    for (deciindex = 0; deciindex < num_deci_sample; deciindex++) {
+    for (deciindex = 0; deciindex < 2 * s->lfe; deciindex++) {
         s->dcadsp.lfe_fir[idx](samples_out, samples_in, prCoeff);
         samples_in++;
         samples_out += 2 * 32 * (1 + idx);
@@ -849,27 +930,56 @@ static int dca_subsubframe(DCAContext *s, int base_channel, int block_index)
     return 0;
 }
 
-static int dca_filter_channels(DCAContext *s, int block_index)
+static int dca_filter_channels(DCAContext *s, int block_index, int upsample)
 {
     float (*subband_samples)[DCA_SUBBANDS][8] = s->subband_samples[block_index];
     int k;
 
-    /* 32 subbands QMF */
-    for (k = 0; k < s->prim_channels; k++) {
-        if (s->channel_order_tab[k] >= 0)
-            qmf_32_subbands(s, k, subband_samples[k],
-                            s->samples_chanptr[s->channel_order_tab[k]],
-                            M_SQRT1_2 / 32768.0);
+    if (upsample) {
+        if (!s->qmf64_table) {
+            s->qmf64_table = qmf64_precompute();
+            if (!s->qmf64_table)
+                return AVERROR(ENOMEM);
+        }
+
+        /* 64 subbands QMF */
+        for (k = 0; k < s->prim_channels; k++) {
+            if (s->channel_order_tab[k] >= 0)
+                qmf_64_subbands(s, k, subband_samples[k],
+                                s->samples_chanptr[s->channel_order_tab[k]],
+                                /* Upsampling needs a factor 2 here. */
+                                M_SQRT2 / 32768.0);
+        }
+    } else {
+        /* 32 subbands QMF */
+        for (k = 0; k < s->prim_channels; k++) {
+            if (s->channel_order_tab[k] >= 0)
+                qmf_32_subbands(s, k, subband_samples[k],
+                                s->samples_chanptr[s->channel_order_tab[k]],
+                                M_SQRT1_2 / 32768.0);
+        }
     }
 
     /* 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]];
+        lfe_interpolation_fir(s,
                               s->lfe_data + 2 * s->lfe * (block_index + 4),
-                              s->samples_chanptr[ff_dca_lfe_index[s->amode]]);
-        /* 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) {
@@ -1050,8 +1160,10 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data,
     DCAContext *s = avctx->priv_data;
     int channels, full_channels;
     int core_ss_end;
+    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,
                                                   DCA_MAX_FRAME_SIZE + DCA_MAX_EXSS_HEADER_SIZE);
@@ -1279,6 +1391,43 @@ FF_ENABLE_DEPRECATION_WARNINGS
 
     /* 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)
+                avctx->channels += s->xll_channels - s->xll_residual_channels;
+        }
+    }
+
+    /* FIXME: This is an ugly hack, to just revert to the default
+     * layout if we have additional channels. Need to convert the XLL
+     * channel masks to libav 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) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
@@ -1309,13 +1458,13 @@ FF_ENABLE_DEPRECATION_WARNINGS
     /* filter to get final output */
     for (i = 0; i < (s->sample_blocks / 8); i++) {
         int ch;
-
+        unsigned block = upsample ? 512 : 256;
         for (ch = 0; ch < channels; ch++)
-            s->samples_chanptr[ch] = samples_flt[ch] + i * 256;
+            s->samples_chanptr[ch] = samples_flt[ch] + i * block;
         for (; ch < full_channels; ch++)
-            s->samples_chanptr[ch] = s->extra_channels[ch - channels] + i * 256;
+            s->samples_chanptr[ch] = s->extra_channels[ch - channels] + i * block;
 
-        dca_filter_channels(s, i);
+        dca_filter_channels(s, i, upsample);
 
         /* If this was marked as a DTS-ES stream we need to subtract back- */
         /* channel from SL & SR to remove matrixed back-channel signal */
@@ -1333,6 +1482,11 @@ FF_ENABLE_DEPRECATION_WARNINGS
     for (i = 0; i < 2 * s->lfe * 4; i++)
         s->lfe_data[i] = s->lfe_data[i + lfe_samples];
 
+    if (s->exss_ext_mask & DCA_EXT_EXSS_XLL) {
+        ret = ff_dca_xll_decode_audio(s, frame);
+        if (ret < 0)
+            return ret;
+    }
     /* AVMatrixEncoding
      *
      * DCA_STEREO_TOTAL (Lt/Rt) is equivalent to Dolby Surround */
@@ -1387,6 +1541,8 @@ static av_cold int dca_decode_end(AVCodecContext *avctx)
     DCAContext *s = avctx->priv_data;
     ff_mdct_end(&s->imdct);
     av_freep(&s->extra_channels_buffer);
+    av_freep(&s->xll_sample_buf);
+    av_freep(&s->qmf64_table);
     return 0;
 }
 
@@ -1401,6 +1557,7 @@ static const AVProfile profiles[] = {
 
 static const AVOption options[] = {
     { "disable_xch", "disable decoding of the XCh extension", offsetof(DCAContext, xch_disable), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM },
+    { "disable_xll", "disable decoding of the XLL extension", offsetof(DCAContext, xll_disable), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM },
     { NULL },
 };
 
diff --git a/libavcodec/version.h b/libavcodec/version.h
index 816d7ea..0d5408b 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -29,7 +29,7 @@
 #include "libavutil/version.h"
 
 #define LIBAVCODEC_VERSION_MAJOR 56
-#define LIBAVCODEC_VERSION_MINOR 18
+#define LIBAVCODEC_VERSION_MINOR 19
 #define LIBAVCODEC_VERSION_MICRO  0
 
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \




More information about the ffmpeg-cvslog mailing list