Commit 235dfe29 authored by Gildas Bazin's avatar Gildas Bazin

* modules/access/vcd/*, configure.ac.in:
   - Major changes to allow reading vcd images directly from the hard drive
      (you need a .cue and .bin file).
   - Removed duplicated code by merging ioctl_GetTrackCount and ioctl_GetSectors.
   - Implemented necessary ioctls for Win9x/NT/2K/XP.
parent 954bdeb8
...@@ -305,7 +305,7 @@ AC_EGREP_HEADER(strncasecmp,strings.h,[ ...@@ -305,7 +305,7 @@ AC_EGREP_HEADER(strncasecmp,strings.h,[
dnl Check for headers dnl Check for headers
AC_CHECK_HEADERS(stdint.h getopt.h strings.h inttypes.h sys/int_types.h) AC_CHECK_HEADERS(stdint.h getopt.h strings.h inttypes.h sys/int_types.h)
AC_CHECK_HEADERS(sys/sockio.h fcntl.h sys/types.h sys/time.h sys/times.h) AC_CHECK_HEADERS(sys/sockio.h fcntl.h sys/types.h sys/time.h sys/times.h sys/ioctl.h)
AC_CHECK_HEADERS(dlfcn.h image.h) AC_CHECK_HEADERS(dlfcn.h image.h)
AC_CHECK_HEADERS(arpa/inet.h net/if.h netinet/in.h sys/socket.h) AC_CHECK_HEADERS(arpa/inet.h net/if.h netinet/in.h sys/socket.h)
AC_CHECK_HEADERS(machine/param.h sys/shm.h) AC_CHECK_HEADERS(machine/param.h sys/shm.h)
...@@ -965,7 +965,7 @@ dnl ...@@ -965,7 +965,7 @@ dnl
dnl VCD module dnl VCD module
dnl dnl
AC_ARG_ENABLE(vcd, AC_ARG_ENABLE(vcd,
[ --enable-vcd VCD support for Linux, FreeBSD and MacOS X (default enabled)]) [ --enable-vcd VCD support for Linux, FreeBSD, MacOS X and Win32 (default enabled)])
if test "x${enable_vcd}" != "xno" if test "x${enable_vcd}" != "xno"
then then
...@@ -978,7 +978,7 @@ then ...@@ -978,7 +978,7 @@ then
AC_DEFINE(HAVE_IOC_TOC_HEADER_IN_SYS_CDIO_H, 1, For FreeBSD VCD support) AC_DEFINE(HAVE_IOC_TOC_HEADER_IN_SYS_CDIO_H, 1, For FreeBSD VCD support)
]) ])
if test "x${SYS}" = "xbsdi" if test "x${SYS}" = "xbsdi" -o "x${SYS}" = "xmingw32"
then then
PLUGINS="${PLUGINS} vcd" PLUGINS="${PLUGINS} vcd"
fi fi
......
This diff is collapsed.
...@@ -2,9 +2,10 @@ ...@@ -2,9 +2,10 @@
* cdrom.h: cdrom tools header * cdrom.h: cdrom tools header
***************************************************************************** *****************************************************************************
* Copyright (C) 1998-2001 VideoLAN * Copyright (C) 1998-2001 VideoLAN
* $Id: cdrom.h,v 1.2 2002/08/08 22:28:22 sam Exp $ * $Id: cdrom.h,v 1.3 2002/10/15 19:56:59 gbazin Exp $
* *
* Author: Johan Bilien <jobi@via.ecp.fr> * Authors: Johan Bilien <jobi@via.ecp.fr>
* Gildas Bazin <gbazin@netcourrier.com>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
...@@ -21,17 +22,191 @@ ...@@ -21,17 +22,191 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/ *****************************************************************************/
/* where the data start on a VCD sector */ /*****************************************************************************
#define VCD_DATA_START 24 * The vcddev structure
/* size of the availablr data on a VCD sector */ *****************************************************************************/
#define VCD_DATA_SIZE 2324 typedef struct vcddev_s
/* size of a VCD sector, header and tail included */ {
#define VCD_SECTOR_SIZE 2352 char *psz_dev; /* vcd device name */
/* Section used in vcd image mode */
int i_vcdimage_handle; /* vcd image file descriptor */
int i_tracks; /* number of tracks of the vcd */
int *p_sectors; /* tracks layout on the vcd */
/* Section used in vcd device mode */
#ifdef WIN32
HANDLE h_device_handle; /* vcd device descriptor */
long hASPI;
short i_sid;
long (*lpSendCommand)( void* );
#else
int i_device_handle; /* vcd device descriptor */
#endif
} vcddev_t;
/*****************************************************************************
* Misc. Macros
*****************************************************************************/
/* LBA = msf.frame + 75 * ( msf.second + 60 * msf.minute ) */
#define MSF_TO_LBA(min, sec, frame) ((int)frame + 75 * (sec + 60 * min))
/* LBA = msf.frame + 75 * ( msf.second - 2 + 60 * msf.minute ) */
#define MSF_TO_LBA2(min, sec, frame) ((int)frame + 75 * (sec -2 + 60 * min))
#ifndef O_BINARY
# define O_BINARY 0
#endif
#define VCDDEV_T 1
/*****************************************************************************
* Platform specifics
*****************************************************************************/
#if defined( SYS_DARWIN )
#define darwin_freeTOC( p ) free( (void*)p )
#define CD_MIN_TRACK_NO 01
#define CD_MAX_TRACK_NO 99
#endif
#if defined( WIN32 )
/* Win32 DeviceIoControl specifics */
#ifndef MAXIMUM_NUMBER_TRACKS
# define MAXIMUM_NUMBER_TRACKS 100
#endif
typedef struct _TRACK_DATA {
UCHAR Reserved;
UCHAR Control : 4;
UCHAR Adr : 4;
UCHAR TrackNumber;
UCHAR Reserved1;
UCHAR Address[4];
} TRACK_DATA, *PTRACK_DATA;
typedef struct _CDROM_TOC {
UCHAR Length[2];
UCHAR FirstTrack;
UCHAR LastTrack;
TRACK_DATA TrackData[MAXIMUM_NUMBER_TRACKS];
} CDROM_TOC, *PCDROM_TOC;
typedef enum _TRACK_MODE_TYPE {
YellowMode2,
XAForm2,
CDDA
} TRACK_MODE_TYPE, *PTRACK_MODE_TYPE;
typedef struct __RAW_READ_INFO {
LARGE_INTEGER DiskOffset;
ULONG SectorCount;
TRACK_MODE_TYPE TrackMode;
} RAW_READ_INFO, *PRAW_READ_INFO;
#ifndef IOCTL_CDROM_BASE
# define IOCTL_CDROM_BASE FILE_DEVICE_CD_ROM
#endif
#ifndef IOCTL_CDROM_READ_TOC
# define IOCTL_CDROM_READ_TOC CTL_CODE(IOCTL_CDROM_BASE, 0x0000, \
METHOD_BUFFERED, FILE_READ_ACCESS)
#endif
#ifndef IOCTL_CDROM_RAW_READ
#define IOCTL_CDROM_RAW_READ CTL_CODE(IOCTL_CDROM_BASE, 0x000F, \
METHOD_OUT_DIRECT, FILE_READ_ACCESS)
#endif
/* Win32 aspi specific */
#define WIN_NT ( GetVersion() < 0x80000000 )
#define ASPI_HAID 0
#define ASPI_TARGET 0
#define DTYPE_CDROM 0x05
#define SENSE_LEN 0x0E
#define SC_GET_DEV_TYPE 0x01
#define SC_EXEC_SCSI_CMD 0x02
#define SC_GET_DISK_INFO 0x06
#define SS_COMP 0x01
#define SS_PENDING 0x00
#define SS_NO_ADAPTERS 0xE8
#define SRB_DIR_IN 0x08
#define SRB_DIR_OUT 0x10
#define SRB_EVENT_NOTIFY 0x40
#define READ_CD 0xbe
#define SECTOR_TYPE_MODE2 0x14
#define READ_CD_USERDATA_MODE2 0x10
#define READ_TOC 0x43
#define READ_TOC_FORMAT_TOC 0x0
#pragma pack(1)
struct SRB_GetDiskInfo
{
unsigned char SRB_Cmd;
unsigned char SRB_Status;
unsigned char SRB_HaId;
unsigned char SRB_Flags;
unsigned long SRB_Hdr_Rsvd;
unsigned char SRB_Target;
unsigned char SRB_Lun;
unsigned char SRB_DriveFlags;
unsigned char SRB_Int13HDriveInfo;
unsigned char SRB_Heads;
unsigned char SRB_Sectors;
unsigned char SRB_Rsvd1[22];
};
struct SRB_GDEVBlock
{
unsigned char SRB_Cmd;
unsigned char SRB_Status;
unsigned char SRB_HaId;
unsigned char SRB_Flags;
unsigned long SRB_Hdr_Rsvd;
unsigned char SRB_Target;
unsigned char SRB_Lun;
unsigned char SRB_DeviceType;
unsigned char SRB_Rsvd1;
};
struct SRB_ExecSCSICmd
{
unsigned char SRB_Cmd;
unsigned char SRB_Status;
unsigned char SRB_HaId;
unsigned char SRB_Flags;
unsigned long SRB_Hdr_Rsvd;
unsigned char SRB_Target;
unsigned char SRB_Lun;
unsigned short SRB_Rsvd1;
unsigned long SRB_BufLen;
unsigned char *SRB_BufPointer;
unsigned char SRB_SenseLen;
unsigned char SRB_CDBLen;
unsigned char SRB_HaStat;
unsigned char SRB_TargStat;
unsigned long *SRB_PostProc;
unsigned char SRB_Rsvd2[20];
unsigned char CDBByte[16];
unsigned char SenseArea[SENSE_LEN+2];
};
#pragma pack()
#endif /* WIN32 */
/*****************************************************************************
* Local Prototypes
*****************************************************************************/
static int OpenVCDImage( vlc_object_t *, const char *, vcddev_t * );
static void CloseVCDImage( vlc_object_t *, vcddev_t * );
/****************************************************************************** #if defined( SYS_DARWIN )
* Prototypes * static CDTOC *darwin_getTOC( vlc_object_t *, const char * );
******************************************************************************/ static int darwin_getNumberOfDescriptors( CDTOC * );
int ioctl_GetTrackCount ( vlc_object_t *, int, const char *psz_dev ); static int darwin_getNumberOfTracks( CDTOC *, int );
int * ioctl_GetSectors ( vlc_object_t *, int, const char *psz_dev );
int ioctl_ReadSector ( vlc_object_t *, int, int, byte_t * );
#elif defined( WIN32 )
static int win32_vcd_open( vlc_object_t *, const char *, vcddev_t * );
#endif
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* vcd.c : VCD input module for vlc * vcd.c : VCD input module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2000 VideoLAN * Copyright (C) 2000 VideoLAN
* $Id: vcd.c,v 1.6 2002/10/04 18:07:21 sam Exp $ * $Id: vcd.c,v 1.7 2002/10/15 19:56:59 gbazin Exp $
* *
* Author: Johan Bilien <jobi@via.ecp.fr> * Author: Johan Bilien <jobi@via.ecp.fr>
* *
...@@ -36,23 +36,28 @@ ...@@ -36,23 +36,28 @@
# include <unistd.h> # include <unistd.h>
#endif #endif
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h> #include <string.h>
#include <errno.h>
#if defined( WIN32 )
# include <io.h> /* read() */
#endif
#include "vcd.h" #include "vcd.h"
#include "cdrom.h"
/* how many blocks VCDRead will read in each loop */ /* how many blocks VCDRead will read in each loop */
#define VCD_BLOCKS_ONCE 20 #define VCD_BLOCKS_ONCE 20
#define VCD_DATA_ONCE (VCD_BLOCKS_ONCE * VCD_DATA_SIZE) #define VCD_DATA_ONCE (VCD_BLOCKS_ONCE * VCD_DATA_SIZE)
/*****************************************************************************
* thread_vcd_data_t: VCD information
*****************************************************************************/
typedef struct thread_vcd_data_s
{
vcddev_t *vcddev; /* vcd device descriptor */
int nb_tracks; /* Nb of tracks (titles) */
int i_track; /* Current track */
int i_sector; /* Current Sector */
int * p_sectors; /* Track sectors */
vlc_bool_t b_end_of_track; /* If the end of track was reached */
} thread_vcd_data_t;
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
*****************************************************************************/ *****************************************************************************/
...@@ -87,7 +92,6 @@ static int VCDOpen( vlc_object_t *p_this ) ...@@ -87,7 +92,6 @@ static int VCDOpen( vlc_object_t *p_this )
char * psz_parser; char * psz_parser;
char * psz_source; char * psz_source;
char * psz_next; char * psz_next;
struct stat stat_info;
thread_vcd_data_t * p_vcd; thread_vcd_data_t * p_vcd;
int i; int i;
input_area_t * p_area; input_area_t * p_area;
...@@ -99,6 +103,12 @@ static int VCDOpen( vlc_object_t *p_this ) ...@@ -99,6 +103,12 @@ static int VCDOpen( vlc_object_t *p_this )
p_input->pf_set_area = VCDSetArea; p_input->pf_set_area = VCDSetArea;
p_input->pf_set_program = VCDSetProgram; p_input->pf_set_program = VCDSetProgram;
#ifdef WIN32
/* On Win32 we want the VCD access plugin to be explicitly requested,
* we end up with lots of problems otherwise */
if( !p_input->psz_access || !*p_input->psz_access ) return( -1 );
#endif
/* parse the options passed in command line : */ /* parse the options passed in command line : */
psz_orig = psz_parser = psz_source = strdup( p_input->psz_name ); psz_orig = psz_parser = psz_source = strdup( p_input->psz_name );
...@@ -137,29 +147,15 @@ static int VCDOpen( vlc_object_t *p_this ) ...@@ -137,29 +147,15 @@ static int VCDOpen( vlc_object_t *p_this )
return -1; return -1;
} }
psz_source = config_GetPsz( p_input, "vcd" ); psz_source = config_GetPsz( p_input, "vcd" );
if( !psz_source ) return -1;
} }
/* test the type of file given */
if( stat( psz_source, &stat_info ) == -1 )
{
msg_Err( p_input, "cannot stat() source `%s' (%s)",
psz_source, strerror(errno));
return( -1 );
}
if( !S_ISBLK(stat_info.st_mode) && !S_ISCHR(stat_info.st_mode))
{
msg_Warn( p_input, "vcd module discarded (not a valid drive)" );
return -1;
}
p_vcd = malloc( sizeof(thread_vcd_data_t) ); p_vcd = malloc( sizeof(thread_vcd_data_t) );
if( p_vcd == NULL ) if( p_vcd == NULL )
{ {
msg_Err( p_input, "out of memory" ); msg_Err( p_input, "out of memory" );
free( psz_source );
return -1; return -1;
} }
...@@ -177,39 +173,26 @@ static int VCDOpen( vlc_object_t *p_this ) ...@@ -177,39 +173,26 @@ static int VCDOpen( vlc_object_t *p_this )
vlc_mutex_unlock( &p_input->stream.stream_lock ); vlc_mutex_unlock( &p_input->stream.stream_lock );
p_vcd->i_handle = open( psz_source, O_RDONLY | O_NONBLOCK ); if( !(p_vcd->vcddev = ioctl_Open( p_this, psz_source )) )
if( p_vcd->i_handle == -1 )
{ {
msg_Err( p_input, "could not open %s", psz_source ); msg_Err( p_input, "could not open %s", psz_source );
free (p_vcd); free( psz_source );
free( p_vcd );
return -1; return -1;
} }
/* We read the Table Of Content information */ /* We read the Table Of Content information */
p_vcd->nb_tracks = ioctl_GetTrackCount( VLC_OBJECT( p_input), p_vcd->nb_tracks = ioctl_GetTracksMap( VLC_OBJECT(p_input),
p_vcd->i_handle, psz_source ); p_vcd->vcddev, &p_vcd->p_sectors );
free( psz_source );
if( p_vcd->nb_tracks < 0 ) if( p_vcd->nb_tracks < 0 )
{
msg_Err( p_input, "unable to count tracks" ); msg_Err( p_input, "unable to count tracks" );
close( p_vcd->i_handle );
free( p_vcd );
return -1;
}
else if( p_vcd->nb_tracks <= 1 ) else if( p_vcd->nb_tracks <= 1 )
{
msg_Err( p_input, "no movie tracks found" ); msg_Err( p_input, "no movie tracks found" );
close( p_vcd->i_handle ); if( p_vcd->nb_tracks <= 1)
free( p_vcd );
return -1;
}
p_vcd->p_sectors = ioctl_GetSectors( VLC_OBJECT( p_input),
p_vcd->i_handle, psz_source );
if( p_vcd->p_sectors == NULL )
{ {
input_BuffersEnd( p_input, p_input->p_method_data ); //input_BuffersEnd( p_input, p_input->p_method_data ); /* ??? */
close( p_vcd->i_handle ); ioctl_Close( p_this, p_vcd->vcddev );
free( p_vcd ); free( p_vcd );
return -1; return -1;
} }
...@@ -263,7 +246,7 @@ static void VCDClose( vlc_object_t *p_this ) ...@@ -263,7 +246,7 @@ static void VCDClose( vlc_object_t *p_this )
input_thread_t * p_input = (input_thread_t *)p_this; input_thread_t * p_input = (input_thread_t *)p_this;
thread_vcd_data_t *p_vcd = (thread_vcd_data_t *)p_input->p_access_data; thread_vcd_data_t *p_vcd = (thread_vcd_data_t *)p_input->p_access_data;
close( p_vcd->i_handle ); ioctl_Close( p_this, p_vcd->vcddev );
free( p_vcd ); free( p_vcd );
} }
...@@ -292,7 +275,7 @@ static int VCDRead( input_thread_t * p_input, byte_t * p_buffer, ...@@ -292,7 +275,7 @@ static int VCDRead( input_thread_t * p_input, byte_t * p_buffer,
for ( i_index = 0 ; i_index < i_blocks ; i_index++ ) for ( i_index = 0 ; i_index < i_blocks ; i_index++ )
{ {
if ( ioctl_ReadSector( VLC_OBJECT(p_input), p_vcd->i_handle, if ( ioctl_ReadSector( VLC_OBJECT(p_input), p_vcd->vcddev,
p_vcd->i_sector, p_buffer + i_index * VCD_DATA_SIZE ) < 0 ) p_vcd->i_sector, p_buffer + i_index * VCD_DATA_SIZE ) < 0 )
{ {
msg_Err( p_input, "could not read sector %d", p_vcd->i_sector ); msg_Err( p_input, "could not read sector %d", p_vcd->i_sector );
...@@ -321,7 +304,7 @@ static int VCDRead( input_thread_t * p_input, byte_t * p_buffer, ...@@ -321,7 +304,7 @@ static int VCDRead( input_thread_t * p_input, byte_t * p_buffer,
if ( i_len % VCD_DATA_SIZE ) /* this should not happen */ if ( i_len % VCD_DATA_SIZE ) /* this should not happen */
{ {
if ( ioctl_ReadSector( VLC_OBJECT(p_input), p_vcd->i_handle, if ( ioctl_ReadSector( VLC_OBJECT(p_input), p_vcd->vcddev,
p_vcd->i_sector, p_last_sector ) < 0 ) p_vcd->i_sector, p_last_sector ) < 0 )
{ {
msg_Err( p_input, "could not read sector %d", p_vcd->i_sector ); msg_Err( p_input, "could not read sector %d", p_vcd->i_sector );
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* vcd.h: thread structure of the VCD plugin * vcd.h: thread structure of the VCD plugin
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: vcd.h,v 1.1 2002/08/04 17:23:42 sam Exp $ * $Id: vcd.h,v 1.2 2002/10/15 19:56:59 gbazin Exp $
* *
* Author: Johan Bilien <jobi@via.ecp.fr> * Author: Johan Bilien <jobi@via.ecp.fr>
* *
...@@ -21,17 +21,24 @@ ...@@ -21,17 +21,24 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/ *****************************************************************************/
/***************************************************************************** /* where the data start on a VCD sector */
* thread_vcd_data_t: VCD information #define VCD_DATA_START 24
*****************************************************************************/ /* size of the availablr data on a VCD sector */
typedef struct thread_vcd_data_s #define VCD_DATA_SIZE 2324
{ /* size of a VCD sector, header and tail included */
int i_handle; /* File descriptor */ #define VCD_SECTOR_SIZE 2352
int nb_tracks; /* Nb of tracks (titles) */ /* size of a CD sector */
int i_track; /* Current track */ #define CD_SECTOR_SIZE 2048
int i_sector; /* Current Sector */
int * p_sectors; /* Track sectors */
vlc_bool_t b_end_of_track; /* If the end of track was reached */
} thread_vcd_data_t; #ifndef VCDDEV_T
typedef struct vcddev_s vcddev_t;
#endif
/*****************************************************************************
* Prototypes
*****************************************************************************/
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 * );
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment