]> git.sesse.net Git - vlc/commitdiff
* configure.ac.in: libvorbis depends on libogg.
authorGildas Bazin <gbazin@videolan.org>
Mon, 28 Oct 2002 22:31:50 +0000 (22:31 +0000)
committerGildas Bazin <gbazin@videolan.org>
Mon, 28 Oct 2002 22:31:50 +0000 (22:31 +0000)
* include/vlc_threads.h: changed the different threads priorities to optimize
   audio and video quality as well as responsiveness.
* modules/audio_output/waveout.c modules/audio_output/directx.c: waveout and
   directx will now use the float32 format if available. Various tweaks for
   better performance.

configure.ac.in
include/vlc_threads.h
modules/audio_output/directx.c
modules/audio_output/waveout.c

index e5830c61ab677ef962459c3b756262f72f244705..6f9422680c2a5ad1eeb518b7b8d5ca2f8ef503ac 100644 (file)
@@ -1393,7 +1393,7 @@ if test "x${enable_vorbis}" != "xno"
 then
   AC_CHECK_HEADERS(vorbis/codec.h, [
     PLUGINS="${PLUGINS} vorbis"
-    LDFLAGS_vorbis="${LDFLAGS_vorbis} -lvorbis"
+    LDFLAGS_vorbis="${LDFLAGS_vorbis} -lvorbis -logg"
    ],[])
 fi
 
index 88f89ce1f975ef48f7627176fa9d77f10e0f26c7..e7e09b332576bbc13937086a1339e7f5f8d4230f 100644 (file)
@@ -3,7 +3,7 @@
  * This header provides portable declarations for mutexes & conditions
  *****************************************************************************
  * Copyright (C) 1999, 2002 VideoLAN
- * $Id: vlc_threads.h,v 1.15 2002/10/20 12:23:47 massiot Exp $
+ * $Id: vlc_threads.h,v 1.16 2002/10/28 22:31:50 gbazin Exp $
  *
  * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
  *          Samuel Hocevar <sam@via.ecp.fr>
@@ -76,8 +76,8 @@
 
 #elif defined(WIN32)
 #   define VLC_THREAD_PRIORITY_LOW 0
-#   define VLC_THREAD_PRIORITY_INPUT THREAD_PRIORITY_ABOVE_NORMAL
-#   define VLC_THREAD_PRIORITY_AUDIO THREAD_PRIORITY_ABOVE_NORMAL
+#   define VLC_THREAD_PRIORITY_INPUT THREAD_PRIORITY_TIME_CRITICAL
+#   define VLC_THREAD_PRIORITY_AUDIO THREAD_PRIORITY_HIGHEST
 #   define VLC_THREAD_PRIORITY_VIDEO 0
 #   define VLC_THREAD_PRIORITY_OUTPUT THREAD_PRIORITY_ABOVE_NORMAL
 
index fb3d4262d555a1c22c4de48e9dafbcbf90d6bfb5..3f4ee3f160114f6a6ff530877f19a44c84457223 100644 (file)
@@ -2,7 +2,7 @@
  * directx.c: Windows DirectX audio output method
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: directx.c,v 1.4 2002/10/20 12:23:47 massiot Exp $
+ * $Id: directx.c,v 1.5 2002/10/28 22:31:49 gbazin Exp $
  *
  * Authors: Gildas Bazin <gbazin@netcourrier.com>
  *
 #include <initguid.h>
 DEFINE_GUID(IID_IDirectSoundNotify, 0xb0210783, 0x89cd, 0x11d0, 0xaf, 0x8, 0x0, 0xa0, 0xc9, 0x25, 0xcd, 0x16);
 
+/*****************************************************************************
+ * Useful macros
+ *****************************************************************************/
+#ifndef WAVE_FORMAT_IEEE_FLOAT
+#   define WAVE_FORMAT_IEEE_FLOAT 0x0003
+#endif
+
 /*****************************************************************************
  * notification_thread_t: DirectX event thread
  *****************************************************************************/
@@ -82,8 +89,6 @@ struct aout_sys_t
 
     HINSTANCE           hdsound_dll;      /* handle of the opened dsound dll */
 
