/*
 * Copyright (C) 2016 foo86
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#define BITSTREAM_READER_LE

#include "libavutil/channel_layout.h"

#include "dcadec.h"
#include "dcadata.h"
#include "dcahuff.h"
#include "dca_syncwords.h"
#include "bytestream.h"

#define AMP_MAX     56

enum LBRFlags {
    LBR_FLAG_24_BIT             = 0x01,
    LBR_FLAG_LFE_PRESENT        = 0x02,
    LBR_FLAG_BAND_LIMIT_2_3     = 0x04,
    LBR_FLAG_BAND_LIMIT_1_2     = 0x08,
    LBR_FLAG_BAND_LIMIT_1_3     = 0x0c,
    LBR_FLAG_BAND_LIMIT_1_4     = 0x10,
    LBR_FLAG_BAND_LIMIT_1_8     = 0x18,
    LBR_FLAG_BAND_LIMIT_NONE    = 0x14,
    LBR_FLAG_BAND_LIMIT_MASK    = 0x1c,
    LBR_FLAG_DMIX_STEREO        = 0x20,
    LBR_FLAG_DMIX_MULTI_CH      = 0x40
};

enum LBRChunkTypes {
    LBR_CHUNK_NULL              = 0x00,
    LBR_CHUNK_PAD               = 0x01,
    LBR_CHUNK_FRAME             = 0x04,
    LBR_CHUNK_FRAME_NO_CSUM     = 0x06,
    LBR_CHUNK_LFE               = 0x0a,
    LBR_CHUNK_ECS               = 0x0b,
    LBR_CHUNK_RESERVED_1        = 0x0c,
    LBR_CHUNK_RESERVED_2        = 0x0d,
    LBR_CHUNK_SCF               = 0x0e,
    LBR_CHUNK_TONAL             = 0x10,
    LBR_CHUNK_TONAL_GRP_1       = 0x11,
    LBR_CHUNK_TONAL_GRP_2       = 0x12,
    LBR_CHUNK_TONAL_GRP_3       = 0x13,
    LBR_CHUNK_TONAL_GRP_4       = 0x14,
    LBR_CHUNK_TONAL_GRP_5       = 0x15,
    LBR_CHUNK_TONAL_SCF         = 0x16,
    LBR_CHUNK_TONAL_SCF_GRP_1   = 0x17,
    LBR_CHUNK_TONAL_SCF_GRP_2   = 0x18,
    LBR_CHUNK_TONAL_SCF_GRP_3   = 0x19,
    LBR_CHUNK_TONAL_SCF_GRP_4   = 0x1a,
    LBR_CHUNK_TONAL_SCF_GRP_5   = 0x1b,
    LBR_CHUNK_RES_GRID_LR       = 0x30,
    LBR_CHUNK_RES_GRID_LR_LAST  = 0x3f,
    LBR_CHUNK_RES_GRID_HR       = 0x40,
    LBR_CHUNK_RES_GRID_HR_LAST  = 0x4f,
    LBR_CHUNK_RES_TS_1          = 0x50,
    LBR_CHUNK_RES_TS_1_LAST     = 0x5f,
    LBR_CHUNK_RES_TS_2          = 0x60,
    LBR_CHUNK_RES_TS_2_LAST     = 0x6f,
    LBR_CHUNK_EXTENSION         = 0x7f
};

typedef struct LBRChunk {
    int id, len;
    const uint8_t *data;
} LBRChunk;

static const int8_t channel_reorder_nolfe[7][5] = {
    { 0, -1, -1, -1, -1 },  // C
    { 0,  1, -1, -1, -1 },  // LR
    { 0,  1,  2, -1, -1 },  // LR C
    { 0,  1, -1, -1, -1 },  // LsRs
    { 1,  2,  0, -1, -1 },  // LsRs C
    { 0,  1,  2,  3, -1 },  // LR LsRs
    { 0,  1,  3,  4,  2 },  // LR LsRs C
};

static const int8_t channel_reorder_lfe[7][5] = {
    { 0, -1, -1, -1, -1 },  // C
    { 0,  1, -1, -1, -1 },  // LR
    { 0,  1,  2, -1, -1 },  // LR C
    { 1,  2, -1, -1, -1 },  // LsRs
    { 2,  3,  0, -1, -1 },  // LsRs C
    { 0,  1,  3,  4, -1 },  // LR LsRs
    { 0,  1,  4,  5,  2 },  // LR LsRs C
};

static const uint8_t lfe_index[7] = {
    1, 2, 3, 0, 1, 2, 3
};

static const uint8_t channel_counts[7] = {
    1, 2, 3, 2, 3, 4, 5
};

static const uint16_t channel_layouts[7] = {
    AV_CH_LAYOUT_MONO,
    AV_CH_LAYOUT_STEREO,
    AV_CH_LAYOUT_SURROUND,
    AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT,
    AV_CH_FRONT_CENTER | AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT,
    AV_CH_LAYOUT_2_2,
    AV_CH_LAYOUT_5POINT0
};

static float    cos_tab[256];
static float    lpc_tab[16];

static av_cold void init_tables(void)
{
    static int initialized;
    int i;

    if (initialized)
        return;

    for (i = 0; i < 256; i++)
        cos_tab[i] = cos(M_PI * i / 128);

    for (i = 0; i < 16; i++)
        lpc_tab[i] = sin((i - 8) * (M_PI / ((i < 8) ? 17 : 15)));

    initialized = 1;
}

static int parse_lfe_24(DCALbrDecoder *s)
{
    int step_max = FF_ARRAY_ELEMS(ff_dca_lfe_step_size_24) - 1;
    int i, ps, si, code, step_i;
    float step, value, delta;

    ps = get_bits(&s->gb, 24);
    si = ps >> 23;

    value = (((ps & 0x7fffff) ^ -si) + si) * (1.0f / 0x7fffff);

    step_i = get_bits(&s->gb, 8);
    if (step_i > step_max) {
        av_log(s->avctx, AV_LOG_ERROR, "Invalid LFE step size index\n");
        return -1;
    }

    step = ff_dca_lfe_step_size_24[step_i];

    for (i = 0; i < 64; i++) {
        code = get_bits(&s->gb, 6);

        delta = step * 0.03125f;
        if (code & 16)
            delta += step;
        if (code & 8)
            delta += step * 0.5f;
        if (code & 4)
            delta += step * 0.25f;
        if (code & 2)
            delta += step * 0.125f;
        if (code & 1)
            delta += step * 0.0625f;

        if (code & 32) {
            value -= delta;
            if (value < -3.0f)
                value = -3.0f;
        } else {
            value += delta;
            if (value > 3.0f)
                value = 3.0f;
        }

        step_i += ff_dca_lfe_delta_index_24[code & 31];
        step_i = av_clip(step_i, 0, step_max);

        step = ff_dca_lfe_step_size_24[step_i];
        s->lfe_data[i] = value * s->lfe_scale;
    }

    return 0;
}

static int parse_lfe_16(DCALbrDecoder *s)
{
    int step_max = FF_ARRAY_ELEMS(ff_dca_lfe_step_size_16) - 1;
    int i, ps, si, code, step_i;
    float step, value, delta;

    ps = get_bits(&s->gb, 16);
    si = ps >> 15;

    value = (((ps & 0x7fff) ^ -si) + si) * (1.0f / 0x7fff);

    step_i = get_bits(&s->gb, 8);
    if (step_i > step_max) {
        av_log(s->avctx, AV_LOG_ERROR, "Invalid LFE step size index\n");
        return -1;
    }

    step = ff_dca_lfe_step_size_16[step_i];

    for (i = 0; i < 64; i++) {
        code = get_bits(&s->gb, 4);

        delta = step * 0.125f;
        if (code & 4)
            delta += step;
        if (code & 2)
            delta += step * 0.5f;
        if (code & 1)
            delta += step * 0.25f;

        if (code & 8) {
            value -= delta;
            if (value < -3.0f)
                value = -3.0f;
        } else {
            value += delta;
            if (value > 3.0f)
                value = 3.0f;
        }

        step_i += ff_dca_lfe_delta_index_16[code & 7];
        step_i = av_clip(step_i, 0, step_max);

        step = ff_dca_lfe_step_size_16[step_i];
        s->lfe_data[i] = value * s->lfe_scale;
    }

    return 0;
}

static int parse_lfe_chunk(DCALbrDecoder *s, LBRChunk *chunk)
{
    if (!(s->flags & LBR_FLAG_LFE_PRESENT))
        return 0;

    if (!chunk->len)
        return 0;

    if (init_get_bits8(&s->gb, chunk->data, chunk->len) < 0)
        return -1;

    // Determine bit depth from chunk size
    if (chunk->len >= 52)
        return parse_lfe_24(s);
    if (chunk->len >= 35)
        return parse_lfe_16(s);

    av_log(s->avctx, AV_LOG_ERROR, "LFE chunk too short\n");
    return -1;
}

static inline int parse_vlc(GetBitContext *s, VLC *vlc, int max_depth)
{
    int v = get_vlc2(s, vlc->table, vlc->bits, max_depth);
    if (v > 0)
        return v - 1;
    // Rare value
    return get_bits(s, get_bits(s, 3) + 1);
}

static int parse_tonal(DCALbrDecoder *s, int group)
{
    unsigned int amp[DCA_LBR_CHANNELS_TOTAL];
    unsigned int phs[DCA_LBR_CHANNELS_TOTAL];
    unsigned int diff, main_amp, shift;
    int sf, sf_idx, ch, main_ch, freq;
    int ch_nbits = av_ceil_log2(s->nchannels_total);

    // Parse subframes for this group
    for (sf = 0; sf < 1 << group; sf += diff ? 8 : 1) {
        sf_idx = ((s->framenum << group) + sf) & 31;
        s->tonal_bounds[group][sf_idx][0] = s->ntones;

        // Parse tones for this subframe
        for (freq = 1;; freq++) {
            if (get_bits_left(&s->gb) < 1) {
                av_log(s->avctx, AV_LOG_ERROR, "Tonal group chunk too short\n");
                return -1;
            }

            diff = parse_vlc(&s->gb, &ff_dca_vlc_tnl_grp[group], 2);
            if (diff >= FF_ARRAY_ELEMS(ff_dca_fst_amp)) {
                av_log(s->avctx, AV_LOG_ERROR, "Invalid tonal frequency diff\n");
                return -1;
            }

            diff = get_bitsz(&s->gb, diff >> 2) + ff_dca_fst_amp[diff];
            if (diff <= 1)
                break;  // End of subframe

            freq += diff - 2;
            if (freq >> (5 - group) > s->nsubbands * 4 - 6) {
                av_log(s->avctx, AV_LOG_ERROR, "Invalid spectral line offset\n");
                return -1;
            }

            // Main channel
            main_ch = get_bitsz(&s->gb, ch_nbits);
            main_amp = parse_vlc(&s->gb, &ff_dca_vlc_tnl_scf, 2)
                + s->tonal_scf[ff_dca_freq_to_sb[freq >> (7 - group)]]
                + s->limited_range - 2;
            amp[main_ch] = main_amp < AMP_MAX ? main_amp : 0;
            phs[main_ch] = get_bits(&s->gb, 3);

            // Secondary channels
            for (ch = 0; ch < s->nchannels_total; ch++) {
                if (ch == main_ch)
                    continue;
                if (get_bits1(&s->gb)) {
                    amp[ch] = amp[main_ch] - parse_vlc(&s->gb, &ff_dca_vlc_damp, 1);
                    phs[ch] = phs[main_ch] - parse_vlc(&s->gb, &ff_dca_vlc_dph,  1);
                } else {
                    amp[ch] = 0;
                    phs[ch] = 0;
                }
            }

            if (amp[main_ch]) {
                // Allocate new tone
                DCALbrTone *t = &s->tones[s->ntones];
                s->ntones = (s->ntones + 1) & (DCA_LBR_TONES - 1);

                t->x_freq = freq >> (5 - group);
                t->f_delt = (freq & ((1 << (5 - group)) - 1)) << group;
                t->ph_rot = 256 - (t->x_freq & 1) * 128 - t->f_delt * 4;

                shift = ff_dca_ph0_shift[(t->x_freq & 3) * 2 + (freq & 1)]
                    - ((t->ph_rot << (5 - group)) - t->ph_rot);

                for (ch = 0; ch < s->nchannels; ch++) {
                    t->amp[ch] = amp[ch] < AMP_MAX ? amp[ch] : 0;
                    t->phs[ch] = 128 - phs[ch] * 32 + shift;
                }
            }
        }

        s->tonal_bounds[group][sf_idx][1] = s->ntones;
    }

    return 0;
}

static int parse_tonal_chunk(DCALbrDecoder *s, LBRChunk *chunk)
{
    int sb, group;

    if (!chunk->len)
        return 0;

    if (init_get_bits8(&s->gb, chunk->data, chunk->len) < 0)
        return -1;

    // Scale factors
    if (chunk->id == LBR_CHUNK_SCF || chunk->id == LBR_CHUNK_TONAL_SCF) {
        if (get_bits_left(&s->gb) < 36) {
            av_log(s->avctx, AV_LOG_ERROR, "Tonal scale factor chunk too short\n");
            return -1;
        }
        for (sb = 0; sb < 6; sb++)
            s->tonal_scf[sb] = get_bits(&s->gb, 6);
    }

    // Tonal groups
    if (chunk->id == LBR_CHUNK_TONAL || chunk->id == LBR_CHUNK_TONAL_SCF)
        for (group = 0; group < 5; group++)
            if (parse_tonal(s, group) < 0)
                return -1;

    return 0;
}

static int parse_tonal_group(DCALbrDecoder *s, LBRChunk *chunk)
{
    if (!chunk->len)
        return 0;

    if (init_get_bits8(&s->gb, chunk->data, chunk->len) < 0)
        return -1;

    return parse_tonal(s, chunk->id);
}

/**
 * Check point to ensure that enough bits are left. Aborts decoding
 * by skipping to the end of chunk otherwise.
 */
