]> git.sesse.net Git - vlc/commitdiff
. all plugins now compile with -fPIC.
authorSam Hocevar <sam@videolan.org>
Sun, 7 Jan 2001 16:17:59 +0000 (16:17 +0000)
committerSam Hocevar <sam@videolan.org>
Sun, 7 Jan 2001 16:17:59 +0000 (16:17 +0000)
 . made the audio_output API a bit simpler.

 . got rid of modules_config.h.

 . fixed `make install' rule.

 . fixed warnings in the MMX YUV compilation.

 . probably fixed a bug in the input : pp_foo structures were free()d at
   the end, but this was useless since the last call to realloc() is
   equivalent to free(), and two consecutive calls to free() aren't a
   goo idea.

 . we check that the version number match and that we don't already have
   a module by that name when loading a new module.

 . all public module_* functions now properly lock the module bank.

 . the audio_output now uses the new module API ; EsounD and DSP modules
   have been ported, which should be enough for Henri to port the ALSA one.

   The new plugin API is now much simpler ; it's now just a matter of
calling module_Need( p_main->p_module_bank, MODULE_CAPABILITY_FOO, p_data );
and if successful we get the best module. Capabilities can be ORed, so that
one can ask for a plugin that does VOUT _and_ INTF actions for instance.

   It's not complete yet though -- by making it generic I had to do a few
ugly casts here and there, which I am going to fix ASAP. Also, command line
selection of a plugin does not work yet.

   The switch to the new plugin API has probably broken the BeOS audio
output ; we can either wait until the whole vlc has switched to the new
plugins, or create a separate beos_sound.so that conforms to the new API.

20 files changed:
Makefile.in
debian/rules
include/audio_output.h
include/modules.h
include/modules_config.h [deleted file]
plugins/alsa/alsa.c
plugins/alsa/aout_alsa.c
plugins/beos/aout_beos.cpp
plugins/beos/beos.cpp
plugins/dsp/aout_dsp.c
plugins/dsp/dsp.c
plugins/dummy/aout_dummy.c
plugins/dummy/dummy.c
plugins/esd/aout_esd.c
plugins/esd/esd.c
plugins/null/null.c
plugins/yuvmmx/video_yuv_asm.h
src/audio_output/audio_output.c
src/input/input_programs.c
src/misc/modules.c

index 2840b88389543ced379c22b7c4e72452c3203ad4..d09d19f86f85b7f87b3a59bebbab50f6879a00d4 100644 (file)
@@ -150,9 +150,7 @@ endif
 #
 # C compiler flags: plugin compilation
 #
-ifneq (,$(findstring solaris,$(SYS)))
 PCFLAGS += -fPIC
-endif
 
 #
 # C compiler flags: dependancies
@@ -407,9 +405,9 @@ install:
        mkdir -p $(prefix)/bin
        $(INSTALL) vlc $(prefix)/bin
 # ugly
-       for alias in "" @ALIASES@ ; do if test $$alias ; then ln -s vlc $(prefix)/bin/$$alias ; fi ; done
+       for alias in "" @ALIASES@ ; do if test $$alias ; then rm -f $(prefix)/bin/$$alias && ln -s vlc $(prefix)/bin/$$alias ; fi ; done
        mkdir -p $(prefix)/lib/videolan/vlc
-       $(INSTALL) -m 644 $(PLUGINS) $(prefix)/lib/videolan/vlc
+       $(INSTALL) -m 644 $(PLUGINS:%=lib/%.so) $(prefix)/lib/videolan/vlc
        mkdir -p $(prefix)/share/videolan
        $(INSTALL) -m 644 share/*.psf $(prefix)/share/videolan
        $(INSTALL) -m 644 share/*.png $(prefix)/share/videolan
@@ -478,11 +476,11 @@ $(STD_PLUGIN_OBJ): %.o: %.c
 
 $(PLUGIN_GNOME): %.o: Makefile.dep
 $(PLUGIN_GNOME): %.o: %.c
-       $(CC) $(CFLAGS) `gnome-config --cflags gnomeui` -c -o $@ $<
+       $(CC) $(CFLAGS) $(PCFLAGS) `gnome-config --cflags gnomeui` -c -o $@ $<
 
 $(PLUGIN_GLIDE): %.o: Makefile.dep
 $(PLUGIN_GLIDE): %.o: %.c
-       $(CC) $(CFLAGS) -I/usr/include/glide -c -o $@ $<
+       $(CC) $(CFLAGS) $(PCFLAGS) -I/usr/include/glide -c -o $@ $<
 
 #
 # Real targets
@@ -501,56 +499,56 @@ lib/beos.so: $(PLUGIN_BEOS)
 
 lib/esd.so: $(PLUGIN_ESD)
 ifneq (,$(findstring bsd,$(SYS)))
-       $(CC) $(LCFLAGS) -shared -lesd -o $@ $^
+       $(CC) -shared -lesd -o $@ $^ $(LCFLAGS) -lesd
 else
-       $(CC) $(LCFLAGS) -shared -laudiofile -lesd -o $@ $^
+       $(CC) -shared -o $@ $^ $(LCFLAGS) -laudiofile -lesd
 endif
 
 lib/dsp.so: $(PLUGIN_DSP)
-       $(CC) $(LCFLAGS) -shared -o $@ $^
+       $(CC) -shared -o $@ $^ $(LCFLAGS)
 
 lib/alsa.so: $(PLUGIN_ALSA)
-       $(CC) $(LCFLAGS) -shared -o $@ $^
+       $(CC) -shared -o $@ $^ $(LCFLAGS)
 
 lib/null.so: $(PLUGIN_NULL)
-       $(CC) $(LCFLAGS) -shared -o $@ $^
+       $(CC) -shared -o $@ $^ $(LCFLAGS)
 
 lib/dummy.so: $(PLUGIN_DUMMY)
-       $(CC) $(LCFLAGS) -shared -o $@ $^
+       $(CC) -shared -o $@ $^ $(LCFLAGS)
 
 lib/fb.so: $(PLUGIN_FB)
-       $(CC) $(LCFLAGS) -shared -o $@ $^
+       $(CC) -shared -o $@ $^ $(LCFLAGS)
 
 lib/x11.so: $(PLUGIN_X11)
-       $(CC) $(LCFLAGS) -shared -L/usr/X11R6/lib -lX11 -lXext -o $@ $^
+       $(CC) -shared -L/usr/X11R6/lib -o $@ $^ $(LCFLAGS) -lX11 -lXext
 
 lib/mga.so: $(PLUGIN_MGA)
-       $(CC) $(LCFLAGS) -shared -L/usr/X11R6/lib -lX11 -lXext -o $@ $^
+       $(CC) -shared -L/usr/X11R6/lib -o $@ $^ $(LCFLAGS) -lX11 -lXext
 
 lib/gnome.so: $(PLUGIN_GNOME)
-       $(CC) $(LCFLAGS) -shared `gnome-config --libs gnomeui | sed 's,-rdynamic,,'` -o $@ $^
+       $(CC) -shared -o $@ $^ $(LCFLAGS) `gnome-config --libs gnomeui | sed 's,-rdynamic,,'`
 
 lib/glide.so: $(PLUGIN_GLIDE)
-       $(CC) $(LCFLAGS) -shared $(LIB_GLIDE) -o $@ $^
+       $(CC) -shared $(LIB_GLIDE) -o $@ $^ $(LCFLAGS)
 
 lib/ggi.so: $(PLUGIN_GGI)
-       $(CC) $(LCFLAGS) -shared $(LIB_GGI) -o $@ $^
+       $(CC) -shared $(LIB_GGI) -o $@ $^ $(LCFLAGS)
 
 lib/sdl.so: $(PLUGIN_SDL)
-       $(CC) $(LCFLAGS) -shared $(LIB_SDL) -o $@ $^
+       $(CC) -shared $(LIB_SDL) -o $@ $^ $(LCFLAGS)
 
 lib/yuv.so: $(PLUGIN_YUV)
 ifeq ($(SYS),beos)
        $(CC) $(CFLAGS) -nostart -Xlinker -soname=$@ -o $@ $^ plugins/_APP_
 else
-       $(CC) $(LCFLAGS) -shared -o $@ $^
+       $(CC) -shared -o $@ $^ $(LCFLAGS)
 endif
 
 lib/yuvmmx.so: $(PLUGIN_YUVMMX)
 ifeq ($(SYS),beos)
        $(CC) $(CFLAGS) -nostart -Xlinker -soname=$@ -o $@ $^ plugins/_APP_
 else
-       $(CC) $(LCFLAGS) -shared -o $@ $^
+       $(CC) -shared -o $@ $^ $(LCFLAGS)
 endif
 
 ################################################################################
index cec54c570e14fe8a448d88afa1e1ac8704ac268e..8db01cd2932f151e1a70593df49598393c517802 100755 (executable)
@@ -6,7 +6,7 @@
 #export DH_VERBOSE=1
 
 # This is the debhelper compatability version to use.
-export DH_COMPAT=1
+export DH_COMPAT=3
 
 build: build-stamp
 build-stamp:
@@ -15,9 +15,9 @@ build-stamp:
        ./configure --prefix=/usr \
                --mandir=\$${prefix}/share/man \
                --infodir=\$${prefix}/share/info \
-               --enable-mmx --enable-gnome --enable-fb \
-               --enable-ggi --enable-esd --enable-glide \
-               --enable-sdl
+               --enable-gnome --enable-fb \
+               --with-ggi --enable-esd --with-glide \
+               --with-sdl
        $(MAKE)
 
        touch build-stamp
index acde929a4824fb574126ab82b1376a0598e3616b..31457b10f63aa8e6bdbd27dd08d47fa30b6d4ad4 100644 (file)
@@ -120,16 +120,13 @@ typedef struct
 /*****************************************************************************
  * aout_thread_t : audio output thread descriptor
  *****************************************************************************/
-typedef int  (aout_sys_open_t)           ( p_aout_thread_t p_aout );
-typedef int  (aout_sys_reset_t)          ( p_aout_thread_t p_aout );
-typedef int  (aout_sys_setformat_t)      ( p_aout_thread_t p_aout );
-typedef int  (aout_sys_setchannels_t)    ( p_aout_thread_t p_aout );
-typedef int  (aout_sys_setrate_t)        ( p_aout_thread_t p_aout );
-typedef long (aout_sys_getbufinfo_t)     ( p_aout_thread_t p_aout,
-                                           long l_buffer_limit );
-typedef void (aout_sys_playsamples_t)    ( p_aout_thread_t p_aout,
-                                           byte_t *buffer, int i_size );
-typedef void (aout_sys_close_t)          ( p_aout_thread_t p_aout );
+typedef int  (aout_open_t)       ( p_aout_thread_t p_aout );
+typedef int  (aout_setformat_t)  ( p_aout_thread_t p_aout );
+typedef long (aout_getbufinfo_t) ( p_aout_thread_t p_aout,
+                                   long l_buffer_limit );
+typedef void (aout_play_t)       ( p_aout_thread_t p_aout,
+                                   byte_t *buffer, int i_size );
+typedef void (aout_close_t)      ( p_aout_thread_t p_aout );
 
 typedef struct aout_thread_s
 {
@@ -140,15 +137,13 @@ typedef struct aout_thread_s
     vlc_mutex_t         fifos_lock;
     aout_fifo_t         fifo[ AOUT_MAX_FIFOS ];
 
-    /* Plugins */
-    aout_sys_open_t *           p_sys_open;
-    aout_sys_reset_t *          p_sys_reset;
-    aout_sys_setformat_t *      p_sys_setformat;
-    aout_sys_setchannels_t *    p_sys_setchannels;
-    aout_sys_setrate_t *        p_sys_setrate;
-    aout_sys_getbufinfo_t *     p_sys_getbufinfo;
-    aout_sys_playsamples_t *    p_sys_playsamples;
-    aout_sys_close_t *          p_sys_close;
+    /* Plugin used and shortcuts to access its capabilities */
+    struct module_s *   p_module;
+    aout_open_t *       p_open;
+    aout_setformat_t *  p_setformat;
+    aout_getbufinfo_t * p_getbufinfo;
+    aout_play_t *       p_play;
+    aout_close_t *      p_close;
 
     void *              buffer;
     /* The s32 buffer is used to mix all the audio fifos together before
index 6aadb7717b3b73bc038ec54c5c7a55c221587ec4..ab7aa8196ec14cf2a72deb3ec1e6f6b587aa6f11 100644 (file)
@@ -31,8 +31,90 @@ typedef void *  module_handle_t;
 #endif
 
 /*****************************************************************************
- * Configuration structure
+ * Module capabilities.
  *****************************************************************************/
+
+#define MODULE_CAPABILITY_NULL     0       /* The Module can't do anything */
+#define MODULE_CAPABILITY_INTF     1<<0    /* Interface */
+#define MODULE_CAPABILITY_INPUT    1<<1    /* Input */
+#define MODULE_CAPABILITY_DECAPS   1<<2    /* Decaps */
+#define MODULE_CAPABILITY_ADEC     1<<3    /* Audio decoder */
+#define MODULE_CAPABILITY_VDEC     1<<4    /* Video decoder */
+#define MODULE_CAPABILITY_AOUT     1<<5    /* Audio output */
+#define MODULE_CAPABILITY_VOUT     1<<6    /* Video output */
+#define MODULE_CAPABILITY_YUV      1<<7    /* YUV colorspace conversion */
+#define MODULE_CAPABILITY_AFX      1<<8    /* Audio effects */
+#define MODULE_CAPABILITY_VFX      1<<9    /* Video effects */
+
+/* FIXME: not yet used */
+typedef struct probedata_s
+{
+    struct
+    {
+        char * psz_data;
+    } aout;
+} probedata_t;
+
+/* FIXME: find a nicer way to do this. */
+typedef struct function_list_s
+{
+    int ( * p_probe ) ( probedata_t * p_data );
+
+    union
+    {
+        struct
+        {
+            int  ( * p_open )       ( struct aout_thread_s * p_aout );
+            int  ( * p_setformat )  ( struct aout_thread_s * p_aout );
+            long ( * p_getbufinfo ) ( struct aout_thread_s * p_aout,
+                                      long l_buffer_info );
+            void ( * p_play )       ( struct aout_thread_s * p_aout,
+                                      byte_t *buffer, int i_size );
+            void ( * p_close )      ( struct aout_thread_s * p_aout );
+       } aout;
+
+    } functions;
+
+} function_list_t;
+
+typedef struct module_functions_s
+{
+    /* The order here has to be the same as above for the #defines */
+    function_list_t intf;
+    function_list_t input;
+    function_list_t decaps;
+    function_list_t adec;
+    function_list_t vdec;
+    function_list_t aout;
+    function_list_t vout;
+    function_list_t yuv;
+    function_list_t afx;
+    function_list_t vfx;
+
+} module_functions_t;
+
+typedef struct module_functions_s * p_module_functions_t;
+
+/*****************************************************************************
+ * Macros used to build the configuration structure.
+ *****************************************************************************/
+
+/* Mandatory first and last parts of the structure */
+#define MODULE_CONFIG_ITEM_START       0x01    /* The main window */
+#define MODULE_CONFIG_ITEM_END         0x00    /* End of the window */
+
+/* Configuration widgets */
+#define MODULE_CONFIG_ITEM_PANE        0x02    /* A notebook pane */
+#define MODULE_CONFIG_ITEM_FRAME       0x03    /* A frame */
+#define MODULE_CONFIG_ITEM_COMMENT     0x04    /* A comment text */
+#define MODULE_CONFIG_ITEM_STRING      0x05    /* A string */
+#define MODULE_CONFIG_ITEM_FILE        0x06    /* A file selector */
+#define MODULE_CONFIG_ITEM_CHECK       0x07    /* A checkbox */
+#define MODULE_CONFIG_ITEM_CHOOSE      0x08    /* A choose box */
+#define MODULE_CONFIG_ITEM_RADIO       0x09    /* A radio box */
+#define MODULE_CONFIG_ITEM_SCALE       0x0a    /* A horizontal ruler */
+#define MODULE_CONFIG_ITEM_SPIN        0x0b    /* A numerical selector */
+
 typedef struct module_config_s
 {
     int         i_type;                         /* Configuration widget type */
@@ -46,7 +128,16 @@ typedef struct module_config_s
  * Bank and module description structures
  *****************************************************************************/
 
-/* The main module structure */
+/* The module bank structure */
+typedef struct module_bank_s
+{
+    struct module_s *   first; /* First module of the bank */
+
+    vlc_mutex_t         lock;  /* Global lock -- you can't imagine how awful it
+                                  is to design thread-safe linked lists. */
+} module_bank_t;
+
+/* The module description structure */
 typedef struct module_s
 {
     boolean_t           b_builtin;  /* Set to true if the module is built in */
@@ -64,20 +155,12 @@ typedef struct module_s
     struct module_s *   next;                                 /* Next module */
     struct module_s *   prev;                             /* Previous module */
 
-    u32                 i_capabilities;                   /* Capability list */
-
     module_config_t *   p_config;    /* Module configuration structure table */
 
-} module_t;
+    u32                     i_capabilities;               /* Capability list */
+    p_module_functions_t    p_functions;             /* Capability functions */
 
-/* The module bank structure */
-typedef struct module_bank_s
-{
-    module_t *          first; /* First module of the bank */
-
-    vlc_mutex_t         lock;  /* Global lock -- you can't imagine how awful it
-                                  is to design thread-safe linked lists. */
-} module_bank_t;
+} module_t;
 
 /*****************************************************************************
  * Exported functions.
@@ -88,6 +171,8 @@ void            module_DestroyBank  ( module_bank_t * p_bank );
 void            module_ResetBank    ( module_bank_t * p_bank );
 void            module_ManageBank   ( module_bank_t * p_bank );
 
-int module_Need    ( module_t * p_module );
-int module_Unneed  ( module_t * p_module );
+module_t *      module_Need         ( module_bank_t *p_bank,
+                                      int i_capabilities, void *p_data );
+void            module_Unneed       ( module_bank_t * p_bank,
+                                      module_t * p_module );
 
diff --git a/include/modules_config.h b/include/modules_config.h
deleted file mode 100644 (file)
index 7a3a527..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*****************************************************************************
- * modules_config.h : Module configuration tools.
- *****************************************************************************
- * Copyright (C) 2001 VideoLAN
- *
- * Authors: Samuel Hocevar <sam@zoy.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
- *****************************************************************************/
-
-/*****************************************************************************
- * Module capabilities.
- *****************************************************************************/
-#define MODULE_CAPABILITY_NULL     0       /* The Module can't do anything */
-#define MODULE_CAPABILITY_INTF     1<<0    /* Interface */
-#define MODULE_CAPABILITY_INPUT    1<<1    /* Input */
-#define MODULE_CAPABILITY_DECAPS   1<<2    /* Decaps */
-#define MODULE_CAPABILITY_ADEC     1<<3    /* Audio decoder */
-#define MODULE_CAPABILITY_VDEC     1<<4    /* Video decoder */
-#define MODULE_CAPABILITY_AOUT     1<<5    /* Audio output */
-#define MODULE_CAPABILITY_VOUT     1<<6    /* Video output */
-#define MODULE_CAPABILITY_YUV      1<<7    /* YUV colorspace conversion */
-#define MODULE_CAPABILITY_AFX      1<<8    /* Audio effects */
-#define MODULE_CAPABILITY_VFX      1<<9    /* Video effects */
-
-/*****************************************************************************
- * Macros used to build the configuration structure.
- *****************************************************************************/
-
-/* Mandatory first and last parts of the structure */
-#define MODULE_CONFIG_ITEM_START       0x01    /* The main window */
-#define MODULE_CONFIG_ITEM_END         0x00    /* End of the window */
-
-/* Configuration widgets */
-#define MODULE_CONFIG_ITEM_PANE        0x02    /* A notebook pane */
-#define MODULE_CONFIG_ITEM_FRAME       0x03    /* A frame */
-#define MODULE_CONFIG_ITEM_COMMENT     0x04    /* A comment text */
-#define MODULE_CONFIG_ITEM_STRING      0x05    /* A string */
-#define MODULE_CONFIG_ITEM_FILE        0x06    /* A file selector */
-#define MODULE_CONFIG_ITEM_CHECK       0x07    /* A checkbox */
-#define MODULE_CONFIG_ITEM_CHOOSE      0x08    /* A choose box */
-#define MODULE_CONFIG_ITEM_RADIO       0x09    /* A radio box */
-#define MODULE_CONFIG_ITEM_SCALE       0x0a    /* A horizontal ruler */
-#define MODULE_CONFIG_ITEM_SPIN        0x0b    /* A numerical selector */
-
index 0ddf1c5c86a62addeaedc7b54dc0d09a08d727de..e83a79d53ae69ab8a60be7b865989bb25f447b12 100644 (file)
@@ -52,12 +52,9 @@ static void aout_GetPlugin( p_aout_thread_t p_aout );
 
 /* Audio output */
 int     aout_AlsaOpen         ( aout_thread_t *p_aout );
-int     aout_AlsaReset        ( aout_thread_t *p_aout );
 int     aout_AlsaSetFormat    ( aout_thread_t *p_aout );
-int     aout_AlsaSetChannels  ( aout_thread_t *p_aout );
-int     aout_AlsaSetRate      ( aout_thread_t *p_aout );
 long    aout_AlsaGetBufInfo   ( aout_thread_t *p_aout, long l_buffer_info );
-void    aout_AlsaPlaySamples  ( aout_thread_t *p_aout, byte_t *buffer,
+void    aout_AlsaPlay         ( aout_thread_t *p_aout, byte_t *buffer,
                                int i_size );
 void    aout_AlsaClose        ( aout_thread_t *p_aout );
 
@@ -96,12 +93,9 @@ plugin_info_t * GetConfig( void )
 
 static void aout_GetPlugin( p_aout_thread_t p_aout )
 {
-    p_aout->p_sys_open        = aout_AlsaOpen;
-    p_aout->p_sys_reset       = aout_AlsaReset;
-    p_aout->p_sys_setformat   = aout_AlsaSetFormat;
-    p_aout->p_sys_setchannels = aout_AlsaSetChannels;
-    p_aout->p_sys_setrate     = aout_AlsaSetRate;
-    p_aout->p_sys_getbufinfo  = aout_AlsaGetBufInfo;
-    p_aout->p_sys_playsamples = aout_AlsaPlaySamples;
-    p_aout->p_sys_close       = aout_AlsaClose;
+    p_aout->p_open        = aout_AlsaOpen;
+    p_aout->p_setformat   = aout_AlsaSetFormat;
+    p_aout->p_getbufinfo  = aout_AlsaGetBufInfo;
+    p_aout->p_play        = aout_AlsaPlay;
+    p_aout->p_close       = aout_AlsaClose;
 }
index 7436e49189badcc7e83c76d61ecbd92b5e432645..019601667d4852952e25bf63e92f5bf6ab634108 100644 (file)
@@ -204,39 +204,6 @@ int aout_AlsaSetFormat ( aout_thread_t *p_aout )
     return ( 0 );
 }
 
-/*****************************************************************************
- * aout_AlsaReset: resets the dsp
- *****************************************************************************/
-int aout_AlsaReset ( aout_thread_t *p_aout )
-{
-    /* TODO : put something in here, such as close and open again 
-     * or check status, drain, flush, .... */ 
-    return ( 0 );
-}
-
-/*****************************************************************************
- * aout_AlsaSetChannels: sets mono, stereo and other modes
- *****************************************************************************/
-int aout_AlsaSetChannels ( aout_thread_t *p_aout )
-{
-    /* TODO : normally, nothing
-     * everything should be done in the AlsaSetFormat, as far a I understand
-     * the alsa documentation
-     */
-    return ( 0 );
-}
-
-/*****************************************************************************
- * aout_AlsaSetRate: sets the audio output rate
- *****************************************************************************
- * As in the previous function, the rate is supposed to be set in the
- * AlsaSetFormat function
- *****************************************************************************/
-int aout_AlsaSetRate ( aout_thread_t *p_aout )
-{
-    return ( 0 );
-}
-
 /*****************************************************************************
  * aout_AlsaGetBufInfo: buffer status query
  *****************************************************************************/
@@ -286,9 +253,9 @@ long aout_AlsaGetBufInfo ( aout_thread_t *p_aout, long l_buffer_limit )
 }
 
 /*****************************************************************************
- * aout_AlsaPlaySamples
+ * aout_AlsaPlay
  *****************************************************************************/
-void aout_AlsaPlaySamples ( aout_thread_t *p_aout, byte_t *buffer, int i_size )
+void aout_AlsaPlay ( aout_thread_t *p_aout, byte_t *buffer, int i_size )
 {
     int i_write_returns;
 
index 347350f0b936489010f7a16026405662f3667cc3..b1d22457e787afd16de82e7f3b4d1fcef9bc775f 100644 (file)
@@ -2,7 +2,7 @@
  * aout_beos.cpp: beos interface
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: aout_beos.cpp,v 1.7 2001/01/05 18:46:43 massiot Exp $
+ * $Id: aout_beos.cpp,v 1.8 2001/01/07 16:17:58 sam Exp $
  *
  * Authors:
  * Samuel Hocevar <sam@via.ecp.fr>
@@ -135,13 +135,6 @@ int aout_BeOpen( aout_thread_t *p_aout )
 
     return( 0 );
 }
-/*****************************************************************************
- * aout_BeReset: resets the dsp
- *****************************************************************************/
-int aout_BeReset( aout_thread_t *p_aout )
-{
-    return( 0 );
-}
 
 /*****************************************************************************
  * aout_BeSetFormat: sets the dsp output format
@@ -151,22 +144,6 @@ int aout_BeSetFormat( aout_thread_t *p_aout )
     return( 0 );
 }
 
-/*****************************************************************************
- * aout_BeSetChannels: sets the dsp's stereo or mono mode
- *****************************************************************************/
-int aout_BeSetChannels( aout_thread_t *p_aout )
-{
-    return( 0 );
-}
-
-/*****************************************************************************
- * aout_BeSetRate: sets the dsp's audio output rate
- *****************************************************************************/
-int aout_BeSetRate( aout_thread_t *p_aout )
-{
-    return( 0 );
-}
-
 /*****************************************************************************
  * aout_BeGetBufInfo: buffer status query
  *****************************************************************************/
@@ -185,11 +162,11 @@ long aout_BeGetBufInfo( aout_thread_t *p_aout, long l_buffer_limit )
 }
 
 /*****************************************************************************
- * aout_BePlaySamples: plays a sound samples buffer
+ * aout_BePlay: plays a sound samples buffer
  *****************************************************************************
  * This function writes a buffer of i_length bytes in the dsp
  *****************************************************************************/
-void aout_BePlaySamples( aout_thread_t *p_aout, byte_t *buffer, int i_size )
+void aout_BePlay( aout_thread_t *p_aout, byte_t *buffer, int i_size )
 {
     long i_newbuf_pos;
 
index b86b2b55826a4766e1e478264033dafb874e872a..916e583dcf3143cab592c7ec55e76e9be1198c7c 100644 (file)
@@ -54,7 +54,7 @@ int     aout_BeSetFormat    ( aout_thread_t *p_aout );
 int     aout_BeSetChannels  ( aout_thread_t *p_aout );
 int     aout_BeSetRate      ( aout_thread_t *p_aout );
 long    aout_BeGetBufInfo   ( aout_thread_t *p_aout, long l_buffer_info );
-void    aout_BePlaySamples  ( aout_thread_t *p_aout, byte_t *buffer,
+void    aout_BePlay         ( aout_thread_t *p_aout, byte_t *buffer,
                               int i_size );
 void    aout_BeClose        ( aout_thread_t *p_aout );
 
@@ -102,14 +102,11 @@ plugin_info_t * GetConfig( void )
 
 static void aout_GetPlugin( p_aout_thread_t p_aout )
 {
-    p_aout->p_sys_open        = aout_BeOpen;
-    p_aout->p_sys_reset       = aout_BeReset;
-    p_aout->p_sys_setformat   = aout_BeSetFormat;
-    p_aout->p_sys_setchannels = aout_BeSetChannels;
-    p_aout->p_sys_setrate     = aout_BeSetRate;
-    p_aout->p_sys_getbufinfo  = aout_BeGetBufInfo;
-    p_aout->p_sys_playsamples = aout_BePlaySamples;
-    p_aout->p_sys_close       = aout_BeClose;
+    p_aout->p_open        = aout_BeOpen;
+    p_aout->p_setformat   = aout_BeSetFormat;
+    p_aout->p_getbufinfo  = aout_BeGetBufInfo;
+    p_aout->p_play        = aout_BePlay;
+    p_aout->p_close       = aout_BeClose;
 }
 
 static void vout_GetPlugin( p_vout_thread_t p_vout )
index 128843a783207b66116e853e1d66f635589f4e6e..5e25f58f43868d32316af938e4b9c30e732ec957 100644 (file)
@@ -3,7 +3,8 @@
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
  *
- * Authors:
+ * Authors: Michel Kaempf <maxx@via.ecp.fr>
+ *          Samuel Hocevar <sam@zoy.org>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 
 /* TODO:
  *
- * - an aout_DspGetFormats() function
+ * - an aout_GetFormats() function
  * - dsp inline/static
  * - make this library portable (see mpg123)
- * - macroify aout_DspPlaySamples &/| aout_DspGetBufInfo ?
  *
  */
 
 #include "intf_msg.h"                        /* intf_DbgMsg(), intf_ErrMsg() */
 #include "main.h"
 
+#include "modules.h"
+
 /*****************************************************************************
- * vout_dsp_t: dsp audio output method descriptor
+ * aout_sys_t: dsp audio output method descriptor
  *****************************************************************************
  * This structure is part of the audio output thread descriptor.
  * It describes the dsp specific properties of an audio device.
@@ -74,31 +76,82 @@ typedef struct aout_sys_s
 } aout_sys_t;
 
 /*****************************************************************************
- * aout_DspOpen: opens the audio device (the digital sound processor)
+ * Local prototypes.
+ *****************************************************************************/
+static int     aout_Probe       ( probedata_t *p_data );
+static int     aout_Open        ( aout_thread_t *p_aout );
+static int     aout_SetFormat   ( aout_thread_t *p_aout );
+static long    aout_GetBufInfo  ( aout_thread_t *p_aout, long l_buffer_info );
+static void    aout_Play        ( aout_thread_t *p_aout,
+                                  byte_t *buffer, int i_size );
+static void    aout_Close       ( aout_thread_t *p_aout );
+
+/*****************************************************************************
+ * Functions exported as capabilities. They are declared as static so that
+ * we don't pollute the namespace too much.
+ *****************************************************************************/
+void dsp_aout_getfunctions( function_list_t * p_function_list )
+{
+    p_function_list->p_probe = aout_Probe;
+    p_function_list->functions.aout.p_open = aout_Open;
+    p_function_list->functions.aout.p_setformat = aout_SetFormat;
+    p_function_list->functions.aout.p_getbufinfo = aout_GetBufInfo;
+    p_function_list->functions.aout.p_play = aout_Play;
+    p_function_list->functions.aout.p_close = aout_Close;
+}
+
+/*****************************************************************************
+ * aout_Probe: probes the audio device and return a score
+ *****************************************************************************
+ * This function tries to open the dps and returns a score to the plugin
+ * manager so that it can 
+ *****************************************************************************/
+static int aout_Probe( probedata_t *p_data )
+{
+    char * psz_device = main_GetPszVariable( AOUT_DSP_VAR, AOUT_DSP_DEFAULT );
+    int i_fd = open( psz_device, O_WRONLY|O_NONBLOCK );
+
+    /* If we were unable to open the device, there is no way we can use
+     * the plugin. Return a score of 0. */
+    if( i_fd < 0 )
+    {
+        return( 0 );
+    }
+
+    /* Otherwise, there are good chances we can use this plugin, return 100. */
+    close( i_fd );
+    return( 100 );
+}
+
+/*****************************************************************************
+ * aout_Open: opens the audio device (the digital sound processor)
  *****************************************************************************
- * - This function opens the dsp as an usual non-blocking write-only file, and
- *   modifies the p_aout->p_sys->i_fd with the file's descriptor.
+ * This function opens the dsp as a usual non-blocking write-only file, and
+ * modifies the p_aout->i_fd with the file's descriptor.
  *****************************************************************************/
-int aout_DspOpen( aout_thread_t *p_aout )
+static int aout_Open( aout_thread_t *p_aout )
 {
     /* Allocate structure */
     p_aout->p_sys = malloc( sizeof( aout_sys_t ) );
     if( p_aout->p_sys == NULL )
     {
-        intf_ErrMsg("error: %s", strerror(ENOMEM) );
+        intf_ErrMsg("aout error: %s", strerror(ENOMEM) );
         return( 1 );
     }
 
     /* Initialize some variables */
-    p_aout->i_format = AOUT_FORMAT_DEFAULT;
     p_aout->psz_device = main_GetPszVariable( AOUT_DSP_VAR, AOUT_DSP_DEFAULT );
-    p_aout->i_channels = 1 + main_GetIntVariable( AOUT_STEREO_VAR, AOUT_STEREO_DEFAULT );
-    p_aout->l_rate     = main_GetIntVariable( AOUT_RATE_VAR, AOUT_RATE_DEFAULT );
+    p_aout->i_format   = AOUT_FORMAT_DEFAULT;
+    p_aout->i_channels = 1 + main_GetIntVariable( AOUT_STEREO_VAR,
+                                                  AOUT_STEREO_DEFAULT );
+    p_aout->l_rate     = main_GetIntVariable( AOUT_RATE_VAR,
+                                              AOUT_RATE_DEFAULT );
 
     /* Open the sound device */
-    if ( (p_aout->i_fd = open( p_aout->psz_device, O_WRONLY|O_NONBLOCK )) < 0 )
+    if( (p_aout->i_fd = open( p_aout->psz_device, O_WRONLY|O_NONBLOCK )) < 0 )
     {
-        intf_ErrMsg( "aout error: can't open audio device (%s)", p_aout->psz_device );
+        intf_ErrMsg( "aout error: can't open audio device (%s)",
+                     p_aout->psz_device );
         return( -1 );
     }
 
@@ -106,92 +159,72 @@ int aout_DspOpen( aout_thread_t *p_aout )
 }
 
 /*****************************************************************************
- * aout_DspReset: resets the dsp
- *****************************************************************************/
-int aout_DspReset( aout_thread_t *p_aout )
-{
-    if ( ioctl( p_aout->i_fd, SNDCTL_DSP_RESET, NULL ) < 0 )
-    {
-        intf_ErrMsg( "aout error: can't reset audio device (%s)", p_aout->psz_device );
-    return( -1 );
-    }
-
-    return( 0 );
-}
-
-/*****************************************************************************
- * aout_DspSetFormat: sets the dsp output format
+ * aout_SetFormat: resets the dsp and sets its format
  *****************************************************************************
- * This functions tries to initialize the dsp output format with the value
- * contained in the dsp structure, and if this value could not be set, the
- * default value returned by ioctl is set.
+ * This functions resets the DSP device, tries to initialize the output
+ * format with the value contained in the dsp structure, and if this value
+ * could not be set, the default value returned by ioctl is set. It then
+ * does the same for the stereo mode, and for the output rate.
  *****************************************************************************/
-int aout_DspSetFormat( aout_thread_t *p_aout )
+static int aout_SetFormat( aout_thread_t *p_aout )
 {
     int i_format;
+    long l_rate;
+    boolean_t b_stereo = p_aout->b_stereo;
 
+    /* Reset the DSP device */
+    if( ioctl( p_aout->i_fd, SNDCTL_DSP_RESET, NULL ) < 0 )
+    {
+        intf_ErrMsg( "aout error: can't reset audio device (%s)",
+                     p_aout->psz_device );
+        return( -1 );
+    }
+
+    /* Set the output format */
     i_format = p_aout->i_format;
-    if ( ioctl( p_aout->i_fd, SNDCTL_DSP_SETFMT, &i_format ) < 0 )
+    if( ioctl( p_aout->i_fd, SNDCTL_DSP_SETFMT, &i_format ) < 0 )
     {
-        intf_ErrMsg( "aout error: can't set audio output format (%i)", p_aout->i_format );
+        intf_ErrMsg( "aout error: can't set audio output format (%i)",
+                     p_aout->i_format );
         return( -1 );
     }
 
-    if ( i_format != p_aout->i_format )
+    if( i_format != p_aout->i_format )
     {
-        intf_DbgMsg( "aout debug: audio output format not supported (%i)", p_aout->i_format );
+        intf_DbgMsg( "aout debug: audio output format not supported (%i)",
+                     p_aout->i_format );
         p_aout->i_format = i_format;
     }
 
-    return( 0 );
-}
-
-/*****************************************************************************
- * aout_DspSetChannels: sets the dsp's stereo or mono mode
- *****************************************************************************
- * This function acts just like the previous one...
- *****************************************************************************/
-int aout_DspSetChannels( aout_thread_t *p_aout )
-{
-    boolean_t b_stereo = p_aout->b_stereo;
-
-    if ( ioctl( p_aout->i_fd, SNDCTL_DSP_STEREO, &b_stereo ) < 0 )
+    /* Set the number of channels */
+    if( ioctl( p_aout->i_fd, SNDCTL_DSP_STEREO, &b_stereo ) < 0 )
     {
-        intf_ErrMsg( "aout error: can't set number of audio channels (%i)", p_aout->i_channels );
+        intf_ErrMsg( "aout error: can't set number of audio channels (%i)",
+                     p_aout->i_channels );
         return( -1 );
     }
 
-    if ( b_stereo != p_aout->b_stereo )
+    if( b_stereo != p_aout->b_stereo )
     {
-        intf_DbgMsg( "aout debug: number of audio channels not supported (%i)", p_aout->i_channels );
+        intf_DbgMsg( "aout debug: number of audio channels not supported (%i)",
+                     p_aout->i_channels );
         p_aout->b_stereo = b_stereo;
         p_aout->i_channels = 1 + b_stereo;
     }
 
-    return( 0 );
-}
-
-/*****************************************************************************
- * aout_DspSetRate: sets the dsp's audio output rate
- *****************************************************************************
- * This function tries to initialize the dsp with the rate contained in the
- * dsp structure, but if the dsp doesn't support this value, the function uses
- * the value returned by ioctl...
- *****************************************************************************/
-int aout_DspSetRate( aout_thread_t *p_aout )
-{
-    long l_rate;
-
+    /* Set the output rate */
     l_rate = p_aout->l_rate;
-    if ( ioctl( p_aout->i_fd, SNDCTL_DSP_SPEED, &l_rate ) < 0 )
+    if( ioctl( p_aout->i_fd, SNDCTL_DSP_SPEED, &l_rate ) < 0 )
     {
-        intf_ErrMsg( "aout error: can't set audio output rate (%li)", p_aout->l_rate );
+        intf_ErrMsg( "aout error: can't set audio output rate (%li)",
+                     p_aout->l_rate );
         return( -1 );
     }
 
-    if ( l_rate != p_aout->l_rate )
+    if( l_rate != p_aout->l_rate )
     {
-        intf_DbgMsg( "aout debug: audio output rate not supported (%li)", p_aout->l_rate );
+        intf_DbgMsg( "aout debug: audio output rate not supported (%li)",
+                     p_aout->l_rate );
         p_aout->l_rate = l_rate;
     }
 
@@ -199,7 +232,7 @@ int aout_DspSetRate( aout_thread_t *p_aout )
 }
 
 /*****************************************************************************
- * aout_DspGetBufInfo: buffer status query
+ * aout_GetBufInfo: buffer status query
  *****************************************************************************
  * This function fills in the audio_buf_info structure :
  * - int fragments : number of available fragments (partially usend ones not
@@ -209,7 +242,7 @@ int aout_DspSetRate( aout_thread_t *p_aout )
  * - int bytes : available space in bytes (includes partially used fragments)
  * Note! 'bytes' could be more than fragments*fragsize
  *****************************************************************************/
-long aout_DspGetBufInfo( aout_thread_t *p_aout, long l_buffer_limit )
+static long aout_GetBufInfo( aout_thread_t *p_aout, long l_buffer_limit )
 {
     ioctl( p_aout->i_fd, SNDCTL_DSP_GETOSPACE, &p_aout->p_sys->audio_buf );
 
@@ -220,11 +253,11 @@ long aout_DspGetBufInfo( aout_thread_t *p_aout, long l_buffer_limit )
 }
 
 /*****************************************************************************
- * aout_DspPlaySamples: plays a sound samples buffer
+ * aout_Play: plays a sound samples buffer
  *****************************************************************************
  * This function writes a buffer of i_length bytes in the dsp
  *****************************************************************************/
-void aout_DspPlaySamples( aout_thread_t *p_aout, byte_t *buffer, int i_size )
+static void aout_Play( aout_thread_t *p_aout, byte_t *buffer, int i_size )
 {
     if( p_aout->b_active )
     {
@@ -233,9 +266,9 @@ void aout_DspPlaySamples( aout_thread_t *p_aout, byte_t *buffer, int i_size )
 }
 
 /*****************************************************************************
- * aout_DspClose: closes the dsp audio device
+ * aout_Close: closes the dsp audio device
  *****************************************************************************/
-void aout_DspClose( aout_thread_t *p_aout )
+static void aout_Close( aout_thread_t *p_aout )
 {
     close( p_aout->i_fd );
 }
index 42591162d8d726573cdff483dd4d3030e5308846..709a9fcaf11465afb2d545c1c4ceab2a9ae759cb 100644 (file)
@@ -1,9 +1,10 @@
 /*****************************************************************************
- * dsp.c : OSS /dev/dsp plugin for vlc
+ * dsp.c : OSS /dev/dsp module for vlc
  *****************************************************************************
  * Copyright (C) 2000 VideoLAN
  *
- * Authors:
+ * Authors: Michel Kaempf <maxx@via.ecp.fr>
+ *          Samuel Hocevar <sam@zoy.org>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  *****************************************************************************/
 
+#define MODULE_NAME dsp
+
 /*****************************************************************************
  * Preamble
  *****************************************************************************/
 #include "defs.h"
 
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
 #include <stdlib.h>                                      /* malloc(), free() */
-#include <unistd.h>                                               /* close() */
+#include <string.h>                                              /* strdup() */
 
 #include "config.h"
 #include "common.h"                                     /* boolean_t, byte_t */
 #include "threads.h"
 #include "mtime.h"
 #include "tests.h"
-#include "plugins.h"
 
-#include "interface.h"
-#include "audio_output.h"
-#include "video.h"
-#include "video_output.h"
+#include "modules.h"
+#include "modules_inner.h"
 
-#include "main.h"
+/*****************************************************************************
+ * Build configuration tree.
+ *****************************************************************************/
+MODULE_CONFIG_START( "Configuration for dsp module" )
+    ADD_FRAME( "OSS Device" )
+        ADD_FILE( "Device name: ", MODULE_VAR(device), NULL )
+MODULE_CONFIG_END
 
 /*****************************************************************************
- * Exported prototypes
+ * Capabilities defined in the other files.
  *****************************************************************************/
-static void aout_GetPlugin( p_aout_thread_t p_aout );
-
-/* Audio output */
-int     aout_DspOpen         ( aout_thread_t *p_aout );
-int     aout_DspReset        ( aout_thread_t *p_aout );
-int     aout_DspSetFormat    ( aout_thread_t *p_aout );
-int     aout_DspSetChannels  ( aout_thread_t *p_aout );
-int     aout_DspSetRate      ( aout_thread_t *p_aout );
-long    aout_DspGetBufInfo   ( aout_thread_t *p_aout, long l_buffer_info );
-void    aout_DspPlaySamples  ( aout_thread_t *p_aout, byte_t *buffer,
-                               int i_size );
-void    aout_DspClose        ( aout_thread_t *p_aout );
+void dsp_aout_getfunctions( function_list_t * p_function_list );
 
 /*****************************************************************************
- * GetConfig: get the plugin structure and configuration
+ * InitModule: get the module structure and configuration.
+ *****************************************************************************
+ * We have to fill psz_name, psz_longname and psz_version. These variables
+ * will be strdup()ed later by the main application because the module can
+ * be unloaded later to save memory, and we want to be able to access this
+ * data even after the module has been unloaded.
  *****************************************************************************/
-plugin_info_t * GetConfig( void )
+int InitModule( module_t * p_module )
 {
-    int i_fd;
-    plugin_info_t * p_info = (plugin_info_t *) malloc( sizeof(plugin_info_t) );
+    p_module->psz_name = MODULE_STRING;
+    p_module->psz_longname = "Linux OSS /dev/dsp module";
+    p_module->psz_version = VERSION;
 
-    p_info->psz_name    = "OSS /dev/dsp";
-    p_info->psz_version = VERSION;
-    p_info->psz_author  = "the VideoLAN team <vlc@videolan.org>";
+    p_module->i_capabilities = MODULE_CAPABILITY_NULL
+                                | MODULE_CAPABILITY_AOUT;
 
-    p_info->aout_GetPlugin = aout_GetPlugin;
-    p_info->vout_GetPlugin = NULL;
-    p_info->intf_GetPlugin = NULL;
-    p_info->yuv_GetPlugin  = NULL;
+    return( 0 );
+}
 
-    /* Test if the device can be opened */
-    if ( (i_fd = open( main_GetPszVariable( AOUT_DSP_VAR, AOUT_DSP_DEFAULT ),
-                       O_WRONLY|O_NONBLOCK )) < 0 )
-    {
-        p_info->i_score = 0;
-    }
-    else
+/*****************************************************************************
+ * ActivateModule: set the module to an usable state.
+ *****************************************************************************
+ * This function fills the capability functions and the configuration
+ * structure. Once ActivateModule() has been called, the i_usage can
+ * be set to 0 and calls to NeedModule() be made to increment it. To unload
+ * the module, one has to wait until i_usage == 0 and call DeactivateModule().
+ *****************************************************************************/
+int ActivateModule( module_t * p_module )
+{
+    p_module->p_functions = malloc( sizeof( module_functions_t ) );
+    if( p_module->p_functions == NULL )
     {
-        close( i_fd );
-        p_info->i_score = 0x100;
+        return( -1 );
     }
 
-    /* If this plugin was requested, score it higher */
-    if( TestMethod( AOUT_METHOD_VAR, "dsp" ) )
-    {
-        p_info->i_score += 0x200;
-    }
+    dsp_aout_getfunctions( &p_module->p_functions->aout );
 
-    return( p_info );
+    p_module->p_config = p_config;
+
+    return( 0 );
 }
 
 /*****************************************************************************
- * Following functions are only called through the p_info structure
+ * DeactivateModule: make sure the module can be unloaded.
+ *****************************************************************************
+ * This function must only be called when i_usage == 0. If it successfully
+ * returns, i_usage can be set to -1 and the module unloaded. Be careful to
+ * lock usage_lock during the whole process.
  *****************************************************************************/
-
-static void aout_GetPlugin( p_aout_thread_t p_aout )
+int DeactivateModule( module_t * p_module )
 {
-    p_aout->p_sys_open        = aout_DspOpen;
-    p_aout->p_sys_reset       = aout_DspReset;
-    p_aout->p_sys_setformat   = aout_DspSetFormat;
-    p_aout->p_sys_setchannels = aout_DspSetChannels;
-    p_aout->p_sys_setrate     = aout_DspSetRate;
-    p_aout->p_sys_getbufinfo  = aout_DspGetBufInfo;
-    p_aout->p_sys_playsamples = aout_DspPlaySamples;
-    p_aout->p_sys_close       = aout_DspClose;
+    free( p_module->p_functions );
+
+    return( 0 );
 }
 
index fb87e151c24c82949871dd91442bf275918aa3de..c35dbbaa1ceab31385058d9a5ab0b206bdeab8d6 100644 (file)
@@ -60,14 +60,6 @@ int aout_DummyOpen( aout_thread_t *p_aout )
     return( 0 );
 }
 
-/*****************************************************************************
- * aout_DummyReset: fake reset
- *****************************************************************************/
-int aout_DummyReset( aout_thread_t *p_aout )
-{
-    return( 0 );
-}
-
 /*****************************************************************************
  * aout_DummySetFormat: pretends to set the dsp output format
  *****************************************************************************/
@@ -76,22 +68,6 @@ int aout_DummySetFormat( aout_thread_t *p_aout )
     return( 0 );
 }
 
-/*****************************************************************************
- * aout_DummySetChannels: pretends to set stereo or mono mode
- *****************************************************************************/
-int aout_DummySetChannels( aout_thread_t *p_aout )
-{
-    return( 0 );
-}
-
-/*****************************************************************************
- * aout_DummySetRate: pretends to set audio output rate
- *****************************************************************************/
-int aout_DummySetRate( aout_thread_t *p_aout )
-{
-    return( 0 );
-}
-
 /*****************************************************************************
  * aout_DummyGetBufInfo: returns available bytes in buffer
  *****************************************************************************/
@@ -101,10 +77,11 @@ long aout_DummyGetBufInfo( aout_thread_t *p_aout, long l_buffer_limit )
 }
 
 /*****************************************************************************
- * aout_DummyPlaySamples: pretends to play a sound
+ * aout_DummyPlay: pretends to play a sound
  *****************************************************************************/
-void aout_DummyPlaySamples( aout_thread_t *p_aout, byte_t *buffer, int i_size )
+void aout_DummyPlay( aout_thread_t *p_aout, byte_t *buffer, int i_size )
 {
+    ;
 }
 
 /*****************************************************************************
index 6113b3e7df683d2bdd1d8fcd531bedb414278187..7ce2ed0fcccb246b852028f765208fc483b21e88 100644 (file)
@@ -48,12 +48,9 @@ static void intf_GetPlugin( p_intf_thread_t p_intf );
 
 /* Audio output */
 int     aout_DummyOpen         ( aout_thread_t *p_aout );
-int     aout_DummyReset        ( aout_thread_t *p_aout );
 int     aout_DummySetFormat    ( aout_thread_t *p_aout );
-int     aout_DummySetChannels  ( aout_thread_t *p_aout );
-int     aout_DummySetRate      ( aout_thread_t *p_aout );
 long    aout_DummyGetBufInfo   ( aout_thread_t *p_aout, long l_buffer_info );
-void    aout_DummyPlaySamples  ( aout_thread_t *p_aout, byte_t *buffer,
+void    aout_DummyPlay         ( aout_thread_t *p_aout, byte_t *buffer,
                                  int i_size );
 void    aout_DummyClose        ( aout_thread_t *p_aout );
 
@@ -114,14 +111,11 @@ plugin_info_t * GetConfig( void )
 
 static void aout_GetPlugin( p_aout_thread_t p_aout )
 {
-    p_aout->p_sys_open        = aout_DummyOpen;
-    p_aout->p_sys_reset       = aout_DummyReset;
-    p_aout->p_sys_setformat   = aout_DummySetFormat;
-    p_aout->p_sys_setchannels = aout_DummySetChannels;
-    p_aout->p_sys_setrate     = aout_DummySetRate;
-    p_aout->p_sys_getbufinfo  = aout_DummyGetBufInfo;
-    p_aout->p_sys_playsamples = aout_DummyPlaySamples;
-    p_aout->p_sys_close       = aout_DummyClose;
+    p_aout->p_open        = aout_DummyOpen;
+    p_aout->p_setformat   = aout_DummySetFormat;
+    p_aout->p_getbufinfo  = aout_DummyGetBufInfo;
+    p_aout->p_play        = aout_DummyPlay;
+    p_aout->p_close       = aout_DummyClose;
 }
 
 static void vout_GetPlugin( p_vout_thread_t p_vout )
index 29ca0b1a5ef7bca9d9e73fd775363ae9e5897bcc..10255e3e2f24605c003df7020f4f797399a8f972 100644 (file)
@@ -3,7 +3,7 @@
  *****************************************************************************
  * Copyright (C) 2000 VideoLAN
  *
- * Authors:
+ * Authors: Samuel Hocevar <sam@zoy.org>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -51,6 +51,8 @@
 #include "intf_msg.h"                        /* intf_DbgMsg(), intf_ErrMsg() */
 #include "main.h"
 
+#include "modules.h"
+
 /*****************************************************************************
  * aout_sys_t: esd audio output method descriptor
  *****************************************************************************
@@ -64,9 +66,47 @@ typedef struct aout_sys_s
 } aout_sys_t;
 
 /*****************************************************************************
- * aout_EsdOpen: opens an esd socket
+ * Local prototypes.
  *****************************************************************************/
-int aout_EsdOpen( aout_thread_t *p_aout )
+static int     aout_Probe       ( probedata_t *p_data );
+static int     aout_Open        ( aout_thread_t *p_aout );
+static int     aout_SetFormat   ( aout_thread_t *p_aout );
+static long    aout_GetBufInfo  ( aout_thread_t *p_aout, long l_buffer_info );
+static void    aout_Play        ( aout_thread_t *p_aout,
+                                  byte_t *buffer, int i_size );
+static void    aout_Close       ( aout_thread_t *p_aout );
+
+/*****************************************************************************
+ * Functions exported as capabilities. They are declared as static so that
+ * we don't pollute the namespace too much.
+ *****************************************************************************/
+void esd_aout_getfunctions( function_list_t * p_function_list )
+{
+    p_function_list->p_probe = aout_Probe;
+    p_function_list->functions.aout.p_open = aout_Open;
+    p_function_list->functions.aout.p_setformat = aout_SetFormat;
+    p_function_list->functions.aout.p_getbufinfo = aout_GetBufInfo;
+    p_function_list->functions.aout.p_play = aout_Play;
+    p_function_list->functions.aout.p_close = aout_Close;
+}
+
+/*****************************************************************************
+ * aout_Probe: probes the audio device and return a score
+ *****************************************************************************
+ * This function tries to open the dps and returns a score to the plugin
+ * manager so that it can 
+ *****************************************************************************/
+static int aout_Probe( probedata_t *p_data )
+{
+    /* We don't have to test anything -- if we managed to open this plugin,
+     * it means we have the appropriate libs. */
+    return( 50 );
+}
+
+/*****************************************************************************
+ * aout_Open: open an esd socket
+ *****************************************************************************/
+static int aout_Open( aout_thread_t *p_aout )
 {
     /* mpg123 does it this way */
     int i_bits = ESD_BITS16;
@@ -112,52 +152,28 @@ int aout_EsdOpen( aout_thread_t *p_aout )
 }
 
 /*****************************************************************************
- * aout_EsdReset: resets the dsp
- *****************************************************************************/
-int aout_EsdReset( aout_thread_t *p_aout )
-{
-    return( 0 );
-}
-
-/*****************************************************************************
- * aout_EsdSetFormat: sets the dsp output format
- *****************************************************************************/
-int aout_EsdSetFormat( aout_thread_t *p_aout )
-{
-    return( 0 );
-}
-
-/*****************************************************************************
- * aout_EsdSetChannels: sets the dsp's stereo or mono mode
- *****************************************************************************/
-int aout_EsdSetChannels( aout_thread_t *p_aout )
-{
-    return( 0 );
-}
-
-/*****************************************************************************
- * aout_EsdSetRate: sets the dsp's audio output rate
+ * aout_SetFormat: set the output format
  *****************************************************************************/
-int aout_EsdSetRate( aout_thread_t *p_aout )
+static int aout_SetFormat( aout_thread_t *p_aout )
 {
     return( 0 );
 }
 
 /*****************************************************************************
- * aout_EsdGetBufInfo: buffer status query
+ * aout_GetBufInfo: buffer status query
  *****************************************************************************/
-long aout_EsdGetBufInfo( aout_thread_t *p_aout, long l_buffer_limit )
+long aout_GetBufInfo( aout_thread_t *p_aout, long l_buffer_limit )
 {
     /* arbitrary value that should be changed */
     return( l_buffer_limit );
 }
 
 /*****************************************************************************
- * aout_EsdPlaySamples: plays a sound samples buffer
+ * aout_Play: play a sound samples buffer
  *****************************************************************************
- * This function writes a buffer of i_length bytes in the dsp
+ * This function writes a buffer of i_length bytes in the socket
  *****************************************************************************/
-void aout_EsdPlaySamples( aout_thread_t *p_aout, byte_t *buffer, int i_size )
+void aout_Play( aout_thread_t *p_aout, byte_t *buffer, int i_size )
 {
     int amount;
 
@@ -182,9 +198,9 @@ void aout_EsdPlaySamples( aout_thread_t *p_aout, byte_t *buffer, int i_size )
 }
 
 /*****************************************************************************
- * aout_EsdClose: closes the dsp audio device
+ * aout_Close: close the Esound socket
  *****************************************************************************/
-void aout_EsdClose( aout_thread_t *p_aout )
+void aout_Close( aout_thread_t *p_aout )
 {
     close( p_aout->i_fd );
 }
index ee35ec897d6bcf9d28add2bf8ad046892067cba4..2cafb04d25b98a859d9dc2f170e6477a199673b3 100644 (file)
@@ -1,9 +1,9 @@
 /*****************************************************************************
- * esd.c : Esound plugin for vlc
+ * esd.c : EsounD module
  *****************************************************************************
- * Copyright (C) 2000 VideoLAN
+ * Copyright (C) 2000, 2001 VideoLAN
  *
- * Authors:
+ * Authors: Samuel Hocevar <sam@zoy.org>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  *****************************************************************************/
 
+#define MODULE_NAME esd
+
 /*****************************************************************************
  * Preamble
  *****************************************************************************/
 #include "defs.h"
 
 #include <stdlib.h>                                      /* malloc(), free() */
+#include <string.h>                                              /* strdup() */
 
 #include "config.h"
 #include "common.h"                                     /* boolean_t, byte_t */
 #include "threads.h"
 #include "mtime.h"
 #include "tests.h"
-#include "plugins.h"
 
-#include "interface.h"
-#include "audio_output.h"
-#include "video.h"
-#include "video_output.h"
+#include "modules.h"
+#include "modules_inner.h"
 
 /*****************************************************************************
- * Exported prototypes
+ * Build configuration tree.
  *****************************************************************************/
-static void aout_GetPlugin( p_aout_thread_t p_aout );
-
-/* Audio output */
-int     aout_EsdOpen         ( aout_thread_t *p_aout );
-int     aout_EsdReset        ( aout_thread_t *p_aout );
-int     aout_EsdSetFormat    ( aout_thread_t *p_aout );
-int     aout_EsdSetChannels  ( aout_thread_t *p_aout );
-int     aout_EsdSetRate      ( aout_thread_t *p_aout );
-long    aout_EsdGetBufInfo   ( aout_thread_t *p_aout, long l_buffer_info );
-void    aout_EsdPlaySamples  ( aout_thread_t *p_aout, byte_t *buffer,
-                               int i_size );
-void    aout_EsdClose        ( aout_thread_t *p_aout );
+MODULE_CONFIG_START( "Configuration for esd module" )
+    ADD_FRAME( "EsounD" )
+        ADD_COMMENT( "This module does not need configuration" )
+MODULE_CONFIG_END
 
 /*****************************************************************************
- * GetConfig: get the plugin structure and configuration
+ * Capabilities defined in the other files.
  *****************************************************************************/
-plugin_info_t * GetConfig( void )
-{
-    plugin_info_t * p_info = (plugin_info_t *) malloc( sizeof(plugin_info_t) );
+void esd_aout_getfunctions( function_list_t * p_function_list );
 
-    p_info->psz_name    = "Esound";
-    p_info->psz_version = VERSION;
-    p_info->psz_author  = "the VideoLAN team <vlc@videolan.org>";
+/*****************************************************************************
+ * InitModule: get the module structure and configuration.
+ *****************************************************************************
+ * We have to fill psz_name, psz_longname and psz_version. These variables
+ * will be strdup()ed later by the main application because the module can
+ * be unloaded later to save memory, and we want to be able to access this
+ * data even after the module has been unloaded.
+ *****************************************************************************/
+int InitModule( module_t * p_module )
+{
+    p_module->psz_name = MODULE_STRING;
+    p_module->psz_longname = "EsounD audio module";
+    p_module->psz_version = VERSION;
 
-    p_info->aout_GetPlugin = aout_GetPlugin;
-    p_info->vout_GetPlugin = NULL;
-    p_info->intf_GetPlugin = NULL;
-    p_info->yuv_GetPlugin  = NULL;
+    p_module->i_capabilities = MODULE_CAPABILITY_NULL
+                                | MODULE_CAPABILITY_AOUT;
 
-    /* esound should always work, but score it lower than DSP */
-    p_info->i_score = 0x100;
+    return( 0 );
+}
 
-    /* If this plugin was requested, score it higher */
-    if( TestMethod( AOUT_METHOD_VAR, "esd" ) )
+/*****************************************************************************
+ * ActivateModule: set the module to an usable state.
+ *****************************************************************************
+ * This function fills the capability functions and the configuration
+ * structure. Once ActivateModule() has been called, the i_usage can
+ * be set to 0 and calls to NeedModule() be made to increment it. To unload
+ * the module, one has to wait until i_usage == 0 and call DeactivateModule().
+ *****************************************************************************/
+int ActivateModule( module_t * p_module )
+{
+    p_module->p_functions = malloc( sizeof( module_functions_t ) );
+    if( p_module->p_functions == NULL )
     {
-        p_info->i_score += 0x200;
+        return( -1 );
     }
 
-    return( p_info );
+    esd_aout_getfunctions( &p_module->p_functions->aout );
+
+    p_module->p_config = p_config;
+
+    return( 0 );
 }
 
 /*****************************************************************************
- * Following functions are only called through the p_info structure
+ * DeactivateModule: make sure the module can be unloaded.
+ *****************************************************************************
+ * This function must only be called when i_usage == 0. If it successfully
+ * returns, i_usage can be set to -1 and the module unloaded. Be careful to
+ * lock usage_lock during the whole process.
  *****************************************************************************/
-
-static void aout_GetPlugin( p_aout_thread_t p_aout )
+int DeactivateModule( module_t * p_module )
 {
-    p_aout->p_sys_open        = aout_EsdOpen;
-    p_aout->p_sys_reset       = aout_EsdReset;
-    p_aout->p_sys_setformat   = aout_EsdSetFormat;
-    p_aout->p_sys_setchannels = aout_EsdSetChannels;
-    p_aout->p_sys_setrate     = aout_EsdSetRate;
-    p_aout->p_sys_getbufinfo  = aout_EsdGetBufInfo;
-    p_aout->p_sys_playsamples = aout_EsdPlaySamples;
-    p_aout->p_sys_close       = aout_EsdClose;
+    free( p_module->p_functions );
+
+    return( 0 );
 }
 
index 7ffa9731116d4367df1123f3e5a2bfa3e19a9b5a..271b2c13a4668a19d76f782410141e011c88fe5e 100644 (file)
 #include "threads.h"
 #include "mtime.h"
 #include "tests.h"
+
 #include "modules.h"
 #include "modules_inner.h"
-#include "modules_config.h"
 
 /*****************************************************************************
  * Build configuration tree.
  *****************************************************************************/
 MODULE_CONFIG_START( "Configuration for null module" )
-    ADD_PANE( "First" )
-        ADD_FRAME( "First test" )
+    ADD_PANE( "First pane" )
+        ADD_FRAME( "First frame" )
             ADD_COMMENT( "You can put whatever you want here." )
             ADD_STRING( "Random text: ", MODULE_VAR(text), NULL )
-        ADD_FRAME( "Second test" )
+        ADD_FRAME( "Second frame" )
             ADD_COMMENT( "The file below is not used." )
             ADD_FILE( "Select file: ", MODULE_VAR(file), NULL )
-        ADD_FRAME( "Third test" )
+        ADD_FRAME( "Third frame" )
             ADD_COMMENT( "This space intentionally left blank." )
-    ADD_PANE( "Second" )
-        ADD_FRAME( "NULL Frame" )
+    ADD_PANE( "Second pane" )
+        ADD_FRAME( "Frame" )
             ADD_COMMENT( "There is nothing in this frame." )
 MODULE_CONFIG_END
 
@@ -68,7 +68,7 @@ MODULE_CONFIG_END
 int InitModule( module_t * p_module )
 {
     p_module->psz_name = MODULE_STRING;
-    p_module->psz_longname = "the Null Module that does nothing";
+    p_module->psz_longname = "the Null module that does nothing";
     p_module->psz_version = VERSION;
 
     p_module->i_capabilities = MODULE_CAPABILITY_NULL;
@@ -86,7 +86,11 @@ int InitModule( module_t * p_module )
  *****************************************************************************/
 int ActivateModule( module_t * p_module )
 {
+    /* Since the Null module can't do anything, there is no need to
+     * fill the p_functions structure. */
+    p_module->p_functions = NULL;
     p_module->p_config = p_config;
+
     return( 0 );
 }
 
@@ -99,6 +103,7 @@ int ActivateModule( module_t * p_module )
  *****************************************************************************/
 int DeactivateModule( module_t * p_module )
 {
+    /* We didn't allocate p_functions - so we don't have to free it */
     return( 0 );
 }
 
index 1030efe19b8e01fd91b2ac0d9c0c0382850438ae..19622b885e914df008ade08c00c3b4325ea1ba99 100644 (file)
  *****************************************************************************/
 
 /* hope these constant values are cache line aligned */
-static unsigned long long mmx_80w     = 0x0080008000800080;
-static unsigned long long mmx_10w     = 0x1010101010101010;
-static unsigned long long mmx_00ffw   = 0x00ff00ff00ff00ff;
-static unsigned long long mmx_Y_coeff = 0x253f253f253f253f;
+#define UNUSED_LONGLONG(foo) \
+    static unsigned long long foo __attribute__((unused))
+UNUSED_LONGLONG(mmx_80w)     = 0x0080008000800080;
+UNUSED_LONGLONG(mmx_10w)     = 0x1010101010101010;
+UNUSED_LONGLONG(mmx_00ffw)   = 0x00ff00ff00ff00ff;
+UNUSED_LONGLONG(mmx_Y_coeff) = 0x253f253f253f253f;
 
-static unsigned long long mmx_U_green = 0xf37df37df37df37d;
-static unsigned long long mmx_U_blue  = 0x4093409340934093;
-static unsigned long long mmx_V_red   = 0x3312331233123312;
-static unsigned long long mmx_V_green = 0xe5fce5fce5fce5fc;
+UNUSED_LONGLONG(mmx_U_green) = 0xf37df37df37df37d;
+UNUSED_LONGLONG(mmx_U_blue)  = 0x4093409340934093;
+UNUSED_LONGLONG(mmx_V_red)   = 0x3312331233123312;
+UNUSED_LONGLONG(mmx_V_green) = 0xe5fce5fce5fce5fc;
 
-static unsigned long long mmx_redmask = 0xf8f8f8f8f8f8f8f8;
-static unsigned long long mmx_grnmask = 0xfcfcfcfcfcfcfcfc;
-static unsigned long long mmx_grnshift   = 0x03;
-static unsigned long long mmx_blueshift  = 0x03;
+UNUSED_LONGLONG(mmx_redmask) = 0xf8f8f8f8f8f8f8f8;
+UNUSED_LONGLONG(mmx_grnmask) = 0xfcfcfcfcfcfcfcfc;
+UNUSED_LONGLONG(mmx_grnshift)   = 0x03;
+UNUSED_LONGLONG(mmx_blueshift)  = 0x03;
+#undef UNUSED_LONGLONG
 
 #define MMX_INIT_16 "                                                       \n\
                                                                             \n\
index 9c1af062af66e17925051518148395b0bcb2c784..4fca2339e3e185a22d09e5b14701eac7a484f296 100644 (file)
@@ -47,6 +47,7 @@
 #include "threads.h"
 #include "mtime.h"                             /* mtime_t, mdate(), msleep() */
 #include "plugins.h"
+#include "modules.h"
 
 #include "intf_msg.h"                        /* intf_DbgMsg(), intf_ErrMsg() */
 
@@ -99,9 +100,6 @@ static __inline__ void InitializeIncrement( aout_increment_t * p_increment, long
 aout_thread_t *aout_CreateThread( int *pi_status )
 {
     aout_thread_t * p_aout;                             /* thread descriptor */
-    typedef void    ( aout_getplugin_t ) ( aout_thread_t * p_aout );
-    int             i_index;
-    int             i_best_index = 0, i_best_score = 0;
 #if 0
     int             i_status;                               /* thread status */
 #endif
@@ -113,41 +111,31 @@ aout_thread_t *aout_CreateThread( int *pi_status )
         return( NULL );
     }
 
-    /* Get a suitable audio plugin */
-    for( i_index = 0 ; i_index < p_main->p_bank->i_plugin_count ; i_index++ )
-    {
-        /* If there's a plugin in p_info ... */
-        if( p_main->p_bank->p_info[ i_index ] != NULL )
-        {
-            /* ... and if this plugin provides the functions we want ... */
-            if( p_main->p_bank->p_info[ i_index ]->aout_GetPlugin != NULL )
-            {
-                /* ... and if this plugin has a good score ... */
-                if( p_main->p_bank->p_info[ i_index ]->i_score > i_best_score )
-                {
-                    /* ... then take it */
-                    i_best_score = p_main->p_bank->p_info[ i_index ]->i_score;
-                    i_best_index = i_index;
-                }
-            }
-        }
-    }
+    /* Choose the best module */
+    p_aout->p_module = module_Need( p_main->p_module_bank,
+                                    MODULE_CAPABILITY_AOUT, NULL );
 
-    if( i_best_score == 0 )
+    if( p_aout->p_module == NULL )
     {
+        intf_ErrMsg( "aout error: no suitable aout module" );
         free( p_aout );
         return( NULL );
     }
 
-    /* Get the plugin functions */
-    ( (aout_getplugin_t *)
-      p_main->p_bank->p_info[ i_best_index ]->aout_GetPlugin )( p_aout );
+#define aout_functions p_aout->p_module->p_functions->aout.functions.aout
+    p_aout->p_open       = aout_functions.p_open;
+    p_aout->p_setformat  = aout_functions.p_setformat;
+    p_aout->p_getbufinfo = aout_functions.p_getbufinfo;
+    p_aout->p_play       = aout_functions.p_play;
+    p_aout->p_close      = aout_functions.p_close;
+#undef aout_functions
 
     /*
      * Initialize audio device
      */
-    if ( p_aout->p_sys_open( p_aout ) )
+    if ( p_aout->p_open( p_aout ) )
     {
+        module_Unneed( p_main->p_module_bank, p_aout->p_module );
         free( p_aout );
         return( NULL );
     }
@@ -155,27 +143,10 @@ aout_thread_t *aout_CreateThread( int *pi_status )
     p_aout->b_stereo = ( p_aout->i_channels == 2 ) ? 1 : 0; /* FIXME: only works
                                                    for i_channels == 1 or 2 ??*/
 
-    if ( p_aout->p_sys_reset( p_aout ) )
-    {
-        p_aout->p_sys_close( p_aout );
-        free( p_aout );
-        return( NULL );
-    }
-    if ( p_aout->p_sys_setformat( p_aout ) )
+    if ( p_aout->p_setformat( p_aout ) )
     {
-        p_aout->p_sys_close( p_aout );
-        free( p_aout );
-        return( NULL );
-    }
-    if ( p_aout->p_sys_setchannels( p_aout ) )
-    {
-        p_aout->p_sys_close( p_aout );
-        free( p_aout );
-        return( NULL );
-    }
-    if ( p_aout->p_sys_setrate( p_aout ) )
-    {
-        p_aout->p_sys_close( p_aout );
+        p_aout->p_close( p_aout );
+        module_Unneed( p_main->p_module_bank, p_aout->p_module );
         free( p_aout );
         return( NULL );
     }
@@ -188,7 +159,8 @@ aout_thread_t *aout_CreateThread( int *pi_status )
      * this thread is only called in main and all calls are blocking */
     if( aout_SpawnThread( p_aout ) )
     {
-        p_aout->p_sys_close( p_aout );
+        p_aout->p_close( p_aout );
+        module_Unneed( p_main->p_module_bank, p_aout->p_module );
         free( p_aout );
         return( NULL );
     }
@@ -362,8 +334,11 @@ void aout_DestroyThread( aout_thread_t * p_aout, int *pi_status )
     }
     vlc_mutex_destroy( &p_aout->fifos_lock );
     
+    /* Release the aout module */
+    module_Unneed( p_main->p_module_bank, p_aout->p_module );
+
     /* Free the structure */
-    p_aout->p_sys_close( p_aout );
+    p_aout->p_close( p_aout );
     intf_DbgMsg("aout debug: audio device (%s) closed", p_aout->psz_device);
 
     /* Free structure */
@@ -822,9 +797,9 @@ void aout_Thread_U8_Mono( aout_thread_t * p_aout )
             ((u8 *)p_aout->buffer)[l_buffer] = (u8)( ( (p_aout->s32_buffer[l_buffer] / AOUT_MAX_FIFOS / 256 ) + 128 ) * p_aout->vol / 256 );
             p_aout->s32_buffer[l_buffer] = 0;
         }
-        l_bytes = p_aout->p_sys_getbufinfo( p_aout, l_buffer_limit );
+        l_bytes = p_aout->p_getbufinfo( p_aout, l_buffer_limit );
         p_aout->date = mdate() + ((((mtime_t)(l_bytes / 1 )) * 1000000) / ((mtime_t)p_aout->l_rate)); /* sizeof(u8) << (p_aout->b_stereo) == 1 */
-        p_aout->p_sys_playsamples( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(u8) );
+        p_aout->p_play( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(u8) );
         if ( l_bytes > (l_buffer_limit * sizeof(u8) * 2) ) /* There are 2 channels (left & right) */
         {
             msleep( p_aout->l_msleep );
@@ -1113,9 +1088,9 @@ void aout_Thread_U8_Stereo( aout_thread_t * p_aout )
             ((u8 *)p_aout->buffer)[l_buffer] = (u8)( ( (p_aout->s32_buffer[l_buffer] / AOUT_MAX_FIFOS / 256) + 128 ) * p_aout->vol / 256 );
             p_aout->s32_buffer[l_buffer] = 0;
         }
-        l_bytes = p_aout->p_sys_getbufinfo( p_aout, l_buffer_limit );
+        l_bytes = p_aout->p_getbufinfo( p_aout, l_buffer_limit );
         p_aout->date = mdate() + ((((mtime_t)(l_bytes / 2 )) * 1000000) / ((mtime_t)p_aout->l_rate)); /* sizeof(u8) << (p_aout->b_stereo) == 2 */
-        p_aout->p_sys_playsamples( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(u8) );
+        p_aout->p_play( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(u8) );
         if ( l_bytes > (l_buffer_limit * sizeof(u8)) )
         {
             msleep( p_aout->l_msleep );
@@ -1408,9 +1383,9 @@ void aout_Thread_S16_Stereo( aout_thread_t * p_aout )
             p_aout->s32_buffer[l_buffer] = 0;
         }
 
-        l_bytes = p_aout->p_sys_getbufinfo( p_aout, l_buffer_limit );
+        l_bytes = p_aout->p_getbufinfo( p_aout, l_buffer_limit );
         p_aout->date = mdate() + ((((mtime_t)(l_bytes / 4)) * 1000000) / ((mtime_t)p_aout->l_rate)); /* sizeof(s16) << (p_aout->b_stereo) == 4 */
-        p_aout->p_sys_playsamples( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(s16) );
+        p_aout->p_play( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(s16) );
         if ( l_bytes > (l_buffer_limit * sizeof(s16)) )
         {
             msleep( p_aout->l_msleep );
index 108eed1f84ebb8c8e6376045fb03e81770c58df2..907354148ae4e3f795290068bfd82af41823cb28 100644 (file)
@@ -2,7 +2,7 @@
  * input_programs.c: es_descriptor_t, pgrm_descriptor_t management
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: input_programs.c,v 1.20 2001/01/07 04:31:18 henri Exp $
+ * $Id: input_programs.c,v 1.21 2001/01/07 16:17:58 sam Exp $
  *
  * Authors:
  *
@@ -84,15 +84,12 @@ void input_EndStream( input_thread_t * p_input )
         /* Don't put i instead of 0 !! */
         input_DelProgram( p_input, p_input->stream.pp_programs[0] );
     }
-    free( p_input->stream.pp_programs );
 
     /* Free standalone ES */
     for( i = 0; i < p_input->stream.i_es_number; i++ )
     {
         input_DelES( p_input, p_input->stream.pp_es[0] );
     }
-    free( p_input->stream.pp_es );
-    free( p_input->stream.pp_selected_es );
 }
 
 /*****************************************************************************
@@ -202,9 +199,6 @@ void input_DelProgram( input_thread_t * p_input, pgrm_descriptor_t * p_pgrm )
         input_DelES( p_input, p_pgrm->pp_es[i_index] );
     }
 
-    /* Free the table of es descriptors */
-    free( p_pgrm->pp_es );
-
     /* Free the demux data */
     if( p_pgrm->p_demux_data != NULL )
     {
@@ -221,16 +215,19 @@ void input_DelProgram( input_thread_t * p_input, pgrm_descriptor_t * p_pgrm )
 
     /* Remove this program from the stream's list of programs */
     p_input->stream.i_pgrm_number--;
+
     p_input->stream.pp_programs[i_pgrm_index] =
         p_input->stream.pp_programs[p_input->stream.i_pgrm_number];
     p_input->stream.pp_programs = realloc( p_input->stream.pp_programs,
                                            p_input->stream.i_pgrm_number
                                             * sizeof(pgrm_descriptor_t *) );
 
-    if( p_input->stream.pp_programs == NULL)
+    if( p_input->stream.i_pgrm_number && p_input->stream.pp_programs == NULL)
     {
-        intf_ErrMsg( "Unable to realloc memory in input_DelProgram" );
+        intf_ErrMsg( "input error: unable to realloc program list"
+                     " in input_DelProgram" );
     }
+
     /* Free the description of this program */
     free( p_pgrm );
 }
@@ -360,7 +357,7 @@ void input_DelES( input_thread_t * p_input, es_descriptor_t * p_es )
                 p_pgrm->pp_es = realloc( p_pgrm->pp_es,
                                          p_pgrm->i_es_number
                                           * sizeof(es_descriptor_t *));
-                if( p_pgrm->pp_es == NULL )
+                if( p_pgrm->i_es_number && p_pgrm->pp_es == NULL )
                 {
                     intf_ErrMsg( "Unable to realloc memory in input_DelES" );
                 }
@@ -391,7 +388,7 @@ void input_DelES( input_thread_t * p_input, es_descriptor_t * p_es )
     p_input->stream.pp_es = realloc( p_input->stream.pp_es,
                                      p_input->stream.i_es_number
                                       * sizeof(es_descriptor_t *));
-    if( p_input->stream.pp_es == NULL )
+    if( p_input->stream.i_es_number && p_input->stream.pp_es == NULL )
     {
         intf_ErrMsg( "Unable to realloc memory in input_DelES" );
     }
index fff8bbd4b76b0c3dc7683659310e5146252b81bc..65bc8631c407e78ccb5770e88f16e317dde71c6f 100644 (file)
@@ -55,6 +55,8 @@
 static int AllocateDynModule( module_bank_t * p_bank, char * psz_filename );
 static int HideModule( module_t * p_module );
 static int FreeModule( module_bank_t * p_bank, module_t * p_module );
+static int LockModule( module_t * p_module );
+static int UnlockModule( module_t * p_module );
 static int CallSymbol( module_t * p_module, char * psz_name );
 
 /*****************************************************************************
@@ -109,12 +111,12 @@ void module_InitBank( module_bank_t * p_bank )
 
                 /* We only load files ending with ".so" */
                 if( i_filelen > 3
-                        && !strcmp( file->d_name + i_filelen - 3, ".so" ) )
+                        && !strncmp( file->d_name + i_filelen - 3, ".so", 3 ) )
                 {
 #ifdef SYS_BEOS
                     /* Under BeOS, we need to add beos_GetProgramPath() to
                      * access files under the current directory */
-                    if( memcmp( file->d_name, "/", 1 ) )
+                    if( strncmp( file->d_name, "/", 1 ) )
                     {
                         psz_file = malloc( i_programlen + i_dirlen
                                                + i_filelen + 3 );
@@ -236,87 +238,99 @@ void module_ManageBank( module_bank_t * p_bank )
 }
 
 /*****************************************************************************
- * module_Need: increase the usage count of a module and load it if needed.
+ * module_Need: return the best module function, given a capability list.
  *****************************************************************************
- * This function has to be called before a thread starts using a module. If
- * the module is already loaded, we just increase its usage count. If it isn't
- * loaded, we have to dynamically open it and initialize it.
- * If you successfully call module_Need() at any moment, be careful to call
- * module_Unneed() when you don't need it anymore.
+ * This function returns the module that best fits the asked capabilities.
  *****************************************************************************/
-int module_Need( module_t * p_module )
+module_t * module_Need( module_bank_t *p_bank,
+                        int i_capabilities, void *p_data )
 {
-    if( p_module->i_usage >= 0 )
-    {
-        /* This module is already loaded and activated, we can return */
-        p_module->i_usage++;
-        return( 0 );
-    }
+    module_t * p_module;
+    module_t * p_bestmodule = NULL;
+    int i_score, i_totalscore, i_bestscore = 0;
+    int i_index;
 
-    if( p_module->b_builtin )
-    {
-        /* A built-in module should always have a refcount >= 0 ! */
-        intf_ErrMsg( "module error: built-in module `%s' has refcount %i",
-                     p_module->psz_name, p_module->i_usage );
-        return( -1 );
-    }
+    /* We take the global lock */
+    vlc_mutex_lock( &p_bank->lock );
 
