* modules/access/vcd/*, modules/access/cdda.c: changed ioctl_ReadSector() into ioctl_...
authorGildas Bazin <gbazin@videolan.org>
Sun, 18 May 2003 15:44:03 +0000 (15:44 +0000)
committerGildas Bazin <gbazin@videolan.org>
Sun, 18 May 2003 15:44:03 +0000 (15:44 +0000)
  Modified the cdda plugin to read 20 sectors at a time. This was necessary because it was overkill to read the data sectors by sectors and was creating problems under Windows.

modules/access/cdda.c
modules/access/vcd/cdrom.c
modules/access/vcd/cdrom.h
modules/access/vcd/cdrom_internals.h
modules/access/vcd/vcd.c

index 688dfca..bf8b940 100644 (file)
@@ -2,7 +2,7 @@
  * cdda.c : CD digital audio input module for vlc
  *****************************************************************************
  * Copyright (C) 2000 VideoLAN
- * $Id: cdda.c,v 1.1 2003/05/17 20:30:31 gbazin Exp $
+ * $Id: cdda.c,v 1.2 2003/05/18 15:44:03 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *          Gildas Bazin <gbazin@netcourrier.com>
@@ -240,6 +240,9 @@ static int CDDAOpen( vlc_object_t *p_this )
     p_input->pf_set_area = CDDASetArea;
     p_input->pf_set_program = CDDASetProgram;
 
+    /* Update default_pts to a suitable value for cdda access */
+    p_input->i_pts_delay = config_GetInt( p_input, "cdda-caching" ) * 1000;
+
     return 0;
 }
 
