]> git.sesse.net Git - vlc/commitdiff
* ./src/audio_output/output.c: reverted my previous aout_OutputNextBuffer
authorSam Hocevar <sam@videolan.org>
Sun, 25 Aug 2002 09:40:00 +0000 (09:40 +0000)
committerSam Hocevar <sam@videolan.org>
Sun, 25 Aug 2002 09:40:00 +0000 (09:40 +0000)
    prototype change; it looks like we won't need it after all.
  * ./src/audio_output/output.c: if audio output is too slow, but we
    know there is no next packet, then we play it anyway. Rationale behind
    this is: better play a slightly wrongly dated packet than play silence,
    because it might be wrongly dated but there are chances it won't break
    audio continuity.
  * ./modules/audio_output/sdl.c: workaround for SDL's crap audio output
    system (callback gets called at random times, and no way to know the
    latency of the samples being played). Audio output is now rather good
    here, but please give feedback.
  * ./modules/audio_output/oss.c: we delay a bit before asking for a new
    buffer to avoid starvation.

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/audio_output/waveout.c
modules/gui/macosx/aout.m
modules/gui/qnx/aout.c
modules/video_output/directx/aout.c
src/audio_output/output.c

index 1ac455edaaf2b2fdb16db9017166037cf2e91c0d..5c4214ae86f315cc6c4a2ad79586396ed1628af3 100644 (file)
@@ -2,7 +2,7 @@
  * aout_internal.h : internal defines for audio output
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: aout_internal.h,v 1.11 2002/08/24 10:19:42 sam Exp $
+ * $Id: aout_internal.h,v 1.12 2002/08/25 09:39:59 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, mtime_t, vlc_bool_t ) );
+VLC_EXPORT( aout_buffer_t *, aout_OutputNextBuffer, ( aout_instance_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 cdd5ebdb969713eb9941eebb609e0ff78a3d38de..370a0d0e06302abafeb1d66f2c3ea57fcc8c0a69 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, mtime_t, vlc_bool_t ) ;
+    aout_buffer_t * (* aout_OutputNextBuffer_inner) ( aout_instance_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 e637d561dc9aec5ebd634e7d4913236e73928047..7e5ca61eace876a73727422e68fe82f77bc915c1 100644 (file)
@@ -2,7 +2,7 @@
  * alsa.c : alsa plugin for vlc
  *****************************************************************************
  * Copyright (C) 2000-2001 VideoLAN
- * $Id: alsa.c,v 1.7 2002/08/24 10:19:42 sam Exp $
+ * $Id: alsa.c,v 1.8 2002/08/25 09:39:59 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, 0,
+            p_buffer = aout_OutputNextBuffer( p_aout, next_date,
                                               p_sys->b_can_sleek );
 
             /* Audio output buffer shortage -> stop the fill process and
index ea7cb91dae0d148c357f9ab764327df20c8e59dd..5508b1f09a5c5566c183bd01ff1e8920a2673148 100644 (file)
@@ -206,7 +206,7 @@ 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, VLC_FALSE );
+                                                  VLC_FALSE );
 
         if ( p_buffer != NULL )
         {
index cc1da6095cace86120f2c7b10e500db8e85f5881..38a3d4a088755c64b8106d467b53dae3554e14bb 100644 (file)
@@ -2,7 +2,7 @@
  * esd.c : EsounD module
  *****************************************************************************
  * Copyright (C) 2000, 2001 VideoLAN
- * $Id: esd.c,v 1.9 2002/08/24 10:19:42 sam Exp $
+ * $Id: esd.c,v 1.10 2002/08/25 09:39:59 sam Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *
@@ -203,7 +203,7 @@ 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, VLC_FALSE );
+                                                  VLC_FALSE );
 
         if ( p_buffer != NULL )
         {
index b0ec8f0e608dfb17ba947034f4f586d568d75afe..47d9b071ffc188541d430f667ec8a1793b2ac6cf 100644 (file)
@@ -2,7 +2,7 @@
  * oss.c : OSS /dev/dsp module for vlc
  *****************************************************************************
  * Copyright (C) 2000-2002 VideoLAN
- * $Id: oss.c,v 1.17 2002/08/24 21:11:21 sam Exp $
+ * $Id: oss.c,v 1.18 2002/08/25 09:40:00 sam Exp $
  *
  * Authors: Michel Kaempf <maxx@via.ecp.fr>
  *          Samuel Hocevar <sam@zoy.org>
@@ -318,29 +318,29 @@ static int OSSThread( aout_instance_t * p_aout )
 
         if ( p_aout->output.output.i_format != AOUT_FMT_SPDIF )
         {
-            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;
+            mtime_t buffered;
 
-            while( buffered > 50000 )
+            do
             {
-                msleep( buffered / 2 - 10000 );
                 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;
-            }
+                if( buffered < 50000 )
+                {
+                    break;
+                }
+                msleep( buffered / 2 - 10000 );
+
+            } while( VLC_TRUE );
 
-            /* Next buffer will be played at mdate()+buffered, and we tell
-             * the audio output that it can wait for a new packet for
-             * 20000 microseconds. */
+            /* Next buffer will be played at mdate()+buffered */
             p_buffer = aout_OutputNextBuffer( p_aout, mdate() + buffered,
-                                              20000, VLC_FALSE );
+                                              VLC_FALSE );
         }
         else
         {
-            p_buffer = aout_OutputNextBuffer( p_aout, 0, 0, VLC_TRUE );
+            p_buffer = aout_OutputNextBuffer( p_aout, 0, VLC_TRUE );
         }
 
         if ( p_buffer != NULL )
