imc.c 33.8 KB
Newer Older
Kostya Shishkov's avatar
Kostya Shishkov 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
/*
 * IMC compatible decoder
 * Copyright (c) 2002-2004 Maxim Poliakovski
 * Copyright (c) 2006 Benjamin Larsson
 * Copyright (c) 2006 Konstantin Shishkov
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/**
25 26
 *  @file
 *  IMC - Intel Music Coder
Kostya Shishkov's avatar
Kostya Shishkov committed
27
 *  A mdct based codec using a 256 points large transform
Kostya Shishkov's avatar
Kostya Shishkov committed
28
 *  divided into 32 bands with some mix of scale factors.
Kostya Shishkov's avatar
Kostya Shishkov committed
29 30 31 32 33 34 35 36
 *  Only mono is supported.
 */


#include <math.h>
#include <stddef.h>
#include <stdio.h>

37
#include "libavutil/channel_layout.h"
38
#include "libavutil/ffmath.h"
39
#include "libavutil/float_dsp.h"
40
#include "libavutil/internal.h"
Kostya Shishkov's avatar
Kostya Shishkov committed
41
#include "avcodec.h"
42
#include "bswapdsp.h"
43
#include "get_bits.h"
44
#include "fft.h"
45
#include "internal.h"
46
#include "sinewin.h"
Kostya Shishkov's avatar
Kostya Shishkov committed
47 48 49

#include "imcdata.h"

50
#define IMC_BLOCK_SIZE 64
Kostya Shishkov's avatar
Kostya Shishkov committed
51 52 53 54
#define IMC_FRAME_ID 0x21
#define BANDS 32
#define COEFFS 256

55
typedef struct IMCChannel {
Kostya Shishkov's avatar
Kostya Shishkov committed
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
    float old_floor[BANDS];
    float flcoeffs1[BANDS];
    float flcoeffs2[BANDS];
    float flcoeffs3[BANDS];
    float flcoeffs4[BANDS];
    float flcoeffs5[BANDS];
    float flcoeffs6[BANDS];
    float CWdecoded[COEFFS];

    int bandWidthT[BANDS];     ///< codewords per band
    int bitsBandT[BANDS];      ///< how many bits per codeword in band
    int CWlengthT[COEFFS];     ///< how many bits in each codeword
    int levlCoeffBuf[BANDS];
    int bandFlagsBuf[BANDS];   ///< flags for each band
    int sumLenArr[BANDS];      ///< bits for all coeffs in band
    int skipFlagRaw[BANDS];    ///< skip flags are stored in raw form or not
    int skipFlagBits[BANDS];   ///< bits used to code skip flags
73
    int skipFlagCount[BANDS];  ///< skipped coefficients per band
Kostya Shishkov's avatar
Kostya Shishkov committed
74 75
    int skipFlags[COEFFS];     ///< skip coefficient decoding or not
    int codewords[COEFFS];     ///< raw codewords read from bitstream
76 77 78 79 80 81

    float last_fft_im[COEFFS];

    int decoder_reset;
} IMCChannel;

82
typedef struct IMCContext {
Kostya Shishkov's avatar
Kostya Shishkov committed
83
    IMCChannel chctx[2];
84 85 86 87 88 89 90 91 92 93

    /** MDCT tables */
    //@{
    float mdct_sine_window[COEFFS];
    float post_cos[COEFFS];
    float post_sin[COEFFS];
    float pre_coef1[COEFFS];
    float pre_coef2[COEFFS];
    //@}

Kostya Shishkov's avatar
Kostya Shishkov committed
94 95 96
    float sqrt_tab[30];
    GetBitContext gb;

97
    BswapDSPContext bdsp;
98
    AVFloatDSPContext *fdsp;
Kostya Shishkov's avatar
Kostya Shishkov committed
99
    FFTContext fft;
Kostya Shishkov's avatar
Kostya Shishkov committed
100
    DECLARE_ALIGNED(32, FFTComplex, samples)[COEFFS / 2];
101
    float *out_samples;
Kostya Shishkov's avatar
Kostya Shishkov committed
102

Kostya Shishkov's avatar
Kostya Shishkov committed
103 104
    int coef0_pos;

Kostya Shishkov's avatar
Kostya Shishkov committed
105 106
    int8_t cyclTab[32], cyclTab2[32];
    float  weights1[31], weights2[31];
Kostya Shishkov's avatar
Kostya Shishkov committed
107 108
} IMCContext;

109 110 111 112 113 114
static VLC huffman_vlc[4][4];

#define VLC_TABLES_SIZE 9512

static const int vlc_offsets[17] = {
    0,     640, 1156, 1732, 2308, 2852, 3396, 3924,
Kostya Shishkov's avatar
Kostya Shishkov committed
115 116
    4452, 5220, 5860, 6628, 7268, 7908, 8424, 8936, VLC_TABLES_SIZE
};
117 118

static VLC_TYPE vlc_tables[VLC_TABLES_SIZE][2];
Kostya Shishkov's avatar
Kostya Shishkov committed
119

120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
static inline double freq2bark(double freq)
{
    return 3.5 * atan((freq / 7500.0) * (freq / 7500.0)) + 13.0 * atan(freq * 0.00076);
}

static av_cold void iac_generate_tabs(IMCContext *q, int sampling_rate)
{
    double freqmin[32], freqmid[32], freqmax[32];
    double scale = sampling_rate / (256.0 * 2.0 * 2.0);
    double nyquist_freq = sampling_rate * 0.5;
    double freq, bark, prev_bark = 0, tf, tb;
    int i, j;

    for (i = 0; i < 32; i++) {
        freq = (band_tab[i] + band_tab[i + 1] - 1) * scale;
        bark = freq2bark(freq);

        if (i > 0) {
            tb = bark - prev_bark;
139 140
            q->weights1[i - 1] = ff_exp10(-1.0 * tb);
            q->weights2[i - 1] = ff_exp10(-2.7 * tb);
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
        }
        prev_bark = bark;

        freqmid[i] = freq;

        tf = freq;
        while (tf < nyquist_freq) {
            tf += 0.5;
            tb =  freq2bark(tf);
            if (tb > bark + 0.5)
                break;
        }
        freqmax[i] = tf;

        tf = freq;
        while (tf > 0.0) {
            tf -= 0.5;
            tb =  freq2bark(tf);
            if (tb <= bark - 0.5)
                break;
        }
        freqmin[i] = tf;
    }

    for (i = 0; i < 32; i++) {
        freq = freqmax[i];
        for (j = 31; j > 0 && freq <= freqmid[j]; j--);
        q->cyclTab[i] = j + 1;

        freq = freqmin[i];
        for (j = 0; j < 32 && freq >= freqmid[j]; j++);
        q->cyclTab2[i] = j - 1;
    }
}

Kostya Shishkov's avatar
Kostya Shishkov committed
176
static av_cold int imc_decode_init(AVCodecContext *avctx)
Kostya Shishkov's avatar
Kostya Shishkov committed
177
{
178
    int i, j, ret;
Kostya Shishkov's avatar
Kostya Shishkov committed
179 180 181
    IMCContext *q = avctx->priv_data;
    double r1, r2;

182 183 184 185 186 187 188 189
    if (avctx->codec_id == AV_CODEC_ID_IAC && avctx->sample_rate > 96000) {
        av_log(avctx, AV_LOG_ERROR,
               "Strange sample rate of %i, file likely corrupt or "
               "needing a new table derivation method.\n",
               avctx->sample_rate);
        return AVERROR_PATCHWELCOME;
    }

190 191 192 193
    if (avctx->codec_id == AV_CODEC_ID_IMC)
        avctx->channels = 1;

    if (avctx->channels > 2) {
194
        avpriv_request_sample(avctx, "Number of channels > 2");
195 196 197
        return AVERROR_PATCHWELCOME;
    }

198 199
    for (j = 0; j < avctx->channels; j++) {
        q->chctx[j].decoder_reset = 1;
Kostya Shishkov's avatar
Kostya Shishkov committed
200

201 202 203 204 205 206
        for (i = 0; i < BANDS; i++)
            q->chctx[j].old_floor[i] = 1.0;

        for (i = 0; i < COEFFS / 2; i++)
            q->chctx[j].last_fft_im[i] = 0;
    }
Kostya Shishkov's avatar
Kostya Shishkov committed
207 208

    /* Build mdct window, a simple sine window normalized with sqrt(2) */
209
    ff_sine_window_init(q->mdct_sine_window, COEFFS);
Kostya Shishkov's avatar
Kostya Shishkov committed
210
    for (i = 0; i < COEFFS; i++)
211
        q->mdct_sine_window[i] *= sqrt(2.0);
Kostya Shishkov's avatar
Kostya Shishkov committed
212
    for (i = 0; i < COEFFS / 2; i++) {
213 214
        q->post_cos[i] = (1.0f / 32768) * cos(i / 256.0 * M_PI);
        q->post_sin[i] = (1.0f / 32768) * sin(i / 256.0 * M_PI);
Kostya Shishkov's avatar
Kostya Shishkov committed
215 216 217 218

        r1 = sin((i * 4.0 + 1.0) / 1024.0 * M_PI);
        r2 = cos((i * 4.0 + 1.0) / 1024.0 * M_PI);

Kostya Shishkov's avatar
Kostya Shishkov committed
219
        if (i & 0x1) {
Kostya Shishkov's avatar
Kostya Shishkov committed
220 221
            q->pre_coef1[i] =  (r1 + r2) * sqrt(2.0);
            q->pre_coef2[i] = -(r1 - r2) * sqrt(2.0);
Kostya Shishkov's avatar
Kostya Shishkov committed
222
        } else {
Kostya Shishkov's avatar
Kostya Shishkov committed
223 224 225 226 227 228 229
            q->pre_coef1[i] = -(r1 + r2) * sqrt(2.0);
            q->pre_coef2[i] =  (r1 - r2) * sqrt(2.0);
        }
    }

    /* Generate a square root table */

Kostya Shishkov's avatar
Kostya Shishkov committed
230
    for (i = 0; i < 30; i++)
Kostya Shishkov's avatar
Kostya Shishkov committed
231 232 233
        q->sqrt_tab[i] = sqrt(i);

    /* initialize the VLC tables */
Kostya Shishkov's avatar
Kostya Shishkov committed
234 235
    for (i = 0; i < 4 ; i++) {
        for (j = 0; j < 4; j++) {
236
            huffman_vlc[i][j].table = &vlc_tables[vlc_offsets[i * 4 + j]];
237 238
            huffman_vlc[i][j].table_allocated = vlc_offsets[i * 4 + j + 1] - vlc_offsets[i * 4 + j];
            init_vlc(&huffman_vlc[i][j], 9, imc_huffman_sizes[i],
Kostya Shishkov's avatar
Kostya Shishkov committed
239
                     imc_huffman_lens[i][j], 1, 1,
240
                     imc_huffman_bits[i][j], 2, 2, INIT_VLC_USE_NEW_STATIC);
Kostya Shishkov's avatar
Kostya Shishkov committed
241 242
        }
    }
243

244
    if (avctx->codec_id == AV_CODEC_ID_IAC) {
245
        iac_generate_tabs(q, avctx->sample_rate);
Kostya Shishkov's avatar
Kostya Shishkov committed
246
    } else {
247 248
        memcpy(q->cyclTab,  cyclTab,  sizeof(cyclTab));
        memcpy(q->cyclTab2, cyclTab2, sizeof(cyclTab2));
Kostya Shishkov's avatar
Kostya Shishkov committed
249 250 251 252
        memcpy(q->weights1, imc_weights1, sizeof(imc_weights1));
        memcpy(q->weights2, imc_weights2, sizeof(imc_weights2));
    }

253 254 255 256
    if ((ret = ff_fft_init(&q->fft, 7, 1))) {
        av_log(avctx, AV_LOG_INFO, "FFT init failed\n");
        return ret;
    }
257
    ff_bswapdsp_init(&q->bdsp);
258
    q->fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT);
259 260 261 262 263 264
    if (!q->fdsp) {
        ff_fft_end(&q->fft);

        return AVERROR(ENOMEM);
    }

265
    avctx->sample_fmt     = AV_SAMPLE_FMT_FLTP;
266 267
    avctx->channel_layout = avctx->channels == 1 ? AV_CH_LAYOUT_MONO
                                                 : AV_CH_LAYOUT_STEREO;
268

Kostya Shishkov's avatar
Kostya Shishkov committed
269 270 271
    return 0;
}

Kostya Shishkov's avatar
Kostya Shishkov committed
272 273 274
static void imc_calculate_coeffs(IMCContext *q, float *flcoeffs1,
                                 float *flcoeffs2, int *bandWidthT,
                                 float *flcoeffs3, float *flcoeffs5)
Kostya Shishkov's avatar
Kostya Shishkov committed
275 276 277 278 279 280 281 282
{
    float   workT1[BANDS];
    float   workT2[BANDS];
    float   workT3[BANDS];
    float   snr_limit = 1.e-30;
    float   accum = 0.0;
    int i, cnt2;

Kostya Shishkov's avatar
Kostya Shishkov committed
283
    for (i = 0; i < BANDS; i++) {
Kostya Shishkov's avatar
Kostya Shishkov committed
284
        flcoeffs5[i] = workT2[i] = 0.0;
Kostya Shishkov's avatar
Kostya Shishkov committed
285
        if (bandWidthT[i]) {
Kostya Shishkov's avatar
Kostya Shishkov committed
286 287 288
            workT1[i] = flcoeffs1[i] * flcoeffs1[i];
            flcoeffs3[i] = 2.0 * flcoeffs2[i];
        } else {
Kostya Shishkov's avatar
Kostya Shishkov committed
289
            workT1[i]    = 0.0;
Kostya Shishkov's avatar
Kostya Shishkov committed
290 291 292 293 294 295 296
            flcoeffs3[i] = -30000.0;
        }
        workT3[i] = bandWidthT[i] * workT1[i] * 0.01;
        if (workT3[i] <= snr_limit)
            workT3[i] = 0.0;
    }

Kostya Shishkov's avatar
Kostya Shishkov committed
297
    for (i = 0; i < BANDS; i++) {
Kostya Shishkov's avatar
Kostya Shishkov committed
298
        for (cnt2 = i; cnt2 < q->cyclTab[i]; cnt2++)
Kostya Shishkov's avatar
Kostya Shishkov committed
299
            flcoeffs5[cnt2] = flcoeffs5[cnt2] + workT3[i];
Kostya Shishkov's avatar
Kostya Shishkov committed
300
        workT2[cnt2 - 1] = workT2[cnt2 - 1] + workT3[i];
Kostya Shishkov's avatar
Kostya Shishkov committed
301 302
    }

Kostya Shishkov's avatar
Kostya Shishkov committed
303
    for (i = 1; i < BANDS; i++) {
Kostya Shishkov's avatar
Kostya Shishkov committed
304
        accum = (workT2[i - 1] + accum) * q->weights1[i - 1];
Kostya Shishkov's avatar
Kostya Shishkov committed
305 306 307
        flcoeffs5[i] += accum;
    }

Kostya Shishkov's avatar
Kostya Shishkov committed
308
    for (i = 0; i < BANDS; i++)
Kostya Shishkov's avatar
Kostya Shishkov committed
309 310
        workT2[i] = 0.0;

Kostya Shishkov's avatar
Kostya Shishkov committed
311
    for (i = 0; i < BANDS; i++) {
Kostya Shishkov's avatar
Kostya Shishkov committed
312
        for (cnt2 = i - 1; cnt2 > q->cyclTab2[i]; cnt2--)
Kostya Shishkov's avatar
Kostya Shishkov committed
313 314 315 316 317 318
            flcoeffs5[cnt2] += workT3[i];
        workT2[cnt2+1] += workT3[i];
    }

    accum = 0.0;

Kostya Shishkov's avatar
Kostya Shishkov committed
319
    for (i = BANDS-2; i >= 0; i--) {
Kostya Shishkov's avatar
Kostya Shishkov committed
320
        accum = (workT2[i+1] + accum) * q->weights2[i];
Kostya Shishkov's avatar
Kostya Shishkov committed
321
        flcoeffs5[i] += accum;
Kostya Shishkov's avatar
Kostya Shishkov committed
322
        // there is missing code here, but it seems to never be triggered
Kostya Shishkov's avatar
Kostya Shishkov committed
323 324 325 326
    }
}


Kostya Shishkov's avatar
Kostya Shishkov committed
327 328
static void imc_read_level_coeffs(IMCContext *q, int stream_format_code,
                                  int *levlCoeffs)
Kostya Shishkov's avatar
Kostya Shishkov committed
329 330 331 332 333 334 335 336
{
    int i;
    VLC *hufftab[4];
    int start = 0;
    const uint8_t *cb_sel;
    int s;

    s = stream_format_code >> 1;
337 338 339 340
    hufftab[0] = &huffman_vlc[s][0];
    hufftab[1] = &huffman_vlc[s][1];
    hufftab[2] = &huffman_vlc[s][2];
    hufftab[3] = &huffman_vlc[s][3];
Kostya Shishkov's avatar
Kostya Shishkov committed
341 342
    cb_sel = imc_cb_select[s];

Kostya Shishkov's avatar
Kostya Shishkov committed
343
    if (stream_format_code & 4)
Kostya Shishkov's avatar
Kostya Shishkov committed
344
        start = 1;
Kostya Shishkov's avatar
Kostya Shishkov committed
345
    if (start)
Kostya Shishkov's avatar
Kostya Shishkov committed
346
        levlCoeffs[0] = get_bits(&q->gb, 7);
Kostya Shishkov's avatar
Kostya Shishkov committed
347 348 349 350
    for (i = start; i < BANDS; i++) {
        levlCoeffs[i] = get_vlc2(&q->gb, hufftab[cb_sel[i]]->table,
                                 hufftab[cb_sel[i]]->bits, 2);
        if (levlCoeffs[i] == 17)
Kostya Shishkov's avatar
Kostya Shishkov committed
351 352 353 354
            levlCoeffs[i] += get_bits(&q->gb, 4);
    }
}

Kostya Shishkov's avatar
Kostya Shishkov committed
355 356 357 358 359 360 361 362 363 364 365
static void imc_read_level_coeffs_raw(IMCContext *q, int stream_format_code,
                                      int *levlCoeffs)
{
    int i;

    q->coef0_pos  = get_bits(&q->gb, 5);
    levlCoeffs[0] = get_bits(&q->gb, 7);
    for (i = 1; i < BANDS; i++)
        levlCoeffs[i] = get_bits(&q->gb, 4);
}

Kostya Shishkov's avatar
Kostya Shishkov committed
366 367
static void imc_decode_level_coefficients(IMCContext *q, int *levlCoeffBuf,
                                          float *flcoeffs1, float *flcoeffs2)
Kostya Shishkov's avatar
Kostya Shishkov committed
368 369 370
{
    int i, level;
    float tmp, tmp2;
Kostya Shishkov's avatar
Kostya Shishkov committed
371
    // maybe some frequency division thingy
Kostya Shishkov's avatar
Kostya Shishkov committed
372

373
    flcoeffs1[0] = 20000.0 / exp2 (levlCoeffBuf[0] * 0.18945); // 0.18945 = log2(10) * 0.05703125
374
    flcoeffs2[0] = log2f(flcoeffs1[0]);
Kostya Shishkov's avatar
Kostya Shishkov committed
375
    tmp  = flcoeffs1[0];
Kostya Shishkov's avatar
Kostya Shishkov committed
376 377
    tmp2 = flcoeffs2[0];

Kostya Shishkov's avatar
Kostya Shishkov committed
378
    for (i = 1; i < BANDS; i++) {
Kostya Shishkov's avatar
Kostya Shishkov committed
379 380 381 382 383 384
        level = levlCoeffBuf[i];
        if (level == 16) {
            flcoeffs1[i] = 1.0;
            flcoeffs2[i] = 0.0;
        } else {
            if (level < 17)
Kostya Shishkov's avatar
Kostya Shishkov committed
385
                level -= 7;
Kostya Shishkov's avatar
Kostya Shishkov committed
386
            else if (level <= 24)
Kostya Shishkov's avatar
Kostya Shishkov committed
387
                level -= 32;
Kostya Shishkov's avatar
Kostya Shishkov committed
388
            else
Kostya Shishkov's avatar
Kostya Shishkov committed
389
                level -= 16;
Kostya Shishkov's avatar
Kostya Shishkov committed
390 391

            tmp  *= imc_exp_tab[15 + level];
Benjamin Larsson's avatar
Benjamin Larsson committed
392
            tmp2 += 0.83048 * level;  // 0.83048 = log2(10) * 0.25
Kostya Shishkov's avatar
Kostya Shishkov committed
393 394 395 396 397 398 399
            flcoeffs1[i] = tmp;
            flcoeffs2[i] = tmp2;
        }
    }
}


Kostya Shishkov's avatar
Kostya Shishkov committed
400 401 402 403
static void imc_decode_level_coefficients2(IMCContext *q, int *levlCoeffBuf,
                                           float *old_floor, float *flcoeffs1,
                                           float *flcoeffs2)
{
Kostya Shishkov's avatar
Kostya Shishkov committed
404
    int i;
Kostya Shishkov's avatar
Kostya Shishkov committed
405 406 407 408 409
    /* FIXME maybe flag_buf = noise coding and flcoeffs1 = new scale factors
     *       and flcoeffs2 old scale factors
     *       might be incomplete due to a missing table that is in the binary code
     */
    for (i = 0; i < BANDS; i++) {
Kostya Shishkov's avatar
Kostya Shishkov committed
410
        flcoeffs1[i] = 0;
Kostya Shishkov's avatar
Kostya Shishkov committed
411
        if (levlCoeffBuf[i] < 16) {
Kostya Shishkov's avatar
Kostya Shishkov committed
412
            flcoeffs1[i] = imc_exp_tab2[levlCoeffBuf[i]] * old_floor[i];
Kostya Shishkov's avatar
Kostya Shishkov committed
413
            flcoeffs2[i] = (levlCoeffBuf[i] - 7) * 0.83048 + flcoeffs2[i]; // 0.83048 = log2(10) * 0.25
Kostya Shishkov's avatar
Kostya Shishkov committed
414 415 416 417 418 419
        } else {
            flcoeffs1[i] = old_floor[i];
        }
    }
}

Kostya Shishkov's avatar
Kostya Shishkov committed
420 421 422 423 424 425 426 427
static void imc_decode_level_coefficients_raw(IMCContext *q, int *levlCoeffBuf,
                                              float *flcoeffs1, float *flcoeffs2)
{
    int i, level, pos;
    float tmp, tmp2;

    pos = q->coef0_pos;
    flcoeffs1[pos] = 20000.0 / pow (2, levlCoeffBuf[0] * 0.18945); // 0.18945 = log2(10) * 0.05703125
428
    flcoeffs2[pos] = log2f(flcoeffs1[pos]);
Kostya Shishkov's avatar
Kostya Shishkov committed
429 430 431 432 433 434 435 436 437 438 439 440 441
    tmp  = flcoeffs1[pos];
    tmp2 = flcoeffs2[pos];

    levlCoeffBuf++;
    for (i = 0; i < BANDS; i++) {
        if (i == pos)
            continue;
        level = *levlCoeffBuf++;
        flcoeffs1[i] = tmp  * powf(10.0, -level * 0.4375); //todo tab
        flcoeffs2[i] = tmp2 - 1.4533435415 * level; // 1.4533435415 = log2(10) * 0.4375
    }
}

