From 711160b2a2a3c716670d6f4c0f74a7545db8bddc Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Sat, 24 Aug 2002 10:19:43 +0000 Subject: [PATCH] * ./src/audio_output/output.c: added an argument to aout_OutputNextBuffer which lets the audio output module give a timeout value for buffer delivery. This fixes a few issues with aout modules which were calling aout_OutputNextBuffer way too early. --- include/aout_internal.h | 4 ++-- include/vlc_symbols.h | 2 +- modules/audio_output/alsa.c | 4 ++-- modules/audio_output/arts.c | 3 ++- modules/audio_output/esd.c | 9 ++++----- modules/audio_output/oss.c | 31 +++++++++++++++-------------- modules/audio_output/sdl.c | 15 ++++++++++++-- modules/gui/macosx/aout.m | 4 ++-- modules/gui/qnx/aout.c | 4 ++-- modules/video_output/directx/aout.c | 4 ++-- src/audio_output/input.c | 6 +++--- src/audio_output/output.c | 25 +++++++++++++++++------ 12 files changed, 68 insertions(+), 43 deletions(-) diff --git a/include/aout_internal.h b/include/aout_internal.h index c441b93c63..1ac455edaa 100644 --- a/include/aout_internal.h +++ b/include/aout_internal.h @@ -2,7 +2,7 @@ * aout_internal.h : internal defines for audio output ***************************************************************************** * Copyright (C) 2002 VideoLAN - * $Id: aout_internal.h,v 1.10 2002/08/21 23:19:58 sam Exp $ + * $Id: aout_internal.h,v 1.11 2002/08/24 10:19:42 sam Exp $ * * Authors: Christophe Massiot * @@ -211,7 +211,7 @@ int aout_OutputNew( aout_instance_t * p_aout, audio_sample_format_t * p_format ); void aout_OutputPlay( aout_instance_t * p_aout, aout_buffer_t * p_buffer ); void aout_OutputDelete( aout_instance_t * p_aout ); -VLC_EXPORT( aout_buffer_t *, aout_OutputNextBuffer, ( aout_instance_t *, mtime_t, vlc_bool_t ) ); +VLC_EXPORT( aout_buffer_t *, aout_OutputNextBuffer, ( aout_instance_t *, mtime_t, mtime_t, vlc_bool_t ) ); void aout_FormatPrepare( audio_sample_format_t * p_format ); void aout_FifoInit( aout_instance_t *, aout_fifo_t *, u32 ); diff --git a/include/vlc_symbols.h b/include/vlc_symbols.h index 370a0d0e06..cdd5ebdb96 100644 --- a/include/vlc_symbols.h +++ b/include/vlc_symbols.h @@ -4,7 +4,7 @@ struct module_symbols_t { aout_buffer_t * (* aout_BufferNew_inner) ( aout_instance_t *, aout_input_t *, size_t ) ; aout_buffer_t * (* aout_FifoPop_inner) ( aout_instance_t * p_aout, aout_fifo_t * p_fifo ) ; - aout_buffer_t * (* aout_OutputNextBuffer_inner) ( aout_instance_t *, mtime_t, vlc_bool_t ) ; + aout_buffer_t * (* aout_OutputNextBuffer_inner) ( aout_instance_t *, mtime_t, mtime_t, vlc_bool_t ) ; aout_input_t * (* __aout_InputNew_inner) ( vlc_object_t *, aout_instance_t **, audio_sample_format_t * ) ; aout_instance_t * (* __aout_NewInstance_inner) ( vlc_object_t * ) ; char * (* __config_GetPsz_inner) (vlc_object_t *, const char *) ; diff --git a/modules/audio_output/alsa.c b/modules/audio_output/alsa.c index 7718a4e744..e637d561dc 100644 --- a/modules/audio_output/alsa.c +++ b/modules/audio_output/alsa.c @@ -2,7 +2,7 @@ * alsa.c : alsa plugin for vlc ***************************************************************************** * Copyright (C) 2000-2001 VideoLAN - * $Id: alsa.c,v 1.6 2002/08/19 23:07:30 sam Exp $ + * $Id: alsa.c,v 1.7 2002/08/24 10:19:42 sam Exp $ * * Authors: Henri Fallon - Original Author * Jeffrey Baker - Port to ALSA 1.0 API @@ -473,7 +473,7 @@ static void ALSAFill( aout_instance_t * p_aout ) snd_pcm_status_get_tstamp( p_status, &ts_next ); next_date = (mtime_t)ts_next.tv_sec * 1000000 + ts_next.tv_usec; - p_buffer = aout_OutputNextBuffer( p_aout, next_date, + p_buffer = aout_OutputNextBuffer( p_aout, next_date, 0, p_sys->b_can_sleek ); /* Audio output buffer shortage -> stop the fill process and diff --git a/modules/audio_output/arts.c b/modules/audio_output/arts.c index e92dd3ae79..ea7cb91dae 100644 --- a/modules/audio_output/arts.c +++ b/modules/audio_output/arts.c @@ -205,7 +205,8 @@ static int aRtsThread( aout_instance_t * p_aout ) /* Get the presentation date of the next write() operation. It * is equal to the current date + latency */ - p_buffer = aout_OutputNextBuffer( p_aout, mdate() + p_sys->latency, 0 ); + p_buffer = aout_OutputNextBuffer( p_aout, mdate() + p_sys->latency, + 0, VLC_FALSE ); if ( p_buffer != NULL ) { diff --git a/modules/audio_output/esd.c b/modules/audio_output/esd.c index cbf8130117..cc1da6095c 100644 --- a/modules/audio_output/esd.c +++ b/modules/audio_output/esd.c @@ -2,7 +2,7 @@ * esd.c : EsounD module ***************************************************************************** * Copyright (C) 2000, 2001 VideoLAN - * $Id: esd.c,v 1.8 2002/08/19 23:07:30 sam Exp $ + * $Id: esd.c,v 1.9 2002/08/24 10:19:42 sam Exp $ * * Authors: Samuel Hocevar * @@ -149,12 +149,10 @@ static int SetFormat( aout_instance_t *p_aout ) (mtime_t)( esd_get_latency( esd_open_sound(NULL) ) + ESD_BUF_SIZE/2 * p_aout->output.output.i_bytes_per_frame * p_aout->output.output.i_rate - / p_aout->output.output.i_frame_length / ESD_DEFAULT_RATE ) * (mtime_t)1000000 / p_aout->output.output.i_bytes_per_frame - / p_aout->output.output.i_rate - * p_aout->output.output.i_frame_length; + / p_aout->output.output.i_rate; p_sys->b_initialized = VLC_TRUE; @@ -204,7 +202,8 @@ static int ESDThread( aout_instance_t * p_aout ) /* Get the presentation date of the next write() operation. It * is equal to the current date + buffered samples + esd latency */ - p_buffer = aout_OutputNextBuffer( p_aout, mdate() + p_sys->latency, 0 ); + p_buffer = aout_OutputNextBuffer( p_aout, mdate() + p_sys->latency, + 0, VLC_FALSE ); if ( p_buffer != NULL ) { diff --git a/modules/audio_output/oss.c b/modules/audio_output/oss.c index acb85fc20c..6239160163 100644 --- a/modules/audio_output/oss.c +++ b/modules/audio_output/oss.c @@ -2,7 +2,7 @@ * oss.c : OSS /dev/dsp module for vlc ***************************************************************************** * Copyright (C) 2000-2002 VideoLAN - * $Id: oss.c,v 1.14 2002/08/24 01:14:29 sigmunau Exp $ + * $Id: oss.c,v 1.15 2002/08/24 10:19:42 sam Exp $ * * Authors: Michel Kaempf * Samuel Hocevar @@ -65,7 +65,7 @@ struct aout_sys_t volatile vlc_bool_t b_initialized; }; -#define FRAME_SIZE 2048 +#define FRAME_SIZE 1024 #define A52_FRAME_NB 1536 /***************************************************************************** @@ -86,6 +86,7 @@ vlc_module_begin(); add_file( "dspdev", "/dev/dsp", NULL, N_("OSS dsp device"), NULL ); set_description( _("Linux OSS /dev/dsp module") ); set_capability( "audio output", 100 ); + add_shortcut( "dsp" ); set_callbacks( Open, Close ); vlc_module_end(); @@ -258,7 +259,9 @@ static void Close( vlc_object_t * p_this ) p_aout->b_die = 1; vlc_thread_join( p_aout ); + ioctl( p_sys->i_fd, SNDCTL_DSP_RESET, NULL ); close( p_sys->i_fd ); + free( p_sys ); } @@ -305,22 +308,20 @@ static int OSSThread( aout_instance_t * p_aout ) if ( p_aout->output.output.i_format != AOUT_FMT_SPDIF ) { - mtime_t next_date = 0; - /* Get the presentation date of the next write() operation. It - * is equal to the current date + duration of buffered samples. - * Order is important here, since GetBufInfo is believed to take - * more time than mdate(). */ - next_date = (mtime_t)GetBufInfo( p_aout ) * 100000 - / p_aout->output.output.i_bytes_per_frame - / p_aout->output.output.i_rate - * p_aout->output.output.i_frame_length; - next_date += mdate(); - - p_buffer = aout_OutputNextBuffer( p_aout, next_date, VLC_FALSE ); + mtime_t buffered = (mtime_t)GetBufInfo( p_aout ) * 1000000 + / p_aout->output.output.i_bytes_per_frame + / p_aout->output.output.i_rate + * p_aout->output.output.i_frame_length; + + /* Next buffer will be played at mdate()+buffered, and we tell + * the audio output that it can wait for a new packet for + * buffered/2 microseconds. */ + p_buffer = aout_OutputNextBuffer( p_aout, mdate() + buffered, + buffered / 2, VLC_FALSE ); } else { - p_buffer = aout_OutputNextBuffer( p_aout, 0, VLC_TRUE ); + p_buffer = aout_OutputNextBuffer( p_aout, 0, 0, VLC_TRUE ); } if ( p_buffer != NULL ) diff --git a/modules/audio_output/sdl.c b/modules/audio_output/sdl.c index 3541e8411a..e332ea5cc0 100644 --- a/modules/audio_output/sdl.c +++ b/modules/audio_output/sdl.c @@ -2,7 +2,7 @@ * sdl.c : SDL audio output plugin for vlc ***************************************************************************** * Copyright (C) 2000-2002 VideoLAN - * $Id: sdl.c,v 1.4 2002/08/21 22:41:59 massiot Exp $ + * $Id: sdl.c,v 1.5 2002/08/24 10:19:42 sam Exp $ * * Authors: Michel Kaempf * Samuel Hocevar @@ -149,8 +149,16 @@ static void Close ( vlc_object_t *p_this ) static void SDLCallback( void * _p_aout, byte_t * p_stream, int i_len ) { aout_instance_t * p_aout = (aout_instance_t *)_p_aout; +//static mtime_t old = 0; +//static mtime_t diff = 0; +//mtime_t foo = mdate(); + aout_buffer_t * p_buffer; +//if(old) diff = (9 * diff + (foo-old))/10; /* FIXME : take into account SDL latency instead of mdate() */ - aout_buffer_t * p_buffer = aout_OutputNextBuffer( p_aout, mdate(), 1 ); + p_buffer = aout_OutputNextBuffer( p_aout, mdate(), 0, VLC_TRUE ); + //p_buffer = aout_OutputNextBuffer( p_aout, foo - diff, 0, VLC_TRUE ); +//fprintf(stderr, "foo - old : %lli, diff : %lli\n", foo-old, diff); +//old=foo; if ( i_len != FRAME_SIZE * sizeof(s16) * p_aout->output.output.i_channels ) @@ -160,11 +168,14 @@ static void SDLCallback( void * _p_aout, byte_t * p_stream, int i_len ) if ( p_buffer != NULL ) { +//fprintf(stderr, "got buffer %lli\n", p_buffer->end_date - p_buffer->start_date); + p_aout->p_vlc->pf_memcpy( p_stream, p_buffer->p_buffer, i_len ); aout_BufferFree( p_buffer ); } else { +//fprintf(stderr, "NO BUFFER !\n"); p_aout->p_vlc->pf_memset( p_stream, 0, i_len ); } } diff --git a/modules/gui/macosx/aout.m b/modules/gui/macosx/aout.m index 6abb59b648..78185cc653 100644 --- a/modules/gui/macosx/aout.m +++ b/modules/gui/macosx/aout.m @@ -2,7 +2,7 @@ * aout.m: CoreAudio output plugin ***************************************************************************** * Copyright (C) 2002 VideoLAN - * $Id: aout.m,v 1.5 2002/08/19 21:31:11 massiot Exp $ + * $Id: aout.m,v 1.6 2002/08/24 10:19:42 sam Exp $ * * Authors: Colin Delacroix * Jon Lech Johansen @@ -236,7 +236,7 @@ static OSStatus IOCallback( AudioDeviceID inDevice, current_date = p_sys->clock_diff + AudioConvertHostTimeToNanos(host_time.mHostTime) / 1000; - p_buffer = aout_OutputNextBuffer( p_aout, current_date, 0 ); + p_buffer = aout_OutputNextBuffer( p_aout, current_date, 0, VLC_FALSE ); /* move data into output data buffer */ if ( p_buffer != NULL ) diff --git a/modules/gui/qnx/aout.c b/modules/gui/qnx/aout.c index 33c96232fc..4bbec89732 100644 --- a/modules/gui/qnx/aout.c +++ b/modules/gui/qnx/aout.c @@ -306,11 +306,11 @@ static int QNXaoutThread( aout_instance_t * p_aout ) * p_aout->output.output.i_frame_length; next_date += mdate(); - p_buffer = aout_OutputNextBuffer( p_aout, next_date, VLC_FALSE ); + p_buffer = aout_OutputNextBuffer( p_aout, next_date, 0, VLC_FALSE ); } else { - p_buffer = aout_OutputNextBuffer( p_aout, 0, VLC_TRUE ); + p_buffer = aout_OutputNextBuffer( p_aout, 0, 0, VLC_TRUE ); } if ( p_buffer != NULL ) diff --git a/modules/video_output/directx/aout.c b/modules/video_output/directx/aout.c index 59ee239d0c..4950854653 100644 --- a/modules/video_output/directx/aout.c +++ b/modules/video_output/directx/aout.c @@ -2,7 +2,7 @@ * aout.c: Windows DirectX audio output method ***************************************************************************** * Copyright (C) 2001 VideoLAN - * $Id: aout.c,v 1.5 2002/08/19 21:31:11 massiot Exp $ + * $Id: aout.c,v 1.6 2002/08/24 10:19:42 sam Exp $ * * Authors: Gildas Bazin * @@ -559,7 +559,7 @@ static void DirectSoundThread( notification_thread_t *p_notif ) } /* FIXME : take into account DirectSound latency instead of mdate() */ - p_buffer = aout_OutputNextBuffer( p_aout, mdate(), 0 ); + p_buffer = aout_OutputNextBuffer( p_aout, mdate(), 0, VLC_FALSE ); /* Now do the actual memcpy into the circular buffer */ if ( l_bytes1 != p_notif->i_buffer_size ) diff --git a/src/audio_output/input.c b/src/audio_output/input.c index 81689a37ac..77f21a2057 100644 --- a/src/audio_output/input.c +++ b/src/audio_output/input.c @@ -2,7 +2,7 @@ * input.c : internal management of input streams for the audio output ***************************************************************************** * Copyright (C) 2002 VideoLAN - * $Id: input.c,v 1.7 2002/08/21 22:41:59 massiot Exp $ + * $Id: input.c,v 1.8 2002/08/24 10:19:43 sam Exp $ * * Authors: Christophe Massiot * @@ -229,7 +229,7 @@ void aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input, /* The decoder is _very_ late. This can only happen if the user * pauses the stream (or if the decoder is buggy, which cannot * happen :). */ - msg_Warn( p_aout, "Computed PTS is out of range (%lld), clearing out", + msg_Warn( p_aout, "computed PTS is out of range (%lld), clearing out", start_date ); vlc_mutex_lock( &p_aout->mixer_lock ); aout_FifoSet( p_aout, &p_input->fifo, 0 ); @@ -237,7 +237,7 @@ void aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input, start_date = 0; } - if ( p_buffer->start_date < mdate() - AOUT_MIN_PREPARE_TIME ) + if ( p_buffer->start_date < mdate() + AOUT_MIN_PREPARE_TIME ) { /* The decoder gives us f*cked up PTS. It's its business, but we * can't present it anyway, so drop the buffer. */ diff --git a/src/audio_output/output.c b/src/audio_output/output.c index 21f93974fe..46180b1b8c 100644 --- a/src/audio_output/output.c +++ b/src/audio_output/output.c @@ -2,7 +2,7 @@ * output.c : internal management of output streams for the audio output ***************************************************************************** * Copyright (C) 2002 VideoLAN - * $Id: output.c,v 1.9 2002/08/21 22:41:59 massiot Exp $ + * $Id: output.c,v 1.10 2002/08/24 10:19:43 sam Exp $ * * Authors: Christophe Massiot * @@ -163,18 +163,31 @@ void aout_OutputPlay( aout_instance_t * p_aout, aout_buffer_t * p_buffer ) * compensate it by itself. S/PDIF outputs should always set b_can_sleek = 1. *****************************************************************************/ aout_buffer_t * aout_OutputNextBuffer( aout_instance_t * p_aout, - mtime_t start_date , + mtime_t start_date, + mtime_t timeout, vlc_bool_t b_can_sleek ) { aout_buffer_t * p_buffer; + mtime_t now = mdate(); vlc_mutex_lock( &p_aout->mixer_lock ); - p_buffer = p_aout->output.fifo.p_first; + timeout += now; + + while( p_aout->output.fifo.p_first == NULL && timeout > now ) + { + vlc_mutex_unlock( &p_aout->mixer_lock ); + msleep( AOUT_PTS_TOLERANCE / 2 ); + vlc_mutex_lock( &p_aout->mixer_lock ); + now = mdate(); + } + + p_buffer = p_aout->output.fifo.p_first; while ( p_buffer != NULL && p_buffer->start_date < start_date ) { - msg_Dbg( p_aout, "audio output is too slow (%lld)", - start_date - p_buffer->start_date ); + msg_Dbg( p_aout, "audio output is too slow (%lld), trashing %lldms", + start_date - p_buffer->start_date, + p_buffer->end_date - p_buffer->start_date ); p_buffer = p_buffer->p_next; } @@ -185,7 +198,7 @@ aout_buffer_t * aout_OutputNextBuffer( aout_instance_t * p_aout, /* Set date to 0, to allow the mixer to send a new buffer ASAP */ aout_FifoSet( p_aout, &p_aout->output.fifo, 0 ); vlc_mutex_unlock( &p_aout->mixer_lock ); - msg_Dbg( p_aout, "audio output is starving" ); + msg_Dbg( p_aout, "audio output is starving, waited too long" ); return NULL; } -- 2.20.1