Commit 0374d333 authored by Sam Hocevar's avatar Sam Hocevar

chargement dynamique de plugins audio/video/interface

 utilisation: c'est tout con, �a marche comme avant. pour le moment
  il n'y a pas de v�rification des symboles mais �a viendra.

 seule restriction, il faut �tre dans le r�pertoire vlc quand on lance
  le client, parce que le chemin des plugins est relatif, mais �a aussi
  �a va changer.

 le Makefile devient pas tr�s beau, il faudra songer � passer � automake
parent f8371eed
......@@ -16,7 +16,7 @@ SHELL=/bin/sh
# Audio output settings
AUDIO = dsp
# Not yet supported
AUDIO += esd
#AUDIO += esd
# Fallback method that should always work
AUDIO += dummy
......@@ -64,12 +64,10 @@ PROGRAM_VERSION = 0.95.0
# audio options
audio := $(shell echo $(AUDIO) | tr 'A-Z' 'a-z')
AUDIO := $(shell echo $(AUDIO) | tr 'a-z' 'A-Z')
DEFINE += $(AUDIO:%=-DAUDIO_%)
# video options
video := $(shell echo $(VIDEO) | tr 'A-Z' 'a-z')
VIDEO := $(shell echo $(VIDEO) | tr 'a-z' 'A-Z')
DEFINE += $(VIDEO:%=-DVIDEO_%)
# PROGRAM_OPTIONS is an identification string of the compilation options
PROGRAM_OPTIONS = $(ARCH) $(SYS)
......@@ -103,33 +101,12 @@ endif
#
INCLUDE += -Iinclude
ifneq (,$(findstring x11,$(video)))
INCLUDE += -I/usr/X11R6/include
endif
ifneq (,$(findstring glide,$(video)))
INCLUDE += -I/usr/include/glide
endif
#
# Libraries
#
LIB += -lpthread
LIB += -lm
ifneq (,$(findstring x11,$(video)))
LIB += -L/usr/X11R6/lib -lX11 -lXext
endif
ifneq (,$(findstring ggi,$(video)))
LIB += -lggi
endif
ifneq (,$(findstring glide,$(video)))
LIB += -lglide2x
endif
ifneq (,$(findstring esd,$(audio)))
LIB += -lesd -laudiofile
endif
LIB += -ldl
#
# C compiler flags: compilation
......@@ -207,8 +184,7 @@ interface_obj = interface/main.o \
interface/intf_msg.o \
interface/intf_cmd.o \
interface/intf_ctrl.o \
interface/intf_console.o \
$(video:%=interface/intf_%.o)
interface/intf_console.o
input_obj = input/input_vlan.o \
input/input_file.o \
......@@ -219,13 +195,11 @@ input_obj = input/input_vlan.o \
input/input_psi.o \
input/input.o
audio_output_obj = audio_output/audio_output.o \
$(audio:%=audio_output/aout_%.o)
audio_output_obj = audio_output/audio_output.o
video_output_obj = video_output/video_output.o \
video_output/video_text.o \
video_output/video_yuv.o \
$(video:%=video_output/vout_%.o)
video_output/video_yuv.o
ac3_decoder_obj = ac3_decoder/ac3_decoder.o \
ac3_decoder/ac3_parse.o \
......@@ -302,10 +276,21 @@ endif
endif
endif
#
# Plugins
#
interface_plugin = $(video:%=interface/intf_%.so)
audio_plugin = $(audio:%=audio_output/aout_%.so)
video_plugin = $(video:%=video_output/vout_%.so)
PLUGIN_OBJ = $(interface_plugin) \
$(audio_plugin) \
$(video_plugin) \
#
# Other lists of files
#
sources := $(C_OBJ:%.o=%.c)
sources := $(C_OBJ:%.o=%.c) $(PLUGIN_OBJ:%.so=%.c)
dependancies := $(sources:%.c=dep/%.d)
# All symbols must be exported
......@@ -321,10 +306,10 @@ export
all: vlc
clean:
rm -f $(C_OBJ) $(ASM_OBJ)
rm -f $(C_OBJ) $(ASM_OBJ) $(PLUGIN_OBJ)
distclean: clean
rm -f **/*.o **/*~ *.log
rm -f **/*.o **/*.so **/*~ *.log
rm -f vlc gmon.out core
rm -rf dep
......@@ -340,8 +325,8 @@ FORCE:
#
# Real targets
#
vlc: $(C_OBJ) $(ASM_OBJ)
$(CC) $(LCFLAGS) $(CFLAGS) -o $@ $(C_OBJ) $(ASM_OBJ)
vlc: $(C_OBJ) $(ASM_OBJ) $(PLUGIN_OBJ)
$(CC) $(LCFLAGS) $(CFLAGS) --export-dynamic -rdynamic -o $@ $(C_OBJ) $(ASM_OBJ)
#
# Generic rules (see below)
......@@ -352,14 +337,51 @@ $(dependancies): %.d: FORCE
$(C_OBJ): %.o: Makefile.dep
$(C_OBJ): %.o: dep/%.d
$(C_OBJ): %.o: %.c
@echo "compiling $*.c"
@echo "compiling $*.o from $*.c"
@$(CC) $(CCFLAGS) $(CFLAGS) -c -o $@ $<
$(ASM_OBJ): %.o: Makefile.dep
$(ASM_OBJ): %.o: %.S
@echo "assembling $*.S"
@echo "assembling $*.o from $*.S"
@$(CC) $(CFLAGS) -c -o $@ $<
$(PLUGIN_OBJ): %.so: Makefile.dep
$(PLUGIN_OBJ): %.so: dep/%.d
# audio plugins
audio_output/aout_dummy.so \
audio_output/aout_dsp.so: %.so: %.c
@echo "compiling $*.so from $*.c"
@$(CC) $(CCFLAGS) $(CFLAGS) -shared -o $@ $<
audio_output/aout_esd.so: %.so: %.c
@echo "compiling $*.so from $*.c"
@$(CC) $(CCFLAGS) $(CFLAGS) -laudiofile -lesd -shared -o $@ $<
# video plugins
interface/intf_dummy.so \
video_output/vout_dummy.so \
interface/intf_fb.so \
video_output/vout_fb.so: %.so: %.c
@echo "compiling $*.so from $*.c"
@$(CC) $(CCFLAGS) $(CFLAGS) -shared -o $@ $<
interface/intf_x11.so \
video_output/vout_x11.so: %.so: %.c
@echo "compiling $*.so from $*.c"
@$(CC) $(CCFLAGS) $(CFLAGS) -I/usr/X11R6/include -L/usr/X11R6/lib -lX11 -lXext -shared -o $@ $<
interface/intf_glide.so \
video_output/vout_glide.so: %.so: %.c
@echo "compiling $*.so from $*.c"
@$(CC) $(CCFLAGS) $(CFLAGS) -I/usr/include/glide -lglide2x -shared -o $@ $<
interface/intf_ggi.so \
video_output/vout_ggi.so: %.so: %.c
@echo "compiling $*.so from $*.c"
@$(CC) $(CCFLAGS) $(CFLAGS) -lggi -shared -o $@ $<
################################################################################
# Note on generic rules and dependancies
################################################################################
......
......@@ -164,7 +164,8 @@ typedef struct aout_thread_s
vlc_mutex_t fifos_lock;
aout_fifo_t fifo[ AOUT_MAX_FIFOS ];
/* method-dependant functions */
/* Plugins */
void * p_aout_plugin; /* video output plugin */
aout_sys_open_t * p_sys_open;
aout_sys_reset_t * p_sys_reset;
aout_sys_setformat_t * p_sys_setformat;
......@@ -208,21 +209,6 @@ typedef struct aout_thread_s
} aout_thread_t;
/* Output methods */
#define AOUT_DUMMY_METHOD 0x0000 /* dummy video output */
#define AOUT_DSP_METHOD 0x0001 /* linux /dev/dsp */
/* Get the fallback method */
#ifdef AUDIO_DSP
#define AOUT_DEFAULT_METHOD "dsp"
#else
#ifdef AUDIO_ESD
#define AOUT_DEFAULT_METHOD "esd"
#else
#define AOUT_DEFAULT_METHOD "dummy"
#endif
#endif
/* Those are from <linux/soundcard.h> but are needed because of formats
* on other platforms */
#define AOUT_FMT_U8 0x00000008
......
......@@ -211,7 +211,10 @@
/* Environment variable containing the audio output method */
#define AOUT_METHOD_VAR "vlc_aout"
/* The fallback method */
#define AOUT_DEFAULT_METHOD "dsp"
/* Environment variable used to store dsp device name, and default value */
#define AOUT_DSP_VAR "vlc_dsp"
#define AOUT_DSP_DEFAULT "/dev/dsp"
......@@ -234,7 +237,10 @@
/* Environment variable containing the display method */
#define VOUT_METHOD_VAR "vlc_vout"
/* The fallback method */
#define VOUT_DEFAULT_METHOD "x11"
/* Environment variable used in place of DISPLAY if available */
#define VOUT_DISPLAY_VAR "vlc_display"
......
......@@ -38,7 +38,8 @@ typedef struct intf_thread_s
p_intf_console_t p_console; /* console */
p_intf_sys_t p_sys; /* system interface */
/* method-specific functions */
/* Plugin */
void * p_intf_plugin; /* interface plugin */
intf_sys_create_t * p_sys_create; /* create interface thread */
intf_sys_manage_t * p_sys_manage; /* main loop */
intf_sys_destroy_t * p_sys_destroy; /* destroy interface */
......
......@@ -107,7 +107,6 @@ typedef struct vout_thread_s
vlc_mutex_t change_lock; /* thread change lock */
int * pi_status; /* temporary status flag */
p_vout_sys_t p_sys; /* system output method */
int i_method; /* display method */
/* Current display properties */
u16 i_changes; /* changes made to the thread */
......@@ -135,7 +134,8 @@ typedef struct vout_thread_s
u32 i_gray_pixel; /* gray */
u32 i_blue_pixel; /* blue */
/* method-dependant functions */
/* Plugins */
void * p_vout_plugin; /* video output plugin */
vout_sys_create_t * p_sys_create; /* allocate output method */
vout_sys_init_t * p_sys_init; /* initialize output method */
vout_sys_end_t * p_sys_end; /* terminate output method */
......@@ -181,42 +181,6 @@ typedef struct vout_thread_s
int i_synchro_level; /* trashing level */
} vout_thread_t;
/* Output methods */
#define VOUT_DUMMY_METHOD 0x0000 /* dummy video output */
#define VOUT_X11_METHOD 0x0001 /* X11 */
#define VOUT_GGI_METHOD 0x0002 /* General Graphics Interface */
#define VOUT_FB_METHOD 0x0003 /* Linux framebuffer */
#define VOUT_GLIDE_METHOD 0x0004 /* Voodoo 3dfx */
#define VOUT_DGA_METHOD 0x0005 /* X11 DGA extension */
#define VOUT_BEOS_METHOD 0x0006 /* BeOS rendering */
/* Get the fallback method */
#ifdef VIDEO_X11
#define VOUT_DEFAULT_METHOD "x11"
#else
#ifdef VIDEO_FB
#define VOUT_DEFAULT_METHOD "fb"
#else
#ifdef VIDEO_GGI
#define VOUT_DEFAULT_METHOD "ggi"
#else
#ifdef VIDEO_GLIDE
#define VOUT_DEFAULT_METHOD "glide"
#else
#ifdef VIDEO_DGA
#define VOUT_DEFAULT_METHOD "dga"
#else
#ifdef VIDEO_BEOS
#define VOUT_DEFAULT_METHOD "beos"
#else
#define VOUT_DEFAULT_METHOD "dummy"
#endif
#endif
#endif
#endif
#endif
#endif
/* Flags for changes - these flags are set in the i_changes field when another
* thread changed a variable */
#define VOUT_INFO_CHANGE 0x0001 /* b_info changed */
......
......@@ -23,6 +23,8 @@
#include <stdio.h> /* "intf_msg.h" */
#include <stdlib.h> /* calloc(), malloc(), free() */
#include <dlfcn.h> /* plugins */
#include "common.h"
#include "config.h"
#include "mtime.h" /* mtime_t, mdate(), msleep() */
......@@ -31,7 +33,6 @@
#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */
#include "audio_output.h"
#include "audio_sys.h"
#include "main.h"
/*****************************************************************************
......@@ -62,6 +63,7 @@ aout_thread_t *aout_CreateThread( int *pi_status )
{
aout_thread_t * p_aout; /* thread descriptor */
char * psz_method;
char * psz_plugin;
// int i_status; /* thread status */
/* Allocate descriptor */
......@@ -71,58 +73,39 @@ aout_thread_t *aout_CreateThread( int *pi_status )
return( NULL );
}
/* initialize method-dependent functions */
/* Initialize method-dependent functions */
psz_method = main_GetPszVariable( AOUT_METHOD_VAR, AOUT_DEFAULT_METHOD );
if( !strcmp(psz_method, "dummy") )
{
p_aout->p_sys_open = aout_DummySysOpen;
p_aout->p_sys_reset = aout_DummySysReset;
p_aout->p_sys_setformat = aout_DummySysSetFormat;
p_aout->p_sys_setchannels = aout_DummySysSetChannels;
p_aout->p_sys_setrate = aout_DummySysSetRate;
p_aout->p_sys_getbufinfo = aout_DummySysGetBufInfo;
p_aout->p_sys_playsamples = aout_DummySysPlaySamples;
p_aout->p_sys_close = aout_DummySysClose;
}
#ifdef AUDIO_DSP
else if( !strcmp(psz_method, "dsp") )
{
p_aout->p_sys_open = aout_DspSysOpen;
p_aout->p_sys_reset = aout_DspSysReset;
p_aout->p_sys_setformat = aout_DspSysSetFormat;
p_aout->p_sys_setchannels = aout_DspSysSetChannels;
p_aout->p_sys_setrate = aout_DspSysSetRate;
p_aout->p_sys_getbufinfo = aout_DspSysGetBufInfo;
p_aout->p_sys_playsamples = aout_DspSysPlaySamples;
p_aout->p_sys_close = aout_DspSysClose;
}
#endif
#ifdef AUDIO_ESD
else if( !strcmp(psz_method, "esd") )
{
p_aout->p_sys_open = aout_EsdSysOpen;
p_aout->p_sys_reset = aout_EsdSysReset;
p_aout->p_sys_setformat = aout_EsdSysSetFormat;
p_aout->p_sys_setchannels = aout_EsdSysSetChannels;
p_aout->p_sys_setrate = aout_EsdSysSetRate;
p_aout->p_sys_getbufinfo = aout_EsdSysGetBufInfo;
p_aout->p_sys_playsamples = aout_EsdSysPlaySamples;
p_aout->p_sys_close = aout_EsdSysClose;
}
#endif
else
psz_plugin = malloc( sizeof("./audio_output/aout_.so") + strlen(psz_method) );
sprintf( psz_plugin, "./audio_output/aout_%s.so", psz_method );
p_aout->p_aout_plugin = dlopen (psz_plugin, RTLD_LAZY);
if( p_aout->p_aout_plugin == NULL )
{
intf_ErrMsg( "error: requested audio output method not available\n" );
intf_ErrMsg( "error: could not open audio plugin %s\n", psz_method );
free( psz_plugin );
free( p_aout );
return( NULL );
}
free( psz_plugin );
/* Get plugins */
p_aout->p_sys_open = dlsym(p_aout->p_aout_plugin, "aout_SysOpen");
p_aout->p_sys_reset = dlsym(p_aout->p_aout_plugin, "aout_SysReset");
p_aout->p_sys_setformat = dlsym(p_aout->p_aout_plugin, "aout_SysSetFormat");
p_aout->p_sys_setchannels = dlsym(p_aout->p_aout_plugin, "aout_SysSetChannels");
p_aout->p_sys_setrate = dlsym(p_aout->p_aout_plugin, "aout_SysSetRate");
p_aout->p_sys_getbufinfo = dlsym(p_aout->p_aout_plugin, "aout_SysGetBufInfo");
p_aout->p_sys_playsamples = dlsym(p_aout->p_aout_plugin, "aout_SysPlaySamples");
p_aout->p_sys_close = dlsym(p_aout->p_aout_plugin, "aout_SysClose");
/*
* Initialize audio device
*/
if ( p_aout->p_sys_open( p_aout ) )
{
dlclose( p_aout->p_aout_plugin );
free( p_aout );
return( NULL );
}
......@@ -133,24 +116,28 @@ aout_thread_t *aout_CreateThread( int *pi_status )
if ( p_aout->p_sys_reset( p_aout ) )
{
p_aout->p_sys_close( p_aout );
dlclose( p_aout->p_aout_plugin );
free( p_aout );
return( NULL );
}
if ( p_aout->p_sys_setformat( p_aout ) )
{
p_aout->p_sys_close( p_aout );
dlclose( p_aout->p_aout_plugin );
free( p_aout );
return( NULL );
}
if ( p_aout->p_sys_setchannels( p_aout ) )
{
p_aout->p_sys_close( p_aout );
dlclose( p_aout->p_aout_plugin );
free( p_aout );
return( NULL );
}
if ( p_aout->p_sys_setrate( p_aout ) )
{
p_aout->p_sys_close( p_aout );
dlclose( p_aout->p_aout_plugin );
free( p_aout );
return( NULL );
}
......@@ -161,6 +148,7 @@ aout_thread_t *aout_CreateThread( int *pi_status )
if( aout_SpawnThread( p_aout ) )
{
p_aout->p_sys_close( p_aout );
dlclose( p_aout->p_aout_plugin );
free( p_aout );
return( NULL );
}
......@@ -325,6 +313,11 @@ void aout_DestroyThread( aout_thread_t * p_aout, int *pi_status )
/* Free the structure */
p_aout->p_sys_close( p_aout );
intf_DbgMsg("aout debug: audio device (%s) closed\n", p_aout->psz_device);
/* Close plugin */
dlclose( p_aout->p_aout_plugin );
/* Free structure */
free( p_aout );
}
......
/*****************************************************************************
* audio_sys.h : header of the method-dependant functions library
* (c)1999 VideoLAN
*****************************************************************************
* Required headers:
* - "common.h" ( byte_t )
* - "audio_output.h" ( aout_dsp_t )
*****************************************************************************/
/*****************************************************************************
* Prototypes
*****************************************************************************/
#ifdef AUDIO_DUMMY
int aout_DummySysOpen ( aout_thread_t *p_aout );
int aout_DummySysReset ( aout_thread_t *p_aout );
int aout_DummySysSetFormat ( aout_thread_t *p_aout );
int aout_DummySysSetChannels ( aout_thread_t *p_aout );
int aout_DummySysSetRate ( aout_thread_t *p_aout );
long aout_DummySysGetBufInfo ( aout_thread_t *p_aout, long l_buffer_info );
void aout_DummySysPlaySamples ( aout_thread_t *p_aout, byte_t *buffer, int i_size );
void aout_DummySysClose ( aout_thread_t *p_aout );
#endif
#ifdef AUDIO_DSP
int aout_DspSysOpen ( aout_thread_t *p_aout );
int aout_DspSysReset ( aout_thread_t *p_aout );
int aout_DspSysSetFormat ( aout_thread_t *p_aout );
int aout_DspSysSetChannels ( aout_thread_t *p_aout );
int aout_DspSysSetRate ( aout_thread_t *p_aout );
long aout_DspSysGetBufInfo ( aout_thread_t *p_aout, long l_buffer_info );
void aout_DspSysPlaySamples ( aout_thread_t *p_aout, byte_t *buffer, int i_size );
void aout_DspSysClose ( aout_thread_t *p_aout );
#endif
#ifdef AUDIO_ESD
int aout_EsdSysOpen ( aout_thread_t *p_aout );
int aout_EsdSysReset ( aout_thread_t *p_aout );
int aout_EsdSysSetFormat ( aout_thread_t *p_aout );
int aout_EsdSysSetChannels ( aout_thread_t *p_aout );
int aout_EsdSysSetRate ( aout_thread_t *p_aout );
long aout_EsdSysGetBufInfo ( aout_thread_t *p_aout, long l_buffer_info );
void aout_EsdSysPlaySamples ( aout_thread_t *p_aout, byte_t *buffer, int i_size );
void aout_EsdSysClose ( aout_thread_t *p_aout );
#endif
......@@ -16,6 +16,8 @@
#include <sys/types.h>
#include <sys/uio.h> /* for input.h */
#include <dlfcn.h> /* plugins */
#include "config.h"
#include "common.h"
#include "mtime.h"
......@@ -29,8 +31,6 @@
#include "video.h"
#include "video_output.h"
#include "intf_sys.h"
/*****************************************************************************
* intf_channel_t: channel description
*****************************************************************************
......@@ -62,13 +62,14 @@ static int ParseChannel ( intf_channel_t *p_channel, char *psz_str );
/*****************************************************************************
* intf_Create: prepare interface before main loop
*****************************************************************************
* This function opens output devices and create specific interfaces. It send
* it's own error messages.
* This function opens output devices and creates specific interfaces. It sends
* its own error messages.
*****************************************************************************/
intf_thread_t* intf_Create( void )
{
intf_thread_t *p_intf;
char * psz_method;
char * psz_plugin;
/* Allocate structure */
p_intf = malloc( sizeof( intf_thread_t ) );
......@@ -78,69 +79,27 @@ intf_thread_t* intf_Create( void )
return( NULL );
}
/* initialize method-dependent functions */
/* Initialize method-dependent functions */
psz_method = main_GetPszVariable( VOUT_METHOD_VAR, VOUT_DEFAULT_METHOD );
psz_plugin = malloc( sizeof("./interface/intf_.so") + strlen(psz_method) );
sprintf( psz_plugin, "./interface/intf_%s.so", psz_method );
if( !strcmp(psz_method, "dummy") )
{
p_intf->p_sys_create = intf_DummySysCreate;
p_intf->p_sys_manage = intf_DummySysManage;
p_intf->p_sys_destroy = intf_DummySysDestroy;
}
#ifdef VIDEO_X11
else if( !strcmp(psz_method, "x11") )
{
p_intf->p_sys_create = intf_X11SysCreate;
p_intf->p_sys_manage = intf_X11SysManage;
p_intf->p_sys_destroy = intf_X11SysDestroy;
}
#endif
#ifdef VIDEO_FB
else if( !strcmp(psz_method, "fb") )
{
p_intf->p_sys_create = intf_FBSysCreate;
p_intf->p_sys_manage = intf_FBSysManage;
p_intf->p_sys_destroy = intf_FBSysDestroy;
}
#endif
#ifdef VIDEO_GGI
else if( !strcmp(psz_method, "ggi") )
{
p_intf->p_sys_create = intf_GGISysCreate;
p_intf->p_sys_manage = intf_GGISysManage;
p_intf->p_sys_destroy = intf_GGISysDestroy;
}
#endif
#ifdef VIDEO_DGA
else if( !strcmp(psz_method, "dga") )
{
p_intf->p_sys_create = intf_DGASysCreate;
p_intf->p_sys_manage = intf_DGASysManage;
p_intf->p_sys_destroy = intf_DGASysDestroy;
}
#endif
#ifdef VIDEO_GLIDE
else if( !strcmp(psz_method, "glide") )
{
p_intf->p_sys_create = intf_GlideSysCreate;
p_intf->p_sys_manage = intf_GlideSysManage;
p_intf->p_sys_destroy = intf_GlideSysDestroy;
}
#endif
#ifdef VIDEO_BEOS
else if( !strcmp(psz_method, "beos") )
{
p_intf->p_sys_create = intf_BSysCreate;
p_intf->p_sys_manage = intf_BSysManage;
p_intf->p_sys_destroy = intf_BSysDestroy;
}
#endif
else
p_intf->p_intf_plugin = dlopen( psz_plugin, RTLD_LAZY );
if( p_intf->p_intf_plugin == NULL )
{
intf_ErrMsg( "error: requested video output method not available\n" );
intf_ErrMsg( "error: could not open interface plugin %s\n", psz_plugin );
free( psz_plugin );
free( p_intf );
return( NULL );
}
free( psz_plugin );
/* Get plugins */
p_intf->p_sys_create = dlsym(p_intf->p_intf_plugin, "intf_SysCreate");
p_intf->p_sys_manage = dlsym(p_intf->p_intf_plugin, "intf_SysManage");
p_intf->p_sys_destroy = dlsym(p_intf->p_intf_plugin, "intf_SysDestroy");
/* Initialize structure */
p_intf->b_die = 0;
......@@ -157,6 +116,7 @@ intf_thread_t* intf_Create( void )
if( p_intf->p_console == NULL )
{
intf_ErrMsg("error: can't create control console\n");
dlclose( p_intf->p_intf_plugin );
free( p_intf );
return( NULL );
}
......@@ -164,6 +124,7 @@ intf_thread_t* intf_Create( void )
{
intf_ErrMsg("error: can't create interface\n");
intf_ConsoleDestroy( p_intf->p_console );
dlclose( p_intf->p_intf_plugin );
free( p_intf );
return( NULL );