]> git.sesse.net Git - vlc/blobdiff - modules/access/dvdnav.c
imem: don't pass data pointer through MRL either
[vlc] / modules / access / dvdnav.c
index 6d0f2a6ebd050d3d91290b4bb22be17bf9d55b66..083f7164be6cb06d3948ec5a6efc0107546d6fb8 100644 (file)
@@ -16,9 +16,9 @@
  * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
 
 /*****************************************************************************
 #include <vlc_access.h>
 #include <vlc_demux.h>
 #include <vlc_charset.h>
+#include <vlc_fs.h>
 
 #include <vlc_dialog.h>
 
 #ifdef HAVE_UNISTD_H
 #   include <unistd.h>
 #endif
-#ifdef HAVE_SYS_TYPES_H
-#   include <sys/types.h>
-#endif
+#include <sys/types.h>
 #ifdef HAVE_SYS_STAT_H
 #   include <sys/stat.h>
 #endif
@@ -52,8 +51,8 @@
 #   include <fcntl.h>
 #endif
 
-#include "vlc_keys.h"
-#include "vlc_iso_lang.h"
+#include <vlc_keys.h>
+#include <vlc_iso_lang.h>
 
 /* FIXME we should find a better way than including that */
 #include "../../src/text/iso-639_def.h"
@@ -139,8 +138,6 @@ struct demux_sys_t
     bool b_spu_change;
 
     /* */
-    int i_aspect;
-
     int           i_title;
     input_title_t **title;
 
@@ -183,12 +180,12 @@ static int Open( vlc_object_t *p_this )
     int         i_angle;
     char        *psz_name;
     char        *psz_code;