index e332ea5cc0699632247420b297a57fcdfcb1bdcf..0d63ee235dfeaa9ed16a3cf2267a8899f8c26664 100644 (file)
@@ -2,7 +2,7 @@
  * sdl.c : SDL audio output plugin for vlc
  *****************************************************************************
  * Copyright (C) 2000-2002 VideoLAN
- * $Id: sdl.c,v 1.5 2002/08/24 10:19:42 sam Exp $
+ * $Id: sdl.c,v 1.6 2002/08/25 09:40:00 sam Exp $
  *
  * Authors: Michel Kaempf <maxx@via.ecp.fr>
  *          Samuel Hocevar <sam@zoy.org>
 
 #include SDL_INCLUDE_FILE
 
-#define FRAME_SIZE 2048*2
+#define FRAME_SIZE 2048
+
+/*****************************************************************************
+ * aout_sys_t: SDL audio output method descriptor
+ *****************************************************************************
+ * This structure is part of the audio output thread descriptor.
+ * It describes the specific properties of an audio device.
+ *****************************************************************************/
+struct aout_sys_t
+{   
+    mtime_t call_time;
+    mtime_t buffer_time;
+};
 
 /*****************************************************************************
  * Local prototypes
@@ -66,12 +78,21 @@ vlc_module_end();
 static int Open ( vlc_object_t *p_this )
 {
     aout_instance_t *p_aout = (aout_instance_t *)p_this;
+    aout_sys_t * p_sys;
 
     Uint32 i_flags = SDL_INIT_AUDIO;
 
     if( SDL_WasInit( i_flags ) )
     {
-        return 1;
+        return VLC_EGENERIC;
+    }
+
+    /* Allocate structure */
+    p_aout->output.p_sys = p_sys = malloc( sizeof( aout_sys_t ) );
+    if( p_sys == NULL )
+    {
+        msg_Err( p_aout, "out of memory" );
+        return VLC_ENOMEM;
     }
 
     p_aout->output.pf_setformat = SetFormat;
@@ -91,10 +112,11 @@ static int Open ( vlc_object_t *p_this )
     if( SDL_Init( i_flags ) < 0 )
     {
         msg_Err( p_aout, "cannot initialize SDL (%s)", SDL_GetError() );
-        return 1;
+        free( p_sys );
+        return VLC_EGENERIC;
     }
 