static int ensure_bits(GetBitContext *s, int n)
{
    int left = get_bits_left(s);
    if (left < 0)
        return -1;
    if (left < n) {
        skip_bits_long(s, left);
        return 1;
    }
    return 0;
}

static int parse_scale_factors(DCALbrDecoder *s, uint8_t *scf)
{
    int i, sf, prev, next, dist;

    // Truncated scale factors remain zero
    if (ensure_bits(&s->gb, 20))
        return 0;

    // Initial scale factor
    prev = parse_vlc(&s->gb, &ff_dca_vlc_fst_rsd_amp, 2);

    for (sf = 0; sf < 7; sf += dist) {
        scf[sf] = prev; // Store previous value

        if (ensure_bits(&s->gb, 20))
            return 0;

        // Interpolation distance
        dist = parse_vlc(&s->gb, &ff_dca_vlc_rsd_apprx, 1) + 1;
        if (dist > 7 - sf) {
            av_log(s->avctx, AV_LOG_ERROR, "Invalid scale factor distance\n");
            return -1;
        }

        if (ensure_bits(&s->gb, 20))
            return 0;

        // Final interpolation point
        next = parse_vlc(&s->gb, &ff_dca_vlc_rsd_amp, 2);

        if (next & 1)
            next = prev + ((next + 1) >> 1);
        else
            next = prev - ( next      >> 1);

        // Interpolate
        switch (dist) {
        case 2:
            if (next > prev)
                scf[sf + 1] = prev + ((next - prev) >> 1);
            else
                scf[sf + 1] = prev - ((prev - next) >> 1);
            break;

        case 4:
            if (next > prev) {
                scf[sf + 1] = prev + ( (next - prev)      >> 2);
                scf[sf + 2] = prev + ( (next - prev)      >> 1);
                scf[sf + 3] = prev + (((next - prev) * 3) >> 2);
            } else {
                scf[sf + 1] = prev - ( (prev - next)      >> 2);
                scf[sf + 2] = prev - ( (prev - next)      >> 1);
                scf[sf + 3] = prev - (((prev - next) * 3) >> 2);
            }
            break;

        default:
            for (i = 1; i < dist; i++)
                scf[sf + i] = prev + (next - prev) * i / dist;
            break;
        }

        prev = next;
    }

    scf[sf] = next; // Store final value

    return 0;
}

static int parse_st_code(GetBitContext *s, int min_v)
{
    unsigned int v = parse_vlc(s, &ff_dca_vlc_st_grid, 2) + min_v;

    if (v & 1)
        v = 16 + (v >> 1);
    else
        v = 16 - (v >> 1);

    if (v >= FF_ARRAY_ELEMS(ff_dca_st_coeff))
        v = 16;
    return v;
}

