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

araw: refactor decoder to support byte-unaligned formats

parent c96ea579
......@@ -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
*****************************************************************************/
......
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