X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Faudio_output%2Falsa.c;h=dbcb02bc1a6b01d71961a844e3222e84d9811216;hb=8f3d5d03e6c625f3527e8e8dd9e5391180e2a398;hp=a90e2fde0a85a0bba929bc67819793e1e41538fd;hpb=9af57553c9e93a62d2f9b68f78d0420053fbffa2;p=vlc diff --git a/modules/audio_output/alsa.c b/modules/audio_output/alsa.c index a90e2fde0a..dbcb02bc1a 100644 --- a/modules/audio_output/alsa.c +++ b/modules/audio_output/alsa.c @@ -40,6 +40,8 @@ #define ALSA_PCM_NEW_SW_PARAMS_API #include +/*#define ALSA_DEBUG*/ + /***************************************************************************** * aout_sys_t: ALSA audio output method descriptor ***************************************************************************** @@ -583,34 +585,34 @@ static int Open( vlc_object_t *p_this ) p_aout->output.output.i_rate ); } - /* Set buffer size. */ + /* Set period size. */ #ifdef HAVE_ALSA_NEW_API - if ( ( i_snd_rc = snd_pcm_hw_params_set_buffer_size_near( p_sys->p_snd_pcm, - p_hw, &i_buffer_size ) ) < 0 ) + if ( ( i_snd_rc = snd_pcm_hw_params_set_period_size_near( p_sys->p_snd_pcm, + p_hw, &i_period_size, NULL ) ) < 0 ) #else - if ( ( i_snd_rc = snd_pcm_hw_params_set_buffer_size_near( p_sys->p_snd_pcm, - p_hw, i_buffer_size ) ) < 0 ) + if ( ( i_snd_rc = snd_pcm_hw_params_set_period_size_near( p_sys->p_snd_pcm, + p_hw, i_period_size, NULL ) ) < 0 ) #endif { - msg_Err( p_aout, "unable to set buffer size (%s)", + msg_Err( p_aout, "unable to set period size (%s)", snd_strerror( i_snd_rc ) ); goto error; } + p_aout->output.i_nb_samples = i_period_size; - /* Set period size. */ +/* Set buffer size. */ #ifdef HAVE_ALSA_NEW_API - if ( ( i_snd_rc = snd_pcm_hw_params_set_period_size_near( p_sys->p_snd_pcm, - p_hw, &i_period_size, NULL ) ) < 0 ) + if ( ( i_snd_rc = snd_pcm_hw_params_set_buffer_size_near( p_sys->p_snd_pcm, + p_hw, &i_buffer_size ) ) < 0 ) #else - if ( ( i_snd_rc = snd_pcm_hw_params_set_period_size_near( p_sys->p_snd_pcm, - p_hw, i_period_size, NULL ) ) < 0 ) + if ( ( i_snd_rc = snd_pcm_hw_params_set_buffer_size_near( p_sys->p_snd_pcm, + p_hw, i_buffer_size ) ) < 0 ) #endif { - msg_Err( p_aout, "unable to set period size (%s)", + msg_Err( p_aout, "unable to set buffer size (%s)", snd_strerror( i_snd_rc ) ); goto error; } - p_aout->output.i_nb_samples = i_period_size; /* Commit hardware parameters. */ if ( ( i_snd_rc = snd_pcm_hw_params( p_sys->p_snd_pcm, p_hw ) ) < 0 ) @@ -760,10 +762,13 @@ static int ALSAThread( aout_instance_t * p_aout ) /* Wait for the exact time to start playing (avoids resampling) */ vlc_mutex_lock( &p_sys->lock ); - while( !p_sys->start_date ) + while( !p_sys->start_date && !p_aout->b_die ) vlc_cond_wait( &p_sys->wait, &p_sys->lock ); vlc_mutex_unlock( &p_sys->lock ); + if( p_aout->b_die ) + goto cleanup; + mwait( p_sys->start_date - AOUT_PTS_TOLERANCE / 4 ); while ( !p_aout->b_die ) @@ -771,6 +776,7 @@ static int ALSAThread( aout_instance_t * p_aout ) ALSAFill( p_aout ); } +cleanup: snd_pcm_drop( p_sys->p_snd_pcm ); free( p_aout->output.p_sys->p_status ); return 0; @@ -826,28 +832,26 @@ static void ALSAFill( aout_instance_t * p_aout ) { /* Here the device should be in RUNNING state. * p_status is valid. */ + snd_pcm_sframes_t delay = snd_pcm_status_get_delay( p_status ); + int i_bytes = snd_pcm_frames_to_bytes( p_sys->p_snd_pcm, delay ); + next_date = mdate() + ( (mtime_t)i_bytes * 1000000 + / p_aout->output.output.i_bytes_per_frame + / p_aout->output.output.i_rate + * p_aout->output.output.i_frame_length ); -#if 0 - /* This apparently does not work correctly in Alsa 1.0.11 */ - snd_pcm_status_get_tstamp( p_status, &ts_next ); - next_date = (mtime_t)ts_next.tv_sec * 1000000 + ts_next.tv_usec; - if( next_date ) - { - next_date += (mtime_t)snd_pcm_status_get_delay(p_status) - * 1000000 / p_aout->output.output.i_rate; - } - else +#ifdef ALSA_DEBUG + snd_pcm_state_t state = snd_pcm_status_get_state( p_status ); + if( state != SND_PCM_STATE_RUNNING ) + msg_Err( p_aout, "pcm status (%d) != RUNNING", state ); + + msg_Dbg( p_aout, "Delay is %ld frames (%d bytes)", delay, i_bytes ); + + msg_Dbg( p_aout, "Bytes per frame: %d", p_aout->output.output.i_bytes_per_frame ); + msg_Dbg( p_aout, "Rate: %d", p_aout->output.output.i_rate ); + msg_Dbg( p_aout, "Frame length: %d", p_aout->output.output.i_frame_length ); + + msg_Dbg( p_aout, "Next date is in %d microseconds", (int)(next_date - mdate()) ); #endif - { - /* With screwed ALSA drivers the timestamp is always zero; - * use another method then */ - snd_pcm_sframes_t delay = 0; - - snd_pcm_delay( p_sys->p_snd_pcm, &delay ); - next_date = mdate() + (mtime_t)(delay) * 1000000 - / p_aout->output.output.i_rate - * p_aout->output.output.i_frame_length; - } } p_buffer = aout_OutputNextBuffer( p_aout, next_date,