static int parse_grid_1_chunk(DCALbrDecoder *s, LBRChunk *chunk, int ch1, int ch2)
{
    int ch, sb, sf, nsubbands;

    if (!chunk->len)
        return 0;

    if (init_get_bits8(&s->gb, chunk->data, chunk->len) < 0)
        return -1;

    // Scale factors
    nsubbands = ff_dca_scf_to_grid_1[s->nsubbands - 1] + 1;
    for (sb = 2; sb < nsubbands; sb++) {
        if (parse_scale_factors(s, s->grid_1_scf[ch1][sb]) < 0)
            return -1;
        if (ch1 != ch2 && ff_dca_grid_1_to_scf[sb] < s->min_mono_subband
            && parse_scale_factors(s, s->grid_1_scf[ch2][sb]) < 0)
            return -1;
    }

    if (get_bits_left(&s->gb) < 1)
        return 0;   // Should not happen, but a sample exists that proves otherwise

    // Average values for third grid
    for (sb = 0; sb < s->nsubbands - 4; sb++) {
        s->grid_3_avg[ch1][sb] = parse_vlc(&s->gb, &ff_dca_vlc_avg_g3, 2) - 16;
        if (ch1 != ch2) {
            if (sb + 4 < s->min_mono_subband)
                s->grid_3_avg[ch2][sb] = parse_vlc(&s->gb, &ff_dca_vlc_avg_g3, 2) - 16;
            else
                s->grid_3_avg[ch2][sb] = s->grid_3_avg[ch1][sb];
        }
    }

    if (get_bits_left(&s->gb) < 0) {
        av_log(s->avctx, AV_LOG_ERROR, "First grid chunk too short\n");
        return -1;
    }

    // Stereo image for partial mono mode
    if (ch1 != ch2) {
        int min_v[2];

        if (ensure_bits(&s->gb, 8))
            return 0;

        min_v[0] = get_bits(&s->gb, 4);
        min_v[1] = get_bits(&s->gb, 4);

        nsubbands = (s->nsubbands - s->min_mono_subband + 3) / 4;
        for (sb = 0; sb < nsubbands; sb++)
            for (ch = ch1; ch <= ch2; ch++)
                for (sf = 1; sf <= 4; sf++)
                    s->part_stereo[ch][sb][sf] = parse_st_code(&s->gb, min_v[ch - ch1]);

        if (get_bits_left(&s->gb) >= 0)
            s->part_stereo_pres |= 1 << ch1;
    }

    // Low resolution spatial information is not decoded

    return 0;
}

static int parse_grid_1_sec_ch(DCALbrDecoder *s, int ch2)
{
    int sb, nsubbands;

    // Scale factors
    nsubbands = ff_dca_scf_to_grid_1[s->nsubbands - 1] + 1;
    for (sb = 2; sb < nsubbands; sb++) {
        if (ff_dca_grid_1_to_scf[sb] >= s->min_mono_subband
            && parse_scale_factors(s, s->grid_1_scf[ch2][sb]) < 0)
            return -1;
    }

    // Average values for third grid
    for (sb = 0; sb < s->nsubbands - 4; sb++) {
        if (sb + 4 >= s->min_mono_subband) {
            if (ensure_bits(&s->gb, 20))
                return 0;
            s->grid_3_avg[ch2][sb] = parse_vlc(&s->gb, &ff_dca_vlc_avg_g3, 2) - 16;
        }
    }

    return 0;
}

static void parse_grid_3(DCALbrDecoder *s, int ch1, int ch2, int sb, int flag)
{
    int i, ch;

    for (ch = ch1; ch <= ch2; ch++) {
        if ((ch != ch1 && sb + 4 >= s->min_mono_subband) != flag)
            continue;

        if (s->grid_3_pres[ch] & (1U << sb))
            continue;   // Already parsed

        for (i = 0; i < 8; i++) {
            if (ensure_bits(&s->gb, 20))
                return;
            s->grid_3_scf[ch][sb][i] = parse_vlc(&s->gb, &ff_dca_vlc_grid_3, 2) - 16;
        }

        // Flag scale factors for this subband parsed
        s->grid_3_pres[ch] |= 1U << sb;
    }
}

static float lbr_rand(DCALbrDecoder *s, int sb)
{
    s->lbr_rand = 1103515245U * s->lbr_rand + 12345U;
    return s->lbr_rand * s->sb_scf[sb];
}

/**
 * Parse time samples for one subband, filling truncated samples with randomness
 */
static void parse_ch(DCALbrDecoder *s, int ch, int sb, int quant_level, int flag)
{
    float *samples = s->time_samples[ch][sb];
    int i, j, code, nblocks, coding_method;

    if (ensure_bits(&s->gb, 20))
        return; // Too few bits left

    coding_method = get_bits1(&s->gb);

    switch (quant_level) {
    case 1:
        nblocks = FFMIN(get_bits_left(&s->gb) / 8, DCA_LBR_TIME_SAMPLES / 8);
        for (i = 0; i < nblocks; i++, samples += 8) {
            code = get_bits(&s->gb, 8);
            for (j = 0; j < 8; j++)
                samples[j] = ff_dca_rsd_level_2a[(code >> j) & 1];
        }
        i = nblocks * 8;
        break;

    case 2:
        if (coding_method) {
            for (i = 0; i < DCA_LBR_TIME_SAMPLES && get_bits_left(&s->gb) >= 2; i++) {
                if (get_bits1(&s->gb))
                    samples[i] = ff_dca_rsd_level_2b[get_bits1(&s->gb)];
                else
                    samples[i] = 0;
            }
        } else {
            nblocks = FFMIN(get_bits_left(&s->gb) / 8, (DCA_LBR_TIME_SAMPLES + 4) / 5);
            for (i = 0; i < nblocks; i++, samples += 5) {
                code = ff_dca_rsd_pack_5_in_8[get_bits(&s->gb, 8)];
                for (j = 0; j < 5; j++)
                    samples[j] = ff_dca_rsd_level_3[(code >> j * 2) & 3];
            }
            i = nblocks * 5;
        }
        break;

    case 3:
        nblocks = FFMIN(get_bits_left(&s->gb) / 7, (DCA_LBR_TIME_SAMPLES + 2) / 3);
        for (i = 0; i < nblocks; i++, samples += 3) {
            code = get_bits(&s->gb, 7);
            for (j = 0; j < 3; j++)
                samples[j] = ff_dca_rsd_level_5[ff_dca_rsd_pack_3_in_7[code][j]];
        }
        i = nblocks * 3;
        break;

    case 4:
        for (i = 0; i < DCA_LBR_TIME_SAMPLES && get_bits_left(&s->gb) >= 6; i++)
            samples[i] = ff_dca_rsd_level_8[get_vlc2(&s->gb, ff_dca_vlc_rsd.table, 6, 1)];
        break;

    case 5:
        nblocks = FFMIN(get_bits_left(&s->gb) / 4, DCA_LBR_TIME_SAMPLES);
        for (i = 0; i < nblocks; i++)
            samples[i] = ff_dca_rsd_level_16[get_bits(&s->gb, 4)];
        break;

    default:
        av_assert0(0);
    }

    if (flag && get_bits_left(&s->gb) < 20)
        return; // Skip incomplete mono subband

    for (; i < DCA_LBR_TIME_SAMPLES; i++)
        s->time_samples[ch][sb][i] = lbr_rand(s, sb);

    s->ch_pres[ch] |= 1U << sb;
}

static int parse_ts(DCALbrDecoder *s, int ch1, int ch2,
                    int start_sb, int end_sb, int flag)
{
    int sb, sb_g3, sb_reorder, quant_level;

    for (sb = start_sb; sb < end_sb; sb++) {
        // Subband number before reordering
        if (sb < 6) {
            sb_reorder = sb;
        } else if (flag && sb < s->max_mono_subband) {
            sb_reorder = s->sb_indices[sb];
        } else {
            if (ensure_bits(&s->gb, 28))
                break;
            sb_reorder = get_bits(&s->gb, s->limited_range + 3);
            if (sb_reorder < 6)
                sb_reorder = 6;
            s->sb_indices[sb] = sb_reorder;
        }
        if (sb_reorder >= s->nsubbands)
            return -1;

        // Third grid scale factors
        if (sb == 12) {
            for (sb_g3 = 0; sb_g3 < s->g3_avg_only_start_sb - 4; sb_g3++)
                parse_grid_3(s, ch1, ch2, sb_g3, flag);
        } else if (sb < 12 && sb_reorder >= 4) {
            parse_grid_3(s, ch1, ch2, sb_reorder - 4, flag);
        }

        // Secondary channel flags
        if (ch1 != ch2) {
            if (ensure_bits(&s->gb, 20))
                break;
            if (!flag || sb_reorder >= s->max_mono_subband)
                s->sec_ch_sbms[ch1 / 2][sb_reorder] = get_bits(&s->gb, 8);
            if (flag && sb_reorder >= s->min_mono_subband)
                s->sec_ch_lrms[ch1 / 2][sb_reorder] = get_bits(&s->gb, 8);
        }

        quant_level = s->quant_levels[ch1 / 2][sb];
        if (!quant_level)
            return -1;

        // Time samples for one or both channels
        if (sb < s->max_mono_subband && sb_reorder >= s->min_mono_subband) {
            if (!flag)
                parse_ch(s, ch1, sb_reorder, quant_level, 0);
            else if (ch1 != ch2)
                parse_ch(s, ch2, sb_reorder, quant_level, 1);
        } else {
            parse_ch(s, ch1, sb_reorder, quant_level, 0);
            if (ch1 != ch2)
                parse_ch(s, ch2, sb_reorder, quant_level, 0);
        }
    }

    return 0;
}