-    vlc_value_t val;
 
     if( !p_demux->psz_path || !*p_demux->psz_path )
     {
         /* Only when selected */
-        if( !p_this->b_force ) return VLC_EGENERIC;
+        if( !p_demux->psz_access || !*p_demux->psz_access )
+            return VLC_EGENERIC;
 
         psz_name = var_CreateGetString( p_this, "dvd" );
         if( !psz_name )
@@ -200,8 +197,11 @@ static int Open( vlc_object_t *p_this )
         psz_name = ToLocaleDup( p_demux->psz_path );
 
 #ifdef WIN32
-    if( psz_name[0] && psz_name[1] == ':' &&
-        psz_name[2] == '\\' && psz_name[3] == '\0' ) psz_name[2] = '\0';
+    /* Remove trailing backslash, otherwise dvdnav_open will fail */
+    if( *psz_name && *(psz_name + strlen(psz_name) - 1) == '\\' )
+    {
+        *(psz_name + strlen(psz_name) - 1) = '\0';
+    }
 #endif
 
     /* Try some simple probing to avoid going through dvdnav_open too often */
@@ -226,7 +226,6 @@ static int Open( vlc_object_t *p_this )
     p_sys->b_reset_pcr = false;
 
     ps_track_init( p_sys->tk );
-    p_sys->i_aspect = -1;
     p_sys->i_mux_rate = 0;
     p_sys->i_pgc_length = 0;
     p_sys->b_spu_change = false;
@@ -303,16 +302,14 @@ static int Open( vlc_object_t *p_this )
 
     DemuxTitles( p_demux );
 
-    var_Create( p_demux, "dvdnav-menu", VLC_VAR_BOOL|VLC_VAR_DOINHERIT );
-    var_Get( p_demux, "dvdnav-menu", &val );
-    if( val.b_bool )
+    if( var_CreateGetBool( p_demux, "dvdnav-menu" ) )
     {
         msg_Dbg( p_demux, "trying to go to dvd menu" );
 
         if( dvdnav_title_play( p_sys->dvdnav, 1 ) != DVDNAV_STATUS_OK )
         {
             msg_Err( p_demux, "cannot set title (can't decrypt DVD?)" );
-            dialog_Fatal( p_demux, _("Playback failure"),
+            dialog_Fatal( p_demux, _("Playback failure"), "%s",
                             _("VLC cannot set the DVD's title. It possibly "
                               "cannot decrypt the entire disc.") );
             dvdnav_close( p_sys->dvdnav );
@@ -330,16 +327,15 @@ static int Open( vlc_object_t *p_this )
         }
     }
 
-    var_Create( p_demux, "dvdnav-angle", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT );
-    var_Get( p_demux, "dvdnav-angle", &val );
-    i_angle = val.i_int > 0 ? val.i_int : 1;
+    i_angle = var_CreateGetInteger( p_demux, "dvdnav-angle" );
+    if( i_angle <= 0 ) i_angle = 1;
 
     /* Update default_pts to a suitable value for dvdnav access */
     var_Create( p_demux, "dvdnav-caching", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT );
 
     /* FIXME hack hack hack hack FIXME */
     /* Get p_input and create variable */
-    p_sys->p_input = vlc_object_find( p_demux, VLC_OBJECT_INPUT, FIND_PARENT );
+    p_sys->p_input = demux_GetParentInput( p_demux );
     var_Create( p_sys->p_input, "x-start", VLC_VAR_INTEGER );
     var_Create( p_sys->p_input, "y-start", VLC_VAR_INTEGER );
     var_Create( p_sys->p_input, "x-end", VLC_VAR_INTEGER );
@@ -385,7 +381,7 @@ static void Close( vlc_object_t *p_this )
 
     /* Stop still image handler */
     if( p_sys->still.b_created )
-        vlc_timer_destroy( &p_sys->still.timer );
+        vlc_timer_destroy( p_sys->still.timer );
     vlc_mutex_destroy( &p_sys->still.lock );
 
     var_Destroy( p_sys->p_input, "highlight-mutex" );
@@ -419,11 +415,7 @@ static void Close( vlc_object_t *p_this )
 static int Control( demux_t *p_demux, int i_query, va_list args )
 {
     demux_sys_t *p_sys = p_demux->p_sys;
-    double f, *pf;
-    bool *pb;
-    int64_t *pi64;
     input_title_t ***ppp_title;
-    int          *pi_int;
     int i;
 
     switch( i_query )
@@ -440,41 +432,37 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
                 return VLC_EGENERIC;
             }
 
-            if( i_query == DEMUX_GET_POSITION )
+            switch( i_query )
             {
-                pf = (double*)va_arg( args, double* );
-                *pf = (double)pos / (double)len;
+            case DEMUX_GET_POSITION:
+                *va_arg( args, double* ) = (double)pos / (double)len;
                 return VLC_SUCCESS;
-            }
-            else if( i_query == DEMUX_SET_POSITION )
-            {
-                f = (double)va_arg( args, double );
-                pos = f * len;
+
+            case DEMUX_SET_POSITION:
+                pos = va_arg( args, double ) * len;
                 if( dvdnav_sector_search( p_sys->dvdnav, pos, SEEK_SET ) ==
                       DVDNAV_STATUS_OK )
                 {
                     return VLC_SUCCESS;
                 }
-            }
-            else if( i_query == DEMUX_GET_TIME )
-            {
-                pi64 = (int64_t*)va_arg( args, int64_t * );
+                break;
+
+            case DEMUX_GET_TIME:
                 if( p_sys->i_pgc_length > 0 )
                 {
-                    *pi64 = p_sys->i_pgc_length * pos / len;
+                    *va_arg( args, int64_t * ) = p_sys->i_pgc_length*pos/len;
                     return VLC_SUCCESS;
                 }
-            }
-            else if( i_query == DEMUX_GET_LENGTH )
-            {
-                pi64 = (int64_t*)va_arg( args, int64_t * );
+                break;
+
+            case DEMUX_GET_LENGTH:
                 if( p_sys->i_pgc_length > 0 )
                 {
-                    *pi64 = (int64_t)p_sys->i_pgc_length;
+                    *va_arg( args, int64_t * ) = (int64_t)p_sys->i_pgc_length;
                     return VLC_SUCCESS;
                 }
+                break;
             }
-
             return VLC_EGENERIC;
         }
 
@@ -483,21 +471,19 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
         case DEMUX_CAN_SEEK:
         case DEMUX_CAN_CONTROL_PACE:
             /* TODO */
-            pb = (bool*)va_arg( args, bool * );
-            *pb = true;
+            *va_arg( args, bool * ) = true;
             return VLC_SUCCESS;
 
         case DEMUX_SET_PAUSE_STATE:
             return VLC_SUCCESS;
 
         case DEMUX_GET_TITLE_INFO:
-            ppp_title = (input_title_t***)va_arg( args, input_title_t*** );
-            pi_int    = (int*)va_arg( args, int* );
-            *((int*)va_arg( args, int* )) = 0; /* Title offset */
-            *((int*)va_arg( args, int* )) = 1; /* Chapter offset */
+            ppp_title = va_arg( args, input_title_t*** );
+            *va_arg( args, int* ) = p_sys->i_title;
+            *va_arg( args, int* ) = 0; /* Title offset */
+            *va_arg( args, int* ) = 1; /* Chapter offset */
 
             /* Duplicate title infos */
-            *pi_int = p_sys->i_title;
             *ppp_title = malloc( sizeof( input_title_t ** ) * p_sys->i_title );
             for( i = 0; i < p_sys->i_title; i++ )
             {
@@ -522,40 +508,21 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
             return VLC_SUCCESS;
 
         case DEMUX_SET_SEEKPOINT:
-            i = (int)va_arg( args, int );
+            i = va_arg( args, int );
             if( p_demux->info.i_title == 0 )
             {
-                int i_ret;
-                /* Special case */
-                switch( i )
-                {
-                case 0:
-                    i_ret = dvdnav_menu_call( p_sys->dvdnav, DVD_MENU_Escape );
-                    break;
-                case 1:
-                    i_ret = dvdnav_menu_call( p_sys->dvdnav, DVD_MENU_Root );
-                    break;
-                case 2:
-                    i_ret = dvdnav_menu_call( p_sys->dvdnav, DVD_MENU_Title );
-                    break;
-                case 3:
-                    i_ret = dvdnav_menu_call( p_sys->dvdnav, DVD_MENU_Part );
-                    break;
-                case 4:
-                    i_ret = dvdnav_menu_call( p_sys->dvdnav,
-                                              DVD_MENU_Subpicture );
-                    break;
-                case 5:
-                    i_ret = dvdnav_menu_call( p_sys->dvdnav, DVD_MENU_Audio );
-                    break;
-                case 6:
-                    i_ret = dvdnav_menu_call( p_sys->dvdnav, DVD_MENU_Angle );
-                    break;
-                default:
-                    return VLC_EGENERIC;
-                }
-
-                if( i_ret != DVDNAV_STATUS_OK )
+                static const int argtab[] = {
+                    DVD_MENU_Escape,
+                    DVD_MENU_Root,
+                    DVD_MENU_Title,
+                    DVD_MENU_Part,
+                    DVD_MENU_Subpicture,
+                    DVD_MENU_Audio,
+                    DVD_MENU_Angle
+                };
+                enum { numargs = sizeof(argtab)/sizeof(int) };
+                if( (unsigned)i >= numargs || DVDNAV_STATUS_OK !=
+                           dvdnav_menu_call(p_sys->dvdnav,argtab[i]) )
                     return VLC_EGENERIC;
             }
             else if( dvdnav_part_play( p_sys->dvdnav, p_demux->info.i_title,
@@ -569,8 +536,8 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
             return VLC_SUCCESS;
 
         case DEMUX_GET_PTS_DELAY:
-            pi64 = (int64_t*)va_arg( args, int64_t * );
-            *pi64 = (int64_t)var_GetInteger( p_demux, "dvdnav-caching" ) *1000;
+            *va_arg( args, int64_t * )
+                 = (int64_t)var_GetInteger( p_demux, "dvdnav-caching" ) *1000;
             return VLC_SUCCESS;
 
         case DEMUX_GET_META:
@@ -638,6 +605,7 @@ static int Demux( demux_t *p_demux )
     {
     case DVDNAV_BLOCK_OK:   /* mpeg block */
         vlc_mutex_lock( &p_sys->still.lock );
+        vlc_timer_schedule( p_sys->still.timer, false, 0, 0 );
         p_sys->still.b_enabled = false;
         vlc_mutex_unlock( &p_sys->still.lock );
         if( p_sys->b_reset_pcr )
@@ -666,8 +634,8 @@ static int Demux( demux_t *p_demux )
 
             if( event->length != 0xff && p_sys->still.b_created )
             {
-                mtime_t delay = event->length * INT64_C(1) * CLOCK_FREQ;
-                vlc_timer_schedule( &p_sys->still.timer, false, delay, 0 );
+                mtime_t delay = event->length * CLOCK_FREQ;
+                vlc_timer_schedule( p_sys->still.timer, false, delay, 0 );
             }
 
             b_still_init = true;
@@ -758,10 +726,6 @@ static int Demux( demux_t *p_demux )
         msg_Dbg( p_demux, "     - vtsN=%d", event->new_vtsN );
         msg_Dbg( p_demux, "     - domain=%d", event->new_domain );
 
-        /* dvdnav_get_video_aspect / dvdnav_get_video_scale_permission */
-        /* TODO check if we always have VTS and CELL */
-        p_sys->i_aspect = dvdnav_get_video_aspect( p_sys->dvdnav );
-
         /* reset PCR */
         es_out_Control( p_demux->out, ES_OUT_RESET_PCR );
 
@@ -911,7 +875,7 @@ static char *DemuxGetLanguageCode( demux_t *p_demux, const char *psz_var )
     if( ( p = strchr( psz_lang, ',' ) ) )
         *p = '\0';
 
-    for( pl = p_languages; pl->psz_iso639_1 != NULL; pl++ )
+    for( pl = p_languages; pl->psz_eng_name != NULL; pl++ )
     {
         if( *psz_lang == '\0' )
             continue;
@@ -925,7 +889,7 @@ static char *DemuxGetLanguageCode( demux_t *p_demux, const char *psz_var )
 
     free( psz_lang );
 
-    if( pl->psz_iso639_1 != NULL )
+    if( pl->psz_eng_name != NULL )
         return strdup( pl->psz_iso639_1 );
 
     return strdup(LANGUAGE_DEFAULT);
@@ -1024,8 +988,10 @@ static void ButtonUpdate( demux_t *p_demux, bool b_mode )
         {
             pci_t *pci = dvdnav_get_current_nav_pci( p_sys->dvdnav );
 
-            b_button_ok = dvdnav_get_highlight_area( pci, i_button, b_mode, &hl ) == DVDNAV_STATUS_OK;
+            b_button_ok = DVDNAV_STATUS_OK ==
+                      dvdnav_get_highlight_area( pci, i_button, b_mode, &hl );
         }
+
         if( b_button_ok )
         {
             int i;
@@ -1041,15 +1007,14 @@ static void ButtonUpdate( demux_t *p_demux, bool b_mode )
             }
 
             vlc_mutex_lock( p_mutex );
-            val.i_int = hl.sx; var_Set( p_sys->p_input, "x-start", val );
-            val.i_int = hl.ex; var_Set( p_sys->p_input, "x-end", val );
-            val.i_int = hl.sy; var_Set( p_sys->p_input, "y-start", val );
-            val.i_int = hl.ey; var_Set( p_sys->p_input, "y-end", val );
+            var_SetInteger( p_sys->p_input, "x-start", hl.sx );
+            var_SetInteger( p_sys->p_input, "x-end",  hl.ex );
+            var_SetInteger( p_sys->p_input, "y-start", hl.sy );
+            var_SetInteger( p_sys->p_input, "y-end", hl.ey );
 
-            val.p_address = (void *)p_sys->palette;
-            var_Set( p_sys->p_input, "menu-palette", val );
+            var_SetAddress( p_sys->p_input, "menu-palette", p_sys->palette );
 
-            val.b_bool = true; var_Set( p_sys->p_input, "highlight", val );
+            var_SetBool( p_sys->p_input, "highlight", true );
             vlc_mutex_unlock( p_mutex );
 
             msg_Dbg( p_demux, "buttonUpdate %d", i_button );
@@ -1061,8 +1026,7 @@ static void ButtonUpdate( demux_t *p_demux, bool b_mode )
 
             /* Show all */
             vlc_mutex_lock( p_mutex );
-            val.b_bool = false;
-            var_Set( p_sys->p_input, "highlight", val );
+            var_SetBool( p_sys->p_input, "highlight", false );
             vlc_mutex_unlock( p_mutex );
         }
     }
@@ -1213,16 +1177,6 @@ static void ESNew( demux_t *p_demux, int i_id )
     /* Add a new ES */
     if( tk->fmt.i_cat == VIDEO_ES )
     {
-        switch( p_sys->i_aspect )
-        {
-        case 1: tk->fmt.video.i_aspect = VOUT_ASPECT_FACTOR; break;
-        case 2: tk->fmt.video.i_aspect = VOUT_ASPECT_FACTOR * 4 / 3; break;
-        case 3: tk->fmt.video.i_aspect = VOUT_ASPECT_FACTOR * 16 / 9; break;
-        case 4: tk->fmt.video.i_aspect = VOUT_ASPECT_FACTOR * 221 / 10; break;
-        default:
-            tk->fmt.video.i_aspect = 0;
-            break;
-        }
         b_select = true;
     }
     else if( tk->fmt.i_cat == AUDIO_ES )
@@ -1319,8 +1273,8 @@ static int EventMouse( vlc_object_t *p_vout, char const *psz_var,
 
     /* FIXME? PCI usage thread safe? */
     pci_t *pci = dvdnav_get_current_nav_pci( p_sys->dvdnav );
-    int x = var_GetInteger( p_vout, "mouse-x" );
-    int y = var_GetInteger( p_vout, "mouse-y" );
+    int x = val.coords.x;
+    int y = val.coords.y;
 
     if( psz_var[6] == 'm' ) /* mouse-moved */
         dvdnav_mouse_select( p_sys->dvdnav, pci, x, y );
@@ -1331,8 +1285,8 @@ static int EventMouse( vlc_object_t *p_vout, char const *psz_var,
         ButtonUpdate( p_demux, true );
         dvdnav_mouse_activate( p_sys->dvdnav, pci, x, y );
     }
-
-    (void)oldval; (void)val;
+    (void)p_vout;
+    (void)oldval;
     return VLC_SUCCESS;
 }
 
@@ -1416,30 +1370,27 @@ static int ProbeDVD( demux_t *p_demux, char *psz_name )
         return VLC_SUCCESS;
     }
 
-    if( !strcmp( psz_name, "-" ) ) /* stdin -> file access */
-        return VLC_EGENERIC;
-
-    if( (i_fd = utf8_open( psz_name, O_RDONLY |O_NONBLOCK, 0666 )) == -1 )
+    if( (i_fd = vlc_open( psz_name, O_RDONLY |O_NONBLOCK )) == -1 )
     {
         return VLC_SUCCESS; /* Let dvdnav_open() do the probing */
     }
 
+    i_ret = VLC_EGENERIC;
+
     if( fstat( i_fd, &stat_info ) || !S_ISREG( stat_info.st_mode ) )
     {
-        close( i_fd );
-
-        if( S_ISFIFO( stat_info.st_mode ) )
-            return VLC_EGENERIC;
-        return VLC_SUCCESS; /* Let dvdnav_open() do the probing */
+        if( !S_ISFIFO( stat_info.st_mode ) )
+            i_ret = VLC_SUCCESS; /* Let dvdnav_open() do the probing */
+        goto bailout;
     }
 
     /* Try to find the anchor (2 bytes at LBA 256) */
-    i_ret = VLC_EGENERIC;
     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 */
 
+bailout:
     close( i_fd );
 
     return i_ret;