Commit efec6179 authored by Derk-Jan Hartman's avatar Derk-Jan Hartman

* Updated coreaudio resampler. will play small lpcm samples, but still crashes sometimes.

  problem is writing to freed memory???
  possibly related to dropped buffers?
parent 17ae484b
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* coreaudio.c resampler based on CoreAudio's AudioConverter * coreaudio.c resampler based on CoreAudio's AudioConverter
***************************************************************************** *****************************************************************************
* Copyright (C) 2003 VideoLAN * Copyright (C) 2003 VideoLAN
* $Id: coreaudio.c,v 1.5 2004/03/03 20:39:51 gbazin Exp $ * $Id$
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* Jon Lech Johansen <jon-vl@nanocrew.net> * Jon Lech Johansen <jon-vl@nanocrew.net>
...@@ -56,6 +56,13 @@ struct aout_filter_sys_t ...@@ -56,6 +56,13 @@ struct aout_filter_sys_t
AudioConverterRef s_converter; AudioConverterRef s_converter;
unsigned int i_remainder; unsigned int i_remainder;
unsigned int i_first_rate; unsigned int i_first_rate;
uint32_t p_bufferized[32768];
int i_bufferized;
int32_t p_output[32768];
int i_output;
audio_date_t end_date;
}; };
/***************************************************************************** /*****************************************************************************
...@@ -187,6 +194,8 @@ static int Create( vlc_object_t *p_this ) ...@@ -187,6 +194,8 @@ static int Create( vlc_object_t *p_this )
/* We don't want a new buffer to be created because we're not sure we'll /* We don't want a new buffer to be created because we're not sure we'll
* actually need to resample anything. */ * actually need to resample anything. */
p_filter->b_in_place = VLC_FALSE; p_filter->b_in_place = VLC_FALSE;
p_sys->i_bufferized = 0;
p_sys->i_output = 0;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -220,15 +229,14 @@ static void Close( vlc_object_t * p_this ) ...@@ -220,15 +229,14 @@ static void Close( vlc_object_t * p_this )
* DoWork: convert a buffer * DoWork: convert a buffer
*****************************************************************************/ *****************************************************************************/
static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter, static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter,
aout_buffer_t * p_in_buf, aout_buffer_t * p_out_buf ) aout_buffer_t * p_in_buf, aout_buffer_t * p_real_out_buf )
{ {
struct aout_filter_sys_t * p_sys = p_filter->p_sys; struct aout_filter_sys_t * p_sys = p_filter->p_sys;
int32_t *p_in = (int32_t *)p_in_buf->p_buffer; int32_t *p_in = p_sys->p_bufferized;
int32_t *p_out; int32_t *p_out;
UInt32 i_output_size; int i_input_samples;
unsigned int i_out_nb, i_wanted_nb, i_new_rate;
OSErr err; OSErr err;
aout_buffer_t * p_middle_buf; unsigned int i_out_nb;
unsigned int i_nb_channels = aout_FormatNbChannels( &p_filter->input ); unsigned int i_nb_channels = aout_FormatNbChannels( &p_filter->input );
...@@ -243,14 +251,33 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter, ...@@ -243,14 +251,33 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter,
} }
p_filter->b_continuity = VLC_TRUE; p_filter->b_continuity = VLC_TRUE;
p_sys->i_remainder = 0; p_sys->i_remainder = 0;
aout_DateInit( &p_filter->p_sys->end_date, p_filter->output.i_rate );
} }
#endif #endif
i_out_nb = (p_in_buf->i_nb_samples * p_filter->output.i_rate memcpy( p_sys->p_bufferized + p_sys->i_bufferized * i_nb_channels,
p_in_buf->p_buffer,
__MIN(p_in_buf->i_nb_samples * 4 * i_nb_channels,
sizeof(p_sys->p_bufferized)
- p_sys->i_bufferized * 4 * i_nb_channels) );
p_sys->i_bufferized += p_in_buf->i_nb_samples;
i_input_samples = p_sys->i_bufferized;
if ( i_input_samples >= 512 )
{
aout_buffer_t * p_middle_buf, * p_out_buf;
UInt32 i_output_size;
unsigned int i_wanted_nb, i_new_rate;
i_out_nb = (i_input_samples * p_filter->output.i_rate
+ p_sys->i_remainder) / p_sys->i_first_rate; + p_sys->i_remainder) / p_sys->i_first_rate;
p_sys->i_remainder = (p_in_buf->i_nb_samples * p_filter->output.i_rate p_sys->i_remainder = (i_input_samples * p_filter->output.i_rate
+ p_sys->i_remainder) % p_sys->i_first_rate; + p_sys->i_remainder) % p_sys->i_first_rate;
aout_BufferAlloc( &p_filter->output_alloc,
i_out_nb * 1000000 / p_filter->output.i_rate,
NULL, p_out_buf );
i_output_size = i_out_nb * 4 * i_nb_channels; i_output_size = i_out_nb * 4 * i_nb_channels;
if ( i_output_size > p_out_buf->i_size ) if ( i_output_size > p_out_buf->i_size )
{ {
...@@ -264,7 +291,7 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter, ...@@ -264,7 +291,7 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter,
} }
p_out = (int32_t*)p_middle_buf->p_buffer; p_out = (int32_t*)p_middle_buf->p_buffer;
err = AudioConverterConvertBuffer( p_sys->s_converter, err = AudioConverterConvertBuffer( p_sys->s_converter,
p_in_buf->i_nb_samples * 4 * i_nb_channels, p_in, i_input_samples * 4 * i_nb_channels, p_in,
&i_output_size, p_out ); &i_output_size, p_out );
if( err != noErr ) if( err != noErr )
{ {
...@@ -273,14 +300,18 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter, ...@@ -273,14 +300,18 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter,
i_output_size = i_out_nb * 4 * i_nb_channels; i_output_size = i_out_nb * 4 * i_nb_channels;
memset( p_out, 0, i_output_size ); memset( p_out, 0, i_output_size );
} }
memmove( p_sys->p_bufferized,
p_sys->p_bufferized + i_input_samples * 4 * i_nb_channels,
(p_sys->i_bufferized - i_input_samples) * 4 * i_nb_channels );
p_sys->i_bufferized -= i_input_samples;
p_middle_buf->i_nb_samples = i_output_size / 4 / i_nb_channels; p_middle_buf->i_nb_samples = i_output_size / 4 / i_nb_channels;
p_middle_buf->i_nb_bytes = i_output_size; p_middle_buf->i_nb_bytes = i_output_size;
p_middle_buf->start_date = p_in_buf->start_date; p_middle_buf->start_date = p_in_buf->start_date;
p_middle_buf->end_date = p_middle_buf->start_date + p_middle_buf->i_nb_samples * p_middle_buf->end_date = p_middle_buf->start_date
1000000 / p_filter->output.i_rate; + p_middle_buf->i_nb_samples * 1000000 / p_filter->output.i_rate;
i_wanted_nb = p_in_buf->i_nb_samples * p_filter->output.i_rate i_wanted_nb = i_input_samples * p_filter->output.i_rate
/ p_filter->input.i_rate; / p_filter->input.i_rate;
i_new_rate = p_middle_buf->i_nb_samples * p_filter->output.i_rate i_new_rate = p_middle_buf->i_nb_samples * p_filter->output.i_rate
/ i_wanted_nb; / i_wanted_nb;
...@@ -293,4 +324,36 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter, ...@@ -293,4 +324,36 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter,
{ {
aout_BufferFree( p_middle_buf ); aout_BufferFree( p_middle_buf );
} }
memcpy( p_sys->p_output + p_sys->i_output * i_nb_channels,
p_out_buf->p_buffer,
__MIN(p_out_buf->i_nb_samples * 4 * i_nb_channels,
sizeof(p_sys->p_output)
- p_sys->i_output * 4 * i_nb_channels) );
p_sys->i_output += p_out_buf->i_nb_samples;
aout_BufferFree( p_out_buf );
}
i_out_nb = (p_in_buf->i_nb_samples * p_filter->output.i_rate
+ p_sys->i_first_rate - 1) / p_sys->i_first_rate;
if ( i_out_nb > p_sys->i_output )
i_out_nb = p_sys->i_output;
p_real_out_buf->i_nb_samples = i_out_nb;
p_real_out_buf->i_nb_bytes = i_out_nb * 4 * i_nb_channels;
if( p_in_buf->start_date !=
aout_DateGet( &p_filter->p_sys->end_date ) )
{
aout_DateSet( &p_filter->p_sys->end_date, p_in_buf->start_date );
}
p_real_out_buf->end_date = aout_DateIncrement( &p_filter->p_sys->end_date,
i_out_nb );
memcpy( p_real_out_buf->p_buffer, p_sys->p_output,
i_out_nb * 4 * i_nb_channels );
memmove( p_sys->p_output, p_sys->p_output + i_out_nb * i_nb_channels,
(p_sys->i_output - i_out_nb) * 4 * i_nb_channels );
p_sys->i_output -= i_out_nb;
} }
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