/**
 * Convert from reflection coefficients to direct form coefficients
 */
static void convert_lpc(float *coeff, const int *codes)
{
    int i, j;

    for (i = 0; i < 8; i++) {
        float rc = lpc_tab[codes[i]];
        for (j = 0; j < (i + 1) / 2; j++) {
            float tmp1 = coeff[    j    ];
            float tmp2 = coeff[i - j - 1];
            coeff[    j    ] = tmp1 + rc * tmp2;
            coeff[i - j - 1] = tmp2 + rc * tmp1;
        }
        coeff[i] = rc;
    }
}

static int parse_lpc(DCALbrDecoder *s, int ch1, int ch2, int start_sb, int end_sb)
{
    int f = s->framenum & 1;
    int i, sb, ch, codes[16];

    // First two subbands have two sets of coefficients, third subband has one
    for (sb = start_sb; sb < end_sb; sb++) {
        int ncodes = 8 * (1 + (sb < 2));
        for (ch = ch1; ch <= ch2; ch++) {
            if (ensure_bits(&s->gb, 4 * ncodes))
                return 0;
            for (i = 0; i < ncodes; i++)
                codes[i] = get_bits(&s->gb, 4);
            for (i = 0; i < ncodes / 8; i++)
                convert_lpc(s->lpc_coeff[f][ch][sb][i], &codes[i * 8]);
        }
    }

    return 0;
}

static int parse_high_res_grid(DCALbrDecoder *s, LBRChunk *chunk, int ch1, int ch2)
{
    int quant_levels[DCA_LBR_SUBBANDS];
    int sb, ch, ol, st, max_sb, profile;

    if (!chunk->len)
        return 0;

    if (init_get_bits8(&s->gb, chunk->data, chunk->len) < 0)
        return -1;

    // Quantizer profile
    profile = get_bits(&s->gb, 8);
    // Overall level
    ol = (profile >> 3) & 7;
    // Steepness
    st = profile >> 6;
    // Max energy subband
    max_sb = profile & 7;

    // Calculate quantization levels
    for (sb = 0; sb < s->nsubbands; sb++) {
        int f = sb * s->limited_rate / s->nsubbands;
        int a = 18000 / (12 * f / 1000 + 100 + 40 * st) + 20 * ol;
        if (a <= 95)
            quant_levels[sb] = 1;
        else if (a <= 140)
            quant_levels[sb] = 2;
        else if (a <= 180)
            quant_levels[sb] = 3;
        else if (a <= 230)
            quant_levels[sb] = 4;
        else
            quant_levels[sb] = 5;
    }

    // Reorder quantization levels for lower subbands
    for (sb = 0; sb < 8; sb++)
        s->quant_levels[ch1 / 2][sb] = quant_levels[ff_dca_sb_reorder[max_sb][sb]];
    for (; sb < s->nsubbands; sb++)
        s->quant_levels[ch1 / 2][sb] = quant_levels[sb];

    // LPC for the first two subbands
    if (parse_lpc(s, ch1, ch2, 0, 2) < 0)
        return -1;

    // Time-samples for the first two subbands of main channel
    if (parse_ts(s, ch1, ch2, 0, 2, 0) < 0)
        return -1;

    // First two bands of the first grid
    for (sb = 0; sb < 2; sb++)
        for (ch = ch1; ch <= ch2; ch++)
            if (parse_scale_factors(s, s->grid_1_scf[ch][sb]) < 0)
                return -1;

    return 0;
}

static int parse_grid_2(DCALbrDecoder *s, int ch1, int ch2,
                        int start_sb, int end_sb, int flag)
{
    int i, j, sb, ch, nsubbands;

    nsubbands = ff_dca_scf_to_grid_2[s->nsubbands - 1] + 1;
    if (end_sb > nsubbands)
        end_sb = nsubbands;

    for (sb = start_sb; sb < end_sb; sb++) {
        for (ch = ch1; ch <= ch2; ch++) {
            uint8_t *g2_scf = s->grid_2_scf[ch][sb];

            if ((ch != ch1 && ff_dca_grid_2_to_scf[sb] >= s->min_mono_subband) != flag) {
                if (!flag)
                    memcpy(g2_scf, s->grid_2_scf[ch1][sb], 64);
                continue;
            }

            // Scale factors in groups of 8
            for (i = 0; i < 8; i++, g2_scf += 8) {
                if (get_bits_left(&s->gb) < 1) {
                    memset(g2_scf, 0, 64 - i * 8);
                    break;
                }
                // Bit indicating if whole group has zero values
                if (get_bits1(&s->gb)) {
                    for (j = 0; j < 8; j++) {
                        if (ensure_bits(&s->gb, 20))
                            break;
                        g2_scf[j] = parse_vlc(&s->gb, &ff_dca_vlc_grid_2, 2);
                    }
                } else {
                    memset(g2_scf, 0, 8);
                }
            }
        }
    }

    return 0;
}

static int parse_ts1_chunk(DCALbrDecoder *s, LBRChunk *chunk, int ch1, int ch2)
{
    if (!chunk->len)
        return 0;
    if (init_get_bits8(&s->gb, chunk->data, chunk->len) < 0)
        return -1;
    if (parse_lpc(s, ch1, ch2, 2, 3) < 0)
        return -1;
    if (parse_ts(s, ch1, ch2, 2, 4, 0) < 0)
        return -1;
    if (parse_grid_2(s, ch1, ch2, 0, 1, 0) < 0)
        return -1;
    if (parse_ts(s, ch1, ch2, 4, 6, 0) < 0)
        return -1;
    return 0;
}

static int parse_ts2_chunk(DCALbrDecoder *s, LBRChunk *chunk, int ch1, int ch2)
{
    if (!chunk->len)
        return 0;
    if (init_get_bits8(&s->gb, chunk->data, chunk->len) < 0)
        return -1;
    if (parse_grid_2(s, ch1, ch2, 1, 3, 0) < 0)
        return -1;
    if (parse_ts(s, ch1, ch2, 6, s->max_mono_subband, 0) < 0)
        return -1;
    if (ch1 != ch2) {
        if (parse_grid_1_sec_ch(s, ch2) < 0)
            return -1;
        if (parse_grid_2(s, ch1, ch2, 0, 3, 1) < 0)
            return -1;
    }
    if (parse_ts(s, ch1, ch2, s->min_mono_subband, s->nsubbands, 1) < 0)
        return -1;
    return 0;
}

static int init_sample_rate(DCALbrDecoder *s)
{
    double scale = (-1.0 / (1 << 17)) * sqrt(1 << (2 - s->limited_range));
    int i, br_per_ch = s->bit_rate_scaled / s->nchannels_total;

    ff_mdct_end(&s->imdct);

    if (ff_mdct_init(&s->imdct, s->freq_range + 6, 1, scale) < 0)
        return -1;

    for (i = 0; i < 32 << s->freq_range; i++)
        s->window[i] = ff_dca_long_window[i << (2 - s->freq_range)];

    if (br_per_ch < 14000)
        scale = 0.85;
    else if (br_per_ch < 32000)
        scale = (br_per_ch - 14000) * (1.0 / 120000) + 0.85;
    else
        scale = 1.0;

    scale *= 1.0 / INT_MAX;

    for (i = 0; i < s->nsubbands; i++) {
        if (i < 2)
            s->sb_scf[i] = 0;   // The first two subbands are always zero
        else if (i < 5)
            s->sb_scf[i] = (i - 1) * 0.25 * 0.785 * scale;
        else
            s->sb_scf[i] = 0.785 * scale;
    }

    s->lfe_scale = (16 << s->freq_range) * 0.0000078265894;

    return 0;
}

