Index: stream/vcd_read_os2.h =================================================================== --- stream/vcd_read_os2.h (revision 0) +++ stream/vcd_read_os2.h (revision 0) @@ -0,0 +1,275 @@ +#ifndef MPLAYER_VCD_READ_OS2_H +#define MPLAYER_VCD_READ_OS2_H + +#define INCL_DOS +#define INCL_DOSDEVIOCTL +#include + +#include "mp_msg.h" + +#pragma pack( 1 ) + +typedef struct +{ + BYTE bFrame; + BYTE bSecond; + BYTE bMinute; + BYTE bReserved; +} msf_t; + +typedef struct +{ + HFILE hcd; + msf_t msfCurrent; + int iFirstTrack; + int iLastTrack; + msf_t msfLeadOut; +} mp_vcd_priv_t; + +static inline void vcd_set_msf( mp_vcd_priv_t *vcd, unsigned sect ) +{ + sect += 150; + vcd->msfCurrent.bFrame = sect % 75; + sect = sect / 75; + vcd->msfCurrent.bSecond = sect % 60; + sect = sect / 60; + vcd->msfCurrent.bMinute = sect; +} + +static inline unsigned vcd_get_msf( mp_vcd_priv_t *vcd ) +{ + return vcd->msfCurrent.bFrame + + ( vcd->msfCurrent.bSecond + vcd->msfCurrent.bMinute * 60 ) * 75 - 150; +} + +int vcd_seek_to_track( mp_vcd_priv_t *vcd, int track ) +{ + struct + { + UCHAR auchSign[ 4 ]; + BYTE bTrack; + } sParam = {{'C', 'D', '0', '1'}, }; + + struct + { + msf_t msfStart; + BYTE bControlInfo; + } sData; + + ULONG ulParamLen; + ULONG ulDataLen; + ULONG rc; + + sParam.bTrack = track; + + rc = DosDevIOCtl( + vcd->hcd, IOCTL_CDROMAUDIO, CDROMAUDIO_GETAUDIOTRACK, + &sParam, sizeof( sParam ), &ulParamLen, + &sData, sizeof( sData ), &ulDataLen ); + + if( rc ) + { + mp_msg( MSGT_STREAM, MSGL_ERR, "DosDevIOCtl(GETAUDIOTRACK) = 0x%lx\n", rc ); + + return -1; + } + + vcd->msfCurrent = sData.msfStart; + + return VCD_SECTOR_DATA * vcd_get_msf( vcd ); +} + +int vcd_get_track_end( mp_vcd_priv_t *vcd, int track ) +{ + if( track < vcd->iLastTrack ) + return vcd_seek_to_track( vcd, track + 1 ); + + vcd->msfCurrent = vcd->msfLeadOut; + + return VCD_SECTOR_DATA * vcd_get_msf( vcd ); +} + +mp_vcd_priv_t *vcd_read_toc( int fd ) +{ + mp_vcd_priv_t *vcd; + + struct + { + UCHAR auchSign[ 4 ]; + } sParamDisk = {{'C', 'D', '0', '1'}}; + + struct + { + BYTE bFirstTrack; + BYTE bLastTrack; + msf_t msfLeadOut; + } sDataDisk; + + struct + { + UCHAR auchSign[ 4 ]; + BYTE bTrack; + } sParamTrack = {{'C', 'D', '0', '1'}, }; + + struct + { + msf_t msfStart; + BYTE bControlInfo; + } sDataTrack; + + ULONG ulParamLen; + ULONG ulDataLen; + ULONG rc; + int i, iMinute = 0, iSecond = 0, iFrame = 0; + + rc = DosDevIOCtl( + fd, IOCTL_CDROMAUDIO, CDROMAUDIO_GETAUDIODISK, + &sParamDisk, sizeof( sParamDisk ), &ulParamLen, + &sDataDisk, sizeof( sDataDisk ), &ulDataLen ); + + if( rc ) + { + mp_msg( MSGT_OPEN, MSGL_ERR, "DosDevIOCtl(GETAUDIODISK) = 0x%lx\n", rc ); + + return NULL; + } + + mp_msg( MSGT_IDENTIFY, MSGL_INFO, "ID_VCD_START_TRACK=%d\n", sDataDisk.bFirstTrack ); + mp_msg( MSGT_IDENTIFY, MSGL_INFO, "ID_VCD_END_TRACK=%d\n", sDataDisk.bLastTrack ); + + for( i = sDataDisk.bFirstTrack; i <= sDataDisk.bLastTrack + 1; i++ ) + { + if( i <= sDataDisk.bLastTrack ) + { + sParamTrack.bTrack = i; + + rc = DosDevIOCtl( + fd, IOCTL_CDROMAUDIO, CDROMAUDIO_GETAUDIOTRACK, + &sParamTrack, sizeof( sParamTrack ), &ulParamLen, + &sDataTrack, sizeof( sDataTrack ), &ulDataLen ); + + if( rc ) + { + mp_msg( MSGT_OPEN, MSGL_ERR, "DosDevIOCtl(GETAUDIOTRACK) = 0x%lx\n", rc ); + + return NULL; + } + + mp_msg( MSGT_OPEN, MSGL_INFO, "track %02d: adr=%d ctrl=%d %02d:%02d:%02d\n", + i, + sDataTrack.bControlInfo & 0x0F, + ( sDataTrack.bControlInfo >> 4 ) & 0x0F, + sDataTrack.msfStart.bMinute, + sDataTrack.msfStart.bSecond, + sDataTrack.msfStart.bFrame ); + } + else + sDataTrack.msfStart = sDataDisk.msfLeadOut; + + if( mp_msg_test( MSGT_IDENTIFY, MSGL_INFO )) + { + if(i > sDataDisk.bFirstTrack ) + { + iMinute = sDataTrack.msfStart.bMinute - iMinute; + iSecond = sDataTrack.msfStart.bSecond - iSecond; + iFrame = sDataTrack.msfStart.bFrame - iFrame; + + if( iFrame < 0 ) + { + iFrame += 75; + iSecond--; + } + + if( iSecond < 0 ) + { + iSecond += 60; + iMinute--; + } + + mp_msg( MSGT_IDENTIFY, MSGL_INFO, "ID_VCD_TRACK_%d_MSF=%02d:%02d:%02d\n", + i - 1, iMinute, iSecond, iFrame); + } + + iMinute = sDataTrack.msfStart.bMinute; + iSecond = sDataTrack.msfStart.bSecond; + iFrame = sDataTrack.msfStart.bFrame; + } + } + + vcd = calloc( 1, sizeof( mp_vcd_priv_t )); + vcd->hcd = fd; + vcd->iFirstTrack = sDataDisk.bFirstTrack; + vcd->iLastTrack = sDataDisk.bLastTrack; + vcd->msfLeadOut = sDataDisk.msfLeadOut; + + return vcd; +} + +static int vcd_read( mp_vcd_priv_t *vcd, char *mem ) +{ + struct + { + UCHAR auchSign[ 4 ]; + BYTE bAddrMode; + USHORT usSectors; + msf_t msfStart; + BYTE bReserved; + BYTE bInterleavedSize; + } sParam = {{'C', 'D', '0', '1'}, 1, 1, }; + + struct + { + BYTE abSync[ 12 ]; + BYTE abHeader[ 4 ]; + BYTE abSubHeader[ 8 ]; + BYTE abData[ 2324 ]; + BYTE abSpare[ 4 ]; + } sData; + + ULONG ulParamLen; + ULONG ulDataLen; + ULONG rc; + + /* lead-out ? */ + if( vcd->msfCurrent.bMinute == vcd->msfLeadOut.bMinute && + vcd->msfCurrent.bSecond == vcd->msfLeadOut.bSecond && + vcd->msfCurrent.bFrame == vcd->msfLeadOut.bFrame ) + return 0; + + sParam.msfStart = vcd->msfCurrent; + + rc = DosDevIOCtl( + vcd->hcd, IOCTL_CDROMDISK, CDROMDISK_READLONG, + &sParam, sizeof( sParam ), &ulParamLen, + &sData, sizeof( sData ), &ulDataLen ); + + if( rc ) + { + mp_msg( MSGT_STREAM, MSGL_ERR, "DosDevIOCtl(READLONG) = 0x%lx\n", rc ); + + return 0; + } + + memcpy( mem, sData.abData, VCD_SECTOR_DATA ); + + vcd->msfCurrent.bFrame++; + if( vcd->msfCurrent.bFrame == 75 ) + { + vcd->msfCurrent.bFrame = 0; + + vcd->msfCurrent.bSecond++; + if( vcd->msfCurrent.bSecond == 60 ) + { + vcd->msfCurrent.bSecond = 0; + + vcd->msfCurrent.bMinute++; + } + } + + return VCD_SECTOR_DATA; +} + +#pragma pack() + +#endif /* MPLAYER_VCD_READ_OS2_H */ + Index: stream/stream_vcd.c =================================================================== --- stream/stream_vcd.c (revision 28306) +++ stream/stream_vcd.c (working copy) @@ -5,6 +5,12 @@ #include #endif +#if defined(__OS2__) +#define INCL_DOS +#define INCL_DOSDEVIOCTL +#include +#endif + #include "mp_msg.h" #include "stream.h" #include "help_mp.h" @@ -25,6 +31,8 @@ #include "vcd_read_darwin.h" #elif defined(__MINGW32__) || defined(__CYGWIN__) #include "vcd_read_win32.h" +#elif defined(__OS2__) +#include "vcd_read_os2.h" #else #include "vcd_read.h" #endif @@ -85,6 +93,12 @@ HANDLE hd; char device[] = "\\\\.\\?:"; #endif +#if defined(__OS2__) + char device[] = "X:"; + HFILE hcd; + ULONG ulAction; + ULONG rc; +#endif if(mode != STREAM_READ #if defined(__MINGW32__) || defined(__CYGWIN__) @@ -108,6 +122,13 @@ hd = CreateFile(device, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL); f = _open_osfhandle((long)hd, _O_RDONLY); +#elif defined(__OS2__) + device[ 0 ] = p->device[ 0 ]; + rc = DosOpen( device, &hcd, &ulAction, 0, FILE_NORMAL, + OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW, + OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE | OPEN_FLAGS_DASD, + NULL ); + f = rc ? -1 : hcd; #else f=open(p->device,O_RDONLY); #endif Index: configure =================================================================== --- configure (revision 28306) +++ configure (working copy) @@ -5599,7 +5655,7 @@ echocheck "VCD support" -if linux || freebsd || netbsd || openbsd || dragonfly || bsdos || darwin || sunos || mingw32; then +if linux || freebsd || netbsd || openbsd || dragonfly || bsdos || darwin || sunos || mingw32 || os2; then _inputmodules="vcd $_inputmodules" _def_vcd='#define CONFIG_VCD 1' _vcd="yes"