atrac3plus.c 71.2 KB
Newer Older
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
/*
 * ATRAC3+ compatible decoder
 *
 * Copyright (c) 2010-2013 Maxim Poliakovski
 *
 * This file is part of Libav.
 *
 * Libav is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * Libav is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with Libav; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/**
 * @file
 * Bitstream parser for ATRAC3+ decoder.
 */

#include "libavutil/avassert.h"
29

Maxim Polijakowski's avatar
Maxim Polijakowski committed
30
#include "avcodec.h"
31
#include "bitstream.h"
32
#include "vlc.h"
Maxim Polijakowski's avatar
Maxim Polijakowski committed
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
#include "atrac3plus.h"
#include "atrac3plus_data.h"

static VLC_TYPE tables_data[154276][2];
static VLC wl_vlc_tabs[4];
static VLC sf_vlc_tabs[8];
static VLC ct_vlc_tabs[4];
static VLC spec_vlc_tabs[112];
static VLC gain_vlc_tabs[11];
static VLC tone_vlc_tabs[7];

/**
 * Generate canonical VLC table from given descriptor.
 *
 * @param[in]     cb          ptr to codebook descriptor
 * @param[in]     xlat        ptr to translation table or NULL
 * @param[in,out] tab_offset  starting offset to the generated vlc table
 * @param[out]    out_vlc     ptr to vlc table to be generated
 */
static av_cold void build_canonical_huff(const uint8_t *cb, const uint8_t *xlat,
                                         int *tab_offset, VLC *out_vlc)
{
    int i, b;
    uint16_t codes[256];
    uint8_t bits[256];
    unsigned code = 0;
    int index = 0;
    int min_len = *cb++; // get shortest codeword length
    int max_len = *cb++; // get longest  codeword length

    for (b = min_len; b <= max_len; b++) {
        for (i = *cb++; i > 0; i--) {
            av_assert0(index < 256);
            bits[index]  = b;
            codes[index] = code++;
            index++;
        }
        code <<= 1;
    }

    out_vlc->table = &tables_data[*tab_offset];
    out_vlc->table_allocated = 1 << max_len;

    ff_init_vlc_sparse(out_vlc, max_len, index, bits, 1, 1, codes, 2, 2,
                       xlat, 1, 1, INIT_VLC_USE_NEW_STATIC);

    *tab_offset += 1 << max_len;
}

av_cold void ff_atrac3p_init_vlcs(AVCodec *codec)
{
    int i, wl_vlc_offs, ct_vlc_offs, sf_vlc_offs, tab_offset;

86 87 88
    static const int wl_nb_bits[4]  = { 2, 3, 5, 5 };
    static const int wl_nb_codes[4] = { 3, 5, 8, 8 };
    static const uint8_t * const wl_bits[4] = {
Maxim Polijakowski's avatar
Maxim Polijakowski committed
89 90 91
        atrac3p_wl_huff_bits1, atrac3p_wl_huff_bits2,
        atrac3p_wl_huff_bits3, atrac3p_wl_huff_bits4
    };
92
    static const uint8_t * const wl_codes[4] = {
Maxim Polijakowski's avatar
Maxim Polijakowski committed
93 94 95
        atrac3p_wl_huff_code1, atrac3p_wl_huff_code2,
        atrac3p_wl_huff_code3, atrac3p_wl_huff_code4
    };
96
    static const uint8_t * const wl_xlats[4] = {
Maxim Polijakowski's avatar
Maxim Polijakowski committed
97 98 99
        atrac3p_wl_huff_xlat1, atrac3p_wl_huff_xlat2, NULL, NULL
    };

100 101 102
    static const int ct_nb_bits[4]  = { 3, 4, 4, 4 };
    static const int ct_nb_codes[4] = { 4, 8, 8, 8 };
    static const uint8_t * const ct_bits[4]  = {
Maxim Polijakowski's avatar
Maxim Polijakowski committed
103 104 105
        atrac3p_ct_huff_bits1, atrac3p_ct_huff_bits2,
        atrac3p_ct_huff_bits2, atrac3p_ct_huff_bits3
    };
106
    static const uint8_t * const ct_codes[4] = {
Maxim Polijakowski's avatar
Maxim Polijakowski committed
107 108 109
        atrac3p_ct_huff_code1, atrac3p_ct_huff_code2,
        atrac3p_ct_huff_code2, atrac3p_ct_huff_code3
    };
110
    static const uint8_t * const ct_xlats[4] = {
Maxim Polijakowski's avatar
Maxim Polijakowski committed
111 112 113
        NULL, NULL, atrac3p_ct_huff_xlat1, NULL
    };

114 115 116
    static const int sf_nb_bits[8]  = {  9,  9,  9,  9,  6,  6,  7,  7 };
    static const int sf_nb_codes[8] = { 64, 64, 64, 64, 16, 16, 16, 16 };
    static const uint8_t  * const sf_bits[8]  = {
Maxim Polijakowski's avatar
Maxim Polijakowski committed
117 118 119 120
        atrac3p_sf_huff_bits1, atrac3p_sf_huff_bits1, atrac3p_sf_huff_bits2,
        atrac3p_sf_huff_bits3, atrac3p_sf_huff_bits4, atrac3p_sf_huff_bits4,
        atrac3p_sf_huff_bits5, atrac3p_sf_huff_bits6
    };
121
    static const uint16_t * const sf_codes[8] = {
Maxim Polijakowski's avatar
Maxim Polijakowski committed
122 123 124 125
        atrac3p_sf_huff_code1, atrac3p_sf_huff_code1, atrac3p_sf_huff_code2,
        atrac3p_sf_huff_code3, atrac3p_sf_huff_code4, atrac3p_sf_huff_code4,
        atrac3p_sf_huff_code5, atrac3p_sf_huff_code6
    };
126
    static const uint8_t  * const sf_xlats[8] = {
Maxim Polijakowski's avatar
Maxim Polijakowski committed
127 128 129 130
        atrac3p_sf_huff_xlat1, atrac3p_sf_huff_xlat2, NULL, NULL,
        atrac3p_sf_huff_xlat4, atrac3p_sf_huff_xlat5, NULL, NULL
    };

131
    static const uint8_t * const gain_cbs[11] = {
Maxim Polijakowski's avatar
Maxim Polijakowski committed
132 133 134 135 136 137 138
        atrac3p_huff_gain_npoints1_cb, atrac3p_huff_gain_npoints1_cb,
        atrac3p_huff_gain_lev1_cb, atrac3p_huff_gain_lev2_cb,
        atrac3p_huff_gain_lev3_cb, atrac3p_huff_gain_lev4_cb,
        atrac3p_huff_gain_loc3_cb, atrac3p_huff_gain_loc1_cb,
        atrac3p_huff_gain_loc4_cb, atrac3p_huff_gain_loc2_cb,
        atrac3p_huff_gain_loc5_cb
    };
139
    static const uint8_t * const gain_xlats[11] = {
Maxim Polijakowski's avatar
Maxim Polijakowski committed
140 141 142 143 144 145 146
        NULL, atrac3p_huff_gain_npoints2_xlat, atrac3p_huff_gain_lev1_xlat,
        atrac3p_huff_gain_lev2_xlat, atrac3p_huff_gain_lev3_xlat,
        atrac3p_huff_gain_lev4_xlat, atrac3p_huff_gain_loc3_xlat,
        atrac3p_huff_gain_loc1_xlat, atrac3p_huff_gain_loc4_xlat,
        atrac3p_huff_gain_loc2_xlat, atrac3p_huff_gain_loc5_xlat
    };

147
    static const uint8_t * const tone_cbs[7] = {
Maxim Polijakowski's avatar
Maxim Polijakowski committed
148 149 150 151 152
        atrac3p_huff_tonebands_cb,  atrac3p_huff_numwavs1_cb,
        atrac3p_huff_numwavs2_cb,   atrac3p_huff_wav_ampsf1_cb,
        atrac3p_huff_wav_ampsf2_cb, atrac3p_huff_wav_ampsf3_cb,
        atrac3p_huff_freq_cb
    };
153
    static const uint8_t * const tone_xlats[7] = {
Maxim Polijakowski's avatar
Maxim Polijakowski committed
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
        NULL, NULL, atrac3p_huff_numwavs2_xlat, atrac3p_huff_wav_ampsf1_xlat,
        atrac3p_huff_wav_ampsf2_xlat, atrac3p_huff_wav_ampsf3_xlat,
        atrac3p_huff_freq_xlat
    };

    for (i = 0, wl_vlc_offs = 0, ct_vlc_offs = 2508; i < 4; i++) {
        wl_vlc_tabs[i].table = &tables_data[wl_vlc_offs];
        wl_vlc_tabs[i].table_allocated = 1 << wl_nb_bits[i];
        ct_vlc_tabs[i].table = &tables_data[ct_vlc_offs];
        ct_vlc_tabs[i].table_allocated = 1 << ct_nb_bits[i];

        ff_init_vlc_sparse(&wl_vlc_tabs[i], wl_nb_bits[i], wl_nb_codes[i],
                           wl_bits[i],  1, 1,
                           wl_codes[i], 1, 1,
                           wl_xlats[i], 1, 1,
                           INIT_VLC_USE_NEW_STATIC);

        ff_init_vlc_sparse(&ct_vlc_tabs[i], ct_nb_bits[i], ct_nb_codes[i],
                           ct_bits[i],  1, 1,
                           ct_codes[i], 1, 1,
                           ct_xlats[i], 1, 1,
                           INIT_VLC_USE_NEW_STATIC);

        wl_vlc_offs += wl_vlc_tabs[i].table_allocated;
        ct_vlc_offs += ct_vlc_tabs[i].table_allocated;
    }

    for (i = 0, sf_vlc_offs = 76; i < 8; i++) {
        sf_vlc_tabs[i].table = &tables_data[sf_vlc_offs];
        sf_vlc_tabs[i].table_allocated = 1 << sf_nb_bits[i];

        ff_init_vlc_sparse(&sf_vlc_tabs[i], sf_nb_bits[i], sf_nb_codes[i],
                           sf_bits[i],  1, 1,
                           sf_codes[i], 2, 2,
                           sf_xlats[i], 1, 1,
                           INIT_VLC_USE_NEW_STATIC);
        sf_vlc_offs += sf_vlc_tabs[i].table_allocated;
    }

    tab_offset = 2564;

    /* build huffman tables for spectrum decoding */
    for (i = 0; i < 112; i++) {
        if (atrac3p_spectra_tabs[i].cb)
            build_canonical_huff(atrac3p_spectra_tabs[i].cb,
                                 atrac3p_spectra_tabs[i].xlat,
                                 &tab_offset, &spec_vlc_tabs[i]);
        else
            spec_vlc_tabs[i].table = 0;
    }

    /* build huffman tables for gain data decoding */
    for (i = 0; i < 11; i++)
        build_canonical_huff(gain_cbs[i], gain_xlats[i], &tab_offset, &gain_vlc_tabs[i]);

    /* build huffman tables for tone decoding */
    for (i = 0; i < 7; i++)
        build_canonical_huff(tone_cbs[i], tone_xlats[i], &tab_offset, &tone_vlc_tabs[i]);
}