static int alloc_sample_buffer(DCALbrDecoder *s)
{
    // Reserve space for history and padding
    int nchsamples = DCA_LBR_TIME_SAMPLES + DCA_LBR_TIME_HISTORY * 2;
    int nsamples = nchsamples * s->nchannels * s->nsubbands;
    int ch, sb;
    float *ptr;

    // Reallocate time sample buffer
    av_fast_mallocz(&s->ts_buffer, &s->ts_size, nsamples * sizeof(float));
    if (!s->ts_buffer)
        return -1;

    ptr = s->ts_buffer + DCA_LBR_TIME_HISTORY;
    for (ch = 0; ch < s->nchannels; ch++) {
        for (sb = 0; sb < s->nsubbands; sb++) {
            s->time_samples[ch][sb] = ptr;
            ptr += nchsamples;
        }
    }

    return 0;
}

static int parse_decoder_init(DCALbrDecoder *s, GetByteContext *gb)
{
    int old_rate = s->sample_rate;
    int old_band_limit = s->band_limit;
    int old_nchannels = s->nchannels;
    int version, bit_rate_hi;
    unsigned int sr_code;

    // Sample rate of LBR audio
    sr_code = bytestream2_get_byte(gb);
    if (sr_code >= FF_ARRAY_ELEMS(ff_dca_sampling_freqs)) {
        av_log(s->avctx, AV_LOG_ERROR, "Invalid LBR sample rate\n");
        return AVERROR_INVALIDDATA;
    }
    s->sample_rate = ff_dca_sampling_freqs[sr_code];
    if (s->sample_rate > 48000) {
        avpriv_report_missing_feature(s->avctx, "%d Hz LBR sample rate", s->sample_rate);
        return AVERROR_PATCHWELCOME;
    }

    // LBR speaker mask
    s->ch_mask = bytestream2_get_le16(gb);
    if (!(s->ch_mask & 0x7)) {
        avpriv_report_missing_feature(s->avctx, "LBR channel mask %#x", s->ch_mask);
        return AVERROR_PATCHWELCOME;
    }
    if ((s->ch_mask & 0xfff0) && !(s->warned & 1)) {
        avpriv_report_missing_feature(s->avctx, "LBR channel mask %#x", s->ch_mask);
        s->warned |= 1;
    }

    // LBR bitstream version
    version = bytestream2_get_le16(gb);
    if ((version & 0xff00) != 0x0800) {
        avpriv_report_missing_feature(s->avctx, "LBR stream version %#x", version);
        return AVERROR_PATCHWELCOME;
    }

    // Flags for LBR decoder initialization
    s->flags = bytestream2_get_byte(gb);
    if (s->flags & LBR_FLAG_DMIX_MULTI_CH) {
        avpriv_report_missing_feature(s->avctx, "LBR multi-channel downmix");
        return AVERROR_PATCHWELCOME;
    }
    if ((s->flags & LBR_FLAG_LFE_PRESENT) && s->sample_rate != 48000) {
        if (!(s->warned & 2)) {
            avpriv_report_missing_feature(s->avctx, "%d Hz LFE interpolation", s->sample_rate);
            s->warned |= 2;
        }
        s->flags &= ~LBR_FLAG_LFE_PRESENT;
    }

    // Most significant bit rate nibbles
    bit_rate_hi = bytestream2_get_byte(gb);

    // Least significant original bit rate word
    s->bit_rate_orig = bytestream2_get_le16(gb) | ((bit_rate_hi & 0x0F) << 16);

    // Least significant scaled bit rate word
    s->bit_rate_scaled = bytestream2_get_le16(gb) | ((bit_rate_hi & 0xF0) << 12);

    // Setup number of fullband channels
    s->nchannels_total = ff_dca_count_chs_for_mask(s->ch_mask & ~DCA_SPEAKER_PAIR_LFE1);
    s->nchannels = FFMIN(s->nchannels_total, DCA_LBR_CHANNELS);

    // Setup band limit
    switch (s->flags & LBR_FLAG_BAND_LIMIT_MASK) {
    case LBR_FLAG_BAND_LIMIT_NONE:
        s->band_limit = 0;
        break;
    case LBR_FLAG_BAND_LIMIT_1_2:
        s->band_limit = 1;
        break;
    case LBR_FLAG_BAND_LIMIT_1_4:
        s->band_limit = 2;
        break;
    default:
        avpriv_report_missing_feature(s->avctx, "LBR band limit %#x", s->flags & LBR_FLAG_BAND_LIMIT_MASK);
        return AVERROR_PATCHWELCOME;
    }

    // Setup frequency range
    s->freq_range = ff_dca_freq_ranges[sr_code];

    // Setup resolution profile
    if (s->bit_rate_orig >= 44000 * (s->nchannels_total + 2))
        s->res_profile = 2;
    else if (s->bit_rate_orig >= 25000 * (s->nchannels_total + 2))
        s->res_profile = 1;
    else
        s->res_profile = 0;

    // Setup limited sample rate, number of subbands, etc
    s->limited_rate = s->sample_rate >> s->band_limit;
    s->limited_range = s->freq_range - s->band_limit;
    if (s->limited_range < 0) {
        av_log(s->avctx, AV_LOG_ERROR, "Invalid LBR band limit for frequency range\n");
        return AVERROR_INVALIDDATA;
    }

    s->nsubbands = 8 << s->limited_range;

    s->g3_avg_only_start_sb = s->nsubbands * ff_dca_avg_g3_freqs[s->res_profile] / (s->limited_rate / 2);
    if (s->g3_avg_only_start_sb > s->nsubbands)
        s->g3_avg_only_start_sb = s->nsubbands;

    s->min_mono_subband = s->nsubbands *  2000 / (s->limited_rate / 2);
    if (s->min_mono_subband > s->nsubbands)
        s->min_mono_subband = s->nsubbands;

    s->max_mono_subband = s->nsubbands * 14000 / (s->limited_rate / 2);
    if (s->max_mono_subband > s->nsubbands)
        s->max_mono_subband = s->nsubbands;

    // Handle change of sample rate
    if ((old_rate != s->sample_rate || old_band_limit != s->band_limit) && init_sample_rate(s) < 0)
        return AVERROR(ENOMEM);

    // Setup stereo downmix
    if (s->flags & LBR_FLAG_DMIX_STEREO) {
        DCAContext *dca = s->avctx->priv_data;

        if (s->nchannels_total < 3 || s->nchannels_total > DCA_LBR_CHANNELS_TOTAL - 2) {
            av_log(s->avctx, AV_LOG_ERROR, "Invalid number of channels for LBR stereo downmix\n");
            return AVERROR_INVALIDDATA;
        }

        // This decoder doesn't support ECS chunk
        if (dca->request_channel_layout != DCA_SPEAKER_LAYOUT_STEREO && !(s->warned & 4)) {
            avpriv_report_missing_feature(s->avctx, "Embedded LBR stereo downmix");
            s->warned |= 4;
        }

        // Account for extra downmixed channel pair
        s->nchannels_total += 2;
        s->nchannels = 2;
        s->ch_mask = DCA_SPEAKER_PAIR_LR;
        s->flags &= ~LBR_FLAG_LFE_PRESENT;
    }

    // Handle change of sample rate or number of channels
    if (old_rate != s->sample_rate
        || old_band_limit != s->band_limit
        || old_nchannels != s->nchannels) {
        if (alloc_sample_buffer(s) < 0)
            return AVERROR(ENOMEM);
        ff_dca_lbr_flush(s);
    }

    return 0;
}

