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;