~ubuntu-dev/mplayer/ubuntu-feisty

« back to all changes in this revision

Viewing changes to libavcodec/shorten.c

  • Committer: Reinhard Tartler
  • Date: 2006-07-08 08:45:33 UTC
  • Revision ID: siretart@tauware.de-20060708084533-dbc155bde7122e78
imported mplayer_0.99+1.0pre7try2+cvs20060117

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Shorten decoder
 
3
 * Copyright (c) 2005 Jeff Muizelaar
 
4
 *
 
5
 * This library is free software; you can redistribute it and/or
 
6
 * modify it under the terms of the GNU Lesser General Public
 
7
 * License as published by the Free Software Foundation; either
 
8
 * version 2 of the License, or (at your option) any later version.
 
9
 *
 
10
 * This library is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
13
 * Lesser General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU Lesser General Public
 
16
 * License along with this library; if not, write to the Free Software
 
17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
18
 */
 
19
 
 
20
/**
 
21
 * @file shorten.c
 
22
 * Shorten decoder
 
23
 * @author Jeff Muizelaar
 
24
 *
 
25
 */
 
26
 
 
27
#define DEBUG
 
28
#include <limits.h>
 
29
#include "avcodec.h"
 
30
#include "bitstream.h"
 
31
#include "golomb.h"
 
32
 
 
33
#define MAX_CHANNELS 8
 
34
#define MAX_BLOCKSIZE 65535
 
35
 
 
36
#define OUT_BUFFER_SIZE 16384
 
37
 
 
38
#define ULONGSIZE 2
 
39
 
 
40
#define WAVE_FORMAT_PCM 0x0001
 
41
 
 
42
#define DEFAULT_BLOCK_SIZE 256
 
43
 
 
44
#define TYPESIZE 4
 
45
#define CHANSIZE 0
 
46
#define LPCQSIZE 2
 
47
#define ENERGYSIZE 3
 
48
#define BITSHIFTSIZE 2
 
49
 
 
50
#define TYPE_S16HL 3
 
51
#define TYPE_S16LH 5
 
52
 
 
53
#define NWRAP 3
 
54
#define NSKIPSIZE 1
 
55
 
 
56
#define LPCQUANT 5
 
57
#define V2LPCQOFFSET (1 << LPCQUANT)
 
58
 
 
59
#define FNSIZE 2
 
60
#define FN_DIFF0        0
 
61
#define FN_DIFF1        1
 
62
#define FN_DIFF2        2
 
63
#define FN_DIFF3        3
 
64
#define FN_QUIT         4
 
65
#define FN_BLOCKSIZE    5
 
66
#define FN_BITSHIFT     6
 
67
#define FN_QLPC         7
 
68
#define FN_ZERO         8
 
69
#define FN_VERBATIM     9
 
70
 
 
71
#define VERBATIM_CKSIZE_SIZE 5
 
72
#define VERBATIM_BYTE_SIZE 8
 
73
#define CANONICAL_HEADER_SIZE 44
 
74
 
 
75
typedef struct ShortenContext {
 
76
    AVCodecContext *avctx;
 
77
    GetBitContext gb;
 
78
 
 
79
    int min_framesize, max_framesize;
 
80
    int channels;
 
81
 
 
82
    int32_t *decoded[MAX_CHANNELS];
 
83
    int32_t *offset[MAX_CHANNELS];
 
84
    uint8_t *bitstream;
 
85
    int bitstream_size;
 
86
    int bitstream_index;
 
87
    int allocated_bitstream_size;
 
88
    int header_size;
 
89
    uint8_t header[OUT_BUFFER_SIZE];
 
90
    int version;
 
91
    int cur_chan;
 
92
    int bitshift;
 
93
    int nmean;
 
94
    int internal_ftype;
 
95
    int nwrap;
 
96
    int blocksize;
 
97
    int bitindex;
 
98
    int32_t lpcqoffset;
 
99
} ShortenContext;
 
100
 
 
101
static int shorten_decode_init(AVCodecContext * avctx)
 
102
{
 
103
    ShortenContext *s = avctx->priv_data;
 
104
    s->avctx = avctx;
 
105
 
 
106
    return 0;
 
107
}
 
108
 
 
109
static void allocate_buffers(ShortenContext *s)
 
110
{
 
111
    int i, chan;
 
112
    for (chan=0; chan<s->channels; chan++) {
 
113
        s->offset[chan] = av_realloc(s->offset[chan], sizeof(int32_t)*FFMAX(1, s->nmean));
 
114
 
 
115
        s->decoded[chan] = av_realloc(s->decoded[chan], sizeof(int32_t)*(s->blocksize + s->nwrap));
 
116
        for (i=0; i<s->nwrap; i++)
 
117
            s->decoded[chan][i] = 0;
 
118
        s->decoded[chan] += s->nwrap;
 
119
 
 
120
    }
 
121
}
 