int ff_dca_lbr_parse(DCALbrDecoder *s, uint8_t *data, DCAExssAsset *asset)
{
    struct {
        LBRChunk    lfe;
        LBRChunk    tonal;
        LBRChunk    tonal_grp[5];
        LBRChunk    grid1[DCA_LBR_CHANNELS / 2];
        LBRChunk    hr_grid[DCA_LBR_CHANNELS / 2];
        LBRChunk    ts1[DCA_LBR_CHANNELS / 2];
        LBRChunk    ts2[DCA_LBR_CHANNELS / 2];
    } chunk = { {0} };

    GetByteContext gb;

    int i, ch, sb, sf, ret, group, chunk_id, chunk_len;

    bytestream2_init(&gb, data + asset->lbr_offset, asset->lbr_size);

    // LBR sync word
    if (bytestream2_get_be32(&gb) != DCA_SYNCWORD_LBR) {
        av_log(s->avctx, AV_LOG_ERROR, "Invalid LBR sync word\n");
        return AVERROR_INVALIDDATA;
    }

    // LBR header type
    switch (bytestream2_get_byte(&gb)) {
    case DCA_LBR_HEADER_SYNC_ONLY:
        if (!s->sample_rate) {
            av_log(s->avctx, AV_LOG_ERROR, "LBR decoder not initialized\n");
            return AVERROR_INVALIDDATA;
        }
        break;
    case DCA_LBR_HEADER_DECODER_INIT:
        if ((ret = parse_decoder_init(s, &gb)) < 0) {
            s->sample_rate = 0;
            return ret;
        }
        break;
    default:
        av_log(s->avctx, AV_LOG_ERROR, "Invalid LBR header type\n");
        return AVERROR_INVALIDDATA;
    }

    // LBR frame chunk header
    chunk_id = bytestream2_get_byte(&gb);
    chunk_len = (chunk_id & 0x80) ? bytestream2_get_be16(&gb) : bytestream2_get_byte(&gb);

    if (chunk_len > bytestream2_get_bytes_left(&gb)) {
        chunk_len = bytestream2_get_bytes_left(&gb);
        av_log(s->avctx, AV_LOG_WARNING, "LBR frame chunk was truncated\n");
        if (s->avctx->err_recognition & AV_EF_EXPLODE)
            return AVERROR_INVALIDDATA;
    }

    bytestream2_init(&gb, gb.buffer, chunk_len);

    switch (chunk_id & 0x7f) {
    case LBR_CHUNK_FRAME:
        if (s->avctx->err_recognition & (AV_EF_CRCCHECK | AV_EF_CAREFUL)) {
            int checksum = bytestream2_get_be16(&gb);
            uint16_t res = chunk_id;
            res += (chunk_len >> 8) & 0xff;
            res += chunk_len & 0xff;
            for (i = 0; i < chunk_len - 2; i++)
                res += gb.buffer[i];
            if (checksum != res) {
                av_log(s->avctx, AV_LOG_WARNING, "Invalid LBR checksum\n");
                if (s->avctx->err_recognition & AV_EF_EXPLODE)
                    return AVERROR_INVALIDDATA;
            }
        } else {
            bytestream2_skip(&gb, 2);
        }
        break;
    case LBR_CHUNK_FRAME_NO_CSUM:
        break;
    default:
        av_log(s->avctx, AV_LOG_ERROR, "Invalid LBR frame chunk ID\n");
        return AVERROR_INVALIDDATA;
    }

    // Clear current frame
    memset(s->quant_levels, 0, sizeof(s->quant_levels));
    memset(s->sb_indices, 0xff, sizeof(s->sb_indices));
    memset(s->sec_ch_sbms, 0, sizeof(s->sec_ch_sbms));
    memset(s->sec_ch_lrms, 0, sizeof(s->sec_ch_lrms));
    memset(s->ch_pres, 0, sizeof(s->ch_pres));
    memset(s->grid_1_scf, 0, sizeof(s->grid_1_scf));
    memset(s->grid_2_scf, 0, sizeof(s->grid_2_scf));
    memset(s->grid_3_avg, 0, sizeof(s->grid_3_avg));
    memset(s->grid_3_scf, 0, sizeof(s->grid_3_scf));
    memset(s->grid_3_pres, 0, sizeof(s->grid_3_pres));
    memset(s->tonal_scf, 0, sizeof(s->tonal_scf));
    memset(s->lfe_data, 0, sizeof(s->lfe_data));
    s->part_stereo_pres = 0;
    s->framenum = (s->framenum + 1) & 31;

    for (ch = 0; ch < s->nchannels; ch++) {
        for (sb = 0; sb < s->nsubbands / 4; sb++) {
            s->part_stereo[ch][sb][0] = s->part_stereo[ch][sb][4];
            s->part_stereo[ch][sb][4] = 16;
        }
    }

    memset(s->lpc_coeff[s->framenum & 1], 0, sizeof(s->lpc_coeff[0]));

    for (group = 0; group < 5; group++) {
        for (sf = 0; sf < 1 << group; sf++) {
            int sf_idx = ((s->framenum << group) + sf) & 31;
            s->tonal_bounds[group][sf_idx][0] =
            s->tonal_bounds[group][sf_idx][1] = s->ntones;
        }
    }

    // Parse chunk headers
    while (bytestream2_get_bytes_left(&gb) > 0) {
        chunk_id = bytestream2_get_byte(&gb);
        chunk_len = (chunk_id & 0x80) ? bytestream2_get_be16(&gb) : bytestream2_get_byte(&gb);
        chunk_id &= 0x7f;

        if (chunk_len > bytestream2_get_bytes_left(&gb)) {
            chunk_len = bytestream2_get_bytes_left(&gb);
            av_log(s->avctx, AV_LOG_WARNING, "LBR chunk %#x was truncated\n", chunk_id);
            if (s->avctx->err_recognition & AV_EF_EXPLODE)
                return AVERROR_INVALIDDATA;
        }

        switch (chunk_id) {
        case LBR_CHUNK_LFE:
            chunk.lfe.len  = chunk_len;
            chunk.lfe.data = gb.buffer;
            break;

        case LBR_CHUNK_SCF:
        case LBR_CHUNK_TONAL:
        case LBR_CHUNK_TONAL_SCF:
            chunk.tonal.id   = chunk_id;
            chunk.tonal.len  = chunk_len;
            chunk.tonal.data = gb.buffer;
            break;

        case LBR_CHUNK_TONAL_GRP_1:
        case LBR_CHUNK_TONAL_GRP_2:
        case LBR_CHUNK_TONAL_GRP_3:
        case LBR_CHUNK_TONAL_GRP_4:
        case LBR_CHUNK_TONAL_GRP_5:
            i = LBR_CHUNK_TONAL_GRP_5 - chunk_id;
            chunk.tonal_grp[i].id   = i;
            chunk.tonal_grp[i].len  = chunk_len;
            chunk.tonal_grp[i].data = gb.buffer;
            break;

        case LBR_CHUNK_TONAL_SCF_GRP_1:
        case LBR_CHUNK_TONAL_SCF_GRP_2:
        case LBR_CHUNK_TONAL_SCF_GRP_3:
        case LBR_CHUNK_TONAL_SCF_GRP_4:
        case LBR_CHUNK_TONAL_SCF_GRP_5:
            i = LBR_CHUNK_TONAL_SCF_GRP_5 - chunk_id;
            chunk.tonal_grp[i].id   = i;
            chunk.tonal_grp[i].len  = chunk_len;
            chunk.tonal_grp[i].data = gb.buffer;
            break;

        case LBR_CHUNK_RES_GRID_LR:
        case LBR_CHUNK_RES_GRID_LR + 1:
        case LBR_CHUNK_RES_GRID_LR + 2:
            i = chunk_id - LBR_CHUNK_RES_GRID_LR;
            chunk.grid1[i].len  = chunk_len;
            chunk.grid1[i].data = gb.buffer;
            break;

        case LBR_CHUNK_RES_GRID_HR:
        case LBR_CHUNK_RES_GRID_HR + 1:
        case LBR_CHUNK_RES_GRID_HR + 2:
            i = chunk_id - LBR_CHUNK_RES_GRID_HR;
            chunk.hr_grid[i].len  = chunk_len;
            chunk.hr_grid[i].data = gb.buffer;
            break;

        case LBR_CHUNK_RES_TS_1:
        case LBR_CHUNK_RES_TS_1 + 1:
        case LBR_CHUNK_RES_TS_1 + 2:
            i = chunk_id - LBR_CHUNK_RES_TS_1;
            chunk.ts1[i].len  = chunk_len;
            chunk.ts1[i].data = gb.buffer;
            break;

        case LBR_CHUNK_RES_TS_2:
        case LBR_CHUNK_RES_TS_2 + 1:
        case LBR_CHUNK_RES_TS_2 + 2:
            i = chunk_id - LBR_CHUNK_RES_TS_2;
            chunk.ts2[i].len  = chunk_len;
            chunk.ts2[i].data = gb.buffer;
            break;
        }

        bytestream2_skip(&gb, chunk_len);
    }

    // Parse the chunks
    ret = parse_lfe_chunk(s, &chunk.lfe);

    ret |= parse_tonal_chunk(s, &chunk.tonal);

    for (i = 0; i < 5; i++)
        ret |= parse_tonal_group(s, &chunk.tonal_grp[i]);

    for (i = 0; i < (s->nchannels + 1) / 2; i++) {
        int ch1 = i * 2;
        int ch2 = FFMIN(ch1 + 1, s->nchannels - 1);

        if (parse_grid_1_chunk (s, &chunk.grid1  [i], ch1, ch2) < 0 ||
            parse_high_res_grid(s, &chunk.hr_grid[i], ch1, ch2) < 0) {
            ret = -1;
            continue;
        }

        // TS chunks depend on both grids. TS_2 depends on TS_1.
        if (!chunk.grid1[i].len || !chunk.hr_grid[i].len || !chunk.ts1[i].len)
            continue;

        if (parse_ts1_chunk(s, &chunk.ts1[i], ch1, ch2) < 0 ||
            parse_ts2_chunk(s, &chunk.ts2[i], ch1, ch2) < 0) {
            ret = -1;
            continue;
        }
    }

    if (ret < 0 && (s->avctx->err_recognition & AV_EF_EXPLODE))
        return AVERROR_INVALIDDATA;

    return 0;
}