-    return 0;
+    return VLC_SUCCESS;
 }
 
 /*****************************************************************************
@@ -102,6 +124,8 @@ static int Open ( vlc_object_t *p_this )
  *****************************************************************************/
 static int SetFormat( aout_instance_t *p_aout )
 {
+    aout_sys_t * p_sys = p_aout->output.p_sys;
+
     /* TODO: finish and clean this */
     SDL_AudioSpec desired;
 
@@ -115,15 +139,19 @@ static int SetFormat( aout_instance_t *p_aout )
     /* Open the sound device - FIXME : get the "natural" parameters */
     if( SDL_OpenAudio( &desired, NULL ) < 0 )
     {
-        return -1;
+        return VLC_EGENERIC;
     }
 
     p_aout->output.output.i_format = AOUT_FMT_S16_NE;
     p_aout->output.i_nb_samples = FRAME_SIZE;
 
+    p_sys->call_time = 0;
+    p_sys->buffer_time = (mtime_t)FRAME_SIZE * 1000000
+                          / p_aout->output.output.i_rate;
+
     SDL_PauseAudio( 0 );
 
-    return 0;
+    return VLC_SUCCESS;
 }
 
 /*****************************************************************************
@@ -138,9 +166,14 @@ static void Play( aout_instance_t * p_aout )
  *****************************************************************************/
 static void Close ( vlc_object_t *p_this )
 {
+    aout_instance_t *p_aout = (aout_instance_t *)p_this;
+    aout_sys_t * p_sys = p_aout->output.p_sys;
+
     SDL_PauseAudio( 1 );
     SDL_CloseAudio();
     SDL_QuitSubSystem( SDL_INIT_AUDIO );
+
+    free( p_sys );
 }
 
 /*****************************************************************************
@@ -149,16 +182,29 @@ 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_sys_t * p_sys = p_aout->output.p_sys;
+
     aout_buffer_t * p_buffer;
-//if(old) diff = (9 * diff + (foo-old))/10;
-    /* FIXME : take into account SDL latency instead of mdate() */
-    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;
+
+    /* We try to stay around call_time + buffer_time/2. This is kludgy but
+     * unavoidable because SDL is completely unable to 1. tell us about its
+     * latency, and 2. call SDLCallback at regular intervals. */
+    if( mdate() < p_sys->call_time + p_sys->buffer_time / 2 )
+    {
+        /* We can't wait too much, because SDL will be lost, and we can't
+         * wait too little, because we are not sure that there will be
+         * samples in the queue. */
+        mwait( p_sys->call_time + p_sys->buffer_time / 4 );
+        p_sys->call_time += p_sys->buffer_time;
+    }
+    else
+    {
+        p_sys->call_time = mdate() + p_sys->buffer_time / 4;
+    }
+
+    /* Tell the output we're playing samples at call_time + 2*buffer_time */
+    p_buffer = aout_OutputNextBuffer( p_aout, p_sys->call_time
+                                       + 2 * p_sys->buffer_time, VLC_TRUE );
 
     if ( i_len != FRAME_SIZE * sizeof(s16)
                     * p_aout->output.output.i_channels )
@@ -168,14 +214,11 @@ 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 dbd23ad9fa4f4b1a759f140e089f137637019231..8e5bb3696f3a99fbca4a7657711da649ea12d12c 100644 (file)
@@ -2,7 +2,7 @@
  * waveout.c : Windows waveOut plugin for vlc
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: waveout.c,v 1.4 2002/08/19 21:31:11 massiot Exp $
+ * $Id: waveout.c,v 1.5 2002/08/25 09:40:00 sam Exp $
  *
  * Authors: Gildas Bazin <gbazin@netcourrier.com>
  *      