-    if( p_module->i_usage != -1 )
+    /* Parse the module list for capabilities and probe each of them */
+    for( p_module = p_bank->first ;
+         p_module != NULL ;
+         p_module = p_module->next )
     {
-        /* This shouldn't happen. Ever. We have serious problems here. */
-        intf_ErrMsg( "module error: dynamic module `%s' has refcount %i",
-                     p_module->psz_name, p_module->i_usage );
-        return( -1 );
-    }
+        /* Test that this module can do everything we need */
+        if( ( p_module->i_capabilities & i_capabilities ) == i_capabilities )
+        {
+            i_totalscore = 0;
 
-    /* i_usage == -1, which means that the module isn't in memory */
-    if( ! module_load( p_module->psz_filename, &p_module->handle ) )
-    {
-        /* The dynamic module couldn't be opened */
-        intf_ErrMsg( "module error: cannot open %s (%s)",
-                     p_module->psz_filename, module_error() );
-        return( -1 );
-    }
+            LockModule( p_module );
 
-    if( CallSymbol( p_module, "ActivateModule" ) != 0 )
-    {
-        /* We couldn't call ActivateModule() -- looks nasty, but
-         * we can't do much about it. Just try to unload module. */
-        module_unload( p_module->handle );
-        p_module->i_usage = -1;
-        return( -1 );
+            /* Parse all the requested capabilities and test them */
+            for( i_index = 0 ; (1 << i_index) <= i_capabilities ; i_index++ )
+            {
+                if( ( (1 << i_index) & i_capabilities ) )
+                {
+                    i_score = ( (function_list_t *)p_module->p_functions)
+                                                  [i_index].p_probe( p_data );
+
+                    if( i_score )
+                    {
+                        i_totalscore += i_score;
+                    }
+                    else
+                    {
+                        break;
+                    }
+                }
+            }
+
+            /* If the high score was broken, we have a new champion */
+            if( i_totalscore > i_bestscore )
+            {
+                /* Keep the current module locked, but release the previous */
+                if( p_bestmodule != NULL )
+                {
+                    UnlockModule( p_bestmodule );
+                }
+
+                /* This is the new best module */
+                i_bestscore = i_totalscore;
+                p_bestmodule = p_module;
+            }
+            else
+            {
+                /* This module wasn't interesting, unlock it and forget it */
+                UnlockModule( p_module );
+            }
+        }
     }
 
