Commit 4faf2cab authored by Gildas Bazin's avatar Gildas Bazin

* modules/gui/wxwindows/interface.cpp: resume after pause was broken recently.
* src/audio_output/output.c: reverted a recent change that was screwing up the proper scheduling of audio samples after a starvation. That should improve the heavy resampling we currently have after a pause.
* modules/audio_output/alsa.c: improvements and fixes to the alsa audio output.
parent 558b51e0
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* alsa.c : alsa plugin for vlc * alsa.c : alsa plugin for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2000-2001 VideoLAN * Copyright (C) 2000-2001 VideoLAN
* $Id: alsa.c,v 1.28 2003/05/26 19:06:47 gbazin Exp $ * $Id: alsa.c,v 1.29 2003/07/09 21:42:28 gbazin Exp $
* *
* Authors: Henri Fallon <henri@videolan.org> - Original Author * Authors: Henri Fallon <henri@videolan.org> - Original Author
* Jeffrey Baker <jwbaker@acm.org> - Port to ALSA 1.0 API * Jeffrey Baker <jwbaker@acm.org> - Port to ALSA 1.0 API
...@@ -57,6 +57,12 @@ struct aout_sys_t ...@@ -57,6 +57,12 @@ struct aout_sys_t
#ifdef DEBUG #ifdef DEBUG
snd_output_t * p_snd_stderr; snd_output_t * p_snd_stderr;
#endif #endif
int b_playing; /* playing status */
mtime_t start_date;
vlc_mutex_t lock;
vlc_cond_t wait ;
}; };
#define A52_FRAME_NB 1536 #define A52_FRAME_NB 1536
...@@ -65,7 +71,7 @@ struct aout_sys_t ...@@ -65,7 +71,7 @@ struct aout_sys_t
To convert them to a number of bytes you have to multiply them by the To convert them to a number of bytes you have to multiply them by the
number of channel(s) (eg. 2 for stereo) and the size of a sample (eg. number of channel(s) (eg. 2 for stereo) and the size of a sample (eg.
2 for s16). */ 2 for s16). */
#define ALSA_DEFAULT_PERIOD_SIZE 2048 #define ALSA_DEFAULT_PERIOD_SIZE 1024
#define ALSA_DEFAULT_BUFFER_SIZE ( ALSA_DEFAULT_PERIOD_SIZE << 4 ) #define ALSA_DEFAULT_BUFFER_SIZE ( ALSA_DEFAULT_PERIOD_SIZE << 4 )
#define ALSA_SPDIF_PERIOD_SIZE A52_FRAME_NB #define ALSA_SPDIF_PERIOD_SIZE A52_FRAME_NB
#define ALSA_SPDIF_BUFFER_SIZE ( ALSA_SPDIF_PERIOD_SIZE << 4 ) #define ALSA_SPDIF_BUFFER_SIZE ( ALSA_SPDIF_PERIOD_SIZE << 4 )
...@@ -262,6 +268,10 @@ static int Open( vlc_object_t *p_this ) ...@@ -262,6 +268,10 @@ static int Open( vlc_object_t *p_this )
msg_Err( p_aout, "out of memory" ); msg_Err( p_aout, "out of memory" );
return VLC_ENOMEM; return VLC_ENOMEM;
} }
p_sys->b_playing = VLC_FALSE;
p_sys->start_date = 0;
vlc_cond_init( p_aout, &p_sys->wait );
vlc_mutex_init( p_aout, &p_sys->lock );
/* Get device name */ /* Get device name */
if( (psz_device = config_GetPsz( p_aout, "alsadev" )) == NULL ) if( (psz_device = config_GetPsz( p_aout, "alsadev" )) == NULL )
...@@ -561,6 +571,19 @@ error: ...@@ -561,6 +571,19 @@ error:
*****************************************************************************/ *****************************************************************************/
static void Play( aout_instance_t *p_aout ) static void Play( aout_instance_t *p_aout )
{ {
if( !p_aout->output.p_sys->b_playing )
{
p_aout->output.p_sys->b_playing = 1;
/* get the playing date of the first aout buffer */
p_aout->output.p_sys->start_date =
aout_FifoFirstDate( p_aout, &p_aout->output.fifo );
/* wake up the audio output thread */
vlc_mutex_lock( &p_aout->output.p_sys->lock );
vlc_cond_signal( &p_aout->output.p_sys->wait );
vlc_mutex_unlock( &p_aout->output.p_sys->lock );
}
} }
/***************************************************************************** /*****************************************************************************
...@@ -572,6 +595,11 @@ static void Close( vlc_object_t *p_this ) ...@@ -572,6 +595,11 @@ static void Close( vlc_object_t *p_this )
struct aout_sys_t * p_sys = p_aout->output.p_sys; struct aout_sys_t * p_sys = p_aout->output.p_sys;
int i_snd_rc; int i_snd_rc;
/* make sure the audio output thread is waken up */
vlc_mutex_lock( &p_aout->output.p_sys->lock );
vlc_cond_signal( &p_aout->output.p_sys->wait );
vlc_mutex_unlock( &p_aout->output.p_sys->lock );
p_aout->b_die = VLC_TRUE; p_aout->b_die = VLC_TRUE;
vlc_thread_join( p_aout ); vlc_thread_join( p_aout );
p_aout->b_die = VLC_FALSE; p_aout->b_die = VLC_FALSE;
...@@ -596,20 +624,18 @@ static void Close( vlc_object_t *p_this ) ...@@ -596,20 +624,18 @@ static void Close( vlc_object_t *p_this )
*****************************************************************************/ *****************************************************************************/
static int ALSAThread( aout_instance_t * p_aout ) static int ALSAThread( aout_instance_t * p_aout )
{ {
struct aout_sys_t * p_sys = p_aout->output.p_sys; /* Wait for the exact time to start playing (avoids resampling) */
vlc_mutex_lock( &p_aout->output.p_sys->lock );
if( !p_aout->output.p_sys->start_date )
vlc_cond_wait( &p_aout->output.p_sys->wait,
&p_aout->output.p_sys->lock );
vlc_mutex_unlock( &p_aout->output.p_sys->lock );
mwait( p_aout->output.p_sys->start_date - AOUT_PTS_TOLERANCE / 4 );
while ( !p_aout->b_die ) while ( !p_aout->b_die )
{ {
ALSAFill( p_aout ); ALSAFill( p_aout );
/* Sleep during less than one period to avoid a lot of buffer
underruns */
/* Why do we need to sleep ? --Meuuh */
/* Maybe because I don't want to eat all the cpu by looping
all the time. --Bozo */
/* Shouldn't snd_pcm_wait() make us wait ? --Meuuh */
msleep( p_sys->i_period_time >> 1 );
} }
return 0; return 0;
...@@ -630,18 +656,7 @@ static void ALSAFill( aout_instance_t * p_aout ) ...@@ -630,18 +656,7 @@ static void ALSAFill( aout_instance_t * p_aout )
snd_pcm_status_alloca( &p_status ); snd_pcm_status_alloca( &p_status );
/* Wait for the device's readiness (ie. there is enough space in the
buffer to write at least one complete chunk) */
i_snd_rc = snd_pcm_wait( p_sys->p_snd_pcm, THREAD_SLEEP );
if( i_snd_rc < 0 )
{
msg_Err( p_aout, "ALSA device not ready !!! (%s)",
snd_strerror( i_snd_rc ) );
return;
}
/* Fill in the buffer until space or audio output buffer shortage */ /* Fill in the buffer until space or audio output buffer shortage */
for ( ; ; )
{ {
/* Get the status */ /* Get the status */
i_snd_rc = snd_pcm_status( p_sys->p_snd_pcm, p_status ); i_snd_rc = snd_pcm_status( p_sys->p_snd_pcm, p_status );
...@@ -649,6 +664,8 @@ static void ALSAFill( aout_instance_t * p_aout ) ...@@ -649,6 +664,8 @@ static void ALSAFill( aout_instance_t * p_aout )
{ {
msg_Err( p_aout, "unable to get the device's status (%s)", msg_Err( p_aout, "unable to get the device's status (%s)",
snd_strerror( i_snd_rc ) ); snd_strerror( i_snd_rc ) );
msleep( p_sys->i_period_time >> 1 );
return; return;
} }
...@@ -666,15 +683,18 @@ static void ALSAFill( aout_instance_t * p_aout ) ...@@ -666,15 +683,18 @@ static void ALSAFill( aout_instance_t * p_aout )
i_snd_rc = snd_pcm_status( p_sys->p_snd_pcm, p_status ); i_snd_rc = snd_pcm_status( p_sys->p_snd_pcm, p_status );
if( i_snd_rc < 0 ) if( i_snd_rc < 0 )
{ {
msg_Err( p_aout, msg_Err( p_aout, "unable to get the device's status after "
"unable to get the device's status after recovery (%s)", "recovery (%s)", snd_strerror( i_snd_rc ) );
snd_strerror( i_snd_rc ) );
msleep( p_sys->i_period_time >> 1 );
return; return;
} }
} }
else else
{ {
msg_Err( p_aout, "unable to recover from buffer underrun" ); msg_Err( p_aout, "unable to recover from buffer underrun" );
msleep( p_sys->i_period_time >> 1 );
return; return;
} }
} }
...@@ -691,10 +711,12 @@ static void ALSAFill( aout_instance_t * p_aout ) ...@@ -691,10 +711,12 @@ static void ALSAFill( aout_instance_t * p_aout )
(p_aout->output.output.i_format == (p_aout->output.output.i_format ==
VLC_FOURCC('s','p','d','i')) ); VLC_FOURCC('s','p','d','i')) );
/* Audio output buffer shortage -> stop the fill process and /* Audio output buffer shortage -> stop the fill process and wait */
wait in ALSAThread */
if( p_buffer == NULL ) if( p_buffer == NULL )
{
msleep( p_sys->i_period_time >> 1 );
return; return;
}
i_snd_rc = snd_pcm_writei( p_sys->p_snd_pcm, p_buffer->p_buffer, i_snd_rc = snd_pcm_writei( p_sys->p_snd_pcm, p_buffer->p_buffer,
p_buffer->i_nb_samples ); p_buffer->i_nb_samples );
...@@ -706,8 +728,5 @@ static void ALSAFill( aout_instance_t * p_aout ) ...@@ -706,8 +728,5 @@ static void ALSAFill( aout_instance_t * p_aout )
} }
aout_BufferFree( p_buffer ); aout_BufferFree( p_buffer );
msleep( p_sys->i_period_time >> 2 );
} }
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* interface.cpp : wxWindows plugin for vlc * interface.cpp : wxWindows plugin for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2000-2001 VideoLAN * Copyright (C) 2000-2001 VideoLAN
* $Id: interface.cpp,v 1.43 2003/07/01 13:12:19 sam Exp $ * $Id: interface.cpp,v 1.44 2003/07/09 21:42:28 gbazin Exp $
* *
* Authors: Gildas Bazin <gbazin@netcourrier.com> * Authors: Gildas Bazin <gbazin@netcourrier.com>
* *
...@@ -706,7 +706,7 @@ void Interface::OnPlayStream( wxCommandEvent& WXUNUSED(event) ) ...@@ -706,7 +706,7 @@ void Interface::OnPlayStream( wxCommandEvent& WXUNUSED(event) )
} }
/* Stream is paused, resume it */ /* Stream is paused, resume it */
playlist_Play( p_playlist ); input_SetStatus( p_input, INPUT_STATUS_PLAY );
TogglePlayButton( PLAYING_S ); TogglePlayButton( PLAYING_S );
vlc_object_release( p_input ); vlc_object_release( p_input );
vlc_object_release( p_playlist ); vlc_object_release( p_playlist );
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* output.c : internal management of output streams for the audio output * output.c : internal management of output streams for the audio output
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * Copyright (C) 2002 VideoLAN
* $Id: output.c,v 1.40 2003/05/11 01:00:26 massiot Exp $ * $Id: output.c,v 1.41 2003/07/09 21:42:28 gbazin Exp $
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -304,8 +304,13 @@ aout_buffer_t * aout_OutputNextBuffer( aout_instance_t * p_aout, ...@@ -304,8 +304,13 @@ aout_buffer_t * aout_OutputNextBuffer( aout_instance_t * p_aout,
/* Here we suppose that all buffers have the same duration - this is /* Here we suppose that all buffers have the same duration - this is
* generally true, and anyway if it's wrong it won't be a disaster. */ * generally true, and anyway if it's wrong it won't be a disaster. */
if ( p_buffer->start_date > start_date if ( p_buffer->start_date > start_date
+ (p_buffer->end_date - p_buffer->start_date) + (p_buffer->end_date - p_buffer->start_date) )
+ AOUT_PTS_TOLERANCE ) /*
* + AOUT_PTS_TOLERANCE )
* There is no reason to want that, it just worsen the scheduling of
* an audio sample after an output starvation (ie. on start or on resume)
* --Gibalou
*/
{ {
vlc_mutex_unlock( &p_aout->output_fifo_lock ); vlc_mutex_unlock( &p_aout->output_fifo_lock );
if ( !p_aout->output.b_starving ) if ( !p_aout->output.b_starving )
......
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