-    vlc_mutex_t buffer_lock;                            /* audio buffer lock */
-
     notification_thread_t * p_notif;                 /* DirectSoundThread id */
 
 };
@@ -139,7 +144,6 @@ static int OpenAudio( vlc_object_t *p_this )
     p_aout->output.p_sys->p_dsbuffer = NULL;
     p_aout->output.p_sys->p_dsnotify = NULL;
     p_aout->output.p_sys->p_notif = NULL;
-    vlc_mutex_init( p_aout, &p_aout->output.p_sys->buffer_lock );
 
     p_aout->output.pf_play = Play;
     aout_VolumeSoftInit( p_aout );
@@ -177,17 +181,19 @@ static int OpenAudio( vlc_object_t *p_this )
     p_aout->output.p_sys->p_notif->p_events[1].hEventNotify =
         CreateEvent( NULL, FALSE, FALSE, NULL );
 
-    vlc_mutex_lock( &p_aout->output.p_sys->buffer_lock );
-
     /* then create a new secondary buffer */
+    p_aout->output.output.i_format = VLC_FOURCC('f','l','3','2');
     if( DirectxCreateSecondaryBuffer( p_aout ) )
     {
-        msg_Err( p_aout, "cannot create buffer" );
-        vlc_mutex_unlock( &p_aout->output.p_sys->buffer_lock );
-        return 1;
-    }
+        msg_Err( p_aout, "cannot create WAVE_FORMAT_IEEE_FLOAT buffer" );
 
-    vlc_mutex_unlock( &p_aout->output.p_sys->buffer_lock );
+        p_aout->output.output.i_format = VLC_FOURCC('s','1','6','l');
+        if( DirectxCreateSecondaryBuffer( p_aout ) )
+        {
+            msg_Err( p_aout, "cannot create WAVE_FORMAT_PCM buffer" );
+            return 1;
+        }
+    }
 
     /* start playing the buffer */
     dsresult = IDirectSoundBuffer_Play( p_aout->output.p_sys->p_dsbuffer,
@@ -211,7 +217,8 @@ static int OpenAudio( vlc_object_t *p_this )
     msg_Dbg( p_aout, "creating DirectSoundThread" );
     if( vlc_thread_create( p_aout->output.p_sys->p_notif,
                            "DirectSound Notification Thread",
-                           DirectSoundThread, VLC_THREAD_PRIORITY_OUTPUT, 1 ) )
+                           DirectSoundThread,
+                           THREAD_PRIORITY_TIME_CRITICAL, 1 ) )
     {
         msg_Err( p_aout, "cannot create DirectSoundThread" );
         goto error;
@@ -361,23 +368,34 @@ static int DirectxCreateSecondaryBuffer( aout_instance_t *p_aout )
 
     /* First set the buffer format */
     memset(&waveformat, 0, sizeof(WAVEFORMATEX));
-    waveformat.wFormatTag      = WAVE_FORMAT_PCM;
+    switch( p_aout->output.output.i_format )
+    {
+    case VLC_FOURCC('s','1','6','l'):
+        waveformat.wFormatTag     = WAVE_FORMAT_PCM;
+        waveformat.wBitsPerSample = 16;
+        break;
+    case VLC_FOURCC('f','l','3','2'):
+        waveformat.wFormatTag     = WAVE_FORMAT_IEEE_FLOAT;
+        waveformat.wBitsPerSample = sizeof(float) * 8;
+        break;
+    }
     waveformat.nChannels       = i_nb_channels;
     waveformat.nSamplesPerSec  = p_aout->output.output.i_rate;
-    waveformat.wBitsPerSample  = 16;
     waveformat.nBlockAlign     = waveformat.wBitsPerSample / 8 *
                                  waveformat.nChannels;
     waveformat.nAvgBytesPerSec = waveformat.nSamplesPerSec *
                                      waveformat.nBlockAlign;
 
+    aout_FormatPrepare( &p_aout->output.output );
+
     /* Then fill in the descriptor */
     memset(&dsbdesc, 0, sizeof(DSBUFFERDESC));
     dsbdesc.dwSize = sizeof(DSBUFFERDESC);
     dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2/* Better position accuracy */
                     | DSBCAPS_CTRLPOSITIONNOTIFY     /* We need notification */
                     | DSBCAPS_GLOBALFOCUS;      /* Allows background playing */
-    dsbdesc.dwBufferBytes = FRAME_SIZE * 2 /* frames*/ *      /* buffer size */
-                            sizeof(s16) * i_nb_channels;
+    dsbdesc.dwBufferBytes = FRAME_SIZE * 2 /* frames*/        /* buffer size */
+                            * p_aout->output.output.i_bytes_per_frame;
     dsbdesc.lpwfxFormat = &waveformat;
  
     if( IDirectSound_CreateSoundBuffer( p_aout->output.p_sys->p_dsobject,
@@ -390,8 +408,8 @@ static int DirectxCreateSecondaryBuffer( aout_instance_t *p_aout )
     }
 
     /* backup the size of a frame */
-    p_aout->output.p_sys->p_notif->i_buffer_size = FRAME_SIZE * sizeof(s16)
-                                            * i_nb_channels;
+    p_aout->output.p_sys->p_notif->i_buffer_size = FRAME_SIZE *
+        p_aout->output.output.i_bytes_per_frame;
 
     memset(&dsbcaps, 0, sizeof(DSBCAPS));
     dsbcaps.dwSize = sizeof(DSBCAPS);
@@ -423,7 +441,7 @@ static int DirectxCreateSecondaryBuffer( aout_instance_t *p_aout )
         msg_Err( p_aout, "cannot set position Notification" );
         goto error;
     }
-    p_aout->output.output.i_format = AOUT_FMT_S16_NE;
+
     p_aout->output.i_nb_samples = FRAME_SIZE;
 
     return 0;
@@ -492,18 +510,14 @@ static void DirectSoundThread( notification_thread_t *p_notif )
         void *p_write_position, *p_wrap_around;
         long l_bytes1, l_bytes2;
         aout_buffer_t * p_buffer;
+        long l_play_position;
 
         /* wait for the position notification */
         i_which_event = WaitForMultipleObjects( 2, notification_events, 0,
                                                 INFINITE ) - WAIT_OBJECT_0;
 
-        vlc_mutex_lock( &p_aout->output.p_sys->buffer_lock );
-
         if( p_notif->b_die )
-        {
-            vlc_mutex_unlock( &p_aout->output.p_sys->buffer_lock );
             break;
-        }
 
         /* Before copying anything, we have to lock the buffer */
         dsresult = IDirectSoundBuffer_Lock(
@@ -533,13 +547,35 @@ static void DirectSoundThread( notification_thread_t *p_notif )
         if( dsresult != DS_OK )
         {
             msg_Warn( p_notif, "cannot lock buffer" );
-            vlc_mutex_unlock( &p_aout->output.p_sys->buffer_lock );
             continue;
         }
 
-        /* We also take into account the latency instead of just mdate() */
+        /* We take into account the current latency */
+        if( IDirectSoundBuffer_GetCurrentPosition(
+                p_aout->output.p_sys->p_dsbuffer,
+                &l_play_position, NULL ) == DS_OK )
+        {
+            if( l_play_position > (i_which_event * FRAME_SIZE)
+                  && l_play_position < ((i_which_event+1) * FRAME_SIZE) )
+            {
+                l_play_position = FRAME_SIZE - ( l_play_position /
+                                      p_aout->output.output.i_bytes_per_frame %
+                                      FRAME_SIZE );
+            }
+            else
+            {
+                l_play_position = 2 * FRAME_SIZE - ( l_play_position /
+                                      p_aout->output.output.i_bytes_per_frame %
+                                      FRAME_SIZE );
+            }
+        }
+        else
+        {
+            l_play_position = FRAME_SIZE;
+        }
+
         p_buffer = aout_OutputNextBuffer( p_aout,
-            mdate() + 1000000 / p_aout->output.output.i_rate * FRAME_SIZE,
+            mdate() + 1000000 / p_aout->output.output.i_rate * l_play_position,
             VLC_FALSE );
 
         /* Now do the actual memcpy into the circular buffer */
@@ -562,8 +598,6 @@ static void DirectSoundThread( notification_thread_t *p_notif )
         IDirectSoundBuffer_Unlock( p_aout->output.p_sys->p_dsbuffer,
                         p_write_position, l_bytes1, p_wrap_around, l_bytes2 );
 
-        vlc_mutex_unlock( &p_aout->output.p_sys->buffer_lock );
-
     }
 
     /* free the events */
@@ -571,5 +605,4 @@ static void DirectSoundThread( notification_thread_t *p_notif )
     CloseHandle( notification_events[1] );
 
     msg_Dbg( p_notif, "DirectSoundThread exiting" );
-
 }
index 35f7d74f75e03168b7cf2acff71f936a673daff5..2a860647034ff2641b7f8b408a9ba6cc42b5377c 100644 (file)
@@ -2,7 +2,7 @@
  * waveout.c : Windows waveOut plugin for vlc
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: waveout.c,v 1.9 2002/10/20 12:23:47 massiot Exp $
+ * $Id: waveout.c,v 1.10 2002/10/28 22:31:49 gbazin Exp $
  *
  * Authors: Gildas Bazin <gbazin@netcourrier.com>
  *      
 #include <windows.h>
 #include <mmsystem.h>
 
-#define FRAME_SIZE 2048              /* The size is in samples, not in bytes */
+#define FRAME_SIZE 1024              /* The size is in samples, not in bytes */
+#define FRAMES_NUM 4
+
+/*****************************************************************************
+ * Useful macros
+ *****************************************************************************/
+#ifndef WAVE_FORMAT_IEEE_FLOAT
+#   define WAVE_FORMAT_IEEE_FLOAT 0x0003
+#endif
 
 /*****************************************************************************
  * Local prototypes
@@ -76,7 +84,7 @@ struct aout_sys_t
 
     WAVEFORMATEX waveformat;                                 /* audio format */
 
-    WAVEHDR waveheader[2];
+    WAVEHDR waveheader[FRAMES_NUM];
 
     int i_buffer_size;
 
@@ -91,8 +99,7 @@ struct aout_sys_t
 static int Open( vlc_object_t *p_this )
 {   
     aout_instance_t *p_aout = (aout_instance_t *)p_this;
-    aout_buffer_t *p_buffer;
-    int i_nb_channels;
+    int i_nb_channels, i;
 
     /* Allocate structure */
     p_aout->output.p_sys = malloc( sizeof( aout_sys_t ) );
@@ -116,29 +123,28 @@ static int Open( vlc_object_t *p_this )
 
     /* We need to open the device with default values to be sure it is
      * available */
-    if ( OpenWaveOut( p_aout, WAVE_FORMAT_PCM, i_nb_channels,
+    p_aout->output.output.i_format = VLC_FOURCC('f','l','3','2');
+    if ( OpenWaveOut( p_aout, WAVE_FORMAT_IEEE_FLOAT, i_nb_channels,
                       p_aout->output.output.i_rate ) )
     {
-        msg_Err( p_aout, "cannot open waveout audio device with output "
-                         "rate (%i)",
-                          p_aout->output.output.i_rate );
-        return VLC_EGENERIC;
+        msg_Err( p_aout, "Audio device doesn't allow WAVE_FORMAT_IEEE_FLOAT" );
 
+        p_aout->output.output.i_format = VLC_FOURCC('s','1','6','l');
         if ( OpenWaveOut( p_aout, WAVE_FORMAT_PCM, i_nb_channels,
-                          44100 ) )
+                          p_aout->output.output.i_rate ) )
         {
-            msg_Err( p_aout, "cannot open waveout audio device with output "
-                             "rate (44100)" );
+            msg_Err( p_aout, "cannot open waveout audio device" );
             return VLC_EGENERIC;
         }
-        p_aout->output.output.i_rate = 44100;
     }
 
     waveOutReset( p_aout->output.p_sys->h_waveout );
 
     /* Calculate the frame size in bytes */
-    p_aout->output.p_sys->i_buffer_size = FRAME_SIZE * sizeof(s16)
-                                  * p_aout->output.p_sys->waveformat.nChannels;
+    p_aout->output.i_nb_samples = FRAME_SIZE;
+    aout_FormatPrepare( &p_aout->output.output );
+    p_aout->output.p_sys->i_buffer_size = FRAME_SIZE *
+                                      p_aout->output.output.i_bytes_per_frame;
     /* Allocate silence buffer */
     p_aout->output.p_sys->p_silence_buffer =
         calloc( p_aout->output.p_sys->i_buffer_size, 1 );
@@ -148,20 +154,13 @@ static int Open( vlc_object_t *p_this )
         return 1;
     }
 
-    p_aout->output.output.i_format = AOUT_FMT_S16_NE;
-    p_aout->output.i_nb_samples = FRAME_SIZE;
-
     /* We need to kick off the playback in order to have the callback properly
      * working */
-    PlayWaveOut( p_aout, p_aout->output.p_sys->h_waveout,
-                 &p_aout->output.p_sys->waveheader[0], NULL );
-
-    p_buffer = aout_OutputNextBuffer( p_aout,
-        mdate() + 1000000 / p_aout->output.output.i_rate * FRAME_SIZE,
-        VLC_FALSE );
-    PlayWaveOut( p_aout, p_aout->output.p_sys->h_waveout,
-                 &p_aout->output.p_sys->waveheader[1], p_buffer );
-
+    for( i = 0; i < FRAMES_NUM; i++ )
+    {
+        PlayWaveOut( p_aout, p_aout->output.p_sys->h_waveout,
+                     &p_aout->output.p_sys->waveheader[i], NULL );
+    }
     return 0;
 }
 
@@ -183,7 +182,16 @@ static void Close( vlc_object_t *p_this )
     aout_instance_t *p_aout = (aout_instance_t *)p_this;
 
     /* Before calling waveOutClose we must reset the device */
-    waveOutReset( p_aout->output.p_sys->h_waveout );
+    p_aout->b_die = VLC_TRUE;
+    //Hmmm, waveOutReset never seems to return... why ???
+    //waveOutReset( p_aout->output.p_sys->h_waveout );
+
+    /* Wait for the waveout buffers to be freed */
+    while( !(p_aout->output.p_sys->waveheader[0].dwFlags & WHDR_DONE) || 
+           !(p_aout->output.p_sys->waveheader[1].dwFlags & WHDR_DONE) )
+    {
+        msleep( 1000 );
+    }
 
     /* Close the device */
     if( waveOutClose( p_aout->output.p_sys->h_waveout ) != MMSYSERR_NOERROR )
@@ -209,7 +217,17 @@ static int OpenWaveOut( aout_instance_t *p_aout, int i_format,
     p_aout->output.p_sys->waveformat.wFormatTag = i_format;
     p_aout->output.p_sys->waveformat.nChannels = i_channels;
     p_aout->output.p_sys->waveformat.nSamplesPerSec = i_rate;
-    p_aout->output.p_sys->waveformat.wBitsPerSample = 16;
+
+    switch( i_format )
+    {
+    case WAVE_FORMAT_PCM:
+        p_aout->output.p_sys->waveformat.wBitsPerSample = 16;
+        break;
+    case WAVE_FORMAT_IEEE_FLOAT:
+        p_aout->output.p_sys->waveformat.wBitsPerSample = sizeof(float) * 8;
+        break;
+    }
+
     p_aout->output.p_sys->waveformat.nBlockAlign =
         p_aout->output.p_sys->waveformat.wBitsPerSample / 8 * i_channels;
     p_aout->output.p_sys->waveformat.nAvgBytesPerSec  =
@@ -290,7 +308,9 @@ static void CALLBACK WaveOutCallback( HWAVEOUT h_waveout, UINT uMsg,
     if( p_waveheader->dwUser )
         aout_BufferFree( (aout_buffer_t *)p_waveheader->dwUser );
 
-    /* Take into account WaveOut latency instead of just mdate() */
+    if( p_aout->b_die ) return;
+
+    /* Take into account WaveOut latency ( 1 FRAME ) */
     p_buffer = aout_OutputNextBuffer( p_aout,
         mdate() + 1000000 / p_aout->output.output.i_rate * FRAME_SIZE,
         VLC_FALSE );