122
 
 
123
 
 
124
static inline unsigned int get_uint(ShortenContext *s, int k)
 
125
{
 
126
    if (s->version != 0)
 
127
        k = get_ur_golomb_shorten(&s->gb, ULONGSIZE);
 
128
    return get_ur_golomb_shorten(&s->gb, k);
 
129
}
 
130
 
 
131
 
 
132
static void fix_bitshift(ShortenContext *s, int32_t *buffer)
 
133
{
 
134
    int i;
 
135
 
 
136
    if (s->bitshift != 0)
 
137
        for (i = 0; i < s->blocksize; i++)
 
138
            buffer[s->nwrap + i] <<= s->bitshift;
 
139
}
 
140
 
 
141
 
 
142
static void init_offset(ShortenContext *s)
 
143
{
 
144
    int32_t mean = 0;
 
145
    int  chan, i;
 
146
    int nblock = FFMAX(1, s->nmean);
 
147
    /* initialise offset */
 
148
    switch (s->internal_ftype)
 
149
    {
 
150
        case TYPE_S16HL:
 
151
        case TYPE_S16LH:
 
152
            mean = 0;
 
153
            break;
 
154
        default:
 
155
            av_log(s->avctx, AV_LOG_ERROR, "unknown audio type");
 
156
            abort();
 
157
    }
 
158
 
 
159
    for (chan = 0; chan < s->channels; chan++)
 
160
        for (i = 0; i < nblock; i++)
 
161
            s->offset[chan][i] = mean;
 
162
}
 
163
 
 
164
static int inline get_le32(GetBitContext *gb)
 
165
{
 
166
    return bswap_32(get_bits_long(gb, 32));
 
167
}
 
168
 
 
169
static short inline get_le16(GetBitContext *gb)
 
170
{
 
171
    return bswap_16(get_bits_long(gb, 16));
 
172
}
 
173
 
 
174
static int decode_wave_header(AVCodecContext *avctx, uint8_t *header, int header_size)
 
175
{
 
176
    GetBitContext hb;
 
177
    int len;
 
178
    int chunk_size;
 
179
    short wave_format;
 
180
 
 
181
    init_get_bits(&hb, header, header_size*8);
 
182
    if (get_le32(&hb) != MKTAG('R','I','F','F')) {
 
183
        av_log(avctx, AV_LOG_ERROR, "missing RIFF tag\n");
 
184
        return -1;
 
185
    }
 
186
 
 
187
    chunk_size = get_le32(&hb);
 
188
 
 
189
    if (get_le32(&hb) != MKTAG('W','A','V','E')) {
 
190
        av_log(avctx, AV_LOG_ERROR, "missing WAVE tag\n");
 
191
        return -1;
 
192
    }
 
193
 
 
194
    while (get_le32(&hb) != MKTAG('f','m','t',' ')) {
 
195
        len = get_le32(&hb);
 
196
        skip_bits(&hb, 8*len);
 
197
    }
 
198
    len = get_le32(&hb);
 
199
 
 
200
    if (len < 16) {
 
201
        av_log(avctx, AV_LOG_ERROR, "fmt chunk was too short\n");
 
202
        return -1;
 
203
    }
 
204
 
 
205
    wave_format = get_le16(&hb);
 
206
 
 
207
    switch (wave_format) {
 
208
        case WAVE_FORMAT_PCM:
 
209
            break;
 
210
        default:
 
211
            av_log(avctx, AV_LOG_ERROR, "unsupported wave format\n");
 
212
            return -1;
 
213
    }
 
214
 
 
215
    avctx->channels = get_le16(&hb);
 
216
    avctx->sample_rate = get_le32(&hb);
 
217
    avctx->bit_rate = get_le32(&hb) * 8;
 
218
    avctx->block_align = get_le16(&hb);
 
219
    avctx->bits_per_sample = get_le16(&hb);
 
220
 
 
221
    if (avctx->bits_per_sample != 16) {
 
222
        av_log(avctx, AV_LOG_ERROR, "unsupported number of bits per sample\n");
 
223
        return -1;
 
224
    }
 
225
 
 
226
    len -= 16;
 
227
    if (len > 0)
 
228
        av_log(avctx, AV_LOG_INFO, "%d header bytes unparsed\n", len);
 
229
 
 
230
    return 0;
 
231
}
 
