[FFmpeg-devel] [PATCH 12/12] WMAPRO: use some type punning in decode_coeffs()
Sascha Sommer
saschasommer
Sat Oct 10 19:20:25 CEST 2009
Hi,
On Sonntag, 27. September 2009, Mans Rullgard wrote:
> ---
> libavcodec/wmaprodec.c | 35 ++++++++++++++++++++++-------------
> 1 files changed, 22 insertions(+), 13 deletions(-)
>
> diff --git a/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c
> index e483733..2598ff2 100644
> --- a/libavcodec/wmaprodec.c
> +++ b/libavcodec/wmaprodec.c
> @@ -766,6 +766,12 @@ static int decode_channel_transform(WMAProDecodeCtx*
> s) */
> static int decode_coeffs(WMAProDecodeCtx *s, int c)
> {
> + static const int fval_tab[16] = {
> + 0x00000000, 0x3f800000, 0x40000000, 0x40400000,
> + 0x40800000, 0x40a00000, 0x40c00000, 0x40e00000,
> + 0x41000000, 0x41100000, 0x41200000, 0x41300000,
> + 0x41400000, 0x41500000, 0x41600000, 0x41700000,
> + };
> int vlctable;
> VLC* vlc;
> WMAProChannelCtx* ci = &s->channel[c];
> @@ -801,29 +807,32 @@ static int decode_coeffs(WMAProDecodeCtx *s, int c)
> for (i = 0; i < 4; i += 2) {
> idx = get_vlc2(&s->gb, vec2_vlc.table, VLCBITS,
> VEC2MAXDEPTH); if (idx == HUFF_VEC2_SIZE - 1) {
> - vals[i] = get_vlc2(&s->gb, vec1_vlc.table, VLCBITS,
> VEC1MAXDEPTH); - if (vals[i] == HUFF_VEC1_SIZE - 1)
> - vals[i] += ff_wma_get_large_val(&s->gb);
> - vals[i+1] = get_vlc2(&s->gb, vec1_vlc.table, VLCBITS,
> VEC1MAXDEPTH); - if (vals[i+1] == HUFF_VEC1_SIZE - 1)
> - vals[i+1] += ff_wma_get_large_val(&s->gb);
> + int v0, v1;
> + v0 = get_vlc2(&s->gb, vec1_vlc.table, VLCBITS,
> VEC1MAXDEPTH); + if (v0 == HUFF_VEC1_SIZE - 1)
> + v0 += ff_wma_get_large_val(&s->gb);
> + v1 = get_vlc2(&s->gb, vec1_vlc.table, VLCBITS,
> VEC1MAXDEPTH); + if (v1 == HUFF_VEC1_SIZE - 1)
> + v1 += ff_wma_get_large_val(&s->gb);
> + ((float*)vals)[i ] = v0;
> + ((float*)vals)[i+1] = v1;
> } else {
> - vals[i] = symbol_to_vec2[idx] >> 4;
> - vals[i+1] = symbol_to_vec2[idx] & 0xF;
> + vals[i] = fval_tab[symbol_to_vec2[idx] >> 4 ];
> + vals[i+1] = fval_tab[symbol_to_vec2[idx] & 0xF];
> }
> }
> } else {
> - vals[0] = symbol_to_vec4[idx] >> 12;
> - vals[1] = (symbol_to_vec4[idx] >> 8) & 0xF;
> - vals[2] = (symbol_to_vec4[idx] >> 4) & 0xF;
> - vals[3] = symbol_to_vec4[idx] & 0xF;
> + vals[0] = fval_tab[ symbol_to_vec4[idx] >> 12 ];
> + vals[1] = fval_tab[(symbol_to_vec4[idx] >> 8) & 0xF];
> + vals[2] = fval_tab[(symbol_to_vec4[idx] >> 4) & 0xF];
> + vals[3] = fval_tab[ symbol_to_vec4[idx] & 0xF];
> }
>
> /** decode sign */
> for (i = 0; i < 4; i++) {
> if (vals[i]) {
> int sign = get_bits1(&s->gb) - 1;
> - ci->coeffs[cur_coeff] = (vals[i] ^ sign) - sign;
> + *(uint32_t*)&ci->coeffs[cur_coeff] = vals[i] ^ sign<<31;
> num_zeros = 0;
> } else {
> ci->coeffs[cur_coeff] = 0;
This patch looks a bit ugly but as it seems to be significantly faster I'm not
against it, if such code is acceptable for ffmpeg in general.
I only wonder if the table and sign conversion code should maybe be moved to
another place in ffmpeg so that it can be reused in other codecs?
If the code is going to stay as is, please add a comment that describes the
content of fval_tab and why this is needed.
Regards
Sascha
More information about the ffmpeg-devel
mailing list