Commit e6d8827a authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

araw: refactor decoder to support byte-unaligned formats

parent c96ea579
...@@ -71,9 +71,7 @@ static block_t *EncoderEncode( encoder_t *, aout_buffer_t * ); ...@@ -71,9 +71,7 @@ static block_t *EncoderEncode( encoder_t *, aout_buffer_t * );
struct decoder_sys_t struct decoder_sys_t
{ {
const int16_t *p_logtos16; /* used with m/alaw to int16_t */ void (*decode) (void *, const uint8_t *, unsigned);
int i_bytespersample;
date_t end_date; date_t end_date;
}; };
...@@ -169,6 +167,9 @@ static const int16_t alawtos16[256] = ...@@ -169,6 +167,9 @@ static const int16_t alawtos16[256] =
944, 912, 1008, 976, 816, 784, 880, 848 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 * DecoderOpen: probe the decoder and return score
*****************************************************************************/ *****************************************************************************/
...@@ -228,7 +229,7 @@ static int DecoderOpen( vlc_object_t *p_this ) ...@@ -228,7 +229,7 @@ static int DecoderOpen( vlc_object_t *p_this )
(decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL ) (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
return VLC_ENOMEM; return VLC_ENOMEM;
p_sys->p_logtos16 = NULL; p_sys->decode = NULL;
msg_Dbg( p_dec, "samplerate:%dHz channels:%d bits/sample:%d", 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, 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 ) ...@@ -273,13 +274,15 @@ static int DecoderOpen( vlc_object_t *p_this )
else if( p_dec->fmt_in.i_codec == VLC_CODEC_ALAW ) else if( p_dec->fmt_in.i_codec == VLC_CODEC_ALAW )
{ {
p_dec->fmt_out.i_codec = VLC_CODEC_S16N; 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; p_dec->fmt_in.audio.i_bitspersample = 8;
} }
else if( p_dec->fmt_in.i_codec == VLC_CODEC_MULAW ) else if( p_dec->fmt_in.i_codec == VLC_CODEC_MULAW )
{ {
p_dec->fmt_out.i_codec = VLC_CODEC_S16N; 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; p_dec->fmt_in.audio.i_bitspersample = 8;
} }
else else
...@@ -309,15 +312,8 @@ static int DecoderOpen( vlc_object_t *p_this ) ...@@ -309,15 +312,8 @@ static int DecoderOpen( vlc_object_t *p_this )
p_dec->fmt_out.audio.i_original_channels = p_dec->fmt_out.audio.i_original_channels =
p_dec->fmt_in.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_Init( &p_sys->end_date, p_dec->fmt_out.audio.i_rate, 1 );
date_Set( &p_sys->end_date, 0 ); 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; p_dec->pf_decode_audio = DecodeBlock;
...@@ -332,13 +328,10 @@ static int DecoderOpen( vlc_object_t *p_this ) ...@@ -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 ) static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
{ {
decoder_sys_t *p_sys = p_dec->p_sys; 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; 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 && if( p_block->i_pts > VLC_TS_INVALID &&
p_block->i_pts != date_Get( &p_sys->end_date ) ) 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 ) ...@@ -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 */ /* Don't re-use the same pts twice */
p_block->i_pts = VLC_TS_INVALID; p_block->i_pts = VLC_TS_INVALID;
i_samples = p_block->i_buffer / p_sys->i_bytespersample / const unsigned framebits =
p_dec->fmt_in.audio.i_channels; p_dec->fmt_in.audio.i_bitspersample * p_dec->fmt_in.audio.i_channels;
unsigned samples = (8 * p_block->i_buffer) / framebits;
if( i_samples <= 0 ) if( samples == 0 )
{ {
block_Release( p_block ); block_Release( p_block );
return NULL; return NULL;
} }
/* Create chunks of max 1024 samples */ /* 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 ) if( p_out == NULL )
{ {
block_Release( p_block ); block_Release( p_block );
...@@ -375,30 +368,38 @@ static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_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_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; - p_out->i_pts;
if( p_sys->p_logtos16 ) if( p_sys->decode != NULL )
{ p_sys->decode( p_out->p_buffer, p_block->p_buffer,
int16_t *s = (int16_t*)p_out->p_buffer; samples * p_dec->fmt_in.audio.i_channels );
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--;
}
}
else else
{
memcpy( p_out->p_buffer, p_block->p_buffer, p_out->i_buffer ); 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; 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 * DecoderClose: decoder destruction
*****************************************************************************/ *****************************************************************************/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment