Index: stream/vcd_read_os2.h =================================================================== --- stream/vcd_read_os2.h (revision 0) +++ stream/vcd_read_os2.h (revision 0) @@ -0,0 +1,258 @@ +/* + * implementation of VCD IO for OS/2 + * + * Copyright (c) 2009 KO Myung-Hun (komh@chollian.net) + * + * This file is part of MPlayer. + * + * MPlayer is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * MPlayer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * 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 MPlayer; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPLAYER_VCD_READ_OS2_H +#define MPLAYER_VCD_READ_OS2_H + +#define INCL_DOS +#define INCL_DOSDEVIOCTL +#include + +#include "mp_msg.h" + +struct __attribute__((packed)) msf { + BYTE bFrame; + BYTE bSecond; + BYTE bMinute; + BYTE bReserved; +}; + +typedef struct { + HFILE hcd; + struct msf msfCurrent; + int iFirstTrack; + int iLastTrack; + struct msf msfLeadOut; + BYTE abVCDSector[VCD_SECTOR_SIZE]; +} 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; + } __attribute__((packed)) sParam = {{'C', 'D', '0', '1'},}; + + struct { + struct msf msfStart; + BYTE bControlInfo; + } __attribute__((packed)) 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; + + UCHAR auchParamDisk[ 4 ] = {'C', 'D', '0', '1'}; + + struct { + BYTE bFirstTrack; + BYTE bLastTrack; + struct msf msfLeadOut; + } __attribute__((packed)) sDataDisk; + + struct { + UCHAR auchSign[4]; + BYTE bTrack; + } __attribute__((packed)) sParamTrack = {{'C', 'D', '0', '1'},}; + + struct { + struct msf msfStart; + BYTE bControlInfo; + } __attribute__((packed)) sDataTrack; + + ULONG ulParamLen; + ULONG ulDataLen; + ULONG rc; + int i, iMinute = 0, iSecond = 0, iFrame = 0; + + rc = DosDevIOCtl(fd, IOCTL_CDROMAUDIO, CDROMAUDIO_GETAUDIODISK, + auchParamDisk, sizeof(auchParamDisk), &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, + 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; + struct msf msfStart; + BYTE bReserved; + BYTE bInterleavedSize; + } __attribute__((packed)) sParam = {{'C', 'D', '0', '1'}, 1, 1,}; + + 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, + vcd->abVCDSector, sizeof(vcd->abVCDSector), &ulDataLen); + + if (rc) { + mp_msg(MSGT_STREAM, MSGL_ERR, "DosDevIOCtl(READLONG) = 0x%lx\n", rc); + + return 0; + } + + memcpy(mem, &vcd->abVCDSector[VCD_SECTOR_OFFS], 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; +} + +#endif /* MPLAYER_VCD_READ_OS2_H */ + Index: stream/stream_vcd.c =================================================================== --- stream/stream_vcd.c (revision 30605) +++ stream/stream_vcd.c (working copy) @@ -22,6 +22,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" @@ -42,6 +48,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 @@ -102,6 +110,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__) @@ -125,6 +139,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 30605) +++ configure (working copy) @@ -6148,7 +6148,7 @@ echocheck "VCD support" if test "$_vcd" = auto; then _vcd=no - if linux || freebsd || netbsd || openbsd || dragonfly || bsdos || darwin || sunos; then + if linux || freebsd || netbsd || openbsd || dragonfly || bsdos || darwin || sunos || os2; then _vcd=yes elif mingw32; then cat > $TMPC << EOF