/**
 * Reconstruct high-frequency resolution grid from first and third grids
 */
static void decode_grid(DCALbrDecoder *s, int ch1, int ch2)
{
    int i, ch, sb;

    for (ch = ch1; ch <= ch2; ch++) {
        for (sb = 0; sb < s->nsubbands; sb++) {
            int g1_sb = ff_dca_scf_to_grid_1[sb];

            uint8_t *g1_scf_a = s->grid_1_scf[ch][g1_sb    ];
            uint8_t *g1_scf_b = s->grid_1_scf[ch][g1_sb + 1];

            int w1 = ff_dca_grid_1_weights[g1_sb    ][sb];
            int w2 = ff_dca_grid_1_weights[g1_sb + 1][sb];

            uint8_t *hr_scf = s->high_res_scf[ch][sb];

            if (sb < 4) {
                for (i = 0; i < 8; i++) {
                    int scf = w1 * g1_scf_a[i] + w2 * g1_scf_b[i];
                    hr_scf[i] = scf >> 7;
                }
            } else {
                int8_t *g3_scf = s->grid_3_scf[ch][sb - 4];
                int g3_avg = s->grid_3_avg[ch][sb - 4];

                for (i = 0; i < 8; i++) {
                    int scf = w1 * g1_scf_a[i] + w2 * g1_scf_b[i];
                    hr_scf[i] = (scf >> 7) - g3_avg - g3_scf[i];
                }
            }
        }
    }
}

/**
 * Fill unallocated subbands with randomness
 */
static void random_ts(DCALbrDecoder *s, int ch1, int ch2)
{
    int i, j, k, ch, sb;

    for (ch = ch1; ch <= ch2; ch++) {
        for (sb = 0; sb < s->nsubbands; sb++) {
            float *samples = s->time_samples[ch][sb];

            if (s->ch_pres[ch] & (1U << sb))
                continue;   // Skip allocated subband

            if (sb < 2) {
                // The first two subbands are always zero
                memset(samples, 0, DCA_LBR_TIME_SAMPLES * sizeof(float));
            } else if (sb < 10) {
                for (i = 0; i < DCA_LBR_TIME_SAMPLES; i++)
                    samples[i] = lbr_rand(s, sb);
            } else {
                for (i = 0; i < DCA_LBR_TIME_SAMPLES / 8; i++, samples += 8) {
                    float accum[8] = { 0 };

                    // Modulate by subbands 2-5 in blocks of 8
                    for (k = 2; k < 6; k++) {
                        float *other = &s->time_samples[ch][k][i * 8];
                        for (j = 0; j < 8; j++)
                            accum[j] += fabs(other[j]);
                    }

                    for (j = 0; j < 8; j++)
                        samples[j] = (accum[j] * 0.25f + 0.5f) * lbr_rand(s, sb);
                }
            }
        }
    }
}

static void predict(float *samples, const float *coeff, int nsamples)
{
    int i, j;

    for (i = 0; i < nsamples; i++) {
        float res = 0;
        for (j = 0; j < 8; j++)
            res += coeff[j] * samples[i - j - 1];
        samples[i] -= res;
    }
}

static void synth_lpc(DCALbrDecoder *s, int ch1, int ch2, int sb)
{
    int f = s->framenum & 1;
    int ch;

    for (ch = ch1; ch <= ch2; ch++) {
        float *samples = s->time_samples[ch][sb];

        if (!(s->ch_pres[ch] & (1U << sb)))
            continue;

        if (sb < 2) {
            predict(samples,      s->lpc_coeff[f^1][ch][sb][1],  16);
            predict(samples + 16, s->lpc_coeff[f  ][ch][sb][0],  64);
            predict(samples + 80, s->lpc_coeff[f  ][ch][sb][1],  48);
        } else {
            predict(samples,      s->lpc_coeff[f^1][ch][sb][0],  16);
            predict(samples + 16, s->lpc_coeff[f  ][ch][sb][0], 112);
        }
    }
}

static void filter_ts(DCALbrDecoder *s, int ch1, int ch2)
{
    int i, j, sb, ch;

    for (sb = 0; sb < s->nsubbands; sb++) {
        // Scale factors
        for (ch = ch1; ch <= ch2; ch++) {
            float *samples = s->time_samples[ch][sb];
            uint8_t *hr_scf = s->high_res_scf[ch][sb];
            if (sb < 4) {
                for (i = 0; i < DCA_LBR_TIME_SAMPLES / 16; i++, samples += 16) {
                    unsigned int scf = hr_scf[i];
                    if (scf > AMP_MAX)
                        scf = AMP_MAX;
                    for (j = 0; j < 16; j++)
                        samples[j] *= ff_dca_quant_amp[scf];
                }
            } else {
                uint8_t *g2_scf = s->grid_2_scf[ch][ff_dca_scf_to_grid_2[sb]];
                for (i = 0; i < DCA_LBR_TIME_SAMPLES / 2; i++, samples += 2) {
                    unsigned int scf = hr_scf[i / 8] - g2_scf[i];
                    if (scf > AMP_MAX)
                        scf = AMP_MAX;
                    samples[0] *= ff_dca_quant_amp[scf];
                    samples[1] *= ff_dca_quant_amp[scf];
                }
            }
        }

        // Mid-side stereo
        if (ch1 != ch2) {
            float *samples_l = s->time_samples[ch1][sb];
            float *samples_r = s->time_samples[ch2][sb];
            int ch2_pres = s->ch_pres[ch2] & (1U << sb);

            for (i = 0; i < DCA_LBR_TIME_SAMPLES / 16; i++) {
                int sbms = (s->sec_ch_sbms[ch1 / 2][sb] >> i) & 1;
                int lrms = (s->sec_ch_lrms[ch1 / 2][sb] >> i) & 1;

                if (sb >= s->min_mono_subband) {
                    if (lrms && ch2_pres) {
                        if (sbms) {
                            for (j = 0; j < 16; j++) {
                                float tmp = samples_l[j];
                                samples_l[j] =  samples_r[j];
                                samples_r[j] = -tmp;
                            }
                        } else {
                            for (j = 0; j < 16; j++) {
                                float tmp = samples_l[j];
                                samples_l[j] =  samples_r[j];
                                samples_r[j] =  tmp;
                            }
                        }
                    } else if (!ch2_pres) {
                        if (sbms && (s->part_stereo_pres & (1 << ch1))) {
                            for (j = 0; j < 16; j++)
                                samples_r[j] = -samples_l[j];
                        } else {
                            for (j = 0; j < 16; j++)
                                samples_r[j] =  samples_l[j];
                        }
                    }
                } else if (sbms && ch2_pres) {
                    for (j = 0; j < 16; j++) {
                        float tmp = samples_l[j];
                        samples_l[j] = (tmp + samples_r[j]) * 0.5f;
                        samples_r[j] = (tmp - samples_r[j]) * 0.5f;
                    }
                }

                samples_l += 16;
                samples_r += 16;
            }
        }

        // Inverse prediction
        if (sb < 3)
            synth_lpc(s, ch1, ch2, sb);
    }
}

/**
 * Modulate by interpolated partial stereo coefficients
 */
static void decode_part_stereo(DCALbrDecoder *s, int ch1, int ch2)
{
    int i, ch, sb, sf;

    for (ch = ch1; ch <= ch2; ch++) {
        for (sb = s->min_mono_subband; sb < s->nsubbands; sb++) {
            uint8_t *pt_st = s->part_stereo[ch][(sb - s->min_mono_subband) / 4];
            float *samples = s->time_samples[ch][sb];

            if (s->ch_pres[ch2] & (1U << sb))
                continue;

            for (sf = 1; sf <= 4; sf++, samples += 32) {
                float prev = ff_dca_st_coeff[pt_st[sf - 1]];
                float next = ff_dca_st_coeff[pt_st[sf    ]];

                for (i = 0; i < 32; i++)
                    samples[i] *= (32 - i) * prev + i * next;
            }
        }
    }
}

