Mercurial > libavcodec.hg
comparison wma.c @ 10314:ab687351bfef libavcodec
WMA: store level_table as floats, use type punning for sign flip in decode
author | mru |
---|---|
date | Tue, 29 Sep 2009 10:38:34 +0000 |
parents | 89cd870ca180 |
children | 3d011a01a6a0 |
comparison
equal
deleted
inserted
replaced
10313:f7376a522a7e | 10314:ab687351bfef |
---|---|
27 #include <assert.h> | 27 #include <assert.h> |
28 | 28 |
29 /* XXX: use same run/length optimization as mpeg decoders */ | 29 /* XXX: use same run/length optimization as mpeg decoders */ |
30 //FIXME maybe split decode / encode or pass flag | 30 //FIXME maybe split decode / encode or pass flag |
31 static void init_coef_vlc(VLC *vlc, uint16_t **prun_table, | 31 static void init_coef_vlc(VLC *vlc, uint16_t **prun_table, |
32 uint16_t **plevel_table, uint16_t **pint_table, | 32 float **plevel_table, uint16_t **pint_table, |
33 const CoefVLCTable *vlc_table) | 33 const CoefVLCTable *vlc_table) |
34 { | 34 { |
35 int n = vlc_table->n; | 35 int n = vlc_table->n; |
36 const uint8_t *table_bits = vlc_table->huffbits; | 36 const uint8_t *table_bits = vlc_table->huffbits; |
37 const uint32_t *table_codes = vlc_table->huffcodes; | 37 const uint32_t *table_codes = vlc_table->huffcodes; |
38 const uint16_t *levels_table = vlc_table->levels; | 38 const uint16_t *levels_table = vlc_table->levels; |
39 uint16_t *run_table, *level_table, *int_table; | 39 uint16_t *run_table, *level_table, *int_table; |
40 float *flevel_table; | |
40 int i, l, j, k, level; | 41 int i, l, j, k, level; |
41 | 42 |
42 init_vlc(vlc, VLCBITS, n, table_bits, 1, 1, table_codes, 4, 4, 0); | 43 init_vlc(vlc, VLCBITS, n, table_bits, 1, 1, table_codes, 4, 4, 0); |
43 | 44 |
44 run_table = av_malloc(n * sizeof(uint16_t)); | 45 run_table = av_malloc(n * sizeof(uint16_t)); |
45 level_table = av_malloc(n * sizeof(uint16_t)); | 46 level_table = av_malloc(n * sizeof(uint16_t)); |
47 flevel_table= av_malloc(n * sizeof(*flevel_table)); | |
46 int_table = av_malloc(n * sizeof(uint16_t)); | 48 int_table = av_malloc(n * sizeof(uint16_t)); |
47 i = 2; | 49 i = 2; |
48 level = 1; | 50 level = 1; |
49 k = 0; | 51 k = 0; |
50 while (i < n) { | 52 while (i < n) { |
51 int_table[k] = i; | 53 int_table[k] = i; |
52 l = levels_table[k++]; | 54 l = levels_table[k++]; |
53 for (j = 0; j < l; j++) { | 55 for (j = 0; j < l; j++) { |
54 run_table[i] = j; | 56 run_table[i] = j; |
55 level_table[i] = level; | 57 level_table[i] = level; |
58 flevel_table[i]= level; | |
56 i++; | 59 i++; |
57 } | 60 } |
58 level++; | 61 level++; |
59 } | 62 } |
60 *prun_table = run_table; | 63 *prun_table = run_table; |
61 *plevel_table = level_table; | 64 *plevel_table = flevel_table; |
62 *pint_table = int_table; | 65 *pint_table = int_table; |
66 av_free(level_table); | |
63 } | 67 } |
64 | 68 |
65 /** | 69 /** |
66 *@brief Get the samples per frame for this stream. | 70 *@brief Get the samples per frame for this stream. |
67 *@param sample_rate output sample_rate | 71 *@param sample_rate output sample_rate |
463 * @param coef_nb_bits number of bits for escaped level codes | 467 * @param coef_nb_bits number of bits for escaped level codes |
464 * @return 0 on success, -1 otherwise | 468 * @return 0 on success, -1 otherwise |
465 */ | 469 */ |
466 int ff_wma_run_level_decode(AVCodecContext* avctx, GetBitContext* gb, | 470 int ff_wma_run_level_decode(AVCodecContext* avctx, GetBitContext* gb, |
467 VLC *vlc, | 471 VLC *vlc, |
468 const uint16_t *level_table, const uint16_t *run_table, | 472 const float *level_table, const uint16_t *run_table, |
469 int version, WMACoef *ptr, int offset, | 473 int version, WMACoef *ptr, int offset, |
470 int num_coefs, int block_len, int frame_len_bits, | 474 int num_coefs, int block_len, int frame_len_bits, |
471 int coef_nb_bits) | 475 int coef_nb_bits) |
472 { | 476 { |
473 int code, level, sign; | 477 int code, level, sign; |
478 const uint32_t *ilvl = (const uint32_t*)level_table; | |
479 uint32_t *iptr = (uint32_t*)ptr; | |
474 const unsigned int coef_mask = block_len - 1; | 480 const unsigned int coef_mask = block_len - 1; |
475 for (; offset < num_coefs; offset++) { | 481 for (; offset < num_coefs; offset++) { |
476 code = get_vlc2(gb, vlc->table, VLCBITS, VLCMAX); | 482 code = get_vlc2(gb, vlc->table, VLCBITS, VLCMAX); |
477 if (code > 1) { | 483 if (code > 1) { |
478 /** normal code */ | 484 /** normal code */ |
479 offset += run_table[code]; | 485 offset += run_table[code]; |
480 level = level_table[code]; | 486 sign = get_bits1(gb) - 1; |
487 iptr[offset & coef_mask] = ilvl[code] ^ sign<<31; | |
481 } else if (code == 1) { | 488 } else if (code == 1) { |
482 /** EOB */ | 489 /** EOB */ |
483 break; | 490 break; |
484 } else { | 491 } else { |
485 /** escape */ | 492 /** escape */ |
501 offset += get_bits(gb, frame_len_bits) + 4; | 508 offset += get_bits(gb, frame_len_bits) + 4; |
502 } else | 509 } else |
503 offset += get_bits(gb, 2) + 1; | 510 offset += get_bits(gb, 2) + 1; |
504 } | 511 } |
505 } | 512 } |
506 } | 513 sign = get_bits1(gb) - 1; |
507 sign = get_bits1(gb) - 1; | 514 ptr[offset & coef_mask] = (level^sign) - sign; |
508 ptr[offset & coef_mask] = (level^sign) - sign; | 515 } |
509 } | 516 } |
510 /** NOTE: EOB can be omitted */ | 517 /** NOTE: EOB can be omitted */ |
511 if (offset > num_coefs) { | 518 if (offset > num_coefs) { |
512 av_log(avctx, AV_LOG_ERROR, "overflow in spectral RLE, ignoring\n"); | 519 av_log(avctx, AV_LOG_ERROR, "overflow in spectral RLE, ignoring\n"); |
513 return -1; | 520 return -1; |