Kostya Shishkov's avatar
Kostya Shishkov committed
442 443 444
/**
 * Perform bit allocation depending on bits available
 */
445 446
static int bit_allocation(IMCContext *q, IMCChannel *chctx,
                          int stream_format_code, int freebits, int flag)
Kostya Shishkov's avatar
Kostya Shishkov committed
447
{
Kostya Shishkov's avatar
Kostya Shishkov committed
448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463
    int i, j;
    const float limit = -1.e20;
    float highest = 0.0;
    int indx;
    int t1 = 0;
    int t2 = 1;
    float summa = 0.0;
    int iacc = 0;
    int summer = 0;
    int rres, cwlen;
    float lowest = 1.e10;
    int low_indx = 0;
    float workT[32];
    int flg;
    int found_indx = 0;

Kostya Shishkov's avatar
Kostya Shishkov committed
464
    for (i = 0; i < BANDS; i++)
465
        highest = FFMAX(highest, chctx->flcoeffs1[i]);
Kostya Shishkov's avatar
Kostya Shishkov committed
466

467 468 469 470 471
    for (i = 0; i < BANDS - 1; i++) {
        if (chctx->flcoeffs5[i] <= 0) {
            av_log(NULL, AV_LOG_ERROR, "flcoeffs5 %f invalid\n", chctx->flcoeffs5[i]);
            return AVERROR_INVALIDDATA;
        }
472
        chctx->flcoeffs4[i] = chctx->flcoeffs3[i] - log2f(chctx->flcoeffs5[i]);
473
    }
474
    chctx->flcoeffs4[BANDS - 1] = limit;
Kostya Shishkov's avatar
Kostya Shishkov committed
475 476 477

    highest = highest * 0.25;

Kostya Shishkov's avatar
Kostya Shishkov committed
478
    for (i = 0; i < BANDS; i++) {
Kostya Shishkov's avatar
Kostya Shishkov committed
479
        indx = -1;
480
        if ((band_tab[i + 1] - band_tab[i]) == chctx->bandWidthT[i])
Kostya Shishkov's avatar
Kostya Shishkov committed
481 482
            indx = 0;

483
        if ((band_tab[i + 1] - band_tab[i]) > chctx->bandWidthT[i])
Kostya Shishkov's avatar
Kostya Shishkov committed
484 485
            indx = 1;

486
        if (((band_tab[i + 1] - band_tab[i]) / 2) >= chctx->bandWidthT[i])
Kostya Shishkov's avatar
Kostya Shishkov committed
487 488 489
            indx = 2;

        if (indx == -1)
490
            return AVERROR_INVALIDDATA;
Kostya Shishkov's avatar
Kostya Shishkov committed
491

492
        chctx->flcoeffs4[i] += xTab[(indx * 2 + (chctx->flcoeffs1[i] < highest)) * 2 + flag];
Kostya Shishkov's avatar
Kostya Shishkov committed
493 494 495
    }

    if (stream_format_code & 0x2) {
496 497 498 499
        chctx->flcoeffs4[0] = limit;
        chctx->flcoeffs4[1] = limit;
        chctx->flcoeffs4[2] = limit;
        chctx->flcoeffs4[3] = limit;
Kostya Shishkov's avatar
Kostya Shishkov committed
500 501
    }

Kostya Shishkov's avatar
Kostya Shishkov committed
502
    for (i = (stream_format_code & 0x2) ? 4 : 0; i < BANDS - 1; i++) {
503 504
        iacc  += chctx->bandWidthT[i];
        summa += chctx->bandWidthT[i] * chctx->flcoeffs4[i];
Kostya Shishkov's avatar
Kostya Shishkov committed
505
    }
506 507 508 509

    if (!iacc)
        return AVERROR_INVALIDDATA;

510
    chctx->bandWidthT[BANDS - 1] = 0;
Kostya Shishkov's avatar
Kostya Shishkov committed
511 512 513
    summa = (summa * 0.5 - freebits) / iacc;


Kostya Shishkov's avatar
Kostya Shishkov committed
514
    for (i = 0; i < BANDS / 2; i++) {
Kostya Shishkov's avatar
Kostya Shishkov committed
515
        rres = summer - freebits;
Kostya Shishkov's avatar
Kostya Shishkov committed
516 517
        if ((rres >= -8) && (rres <= 8))
            break;
Kostya Shishkov's avatar
Kostya Shishkov committed
518 519

        summer = 0;
Kostya Shishkov's avatar
Kostya Shishkov committed
520
        iacc   = 0;
Kostya Shishkov's avatar
Kostya Shishkov committed
521

Kostya Shishkov's avatar
Kostya Shishkov committed
522
        for (j = (stream_format_code & 0x2) ? 4 : 0; j < BANDS; j++) {
523
            cwlen = av_clipf(((chctx->flcoeffs4[j] * 0.5) - summa + 0.5), 0, 6);
Kostya Shishkov's avatar
Kostya Shishkov committed
524

525 526
            chctx->bitsBandT[j] = cwlen;
            summer += chctx->bandWidthT[j] * cwlen;
Kostya Shishkov's avatar
Kostya Shishkov committed
527 528

            if (cwlen > 0)
529
                iacc += chctx->bandWidthT[j];
Kostya Shishkov's avatar
Kostya Shishkov committed
530 531 532 533 534 535 536 537
        }

        flg = t2;
        t2 = 1;
        if (freebits < summer)
            t2 = -1;
        if (i == 0)
            flg = t2;
Kostya Shishkov's avatar
Kostya Shishkov committed
538
        if (flg != t2)
Kostya Shishkov's avatar
Kostya Shishkov committed
539 540 541 542 543
            t1++;

        summa = (float)(summer - freebits) / ((t1 + 1) * iacc) + summa;
    }

Kostya Shishkov's avatar
Kostya Shishkov committed
544 545
    for (i = (stream_format_code & 0x2) ? 4 : 0; i < BANDS; i++) {
        for (j = band_tab[i]; j < band_tab[i + 1]; j++)
546
            chctx->CWlengthT[j] = chctx->bitsBandT[i];
Kostya Shishkov's avatar
Kostya Shishkov committed
547 548 549
    }

    if (freebits > summer) {
Kostya Shishkov's avatar
Kostya Shishkov committed
550
        for (i = 0; i < BANDS; i++) {
551 552
            workT[i] = (chctx->bitsBandT[i] == 6) ? -1.e20
                                              : (chctx->bitsBandT[i] * -2 + chctx->flcoeffs4[i] - 0.415);
Kostya Shishkov's avatar
Kostya Shishkov committed
553 554 555 556
        }

        highest = 0.0;

Kostya Shishkov's avatar
Kostya Shishkov committed
557
        do {
Kostya Shishkov's avatar
Kostya Shishkov committed
558 559 560 561 562 563
            if (highest <= -1.e20)
                break;

            found_indx = 0;
            highest = -1.e20;

Kostya Shishkov's avatar
Kostya Shishkov committed
564
            for (i = 0; i < BANDS; i++) {
Kostya Shishkov's avatar
Kostya Shishkov committed
565 566 567 568 569 570 571 572
                if (workT[i] > highest) {
                    highest = workT[i];
                    found_indx = i;
                }
            }

            if (highest > -1.e20) {
                workT[found_indx] -= 2.0;
573
                if (++chctx->bitsBandT[found_indx] == 6)
Kostya Shishkov's avatar
Kostya Shishkov committed
574 575
                    workT[found_indx] = -1.e20;

Kostya Shishkov's avatar
Kostya Shishkov committed
576
                for (j = band_tab[found_indx]; j < band_tab[found_indx + 1] && (freebits > summer); j++) {
577
                    chctx->CWlengthT[j]++;
Kostya Shishkov's avatar
Kostya Shishkov committed
578 579 580
                    summer++;
                }
            }
Kostya Shishkov's avatar
Kostya Shishkov committed
581
        } while (freebits > summer);
Kostya Shishkov's avatar
Kostya Shishkov committed
582 583
    }
    if (freebits < summer) {
Kostya Shishkov's avatar
Kostya Shishkov committed
584
        for (i = 0; i < BANDS; i++) {
585
            workT[i] = chctx->bitsBandT[i] ? (chctx->bitsBandT[i] * -2 + chctx->flcoeffs4[i] + 1.585)
Kostya Shishkov's avatar
Kostya Shishkov committed
586
                                       : 1.e20;
Kostya Shishkov's avatar
Kostya Shishkov committed
587 588 589 590 591 592 593
        }
        if (stream_format_code & 0x2) {
            workT[0] = 1.e20;
            workT[1] = 1.e20;
            workT[2] = 1.e20;
            workT[3] = 1.e20;
        }
Kostya Shishkov's avatar
Kostya Shishkov committed
594 595
        while (freebits < summer) {
            lowest   = 1.e10;
Kostya Shishkov's avatar
Kostya Shishkov committed
596
            low_indx = 0;
Kostya Shishkov's avatar
Kostya Shishkov committed
597
            for (i = 0; i < BANDS; i++) {
Kostya Shishkov's avatar
Kostya Shishkov committed
598
                if (workT[i] < lowest) {
Kostya Shishkov's avatar
Kostya Shishkov committed
599
                    lowest   = workT[i];
Kostya Shishkov's avatar
Kostya Shishkov committed
600 601 602
                    low_indx = i;
                }
            }
Kostya Shishkov's avatar
Kostya Shishkov committed
603 604
            // if (lowest >= 1.e10)
            //     break;
Kostya Shishkov's avatar
Kostya Shishkov committed
605 606
            workT[low_indx] = lowest + 2.0;

607
            if (!--chctx->bitsBandT[low_indx])
Kostya Shishkov's avatar
Kostya Shishkov committed
608 609
                workT[low_indx] = 1.e20;

Kostya Shishkov's avatar
Kostya Shishkov committed
610
            for (j = band_tab[low_indx]; j < band_tab[low_indx+1] && (freebits < summer); j++) {
611 612
                if (chctx->CWlengthT[j] > 0) {
                    chctx->CWlengthT[j]--;
Kostya Shishkov's avatar
Kostya Shishkov committed
613 614 615 616 617 618 619 620
                    summer--;
                }
            }
        }
    }
    return 0;
}