232
 
 
233
static int16_t * interleave_buffer(int16_t *samples, int nchan, int blocksize, int32_t **buffer) {
 
234
    int i, chan;
 
235
    for (i=0; i<blocksize; i++)
 
236
        for (chan=0; chan < nchan; chan++)
 
237
            *samples++ = FFMIN(buffer[chan][i], 32768);
 
238
    return samples;
 
239
}
 
240
 
 
241
static void decode_subframe_lpc(ShortenContext *s, int channel, int residual_size, int pred_order)
 
242
{
 
243
    int sum, i, j;
 
244
    int coeffs[pred_order];
 
245
 
 
246
    for (i=0; i<pred_order; i++)
 
247
        coeffs[i] = get_sr_golomb_shorten(&s->gb, LPCQUANT);
 
248
 
 
249
    for (i=0; i < s->blocksize; i++) {
 
250
        sum = s->lpcqoffset;
 
251
        for (j=0; j<pred_order; j++)
 
252
            sum += coeffs[j] * s->decoded[channel][i-j-1];
 
253
        s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + (sum >> LPCQUANT);
 
254
    }
 
255
}
 
256
 
 
257
 
 
258
static int shorten_decode_frame(AVCodecContext *avctx,
 
259
        void *data, int *data_size,
 
260
        uint8_t *buf, int buf_size)
 
