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 37
 *  Only mono is supported.
 *
 */


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

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

#include "imcdata.h"

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

56
typedef struct IMCChannel {
Kostya Shishkov's avatar
Kostya Shishkov committed
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
    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
    int skipFlagCount[BANDS];  ///< skipped coeffients per band
    int skipFlags[COEFFS];     ///< skip coefficient decoding or not
    int codewords[COEFFS];     ///< raw codewords read from bitstream
77 78 79 80 81 82

    float last_fft_im[COEFFS];

    int decoder_reset;
} IMCChannel;

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

    /** 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
95 96 97
    float sqrt_tab[30];
    GetBitContext gb;

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

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

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

110 111 112 113 114 115
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
116 117
    4452, 5220, 5860, 6628, 7268, 7908, 8424, 8936, VLC_TABLES_SIZE
};
118 119

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

121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
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;
140 141
            q->weights1[i - 1] = ff_exp10(-1.0 * tb);
            q->weights2[i - 1] = ff_exp10(-2.7 * tb);
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 176
        }
        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
177
static av_cold int imc_decode_init(AVCodecContext *avctx)
Kostya Shishkov's avatar
Kostya Shishkov committed
178
{
179
    int i, j, ret;
Kostya Shishkov's avatar
Kostya Shishkov committed
180 181 182
    IMCContext *q = avctx->priv_data;
    double r1, r2;

183 184 185 186 187 188 189 190
    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;
    }

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

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

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

202 203 204 205 206 207
        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
208 209

    /* Build mdct window, a simple sine window normalized with sqrt(2) */
210
    ff_sine_window_init(q->mdct_sine_window, COEFFS);
Kostya Shishkov's avatar
Kostya Shishkov committed
211
    for (i = 0; i < COEFFS; i++)
212
        q->mdct_sine_window[i] *= sqrt(2.0);