621
static void imc_get_skip_coeff(IMCContext *q, IMCChannel *chctx)
Kostya Shishkov's avatar
Kostya Shishkov committed
622
{
Kostya Shishkov's avatar
Kostya Shishkov committed
623 624
    int i, j;

625 626
    memset(chctx->skipFlagBits,  0, sizeof(chctx->skipFlagBits));
    memset(chctx->skipFlagCount, 0, sizeof(chctx->skipFlagCount));
Kostya Shishkov's avatar
Kostya Shishkov committed
627
    for (i = 0; i < BANDS; i++) {
628
        if (!chctx->bandFlagsBuf[i] || !chctx->bandWidthT[i])
Kostya Shishkov's avatar
Kostya Shishkov committed
629 630
            continue;

631 632
        if (!chctx->skipFlagRaw[i]) {
            chctx->skipFlagBits[i] = band_tab[i + 1] - band_tab[i];
Kostya Shishkov's avatar
Kostya Shishkov committed
633

Kostya Shishkov's avatar
Kostya Shishkov committed
634
            for (j = band_tab[i]; j < band_tab[i + 1]; j++) {
635 636 637
                chctx->skipFlags[j] = get_bits1(&q->gb);
                if (chctx->skipFlags[j])
                    chctx->skipFlagCount[i]++;
Kostya Shishkov's avatar
Kostya Shishkov committed
638 639
            }
        } else {
Kostya Shishkov's avatar
Kostya Shishkov committed
640 641
            for (j = band_tab[i]; j < band_tab[i + 1] - 1; j += 2) {
                if (!get_bits1(&q->gb)) { // 0
642 643 644 645
                    chctx->skipFlagBits[i]++;
                    chctx->skipFlags[j]      = 1;
                    chctx->skipFlags[j + 1]  = 1;
                    chctx->skipFlagCount[i] += 2;
Kostya Shishkov's avatar
Kostya Shishkov committed
646 647
                } else {
                    if (get_bits1(&q->gb)) { // 11
648 649 650 651
                        chctx->skipFlagBits[i] += 2;
                        chctx->skipFlags[j]     = 0;
                        chctx->skipFlags[j + 1] = 1;
                        chctx->skipFlagCount[i]++;
Kostya Shishkov's avatar
Kostya Shishkov committed
652
                    } else {
653 654
                        chctx->skipFlagBits[i] += 3;
                        chctx->skipFlags[j + 1] = 0;
Kostya Shishkov's avatar
Kostya Shishkov committed
655
                        if (!get_bits1(&q->gb)) { // 100
656 657
                            chctx->skipFlags[j] = 1;
                            chctx->skipFlagCount[i]++;
Kostya Shishkov's avatar
Kostya Shishkov committed
658
                        } else { // 101
659
                            chctx->skipFlags[j] = 0;
Kostya Shishkov's avatar
Kostya Shishkov committed
660 661 662 663 664
                        }
                    }
                }
            }

Kostya Shishkov's avatar
Kostya Shishkov committed
665
            if (j < band_tab[i + 1]) {
666 667 668
                chctx->skipFlagBits[i]++;
                if ((chctx->skipFlags[j] = get_bits1(&q->gb)))
                    chctx->skipFlagCount[i]++;
Kostya Shishkov's avatar
Kostya Shishkov committed
669 670 671 672 673 674 675 676
            }
        }
    }
}

/**
 * Increase highest' band coefficient sizes as some bits won't be used
 */
677 678
static void imc_adjust_bit_allocation(IMCContext *q, IMCChannel *chctx,
                                      int summer)
Kostya Shishkov's avatar
Kostya Shishkov committed
679
{
Kostya Shishkov's avatar
Kostya Shishkov committed
680 681 682
    float workT[32];
    int corrected = 0;
    int i, j;
Kostya Shishkov's avatar
Kostya Shishkov committed
683 684
    float highest  = 0;
    int found_indx = 0;
Kostya Shishkov's avatar
Kostya Shishkov committed
685

Kostya Shishkov's avatar
Kostya Shishkov committed
686
    for (i = 0; i < BANDS; i++) {
687 688
        workT[i] = (chctx->bitsBandT[i] == 6) ? -1.e20
                                          : (chctx->bitsBandT[i] * -2 + chctx->flcoeffs4[i] - 0.415);
Kostya Shishkov's avatar
Kostya Shishkov committed
689 690 691
    }

    while (corrected < summer) {
Kostya Shishkov's avatar
Kostya Shishkov committed
692
        if (highest <= -1.e20)
Kostya Shishkov's avatar
Kostya Shishkov committed
693 694 695 696
            break;

        highest = -1.e20;

Kostya Shishkov's avatar
Kostya Shishkov committed
697
        for (i = 0; i < BANDS; i++) {
Kostya Shishkov's avatar
Kostya Shishkov committed
698 699 700 701 702 703 704 705
            if (workT[i] > highest) {
                highest = workT[i];
                found_indx = i;
            }
        }

        if (highest > -1.e20) {
            workT[found_indx] -= 2.0;
706
            if (++(chctx->bitsBandT[found_indx]) == 6)
Kostya Shishkov's avatar
Kostya Shishkov committed
707 708
                workT[found_indx] = -1.e20;

Kostya Shishkov's avatar
Kostya Shishkov committed
709
            for (j = band_tab[found_indx]; j < band_tab[found_indx+1] && (corrected < summer); j++) {
710 711
                if (!chctx->skipFlags[j] && (chctx->CWlengthT[j] < 6)) {
                    chctx->CWlengthT[j]++;
Kostya Shishkov's avatar
Kostya Shishkov committed
712 713 714 715 716 717 718
                    corrected++;
                }
            }
        }
    }
}