/**
 * Synthesise tones in the given group for the given tonal subframe
 */
static void synth_tones(DCALbrDecoder *s, int ch, float *values,
                        int group, int group_sf, int synth_idx)
{
    int i, start, count;

    if (synth_idx < 0)
        return;

    start =  s->tonal_bounds[group][group_sf][0];
    count = (s->tonal_bounds[group][group_sf][1] - start) & (DCA_LBR_TONES - 1);

    for (i = 0; i < count; i++) {
        DCALbrTone *t = &s->tones[(start + i) & (DCA_LBR_TONES - 1)];

        if (t->amp[ch]) {
            float amp = ff_dca_synth_env[synth_idx] * ff_dca_quant_amp[t->amp[ch]];
            float c = amp * cos_tab[(t->phs[ch]     ) & 255];
            float s = amp * cos_tab[(t->phs[ch] + 64) & 255];
            const float *cf = ff_dca_corr_cf[t->f_delt];
            int x_freq = t->x_freq;

            switch (x_freq) {
            case 0:
                goto p0;
            case 1:
                values[3] += cf[0] * -s;
                values[2] += cf[1] *  c;
                values[1] += cf[2] *  s;
                values[0] += cf[3] * -c;
                goto p1;
            case 2:
                values[2] += cf[0] * -s;
                values[1] += cf[1] *  c;
                values[0] += cf[2] *  s;
                goto p2;
            case 3:
                values[1] += cf[0] * -s;
                values[0] += cf[1] *  c;
                goto p3;
            case 4:
                values[0] += cf[0] * -s;
                goto p4;
            }

            values[x_freq - 5] += cf[ 0] * -s;
        p4: values[x_freq - 4] += cf[ 1] *  c;
        p3: values[x_freq - 3] += cf[ 2] *  s;
        p2: values[x_freq - 2] += cf[ 3] * -c;
        p1: values[x_freq - 1] += cf[ 4] * -s;
        p0: values[x_freq    ] += cf[ 5] *  c;
            values[x_freq + 1] += cf[ 6] *  s;
            values[x_freq + 2] += cf[ 7] * -c;
            values[x_freq + 3] += cf[ 8] * -s;
            values[x_freq + 4] += cf[ 9] *  c;
            values[x_freq + 5] += cf[10] *  s;
        }

        t->phs[ch] += t->ph_rot;
    }
}

/**
 * Synthesise all tones in all groups for the given residual subframe
 */
static void base_func_synth(DCALbrDecoder *s, int ch, float *values, int sf)
{
    int group;

    // Tonal vs residual shift is 22 subframes
    for (group = 0; group < 5; group++) {
        int group_sf = (s->framenum << group) + ((sf - 22) >> (5 - group));
        int synth_idx = ((((sf - 22) & 31) << group) & 31) + (1 << group) - 1;

        synth_tones(s, ch, values, group, (group_sf - 1) & 31, 30 - synth_idx);
        synth_tones(s, ch, values, group, (group_sf    ) & 31,      synth_idx);
    }
}

static void transform_channel(DCALbrDecoder *s, int ch, float *output)
{
    LOCAL_ALIGNED_32(float, values, [DCA_LBR_SUBBANDS    ], [4]);
    LOCAL_ALIGNED_32(float, result, [DCA_LBR_SUBBANDS * 2], [4]);
    int sf, sb, nsubbands = s->nsubbands, noutsubbands = 8 << s->freq_range;

    // Clear inactive subbands
    if (nsubbands < noutsubbands)
        memset(values[nsubbands], 0, (noutsubbands - nsubbands) * sizeof(values[0]));

    for (sf = 0; sf < DCA_LBR_TIME_SAMPLES / 4; sf++) {
        // Hybrid filterbank
        s->dcadsp->lbr_bank(values, s->time_samples[ch],
                            ff_dca_bank_coeff, sf * 4, nsubbands);

        base_func_synth(s, ch, values[0], sf);

        s->imdct.imdct_calc(&s->imdct, result[0], values[0]);

        // Long window and overlap-add
        s->fdsp->vector_fmul_add(output, result[0], s->window,
                                 s->history[ch], noutsubbands * 4);
        s->fdsp->vector_fmul_reverse(s->history[ch], result[noutsubbands],
                                     s->window, noutsubbands * 4);
        output += noutsubbands * 4;
    }

    // Update history for LPC and forward MDCT
    for (sb = 0; sb < nsubbands; sb++) {
        float *samples = s->time_samples[ch][sb] - DCA_LBR_TIME_HISTORY;
        memcpy(samples, samples + DCA_LBR_TIME_SAMPLES, DCA_LBR_TIME_HISTORY * sizeof(float));
    }
}

int ff_dca_lbr_filter_frame(DCALbrDecoder *s, AVFrame *frame)
{
    AVCodecContext *avctx = s->avctx;
    int i, ret, nchannels, ch_conf = (s->ch_mask & 0x7) - 1;
    const int8_t *reorder;

    avctx->channel_layout = channel_layouts[ch_conf];
    avctx->channels = nchannels = channel_counts[ch_conf];
    avctx->sample_rate = s->sample_rate;
    avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
    avctx->bits_per_raw_sample = 0;
    avctx->profile = FF_PROFILE_DTS_EXPRESS;
    avctx->bit_rate = s->bit_rate_scaled;

    if (s->flags & LBR_FLAG_LFE_PRESENT) {
        avctx->channel_layout |= AV_CH_LOW_FREQUENCY;
        avctx->channels++;
        reorder = channel_reorder_lfe[ch_conf];
    } else {
        reorder = channel_reorder_nolfe[ch_conf];
    }

    frame->nb_samples = 1024 << s->freq_range;
    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
        return ret;

    // Filter fullband channels
    for (i = 0; i < (s->nchannels + 1) / 2; i++) {
        int ch1 = i * 2;
        int ch2 = FFMIN(ch1 + 1, s->nchannels - 1);

        decode_grid(s, ch1, ch2);

        random_ts(s, ch1, ch2);

        filter_ts(s, ch1, ch2);

        if (ch1 != ch2 && (s->part_stereo_pres & (1 << ch1)))
            decode_part_stereo(s, ch1, ch2);

        if (ch1 < nchannels)
            transform_channel(s, ch1, (float *)frame->extended_data[reorder[ch1]]);

        if (ch1 != ch2 && ch2 < nchannels)
            transform_channel(s, ch2, (float *)frame->extended_data[reorder[ch2]]);
    }

    // Interpolate LFE channel
    if (s->flags & LBR_FLAG_LFE_PRESENT) {
        s->dcadsp->lfe_iir((float *)frame->extended_data[lfe_index[ch_conf]],
                           s->lfe_data, ff_dca_lfe_iir,
                           s->lfe_history, 16 << s->freq_range);
    }

    if ((ret = ff_side_data_update_matrix_encoding(frame, AV_MATRIX_ENCODING_NONE)) < 0)
        return ret;

    return 0;
}

av_cold void ff_dca_lbr_flush(DCALbrDecoder *s)
{
    int ch, sb;

    if (!s->sample_rate)
        return;

    // Clear history
    memset(s->part_stereo, 16, sizeof(s->part_stereo));
    memset(s->lpc_coeff, 0, sizeof(s->lpc_coeff));
    memset(s->history, 0, sizeof(s->history));
    memset(s->tonal_bounds, 0, sizeof(s->tonal_bounds));
    memset(s->lfe_history, 0, sizeof(s->lfe_history));
    s->framenum = 0;
    s->ntones = 0;

    for (ch = 0; ch < s->nchannels; ch++) {
        for (sb = 0; sb < s->nsubbands; sb++) {
            float *samples = s->time_samples[ch][sb] - DCA_LBR_TIME_HISTORY;
            memset(samples, 0, DCA_LBR_TIME_HISTORY * sizeof(float));
        }
    }
}

av_cold int ff_dca_lbr_init(DCALbrDecoder *s)
{
    init_tables();

    if (!(s->fdsp = avpriv_float_dsp_alloc(0)))
        return -1;

    s->lbr_rand = 1;
    return 0;
}

av_cold void ff_dca_lbr_close(DCALbrDecoder *s)
{
    s->sample_rate = 0;

    av_freep(&s->ts_buffer);
    s->ts_size = 0;

    av_freep(&s->fdsp);
    ff_mdct_end(&s->imdct);
}
