vlc | branch: master | Rémi Denis-Courmont <[email protected]> | Wed Aug 17 19:35:18 2011 +0300| [e6d8827a31539016b472148dddd0b136f37d661e] | committer: Rémi Denis-Courmont
araw: refactor decoder to support byte-unaligned formats > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=e6d8827a31539016b472148dddd0b136f37d661e --- modules/codec/araw.c | 79 +++++++++++++++++++++++++------------------------ 1 files changed, 40 insertions(+), 39 deletions(-) diff --git a/modules/codec/araw.c b/modules/codec/araw.c index c441e82..73f05a3 100644 --- a/modules/codec/araw.c +++ b/modules/codec/araw.c @@ -71,9 +71,7 @@ static block_t *EncoderEncode( encoder_t *, aout_buffer_t * ); struct decoder_sys_t { - const int16_t *p_logtos16; /* used with m/alaw to int16_t */ - int i_bytespersample; - + void (*decode) (void *, const uint8_t *, unsigned); date_t end_date; }; @@ -169,6 +167,9 @@ static const int16_t alawtos16[256] = 944, 912, 1008, 976, 816, 784, 880, 848 }; +static void DecodeAlaw( void *, const uint8_t *, unsigned ); +static void DecodeUlaw( void *, const uint8_t *, unsigned ); + /***************************************************************************** * DecoderOpen: probe the decoder and return score *****************************************************************************/ @@ -228,7 +229,7 @@ static int DecoderOpen( vlc_object_t *p_this ) (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL ) return VLC_ENOMEM; - p_sys->p_logtos16 = NULL; + p_sys->decode = NULL; msg_Dbg( p_dec, "samplerate:%dHz channels:%d bits/sample:%d", p_dec->fmt_in.audio.i_rate, p_dec->fmt_in.audio.i_channels, @@ -273,13 +274,15 @@ static int DecoderOpen( vlc_object_t *p_this ) else if( p_dec->fmt_in.i_codec == VLC_CODEC_ALAW ) { p_dec->fmt_out.i_codec = VLC_CODEC_S16N; - p_sys->p_logtos16 = alawtos16; + p_dec->fmt_out.audio.i_bitspersample = 16; + p_sys->decode = DecodeAlaw; p_dec->fmt_in.audio.i_bitspersample = 8; } else if( p_dec->fmt_in.i_codec == VLC_CODEC_MULAW ) { p_dec->fmt_out.i_codec = VLC_CODEC_S16N; - p_sys->p_logtos16 = ulawtos16; + p_dec->fmt_out.audio.i_bitspersample = 16; + p_sys->decode = DecodeUlaw; p_dec->fmt_in.audio.i_bitspersample = 8; } else @@ -309,15 +312,8 @@ static int DecoderOpen( vlc_object_t *p_this ) p_dec->fmt_out.audio.i_original_channels = p_dec->fmt_in.audio.i_original_channels; - if( p_dec->fmt_in.i_codec == VLC_CODEC_ALAW || - p_dec->fmt_in.i_codec == VLC_CODEC_MULAW ) - { - p_dec->fmt_out.audio.i_bitspersample = 16; - } - date_Init( &p_sys->end_date, p_dec->fmt_out.audio.i_rate, 1 ); date_Set( &p_sys->end_date, 0 ); - p_sys->i_bytespersample = ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8; p_dec->pf_decode_audio = DecodeBlock; @@ -332,13 +328,10 @@ static int DecoderOpen( vlc_object_t *p_this ) static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) { decoder_sys_t *p_sys = p_dec->p_sys; - block_t *p_block; - aout_buffer_t *p_out; - int i_samples; if( !pp_block || !*pp_block ) return NULL; - p_block = *pp_block; + block_t *p_block = *pp_block; if( p_block->i_pts > VLC_TS_INVALID && p_block->i_pts != date_Get( &p_sys->end_date ) ) @@ -355,19 +348,19 @@ static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) /* Don't re-use the same pts twice */ p_block->i_pts = VLC_TS_INVALID; - i_samples = p_block->i_buffer / p_sys->i_bytespersample / - p_dec->fmt_in.audio.i_channels; - - if( i_samples <= 0 ) + const unsigned framebits = + p_dec->fmt_in.audio.i_bitspersample * p_dec->fmt_in.audio.i_channels; + unsigned samples = (8 * p_block->i_buffer) / framebits; + if( samples == 0 ) { block_Release( p_block ); return NULL; } /* Create chunks of max 1024 samples */ - i_samples = __MIN( i_samples, 1024 ); + if( samples > 1024 ) samples = 1024; - p_out = decoder_NewAudioBuffer( p_dec, i_samples ); + block_t *p_out = decoder_NewAudioBuffer( p_dec, samples ); if( p_out == NULL ) { block_Release( p_block ); @@ -375,30 +368,38 @@ static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) } p_out->i_pts = date_Get( &p_sys->end_date ); - p_out->i_length = date_Increment( &p_sys->end_date, i_samples ) + p_out->i_length = date_Increment( &p_sys->end_date, samples ) - p_out->i_pts; - if( p_sys->p_logtos16 ) - { - int16_t *s = (int16_t*)p_out->p_buffer; - unsigned int i; - - for( i = 0; i < p_out->i_buffer / 2; i++ ) - { - *s++ = p_sys->p_logtos16[*p_block->p_buffer++]; - p_block->i_buffer--; - } - } + if( p_sys->decode != NULL ) + p_sys->decode( p_out->p_buffer, p_block->p_buffer, + samples * p_dec->fmt_in.audio.i_channels ); else - { memcpy( p_out->p_buffer, p_block->p_buffer, p_out->i_buffer ); - p_block->p_buffer += p_out->i_buffer; - p_block->i_buffer -= p_out->i_buffer; - } + + samples = (samples * framebits) / 8; + p_block->p_buffer += samples; + p_block->i_buffer -= samples; return p_out; } +static void DecodeAlaw( void *outp, const uint8_t *in, unsigned samples ) +{ + int16_t *out = outp; + + for( unsigned i = 0; i < samples; i++ ) + *(out++) = alawtos16[*(in++)]; +} + +static void DecodeUlaw( void *outp, const uint8_t *in, unsigned samples ) +{ + int16_t *out = outp; + + for( unsigned i = 0; i < samples; i++ ) + *(out++) = ulawtos16[*(in++)]; +} + /***************************************************************************** * DecoderClose: decoder destruction *****************************************************************************/ _______________________________________________ vlc-commits mailing list [email protected] http://mailman.videolan.org/listinfo/vlc-commits