261
{
 
262
    ShortenContext *s = avctx->priv_data;
 
263
    int i, input_buf_size = 0;
 
264
    int16_t *samples = data;
 
265
    if(s->max_framesize == 0){
 
266
        s->max_framesize= 1024; // should hopefully be enough for the first header
 
267
        s->bitstream= av_fast_realloc(s->bitstream, &s->allocated_bitstream_size, s->max_framesize);
 
268
    }
 
269
 
 
270
    if(1 && s->max_framesize){//FIXME truncated
 
271
        buf_size= FFMIN(buf_size, s->max_framesize - s->bitstream_size);
 
272
        input_buf_size= buf_size;
 
273
 
 
274
        if(s->bitstream_index + s->bitstream_size + buf_size > s->allocated_bitstream_size){
 
275
            //                printf("memmove\n");
 
276
            memmove(s->bitstream, &s->bitstream[s->bitstream_index], s->bitstream_size);
 
277
            s->bitstream_index=0;
 
278
        }
 
279
        memcpy(&s->bitstream[s->bitstream_index + s->bitstream_size], buf, buf_size);
 
280
        buf= &s->bitstream[s->bitstream_index];
 
281
        buf_size += s->bitstream_size;
 
282
        s->bitstream_size= buf_size;
 
283
 
 
284
        if(buf_size < s->max_framesize){
 
285
            //dprintf("wanna more data ... %d\n", buf_size);
 
286
            return input_buf_size;
 
287
        }
 
288
    }
 
289
    init_get_bits(&s->gb, buf, buf_size*8);
 
290
    get_bits(&s->gb, s->bitindex);
 
291
    if (!s->blocksize)
 
292
    {
 
293
        int maxnlpc = 0;
 
294
        /* shorten signature */
 
295
        if (get_bits_long(&s->gb, 32) != bswap_32(ff_get_fourcc("ajkg"))) {
 
296
            av_log(s->avctx, AV_LOG_ERROR, "missing shorten magic 'ajkg'\n");
 
297
            return -1;
 
298
        }
 
299
 
 
300
        s->lpcqoffset = 0;
 
301
        s->blocksize = DEFAULT_BLOCK_SIZE;
 
302
        s->channels = 1;
 
303
        s->nmean = -1;
 
304
        s->version = get_bits(&s->gb, 8);
 
305
        s->internal_ftype = get_uint(s, TYPESIZE);
 
306
 
 
307
        s->channels = get_uint(s, CHANSIZE);
 
308
        if (s->channels > MAX_CHANNELS) {
 
309
            av_log(s->avctx, AV_LOG_ERROR, "too many channels: %d\n", s->channels);
 
310
            return -1;
 
311
        }
 
312
 
 
313
        /* get blocksize if version > 0 */
 
314
        if (s->version > 0) {
 
315
            int skip_bytes;
 
316
            s->blocksize = get_uint(s, av_log2(DEFAULT_BLOCK_SIZE));
 
317
            maxnlpc = get_uint(s, LPCQSIZE);
 
318
            s->nmean = get_uint(s, 0);
 
319
 
 
320
            skip_bytes = get_uint(s, NSKIPSIZE);
 
321
            for (i=0; i<skip_bytes; i++) {
 
322
                skip_bits(&s->gb, 8);
 
323
            }
 
324
        }
 
325
        s->nwrap = FFMAX(NWRAP, maxnlpc);
 
326
 
 
327
        allocate_buffers(s);
 
328
 
 
329
        init_offset(s);
 
330
 
 
331
        if (s->version > 1)
 
332
            s->lpcqoffset = V2LPCQOFFSET;
 
333
 
 
334
        if (get_ur_golomb_shorten(&s->gb, FNSIZE) != FN_VERBATIM) {
 
335
            av_log(s->avctx, AV_LOG_ERROR, "missing verbatim section at begining of stream\n");
 
336
            return -1;
 
337
        }
 
338
 
 
339
        s->header_size = get_ur_golomb_shorten(&s->gb, VERBATIM_CKSIZE_SIZE);
 
340
        if (s->header_size >= OUT_BUFFER_SIZE || s->header_size < CANONICAL_HEADER_SIZE) {
 
341
            av_log(s->avctx, AV_LOG_ERROR, "header is wrong size: %d\n", s->header_size);
 
342
            return -1;
 
343
        }
 
344
 
 
345
        for (i=0; i<s->header_size; i++)
 
346
            s->header[i] = (char)get_ur_golomb_shorten(&s->gb, VERBATIM_BYTE_SIZE);
 
347
 
 
348
        if (decode_wave_header(avctx, s->header, s->header_size) < 0)
 
349
            return -1;
 
350
 
 
351
        s->cur_chan = 0;
 
352
        s->bitshift = 0;
 
353
    }
 
354
    else
 
355
    {
 
356
        int cmd;
 
357
        int len;
 
358
        cmd = get_ur_golomb_shorten(&s->gb, FNSIZE);
 
359
        switch (cmd) {
 
360
            case FN_ZERO:
 
361
            case FN_DIFF0:
 
362
            case FN_DIFF1:
 
363
            case FN_DIFF2:
 
364
            case FN_DIFF3:
 
365
            case FN_QLPC:
 
366
                {
 
367
                    int residual_size = 0;
 
368
                    int channel = s->cur_chan;
 
369
                    int32_t coffset;
 
370
                    if (cmd != FN_ZERO) {
 
371
                        residual_size = get_ur_golomb_shorten(&s->gb, ENERGYSIZE);
 
372
                        /* this is a hack as version 0 differed in defintion of get_sr_golomb_shorten */
 
373
                        if (s->version == 0)
 
374
                            residual_size--;
 
375
                    }
 
376
 
 
377
                    if (s->nmean == 0)
 
378
                        coffset = s->offset[channel][0];
 
379
                    else {
 
380
                        int32_t sum = (s->version < 2) ? 0 : s->nmean / 2;
 
381
                        for (i=0; i<s->nmean; i++)
 
382
                            sum += s->offset[channel][i];
 
383
                        coffset = sum / s->nmean;
 
384
                        if (s->version >= 2)
 
385
                            coffset >>= FFMIN(1, s->bitshift);
 
386
                    }
 
387
                    switch (cmd) {
 
388
                        case FN_ZERO:
 
389
                            for (i=0; i<s->blocksize; i++)
 
390
                                s->decoded[channel][i] = 0;
 
391
                            break;
 
392
                        case FN_DIFF0:
 
393
                            for (i=0; i<s->blocksize; i++)
 
394
                                s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + coffset;
 
395
                            break;
 
396
                        case FN_DIFF1:
 
397
                            for (i=0; i<s->blocksize; i++)
 
398
                                s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + s->decoded[channel][i - 1];
 
399
                            break;
 
400
                        case FN_DIFF2:
 
401
                            for (i=0; i<s->blocksize; i++)
 
402
                                s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + 2*s->decoded[channel][i-1]
 
403
                                                                                                      -   s->decoded[channel][i-2];
 
404
                            break;
 
405
                        case FN_DIFF3:
 
406
                            for (i=0; i<s->blocksize; i++)
 
407
                                s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + 3*s->decoded[channel][i-1]
 
408
                                                                                                      - 3*s->decoded[channel][i-2]
 
409
                                                                                                      +   s->decoded[channel][i-3];
 
410
                            break;
 
411
                        case FN_QLPC:
 
412
                            {
 
413
                                int pred_order = get_ur_golomb_shorten(&s->gb, LPCQSIZE);
 
414
                                for (i=0; i<pred_order; i++)
 
415
                                    s->decoded[channel][i - pred_order] -= coffset;
 
416
                                decode_subframe_lpc(s, channel, residual_size, pred_order);
 
417
                                if (coffset != 0)
 
418
                                    for (i=0; i < s->blocksize; i++)
 
419
                                        s->decoded[channel][i] += coffset;
 
420
                            }
 
421
                    }
 
422
                    if (s->nmean > 0) {
 
423
                        int32_t sum = (s->version < 2) ? 0 : s->blocksize / 2;
 
424
                        for (i=0; i<s->blocksize; i++)
 
425
                            sum += s->decoded[channel][i];
 
426
 
 
427
                        for (i=1; i<s->nmean; i++)
 
428
                            s->offset[channel][i-1] = s->offset[channel][i];
 
429
 
 
430
                        if (s->version < 2)
 
431
                            s->offset[channel][s->nmean - 1] = sum / s->blocksize;
 
432
                        else
 
433
                            s->offset[channel][s->nmean - 1] = (sum / s->blocksize) << s->bitshift;
 
434
                    }
 
435
                    for (i=-s->nwrap; i<0; i++)
 
436
                        s->decoded[channel][i] = s->decoded[channel][i + s->blocksize];
 
437
 
 
438
                    fix_bitshift(s, s->decoded[channel]);
 
439
 
 
440
                    s->cur_chan++;
 
441
                    if (s->cur_chan == s->channels) {
 
442
                        samples = interleave_buffer(samples, s->channels, s->blocksize, s->decoded);
 
443
                        s->cur_chan = 0;
 
444
                        goto frame_done;
 
445
                    }
 
446
                    break;
 
447
                }
 
448
                break;
 
449
            case FN_VERBATIM:
 
450
                len = get_ur_golomb_shorten(&s->gb, VERBATIM_CKSIZE_SIZE);
 
451
                while (len--) {
 
452
                    get_ur_golomb_shorten(&s->gb, VERBATIM_BYTE_SIZE);
 
453
                }
 
454
                break;
 
455
            case FN_BITSHIFT:
 
456
                s->bitshift = get_ur_golomb_shorten(&s->gb, BITSHIFTSIZE);
 
457
                break;
 
458
            case FN_BLOCKSIZE:
 
459
                s->blocksize = get_uint(s, av_log2(s->blocksize));
 
460
                break;
 
461
            case FN_QUIT:
 
462
                return buf_size;
 
463
                break;
 
464
            default:
 
465
                av_log(avctx, AV_LOG_ERROR, "unknown shorten function %d\n", cmd);
 
466
                return -1;
 
467
                break;
 
468
        }
 
469
    }
 
470
frame_done:
 
471
    *data_size = (int8_t *)samples - (int8_t *)data;
 
472
 
 
473
    //    s->last_blocksize = s->blocksize;
 
474
    s->bitindex = get_bits_count(&s->gb) - 8*((get_bits_count(&s->gb))/8);
 
475
    i= (get_bits_count(&s->gb))/8;
 
476
    if (i > buf_size) {
 
477
        av_log(s->avctx, AV_LOG_ERROR, "overread: %d\n", i - buf_size);
 
478
        s->bitstream_size=0;
 
479
        s->bitstream_index=0;
 
480
        return -1;
 
481
    }
 
482
    if (s->bitstream_size) {
 
483
        s->bitstream_index += i;
 
484
        s->bitstream_size  -= i;
 
485
        return input_buf_size;
 
486
    } else
 
487
        return i;
 
488
}
 
489
 
 
490
static int shorten_decode_close(AVCodecContext *avctx)
 
491
{
 
492
    ShortenContext *s = avctx->priv_data;
 
493
    int i;
 
494
 
 
495
    for (i = 0; i < s->channels; i++) {
 
496
        s->decoded[i] -= s->nwrap;
 
497
        av_freep(&s->decoded[i]);
 
498
        av_freep(&s->offset[i]);
 
499
    }
 
500
    av_freep(&s->bitstream);
 
501
    return 0;
 
502
}
 
503
 
 
504
static void shorten_flush(AVCodecContext *avctx){
 
505
    ShortenContext *s = avctx->priv_data;
 
506
 
 
507
    s->bitstream_size=
 
508
        s->bitstream_index= 0;
 
509
}
 
510
 
 
511
AVCodec shorten_decoder = {
 
512
    "shorten",
 
513
    CODEC_TYPE_AUDIO,
 
514
    CODEC_ID_SHORTEN,
 
515
    sizeof(ShortenContext),
 
516
    shorten_decode_init,
 
517
    NULL,
 
518
    shorten_decode_close,
 
519
    shorten_decode_frame,
 
520
    .flush= shorten_flush,
 
521
};