/**
 * Decode number of coded quantization units.
 *
217
 * @param[in]     bc            the Bitstream context
Maxim Polijakowski's avatar
Maxim Polijakowski committed
218 219 220 221 222
 * @param[in,out] chan          ptr to the channel parameters
 * @param[in,out] ctx           ptr to the channel unit context
 * @param[in]     avctx         ptr to the AVCodecContext
 * @return result code: 0 = OK, otherwise - error code
 */
223
static int num_coded_units(BitstreamContext *bc, Atrac3pChanParams *chan,
Maxim Polijakowski's avatar
Maxim Polijakowski committed
224 225
                           Atrac3pChanUnitCtx *ctx, AVCodecContext *avctx)
{
226
    chan->fill_mode = bitstream_read(bc, 2);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
227 228 229
    if (!chan->fill_mode) {
        chan->num_coded_vals = ctx->num_quant_units;
    } else {
230
        chan->num_coded_vals = bitstream_read(bc, 5);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
231 232 233 234 235 236 237
        if (chan->num_coded_vals > ctx->num_quant_units) {
            av_log(avctx, AV_LOG_ERROR,
                   "Invalid number of transmitted units!\n");
            return AVERROR_INVALIDDATA;
        }

        if (chan->fill_mode == 3)
238
            chan->split_point = bitstream_read(bc, 2) + (chan->ch_num << 1) + 1;
Maxim Polijakowski's avatar
Maxim Polijakowski committed
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322
    }

    return 0;
}

/**
 * Add weighting coefficients to the decoded word-length information.
 *
 * @param[in,out] ctx           ptr to the channel unit context
 * @param[in,out] chan          ptr to the channel parameters
 * @param[in]     wtab_idx      index of the table of weights
 * @param[in]     avctx         ptr to the AVCodecContext
 * @return result code: 0 = OK, otherwise - error code
 */
static int add_wordlen_weights(Atrac3pChanUnitCtx *ctx,
                               Atrac3pChanParams *chan, int wtab_idx,
                               AVCodecContext *avctx)
{
    int i;
    const int8_t *weights_tab =
        &atrac3p_wl_weights[chan->ch_num * 3 + wtab_idx - 1][0];

    for (i = 0; i < ctx->num_quant_units; i++) {
        chan->qu_wordlen[i] += weights_tab[i];
        if (chan->qu_wordlen[i] < 0 || chan->qu_wordlen[i] > 7) {
            av_log(avctx, AV_LOG_ERROR,
                   "WL index out of range: pos=%d, val=%d!\n",
                   i, chan->qu_wordlen[i]);
            return AVERROR_INVALIDDATA;
        }
    }

    return 0;
}

/**
 * Subtract weighting coefficients from decoded scalefactors.
 *
 * @param[in,out] ctx           ptr to the channel unit context
 * @param[in,out] chan          ptr to the channel parameters
 * @param[in]     wtab_idx      index of table of weights
 * @param[in]     avctx         ptr to the AVCodecContext
 * @return result code: 0 = OK, otherwise - error code
 */
static int subtract_sf_weights(Atrac3pChanUnitCtx *ctx,
                               Atrac3pChanParams *chan, int wtab_idx,
                               AVCodecContext *avctx)
{
    int i;
    const int8_t *weights_tab = &atrac3p_sf_weights[wtab_idx - 1][0];

    for (i = 0; i < ctx->used_quant_units; i++) {
        chan->qu_sf_idx[i] -= weights_tab[i];
        if (chan->qu_sf_idx[i] < 0 || chan->qu_sf_idx[i] > 63) {
            av_log(avctx, AV_LOG_ERROR,
                   "SF index out of range: pos=%d, val=%d!\n",
                   i, chan->qu_sf_idx[i]);
            return AVERROR_INVALIDDATA;
        }
    }

    return 0;
}

/**
 * Unpack vector quantization tables.
 *
 * @param[in]    start_val    start value for the unpacked table
 * @param[in]    shape_vec    ptr to table to unpack
 * @param[out]   dst          ptr to output array
 * @param[in]    num_values   number of values to unpack
 */
static inline void unpack_vq_shape(int start_val, const int8_t *shape_vec,
                                   int *dst, int num_values)
{
    int i;

    if (num_values) {
        dst[0] = dst[1] = dst[2] = start_val;
        for (i = 3; i < num_values; i++)
            dst[i] = start_val - shape_vec[atrac3p_qu_num_to_seg[i] - 1];
    }
}

323 324 325
#define UNPACK_SF_VQ_SHAPE(bc, dst, num_vals)                                  \
    start_val = bitstream_read((bc), 6);                                       \
    unpack_vq_shape(start_val, &atrac3p_sf_shapes[bitstream_read((bc), 6)][0], \
Maxim Polijakowski's avatar
Maxim Polijakowski committed
326 327 328 329 330
                    (dst), (num_vals))

/**
 * Decode word length for each quantization unit of a channel.
 *
331
 * @param[in]     bc            the Bitstream context
Maxim Polijakowski's avatar
Maxim Polijakowski committed
332 333 334 335 336
 * @param[in,out] ctx           ptr to the channel unit context
 * @param[in]     ch_num        channel to process
 * @param[in]     avctx         ptr to the AVCodecContext
 * @return result code: 0 = OK, otherwise - error code
 */
337
static int decode_channel_wordlen(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx,
Maxim Polijakowski's avatar
Maxim Polijakowski committed
338 339 340 341 342 343 344 345 346 347
                                  int ch_num, AVCodecContext *avctx)
{
    int i, weight_idx = 0, delta, diff, pos, delta_bits, min_val, flag,
        ret, start_val;
    VLC *vlc_tab;
    Atrac3pChanParams *chan     = &ctx->channels[ch_num];
    Atrac3pChanParams *ref_chan = &ctx->channels[0];

    chan->fill_mode = 0;

348
    switch (bitstream_read(bc, 2)) { /* switch according to coding mode */
Maxim Polijakowski's avatar
Maxim Polijakowski committed
349 350
    case 0: /* coded using constant number of bits */
        for (i = 0; i < ctx->num_quant_units; i++)
351
            chan->qu_wordlen[i] = bitstream_read(bc, 3);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
352 353 354
        break;
    case 1:
        if (ch_num) {
355
            if ((ret = num_coded_units(bc, chan, ctx, avctx)) < 0)
Maxim Polijakowski's avatar
Maxim Polijakowski committed
356 357 358
                return ret;

            if (chan->num_coded_vals) {
359
                vlc_tab = &wl_vlc_tabs[bitstream_read(bc, 2)];
Maxim Polijakowski's avatar
Maxim Polijakowski committed
360 361

                for (i = 0; i < chan->num_coded_vals; i++) {
362
                    delta = bitstream_read_vlc(bc, vlc_tab->table, vlc_tab->bits, 1);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
363 364 365 366
                    chan->qu_wordlen[i] = (ref_chan->qu_wordlen[i] + delta) & 7;
                }
            }
        } else {
367 368
            weight_idx = bitstream_read(bc, 2);
            if ((ret = num_coded_units(bc, chan, ctx, avctx)) < 0)
Maxim Polijakowski's avatar
Maxim Polijakowski committed
369 370 371
                return ret;

            if (chan->num_coded_vals) {
372
                pos = bitstream_read(bc, 5);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
373 374 375 376 377 378
                if (pos > chan->num_coded_vals) {
                    av_log(avctx, AV_LOG_ERROR,
                           "WL mode 1: invalid position!\n");
                    return AVERROR_INVALIDDATA;
                }

379 380
                delta_bits = bitstream_read(bc, 2);
                min_val    = bitstream_read(bc, 3);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
381 382

                for (i = 0; i < pos; i++)
383
                    chan->qu_wordlen[i] = bitstream_read(bc, 3);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
384 385

                for (i = pos; i < chan->num_coded_vals; i++)
386
                    chan->qu_wordlen[i] = (min_val + bitstream_read(bc, delta_bits)) & 7;
Maxim Polijakowski's avatar
Maxim Polijakowski committed
387 388 389 390
            }
        }
        break;
    case 2:
391
        if ((ret = num_coded_units(bc, chan, ctx, avctx)) < 0)
Maxim Polijakowski's avatar
Maxim Polijakowski committed
392 393 394
            return ret;

        if (ch_num && chan->num_coded_vals) {
395 396
            vlc_tab = &wl_vlc_tabs[bitstream_read(bc, 2)];
            delta = bitstream_read_vlc(bc, vlc_tab->table, vlc_tab->bits, 1);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
397 398 399 400
            chan->qu_wordlen[0] = (ref_chan->qu_wordlen[0] + delta) & 7;

            for (i = 1; i < chan->num_coded_vals; i++) {
                diff = ref_chan->qu_wordlen[i] - ref_chan->qu_wordlen[i - 1];
401
                delta = bitstream_read_vlc(bc, vlc_tab->table, vlc_tab->bits, 1);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
402 403 404
                chan->qu_wordlen[i] = (chan->qu_wordlen[i - 1] + diff + delta) & 7;
            }
        } else if (chan->num_coded_vals) {
405 406
            flag    = bitstream_read(bc, 1);
            vlc_tab = &wl_vlc_tabs[bitstream_read(bc, 1)];
Maxim Polijakowski's avatar
Maxim Polijakowski committed
407

408
            start_val = bitstream_read(bc, 3);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
409
            unpack_vq_shape(start_val,
410
                            &atrac3p_wl_shapes[start_val][bitstream_read(bc, 4)][0],
Maxim Polijakowski's avatar
Maxim Polijakowski committed
411 412 413 414
                            chan->qu_wordlen, chan->num_coded_vals);

            if (!flag) {
                for (i = 0; i < chan->num_coded_vals; i++) {
415
                    delta = bitstream_read_vlc(bc, vlc_tab->table, vlc_tab->bits, 1);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
416 417 418 419
                    chan->qu_wordlen[i] = (chan->qu_wordlen[i] + delta) & 7;
                }
            } else {
                for (i = 0; i < (chan->num_coded_vals & - 2); i += 2)
420
                    if (!bitstream_read_bit(bc)) {
Maxim Polijakowski's avatar
Maxim Polijakowski committed
421
                        chan->qu_wordlen[i]     = (chan->qu_wordlen[i] +
422 423
                                                   bitstream_read_vlc(bc, vlc_tab->table,
                                                                      vlc_tab->bits, 1)) & 7;
Maxim Polijakowski's avatar
Maxim Polijakowski committed
424
                        chan->qu_wordlen[i + 1] = (chan->qu_wordlen[i + 1] +
425 426
                                                   bitstream_read_vlc(bc, vlc_tab->table,
                                                                      vlc_tab->bits, 1)) & 7;
Maxim Polijakowski's avatar
Maxim Polijakowski committed
427 428 429 430
                    }

                if (chan->num_coded_vals & 1)
                    chan->qu_wordlen[i] = (chan->qu_wordlen[i] +
431 432
                                           bitstream_read_vlc(bc, vlc_tab->table,
                                                              vlc_tab->bits, 1)) & 7;
Maxim Polijakowski's avatar
Maxim Polijakowski committed
433 434 435 436
            }
        }
        break;
    case 3:
437 438
        weight_idx = bitstream_read(bc, 2);
        if ((ret = num_coded_units(bc, chan, ctx, avctx)) < 0)
Maxim Polijakowski's avatar
Maxim Polijakowski committed
439 440 441
            return ret;

        if (chan->num_coded_vals) {
442
            vlc_tab = &wl_vlc_tabs[bitstream_read(bc, 2)];
Maxim Polijakowski's avatar
Maxim Polijakowski committed
443 444

            /* first coefficient is coded directly */
445
            chan->qu_wordlen[0] = bitstream_read(bc, 3);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
446 447

            for (i = 1; i < chan->num_coded_vals; i++) {
448
                delta = bitstream_read_vlc(bc, vlc_tab->table, vlc_tab->bits, 1);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
449 450 451 452 453 454 455 456
                chan->qu_wordlen[i] = (chan->qu_wordlen[i - 1] + delta) & 7;
            }
        }
        break;
    }

    if (chan->fill_mode == 2) {
        for (i = chan->num_coded_vals; i < ctx->num_quant_units; i++)
457
            chan->qu_wordlen[i] = ch_num ? bitstream_read_bit(bc) : 1;
Maxim Polijakowski's avatar
Maxim Polijakowski committed
458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473
    } else if (chan->fill_mode == 3) {
        pos = ch_num ? chan->num_coded_vals + chan->split_point
                     : ctx->num_quant_units - chan->split_point;
        for (i = chan->num_coded_vals; i < pos; i++)
            chan->qu_wordlen[i] = 1;
    }

    if (weight_idx)
        return add_wordlen_weights(ctx, chan, weight_idx, avctx);

    return 0;
}

/**
 * Decode scale factor indexes for each quant unit of a channel.
 *
474
 * @param[in]     bc            the Bitstream context
Maxim Polijakowski's avatar
Maxim Polijakowski committed
475 476 477 478 479
 * @param[in,out] ctx           ptr to the channel unit context
 * @param[in]     ch_num        channel to process
 * @param[in]     avctx         ptr to the AVCodecContext
 * @return result code: 0 = OK, otherwise - error code
 */
480
static int decode_channel_sf_idx(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx,
Maxim Polijakowski's avatar
Maxim Polijakowski committed
481 482 483 484 485 486 487 488
                                 int ch_num, AVCodecContext *avctx)
{
    int i, weight_idx = 0, delta, diff, num_long_vals,
        delta_bits, min_val, vlc_sel, start_val;
    VLC *vlc_tab;
    Atrac3pChanParams *chan     = &ctx->channels[ch_num];
    Atrac3pChanParams *ref_chan = &ctx->channels[0];

489
    switch (bitstream_read(bc, 2)) { /* switch according to coding mode */
Maxim Polijakowski's avatar
Maxim Polijakowski committed
490 491
    case 0: /* coded using constant number of bits */
        for (i = 0; i < ctx->used_quant_units; i++)
492
            chan->qu_sf_idx[i] = bitstream_read(bc, 6);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
493 494 495
        break;
    case 1:
        if (ch_num) {
496
            vlc_tab = &sf_vlc_tabs[bitstream_read(bc, 2)];
Maxim Polijakowski's avatar
Maxim Polijakowski committed
497 498

            for (i = 0; i < ctx->used_quant_units; i++) {
499
                delta = bitstream_read_vlc(bc, vlc_tab->table, vlc_tab->bits, 1);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
500 501 502
                chan->qu_sf_idx[i] = (ref_chan->qu_sf_idx[i] + delta) & 0x3F;
            }
        } else {
503
            weight_idx = bitstream_read(bc, 2);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
504
            if (weight_idx == 3) {
505
                UNPACK_SF_VQ_SHAPE(bc, chan->qu_sf_idx, ctx->used_quant_units);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
506

507 508 509
                num_long_vals = bitstream_read(bc, 5);
                delta_bits    = bitstream_read(bc, 2);
                min_val       = bitstream_read(bc, 4) - 7;
Maxim Polijakowski's avatar
Maxim Polijakowski committed
510 511 512

                for (i = 0; i < num_long_vals; i++)
                    chan->qu_sf_idx[i] = (chan->qu_sf_idx[i] +
513
                                          bitstream_read(bc, 4) - 7) & 0x3F;
Maxim Polijakowski's avatar
Maxim Polijakowski committed
514 515 516 517

                /* all others are: min_val + delta */
                for (i = num_long_vals; i < ctx->used_quant_units; i++)
                    chan->qu_sf_idx[i] = (chan->qu_sf_idx[i] + min_val +
518
                                          bitstream_read(bc, delta_bits)) & 0x3F;
Maxim Polijakowski's avatar
Maxim Polijakowski committed
519
            } else {
520 521 522
                num_long_vals = bitstream_read(bc, 5);
                delta_bits    = bitstream_read(bc, 3);
                min_val       = bitstream_read(bc, 6);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
523 524 525 526 527 528 529 530
                if (num_long_vals > ctx->used_quant_units || delta_bits == 7) {
                    av_log(avctx, AV_LOG_ERROR,
                           "SF mode 1: invalid parameters!\n");
                    return AVERROR_INVALIDDATA;
                }

                /* read full-precision SF indexes */
                for (i = 0; i < num_long_vals; i++)
531
                    chan->qu_sf_idx[i] = bitstream_read(bc, 6);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
532 533 534 535

                /* all others are: min_val + delta */
                for (i = num_long_vals; i < ctx->used_quant_units; i++)
                    chan->qu_sf_idx[i] = (min_val +
536
                                          bitstream_read(bc, delta_bits)) & 0x3F;
Maxim Polijakowski's avatar
Maxim Polijakowski committed
537 538 539 540 541
            }
        }
        break;
    case 2:
        if (ch_num) {
542
            vlc_tab = &sf_vlc_tabs[bitstream_read(bc, 2)];
Maxim Polijakowski's avatar
Maxim Polijakowski committed
543

544
            delta = bitstream_read_vlc(bc, vlc_tab->table, vlc_tab->bits, 1);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
545 546 547 548
            chan->qu_sf_idx[0] = (ref_chan->qu_sf_idx[0] + delta) & 0x3F;

            for (i = 1; i < ctx->used_quant_units; i++) {
                diff  = ref_chan->qu_sf_idx[i] - ref_chan->qu_sf_idx[i - 1];
549
                delta = bitstream_read_vlc(bc, vlc_tab->table, vlc_tab->bits, 1);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
550 551 552
                chan->qu_sf_idx[i] = (chan->qu_sf_idx[i - 1] + diff + delta) & 0x3F;
            }
        } else {
553
            vlc_tab = &sf_vlc_tabs[bitstream_read(bc, 2) + 4];
Maxim Polijakowski's avatar
Maxim Polijakowski committed
554

555
            UNPACK_SF_VQ_SHAPE(bc, chan->qu_sf_idx, ctx->used_quant_units);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
556 557

            for (i = 0; i < ctx->used_quant_units; i++) {
558
                delta = bitstream_read_vlc(bc, vlc_tab->table, vlc_tab->bits, 1);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
559 560 561 562 563 564 565 566 567 568 569
                chan->qu_sf_idx[i] = (chan->qu_sf_idx[i] +
                                      sign_extend(delta, 4)) & 0x3F;
            }
        }
        break;
    case 3:
        if (ch_num) {
            /* copy coefficients from reference channel */
            for (i = 0; i < ctx->used_quant_units; i++)
                chan->qu_sf_idx[i] = ref_chan->qu_sf_idx[i];
        } else {
570 571
            weight_idx = bitstream_read(bc, 2);
            vlc_sel    = bitstream_read(bc, 2);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
572 573 574 575 576
            vlc_tab    = &sf_vlc_tabs[vlc_sel];

            if (weight_idx == 3) {
                vlc_tab = &sf_vlc_tabs[vlc_sel + 4];

577
                UNPACK_SF_VQ_SHAPE(bc, chan->qu_sf_idx, ctx->used_quant_units);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
578

579 580
                diff               = (bitstream_read(bc, 4) + 56)   & 0x3F;
                chan->qu_sf_idx[0] = (chan->qu_sf_idx[0]    + diff) & 0x3F;
Maxim Polijakowski's avatar
Maxim Polijakowski committed
581 582

                for (i = 1; i < ctx->used_quant_units; i++) {
583
                    delta = bitstream_read_vlc(bc, vlc_tab->table, vlc_tab->bits, 1);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
584 585 586 587 588
                    diff               = (diff + sign_extend(delta, 4)) & 0x3F;
                    chan->qu_sf_idx[i] = (diff + chan->qu_sf_idx[i])    & 0x3F;
                }
            } else {
                /* 1st coefficient is coded directly */
589
                chan->qu_sf_idx[0] = bitstream_read(bc, 6);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
590 591

                for (i = 1; i < ctx->used_quant_units; i++) {
592
                    delta = bitstream_read_vlc(bc, vlc_tab->table, vlc_tab->bits, 1);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608
                    chan->qu_sf_idx[i] = (chan->qu_sf_idx[i - 1] + delta) & 0x3F;
                }
            }
        }
        break;
    }

    if (weight_idx && weight_idx < 3)
        return subtract_sf_weights(ctx, chan, weight_idx, avctx);

    return 0;
}

/**
 * Decode word length information for each channel.
 *
609
 * @param[in]     bc            the Bitstream context
Maxim Polijakowski's avatar
Maxim Polijakowski committed
610 611 612 613 614
 * @param[in,out] ctx           ptr to the channel unit context
 * @param[in]     num_channels  number of channels to process
 * @param[in]     avctx         ptr to the AVCodecContext
 * @return result code: 0 = OK, otherwise - error code
 */
615
static int decode_quant_wordlen(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx,
Maxim Polijakowski's avatar
Maxim Polijakowski committed
616 617 618 619 620 621 622 623
                                int num_channels, AVCodecContext *avctx)
{
    int ch_num, i, ret;

    for (ch_num = 0; ch_num < num_channels; ch_num++) {
        memset(ctx->channels[ch_num].qu_wordlen, 0,
               sizeof(ctx->channels[ch_num].qu_wordlen));

624
        if ((ret = decode_channel_wordlen(bc, ctx, ch_num, avctx)) < 0)
Maxim Polijakowski's avatar
Maxim Polijakowski committed
625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641
            return ret;
    }

    /* scan for last non-zero coeff in both channels and
     * set number of quant units having coded spectrum */
    for (i = ctx->num_quant_units - 1; i >= 0; i--)
        if (ctx->channels[0].qu_wordlen[i] ||
            (num_channels == 2 && ctx->channels[1].qu_wordlen[i]))
            break;
    ctx->used_quant_units = i + 1;

    return 0;
}

/**
 * Decode scale factor indexes for each channel.
 *
642
 * @param[in]     bc            the Bitstream context
Maxim Polijakowski's avatar
Maxim Polijakowski committed
643 644 645 646 647
 * @param[in,out] ctx           ptr to the channel unit context
 * @param[in]     num_channels  number of channels to process
 * @param[in]     avctx         ptr to the AVCodecContext
 * @return result code: 0 = OK, otherwise - error code
 */
648
static int decode_scale_factors(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx,
Maxim Polijakowski's avatar
Maxim Polijakowski committed
649 650 651 652 653 654 655 656 657 658 659
                                int num_channels, AVCodecContext *avctx)
{
    int ch_num, ret;

    if (!ctx->used_quant_units)
        return 0;

    for (ch_num = 0; ch_num < num_channels; ch_num++) {
        memset(ctx->channels[ch_num].qu_sf_idx, 0,
               sizeof(ctx->channels[ch_num].qu_sf_idx));

660
        if ((ret = decode_channel_sf_idx(bc, ctx, ch_num, avctx)) < 0)
Maxim Polijakowski's avatar
Maxim Polijakowski committed
661 662 663 664 665 666 667 668 669
            return ret;
    }

    return 0;
}

/**
 * Decode number of code table values.
 *
670
 * @param[in]     bc            the Bitstream context
Maxim Polijakowski's avatar
Maxim Polijakowski committed
671 672 673 674
 * @param[in,out] ctx           ptr to the channel unit context
 * @param[in]     avctx         ptr to the AVCodecContext
 * @return result code: 0 = OK, otherwise - error code
 */
675
static int get_num_ct_values(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx,
Maxim Polijakowski's avatar
Maxim Polijakowski committed
676 677 678 679
                             AVCodecContext *avctx)
{
    int num_coded_vals;

680 681
    if (bitstream_read_bit(bc)) {
        num_coded_vals = bitstream_read(bc, 5);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
682 683 684 685 686 687 688 689 690 691 692
        if (num_coded_vals > ctx->used_quant_units) {
            av_log(avctx, AV_LOG_ERROR,
                   "Invalid number of code table indexes: %d!\n", num_coded_vals);
            return AVERROR_INVALIDDATA;
        }
        return num_coded_vals;
    } else
        return ctx->used_quant_units;
}

#define DEC_CT_IDX_COMMON(OP)                                           \
693
    num_vals = get_num_ct_values(bc, ctx, avctx);                       \
Maxim Polijakowski's avatar
Maxim Polijakowski committed
694 695 696 697 698 699 700 701
    if (num_vals < 0)                                                   \
        return num_vals;                                                \
                                                                        \
    for (i = 0; i < num_vals; i++) {                                    \
        if (chan->qu_wordlen[i]) {                                      \
            chan->qu_tab_idx[i] = OP;                                   \
        } else if (ch_num && ref_chan->qu_wordlen[i])                   \
            /* get clone master flag */                                 \
702
            chan->qu_tab_idx[i] = bitstream_read_bit(bc);               \
Maxim Polijakowski's avatar
Maxim Polijakowski committed
703 704
    }

705
#define CODING_DIRECT bitstream_read(bc, num_bits)
Maxim Polijakowski's avatar
Maxim Polijakowski committed
706

707
#define CODING_VLC bitstream_read_vlc(bc, vlc_tab->table, vlc_tab->bits, 1)
Maxim Polijakowski's avatar
Maxim Polijakowski committed
708 709 710

#define CODING_VLC_DELTA                                                \
    (!i) ? CODING_VLC                                                   \
711 712
         : (pred + bitstream_read_vlc(bc, delta_vlc->table,             \
                                      delta_vlc->bits, 1)) & mask;      \
Maxim Polijakowski's avatar
Maxim Polijakowski committed
713 714 715 716
    pred = chan->qu_tab_idx[i]

#define CODING_VLC_DIFF                                                 \
    (ref_chan->qu_tab_idx[i] +                                          \
717
     bitstream_read_vlc(bc, vlc_tab->table, vlc_tab->bits, 1)) & mask
Maxim Polijakowski's avatar
Maxim Polijakowski committed
718 719 720 721

/**
 * Decode code table indexes for each quant unit of a channel.
 *
722
 * @param[in]     bc            the Bitstream context
Maxim Polijakowski's avatar
Maxim Polijakowski committed
723 724 725 726 727
 * @param[in,out] ctx           ptr to the channel unit context
 * @param[in]     ch_num        channel to process
 * @param[in]     avctx         ptr to the AVCodecContext
 * @return result code: 0 = OK, otherwise - error code
 */
728
static int decode_channel_code_tab(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx,
Maxim Polijakowski's avatar
Maxim Polijakowski committed
729 730 731 732 733 734 735 736
                                   int ch_num, AVCodecContext *avctx)
{
    int i, num_vals, num_bits, pred;
    int mask = ctx->use_full_table ? 7 : 3; /* mask for modular arithmetic */
    VLC *vlc_tab, *delta_vlc;
    Atrac3pChanParams *chan     = &ctx->channels[ch_num];
    Atrac3pChanParams *ref_chan = &ctx->channels[0];

737
    chan->table_type = bitstream_read_bit(bc);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
738

739
    switch (bitstream_read(bc, 2)) { /* switch according to coding mode */
Maxim Polijakowski's avatar
Maxim Polijakowski committed
740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774
    case 0: /* directly coded */
        num_bits = ctx->use_full_table + 2;
        DEC_CT_IDX_COMMON(CODING_DIRECT);
        break;
    case 1: /* entropy-coded */
        vlc_tab = ctx->use_full_table ? &ct_vlc_tabs[1]
                                      : ct_vlc_tabs;
        DEC_CT_IDX_COMMON(CODING_VLC);
        break;
    case 2: /* entropy-coded delta */
        if (ctx->use_full_table) {
            vlc_tab   = &ct_vlc_tabs[1];
            delta_vlc = &ct_vlc_tabs[2];
        } else {
            vlc_tab   = ct_vlc_tabs;
            delta_vlc = ct_vlc_tabs;
        }
        pred = 0;
        DEC_CT_IDX_COMMON(CODING_VLC_DELTA);
        break;
    case 3: /* entropy-coded difference to master */
        if (ch_num) {
            vlc_tab = ctx->use_full_table ? &ct_vlc_tabs[3]
                                          : ct_vlc_tabs;
            DEC_CT_IDX_COMMON(CODING_VLC_DIFF);
        }
        break;
    }

    return 0;
}

/**
 * Decode code table indexes for each channel.
 *
775
 * @param[in]     bc            the Bitstream context
Maxim Polijakowski's avatar
Maxim Polijakowski committed
776 777 778 779 780
 * @param[in,out] ctx           ptr to the channel unit context
 * @param[in]     num_channels  number of channels to process
 * @param[in]     avctx         ptr to the AVCodecContext
 * @return result code: 0 = OK, otherwise - error code
 */
781
static int decode_code_table_indexes(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx,
Maxim Polijakowski's avatar
Maxim Polijakowski committed
782 783 784 785 786 787 788
                                     int num_channels, AVCodecContext *avctx)
{
    int ch_num, ret;

    if (!ctx->used_quant_units)
        return 0;

789
    ctx->use_full_table = bitstream_read_bit(bc);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
790 791 792 793 794

    for (ch_num = 0; ch_num < num_channels; ch_num++) {
        memset(ctx->channels[ch_num].qu_tab_idx, 0,
               sizeof(ctx->channels[ch_num].qu_tab_idx));

795
        if ((ret = decode_channel_code_tab(bc, ctx, ch_num, avctx)) < 0)
Maxim Polijakowski's avatar
Maxim Polijakowski committed
796 797 798 799 800 801 802 803 804 805 806 807
            return ret;
    }

    return 0;
}

/**
 * Decode huffman-coded spectral lines for a given quant unit.
 *
 * This is a generalized version for all known coding modes.
 * Its speed can be improved by creating separate functions for each mode.
 *
808
 * @param[in]   bc          the Bitstream context
Maxim Polijakowski's avatar
Maxim Polijakowski committed
809 810 811 812 813
 * @param[in]   tab         code table telling how to decode spectral lines
 * @param[in]   vlc_tab     ptr to the huffman table associated with the code table
 * @param[out]  out         pointer to buffer where decoded data should be stored
 * @param[in]   num_specs   number of spectral lines to decode
 */
814
static void decode_qu_spectra(BitstreamContext *bc, const Atrac3pSpecCodeTab *tab,
Maxim Polijakowski's avatar
Maxim Polijakowski committed
815 816 817 818 819 820 821 822 823 824
                              VLC *vlc_tab, int16_t *out, const int num_specs)
{
    int i, j, pos, cf;
    int group_size = tab->group_size;
    int num_coeffs = tab->num_coeffs;
    int bits       = tab->bits;
    int is_signed  = tab->is_signed;
    unsigned val, mask = (1 << bits) - 1;

    for (pos = 0; pos < num_specs;) {
825
        if (group_size == 1 || bitstream_read_bit(bc)) {
Maxim Polijakowski's avatar
Maxim Polijakowski committed
826
            for (j = 0; j < group_size; j++) {
827
                val = bitstream_read_vlc(bc, vlc_tab->table, vlc_tab->bits, 1);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
828 829 830 831 832

                for (i = 0; i < num_coeffs; i++) {
                    cf = val & mask;
                    if (is_signed)
                        cf = sign_extend(cf, bits);
833
                    else if (cf && bitstream_read_bit(bc))
Maxim Polijakowski's avatar
Maxim Polijakowski committed
834 835 836 837 838 839 840 841 842 843 844 845 846 847
                        cf = -cf;

                    out[pos++] = cf;
                    val      >>= bits;
                }
            }
        } else /* group skipped */
            pos += group_size * num_coeffs;
    }
}

/**
 * Decode huffman-coded IMDCT spectrum for all channels.
 *
848
 * @param[in]     bc            the Bitstream context
Maxim Polijakowski's avatar
Maxim Polijakowski committed
849 850 851 852
 * @param[in,out] ctx           ptr to the channel unit context
 * @param[in]     num_channels  number of channels to process
 * @param[in]     avctx         ptr to the AVCodecContext
 */