719
static void imc_imdct256(IMCContext *q, IMCChannel *chctx, int channels)
Kostya Shishkov's avatar
Kostya Shishkov committed
720
{
Kostya Shishkov's avatar
Kostya Shishkov committed
721 722
    int i;
    float re, im;
723
    float *dst1 = q->out_samples;
724
    float *dst2 = q->out_samples + (COEFFS - 1);
Kostya Shishkov's avatar
Kostya Shishkov committed
725 726

    /* prerotation */
Kostya Shishkov's avatar
Kostya Shishkov committed
727
    for (i = 0; i < COEFFS / 2; i++) {
728 729 730 731
        q->samples[i].re = -(q->pre_coef1[i] * chctx->CWdecoded[COEFFS - 1 - i * 2]) -
                            (q->pre_coef2[i] * chctx->CWdecoded[i * 2]);
        q->samples[i].im =  (q->pre_coef2[i] * chctx->CWdecoded[COEFFS - 1 - i * 2]) -
                            (q->pre_coef1[i] * chctx->CWdecoded[i * 2]);
Kostya Shishkov's avatar
Kostya Shishkov committed
732 733 734
    }

    /* FFT */
735
    q->fft.fft_permute(&q->fft, q->samples);
Kostya Shishkov's avatar
Kostya Shishkov committed
736
    q->fft.fft_calc(&q->fft, q->samples);
Kostya Shishkov's avatar
Kostya Shishkov committed
737 738

    /* postrotation, window and reorder */
Kostya Shishkov's avatar
Kostya Shishkov committed
739 740 741
    for (i = 0; i < COEFFS / 2; i++) {
        re = ( q->samples[i].re * q->post_cos[i]) + (-q->samples[i].im * q->post_sin[i]);
        im = (-q->samples[i].im * q->post_cos[i]) - ( q->samples[i].re * q->post_sin[i]);
742 743 744 745
        *dst1 =  (q->mdct_sine_window[COEFFS - 1 - i * 2] * chctx->last_fft_im[i])
               + (q->mdct_sine_window[i * 2] * re);
        *dst2 =  (q->mdct_sine_window[i * 2] * chctx->last_fft_im[i])
               - (q->mdct_sine_window[COEFFS - 1 - i * 2] * re);
746 747
        dst1 += 2;
        dst2 -= 2;
748
        chctx->last_fft_im[i] = im;
Kostya Shishkov's avatar
Kostya Shishkov committed
749 750 751
    }
}

752 753
static int inverse_quant_coeff(IMCContext *q, IMCChannel *chctx,
                               int stream_format_code)
Kostya Shishkov's avatar
Kostya Shishkov committed
754
{
Kostya Shishkov's avatar
Kostya Shishkov committed
755 756
    int i, j;
    int middle_value, cw_len, max_size;
Kostya Shishkov's avatar
Kostya Shishkov committed
757
    const float *quantizer;
Kostya Shishkov's avatar
Kostya Shishkov committed
758

Kostya Shishkov's avatar
Kostya Shishkov committed
759 760
    for (i = 0; i < BANDS; i++) {
        for (j = band_tab[i]; j < band_tab[i + 1]; j++) {
761 762
            chctx->CWdecoded[j] = 0;
            cw_len = chctx->CWlengthT[j];
Kostya Shishkov's avatar
Kostya Shishkov committed
763

764
            if (cw_len <= 0 || chctx->skipFlags[j])
Kostya Shishkov's avatar
Kostya Shishkov committed
765 766
                continue;

Kostya Shishkov's avatar
Kostya Shishkov committed
767
            max_size     = 1 << cw_len;
Kostya Shishkov's avatar
Kostya Shishkov committed
768 769
            middle_value = max_size >> 1;

770
            if (chctx->codewords[j] >= max_size || chctx->codewords[j] < 0)
771
                return AVERROR_INVALIDDATA;
Kostya Shishkov's avatar
Kostya Shishkov committed
772

Kostya Shishkov's avatar
Kostya Shishkov committed
773
            if (cw_len >= 4) {
Kostya Shishkov's avatar
Kostya Shishkov committed
774
                quantizer = imc_quantizer2[(stream_format_code & 2) >> 1];
775 776
                if (chctx->codewords[j] >= middle_value)
                    chctx->CWdecoded[j] =  quantizer[chctx->codewords[j] - 8]                * chctx->flcoeffs6[i];
Kostya Shishkov's avatar
Kostya Shishkov committed
777
                else
778
                    chctx->CWdecoded[j] = -quantizer[max_size - chctx->codewords[j] - 8 - 1] * chctx->flcoeffs6[i];
Kostya Shishkov's avatar
Kostya Shishkov committed
779
            }else{
780 781 782
                quantizer = imc_quantizer1[((stream_format_code & 2) >> 1) | (chctx->bandFlagsBuf[i] << 1)];
                if (chctx->codewords[j] >= middle_value)
                    chctx->CWdecoded[j] =  quantizer[chctx->codewords[j] - 1]            * chctx->flcoeffs6[i];
Kostya Shishkov's avatar
Kostya Shishkov committed
783
                else
784
                    chctx->CWdecoded[j] = -quantizer[max_size - 2 - chctx->codewords[j]] * chctx->flcoeffs6[i];
Kostya Shishkov's avatar
Kostya Shishkov committed
785 786 787 788 789 790 791
            }
        }
    }
    return 0;
}


792 793
static void imc_get_coeffs(AVCodecContext *avctx,
                           IMCContext *q, IMCChannel *chctx)
Kostya Shishkov's avatar
Kostya Shishkov committed
794
{
Kostya Shishkov's avatar
Kostya Shishkov committed
795 796
    int i, j, cw_len, cw;

Kostya Shishkov's avatar
Kostya Shishkov committed
797
    for (i = 0; i < BANDS; i++) {
798
        if (!chctx->sumLenArr[i])
Kostya Shishkov's avatar
Kostya Shishkov committed
799
            continue;
800
        if (chctx->bandFlagsBuf[i] || chctx->bandWidthT[i]) {
Kostya Shishkov's avatar
Kostya Shishkov committed
801
            for (j = band_tab[i]; j < band_tab[i + 1]; j++) {
802
                cw_len = chctx->CWlengthT[j];
Kostya Shishkov's avatar
Kostya Shishkov committed
803 804
                cw = 0;

805 806 807 808 809
                if (cw_len && (!chctx->bandFlagsBuf[i] || !chctx->skipFlags[j])) {
                    if (get_bits_count(&q->gb) + cw_len > 512) {
                        av_log(avctx, AV_LOG_WARNING,
                            "Potential problem on band %i, coefficient %i"
                            ": cw_len=%i\n", i, j, cw_len);
810 811
                    } else
                        cw = get_bits(&q->gb, cw_len);
812
                }
Kostya Shishkov's avatar
Kostya Shishkov committed
813

814
                chctx->codewords[j] = cw;
Kostya Shishkov's avatar
Kostya Shishkov committed
815 816 817 818 819
            }
        }
    }
}

