* ./src/audio_output/output.c: added an argument to aout_OutputNextBuffer
authorSam Hocevar <sam@videolan.org>
Sat, 24 Aug 2002 10:19:43 +0000 (10:19 +0000)
committerSam Hocevar <sam@videolan.org>
Sat, 24 Aug 2002 10:19:43 +0000 (10:19 +0000)
    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.

12 files changed:
include/aout_internal.h
include/vlc_symbols.h
modules/audio_output/alsa.c
modules/audio_output/arts.c
modules/audio_output/esd.c
modules/audio_output/oss.c
modules/audio_output/sdl.c
modules/gui/macosx/aout.m
modules/gui/qnx/aout.c
modules/video_output/directx/aout.c
src/audio_output/input.c
src/audio_output/output.c

index c441b93..1ac455e 100644 (file)
@@ -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 <massiot@via.ecp.fr>
  *
@@ -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 );
index 370a0d0..cdd5ebd 100644 (file)
@@ -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 *) ;
index 7718a4e..e637d56 100644 (file)
@@ -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 <henri@videolan.org> - Original Author
  *          Jeffrey Baker <jwbaker@acm.org> - 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
index e92dd3a..ea7cb91 100644 (file)
@@ -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 )
         {
index cbf8130..cc1da60 100644 (file)
@@ -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 <sam@zoy.org>
  *
@@ -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 )
         {
index acb85fc..6239160 100644 (file)
@@ -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 <maxx@via.ecp.fr>
  *          Samuel Hocevar <sam@zoy.org>
@@ -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 )
index 3541e84..e332ea5 100644 (file)
@@ -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 <maxx@via.ecp.fr>
  *          Samuel Hocevar <sam@zoy.org>
@@ -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 );
     }
 }
index 6abb59b..78185cc 100644 (file)
@@ -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 <colin@zoy.org>
  *          Jon Lech Johansen <jon-vl@nanocrew.net>
@@ -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 )
index 33c9623..4bbec89 100644 (file)
@@ -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 )
index 59ee239..4950854 100644 (file)
@@ -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 <gbazin@netcourrier.com>
  *
@@ -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 )
index 81689a3..77f21a2 100644 (file)
@@ -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 <massiot@via.ecp.fr>
  *
@@ -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. */
index 21f9397..46180b1 100644 (file)
@@ -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 <massiot@via.ecp.fr>
  *
@@ -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;
     }