Mercurial > libavcodec.hg
comparison wmaprodec.c @ 10428:99a26e9d6e1b libavcodec
WMAPRO: use some type punning in decode_coeffs()
author | mru |
---|---|
date | Sun, 18 Oct 2009 18:51:54 +0000 |
parents | c8edd2033038 |
children | 3d011a01a6a0 |
comparison
equal
deleted
inserted
replaced
10427:1a3908177e87 | 10428:99a26e9d6e1b |
---|---|
760 *@param c current channel number | 760 *@param c current channel number |
761 *@return 0 on success, < 0 in case of bitstream errors | 761 *@return 0 on success, < 0 in case of bitstream errors |
762 */ | 762 */ |
763 static int decode_coeffs(WMAProDecodeCtx *s, int c) | 763 static int decode_coeffs(WMAProDecodeCtx *s, int c) |
764 { | 764 { |
765 /* Integers 0..15 as single-precision floats. The table saves a | |
766 costly int to float conversion, and storing the values as | |
767 integers allows fast sign-flipping. */ | |
768 static const int fval_tab[16] = { | |
769 0x00000000, 0x3f800000, 0x40000000, 0x40400000, | |
770 0x40800000, 0x40a00000, 0x40c00000, 0x40e00000, | |
771 0x41000000, 0x41100000, 0x41200000, 0x41300000, | |
772 0x41400000, 0x41500000, 0x41600000, 0x41700000, | |
773 }; | |
765 int vlctable; | 774 int vlctable; |
766 VLC* vlc; | 775 VLC* vlc; |
767 WMAProChannelCtx* ci = &s->channel[c]; | 776 WMAProChannelCtx* ci = &s->channel[c]; |
768 int rl_mode = 0; | 777 int rl_mode = 0; |
769 int cur_coeff = 0; | 778 int cur_coeff = 0; |
795 | 804 |
796 if (idx == HUFF_VEC4_SIZE - 1) { | 805 if (idx == HUFF_VEC4_SIZE - 1) { |
797 for (i = 0; i < 4; i += 2) { | 806 for (i = 0; i < 4; i += 2) { |
798 idx = get_vlc2(&s->gb, vec2_vlc.table, VLCBITS, VEC2MAXDEPTH); | 807 idx = get_vlc2(&s->gb, vec2_vlc.table, VLCBITS, VEC2MAXDEPTH); |
799 if (idx == HUFF_VEC2_SIZE - 1) { | 808 if (idx == HUFF_VEC2_SIZE - 1) { |
800 vals[i] = get_vlc2(&s->gb, vec1_vlc.table, VLCBITS, VEC1MAXDEPTH); | 809 int v0, v1; |
801 if (vals[i] == HUFF_VEC1_SIZE - 1) | 810 v0 = get_vlc2(&s->gb, vec1_vlc.table, VLCBITS, VEC1MAXDEPTH); |
802 vals[i] += ff_wma_get_large_val(&s->gb); | 811 if (v0 == HUFF_VEC1_SIZE - 1) |
803 vals[i+1] = get_vlc2(&s->gb, vec1_vlc.table, VLCBITS, VEC1MAXDEPTH); | 812 v0 += ff_wma_get_large_val(&s->gb); |
804 if (vals[i+1] == HUFF_VEC1_SIZE - 1) | 813 v1 = get_vlc2(&s->gb, vec1_vlc.table, VLCBITS, VEC1MAXDEPTH); |
805 vals[i+1] += ff_wma_get_large_val(&s->gb); | 814 if (v1 == HUFF_VEC1_SIZE - 1) |
815 v1 += ff_wma_get_large_val(&s->gb); | |
816 ((float*)vals)[i ] = v0; | |
817 ((float*)vals)[i+1] = v1; | |
806 } else { | 818 } else { |
807 vals[i] = symbol_to_vec2[idx] >> 4; | 819 vals[i] = fval_tab[symbol_to_vec2[idx] >> 4 ]; |
808 vals[i+1] = symbol_to_vec2[idx] & 0xF; | 820 vals[i+1] = fval_tab[symbol_to_vec2[idx] & 0xF]; |
809 } | 821 } |
810 } | 822 } |
811 } else { | 823 } else { |
812 vals[0] = symbol_to_vec4[idx] >> 12; | 824 vals[0] = fval_tab[ symbol_to_vec4[idx] >> 12 ]; |
813 vals[1] = (symbol_to_vec4[idx] >> 8) & 0xF; | 825 vals[1] = fval_tab[(symbol_to_vec4[idx] >> 8) & 0xF]; |
814 vals[2] = (symbol_to_vec4[idx] >> 4) & 0xF; | 826 vals[2] = fval_tab[(symbol_to_vec4[idx] >> 4) & 0xF]; |
815 vals[3] = symbol_to_vec4[idx] & 0xF; | 827 vals[3] = fval_tab[ symbol_to_vec4[idx] & 0xF]; |
816 } | 828 } |
817 | 829 |
818 /** decode sign */ | 830 /** decode sign */ |
819 for (i = 0; i < 4; i++) { | 831 for (i = 0; i < 4; i++) { |
820 if (vals[i]) { | 832 if (vals[i]) { |
821 int sign = get_bits1(&s->gb) - 1; | 833 int sign = get_bits1(&s->gb) - 1; |
822 ci->coeffs[cur_coeff] = (vals[i] ^ sign) - sign; | 834 *(uint32_t*)&ci->coeffs[cur_coeff] = vals[i] ^ sign<<31; |
823 num_zeros = 0; | 835 num_zeros = 0; |
824 } else { | 836 } else { |
825 ci->coeffs[cur_coeff] = 0; | 837 ci->coeffs[cur_coeff] = 0; |
826 /** switch to run level mode when subframe_len / 128 zeros | 838 /** switch to run level mode when subframe_len / 128 zeros |
827 were found in a row */ | 839 were found in a row */ |