Commit 4fca6a51 authored by Jean-Paul Saman's avatar Jean-Paul Saman

access/alsa.c: snd_pcm_readi() before snd_pcm_wait()

The alsa provided 'arecord' application tries to read first before doing
a snd_pcm_wait() (aka poll). Doing it the other way results in loss of
capture buffers when the system is under load. This is either a bug in
alsa implementation of snd_pcm_wait() or something else. The disadvantage
is that there seems to be a lot more overruns now.
parent 248308d7
...@@ -464,51 +464,13 @@ static void *AudioThread( vlc_object_t *p_this ) ...@@ -464,51 +464,13 @@ static void *AudioThread( vlc_object_t *p_this )
do do
{ {
/* Wait for data */ p_block = GrabAudio( p_demux );
int i_wait = snd_pcm_wait( p_sys->p_alsa_pcm, 10 ); /* See poll() comment in oss.c */ if( p_block )
#if 0
msg_Info( p_demux, "ALSA snd_pcm_wait returned (%d): %s %"PRId64,
i_wait, snd_strerror(i_wait), mdate() );
#endif
switch( i_wait )
{ {
case 1: block_FifoPut( p_sys->p_grab->p_fifo, p_block );
{ p_block = NULL;
p_block = GrabAudio( p_demux );
if( p_block )
{
block_FifoPut( p_sys->p_grab->p_fifo, p_block );
p_block = NULL;
}
}
/* FIXME: this is a copy paste from below. Shouldn't be needed
* twice. */
case -EPIPE:
{
/* xrun */
snd_pcm_prepare( p_sys->p_alsa_pcm );
break;
}
case -ESTRPIPE:
{
/* suspend */
int i_resume = snd_pcm_resume( p_sys->p_alsa_pcm );
if( i_resume < 0 && i_resume != -EAGAIN ) snd_pcm_prepare( p_sys->p_alsa_pcm );
break;
}
/* </FIXME> */
default:
{
if (i_wait == 0)
{
snd_pcm_prepare( p_sys->p_alsa_pcm );
}
else
msg_Err(p_demux, "returned: %d (%s)", i_wait, snd_strerror(i_wait));
break;
}
} }
} while( vlc_object_alive( p_grab ) ); } while( vlc_object_alive( p_grab ) );
if( p_block ) if( p_block )
...@@ -533,7 +495,7 @@ static block_t* GrabAudio( demux_t *p_demux ) ...@@ -533,7 +495,7 @@ static block_t* GrabAudio( demux_t *p_demux )
if( !p_block ) if( !p_block )
{ {
msg_Warn( p_demux, "cannot get block" ); msg_Warn( p_demux, "cannot get block" );
return 0; return NULL;
} }
p_sys->p_block = p_block; p_sys->p_block = p_block;
...@@ -542,11 +504,14 @@ static block_t* GrabAudio( demux_t *p_demux ) ...@@ -542,11 +504,14 @@ static block_t* GrabAudio( demux_t *p_demux )
i_read = snd_pcm_readi( p_sys->p_alsa_pcm, p_block->p_buffer, p_sys->i_alsa_chunk_size ); i_read = snd_pcm_readi( p_sys->p_alsa_pcm, p_block->p_buffer, p_sys->i_alsa_chunk_size );
if( i_read <= 0 ) if( i_read <= 0 )
{ {
int i_resume;
switch( i_read ) switch( i_read )
{ {
case -EINTR:
case -EAGAIN: case -EAGAIN:
{
snd_pcm_wait( p_sys->p_alsa_pcm, 10 ); /* See poll() comment in oss.c */
break; break;
}
case -EPIPE: case -EPIPE:
{ {
/* xrun */ /* xrun */
...@@ -557,13 +522,15 @@ static block_t* GrabAudio( demux_t *p_demux ) ...@@ -557,13 +522,15 @@ static block_t* GrabAudio( demux_t *p_demux )
break; break;
} }
case -ESTRPIPE: case -ESTRPIPE:
{
/* suspend */ /* suspend */
i_resume = snd_pcm_resume( p_sys->p_alsa_pcm ); int i_resume = snd_pcm_resume( p_sys->p_alsa_pcm );
if( i_resume < 0 && i_resume != -EAGAIN ) snd_pcm_prepare( p_sys->p_alsa_pcm ); if( i_resume < 0 && i_resume != -EAGAIN ) snd_pcm_prepare( p_sys->p_alsa_pcm );
break; break;
}
default: default:
msg_Err( p_demux, "Failed to read alsa frame (%s)", snd_strerror( i_read ) ); msg_Err( p_demux, "Failed to read alsa frame (%s)", snd_strerror( i_read ) );
return 0; return NULL;
} }
} }
else else
...@@ -572,10 +539,10 @@ static block_t* GrabAudio( demux_t *p_demux ) ...@@ -572,10 +539,10 @@ static block_t* GrabAudio( demux_t *p_demux )
i_read *= p_sys->i_alsa_frame_size; i_read *= p_sys->i_alsa_frame_size;
} }
if( i_read <= 0 ) return 0; if( i_read <= 0 ) return NULL;
p_block->i_buffer = i_read; p_block->i_buffer = i_read;
p_sys->p_block = 0; p_sys->p_block = NULL;
/* Correct the date because of kernel buffering */ /* Correct the date because of kernel buffering */
i_correct = i_read; i_correct = i_read;
......
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