853
static void decode_spectrum(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx,
Maxim Polijakowski's avatar
Maxim Polijakowski committed
854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884
                            int num_channels, AVCodecContext *avctx)
{
    int i, ch_num, qu, wordlen, codetab, tab_index, num_specs;
    const Atrac3pSpecCodeTab *tab;
    Atrac3pChanParams *chan;

    for (ch_num = 0; ch_num < num_channels; ch_num++) {
        chan = &ctx->channels[ch_num];

        memset(chan->spectrum, 0, sizeof(chan->spectrum));

        /* set power compensation level to disabled */
        memset(chan->power_levs, ATRAC3P_POWER_COMP_OFF, sizeof(chan->power_levs));

        for (qu = 0; qu < ctx->used_quant_units; qu++) {
            num_specs = ff_atrac3p_qu_to_spec_pos[qu + 1] -
                        ff_atrac3p_qu_to_spec_pos[qu];

            wordlen = chan->qu_wordlen[qu];
            codetab = chan->qu_tab_idx[qu];
            if (wordlen) {
                if (!ctx->use_full_table)
                    codetab = atrac3p_ct_restricted_to_full[chan->table_type][wordlen - 1][codetab];

                tab_index = (chan->table_type * 8 + codetab) * 7 + wordlen - 1;
                tab       = &atrac3p_spectra_tabs[tab_index];

                /* this allows reusing VLC tables */
                if (tab->redirect >= 0)
                    tab_index = tab->redirect;

885
                decode_qu_spectra(bc, tab, &spec_vlc_tabs[tab_index],
Maxim Polijakowski's avatar
Maxim Polijakowski committed
886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904
                                  &chan->spectrum[ff_atrac3p_qu_to_spec_pos[qu]],
                                  num_specs);
            } else if (ch_num && ctx->channels[0].qu_wordlen[qu] && !codetab) {
                /* copy coefficients from master */
                memcpy(&chan->spectrum[ff_atrac3p_qu_to_spec_pos[qu]],
                       &ctx->channels[0].spectrum[ff_atrac3p_qu_to_spec_pos[qu]],
                       num_specs *
                       sizeof(chan->spectrum[ff_atrac3p_qu_to_spec_pos[qu]]));
                chan->qu_wordlen[qu] = ctx->channels[0].qu_wordlen[qu];
            }
        }

        /* Power compensation levels only present in the bitstream
         * if there are more than 2 quant units. The lowest two units
         * correspond to the frequencies 0...351 Hz, whose shouldn't
         * be affected by the power compensation. */
        if (ctx->used_quant_units > 2) {
            num_specs = atrac3p_subband_to_num_powgrps[ctx->num_coded_subbands - 1];
            for (i = 0; i < num_specs; i++)
905
                chan->power_levs[i] = bitstream_read(bc, 4);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
906 907 908 909 910 911 912 913 914 915 916 917
        }
    }
}

/**
 * Retrieve specified amount of flag bits from the input bitstream.
 * The data can be shortened in the case of the following two common conditions:
 * if all bits are zero then only one signal bit = 0 will be stored,
 * if all bits are ones then two signal bits = 1,0 will be stored.
 * Otherwise, all necessary bits will be directly stored
 * prefixed by two signal bits = 1,1.
 *
918
 * @param[in]   bc              ptr to the BitstreamContext
Maxim Polijakowski's avatar
Maxim Polijakowski committed
919 920 921 922
 * @param[out]  out             where to place decoded flags
 * @param[in]   num_flags       number of flags to process
 * @return: 0 = all flag bits are zero, 1 = there is at least one non-zero flag bit
 */
923
static int get_subband_flags(BitstreamContext *bc, uint8_t *out, int num_flags)
Maxim Polijakowski's avatar
Maxim Polijakowski committed
924 925 926 927 928
{
    int i, result;

    memset(out, 0, num_flags);

929
    result = bitstream_read_bit(bc);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
930
    if (result) {
931
        if (bitstream_read_bit(bc))
Maxim Polijakowski's avatar
Maxim Polijakowski committed
932
            for (i = 0; i < num_flags; i++)
933
                out[i] = bitstream_read_bit(bc);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
934 935 936 937 938 939 940 941 942 943
        else
            memset(out, 1, num_flags);
    }

    return result;
}

/**
 * Decode mdct window shape flags for all channels.
 *
944
 * @param[in]     bc            the Bitstream context
Maxim Polijakowski's avatar
Maxim Polijakowski committed
945 946 947
 * @param[in,out] ctx           ptr to the channel unit context
 * @param[in]     num_channels  number of channels to process
 */
948
static void decode_window_shape(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx,
Maxim Polijakowski's avatar
Maxim Polijakowski committed
949 950 951 952 953
                                int num_channels)
{
    int ch_num;

    for (ch_num = 0; ch_num < num_channels; ch_num++)
954
        get_subband_flags(bc, ctx->channels[ch_num].wnd_shape,
Maxim Polijakowski's avatar
Maxim Polijakowski committed
955 956 957 958 959 960
                          ctx->num_subbands);
}

/**
 * Decode number of gain control points.
 *
961
 * @param[in]     bc              the Bitstream context
Maxim Polijakowski's avatar
Maxim Polijakowski committed
962 963 964 965 966
 * @param[in,out] ctx             ptr to the channel unit context
 * @param[in]     ch_num          channel to process
 * @param[in]     coded_subbands  number of subbands to process
 * @return result code: 0 = OK, otherwise - error code
 */
967
static int decode_gainc_npoints(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx,
Maxim Polijakowski's avatar
Maxim Polijakowski committed
968 969 970 971 972 973
                                int ch_num, int coded_subbands)
{
    int i, delta, delta_bits, min_val;
    Atrac3pChanParams *chan     = &ctx->channels[ch_num];
    Atrac3pChanParams *ref_chan = &ctx->channels[0];

974
    switch (bitstream_read(bc, 2)) { /* switch according to coding mode */
Maxim Polijakowski's avatar
Maxim Polijakowski committed
975 976
    case 0: /* fixed-length coding */
        for (i = 0; i < coded_subbands; i++)
977
            chan->gain_data[i].num_points = bitstream_read(bc, 3);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
978 979 980 981
        break;
    case 1: /* variable-length coding */
        for (i = 0; i < coded_subbands; i++)
            chan->gain_data[i].num_points =
982 983
                bitstream_read_vlc(bc, gain_vlc_tabs[0].table,
                                   gain_vlc_tabs[0].bits, 1);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
984 985 986 987
        break;
    case 2:
        if (ch_num) { /* VLC modulo delta to master channel */
            for (i = 0; i < coded_subbands; i++) {
988 989
                delta = bitstream_read_vlc(bc, gain_vlc_tabs[1].table,
                                           gain_vlc_tabs[1].bits, 1);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
990 991 992 993 994
                chan->gain_data[i].num_points =
                    (ref_chan->gain_data[i].num_points + delta) & 7;
            }
        } else { /* VLC modulo delta to previous */
            chan->gain_data[0].num_points =
995 996
                bitstream_read_vlc(bc, gain_vlc_tabs[0].table,
                                   gain_vlc_tabs[0].bits, 1);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
997 998

            for (i = 1; i < coded_subbands; i++) {
999 1000
                delta = bitstream_read_vlc(bc, gain_vlc_tabs[1].table,
                                           gain_vlc_tabs[1].bits, 1);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011
                chan->gain_data[i].num_points =
                    (chan->gain_data[i - 1].num_points + delta) & 7;
            }
        }
        break;
    case 3:
        if (ch_num) { /* copy data from master channel */
            for (i = 0; i < coded_subbands; i++)
                chan->gain_data[i].num_points =
                    ref_chan->gain_data[i].num_points;
        } else { /* shorter delta to min */
1012 1013
            delta_bits = bitstream_read(bc, 2);
            min_val    = bitstream_read(bc, 3);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1014 1015

            for (i = 0; i < coded_subbands; i++) {
1016
                chan->gain_data[i].num_points = min_val + bitstream_read(bc, delta_bits);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042
                if (chan->gain_data[i].num_points > 7)
                    return AVERROR_INVALIDDATA;
            }
        }
    }

    return 0;
}

/**
 * Implements coding mode 3 (slave) for gain compensation levels.
 *
 * @param[out]   dst   ptr to the output array
 * @param[in]    ref   ptr to the reference channel
 */
static inline void gainc_level_mode3s(AtracGainInfo *dst, AtracGainInfo *ref)
{
    int i;

    for (i = 0; i < dst->num_points; i++)
        dst->lev_code[i] = (i >= ref->num_points) ? 7 : ref->lev_code[i];
}

/**
 * Implements coding mode 1 (master) for gain compensation levels.
 *
1043
 * @param[in]     bc     the Bitstream context
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1044 1045 1046
 * @param[in]     ctx    ptr to the channel unit context
 * @param[out]    dst    ptr to the output array
 */
1047
static inline void gainc_level_mode1m(BitstreamContext *bc,
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1048 1049 1050 1051 1052 1053
                                      Atrac3pChanUnitCtx *ctx,
                                      AtracGainInfo *dst)
{
    int i, delta;

    if (dst->num_points > 0)
1054 1055
        dst->lev_code[0] = bitstream_read_vlc(bc, gain_vlc_tabs[2].table,
                                              gain_vlc_tabs[2].bits, 1);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1056 1057

    for (i = 1; i < dst->num_points; i++) {
1058 1059
        delta = bitstream_read_vlc(bc, gain_vlc_tabs[3].table,
                                   gain_vlc_tabs[3].bits, 1);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1060 1061 1062 1063 1064 1065 1066
        dst->lev_code[i] = (dst->lev_code[i - 1] + delta) & 0xF;
    }
}

/**
 * Decode level code for each gain control point.
 *
1067
 * @param[in]     bc              the Bitstream context
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1068 1069 1070 1071 1072
 * @param[in,out] ctx             ptr to the channel unit context
 * @param[in]     ch_num          channel to process
 * @param[in]     coded_subbands  number of subbands to process
 * @return result code: 0 = OK, otherwise - error code
 */
1073
static int decode_gainc_levels(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx,
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1074 1075 1076 1077 1078 1079
                               int ch_num, int coded_subbands)
{
    int sb, i, delta, delta_bits, min_val, pred;
    Atrac3pChanParams *chan     = &ctx->channels[ch_num];
    Atrac3pChanParams *ref_chan = &ctx->channels[0];

1080
    switch (bitstream_read(bc, 2)) { /* switch according to coding mode */
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1081 1082 1083
    case 0: /* fixed-length coding */
        for (sb = 0; sb < coded_subbands; sb++)
            for (i = 0; i < chan->gain_data[sb].num_points; i++)
1084
                chan->gain_data[sb].lev_code[i] = bitstream_read(bc, 4);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1085 1086 1087 1088 1089
        break;
    case 1:
        if (ch_num) { /* VLC modulo delta to master channel */
            for (sb = 0; sb < coded_subbands; sb++)
                for (i = 0; i < chan->gain_data[sb].num_points; i++) {
1090 1091
                    delta = bitstream_read_vlc(bc, gain_vlc_tabs[5].table,
                                               gain_vlc_tabs[5].bits, 1);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1092 1093 1094 1095 1096 1097
                    pred = (i >= ref_chan->gain_data[sb].num_points)
                           ? 7 : ref_chan->gain_data[sb].lev_code[i];
                    chan->gain_data[sb].lev_code[i] = (pred + delta) & 0xF;
                }
        } else { /* VLC modulo delta to previous */
            for (sb = 0; sb < coded_subbands; sb++)
1098
                gainc_level_mode1m(bc, ctx, &chan->gain_data[sb]);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1099 1100 1101 1102 1103 1104
        }
        break;
    case 2:
        if (ch_num) { /* VLC modulo delta to previous or clone master */
            for (sb = 0; sb < coded_subbands; sb++)
                if (chan->gain_data[sb].num_points > 0) {
1105 1106
                    if (bitstream_read_bit(bc))
                        gainc_level_mode1m(bc, ctx, &chan->gain_data[sb]);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1107 1108 1109 1110 1111 1112
                    else
                        gainc_level_mode3s(&chan->gain_data[sb],
                                           &ref_chan->gain_data[sb]);
                }
        } else { /* VLC modulo delta to lev_codes of previous subband */
            if (chan->gain_data[0].num_points > 0)
1113
                gainc_level_mode1m(bc, ctx, &chan->gain_data[0]);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1114 1115 1116

            for (sb = 1; sb < coded_subbands; sb++)
                for (i = 0; i < chan->gain_data[sb].num_points; i++) {
1117 1118
                    delta = bitstream_read_vlc(bc, gain_vlc_tabs[4].table,
                                               gain_vlc_tabs[4].bits, 1);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130
                    pred = (i >= chan->gain_data[sb - 1].num_points)
                           ? 7 : chan->gain_data[sb - 1].lev_code[i];
                    chan->gain_data[sb].lev_code[i] = (pred + delta) & 0xF;
                }
        }
        break;
    case 3:
        if (ch_num) { /* clone master */
            for (sb = 0; sb < coded_subbands; sb++)
                gainc_level_mode3s(&chan->gain_data[sb],
                                   &ref_chan->gain_data[sb]);
        } else { /* shorter delta to min */
1131 1132
            delta_bits = bitstream_read(bc, 2);
            min_val    = bitstream_read(bc, 4);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1133 1134 1135

            for (sb = 0; sb < coded_subbands; sb++)
                for (i = 0; i < chan->gain_data[sb].num_points; i++) {
1136
                    chan->gain_data[sb].lev_code[i] = min_val + bitstream_read(bc, delta_bits);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149
                    if (chan->gain_data[sb].lev_code[i] > 15)
                        return AVERROR_INVALIDDATA;
                }
        }
        break;
    }

    return 0;
}

