/*
 * 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 LBRHeader {
    LBR_HEADER_SYNC_ONLY    = 1,
    LBR_HEADER_DECODER_INIT = 2
};

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 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 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);
}