Kostya Shishkov's avatar
Kostya Shishkov committed
820 821 822 823 824 825 826 827 828 829 830
static void imc_refine_bit_allocation(IMCContext *q, IMCChannel *chctx)
{
    int i, j;
    int bits, summer;

    for (i = 0; i < BANDS; i++) {
        chctx->sumLenArr[i]   = 0;
        chctx->skipFlagRaw[i] = 0;
        for (j = band_tab[i]; j < band_tab[i + 1]; j++)
            chctx->sumLenArr[i] += chctx->CWlengthT[j];
        if (chctx->bandFlagsBuf[i])
831
            if (((int)((band_tab[i + 1] - band_tab[i]) * 1.5) > chctx->sumLenArr[i]) && (chctx->sumLenArr[i] > 0))
Kostya Shishkov's avatar
Kostya Shishkov committed
832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863
                chctx->skipFlagRaw[i] = 1;
    }

    imc_get_skip_coeff(q, chctx);

    for (i = 0; i < BANDS; i++) {
        chctx->flcoeffs6[i] = chctx->flcoeffs1[i];
        /* band has flag set and at least one coded coefficient */
        if (chctx->bandFlagsBuf[i] && (band_tab[i + 1] - band_tab[i]) != chctx->skipFlagCount[i]) {
            chctx->flcoeffs6[i] *= q->sqrt_tab[ band_tab[i + 1] - band_tab[i]] /
                                   q->sqrt_tab[(band_tab[i + 1] - band_tab[i] - chctx->skipFlagCount[i])];
        }
    }

    /* calculate bits left, bits needed and adjust bit allocation */
    bits = summer = 0;

    for (i = 0; i < BANDS; i++) {
        if (chctx->bandFlagsBuf[i]) {
            for (j = band_tab[i]; j < band_tab[i + 1]; j++) {
                if (chctx->skipFlags[j]) {
                    summer += chctx->CWlengthT[j];
                    chctx->CWlengthT[j] = 0;
                }
            }
            bits   += chctx->skipFlagBits[i];
            summer -= chctx->skipFlagBits[i];
        }
    }
    imc_adjust_bit_allocation(q, chctx, summer);
}

864
static int imc_decode_block(AVCodecContext *avctx, IMCContext *q, int ch)
Kostya Shishkov's avatar
Kostya Shishkov committed
865 866
{
    int stream_format_code;
867
    int imc_hdr, i, j, ret;
Kostya Shishkov's avatar
Kostya Shishkov committed
868
    int flag;
Kostya Shishkov's avatar
Kostya Shishkov committed
869
    int bits;
Kostya Shishkov's avatar
Kostya Shishkov committed
870
    int counter, bitscount;
871
    IMCChannel *chctx = q->chctx + ch;
Kostya Shishkov's avatar
Kostya Shishkov committed
872 873 874 875


    /* Check the frame header */
    imc_hdr = get_bits(&q->gb, 9);
Kostya Shishkov's avatar
Kostya Shishkov committed
876 877 878
    if (imc_hdr & 0x18) {
        av_log(avctx, AV_LOG_ERROR, "frame header check failed!\n");
        av_log(avctx, AV_LOG_ERROR, "got %X.\n", imc_hdr);
879
        return AVERROR_INVALIDDATA;
Kostya Shishkov's avatar
Kostya Shishkov committed
880 881 882 883
    }
    stream_format_code = get_bits(&q->gb, 3);

    if (stream_format_code & 0x04)
884
        chctx->decoder_reset = 1;
Kostya Shishkov's avatar
Kostya Shishkov committed
885

886
    if (chctx->decoder_reset) {
Kostya Shishkov's avatar
Kostya Shishkov committed
887
        for (i = 0; i < BANDS; i++)
888
            chctx->old_floor[i] = 1.0;
Kostya Shishkov's avatar
Kostya Shishkov committed
889
        for (i = 0; i < COEFFS; i++)
890 891
            chctx->CWdecoded[i] = 0;
        chctx->decoder_reset = 0;
Kostya Shishkov's avatar
Kostya Shishkov committed
892 893 894
    }

    flag = get_bits1(&q->gb);
Kostya Shishkov's avatar
Kostya Shishkov committed
895 896 897 898
    if (stream_format_code & 0x1)
        imc_read_level_coeffs_raw(q, stream_format_code, chctx->levlCoeffBuf);
    else
        imc_read_level_coeffs(q, stream_format_code, chctx->levlCoeffBuf);
Kostya Shishkov's avatar
Kostya Shishkov committed
899

900 901 902 903
    if (stream_format_code & 0x1)
        imc_decode_level_coefficients_raw(q, chctx->levlCoeffBuf,
                                          chctx->flcoeffs1, chctx->flcoeffs2);
    else if (stream_format_code & 0x4)
904 905
        imc_decode_level_coefficients(q, chctx->levlCoeffBuf,
                                      chctx->flcoeffs1, chctx->flcoeffs2);
Kostya Shishkov's avatar
Kostya Shishkov committed
906
    else
907 908
        imc_decode_level_coefficients2(q, chctx->levlCoeffBuf, chctx->old_floor,
                                       chctx->flcoeffs1, chctx->flcoeffs2);
Kostya Shishkov's avatar
Kostya Shishkov committed
909

910 911 912 913 914 915 916
    for(i=0; i<BANDS; i++) {
        if(chctx->flcoeffs1[i] > INT_MAX) {
            av_log(avctx, AV_LOG_ERROR, "scalefactor out of range\n");
            return AVERROR_INVALIDDATA;
        }
    }

917
    memcpy(chctx->old_floor, chctx->flcoeffs1, 32 * sizeof(float));
Kostya Shishkov's avatar
Kostya Shishkov committed
918 919

    counter = 0;
Kostya Shishkov's avatar
Kostya Shishkov committed
920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939
    if (stream_format_code & 0x1) {
        for (i = 0; i < BANDS; i++) {
            chctx->bandWidthT[i]   = band_tab[i + 1] - band_tab[i];
            chctx->bandFlagsBuf[i] = 0;
            chctx->flcoeffs3[i]    = chctx->flcoeffs2[i] * 2;
            chctx->flcoeffs5[i]    = 1.0;
        }
    } else {
        for (i = 0; i < BANDS; i++) {
            if (chctx->levlCoeffBuf[i] == 16) {
                chctx->bandWidthT[i] = 0;
                counter++;
            } else
                chctx->bandWidthT[i] = band_tab[i + 1] - band_tab[i];
        }

        memset(chctx->bandFlagsBuf, 0, BANDS * sizeof(int));
        for (i = 0; i < BANDS - 1; i++)
            if (chctx->bandWidthT[i])
                chctx->bandFlagsBuf[i] = get_bits1(&q->gb);
Kostya Shishkov's avatar
Kostya Shishkov committed
940

Kostya Shishkov's avatar
Kostya Shishkov committed
941 942 943 944
        imc_calculate_coeffs(q, chctx->flcoeffs1, chctx->flcoeffs2,
                             chctx->bandWidthT, chctx->flcoeffs3,
                             chctx->flcoeffs5);
    }
Kostya Shishkov's avatar
Kostya Shishkov committed
945 946 947 948 949 950

    bitscount = 0;
    /* first 4 bands will be assigned 5 bits per coefficient */
    if (stream_format_code & 0x2) {
        bitscount += 15;

951 952 953 954
        chctx->bitsBandT[0] = 5;
        chctx->CWlengthT[0] = 5;
        chctx->CWlengthT[1] = 5;
        chctx->CWlengthT[2] = 5;
Kostya Shishkov's avatar
Kostya Shishkov committed
955
        for (i = 1; i < 4; i++) {
Kostya Shishkov's avatar
Kostya Shishkov committed
956 957 958 959
            if (stream_format_code & 0x1)
                bits = 5;
            else
                bits = (chctx->levlCoeffBuf[i] == 16) ? 0 : 5;
960
            chctx->bitsBandT[i] = bits;
Kostya Shishkov's avatar
Kostya Shishkov committed
961
            for (j = band_tab[i]; j < band_tab[i + 1]; j++) {
962
                chctx->CWlengthT[j] = bits;
Kostya Shishkov's avatar
Kostya Shishkov committed
963
                bitscount      += bits;
Kostya Shishkov's avatar
Kostya Shishkov committed
964 965 966
            }
        }
    }
967
    if (avctx->codec_id == AV_CODEC_ID_IAC) {
Kostya Shishkov's avatar
Kostya Shishkov committed
968 969 970 971
        bitscount += !!chctx->bandWidthT[BANDS - 1];
        if (!(stream_format_code & 0x2))
            bitscount += 16;
    }
Kostya Shishkov's avatar
Kostya Shishkov committed
972

973
    if ((ret = bit_allocation(q, chctx, stream_format_code,
Kostya Shishkov's avatar
Kostya Shishkov committed
974 975
                              512 - bitscount - get_bits_count(&q->gb),
                              flag)) < 0) {
Kostya Shishkov's avatar
Kostya Shishkov committed
976
        av_log(avctx, AV_LOG_ERROR, "Bit allocations failed\n");
977
        chctx->decoder_reset = 1;
978
        return ret;
Kostya Shishkov's avatar
Kostya Shishkov committed
979 980
    }

Kostya Shishkov's avatar
Kostya Shishkov committed
981 982 983 984 985
    if (stream_format_code & 0x1) {
        for (i = 0; i < BANDS; i++)
            chctx->skipFlags[i] = 0;
    } else {
        imc_refine_bit_allocation(q, chctx);
Kostya Shishkov's avatar
Kostya Shishkov committed
986 987
    }

Kostya Shishkov's avatar
Kostya Shishkov committed
988
    for (i = 0; i < BANDS; i++) {
989
        chctx->sumLenArr[i] = 0;
Kostya Shishkov's avatar
Kostya Shishkov committed
990

Kostya Shishkov's avatar
Kostya Shishkov committed
991
        for (j = band_tab[i]; j < band_tab[i + 1]; j++)
992 993
            if (!chctx->skipFlags[j])
                chctx->sumLenArr[i] += chctx->CWlengthT[j];
Kostya Shishkov's avatar
Kostya Shishkov committed
994 995
    }

996
    memset(chctx->codewords, 0, sizeof(chctx->codewords));
Kostya Shishkov's avatar
Kostya Shishkov committed
997

998
    imc_get_coeffs(avctx, q, chctx);
Kostya Shishkov's avatar
Kostya Shishkov committed
999

1000
    if (inverse_quant_coeff(q, chctx, stream_format_code) < 0) {
Kostya Shishkov's avatar
Kostya Shishkov committed
1001
        av_log(avctx, AV_LOG_ERROR, "Inverse quantization of coefficients failed\n");
1002
        chctx->decoder_reset = 1;
1003
        return AVERROR_INVALIDDATA;
Kostya Shishkov's avatar
Kostya Shishkov committed
1004 1005
    }

1006 1007
    memset(chctx->skipFlags, 0, sizeof(chctx->skipFlags));

1008
    imc_imdct256(q, chctx, avctx->channels);
1009 1010 1011 1012 1013 1014 1015

    return 0;
}