/**
 * Implements coding mode 0 for gain compensation locations.
 *
1150
 * @param[in]     bc     the Bitstream context
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1151 1152 1153 1154
 * @param[in]     ctx    ptr to the channel unit context
 * @param[out]    dst    ptr to the output array
 * @param[in]     pos    position of the value to be processed
 */
1155
static inline void gainc_loc_mode0(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx,
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1156 1157 1158 1159 1160
                                   AtracGainInfo *dst, int pos)
{
    int delta_bits;

    if (!pos || dst->loc_code[pos - 1] < 15)
1161
        dst->loc_code[pos] = bitstream_read(bc, 5);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1162 1163 1164 1165 1166
    else if (dst->loc_code[pos - 1] >= 30)
        dst->loc_code[pos] = 31;
    else {
        delta_bits         = av_log2(30 - dst->loc_code[pos - 1]) + 1;
        dst->loc_code[pos] = dst->loc_code[pos - 1] +
1167
                             bitstream_read(bc, delta_bits) + 1;
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1168 1169 1170 1171 1172 1173
    }
}

/**
 * Implements coding mode 1 for gain compensation locations.
 *
1174
 * @param[in]     bc     the Bitstream context
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1175 1176 1177
 * @param[in]     ctx    ptr to the channel unit context
 * @param[out]    dst    ptr to the output array
 */
1178
static inline void gainc_loc_mode1(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx,
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1179 1180 1181 1182 1183 1184 1185
                                   AtracGainInfo *dst)
{
    int i;
    VLC *tab;

    if (dst->num_points > 0) {
        /* 1st coefficient is stored directly */
1186
        dst->loc_code[0] = bitstream_read(bc, 5);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1187 1188 1189 1190 1191 1192 1193 1194

        for (i = 1; i < dst->num_points; i++) {
            /* switch VLC according to the curve direction
             * (ascending/descending) */
            tab              = (dst->lev_code[i] <= dst->lev_code[i - 1])
                               ? &gain_vlc_tabs[7]
                               : &gain_vlc_tabs[9];
            dst->loc_code[i] = dst->loc_code[i - 1] +
1195
                               bitstream_read_vlc(bc, tab->table, tab->bits, 1);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1196 1197 1198 1199 1200 1201 1202
        }
    }
}

/**
 * Decode location code for each gain control point.
 *
1203
 * @param[in]     bc              the Bitstream context
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1204 1205 1206 1207 1208 1209
 * @param[in,out] ctx             ptr to the channel unit context
 * @param[in]     ch_num          channel to process
 * @param[in]     coded_subbands  number of subbands to process
 * @param[in]     avctx           ptr to the AVCodecContext
 * @return result code: 0 = OK, otherwise - error code
 */
1210
static int decode_gainc_loc_codes(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx,
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1211 1212 1213 1214 1215 1216 1217 1218 1219
                                  int ch_num, int coded_subbands,
                                  AVCodecContext *avctx)
{
    int sb, i, delta, delta_bits, min_val, pred, more_than_ref;
    AtracGainInfo *dst, *ref;
    VLC *tab;
    Atrac3pChanParams *chan     = &ctx->channels[ch_num];
    Atrac3pChanParams *ref_chan = &ctx->channels[0];

1220
    switch (bitstream_read(bc, 2)) { /* switch according to coding mode */
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1221 1222 1223
    case 0: /* sequence of numbers in ascending order */
        for (sb = 0; sb < coded_subbands; sb++)
            for (i = 0; i < chan->gain_data[sb].num_points; i++)
1224
                gainc_loc_mode0(bc, ctx, &chan->gain_data[sb], i);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1225 1226 1227 1228 1229 1230 1231 1232 1233 1234
        break;
    case 1:
        if (ch_num) {
            for (sb = 0; sb < coded_subbands; sb++) {
                if (chan->gain_data[sb].num_points <= 0)
                    continue;
                dst = &chan->gain_data[sb];
                ref = &ref_chan->gain_data[sb];

                /* 1st value is vlc-coded modulo delta to master */
1235 1236
                delta = bitstream_read_vlc(bc, gain_vlc_tabs[10].table,
                                           gain_vlc_tabs[10].bits, 1);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1237 1238 1239 1240 1241 1242 1243 1244 1245
                pred = ref->num_points > 0 ? ref->loc_code[0] : 0;
                dst->loc_code[0] = (pred + delta) & 0x1F;

                for (i = 1; i < dst->num_points; i++) {
                    more_than_ref = i >= ref->num_points;
                    if (dst->lev_code[i] > dst->lev_code[i - 1]) {
                        /* ascending curve */
                        if (more_than_ref) {
                            delta =
1246 1247
                                bitstream_read_vlc(bc, gain_vlc_tabs[9].table,
                                                   gain_vlc_tabs[9].bits, 1);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1248 1249
                            dst->loc_code[i] = dst->loc_code[i - 1] + delta;
                        } else {
1250 1251
                            if (bitstream_read_bit(bc))
                                gainc_loc_mode0(bc, ctx, dst, i);  // direct coding
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1252 1253 1254 1255 1256 1257
                            else
                                dst->loc_code[i] = ref->loc_code[i];  // clone master
                        }
                    } else { /* descending curve */
                        tab   = more_than_ref ? &gain_vlc_tabs[7]
                                              : &gain_vlc_tabs[10];
1258
                        delta = bitstream_read_vlc(bc, tab->table, tab->bits, 1);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1259 1260 1261 1262 1263 1264 1265 1266 1267
                        if (more_than_ref)
                            dst->loc_code[i] = dst->loc_code[i - 1] + delta;
                        else
                            dst->loc_code[i] = (ref->loc_code[i] + delta) & 0x1F;
                    }
                }
            }
        } else /* VLC delta to previous */
            for (sb = 0; sb < coded_subbands; sb++)
1268
                gainc_loc_mode1(bc, ctx, &chan->gain_data[sb]);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1269 1270 1271 1272 1273 1274 1275 1276
        break;
    case 2:
        if (ch_num) {
            for (sb = 0; sb < coded_subbands; sb++) {
                if (chan->gain_data[sb].num_points <= 0)
                    continue;
                dst = &chan->gain_data[sb];
                ref = &ref_chan->gain_data[sb];
1277 1278
                if (dst->num_points > ref->num_points || bitstream_read_bit(bc))
                    gainc_loc_mode1(bc, ctx, dst);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1279 1280 1281 1282 1283 1284 1285
                else /* clone master for the whole subband */
                    for (i = 0; i < chan->gain_data[sb].num_points; i++)
                        dst->loc_code[i] = ref->loc_code[i];
            }
        } else {
            /* data for the first subband is coded directly */
            for (i = 0; i < chan->gain_data[0].num_points; i++)
1286
                gainc_loc_mode0(bc, ctx, &chan->gain_data[0], i);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1287 1288 1289 1290 1291 1292 1293 1294

            for (sb = 1; sb < coded_subbands; sb++) {
                if (chan->gain_data[sb].num_points <= 0)
                    continue;
                dst = &chan->gain_data[sb];

                /* 1st value is vlc-coded modulo delta to the corresponding
                 * value of the previous subband if any or zero */
1295 1296
                delta = bitstream_read_vlc(bc, gain_vlc_tabs[6].table,
                                           gain_vlc_tabs[6].bits, 1);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1297 1298 1299 1300 1301 1302 1303 1304 1305 1306
                pred             = dst[-1].num_points > 0
                                   ? dst[-1].loc_code[0] : 0;
                dst->loc_code[0] = (pred + delta) & 0x1F;

                for (i = 1; i < dst->num_points; i++) {
                    more_than_ref = i >= dst[-1].num_points;
                    /* Select VLC table according to curve direction and
                     * presence of prediction. */
                    tab = &gain_vlc_tabs[(dst->lev_code[i] > dst->lev_code[i - 1]) *
                                                   2 + more_than_ref + 6];
1307
                    delta = bitstream_read_vlc(bc, tab->table, tab->bits, 1);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320
                    if (more_than_ref)
                        dst->loc_code[i] = dst->loc_code[i - 1] + delta;
                    else
                        dst->loc_code[i] = (dst[-1].loc_code[i] + delta) & 0x1F;
                }
            }
        }
        break;
    case 3:
        if (ch_num) { /* clone master or direct or direct coding */
            for (sb = 0; sb < coded_subbands; sb++)
                for (i = 0; i < chan->gain_data[sb].num_points; i++) {
                    if (i >= ref_chan->gain_data[sb].num_points)
1321
                        gainc_loc_mode0(bc, ctx, &chan->gain_data[sb], i);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1322 1323 1324 1325 1326
                    else
                        chan->gain_data[sb].loc_code[i] =
                            ref_chan->gain_data[sb].loc_code[i];
                }
        } else { /* shorter delta to min */
1327 1328
            delta_bits = bitstream_read(bc, 2) + 1;
            min_val    = bitstream_read(bc, 5);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1329 1330 1331 1332

            for (sb = 0; sb < coded_subbands; sb++)
                for (i = 0; i < chan->gain_data[sb].num_points; i++)
                    chan->gain_data[sb].loc_code[i] = min_val + i +
1333
                                                      bitstream_read(bc, delta_bits);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357
        }
        break;
    }

    /* Validate decoded information */
    for (sb = 0; sb < coded_subbands; sb++) {
        dst = &chan->gain_data[sb];
        for (i = 0; i < chan->gain_data[sb].num_points; i++) {
            if (dst->loc_code[i] < 0 || dst->loc_code[i] > 31 ||
                (i && dst->loc_code[i] <= dst->loc_code[i - 1])) {
                av_log(avctx, AV_LOG_ERROR,
                       "Invalid gain location: ch=%d, sb=%d, pos=%d, val=%d\n",
                       ch_num, sb, i, dst->loc_code[i]);
                return AVERROR_INVALIDDATA;
            }
        }
    }

    return 0;
}

