]> git.sesse.net Git - vlc/blobdiff - modules/access/dvdnav.c
MKV: privatize matroska_segment_c methods
[vlc] / modules / access / dvdnav.c
index 4bc35fecfdb1eb46eae4ac41f926bbac0e966960..8cceae4b9a180f2e4256129c656fe8aa27e74aaa 100644 (file)
@@ -38,6 +38,7 @@
 #include <vlc_charset.h>
 #include <vlc_fs.h>
 #include <vlc_url.h>
+#include <vlc_vout.h>
 
 #include <vlc_dialog.h>
 
@@ -51,6 +52,7 @@
 #ifdef HAVE_FCNTL_H
 #   include <fcntl.h>
 #endif
+#include <errno.h>
 
 #include <vlc_keys.h>
 #include <vlc_iso_lang.h>
@@ -89,11 +91,11 @@ vlc_module_begin ()
     set_description( N_("DVDnav Input") )
     set_category( CAT_INPUT )
     set_subcategory( SUBCAT_INPUT_ACCESS )
-    add_integer( "dvdnav-angle", 1, NULL, ANGLE_TEXT,
+    add_integer( "dvdnav-angle", 1, ANGLE_TEXT,
         ANGLE_LONGTEXT, false )
-    add_integer( "dvdnav-caching", DEFAULT_PTS_DELAY / 1000, NULL,
+    add_integer( "dvdnav-caching", DEFAULT_PTS_DELAY / 1000,
         CACHING_TEXT, CACHING_LONGTEXT, true )
-    add_bool( "dvdnav-menu", true, NULL,
+    add_bool( "dvdnav-menu", true,
         MENU_TEXT, MENU_LONGTEXT, false )
     set_capability( "access_demux", 5 )
     add_shortcut( "dvd", "dvdnav", "file" )
@@ -129,7 +131,7 @@ struct demux_sys_t
     input_thread_t *p_input;
 
     /* event */
-    vlc_object_t *p_vout;
+    vout_thread_t *p_vout;
 
     /* palette for menus */
     uint32_t clut[16];
@@ -162,7 +164,7 @@ static void ESSubtitleUpdate( demux_t * );
 static void ButtonUpdate( demux_t *, bool );
 
 static void ESNew( demux_t *, int );
-static int ProbeDVD( demux_t *, char * );
+static int ProbeDVD( const char * );
 
 static char *DemuxGetLanguageCode( demux_t *p_demux, const char *psz_var );
 
@@ -188,11 +190,16 @@ static int Open( vlc_object_t *p_this )
     int         i_angle;
     char        *psz_file;
     char        *psz_code;
+    bool forced = false;
+
+    if( p_demux->psz_access != NULL
+     && !strncmp(p_demux->psz_access, "dvd", 3) )
+        forced = true;
 
     if( !p_demux->psz_file || !*p_demux->psz_file )
     {
         /* Only when selected */
-        if( !p_demux->psz_access || !*p_demux->psz_access )
+        if( !forced )
             return VLC_EGENERIC;
 
         psz_file = var_InheritString( p_this, "dvd" );
@@ -200,7 +207,7 @@ static int Open( vlc_object_t *p_this )
     else
         psz_file = strdup( p_demux->psz_file );
 
-#ifdef WIN32
+#if defined( WIN32 ) || defined( __OS2__ )
     if( psz_file != NULL )
     {
         /* Remove trailing backslash, otherwise dvdnav_open will fail */
@@ -215,7 +222,7 @@ static int Open( vlc_object_t *p_this )
         return VLC_EGENERIC;
 
     /* Try some simple probing to avoid going through dvdnav_open too often */
-    if( ProbeDVD( p_demux, psz_file ) != VLC_SUCCESS )
+    if( !forced && ProbeDVD( psz_file ) != VLC_SUCCESS )
     {
         free( psz_file );
         return VLC_EGENERIC;
@@ -383,7 +390,6 @@ static void Close( vlc_object_t *p_this )
 {
     demux_t     *p_demux = (demux_t*)p_this;
     demux_sys_t *p_sys = p_demux->p_sys;
-    int i;
 
     /* Stop vout event handler */
     var_DelCallback( p_sys->p_input, "intf-event", EventIntf, p_demux );
@@ -413,7 +419,7 @@ static void Close( vlc_object_t *p_this )
 
     vlc_object_release( p_sys->p_input );
 
-    for( i = 0; i < PS_TK_COUNT; i++ )
+    for( int i = 0; i < PS_TK_COUNT; i++ )
     {
         ps_track_t *tk = &p_sys->tk[i];
         if( tk->b_seen )
@@ -1425,22 +1431,18 @@ static int EventIntf( vlc_object_t *p_input, char const *psz_var,
 
     if (val.i_int == INPUT_EVENT_VOUT)
     {
-        vlc_object_t *p_vout;
-
-        p_vout = p_sys->p_vout;
-        if( p_vout != NULL )
+        if( p_sys->p_vout != NULL )
         {
-            var_DelCallback( p_vout, "mouse-moved", EventMouse, p_demux );
-            var_DelCallback( p_vout, "mouse-clicked", EventMouse, p_demux );
-            vlc_object_release( p_vout );
+            var_DelCallback( p_sys->p_vout, "mouse-moved", EventMouse, p_demux );
+            var_DelCallback( p_sys->p_vout, "mouse-clicked", EventMouse, p_demux );
+            vlc_object_release( p_sys->p_vout );
         }
 
-        p_vout = (vlc_object_t *)input_GetVout( (input_thread_t *)p_input );
-        p_sys->p_vout = p_vout;
-        if( p_vout != NULL )
+        p_sys->p_vout = input_GetVout( (input_thread_t *)p_input );
+        if( p_sys->p_vout != NULL )
         {
-            var_AddCallback( p_vout, "mouse-moved", EventMouse, p_demux );
-            var_AddCallback( p_vout, "mouse-clicked", EventMouse, p_demux );
+            var_AddCallback( p_sys->p_vout, "mouse-moved", EventMouse, p_demux );
+            var_AddCallback( p_sys->p_vout, "mouse-clicked", EventMouse, p_demux );
         }
     }
     (void) psz_var; (void) oldval;
@@ -1450,46 +1452,49 @@ static int EventIntf( vlc_object_t *p_input, char const *psz_var,
 /*****************************************************************************
  * ProbeDVD: very weak probing that avoids going too often into a dvdnav_open()
  *****************************************************************************/
-static int ProbeDVD( demux_t *p_demux, char *psz_name )
+static int ProbeDVD( const char *psz_name )
 {
-    (void)p_demux;
-#ifdef HAVE_SYS_STAT_H
-    struct stat stat_info;
-    uint8_t pi_anchor[2];
-    int i_fd, i_ret;
-
     if( !*psz_name )
-    {
         /* Triggers libdvdcss autodetection */
         return VLC_SUCCESS;
-    }
 
-    if( (i_fd = vlc_open( psz_name, O_RDONLY |O_NONBLOCK )) == -1 )
-    {
-        return VLC_SUCCESS; /* Let dvdnav_open() do the probing */
-    }
+    int fd = vlc_open( psz_name, O_RDONLY | O_NONBLOCK );
+    if( fd == -1 )
+#ifdef HAVE_FDOPENDIR
+        return VLC_EGENERIC;
+#else
+        return (errno == ENOENT) ? VLC_EGENERIC : VLC_SUCCESS;
+#endif
 
-    i_ret = VLC_EGENERIC;
+    int ret = VLC_EGENERIC;
 
-    if( fstat( i_fd, &stat_info ) || !S_ISREG( stat_info.st_mode ) )
+#ifdef HAVE_SYS_STAT_H
+    struct stat stat_info;
+
+    if( fstat( fd, &stat_info ) == -1 )
+         goto bailout;
+
+    if( !S_ISREG( stat_info.st_mode ) )
     {
-        if( !S_ISFIFO( stat_info.st_mode ) )
-            i_ret = VLC_SUCCESS; /* Let dvdnav_open() do the probing */
+        if( S_ISDIR( stat_info.st_mode ) || S_ISBLK( stat_info.st_mode ) )
+            ret = VLC_SUCCESS; /* Let dvdnav_open() do the probing */
         goto bailout;
     }
+#endif
+    /* Match extension as the anchor exhibits too many false positives */
+    const size_t len = strlen( psz_name );
+    if( len < 4 || strcasecmp( psz_name + len - 4, ".iso" ) )
+        goto bailout;
 
     /* Try to find the anchor (2 bytes at LBA 256) */
-    if( lseek( i_fd, 256 * DVD_VIDEO_LB_LEN, SEEK_SET ) != -1
-     && read( i_fd, pi_anchor, 2 ) == 2
-     && GetWLE( pi_anchor ) == 2 )
-        i_ret = VLC_SUCCESS; /* Found a potential anchor */
+    uint16_t anchor;
 
-bailout:
-    close( i_fd );
-
-    return i_ret;
-#else
+    if( lseek( fd, 256 * DVD_VIDEO_LB_LEN, SEEK_SET ) != -1
+     && read( fd, &anchor, 2 ) == 2
+     && GetWLE( &anchor ) == 2 )
+        ret = VLC_SUCCESS; /* Found a potential anchor */
 
-    return VLC_SUCCESS;
-#endif
+bailout:
+    close( fd );
+    return ret;
 }