static int imc_decode_frame(AVCodecContext *avctx, void *data,
                            int *got_frame_ptr, AVPacket *avpkt)
{
1016
    AVFrame *frame     = data;
1017 1018 1019
    const uint8_t *buf = avpkt->data;
    int buf_size = avpkt->size;
    int ret, i;
Kostya Shishkov's avatar
Kostya Shishkov committed
1020

1021 1022
    IMCContext *q = avctx->priv_data;

1023
    LOCAL_ALIGNED_16(uint16_t, buf16, [(IMC_BLOCK_SIZE + AV_INPUT_BUFFER_PADDING_SIZE) / 2]);
1024

Kostya Shishkov's avatar
Kostya Shishkov committed
1025 1026
    if (buf_size < IMC_BLOCK_SIZE * avctx->channels) {
        av_log(avctx, AV_LOG_ERROR, "frame too small!\n");
1027
        return AVERROR_INVALIDDATA;
Kostya Shishkov's avatar
Kostya Shishkov committed
1028 1029
    }

1030
    /* get output buffer */
1031
    frame->nb_samples = COEFFS;
1032
    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
1033
        return ret;
Kostya Shishkov's avatar
Kostya Shishkov committed
1034

1035
    for (i = 0; i < avctx->channels; i++) {
1036
        q->out_samples = (float *)frame->extended_data[i];
1037

1038
        q->bdsp.bswap16_buf(buf16, (const uint16_t *) buf, IMC_BLOCK_SIZE / 2);
1039 1040 1041 1042 1043 1044 1045 1046

        init_get_bits(&q->gb, (const uint8_t*)buf16, IMC_BLOCK_SIZE * 8);

        buf += IMC_BLOCK_SIZE;

        if ((ret = imc_decode_block(avctx, q, i)) < 0)
            return ret;
    }
Kostya Shishkov's avatar
Kostya Shishkov committed
1047

Kostya Shishkov's avatar
Kostya Shishkov committed
1048
    if (avctx->channels == 2) {
1049
        q->fdsp->butterflies_float((float *)frame->extended_data[0],
1050
                                  (float *)frame->extended_data[1], COEFFS);
Kostya Shishkov's avatar
Kostya Shishkov committed
1051
    }
Kostya Shishkov's avatar
Kostya Shishkov committed
1052

1053
    *got_frame_ptr = 1;
Kostya Shishkov's avatar
Kostya Shishkov committed
1054

1055
    return IMC_BLOCK_SIZE * avctx->channels;
Kostya Shishkov's avatar
Kostya Shishkov committed
1056 1057
}

1058
static av_cold int imc_decode_close(AVCodecContext * avctx)
Kostya Shishkov's avatar
Kostya Shishkov committed
1059 1060 1061 1062
{
    IMCContext *q = avctx->priv_data;

    ff_fft_end(&q->fft);
1063
    av_freep(&q->fdsp);
1064

Kostya Shishkov's avatar
Kostya Shishkov committed
1065 1066 1067
    return 0;
}

Michael Niedermayer's avatar
Michael Niedermayer committed
1068 1069 1070 1071 1072 1073 1074 1075
static av_cold void flush(AVCodecContext *avctx)
{
    IMCContext *q = avctx->priv_data;

    q->chctx[0].decoder_reset =
    q->chctx[1].decoder_reset = 1;
}

1076
#if CONFIG_IMC_DECODER
1077
AVCodec ff_imc_decoder = {
1078
    .name           = "imc",
1079
    .long_name      = NULL_IF_CONFIG_SMALL("IMC (Intel Music Coder)"),
1080
    .type           = AVMEDIA_TYPE_AUDIO,
1081
    .id             = AV_CODEC_ID_IMC,
Kostya Shishkov's avatar
Kostya Shishkov committed
1082
    .priv_data_size = sizeof(IMCContext),
1083 1084 1085
    .init           = imc_decode_init,
    .close          = imc_decode_close,
    .decode         = imc_decode_frame,
Michael Niedermayer's avatar
Michael Niedermayer committed
1086
    .flush          = flush,
1087
    .capabilities   = AV_CODEC_CAP_DR1,
1088 1089
    .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                      AV_SAMPLE_FMT_NONE },
Kostya Shishkov's avatar
Kostya Shishkov committed
1090
};
1091 1092
#endif
#if CONFIG_IAC_DECODER
Kostya Shishkov's avatar
Kostya Shishkov committed
1093 1094
AVCodec ff_iac_decoder = {
    .name           = "iac",
1095
    .long_name      = NULL_IF_CONFIG_SMALL("IAC (Indeo Audio Coder)"),
Kostya Shishkov's avatar
Kostya Shishkov committed
1096
    .type           = AVMEDIA_TYPE_AUDIO,
1097
    .id             = AV_CODEC_ID_IAC,
Kostya Shishkov's avatar
Kostya Shishkov committed
1098 1099 1100 1101
    .priv_data_size = sizeof(IMCContext),
    .init           = imc_decode_init,
    .close          = imc_decode_close,
    .decode         = imc_decode_frame,
Michael Niedermayer's avatar
Michael Niedermayer committed
1102
    .flush          = flush,
1103
    .capabilities   = AV_CODEC_CAP_DR1,
1104 1105
    .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                      AV_SAMPLE_FMT_NONE },
Kostya Shishkov's avatar
Kostya Shishkov committed
1106
};
1107
#endif