/**
 * Decode gain control data for all channels.
 *
1358
 * @param[in]     bc            the Bitstream context
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1359 1360 1361 1362 1363
 * @param[in,out] ctx           ptr to the channel unit context
 * @param[in]     num_channels  number of channels to process
 * @param[in]     avctx         ptr to the AVCodecContext
 * @return result code: 0 = OK, otherwise - error code
 */
1364
static int decode_gainc_data(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx,
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1365 1366 1367 1368 1369 1370 1371 1372
                             int num_channels, AVCodecContext *avctx)
{
    int ch_num, coded_subbands, sb, ret;

    for (ch_num = 0; ch_num < num_channels; ch_num++) {
        memset(ctx->channels[ch_num].gain_data, 0,
               sizeof(*ctx->channels[ch_num].gain_data) * ATRAC3P_SUBBANDS);

1373 1374 1375 1376
        if (bitstream_read_bit(bc)) { /* gain control data present? */
            coded_subbands = bitstream_read(bc, 4) + 1;
            if (bitstream_read_bit(bc)) /* is high band gain data replication on? */
                ctx->channels[ch_num].num_gain_subbands = bitstream_read(bc, 4) + 1;
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1377 1378 1379
            else
                ctx->channels[ch_num].num_gain_subbands = coded_subbands;

1380 1381 1382
            if ((ret = decode_gainc_npoints(bc, ctx, ch_num, coded_subbands)) < 0 ||
                (ret = decode_gainc_levels(bc, ctx, ch_num, coded_subbands))  < 0 ||
                (ret = decode_gainc_loc_codes(bc, ctx, ch_num, coded_subbands, avctx)) < 0)
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400
                return ret;

            if (coded_subbands > 0) { /* propagate gain data if requested */
                for (sb = coded_subbands; sb < ctx->channels[ch_num].num_gain_subbands; sb++)
                    ctx->channels[ch_num].gain_data[sb] =
                        ctx->channels[ch_num].gain_data[sb - 1];
            }
        } else {
            ctx->channels[ch_num].num_gain_subbands = 0;
        }
    }

    return 0;
}

/**
 * Decode envelope for all tones of a channel.
 *
1401
 * @param[in]     bc                the Bitstream context
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1402 1403 1404 1405 1406
 * @param[in,out] ctx               ptr to the channel unit context
 * @param[in]     ch_num            channel to process
 * @param[in]     band_has_tones    ptr to an array of per-band-flags:
 *                                  1 - tone data present
 */
1407
static void decode_tones_envelope(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx,
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1408 1409 1410 1411 1412 1413
                                  int ch_num, int band_has_tones[])
{
    int sb;
    Atrac3pWavesData *dst = ctx->channels[ch_num].tones_info;
    Atrac3pWavesData *ref = ctx->channels[0].tones_info;

1414
    if (!ch_num || !bitstream_read_bit(bc)) { /* mode 0: fixed-length coding */
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1415 1416 1417
        for (sb = 0; sb < ctx->waves_info->num_tone_bands; sb++) {
            if (!band_has_tones[sb])
                continue;
1418
            dst[sb].pend_env.has_start_point = bitstream_read_bit(bc);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1419
            dst[sb].pend_env.start_pos       = dst[sb].pend_env.has_start_point
1420 1421
                                               ? bitstream_read(bc, 5) : -1;
            dst[sb].pend_env.has_stop_point  = bitstream_read_bit(bc);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1422
            dst[sb].pend_env.stop_pos        = dst[sb].pend_env.has_stop_point
1423
                                               ? bitstream_read(bc, 5) : 32;
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439
        }
    } else { /* mode 1(slave only): copy master */
        for (sb = 0; sb < ctx->waves_info->num_tone_bands; sb++) {
            if (!band_has_tones[sb])
                continue;
            dst[sb].pend_env.has_start_point = ref[sb].pend_env.has_start_point;
            dst[sb].pend_env.has_stop_point  = ref[sb].pend_env.has_stop_point;
            dst[sb].pend_env.start_pos       = ref[sb].pend_env.start_pos;
            dst[sb].pend_env.stop_pos        = ref[sb].pend_env.stop_pos;
        }
    }
}

/**
 * Decode number of tones for each subband of a channel.
 *
1440
 * @param[in]     bc                the Bitstream context
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1441 1442 1443 1444 1445 1446 1447
 * @param[in,out] ctx               ptr to the channel unit context
 * @param[in]     ch_num            channel to process
 * @param[in]     band_has_tones    ptr to an array of per-band-flags:
 *                                  1 - tone data present
 * @param[in]     avctx             ptr to the AVCodecContext
 * @return result code: 0 = OK, otherwise - error code
 */
1448
static int decode_band_numwavs(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx,
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1449 1450 1451 1452 1453 1454 1455
                               int ch_num, int band_has_tones[],
                               AVCodecContext *avctx)
{
    int mode, sb, delta;
    Atrac3pWavesData *dst = ctx->channels[ch_num].tones_info;
    Atrac3pWavesData *ref = ctx->channels[0].tones_info;

1456
    mode = bitstream_read(bc, ch_num + 1);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1457 1458 1459 1460
    switch (mode) {
    case 0: /** fixed-length coding */
        for (sb = 0; sb < ctx->waves_info->num_tone_bands; sb++)
            if (band_has_tones[sb])
1461
                dst[sb].num_wavs = bitstream_read(bc, 4);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1462 1463 1464 1465 1466
        break;
    case 1: /** variable-length coding */
        for (sb = 0; sb < ctx->waves_info->num_tone_bands; sb++)
            if (band_has_tones[sb])
                dst[sb].num_wavs =
1467 1468
                    bitstream_read_vlc(bc, tone_vlc_tabs[1].table,
                                       tone_vlc_tabs[1].bits, 1);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1469 1470 1471 1472
        break;
    case 2: /** VLC modulo delta to master (slave only) */
        for (sb = 0; sb < ctx->waves_info->num_tone_bands; sb++)
            if (band_has_tones[sb]) {
1473 1474
                delta = bitstream_read_vlc(bc, tone_vlc_tabs[2].table,
                                           tone_vlc_tabs[2].bits, 1);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505
                delta = sign_extend(delta, 3);
                dst[sb].num_wavs = (ref[sb].num_wavs + delta) & 0xF;
            }
        break;
    case 3: /** copy master (slave only) */
        for (sb = 0; sb < ctx->waves_info->num_tone_bands; sb++)
            if (band_has_tones[sb])
                dst[sb].num_wavs = ref[sb].num_wavs;
        break;
    }

    /** initialize start tone index for each subband */
    for (sb = 0; sb < ctx->waves_info->num_tone_bands; sb++)
        if (band_has_tones[sb]) {
            if (ctx->waves_info->tones_index + dst[sb].num_wavs > 48) {
                av_log(avctx, AV_LOG_ERROR,
                       "Too many tones: %d (max. 48), frame: %d!\n",
                       ctx->waves_info->tones_index + dst[sb].num_wavs,
                       avctx->frame_number);
                return AVERROR_INVALIDDATA;
            }
            dst[sb].start_index           = ctx->waves_info->tones_index;
            ctx->waves_info->tones_index += dst[sb].num_wavs;
        }

    return 0;
}

/**
 * Decode frequency information for each subband of a channel.
 *
1506
 * @param[in]     bc                the Bitstream context
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1507 1508 1509 1510 1511
 * @param[in,out] ctx               ptr to the channel unit context
 * @param[in]     ch_num            channel to process
 * @param[in]     band_has_tones    ptr to an array of per-band-flags:
 *                                  1 - tone data present
 */
1512
static void decode_tones_frequency(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx,
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1513 1514 1515 1516 1517 1518 1519
                                   int ch_num, int band_has_tones[])
{
    int sb, i, direction, nbits, pred, delta;
    Atrac3pWaveParam *iwav, *owav;
    Atrac3pWavesData *dst = ctx->channels[ch_num].tones_info;
    Atrac3pWavesData *ref = ctx->channels[0].tones_info;

1520
    if (!ch_num || !bitstream_read_bit(bc)) { /* mode 0: fixed-length coding */
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1521 1522 1523 1524
        for (sb = 0; sb < ctx->waves_info->num_tone_bands; sb++) {
            if (!band_has_tones[sb] || !dst[sb].num_wavs)
                continue;
            iwav      = &ctx->waves_info->waves[dst[sb].start_index];
1525
            direction = (dst[sb].num_wavs > 1) ? bitstream_read_bit(bc) : 0;
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1526 1527
            if (direction) { /** packed numbers in descending order */
                if (dst[sb].num_wavs)
1528
                    iwav[dst[sb].num_wavs - 1].freq_index = bitstream_read(bc, 10);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1529 1530
                for (i = dst[sb].num_wavs - 2; i >= 0 ; i--) {
                    nbits = av_log2(iwav[i+1].freq_index) + 1;
1531
                    iwav[i].freq_index = bitstream_read(bc, nbits);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1532 1533 1534 1535
                }
            } else { /** packed numbers in ascending order */
                for (i = 0; i < dst[sb].num_wavs; i++) {
                    if (!i || iwav[i - 1].freq_index < 512)
1536
                        iwav[i].freq_index = bitstream_read(bc, 10);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1537 1538
                    else {
                        nbits = av_log2(1023 - iwav[i - 1].freq_index) + 1;
1539
                        iwav[i].freq_index = bitstream_read(bc, nbits) +
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551
                                             1024 - (1 << nbits);
                    }
                }
            }
        }
    } else { /* mode 1: VLC modulo delta to master (slave only) */
        for (sb = 0; sb < ctx->waves_info->num_tone_bands; sb++) {
            if (!band_has_tones[sb] || !dst[sb].num_wavs)
                continue;
            iwav = &ctx->waves_info->waves[ref[sb].start_index];
            owav = &ctx->waves_info->waves[dst[sb].start_index];
            for (i = 0; i < dst[sb].num_wavs; i++) {
1552 1553
                delta = bitstream_read_vlc(bc, tone_vlc_tabs[6].table,
                                           tone_vlc_tabs[6].bits, 1);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565
                delta = sign_extend(delta, 8);
                pred  = (i < ref[sb].num_wavs) ? iwav[i].freq_index :
                        (ref[sb].num_wavs ? iwav[ref[sb].num_wavs - 1].freq_index : 0);
                owav[i].freq_index = (pred + delta) & 0x3FF;
            }
        }
    }
}

/**
 * Decode amplitude information for each subband of a channel.
 *
1566
 * @param[in]     bc                the Bitstream context
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1567 1568 1569 1570 1571
 * @param[in,out] ctx               ptr to the channel unit context
 * @param[in]     ch_num            channel to process
 * @param[in]     band_has_tones    ptr to an array of per-band-flags:
 *                                  1 - tone data present
 */
