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