Commit da93449d authored by Laurent Aimar's avatar Laurent Aimar

Added aout pause support.

This does not work well. It seems that a high level of audio is buffered
inside aout after the input fifo (mixer or output one).
parent b1c90ec5
......@@ -284,10 +284,14 @@ struct aout_input_t
bool b_changed;
/* last rate from input */
int i_last_input_rate;
int i_last_input_rate;
/* */
int i_buffer_lost;
int i_buffer_lost;
/* */
bool b_paused;
mtime_t i_pause_date;
};
/** an output stream for the audio output */
......
......@@ -133,7 +133,8 @@ static void DoWork( aout_instance_t * p_aout, aout_buffer_t * p_buffer )
float * p_out = (float *)p_buffer->p_buffer;
float * p_in = (float *)p_input->p_first_byte_to_mix;
if ( p_input->b_error ) continue;
if ( p_input->b_error || p_input->b_paused )
continue;
for ( ; ; )
{
......
......@@ -78,7 +78,7 @@ static void DoWork( aout_instance_t * p_aout, aout_buffer_t * p_buffer )
{
int i = 0;
aout_input_t * p_input = p_aout->pp_inputs[i];
while ( p_input->b_error )
while ( p_input->b_error || p_input->b_paused )
{
p_input = p_aout->pp_inputs[++i];
}
......@@ -91,7 +91,8 @@ static void DoWork( aout_instance_t * p_aout, aout_buffer_t * p_buffer )
aout_buffer_t * p_deleted;
p_input = p_aout->pp_inputs[i];
if ( p_input->b_error ) continue;
if ( p_input->b_error || p_input->b_paused )
continue;
p_fifo = &p_input->fifo;
p_deleted = p_fifo->p_first;
while ( p_deleted != NULL )
......
......@@ -83,7 +83,7 @@ static void DoWork( aout_instance_t * p_aout, aout_buffer_t * p_buffer )
uint8_t * p_in;
uint8_t * p_out;
while ( p_input->b_error )
while ( p_input->b_error || p_input->b_paused )
{
p_input = p_aout->pp_inputs[++i];
/* This can't crash because if no input has b_error == 0, the
......@@ -133,7 +133,8 @@ static void DoWork( aout_instance_t * p_aout, aout_buffer_t * p_buffer )
aout_buffer_t * p_deleted;
p_input = p_aout->pp_inputs[i];
if ( p_input->b_error ) continue;
if ( p_input->b_error || p_input->b_paused )
continue;
p_fifo = &p_input->fifo;
p_deleted = p_fifo->p_first;
while ( p_deleted != NULL )
......
......@@ -140,6 +140,7 @@ aout_buffer_t * aout_DecNewBuffer( aout_input_t *, size_t );
void aout_DecDeleteBuffer( aout_instance_t *, aout_input_t *, aout_buffer_t * );
int aout_DecPlay( aout_instance_t *, aout_input_t *, aout_buffer_t *, int i_input_rate );
int aout_DecGetResetLost( aout_instance_t *, aout_input_t * );
void aout_DecChangePause( aout_instance_t *, aout_input_t *, bool b_paused, mtime_t i_date );
/* Helpers */
......
......@@ -85,14 +85,16 @@ static aout_input_t * DecNew( vlc_object_t * p_this, aout_instance_t * p_aout,
}
p_input = malloc(sizeof(aout_input_t));
if ( p_input == NULL )
if( p_input == NULL )
goto error;
memset( p_input, 0, sizeof(aout_input_t) );
vlc_mutex_init( &p_input->lock );
p_input->b_changed = 0;
p_input->b_error = 1;
p_input->b_changed = false;
p_input->b_error = true;
p_input->b_paused = false;
p_input->i_pause_date = 0;
aout_FormatPrepare( p_format );
......@@ -267,7 +269,7 @@ aout_buffer_t * aout_DecNewBuffer( aout_input_t * p_input,
/ p_input->input.i_frame_length;
/* Suppose the decoder doesn't have more than one buffered buffer */
p_input->b_changed = 0;
p_input->b_changed = false;
aout_unlock_input( NULL, p_input );
......@@ -329,7 +331,7 @@ int aout_DecPlay( aout_instance_t * p_aout, aout_input_t * p_input,
p_new_buffer->end_date = p_buffer->end_date;
aout_BufferFree( p_buffer );
p_buffer = p_new_buffer;
p_input->b_changed = 0;
p_input->b_changed = false;
}
int i_ret = aout_InputPlay( p_aout, p_input, p_buffer, i_input_rate );
......@@ -359,3 +361,28 @@ int aout_DecGetResetLost( aout_instance_t *p_aout, aout_input_t *p_input )
return i_value;
}
void aout_DecChangePause( aout_instance_t *p_aout, aout_input_t *p_input, bool b_paused, mtime_t i_date )
{
mtime_t i_duration = 0;
aout_lock_input( p_aout, p_input );
assert( !p_input->b_paused || !b_paused );
if( p_input->b_paused )
{
i_duration = i_date - p_input->i_pause_date;
}
p_input->b_paused = b_paused;
p_input->i_pause_date = i_date;
aout_unlock_input( p_aout, p_input );
if( i_duration != 0 )
{
aout_lock_mixer( p_aout );
for( aout_buffer_t *p = p_input->fifo.p_first; p != NULL; p = p->p_next )
{
p->start_date += i_duration;
p->end_date += i_duration;
}
aout_unlock_mixer( p_aout );
}
}
......@@ -487,21 +487,30 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
if( p_input->b_restart )
{
aout_fifo_t fifo, dummy_fifo;
aout_fifo_t fifo;
uint8_t *p_first_byte_to_mix;
bool b_paused;
mtime_t i_pause_date;
aout_lock_mixer( p_aout );
aout_lock_input_fifos( p_aout );
/* A little trick to avoid loosing our input fifo */
aout_FifoInit( p_aout, &dummy_fifo, p_aout->mixer.mixer.i_rate );
/* A little trick to avoid loosing our input fifo and properties */
p_first_byte_to_mix = p_input->p_first_byte_to_mix;
fifo = p_input->fifo;
p_input->fifo = dummy_fifo;
b_paused = p_input->b_paused;
i_pause_date = p_input->i_pause_date;
aout_FifoInit( p_aout, &p_input->fifo, p_aout->mixer.mixer.i_rate );
aout_InputDelete( p_aout, p_input );
aout_InputNew( p_aout, p_input );
p_input->p_first_byte_to_mix = p_first_byte_to_mix;
p_input->fifo = fifo;
p_input->b_paused = b_paused;
p_input->i_pause_date = i_pause_date;
aout_unlock_input_fifos( p_aout );
aout_unlock_mixer( p_aout );
......
......@@ -131,7 +131,8 @@ static int MixBuffer( aout_instance_t * p_aout )
aout_fifo_t * p_fifo = &p_input->fifo;
aout_buffer_t * p_buffer;
if ( p_input->b_error ) continue;
if ( p_input->b_error || p_input->b_paused )
continue;
p_buffer = p_fifo->p_first;
while ( p_buffer != NULL && p_buffer->start_date < mdate() )
......@@ -176,7 +177,7 @@ static int MixBuffer( aout_instance_t * p_aout )
mtime_t prev_date;
bool b_drop_buffers;
if ( p_input->b_error )
if ( p_input->b_error || p_input->b_paused )
{
if ( i_first_input == i ) i_first_input++;
continue;
......
......@@ -694,15 +694,17 @@ static void DecoderOutputChangePause( decoder_t *p_dec, bool b_paused, mtime_t i
{
decoder_owner_sys_t *p_owner = p_dec->p_owner;
vlc_assert_locked( &p_owner->lock );
/* XXX only audio and video output have to be paused.
* - for sout it is useless
* - for subs, it is done by the vout
*/
if( p_dec->fmt_in.i_cat == AUDIO_ES )
{
// TODO
//if( p_own->p_vout )
// aout_ChangePause( p_own->p_aout, p_own->p_aout_input, b_paused, i_date );
if( p_owner->p_aout && p_owner->p_aout_input )
aout_DecChangePause( p_owner->p_aout, p_owner->p_aout_input,
b_paused, i_date );
}
else if( p_dec->fmt_in.i_cat == VIDEO_ES )
{
......@@ -1377,7 +1379,8 @@ static int DecoderDecode( decoder_t *p_dec, block_t *p_block )
if( p_vout && p_owner->p_spu_vout == p_vout )
{
/* Preroll does not work very well with subtitle */
if( p_spu->i_start < p_owner->i_preroll_end &&
if( p_spu->i_start > 0 &&
p_spu->i_start < p_owner->i_preroll_end &&
( p_spu->i_stop <= 0 || p_spu->i_stop < p_owner->i_preroll_end ) )
{
subpicture_Delete( p_spu );
......
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