* dvd.c : DVD input module for vlc
*****************************************************************************
* Copyright (C) 2000 VideoLAN
- * $Id: dvd.c,v 1.6 2001/03/21 13:42:33 sam Exp $
+ * $Id: dvd.c,v 1.12 2001/08/06 13:28:00 sam Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
+#define MODULE_NAME dvd
+#include "modules_inner.h"
+
/*****************************************************************************
* Preamble
*****************************************************************************/
#include "defs.h"
-#ifdef HAVE_CSS
-#define MODULE_NAME dvd-css
-#else /* HAVE_CSS */
-#define MODULE_NAME dvd
-#endif /* HAVE_CSS */
-#include "modules_inner.h"
-
#include <stdlib.h> /* malloc(), free() */
#include <string.h> /* strdup() */
+#ifdef GOD_DAMN_DMCA
+# include <dlfcn.h>
+# include "dummy_dvdcss.h"
+#endif
+
#include "config.h"
#include "common.h" /* boolean_t, byte_t */
#include "threads.h"
#include "mtime.h"
+#include "intf_msg.h"
+
#include "modules.h"
+#include "modules_export.h"
/*****************************************************************************
- * Build configuration tree.
+ * Capabilities defined in the other files.
*****************************************************************************/
-MODULE_CONFIG_START
-ADD_WINDOW( "Configuration for DVD module" )
- ADD_COMMENT( "foobar !" )
-MODULE_CONFIG_END
+void _M( input_getfunctions )( function_list_t * p_function_list );
/*****************************************************************************
- * Capabilities defined in the other files.
+ * Local prototypes.
*****************************************************************************/
-void _M( input_getfunctions )( function_list_t * p_function_list );
+#ifdef GOD_DAMN_DMCA
+static void *p_libdvdcss;
+static void ProbeLibDVDCSS ( void );
+static void UnprobeLibDVDCSS( void );
+#endif
/*****************************************************************************
- * 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.
+ * Build configuration tree.
*****************************************************************************/
-MODULE_INIT
-{
- p_module->psz_name = MODULE_STRING;
-#ifdef HAVE_CSS
- p_module->psz_longname = "full DVD input module with CSS decryption";
-#else /* HAVE_CSS */
- p_module->psz_longname = "DVD input module, CSS decryption disabled";
-#endif /* HAVE_CSS */
- p_module->psz_version = VERSION;
+MODULE_CONFIG_START
+ADD_WINDOW( "Configuration for DVD module" )
+ ADD_COMMENT( "foobar !" )
+MODULE_CONFIG_STOP
+MODULE_INIT_START
p_module->i_capabilities = MODULE_CAPABILITY_NULL
| MODULE_CAPABILITY_INPUT;
+#ifdef GOD_DAMN_DMCA
+ p_module->psz_longname = "DVD input module, uses libdvdcss if present";
+#else
+ p_module->psz_longname = "DVD input module, linked with libdvdcss";
+#endif
+MODULE_INIT_STOP
+
+MODULE_ACTIVATE_START
+ _M( input_getfunctions )( &p_module->p_functions->input );
+#ifdef GOD_DAMN_DMCA
+ ProbeLibDVDCSS();
+#endif
+MODULE_ACTIVATE_STOP
- return( 0 );
-}
+MODULE_DEACTIVATE_START
+#ifdef GOD_DAMN_DMCA
+ UnprobeLibDVDCSS();
+#endif
+MODULE_DEACTIVATE_STOP
+
+/* Following functions are local */
+
+#ifdef GOD_DAMN_DMCA
/*****************************************************************************
- * ActivateModule: set the module to an usable state.
+ * ProbeLibDVDCSS: look for a libdvdcss object.
*****************************************************************************
- * 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().
+ * This functions looks for libdvdcss, using dlopen(), and fills function
+ * pointers with what it finds. On failure, uses the dummy libdvdcss
+ * replacement provided by vlc.
*****************************************************************************/
-MODULE_ACTIVATE
+static void ProbeLibDVDCSS( void )
{
- p_module->p_functions = malloc( sizeof( module_functions_t ) );
- if( p_module->p_functions == NULL )
+ char *pp_filelist[4] = { "libdvdcss.so.0",
+ "./libdvdcss.so.0",
+ "./lib/libdvdcss.so.0",
+ NULL };
+ char **pp_file = pp_filelist;
+
+ /* Try to open the dynamic object */
+ do
+ {
+ p_libdvdcss = dlopen( *pp_file, RTLD_LAZY );
+ if( p_libdvdcss != NULL )
+ {
+ intf_WarnMsg( 2, "module: builtin module `dvd' found libdvdcss "
+ "in `%s'", *pp_file );
+ break;
+ }
+ pp_file++;
+
+ } while( *pp_file != NULL );
+
+ /* If libdvdcss.so was found, check that it's valid */
+ if( p_libdvdcss == NULL )
{
- return( -1 );
+ intf_ErrMsg( "dvd warning: libdvdcss.so.0 not present" );
+ }
+ else
+ {
+ /* Check for libdvdcss 0.0.1 */
+ if( dlsym( p_libdvdcss, "dvdcss_crack" ) != NULL )
+ {
+ intf_ErrMsg( "dvd warning: libdvdcss.so.0 has deprecated symbol "
+ "dvdcss_crack(), please upgrade" );
+ dlclose( p_libdvdcss );
+ p_libdvdcss = NULL;
+ }
+ else
+ {
+ dvdcss_open = dlsym( p_libdvdcss, "dvdcss_open" );
+ dvdcss_close = dlsym( p_libdvdcss, "dvdcss_close" );
+ dvdcss_title = dlsym( p_libdvdcss, "dvdcss_title" );
+ dvdcss_seek = dlsym( p_libdvdcss, "dvdcss_seek" );
+ dvdcss_read = dlsym( p_libdvdcss, "dvdcss_read" );
+ dvdcss_readv = dlsym( p_libdvdcss, "dvdcss_readv" );
+ dvdcss_error = dlsym( p_libdvdcss, "dvdcss_error" );
+
+ if( dvdcss_open == NULL || dvdcss_close == NULL
+ || dvdcss_title == NULL || dvdcss_seek == NULL
+ || dvdcss_read == NULL || dvdcss_readv == NULL
+ || dvdcss_error == NULL )
+ {
+ intf_ErrMsg( "dvd warning: missing symbols in libdvdcss.so.0, "
+ "please upgrade libdvdcss or vlc" );
+ dlclose( p_libdvdcss );
+ p_libdvdcss = NULL;
+ }
+ }
}
- _M( input_getfunctions )( &p_module->p_functions->input );
-
- p_module->p_config = p_config;
-
- return( 0 );
+ /* If libdvdcss was not found or was not valid, use the dummy
+ * replacement functions. */
+ if( p_libdvdcss == NULL )
+ {
+ intf_ErrMsg( "dvd warning: no valid libdvdcss found, "
+ "I will only play unencrypted DVDs" );
+
+ dvdcss_open = dummy_dvdcss_open;
+ dvdcss_close = dummy_dvdcss_close;
+ dvdcss_title = dummy_dvdcss_title;
+ dvdcss_seek = dummy_dvdcss_seek;
+ dvdcss_read = dummy_dvdcss_read;
+ dvdcss_readv = dummy_dvdcss_readv;
+ dvdcss_error = dummy_dvdcss_error;
+ }
}
/*****************************************************************************
- * 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.
+ * UnprobeLibDVDCSS: free resources allocated by ProbeLibDVDCSS, if any.
*****************************************************************************/
-MODULE_DEACTIVATE
+static void UnprobeLibDVDCSS( void )
{
- free( p_module->p_functions );
-
- return( 0 );
+ if( p_libdvdcss != NULL )
+ {
+ dlclose( p_libdvdcss );
+ p_libdvdcss = NULL;
+ }
}
+#endif