Mercurial > libavcodec.hg
comparison shorten.c @ 2525:b47af698085e libavcodec
shorten decoder by (Jeff Muizelaar <jrmuizel gmail com>)
author | michael |
---|---|
date | Sat, 26 Feb 2005 03:36:04 +0000 |
parents | |
children | 0b546eab515d |
comparison
equal
deleted
inserted
replaced
2524:673d048d48dc | 2525:b47af698085e |
---|---|
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 }; |