#include <string.h> /* strdup() */
#include <vlc/vlc.h>
+#include <vlc/input.h>
#ifdef HAVE_DIRENT_H
# include <dirent.h>
#include "vlc_interface.h"
#include "intf_eject.h"
-#include "stream_control.h"
-#include "input_ext-intf.h"
-#include "input_ext-dec.h"
-#include "input_ext-plugins.h"
-#include "ninput.h"
-
#include "vlc_playlist.h"
#include "vlc_video.h"
static void CloseModule ( module_handle_t );
static void * GetSymbol ( module_handle_t, const char * );
static void CacheLoad ( vlc_object_t * );
-static void CacheLoadConfig ( module_t *, FILE * );
+static int CacheLoadConfig ( module_t *, FILE * );
static void CacheSave ( vlc_object_t * );
static void CacheSaveConfig ( module_t *, FILE * );
static void CacheMerge ( vlc_object_t *, module_t *, module_t * );
void __module_InitBank( vlc_object_t *p_this )
{
module_bank_t *p_bank;
+ vlc_value_t lockval;
+
+ var_Create( p_this->p_libvlc, "libvlc", VLC_VAR_MUTEX );
+ var_Get( p_this->p_libvlc, "libvlc", &lockval );
+ vlc_mutex_lock( lockval.p_address );
+ if( p_this->p_libvlc->p_module_bank )
+ {
+ p_this->p_libvlc->p_module_bank->i_usage++;
+ vlc_mutex_unlock( lockval.p_address );
+ var_Destroy( p_this->p_libvlc, "libvlc" );
+ return;
+ }
+ vlc_mutex_unlock( lockval.p_address );
+ var_Destroy( p_this->p_libvlc, "libvlc" );
p_bank = vlc_object_create( p_this, sizeof(module_bank_t) );
p_bank->psz_object_name = "module bank";
+ p_bank->i_usage = 1;
p_bank->i_cache = p_bank->i_loaded_cache = 0;
p_bank->pp_cache = p_bank->pp_loaded_cache = 0;
p_bank->b_cache = p_bank->b_cache_dirty =
p_this->p_libvlc->p_module_bank = p_bank;
vlc_object_attach( p_bank, p_this->p_libvlc );
+ module_LoadMain( p_this );
+
return;
}
void __module_EndBank( vlc_object_t *p_this )
{
module_t * p_next;
+ vlc_value_t lockval;
+
+ var_Create( p_this->p_libvlc, "libvlc", VLC_VAR_MUTEX );
+ var_Get( p_this->p_libvlc, "libvlc", &lockval );
+ vlc_mutex_lock( lockval.p_address );
+ if( !p_this->p_libvlc->p_module_bank )
+ {
+ vlc_mutex_unlock( lockval.p_address );
+ var_Destroy( p_this->p_libvlc, "libvlc" );
+ return;
+ }
+ if( --p_this->p_libvlc->p_module_bank->i_usage )
+ {
+ vlc_mutex_unlock( lockval.p_address );
+ var_Destroy( p_this->p_libvlc, "libvlc" );
+ return;
+ }
+ vlc_mutex_unlock( lockval.p_address );
+ var_Destroy( p_this->p_libvlc, "libvlc" );
#ifdef HAVE_DYNAMIC_PLUGINS
if( p_this->p_libvlc->p_module_bank->b_cache ) CacheSave( p_this );
{
module_t *p_module;
int i_score;
+ vlc_bool_t b_force;
module_list_t *p_next;
};
/* Parse the module list for capabilities and probe each of them */
for( i_which_module = 0; i_which_module < p_all->i_count; i_which_module++ )
{
- module_t * p_submodule = NULL;
- int i_shortcut_bonus = 0, i_submodule;
+ int i_shortcut_bonus = 0;
p_module = (module_t *)p_all->p_values[i_which_module].p_object;
/* Test that this module can do what we need */
if( strcmp( p_module->psz_capability, psz_capability ) )
{
- for( i_submodule = 0;
- i_submodule < p_module->i_children;
- i_submodule++ )
- {
- if( !strcmp( ((module_t*)p_module->pp_children[ i_submodule ])
- ->psz_capability, psz_capability ) )
- {
- p_submodule =
- (module_t*)p_module->pp_children[ i_submodule ];
- break;
- }
- }
-
- if( p_submodule == NULL )
- {
- continue;
- }
-
- p_module = p_submodule;
+ /* Don't recurse through the sub-modules because vlc_list_find()
+ * will list them anyway. */
+ continue;
}
/* Test if we have the required CPU */
/* Store this new module */
p_list[ i_index ].p_module = p_module;
p_list[ i_index ].i_score = p_module->i_score + i_shortcut_bonus;
+ p_list[ i_index ].b_force = !!i_shortcut_bonus;
/* Add it to the modules-to-probe list */
if( i_index == 0 )
}
#endif
+ p_this->b_force = p_tmp->b_force;
if( p_tmp->p_module->pf_activate
&& p_tmp->p_module->pf_activate( p_this ) == VLC_SUCCESS )
{
}
free( p_list );
+ p_this->b_force = VLC_FALSE;
if( p_module != NULL )
{
}
else if( p_first == NULL )
{
- msg_Err( p_this, "no %s module matched \"%s\"",
+ if( !strcmp( psz_capability, "access_demux" ) )
+ {
+ msg_Warn( p_this, "no %s module matched \"%s\"",
psz_capability, (psz_name && *psz_name) ? psz_name : "any" );
+ }
+ else
+ {
+ msg_Err( p_this, "no %s module matched \"%s\"",
+ psz_capability, (psz_name && *psz_name) ? psz_name : "any" );
+ }
}
else if( psz_name != NULL && *psz_name )
{
}
else
{
+ module_config_t *p_item;
+
p_module = p_cache_entry->p_module;
p_module->b_loaded = VLC_FALSE;
+
+ /* For now we force loading if the module's config contains
+ * callbacks or actions.
+ * Could be optimized by adding an API call.*/
+ for( p_item = p_module->p_config;
+ p_item->i_type != CONFIG_HINT_END; p_item++ )
+ {
+ if( p_item->pf_callback || p_item->i_action )
+ p_module = AllocatePlugin( p_this, psz_file );
+ }
}
}
FILE *file;
int i, j, i_size, i_read;
char p_cachestring[sizeof(PLUGINSCACHE_FILE COPYRIGHT_MESSAGE)];
- int *pi_cache;
+ int i_cache;
module_cache_t **pp_cache = 0;
+ int32_t i_file_size;
psz_homedir = p_this->p_vlc->psz_homedir;
if( !psz_homedir )
}
free( psz_filename );
+ /* Check the file size */
+ i_read = fread( &i_file_size, sizeof(char), sizeof(i_file_size), file );
+ if( i_read != sizeof(i_file_size) )
+ {
+ msg_Warn( p_this, "This doesn't look like a valid plugins cache "
+ "(too short)" );
+ fclose( file );
+ return;
+ }
+
+ fseek( file, 0, SEEK_END );
+ if( ftell( file ) != i_file_size )
+ {
+ msg_Warn( p_this, "This doesn't look like a valid plugins cache "
+ "(corrupted size)" );
+ fclose( file );
+ return;
+ }
+ fseek( file, sizeof(i_file_size), SEEK_SET );
+
/* Check the file is a plugins cache */
i_size = sizeof(PLUGINSCACHE_FILE COPYRIGHT_MESSAGE) - 1;
i_read = fread( p_cachestring, sizeof(char), i_size, file );
memcmp( p_cachestring, PLUGINSCACHE_FILE COPYRIGHT_MESSAGE, i_size ) )
{
msg_Warn( p_this, "This doesn't look like a valid plugins cache" );
+ fclose( file );
+ return;
}
- pi_cache = &p_this->p_libvlc->p_module_bank->i_loaded_cache;
- fread( pi_cache, sizeof(char), sizeof(*pi_cache), file );
+ p_this->p_libvlc->p_module_bank->i_loaded_cache = 0;
+ fread( &i_cache, sizeof(char), sizeof(i_cache), file );
pp_cache = p_this->p_libvlc->p_module_bank->pp_loaded_cache =
- malloc( *pi_cache * sizeof(void *) );
-
- for( i = 0; i < *pi_cache; i++ )
- {
- int32_t i_size;
- int i_submodules;
+ malloc( i_cache * sizeof(void *) );
#define LOAD_IMMEDIATE(a) \
- fread( &a, sizeof(char), sizeof(a), file )
+ if( fread( &a, sizeof(char), sizeof(a), file ) != sizeof(a) ) goto error
#define LOAD_STRING(a) \
- { fread( &i_size, sizeof(char), sizeof(int32_t), file ); \
- if( i_size ) { \
- a = malloc( i_size ); \
- fread( a, sizeof(char), i_size, file ); \
- } else a = 0; \
- } while(0)
+ { if( fread( &i_size, sizeof(char), sizeof(i_size), file ) \
+ != sizeof(i_size) ) goto error; \
+ if( i_size ) { \
+ a = malloc( i_size ); \
+ if( fread( a, sizeof(char), i_size, file ) != (size_t)i_size ) \
+ goto error; \
+ } else a = 0; \
+ } while(0)
+
+
+ for( i = 0; i < i_cache; i++ )
+ {
+ int16_t i_size;
+ int i_submodules;
pp_cache[i] = malloc( sizeof(module_cache_t) );
+ p_this->p_libvlc->p_module_bank->i_loaded_cache++;
/* Save common info */
LOAD_STRING( pp_cache[i]->psz_file );
LOAD_IMMEDIATE( pp_cache[i]->p_module->b_submodule );
/* Config stuff */
- CacheLoadConfig( pp_cache[i]->p_module, file );
+ if( CacheLoadConfig( pp_cache[i]->p_module, file ) != VLC_SUCCESS )
+ goto error;
LOAD_STRING( pp_cache[i]->p_module->psz_filename );
}
fclose( file );
+ return;
+ error:
+
+ msg_Warn( p_this, "plugins cache not loaded (corrupted)" );
+
+ /* TODO: cleanup */
+ p_this->p_libvlc->p_module_bank->i_loaded_cache = 0;
+
+ fclose( file );
return;
}
-void CacheLoadConfig( module_t *p_module, FILE *file )
+int CacheLoadConfig( module_t *p_module, FILE *file )
{
int i, j, i_lines;
- int32_t i_size;
+ int16_t i_size;
/* Calculate the structure length */
LOAD_IMMEDIATE( p_module->i_config_items );
if( p_module->p_config == NULL )
{
msg_Err( p_module, "config error: can't duplicate p_config" );
- return;
+ return VLC_ENOMEM;
}
/* Do the duplication job */
}
}
- p_module->p_config[i].pf_callback = 0;
+ LOAD_IMMEDIATE( p_module->p_config[i].pf_callback );
}
p_module->p_config[i].i_type = CONFIG_HINT_END;
+
+ return VLC_SUCCESS;
+
+ error:
+
+ return VLC_EGENERIC;
}
/*****************************************************************************
FILE *file;
int i, j, i_cache;
module_cache_t **pp_cache;
+ int32_t i_file_size = 0;
psz_homedir = p_this->p_vlc->psz_homedir;
if( !psz_homedir )
}
free( psz_filename );
+ /* Empty space for file size */
+ fwrite( &i_file_size, sizeof(char), sizeof(i_file_size), file );
+
/* Contains version number */
fprintf( file, PLUGINSCACHE_FILE COPYRIGHT_MESSAGE );
fwrite( &i_cache, sizeof(char), sizeof(i_cache), file );
+#define SAVE_IMMEDIATE(a) \
+ fwrite( &a, sizeof(char), sizeof(a), file )
+#define SAVE_STRING(a) \
+ { i_size = a ? strlen( a ) + 1 : 0; \
+ fwrite( &i_size, sizeof(char), sizeof(i_size), file ); \
+ if( a ) fwrite( a, sizeof(char), i_size, file ); \
+ } while(0)
+
for( i = 0; i < i_cache; i++ )
{
- int32_t i_size;
+ int16_t i_size;
int32_t i_submodule;
-#define SAVE_IMMEDIATE(a) \
- fwrite( &a, sizeof(char), sizeof(a), file )
-#define SAVE_STRING(a) \
- { i_size = a ? strlen( a ) + 1 : 0; \
- fwrite( &i_size, sizeof(char), sizeof(int32_t), file ); \
- if( a ) fwrite( a, sizeof(char), i_size, file ); \
- } while(0)
-
/* Save common info */
SAVE_STRING( pp_cache[i]->psz_file );
SAVE_IMMEDIATE( pp_cache[i]->i_time );
}
}
+ /* Fill-up file size */
+ i_file_size = ftell( file );
+ fseek( file, 0, SEEK_SET );
+ fwrite( &i_file_size, sizeof(char), sizeof(i_file_size), file );
+
fclose( file );
return;
{
int i, j, i_lines = 0;
module_config_t *p_item;
- int32_t i_size;
+ int16_t i_size;
SAVE_IMMEDIATE( p_module->i_config_items );
SAVE_IMMEDIATE( p_module->i_bool_items );
for( j = 0; j < p_module->p_config[i].i_action; j++ )
SAVE_STRING( p_module->p_config[i].ppsz_action_text[j] );
+
+ SAVE_IMMEDIATE( p_module->p_config[i].pf_callback );
}
}