]> git.sesse.net Git - vlc/blobdiff - plugins/dvd/dvd_access.c
* ALL: new module API. Makes a few things a lot simpler, and we gain
[vlc] / plugins / dvd / dvd_access.c
index c0ef18b23c447bd43ff0bd8f4e30f355ede3899e..735665c1ed6253dfbf553e98b111a06d52ea2d9f 100644 (file)
@@ -8,7 +8,7 @@
  *  -dvd_udf to find files
  *****************************************************************************
  * Copyright (C) 1998-2001 VideoLAN
- * $Id: dvd_access.c,v 1.9 2002/03/18 19:14:52 sam Exp $
+ * $Id: dvd_access.c,v 1.22 2002/07/31 20:56:51 sam Exp $
  *
  * Author: Stéphane Borel <stef@via.ecp.fr>
  *
@@ -34,7 +34,8 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include <videolan/vlc.h>
+#include <vlc/vlc.h>
+#include <vlc/input.h>
 
 #ifdef HAVE_UNISTD_H
 #   include <unistd.h>
 #ifdef GOD_DAMN_DMCA
 #   include "dummy_dvdcss.h"
 #else
-#   include <videolan/dvdcss.h>
+#   include <dvdcss/dvdcss.h>
 #endif
 
-#include "stream_control.h"
-#include "input_ext-intf.h"
-#include "input_ext-dec.h"
-#include "input_ext-plugins.h"
-
 #include "dvd.h"
 #include "dvd_es.h"
 #include "dvd_seek.h"
 #include "dvd_summary.h"
 #include "iso_lang.h"
 
-#include "debug.h"
-
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
 
 /* called from outside */
-static int  DVDOpen         ( struct input_thread_s * );
-static void DVDClose        ( struct input_thread_s * );
-static int  DVDSetArea      ( struct input_thread_s *, struct input_area_s * );
-static int  DVDSetProgram   ( struct input_thread_s *, pgrm_descriptor_t * );
-static int  DVDRead         ( struct input_thread_s *, byte_t *, size_t );
-static void DVDSeek         ( struct input_thread_s *, off_t );
+static int  DVDSetArea      ( input_thread_t *, input_area_t * );
+static int  DVDSetProgram   ( input_thread_t *, pgrm_descriptor_t * );
+static ssize_t DVDRead      ( input_thread_t *, byte_t *, size_t );
+static void DVDSeek         ( input_thread_t *, off_t );
 
 static char * DVDParse( input_thread_t * );
 
-/*****************************************************************************
- * Functions exported as capabilities. They are declared as static so that
- * we don't pollute the namespace too much.
- *****************************************************************************/
-void _M( access_getfunctions)( function_list_t * p_function_list )
-{
-#define input p_function_list->functions.access
-    input.pf_open             = DVDOpen;
-    input.pf_close            = DVDClose;
-    input.pf_read             = DVDRead;
-    input.pf_set_area         = DVDSetArea;
-    input.pf_set_program      = DVDSetProgram;
-    input.pf_seek             = DVDSeek;
-#undef input
-}
-
 /*
  * Data access functions
  */
 
-#define DVDLB     p_dvd->i_vts_start + p_dvd->i_vts_lb
 #define DVDTell   LB2OFF( p_dvd->i_vts_start + p_dvd->i_vts_lb ) \
                   - p_input->stream.p_selected_area->i_start
 
 /*****************************************************************************
  * DVDOpen: open dvd
  *****************************************************************************/
-static int DVDOpen( struct input_thread_s *p_input )
+int E_(DVDOpen) ( vlc_object_t *p_this )
 {
+    input_thread_t *        p_input = (input_thread_t *)p_this;
     char *               psz_device;
     thread_dvd_data_t *  p_dvd;
     input_area_t *       p_area;
@@ -121,11 +97,16 @@ static int DVDOpen( struct input_thread_s *p_input )
     p_dvd = malloc( sizeof(thread_dvd_data_t) );
     if( p_dvd == NULL )
     {
-        intf_ErrMsg( "dvd error: out of memory" );
+        msg_Err( p_input, "out of memory" );
         return -1;
     }
     p_input->p_access_data = (void *)p_dvd;
     
+    p_input->pf_read = DVDRead;
+    p_input->pf_seek = DVDSeek;
+    p_input->pf_set_area = DVDSetArea;
+    p_input->pf_set_program = DVDSetProgram;
+
     /* Parse command line */
     if( !( psz_device = DVDParse( p_input ) ) )
     {
@@ -148,14 +129,14 @@ static int DVDOpen( struct input_thread_s *p_input )
 
     if( p_dvd->dvdhandle == NULL )
     {
-        intf_ErrMsg( "dvd error: dvdcss can't open device" );
+        msg_Err( p_input, "dvdcss cannot open device" );
         free( p_dvd );
         return -1;
     }
 
     if( dvdcss_seek( p_dvd->dvdhandle, 0, DVDCSS_NOFLAGS ) < 0 )
     {
-        intf_ErrMsg( "dvd error: %s", dvdcss_error( p_dvd->dvdhandle ) );
+        msg_Err( p_input, "%s", dvdcss_error( p_dvd->dvdhandle ) );
         dvdcss_close( p_dvd->dvdhandle );
         free( p_dvd );
         return -1;
@@ -164,7 +145,7 @@ static int DVDOpen( struct input_thread_s *p_input )
     /* Ifo allocation & initialisation */
     if( IfoCreate( p_dvd ) < 0 )
     {
-        intf_ErrMsg( "dvd error: allcation error in ifo" );
+        msg_Err( p_input, "allcation error in ifo" );
         dvdcss_close( p_dvd->dvdhandle );
         free( p_dvd );
         return -1;
@@ -172,7 +153,7 @@ static int DVDOpen( struct input_thread_s *p_input )
 
     if( IfoInit( p_dvd->p_ifo ) < 0 )
     {
-        intf_ErrMsg( "dvd error: fatal failure in ifo" );
+        msg_Err( p_input, "fatal failure in ifo" );
         IfoDestroy( p_dvd->p_ifo );
         dvdcss_close( p_dvd->dvdhandle );
         free( p_dvd );
@@ -192,7 +173,7 @@ static int DVDOpen( struct input_thread_s *p_input )
     input_InitStream( p_input, sizeof( stream_ps_data_t ) );
 
 #define title_inf p_dvd->p_ifo->vmg.title_inf
-    intf_WarnMsg( 3, "dvd info: number of titles: %d", title_inf.i_title_nb );
+    msg_Dbg( p_input, "number of titles: %d", title_inf.i_title_nb );
 
 #define area p_input->stream.pp_areas
     /* We start from 1 here since the default area 0
@@ -246,7 +227,7 @@ static int DVDOpen( struct input_thread_s *p_input )
 
     vlc_mutex_unlock( &p_input->stream.stream_lock );
 
-    p_input->psz_demux = "dvd";
+    p_input->psz_demux = "dvdold";
 
     return 0;
 }
@@ -254,8 +235,9 @@ static int DVDOpen( struct input_thread_s *p_input )
 /*****************************************************************************
  * DVDClose: close dvd
  *****************************************************************************/
-static void DVDClose( struct input_thread_s *p_input )
+void E_(DVDClose) ( vlc_object_t *p_this )
 {
+    input_thread_t * p_input = (input_thread_t *)p_this;
     thread_dvd_data_t *p_dvd = (thread_dvd_data_t*)p_input->p_access_data;
 
     IfoDestroy( p_dvd->p_ifo );
@@ -297,8 +279,8 @@ static int DVDSetProgram( input_thread_t    * p_input,
             p_dvd->i_prg_cell += ( p_program->i_number - p_dvd->i_angle );
             p_dvd->i_map_cell =  CellPrg2Map( p_dvd );
             p_dvd->i_map_cell += p_dvd->i_angle_cell;
-            p_dvd->i_vts_lb   =  CellStartSector( p_dvd );
-            p_dvd->i_end_lb   =  CellEndSector( p_dvd );
+            p_dvd->i_vts_lb   =  CellFirstSector( p_dvd );
+            p_dvd->i_last_lb  =  CellLastSector( p_dvd );
             p_dvd->i_angle    =  p_program->i_number;
         }
         else
@@ -306,7 +288,7 @@ static int DVDSetProgram( input_thread_t    * p_input,
             p_dvd->i_angle    =  p_program->i_number;
         }
 #undef title
-        intf_WarnMsg( 3, "dvd info: angle %d selected", p_dvd->i_angle );
+        msg_Dbg( p_input, "angle %d selected", p_dvd->i_angle );
     }
 
     return 0;
@@ -381,8 +363,8 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
     if( p_area != p_input->stream.p_selected_area )
     {
         int     i_vts_title;
-        u32     i_start;
-        u32     i_size;
+        u32     i_first;
+        u32     i_last;
 
         /* Reset the Chapter position of the old title */
         p_input->stream.p_selected_area->i_part = 1;
@@ -398,7 +380,7 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
 
         if( IfoTitleSet( p_dvd->p_ifo, p_dvd->i_title ) < 0 )
         {
-            intf_ErrMsg( "dvd error: fatal error in vts ifo" );
+            msg_Err( p_input, "fatal error in vts ifo" );
             free( p_dvd );
             return -1;
         }
@@ -408,8 +390,8 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
         p_dvd->i_title_id =
             vts.title_inf.p_title_start[i_vts_title-1].i_title_id;
 
-        intf_WarnMsg( 3, "dvd: title %d vts_title %d pgc %d",
-                      p_dvd->i_title, i_vts_title, p_dvd->i_title_id );
+        msg_Dbg( p_input, "title %d vts_title %d pgc %d",
+                          p_dvd->i_title, i_vts_title, p_dvd->i_title_id );
 
         /* title set offset XXX: convert to block values */
         p_dvd->i_vts_start =
@@ -420,31 +402,32 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
             vts.title_unit.p_title[p_dvd->i_title_id-1].title.i_cell_nb;
         p_dvd->i_map_cell = 0;
         p_dvd->i_map_cell = CellPrg2Map( p_dvd );
-        i_size            = CellEndSector( p_dvd );
+        i_last            = CellLastSector( p_dvd );
 
         /* first cell */
         p_dvd->i_prg_cell   = 0;
         p_dvd->i_map_cell   = 0;
         p_dvd->i_angle_cell = 0;
         p_dvd->i_map_cell   = CellPrg2Map    ( p_dvd );
-        p_dvd->i_vts_lb     = CellStartSector( p_dvd );
-        p_dvd->i_end_lb     = CellEndSector  ( p_dvd );
+        p_dvd->i_vts_lb     = CellFirstSector( p_dvd );
+        p_dvd->i_last_lb    = CellLastSector ( p_dvd );
 
         /* Force libdvdcss to check its title key.
          * It is only useful for title cracking method. Methods using the
          * decrypted disc key are fast enough to check the key at each seek */
-        if( ( i_start = dvdcss_seek( p_dvd->dvdhandle, DVDLB,
-                                     DVDCSS_SEEK_KEY ) ) < 0 )
+        i_first = dvdcss_seek( p_dvd->dvdhandle,
+                               p_dvd->i_vts_start + p_dvd->i_vts_lb,
+                               DVDCSS_SEEK_KEY );
+        if( i_first < 0 )
         {
-            intf_ErrMsg( "dvd error: %s", dvdcss_error( p_dvd->dvdhandle ) );
+            msg_Err( p_input, "%s", dvdcss_error( p_dvd->dvdhandle ) );
             return -1;
         }
 
-        i_size -= p_dvd->i_vts_lb + 1;
-
         /* Area definition */
-        p_input->stream.p_selected_area->i_start = LB2OFF( i_start );
-        p_input->stream.p_selected_area->i_size  = LB2OFF( i_size );
+        p_input->stream.p_selected_area->i_start = LB2OFF( i_first );
+        p_input->stream.p_selected_area->i_size  =
+                                        LB2OFF( i_last + 1 - p_dvd->i_vts_lb );
 
         /* Destroy obsolete ES by reinitializing programs */
         DVDFlushStream( p_input );
@@ -459,8 +442,8 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
         DVDSetProgram( p_input,
                        p_input->stream.pp_programs[p_dvd->i_angle-1] ); 
 
-        intf_WarnMsg( 3, "dvd info: title start: %d size: %d",
-                         i_start, i_size );
+        msg_Dbg( p_input, "title first %i, last %i, size %i",
+                          i_first, i_last, i_last + 1 - p_dvd->i_vts_lb );
         IfoPrintTitle( p_dvd );
 
         /* No PSM to read in DVD mode, we already have all information */
@@ -471,7 +454,7 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
         DVDReadAudio( p_input );
         DVDReadSPU  ( p_input );
    
-        if( p_input->p_demux_module )
+        if( p_input->p_demux )
         {
             DVDLaunchDecoders( p_input );
         }
@@ -505,8 +488,8 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
  * Returns -1 in case of error, 0 in case of EOF, otherwise the number of
  * bytes.
  *****************************************************************************/
-static int DVDRead( input_thread_t * p_input,
-                    byte_t * p_buffer, size_t i_count )
+static ssize_t DVDRead( input_thread_t * p_input,
+                        byte_t * p_buffer, size_t i_count )
 {
     thread_dvd_data_t *     p_dvd;
     int                     i_read;
@@ -520,7 +503,12 @@ static int DVDRead( input_thread_t * p_input,
 
     while( i_blocks )
     {
-        if( ( i_block_once = __MIN( LbMaxOnce( p_dvd ), i_blocks ) ) <= 0 )
+        i_block_once = LbMaxOnce( p_dvd );
+        if( i_block_once > i_blocks )
+        {
+            i_block_once = i_blocks;
+        }
+        else if( i_block_once <= 0 )
         {
             /* EOT */
             break;
@@ -561,7 +549,7 @@ static int DVDRead( input_thread_t * p_input,
         }
 
         /* EOT */
-        intf_WarnMsg( 4, "dvd info: new title" );
+        msg_Dbg( p_input, "new title" );
         p_dvd->i_title++;
         DVDSetArea( p_input, p_input->stream.pp_areas[p_dvd->i_title] );
     }
@@ -597,16 +585,16 @@ static void DVDSeek( input_thread_t * p_input, off_t i_off )
         /* if we're inside a multi-angle zone, we have to choose i_sector
          * in the current angle ; we can't do it all the time since cells
          * can be very wide out of such zones */
-        p_dvd->i_vts_lb = CellStartSector( p_dvd );
+        p_dvd->i_vts_lb = CellFirstSector( p_dvd );
     }
     
-    p_dvd->i_end_lb   = CellEndSector  ( p_dvd );
+    p_dvd->i_last_lb  = CellLastSector( p_dvd );
     p_dvd->i_chapter  = CellPrg2Chapter( p_dvd );
 
-    if( dvdcss_seek( p_dvd->dvdhandle, DVDLB,
+    if( dvdcss_seek( p_dvd->dvdhandle, p_dvd->i_vts_start + p_dvd->i_vts_lb,
                      DVDCSS_SEEK_MPEG ) < 0 )
     {
-        intf_ErrMsg( "dvd error: %s", dvdcss_error( p_dvd->dvdhandle ) );
+        msg_Err( p_input, "%s", dvdcss_error( p_dvd->dvdhandle ) );
         p_input->b_error = 1;
         return;
     }
@@ -616,8 +604,8 @@ static void DVDSeek( input_thread_t * p_input, off_t i_off )
     p_input->stream.p_selected_area->i_tell = DVDTell;
     vlc_mutex_unlock( &p_input->stream.stream_lock );
 
-    intf_WarnMsg( 4, "Program Cell: %d Cell: %d Chapter: %d tell %lld",
-                     p_dvd->i_prg_cell, p_dvd->i_map_cell, p_dvd->i_chapter, DVDTell );
+    msg_Dbg( p_input, "program cell: %d cell: %d chapter: %d tell %lld",
+             p_dvd->i_prg_cell, p_dvd->i_map_cell, p_dvd->i_chapter, DVDTell );
 
     return;
 }
@@ -633,14 +621,20 @@ static char * DVDParse( input_thread_t * p_input )
     char *               psz_device;
     char *               psz_raw;
     char *               psz_next;
-    boolean_t            b_options = 0;
+    vlc_bool_t           b_options = 0;
     int                  i_title = 1;
     int                  i_chapter = 1;
     int                  i_angle = 1;
     int                  i;
-    
+
     p_dvd = (thread_dvd_data_t*)(p_input->p_access_data);
 
+#ifdef WIN32
+    /* On Win32 we want the DVD access plugin to be explicitly requested,
+     * we end up with lots of problems otherwise */
+    if( !p_input->psz_access || !*p_input->psz_access ) return NULL;
+#endif
+
     psz_parser = psz_device = strdup( p_input->psz_name );
     if( !psz_parser )
     {
@@ -736,9 +730,8 @@ static char * DVDParse( input_thread_t * p_input )
             /* check the raw device */
             if( stat( psz_raw, &stat_info ) == -1 )
             {
-                intf_WarnMsg( 3, "dvd warning: cannot stat() raw"
-                                " device `%s' (%s)",
-                             psz_raw, strerror(errno));
+                msg_Warn( p_input, "cannot stat() raw device `%s' (%s)",
+                                   psz_raw, strerror(errno));
                 /* put back '@' */
                 *(psz_raw - 1) = '@';
                 psz_raw = "";
@@ -750,8 +743,8 @@ static char * DVDParse( input_thread_t * p_input )
 #ifndef WIN32    
                 if( !S_ISCHR(stat_info.st_mode) )
                 {
-                    intf_WarnMsg( 3, "dvd warning: raw device %s is"
-                                     " not a valid char device", psz_raw );
+                    msg_Warn( p_input, "raw device %s is"
+                              " not a valid char device", psz_raw );
                     /* put back '@' */
                     *(psz_raw - 1) = '@';
                     psz_raw = "";
@@ -781,29 +774,31 @@ static char * DVDParse( input_thread_t * p_input )
             /* no device and no access specified: we probably don't want DVD */
             return NULL;
         }
-        psz_device = config_GetPszVariable( "dvd_device" );
+        psz_device = config_GetPsz( p_input, "dvd" );
     }
 
+#ifndef WIN32    
     /* check block device */
     if( stat( psz_device, &stat_info ) == -1 )
     {
-        intf_ErrMsg( "dvd error: cannot stat() device `%s' (%s)",
-                     psz_device, strerror(errno));
+        msg_Err( p_input, "cannot stat() device `%s' (%s)",
+                          psz_device, strerror(errno));
+        free( psz_device );
         return NULL;                    
     }
     
-#ifndef WIN32    
     if( !S_ISBLK(stat_info.st_mode) && !S_ISCHR(stat_info.st_mode) )
     {
-        intf_WarnMsg( 3, "input: DVD plugin discarded"
-                         " (not a valid block device)" );
+        msg_Warn( p_input,
+                  "dvd module discarded (not a valid block device)" );
+        free( psz_device );
         return NULL;
     }
 #endif
     
-    intf_WarnMsg( 2, "input: dvd=%s raw=%s title=%d chapter=%d angle=%d",
-                  psz_device, psz_raw, p_dvd->i_title,
-                  p_dvd->i_chapter, p_dvd->i_angle );
+    msg_Dbg( p_input, "dvd=%s raw=%s title=%d chapter=%d angle=%d",
+                      psz_device, psz_raw, p_dvd->i_title,
+                      p_dvd->i_chapter, p_dvd->i_angle );
 
     return psz_device;
 }