@@ -277,16 +280,15 @@ static int CDDARead( input_thread_t * p_input, byte_t * p_buffer,
 
     i_blocks = i_len / CDDA_DATA_SIZE;
 
-    for ( i_index = 0; i_index < i_blocks; i_index++ )
+    if ( ioctl_ReadSectors( VLC_OBJECT(p_input), p_cdda->vcddev,
+             p_cdda->i_sector, p_buffer, i_blocks, CDDA_TYPE ) < 0 )
     {
-        if ( ioctl_ReadSector( VLC_OBJECT(p_input), p_cdda->vcddev,
-                 p_cdda->i_sector, p_buffer + i_index * CDDA_DATA_SIZE,
-                 CDDA_DATA_START, CDDA_DATA_SIZE ) < 0 )
-        {
-            msg_Err( p_input, "could not read sector %d", p_cdda->i_sector );
-            return -1;
-        }
+        msg_Err( p_input, "could not read sector %d", p_cdda->i_sector );
+        return -1;
+    }
 
+    for ( i_index = 0; i_index < i_blocks; i_index++ )
+    {
         p_cdda->i_sector ++;
         if ( p_cdda->i_sector == p_cdda->p_sectors[p_cdda->i_track + 1] )
         {
index 8c7bfc8..66deea9 100644 (file)
@@ -2,7 +2,7 @@
  * cdrom.c: cdrom tools
  *****************************************************************************
  * Copyright (C) 1998-2001 VideoLAN
- * $Id: cdrom.c,v 1.10 2003/05/18 12:18:46 gbazin Exp $
+ * $Id: cdrom.c,v 1.11 2003/05/18 15:44:03 gbazin Exp $
  *
  * Authors: Johan Bilien <jobi@via.ecp.fr>
  *          Gildas Bazin <gbazin@netcourrier.com>
@@ -542,13 +542,16 @@ int ioctl_GetTracksMap( vlc_object_t *p_this, const vcddev_t *p_vcddev,
 }
 
 /****************************************************************************
- * ioctl_ReadSector: Read a sector (2352 bytes - i_start)
+ * ioctl_ReadSector: Read VCD or CDDA sectors
  ****************************************************************************/
-int ioctl_ReadSector( vlc_object_t *p_this, const vcddev_t *p_vcddev,
-                      int i_sector, byte_t * p_buffer, size_t i_start,
-                      size_t i_len )
+int ioctl_ReadSectors( vlc_object_t *p_this, const vcddev_t *p_vcddev,
+                       int i_sector, byte_t * p_buffer, int i_nb, int i_type )
 {
-    byte_t p_block[ VCD_SECTOR_SIZE ];
+    byte_t *p_block;
+    int i;
+
+    if( i_type == VCD_TYPE ) p_block = malloc( VCD_SECTOR_SIZE * i_nb );
+    else p_block = p_buffer;
 
     if( p_vcddev->i_vcdimage_handle != -1 )
     {
@@ -559,20 +562,18 @@ int ioctl_ReadSector( vlc_object_t *p_this, const vcddev_t *p_vcddev,
                    SEEK_SET ) == -1 )
         {
             msg_Err( p_this, "Could not lseek to sector %d", i_sector );
+            if( i_type == VCD_TYPE ) free( p_block );
             return -1;
         }
 
-        if( read( p_vcddev->i_vcdimage_handle, p_block, VCD_SECTOR_SIZE )
+        if( read( p_vcddev->i_vcdimage_handle, p_block, VCD_SECTOR_SIZE * i_nb)
             == -1 )
         {
-            // msg_Err( p_this, "Could not read sector %d", i_sector );
+            msg_Err( p_this, "Could not read sector %d", i_sector );
+            if( i_type == VCD_TYPE ) free( p_block );
             return -1;
         }
 
-        /* We don't want to keep the header of the read sector */
-        memcpy( p_buffer, p_block + i_start, i_len );
-
-        return 0;
     }
     else
     {
@@ -593,11 +594,12 @@ int ioctl_ReadSector( vlc_object_t *p_this, const vcddev_t *p_vcddev,
         cd_read.sectorType = kCDSectorTypeUnknown;
 
         cd_read.buffer = p_block;
-        cd_read.bufferLength = sizeof(p_block);
+        cd_read.bufferLength = VCD_SECTOR_SIZE * i_nb;
 
         if( ioctl( p_vcddev->i_device_handle, DKIOCCDREAD, &cd_read ) == -1 )
         {
             msg_Err( p_this, "could not read block %d", i_sector );
+            if( i_type == VCD_TYPE ) free( p_block );
             return -1;
         }
 
@@ -611,6 +613,7 @@ int ioctl_ReadSector( vlc_object_t *p_this, const vcddev_t *p_vcddev,
             hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
             if( hEvent == NULL )
             {
+                if( i_type == VCD_TYPE ) free( p_block );
                 return -1;
             }
 
@@ -629,7 +632,8 @@ int ioctl_ReadSector( vlc_object_t *p_this, const vcddev_t *p_vcddev,
             ssc.CDBByte[ 0 ] = READ_CD;
 
             /* Sector type */
-            ssc.CDBByte[ 1 ] = SECTOR_TYPE_MODE2_FORM2;
+            ssc.CDBByte[ 1 ] = i_type == VCD_TYPE ? SECTOR_TYPE_MODE2_FORM2 :
+                                                    SECTOR_TYPE_CDDA;
 
             /* Start of LBA */
             ssc.CDBByte[ 2 ] = ( i_sector >> 24 ) & 0xff;
@@ -638,16 +642,17 @@ int ioctl_ReadSector( vlc_object_t *p_this, const vcddev_t *p_vcddev,
             ssc.CDBByte[ 5 ] = ( i_sector       ) & 0xff;
 
             /* Transfer length */
-            ssc.CDBByte[ 6 ] = 0;
-            ssc.CDBByte[ 7 ] = 0;
-            ssc.CDBByte[ 8 ] = 1;
+            ssc.CDBByte[ 6 ] = ( i_nb >> 16 ) & 0xff;
+            ssc.CDBByte[ 7 ] = ( i_nb >> 8  ) & 0xff;
+            ssc.CDBByte[ 8 ] = ( i_nb       ) & 0xff;
 
             /* Data selection */
-            ssc.CDBByte[ 9 ] = READ_CD_RAW_MODE2;
+            ssc.CDBByte[ 9 ] = i_type == VCD_TYPE ? READ_CD_RAW_MODE2 :
+                                                    READ_CD_USERDATA;
 
             /* Result buffer */
             ssc.SRB_BufPointer  = p_block;
-            ssc.SRB_BufLen = VCD_SECTOR_SIZE;
+            ssc.SRB_BufLen = VCD_SECTOR_SIZE * i_nb;
 
             /* Initiate transfer */
             ResetEvent( hEvent );
@@ -664,6 +669,7 @@ int ioctl_ReadSector( vlc_object_t *p_this, const vcddev_t *p_vcddev,
             /* check that the transfer went as planned */
             if( ssc.SRB_Status != SS_COMP )
             {
+                if( i_type == VCD_TYPE ) free( p_block );
                 return -1;
             }
         }
@@ -674,40 +680,40 @@ int ioctl_ReadSector( vlc_object_t *p_this, const vcddev_t *p_vcddev,
 
             /* Initialize CDROM_RAW_READ structure */
             cdrom_raw.DiskOffset.QuadPart = CD_SECTOR_SIZE * i_sector;
-            cdrom_raw.SectorCount = 1;
-            cdrom_raw.TrackMode = XAForm2;
+            cdrom_raw.SectorCount = i_nb;
+            cdrom_raw.TrackMode =  i_type == VCD_TYPE ? XAForm2 : CDDA;
 
             if( DeviceIoControl( p_vcddev->h_device_handle,
                                  IOCTL_CDROM_RAW_READ, &cdrom_raw,
                                  sizeof(RAW_READ_INFO), p_block,
-                                 sizeof(p_block), &dwBytesReturned, NULL )
-                == 0 )
+                                 VCD_SECTOR_SIZE * i_nb, &dwBytesReturned,
+                                 NULL ) == 0 )
             {
+                if( i_type == VCD_TYPE ) free( p_block );
                 return -1;
             }
         }
 
 #elif defined( HAVE_SCSIREQ_IN_SYS_SCSIIO_H )
         struct scsireq  sc;
-
-        int i_blocks = 1;
         int i_ret;
 
         memset( &sc, 0, sizeof(sc) );
         sc.cmd[0] = 0xBE;
-        sc.cmd[1] = SECTOR_TYPE_MODE2_FORM2;
+        sc.cmd[1] = i_type == VCD_TYPE ? SECTOR_TYPE_MODE2_FORM2:
+                                         SECTOR_TYPE_CDDA;
         sc.cmd[2] = (i_sector >> 24) & 0xff;
         sc.cmd[3] = (i_sector >> 16) & 0xff;
         sc.cmd[4] = (i_sector >>  8) & 0xff;
         sc.cmd[5] = (i_sector >>  0) & 0xff;
-        sc.cmd[6] = (i_blocks >> 16) & 0xff;
-        sc.cmd[7] = (i_blocks >>  8) & 0xff;
-        sc.cmd[8] = (i_blocks >>  0) & 0xff;
-        sc.cmd[9] = READ_CD_RAW_MODE2;
+        sc.cmd[6] = (i_nb >> 16) & 0xff;
+        sc.cmd[7] = (i_nb >>  8) & 0xff;
+        sc.cmd[8] = (i_nb      ) & 0xff;
+        sc.cmd[9] = i_type == VCD_TYPE ? READ_CD_RAW_MODE2 : READ_CD_USERDATA;
         sc.cmd[10] = 0; /* sub channel */
         sc.cmdlen = 12;
         sc.databuf = (caddr_t)p_block;
-        sc.datalen = VCD_SECTOR_SIZE;
+        sc.datalen = VCD_SECTOR_SIZE * i_nb;
         sc.senselen = sizeof( sc.sense );
         sc.flags = SCCMD_READ;
         sc.timeout = 10000;
@@ -716,23 +722,25 @@ int ioctl_ReadSector( vlc_object_t *p_this, const vcddev_t *p_vcddev,
         if( i_ret == -1 )
         {
             msg_Err( p_this, "SCIOCCOMMAND failed" );
+            if( i_type == VCD_TYPE ) free( p_block );
             return -1;
         }
         if( sc.retsts || sc.error )
         {
             msg_Err( p_this, "SCSI command failed: status %d error %d\n",
                              sc.retsts, sc.error );
+            if( i_type == VCD_TYPE ) free( p_block );
            return -1;
         }
 
 #elif defined( HAVE_IOC_TOC_HEADER_IN_SYS_CDIO_H )
-
         int i_size = VCD_SECTOR_SIZE;
 
         if( ioctl( p_vcddev->i_device_handle, CDRIOCSETBLOCKSIZE, &i_size )
             == -1 )
         {
             msg_Err( p_this, "Could not set block size" );
+            if( i_type == VCD_TYPE ) free( p_block );
             return( -1 );
         }
 
@@ -740,36 +748,60 @@ int ioctl_ReadSector( vlc_object_t *p_this, const vcddev_t *p_vcddev,
                    i_sector * VCD_SECTOR_SIZE, SEEK_SET ) == -1 )
         {
             msg_Err( p_this, "Could not lseek to sector %d", i_sector );
+            if( i_type == VCD_TYPE ) free( p_block );
             return( -1 );
         }
 
-        if( read( p_vcddev->i_device_handle, p_block, VCD_SECTOR_SIZE ) == -1 )
+        if( read( p_vcddev->i_device_handle,
+                  p_block, VCD_SECTOR_SIZE * i_nb ) == -1 )
         {
             msg_Err( p_this, "Could not read sector %d", i_sector );
+            if( i_type == VCD_TYPE ) free( p_block );
             return( -1 );
         }
 
 #else
-        int i_dummy = i_sector + 2 * CD_FRAMES;
+        for( i = 0; i < i_nb; i++ )
+        {
+            int i_dummy = i_sector + i + 2 * CD_FRAMES;
 
-#define p_msf ((struct cdrom_msf0 *)p_block)
-        p_msf->minute =   i_dummy / (CD_FRAMES * CD_SECS);
-        p_msf->second = ( i_dummy % (CD_FRAMES * CD_SECS) ) / CD_FRAMES;
-        p_msf->frame =  ( i_dummy % (CD_FRAMES * CD_SECS) ) % CD_FRAMES;
+#define p_msf ((struct cdrom_msf0 *)(p_block + i * VCD_SECTOR_SIZE))
+            p_msf->minute =   i_dummy / (CD_FRAMES * CD_SECS);
+            p_msf->second = ( i_dummy % (CD_FRAMES * CD_SECS) ) / CD_FRAMES;
+            p_msf->frame =  ( i_dummy % (CD_FRAMES * CD_SECS) ) % CD_FRAMES;
 #undef p_msf
 
-        if( ioctl(p_vcddev->i_device_handle, CDROMREADRAW, p_block) == -1 )
-        {
-            msg_Err( p_this, "could not read block %i from disc", i_sector );
-            return( -1 );
+            if( ioctl( p_vcddev->i_device_handle, CDROMREADRAW,
+                       p_block + i * VCD_SECTOR_SIZE ) == -1 )
+            {
+                msg_Err( p_this, "could not read block %i from disc",
+                         i_sector );
+
+                if( i == 0 )
+                {
+                    if( i_type == VCD_TYPE ) free( p_block );
+                    return( -1 );
+                }
+                else break;
+            }
         }
 #endif
+    }
 
-        /* We don't want to keep the header of the read sector */
-        memcpy( p_buffer, p_block + i_start, i_len );
-
-        return( 0 );
+    /* For VCDs, we don't want to keep the header and footer of the
+     * sectors read */
+    if( i_type == VCD_TYPE )
+    {
+        for( i = 0; i < i_nb; i++ )
+        {
+            memcpy( p_buffer + i * VCD_DATA_SIZE,
+                    p_block + i * VCD_SECTOR_SIZE + VCD_DATA_START,
+                    VCD_DATA_SIZE );
+        }
+        free( p_block );
     }
+
+    return( 0 );
 }
 
 /****************************************************************************
index 9aba916..27cf787 100644 (file)
@@ -2,7 +2,7 @@
  * cdrom.h: cdrom tools header
  *****************************************************************************
  * Copyright (C) 1998-2001 VideoLAN
- * $Id: cdrom.h,v 1.5 2003/05/17 20:30:31 gbazin Exp $
+ * $Id: cdrom.h,v 1.6 2003/05/18 15:44:03 gbazin Exp $
  *
  * Authors: Johan Bilien <jobi@via.ecp.fr>
  *          Gildas Bazin <gbazin@netcourrier.com>
@@ -22,6 +22,9 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  *****************************************************************************/
 
+#define CDDA_TYPE 0
+#define VCD_TYPE 1
+
 /* where the data start on a VCD sector */
 #define VCD_DATA_START 24
 /* size of the availablr data on a VCD sector */
@@ -90,5 +93,5 @@ typedef struct entries_sect_s
 vcddev_t *ioctl_Open         ( vlc_object_t *, const char * );
 void      ioctl_Close        ( vlc_object_t *, vcddev_t * );
 int       ioctl_GetTracksMap ( vlc_object_t *, const vcddev_t *, int ** );
-int       ioctl_ReadSector   ( vlc_object_t *, const vcddev_t *,
-                               int, byte_t *, size_t, size_t );
+int       ioctl_ReadSectors  ( vlc_object_t *, const vcddev_t *,
+                               int, byte_t *, int, int );
index 6943fc1..e6a060a 100644 (file)
@@ -2,7 +2,7 @@
  * cdrom_internals.h: cdrom tools private header
  *****************************************************************************
  * Copyright (C) 1998-2001 VideoLAN
- * $Id: cdrom_internals.h,v 1.1 2003/05/17 20:30:31 gbazin Exp $
+ * $Id: cdrom_internals.h,v 1.2 2003/05/18 15:44:03 gbazin Exp $
  *
  * Authors: Johan Bilien <jobi@via.ecp.fr>
  *          Gildas Bazin <gbazin@netcourrier.com>
@@ -134,7 +134,9 @@ typedef struct __RAW_READ_INFO {
 
 #define READ_CD 0xbe
 #define SECTOR_TYPE_MODE2_FORM2 0x14
+#define SECTOR_TYPE_CDDA 0x04
 #define READ_CD_RAW_MODE2 0xF0
+#define READ_CD_USERDATA 0x10
 
 #define READ_TOC 0x43
 #define READ_TOC_FORMAT_TOC 0x0
index 32f7d9e..0a10eb7 100644 (file)
@@ -2,7 +2,7 @@
  * vcd.c : VCD input module for vlc
  *****************************************************************************
  * Copyright (C) 2000 VideoLAN
- * $Id: vcd.c,v 1.20 2003/05/17 20:30:31 gbazin Exp $
+ * $Id: vcd.c,v 1.21 2003/05/18 15:44:03 gbazin Exp $
  *
  * Author: Johan Bilien <jobi@via.ecp.fr>
  *
@@ -297,9 +297,9 @@ static int VCDRead( input_thread_t * p_input, byte_t * p_buffer,
 
     for ( i_index = 0 ; i_index < i_blocks ; i_index++ )
     {
-        if ( ioctl_ReadSector( VLC_OBJECT(p_input), p_vcd->vcddev,
-             p_vcd->i_sector, p_buffer + i_index * VCD_DATA_SIZE,
-             VCD_DATA_START, VCD_DATA_SIZE ) < 0 )
+        if ( ioctl_ReadSectors( VLC_OBJECT(p_input), p_vcd->vcddev,
+             p_vcd->i_sector, p_buffer + i_index * VCD_DATA_SIZE, 1,
+             VCD_TYPE ) < 0 )
         {
             msg_Err( p_input, "could not read sector %d", p_vcd->i_sector );
             return -1;
@@ -351,9 +351,8 @@ static int VCDRead( input_thread_t * p_input, byte_t * p_buffer,
 
     if ( i_len % VCD_DATA_SIZE ) /* this should not happen */
     {
-        if ( ioctl_ReadSector( VLC_OBJECT(p_input), p_vcd->vcddev,
-             p_vcd->i_sector, p_last_sector, VCD_DATA_START,
-             VCD_DATA_SIZE ) < 0 )
+        if ( ioctl_ReadSectors( VLC_OBJECT(p_input), p_vcd->vcddev,
+             p_vcd->i_sector, p_last_sector, 1, VCD_TYPE ) < 0 )
         {
             msg_Err( p_input, "could not read sector %d", p_vcd->i_sector );
             return -1;
@@ -499,8 +498,8 @@ static int VCDEntryPoints( input_thread_t * p_input )
         return -1;
     }
 
-    if( ioctl_ReadSector( VLC_OBJECT(p_input), p_vcd->vcddev,
-        VCD_ENTRIES_SECTOR, p_sector, VCD_DATA_START, VCD_DATA_SIZE ) < 0 )
+    if( ioctl_ReadSectors( VLC_OBJECT(p_input), p_vcd->vcddev,
+        VCD_ENTRIES_SECTOR, p_sector, 1, VCD_TYPE ) < 0 )
     {
         msg_Err( p_input, "could not read entry points sector" );
         free( p_sector );