-    /* Everything worked fine ! The module is ready to be used */
-    p_module->i_usage = 1;
+    /* We release the global lock */
+    vlc_mutex_unlock( &p_bank->lock );
 
-    return( 0 );
+    /* Don't forget that the module is still locked if bestmodule != NULL */
+    return( p_bestmodule );
 }
 
 /*****************************************************************************
  * module_Unneed: decrease the usage count of a module.
  *****************************************************************************
- * This function has to be called before a thread starts using a module. If
- * the module is already loaded, we just increase its usage count. If it isn't
- * loaded, we have to dynamically open it and initialize it.
- * If you successfully call module_Need() at any moment, be careful to call
- * module_Unneed() when you don't need it anymore.
+ * This function must be called by the thread that called module_Need, to
+ * decrease the reference count and allow for hiding of modules.
  *****************************************************************************/
-int module_Unneed( module_t * p_module )
+void module_Unneed( module_bank_t * p_bank, module_t * p_module )
 {
-    if( p_module->i_usage <= 0 )
-    {
-        /* This shouldn't happen. Ever. We have serious problems here. */
-        intf_ErrMsg( "module error: trying to call module_Unneed() on `%s'"
-                     " which isn't even in use", p_module->psz_name );
-        return( -1 );
-    }
+    /* We take the global lock */
+    vlc_mutex_lock( &p_bank->lock );
 
-    /* This module is still in use, we can return */
-    p_module->i_usage--;
-    p_module->i_unused_delay = 0;
+    /* Just unlock the module - we can't do anything if it fails,
+     * so there is no need to check the return value. */
+    UnlockModule( p_module );
 
-    return( 0 );
+    /* We release the global lock */
+    vlc_mutex_unlock( &p_bank->lock );
+
+    return;
 }
 
 /*****************************************************************************
@@ -332,7 +346,7 @@ int module_Unneed( module_t * p_module )
  *****************************************************************************/
 static int AllocateDynModule( module_bank_t * p_bank, char * psz_filename )
 {
-    module_t * p_module;
+    module_t * p_module, * p_othermodule;
     module_handle_t handle;
 
     /* Try to dynamically load the module. */
@@ -358,6 +372,7 @@ static int AllocateDynModule( module_bank_t * p_bank, char * psz_filename )
     p_module->psz_filename = psz_filename;
     p_module->handle = handle;
 
+    /* Initialize the module : fill p_module->psz_name, etc. */
     if( CallSymbol( p_module, "InitModule" ) != 0 )
     {
         /* We couldn't call InitModule() */
@@ -366,6 +381,28 @@ static int AllocateDynModule( module_bank_t * p_bank, char * psz_filename )
         return( -1 );
     }
 
+    /* Check that version numbers match */
+    if( strcmp( VERSION, p_module->psz_version ) )
+    {
+        free( p_module );
+        module_unload( handle );
+        return( -1 );
+    }
+
+    /* Check that we don't already have a module with this name */
+    for( p_othermodule = p_bank->first ;
+         p_othermodule != NULL ;
+         p_othermodule = p_othermodule->next )
+    {
+        if( !strcmp( p_othermodule->psz_name, p_module->psz_name ) )
+        {
+            free( p_module );
+            module_unload( handle );
+            return( -1 );
+        }
+    }
+
+    /* Activate the module : fill the capability structure, etc. */
     if( CallSymbol( p_module, "ActivateModule" ) != 0 )
     {
         /* We couldn't call ActivateModule() */
@@ -447,6 +484,7 @@ static int HideModule( module_t * p_module )
         return( -1 );
     }
 
+    /* Deactivate the module : free the capability structure, etc. */
     if( CallSymbol( p_module, "DeactivateModule" ) != 0 )
     {
         /* We couldn't call DeactivateModule() -- looks nasty, but
@@ -530,6 +568,92 @@ static int FreeModule( module_bank_t * p_bank, module_t * p_module )
     return( 0 );
 }
 
+/*****************************************************************************
+ * LockModule: increase the usage count of a module and load it if needed.
+ *****************************************************************************
+ * This function has to be called before a thread starts using a module. If
+ * the module is already loaded, we just increase its usage count. If it isn't
+ * loaded, we have to dynamically open it and initialize it.
+ * If you successfully call LockModule() at any moment, be careful to call
+ * UnlockModule() when you don't need it anymore.
+ *****************************************************************************/
+static int LockModule( module_t * p_module )
+{
+    if( p_module->i_usage >= 0 )
+    {
+        /* This module is already loaded and activated, we can return */
+        p_module->i_usage++;
+        return( 0 );
+    }
+
+    if( p_module->b_builtin )
+    {
+        /* A built-in module should always have a refcount >= 0 ! */
+        intf_ErrMsg( "module error: built-in module `%s' has refcount %i",
+                     p_module->psz_name, p_module->i_usage );
+        return( -1 );
+    }
+
+    if( p_module->i_usage != -1 )
+    {
+        /* This shouldn't happen. Ever. We have serious problems here. */
+        intf_ErrMsg( "module error: dynamic module `%s' has refcount %i",
+                     p_module->psz_name, p_module->i_usage );
+        return( -1 );
+    }
+
+    /* i_usage == -1, which means that the module isn't in memory */
+    if( ! module_load( p_module->psz_filename, &p_module->handle ) )
+    {
+        /* The dynamic module couldn't be opened */
+        intf_ErrMsg( "module error: cannot open %s (%s)",
+                     p_module->psz_filename, module_error() );
+        return( -1 );
+    }
+
+    /* FIXME: what to do if the guy modified the plugin while it was
+     * unloaded ? It makes XMMS crash nastily, perhaps we should try
+     * to be a bit more clever here. */
+
+    /* Activate the module : fill the capability structure, etc. */
+    if( CallSymbol( p_module, "ActivateModule" ) != 0 )
+    {
+        /* We couldn't call ActivateModule() -- looks nasty, but
+         * we can't do much about it. Just try to unload module. */
+        module_unload( p_module->handle );
+        p_module->i_usage = -1;
+        return( -1 );
+    }
+
+    /* Everything worked fine ! The module is ready to be used */
+    p_module->i_usage = 1;
+
+    return( 0 );
+}
+
+/*****************************************************************************
+ * UnlockModule: decrease the usage count of a module.
+ *****************************************************************************
+ * We decrease the usage count of a module so that we know when a module
+ * becomes unused and can be hidden.
+ *****************************************************************************/
+static int UnlockModule( module_t * p_module )
+{
+    if( p_module->i_usage <= 0 )
+    {
+        /* This shouldn't happen. Ever. We have serious problems here. */
+        intf_ErrMsg( "module error: trying to call module_Unneed() on `%s'"
+                     " which isn't even in use", p_module->psz_name );
+        return( -1 );
+    }
+
+    /* This module is still in use, we can return */
+    p_module->i_usage--;
+    p_module->i_unused_delay = 0;
+
+    return( 0 );
+}
+
 /*****************************************************************************
  * CallSymbol: calls a module symbol.
  *****************************************************************************