Kostya Shishkov's avatar
Kostya Shishkov committed
213
    for (i = 0; i < COEFFS / 2; i++) {
214 215
        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
216 217 218 219

        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
220
        if (i & 0x1) {
Kostya Shishkov's avatar
Kostya Shishkov committed
221 222
            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
223
        } else {
Kostya Shishkov's avatar
Kostya Shishkov committed
224 225 226 227 228 229 230
            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
231
    for (i = 0; i < 30; i++)
Kostya Shishkov's avatar
Kostya Shishkov committed
232 233 234
        q->sqrt_tab[i] = sqrt(i);

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

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

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

        return AVERROR(ENOMEM);
    }

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

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

Kostya Shishkov's avatar
Kostya Shishkov committed
273 274 275
static void imc_calculate_coeffs(IMCContext *q, float *flcoeffs1,
                                 float *flcoeffs2, int *bandWidthT,
                                 float *flcoeffs3, float *flcoeffs5)
Kostya Shishkov's avatar
Kostya Shishkov committed
276 277 278 279 280 281 282 283
{
    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
284
    for (i = 0; i < BANDS; i++) {
Kostya Shishkov's avatar
Kostya Shishkov committed
285
        flcoeffs5[i] = workT2[i] = 0.0;
Kostya Shishkov's avatar
Kostya Shishkov committed
286
        if (bandWidthT[i]) {
Kostya Shishkov's avatar
Kostya Shishkov committed
287 288 289
            workT1[i] = flcoeffs1[i] * flcoeffs1[i];
            flcoeffs3[i] = 2.0 * flcoeffs2[i];
        } else {
Kostya Shishkov's avatar
Kostya Shishkov committed
290
            workT1[i]    = 0.0;
Kostya Shishkov's avatar
Kostya Shishkov committed
291 292 293 294 295 296 297
            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
298
    for (i = 0; i < BANDS; i++) {
Kostya Shishkov's avatar
Kostya Shishkov committed
299
        for (cnt2 = i; cnt2 < q->cyclTab[i]; cnt2++)
Kostya Shishkov's avatar
Kostya Shishkov committed
300
            flcoeffs5[cnt2] = flcoeffs5[cnt2] + workT3[i];
Kostya Shishkov's avatar
Kostya Shishkov committed
301
        workT2[cnt2 - 1] = workT2[cnt2 - 1] + workT3[i];
Kostya Shishkov's avatar
Kostya Shishkov committed
302 303
    }

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

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

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

    accum = 0.0;

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


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

    s = stream_format_code >> 1;
338 339 340 341
    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
342 343
    cb_sel = imc_cb_select[s];

Kostya Shishkov's avatar
Kostya Shishkov committed
344
    if (stream_format_code & 4)
Kostya Shishkov's avatar
Kostya Shishkov committed
345
        start = 1;
Kostya Shishkov's avatar
Kostya Shishkov committed
346
    if (start)
Kostya Shishkov's avatar
Kostya Shishkov committed
347
        levlCoeffs[0] = get_bits(&q->gb, 7);
Kostya Shishkov's avatar
Kostya Shishkov committed
348 349 350 351
    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
352 353 354 355
            levlCoeffs[i] += get_bits(&q->gb, 4);
    }
}

Kostya Shishkov's avatar
Kostya Shishkov committed
356 357 358 359 360 361 362 363 364 365 366
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
367 368
static void imc_decode_level_coefficients(IMCContext *q, int *levlCoeffBuf,
                                          float *flcoeffs1, float *flcoeffs2)
Kostya Shishkov's avatar
Kostya Shishkov committed
369 370 371
{
    int i, level;
    float tmp, tmp2;
Kostya Shishkov's avatar
Kostya Shishkov committed
372
    // maybe some frequency division thingy
Kostya Shishkov's avatar
Kostya Shishkov committed
373

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

Kostya Shishkov's avatar
Kostya Shishkov committed
379
    for (i = 1; i < BANDS; i++) {
Kostya Shishkov's avatar
Kostya Shishkov committed
380 381 382 383 384 385
        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
386
                level -= 7;
Kostya Shishkov's avatar
Kostya Shishkov committed
387
            else if (level <= 24)
Kostya Shishkov's avatar
Kostya Shishkov committed
388
                level -= 32;
Kostya Shishkov's avatar
Kostya Shishkov committed
389
            else
Kostya Shishkov's avatar
Kostya Shishkov committed
390
                level -= 16;
Kostya Shishkov's avatar
Kostya Shishkov committed
391 392

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


Kostya Shishkov's avatar
Kostya Shishkov committed
401 402 403 404
static void imc_decode_level_coefficients2(IMCContext *q, int *levlCoeffBuf,
                                           float *old_floor, float *flcoeffs1,
                                           float *flcoeffs2)
{
Kostya Shishkov's avatar
Kostya Shishkov committed
405
    int i;
Kostya Shishkov's avatar
Kostya Shishkov committed
406 407 408 409 410
    /* 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
411
        flcoeffs1[i] = 0;
Kostya Shishkov's avatar
Kostya Shishkov committed
412
        if (levlCoeffBuf[i] < 16) {
Kostya Shishkov's avatar
Kostya Shishkov committed
413
            flcoeffs1[i] = imc_exp_tab2[levlCoeffBuf[i]] * old_floor[i];
Kostya Shishkov's avatar
Kostya Shishkov committed
414
            flcoeffs2[i] = (levlCoeffBuf[i] - 7) * 0.83048 + flcoeffs2[i]; // 0.83048 = log2(10) * 0.25
Kostya Shishkov's avatar
Kostya Shishkov committed
415 416 417 418 419 420
        } else {
            flcoeffs1[i] = old_floor[i];
        }
    }
}

Kostya Shishkov's avatar
Kostya Shishkov committed
421 422 423 424 425 426 427 428
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
429
    flcoeffs2[pos] = log2f(flcoeffs1[pos]);
Kostya Shishkov's avatar
Kostya Shishkov committed
430 431 432 433 434 435 436 437 438 439 440 441 442
    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
443 444 445
/**
 * Perform bit allocation depending on bits available
 */
446 447
static int bit_allocation(IMCContext *q, IMCChannel *chctx,
                          int stream_format_code, int freebits, int flag)
Kostya Shishkov's avatar
Kostya Shishkov committed
448
{
Kostya Shishkov's avatar
Kostya Shishkov committed
449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464
    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
465
    for (i = 0; i < BANDS; i++)
466
        highest = FFMAX(highest, chctx->flcoeffs1[i]);
Kostya Shishkov's avatar
Kostya Shishkov committed
467

468 469 470 471 472
    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;
        }
473
        chctx->flcoeffs4[i] = chctx->flcoeffs3[i] - log2f(chctx->flcoeffs5[i]);
474
    }
475
    chctx->flcoeffs4[BANDS - 1] = limit;
Kostya Shishkov's avatar
Kostya Shishkov committed
476 477 478

    highest = highest * 0.25;

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

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

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

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

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

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

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

    if (!iacc)
        return AVERROR_INVALIDDATA;

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


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

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

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

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

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

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

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

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

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

        highest = 0.0;

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

            found_indx = 0;
            highest = -1.e20;

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

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

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

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

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

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

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

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

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

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

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

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

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

        highest = -1.e20;

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

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

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

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

    /* prerotation */
Kostya Shishkov's avatar
Kostya Shishkov committed
728
    for (i = 0; i < COEFFS / 2; i++) {
729 730 731 732
        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
733 734 735
    }

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

    /* postrotation, window and reorder */
Kostya Shishkov's avatar
Kostya Shishkov committed
740 741 742
    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]);
743 744 745 746
        *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);
747 748
        dst1 += 2;
        dst2 -= 2;
749
        chctx->last_fft_im[i] = im;
Kostya Shishkov's avatar
Kostya Shishkov committed
750 751 752
    }
}

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

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

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

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

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

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


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

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

806 807 808 809 810
                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);
811 812
                    } else
                        cw = get_bits(&q->gb, cw_len);
813
                }
Kostya Shishkov's avatar
Kostya Shishkov committed
814

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

Kostya Shishkov's avatar
Kostya Shishkov committed
821 822 823 824 825 826 827 828 829 830 831 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 864
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])
            if ((((band_tab[i + 1] - band_tab[i]) * 1.5) > chctx->sumLenArr[i]) && (chctx->sumLenArr[i] > 0))
                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);
}

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


    /* Check the frame header */
    imc_hdr = get_bits(&q->gb, 9);
Kostya Shishkov's avatar
Kostya Shishkov committed
877 878 879
    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);
880
        return AVERROR_INVALIDDATA;
Kostya Shishkov's avatar
Kostya Shishkov committed
881 882 883 884
    }
    stream_format_code = get_bits(&q->gb, 3);

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

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

    flag = get_bits1(&q->gb);
Kostya Shishkov's avatar
Kostya Shishkov committed
896 897 898 899
    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
900

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

911 912 913 914 915 916 917
    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;
        }
    }

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

    counter = 0;
Kostya Shishkov's avatar
Kostya Shishkov committed
921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940
    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
941

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

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

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

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

Kostya Shishkov's avatar
Kostya Shishkov committed
982 983 984 985 986
    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
987 988
    }

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

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

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

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

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

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

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

    return 0;
}

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

1022 1023
    IMCContext *q = avctx->priv_data;

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

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

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

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

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

        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
1048

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

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

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

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

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

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

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

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

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