1572
static void decode_tones_amplitude(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx,
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1573 1574 1575 1576
                                   int ch_num, int band_has_tones[])
{
    int mode, sb, j, i, diff, maxdiff, fi, delta, pred;
    Atrac3pWaveParam *wsrc, *wref;
1577
    int refwaves[48] = { 0 };
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605
    Atrac3pWavesData *dst = ctx->channels[ch_num].tones_info;
    Atrac3pWavesData *ref = ctx->channels[0].tones_info;

    if (ch_num) {
        for (sb = 0; sb < ctx->waves_info->num_tone_bands; sb++) {
            if (!band_has_tones[sb] || !dst[sb].num_wavs)
                continue;
            wsrc = &ctx->waves_info->waves[dst[sb].start_index];
            wref = &ctx->waves_info->waves[ref[sb].start_index];
            for (j = 0; j < dst[sb].num_wavs; j++) {
                for (i = 0, fi = 0, maxdiff = 1024; i < ref[sb].num_wavs; i++) {
                    diff = FFABS(wsrc[j].freq_index - wref[i].freq_index);
                    if (diff < maxdiff) {
                        maxdiff = diff;
                        fi      = i;
                    }
                }

                if (maxdiff < 8)
                    refwaves[dst[sb].start_index + j] = fi + ref[sb].start_index;
                else if (j < ref[sb].num_wavs)
                    refwaves[dst[sb].start_index + j] = j + ref[sb].start_index;
                else
                    refwaves[dst[sb].start_index + j] = -1;
            }
        }
    }

1606
    mode = bitstream_read(bc, ch_num + 1);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1607 1608 1609 1610 1611 1612 1613 1614

    switch (mode) {
    case 0: /** fixed-length coding */
        for (sb = 0; sb < ctx->waves_info->num_tone_bands; sb++) {
            if (!band_has_tones[sb] || !dst[sb].num_wavs)
                continue;
            if (ctx->waves_info->amplitude_mode)
                for (i = 0; i < dst[sb].num_wavs; i++)
1615
                    ctx->waves_info->waves[dst[sb].start_index + i].amp_sf = bitstream_read(bc, 6);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1616
            else
1617
                ctx->waves_info->waves[dst[sb].start_index].amp_sf = bitstream_read(bc, 6);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1618 1619 1620 1621 1622 1623 1624 1625 1626
        }
        break;
    case 1: /** min + VLC delta */
        for (sb = 0; sb < ctx->waves_info->num_tone_bands; sb++) {
            if (!band_has_tones[sb] || !dst[sb].num_wavs)
                continue;
            if (ctx->waves_info->amplitude_mode)
                for (i = 0; i < dst[sb].num_wavs; i++)
                    ctx->waves_info->waves[dst[sb].start_index + i].amp_sf =
1627 1628
                        bitstream_read_vlc(bc, tone_vlc_tabs[3].table,
                                           tone_vlc_tabs[3].bits, 1) + 20;
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1629 1630
            else
                ctx->waves_info->waves[dst[sb].start_index].amp_sf =
1631 1632
                    bitstream_read_vlc(bc, tone_vlc_tabs[4].table,
                                       tone_vlc_tabs[4].bits, 1) + 24;
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1633 1634 1635 1636 1637 1638 1639
        }
        break;
    case 2: /** VLC modulo delta to master (slave only) */
        for (sb = 0; sb < ctx->waves_info->num_tone_bands; sb++) {
            if (!band_has_tones[sb] || !dst[sb].num_wavs)
                continue;
            for (i = 0; i < dst[sb].num_wavs; i++) {
1640 1641
                delta = bitstream_read_vlc(bc, tone_vlc_tabs[5].table,
                                           tone_vlc_tabs[5].bits, 1);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665
                delta = sign_extend(delta, 5);
                pred  = refwaves[dst[sb].start_index + i] >= 0 ?
                        ctx->waves_info->waves[refwaves[dst[sb].start_index + i]].amp_sf : 34;
                ctx->waves_info->waves[dst[sb].start_index + i].amp_sf = (pred + delta) & 0x3F;
            }
        }
        break;
    case 3: /** clone master (slave only) */
        for (sb = 0; sb < ctx->waves_info->num_tone_bands; sb++) {
            if (!band_has_tones[sb])
                continue;
            for (i = 0; i < dst[sb].num_wavs; i++)
                ctx->waves_info->waves[dst[sb].start_index + i].amp_sf =
                    refwaves[dst[sb].start_index + i] >= 0
                    ? ctx->waves_info->waves[refwaves[dst[sb].start_index + i]].amp_sf
                    : 32;
        }
        break;
    }
}

/**
 * Decode phase information for each subband of a channel.
 *
1666
 * @param[in]     bc                the Bitstream context
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1667 1668 1669 1670 1671
 * @param[in,out] ctx               ptr to the channel unit context
 * @param[in]     ch_num            channel to process
 * @param[in]     band_has_tones    ptr to an array of per-band-flags:
 *                                  1 - tone data present
 */
1672
static void decode_tones_phase(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx,
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683
                               int ch_num, int band_has_tones[])
{
    int sb, i;
    Atrac3pWaveParam *wparam;
    Atrac3pWavesData *dst = ctx->channels[ch_num].tones_info;

    for (sb = 0; sb < ctx->waves_info->num_tone_bands; sb++) {
        if (!band_has_tones[sb])
            continue;
        wparam = &ctx->waves_info->waves[dst[sb].start_index];
        for (i = 0; i < dst[sb].num_wavs; i++)
1684
            wparam[i].phase_index = bitstream_read(bc, 5);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1685 1686 1687 1688 1689 1690
    }
}

/**
 * Decode tones info for all channels.
 *
1691
 * @param[in]     bc            the Bitstream context
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1692 1693 1694 1695 1696
 * @param[in,out] ctx           ptr to the channel unit context
 * @param[in]     num_channels  number of channels to process
 * @param[in]     avctx         ptr to the AVCodecContext
 * @return result code: 0 = OK, otherwise - error code
 */
1697
static int decode_tones_info(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx,
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1698 1699 1700 1701 1702 1703 1704 1705 1706
                             int num_channels, AVCodecContext *avctx)
{
    int ch_num, i, ret;
    int band_has_tones[16];

    for (ch_num = 0; ch_num < num_channels; ch_num++)
        memset(ctx->channels[ch_num].tones_info, 0,
               sizeof(*ctx->channels[ch_num].tones_info) * ATRAC3P_SUBBANDS);

1707
    ctx->waves_info->tones_present = bitstream_read_bit(bc);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1708 1709 1710 1711 1712
    if (!ctx->waves_info->tones_present)
        return 0;

    memset(ctx->waves_info->waves, 0, sizeof(ctx->waves_info->waves));

1713
    ctx->waves_info->amplitude_mode = bitstream_read_bit(bc);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1714 1715 1716 1717 1718 1719
    if (!ctx->waves_info->amplitude_mode) {
        avpriv_report_missing_feature(avctx, "GHA amplitude mode 0");
        return AVERROR_PATCHWELCOME;
    }

    ctx->waves_info->num_tone_bands =
1720 1721
        bitstream_read_vlc(bc, tone_vlc_tabs[0].table,
                           tone_vlc_tabs[0].bits, 1) + 1;
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1722 1723

    if (num_channels == 2) {
1724 1725 1726
        get_subband_flags(bc, ctx->waves_info->tone_sharing, ctx->waves_info->num_tone_bands);
        get_subband_flags(bc, ctx->waves_info->tone_master,  ctx->waves_info->num_tone_bands);
        if (get_subband_flags(bc, ctx->waves_info->phase_shift,
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738
                              ctx->waves_info->num_tone_bands)) {
            avpriv_report_missing_feature(avctx, "GHA Phase shifting");
            return AVERROR_PATCHWELCOME;
        }
    }

    ctx->waves_info->tones_index = 0;

    for (ch_num = 0; ch_num < num_channels; ch_num++) {
        for (i = 0; i < ctx->waves_info->num_tone_bands; i++)
            band_has_tones[i] = !ch_num ? 1 : !ctx->waves_info->tone_sharing[i];

1739 1740
        decode_tones_envelope(bc, ctx, ch_num, band_has_tones);
        if ((ret = decode_band_numwavs(bc, ctx, ch_num, band_has_tones,
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1741 1742 1743
                                       avctx)) < 0)
            return ret;

1744 1745 1746
        decode_tones_frequency(bc, ctx, ch_num, band_has_tones);
        decode_tones_amplitude(bc, ctx, ch_num, band_has_tones);
        decode_tones_phase(bc, ctx, ch_num, band_has_tones);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762
    }

    if (num_channels == 2) {
        for (i = 0; i < ctx->waves_info->num_tone_bands; i++) {
            if (ctx->waves_info->tone_sharing[i])
                ctx->channels[1].tones_info[i] = ctx->channels[0].tones_info[i];

            if (ctx->waves_info->tone_master[i])
                FFSWAP(Atrac3pWavesData, ctx->channels[0].tones_info[i],
                       ctx->channels[1].tones_info[i]);
        }
    }

    return 0;
}

1763
int ff_atrac3p_decode_channel_unit(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx,
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1764 1765 1766 1767 1768
                                   int num_channels, AVCodecContext *avctx)
{
    int ret;

    /* parse sound header */
1769
    ctx->num_quant_units = bitstream_read(bc, 5) + 1;
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1770 1771 1772 1773 1774 1775 1776
    if (ctx->num_quant_units > 28 && ctx->num_quant_units < 32) {
        av_log(avctx, AV_LOG_ERROR,
               "Invalid number of quantization units: %d!\n",
               ctx->num_quant_units);
        return AVERROR_INVALIDDATA;
    }

1777
    ctx->mute_flag = bitstream_read_bit(bc);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1778 1779

    /* decode various sound parameters */
1780
    if ((ret = decode_quant_wordlen(bc, ctx, num_channels, avctx)) < 0)
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1781 1782 1783 1784 1785 1786 1787
        return ret;

    ctx->num_subbands       = atrac3p_qu_to_subband[ctx->num_quant_units - 1] + 1;
    ctx->num_coded_subbands = ctx->used_quant_units
                              ? atrac3p_qu_to_subband[ctx->used_quant_units - 1] + 1
                              : 0;

1788
    if ((ret = decode_scale_factors(bc, ctx, num_channels, avctx)) < 0)
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1789 1790
        return ret;

1791
    if ((ret = decode_code_table_indexes(bc, ctx, num_channels, avctx)) < 0)
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1792 1793
        return ret;

1794
    decode_spectrum(bc, ctx, num_channels, avctx);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1795 1796

    if (num_channels == 2) {
1797 1798
        get_subband_flags(bc, ctx->swap_channels, ctx->num_coded_subbands);
        get_subband_flags(bc, ctx->negate_coeffs, ctx->num_coded_subbands);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1799 1800
    }

1801
    decode_window_shape(bc, ctx, num_channels);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1802

1803
    if ((ret = decode_gainc_data(bc, ctx, num_channels, avctx)) < 0)
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1804 1805
        return ret;

1806
    if ((ret = decode_tones_info(bc, ctx, num_channels, avctx)) < 0)
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1807 1808 1809
        return ret;

    /* decode global noise info */
1810
    ctx->noise_present = bitstream_read_bit(bc);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1811
    if (ctx->noise_present) {
1812 1813
        ctx->noise_level_index = bitstream_read(bc, 4);
        ctx->noise_table_index = bitstream_read(bc, 4);
Maxim Polijakowski's avatar
Maxim Polijakowski committed
1814 1815 1816 1817
    }

    return 0;
}