@@ -310,7 +310,7 @@ static void CALLBACK WaveOutCallback( HWAVEOUT h_waveout, UINT uMsg,
         aout_BufferFree( (aout_buffer_t *)p_waveheader->dwUser );
 
     /* FIXME : take into account WaveOut latency instead of mdate() */
-    p_buffer = aout_OutputNextBuffer( p_aout, mdate(), 0 );
+    p_buffer = aout_OutputNextBuffer( p_aout, mdate(), VLC_FALSE );
 
     PlayWaveOut( p_aout, h_waveout, p_waveheader, p_buffer );
 }
index 78185cc6530dd35d5630899d34d6d12041c2badb..920c723150c29c8cc278b6331ad3beabd975892e 100644 (file)
@@ -2,7 +2,7 @@
  * aout.m: CoreAudio output plugin
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: aout.m,v 1.6 2002/08/24 10:19:42 sam Exp $
+ * $Id: aout.m,v 1.7 2002/08/25 09:40:00 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, VLC_FALSE );
+    p_buffer = aout_OutputNextBuffer( p_aout, current_date, VLC_FALSE );
 
     /* move data into output data buffer */
     if ( p_buffer != NULL )
index 4bbec897325a51a985dee180a4ba3113ac8131ef..33c96232fcd67fa90dd8bd612ce400f82c441ed6 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, 0, VLC_FALSE );
+            p_buffer = aout_OutputNextBuffer( p_aout, next_date, VLC_FALSE );
         }
         else
         {
-            p_buffer = aout_OutputNextBuffer( p_aout, 0, 0, VLC_TRUE );
+            p_buffer = aout_OutputNextBuffer( p_aout, 0, VLC_TRUE );
         }
 
         if ( p_buffer != NULL )
index 4950854653314f11e803fd6f94044fc1bb9153b5..4ef9b8b8a6e3281e879fa21e82f25ea4095731e1 100644 (file)
@@ -2,7 +2,7 @@
  * aout.c: Windows DirectX audio output method
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: aout.c,v 1.6 2002/08/24 10:19:42 sam Exp $
+ * $Id: aout.c,v 1.7 2002/08/25 09:40:00 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, VLC_FALSE );
+        p_buffer = aout_OutputNextBuffer( p_aout, mdate(), VLC_FALSE );
 
         /* Now do the actual memcpy into the circular buffer */
         if ( l_bytes1 != p_notif->i_buffer_size )
index 46180b1b8cc0aa89331c84150e46e74ee391b62b..9368de723a39ddd35bacc29654e15c70fc535fec 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.10 2002/08/24 10:19:43 sam Exp $
+ * $Id: output.c,v 1.11 2002/08/25 09:40:00 sam Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -164,28 +164,16 @@ void aout_OutputPlay( aout_instance_t * p_aout, aout_buffer_t * p_buffer )
  *****************************************************************************/
 aout_buffer_t * aout_OutputNextBuffer( aout_instance_t * p_aout,
                                        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 );
 
-    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 )
+    while ( p_buffer && p_buffer->start_date < start_date && p_buffer->p_next )
     {
-        msg_Dbg( p_aout, "audio output is too slow (%lld), trashing %lldms",
+        msg_Dbg( p_aout, "audio output is too slow (%lld), trashing %lldus",
                  start_date - p_buffer->start_date,
                  p_buffer->end_date - p_buffer->start_date );
         p_buffer = p_buffer->p_next;
@@ -198,7 +186,8 @@ 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, waited too long" );
+        msg_Dbg( p_aout,
+                 "audio output is starving (no input), playing silence" );
         return NULL;
     }
 
@@ -208,7 +197,7 @@ aout_buffer_t * aout_OutputNextBuffer( aout_instance_t * p_aout,
                          + (p_buffer->end_date - p_buffer->start_date) )
     {
         vlc_mutex_unlock( &p_aout->mixer_lock );
-        msg_Dbg( p_aout, "audio output is starving (%lld)",
+        msg_Dbg( p_aout, "audio output is starving (%lld), playing silence",
                  p_buffer->start_date - start_date );
         return NULL;
     }