From: Laurent Aimar Date: Mon, 29 Sep 2008 21:44:46 +0000 (+0200) Subject: Added aout pause support. X-Git-Tag: 1.0.0-pre1~2781 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=da93449d1e5abd10fc0663029c165bed2e7371c1;p=vlc 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). --- diff --git a/include/vlc_aout.h b/include/vlc_aout.h index 96a9c5fde5..ff1ba9cf14 100644 --- a/include/vlc_aout.h +++ b/include/vlc_aout.h @@ -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 */ diff --git a/modules/audio_mixer/float32.c b/modules/audio_mixer/float32.c index 943bc5dcfb..0792a50581 100644 --- a/modules/audio_mixer/float32.c +++ b/modules/audio_mixer/float32.c @@ -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 ( ; ; ) { diff --git a/modules/audio_mixer/spdif.c b/modules/audio_mixer/spdif.c index aa65ff021c..bd183f3d0b 100644 --- a/modules/audio_mixer/spdif.c +++ b/modules/audio_mixer/spdif.c @@ -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 ) diff --git a/modules/audio_mixer/trivial.c b/modules/audio_mixer/trivial.c index 5a7c260a76..5c93d9b8e2 100644 --- a/modules/audio_mixer/trivial.c +++ b/modules/audio_mixer/trivial.c @@ -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 ) diff --git a/src/audio_output/aout_internal.h b/src/audio_output/aout_internal.h index 4c87fb0db7..c887ab38c7 100644 --- a/src/audio_output/aout_internal.h +++ b/src/audio_output/aout_internal.h @@ -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 */ diff --git a/src/audio_output/dec.c b/src/audio_output/dec.c index 64f0e8018a..9d52bdcf01 100644 --- a/src/audio_output/dec.c +++ b/src/audio_output/dec.c @@ -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 ); + } +} + diff --git a/src/audio_output/input.c b/src/audio_output/input.c index 2eef4c7ae1..25516b6f07 100644 --- a/src/audio_output/input.c +++ b/src/audio_output/input.c @@ -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 ); diff --git a/src/audio_output/mixer.c b/src/audio_output/mixer.c index 011202c64a..f2c149bb3b 100644 --- a/src/audio_output/mixer.c +++ b/src/audio_output/mixer.c @@ -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; diff --git a/src/input/decoder.c b/src/input/decoder.c index 2bb25fc157..5ccdfe694a 100644 --- a/src/input/decoder.c +++ b/src/input/decoder.c @@ -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 );