Update to MPlayer SVN rev 34180.
[vaapi:mplayer.git] / stream / vcd_read_os2.h
1 /*
2  * implementation of VCD IO for OS/2
3  *
4  * Copyright (c) 2009 KO Myung-Hun (komh@chollian.net)
5  *
6  * This file is part of MPlayer.
7  *
8  * MPlayer is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * MPlayer is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with MPlayer; if not, write to the Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21  */
22
23 #ifndef MPLAYER_VCD_READ_OS2_H
24 #define MPLAYER_VCD_READ_OS2_H
25
26 #include "mp_msg.h"
27
28 struct __attribute__((packed)) msf {
29     BYTE bFrame;
30     BYTE bSecond;
31     BYTE bMinute;
32     BYTE bReserved;
33 };
34
35 typedef struct {
36     HFILE      hcd;
37     struct msf msfCurrent;
38     int        iFirstTrack;
39     int        iLastTrack;
40     struct msf msfLeadOut;
41     BYTE       abVCDSector[VCD_SECTOR_SIZE];
42 } mp_vcd_priv_t;
43
44 static inline void vcd_set_msf(mp_vcd_priv_t *vcd, unsigned sect)
45 {
46     sect += 150;
47     vcd->msfCurrent.bFrame = sect % 75;
48     sect = sect / 75;
49     vcd->msfCurrent.bSecond = sect % 60;
50     sect = sect / 60;
51     vcd->msfCurrent.bMinute = sect;
52 }
53
54 static inline unsigned vcd_get_msf(mp_vcd_priv_t *vcd)
55 {
56   return vcd->msfCurrent.bFrame  +
57         (vcd->msfCurrent.bSecond + vcd->msfCurrent.bMinute * 60) * 75 - 150;
58 }
59
60 static int vcd_seek_to_track(mp_vcd_priv_t *vcd, int track)
61 {
62     struct {
63         UCHAR auchSign[4];
64         BYTE  bTrack;
65     } __attribute__((packed)) sParam = {{'C', 'D', '0', '1'},};
66
67     struct {
68         struct msf msfStart;
69         BYTE       bControlInfo;
70     } __attribute__((packed)) sData;
71
72     ULONG ulParamLen;
73     ULONG ulDataLen;
74     ULONG rc;
75
76     sParam.bTrack = track;
77     rc = DosDevIOCtl(vcd->hcd, IOCTL_CDROMAUDIO, CDROMAUDIO_GETAUDIOTRACK,
78                      &sParam, sizeof(sParam), &ulParamLen,
79                      &sData, sizeof(sData), &ulDataLen);
80     if (rc) {
81         mp_msg(MSGT_STREAM, MSGL_ERR, "DosDevIOCtl(GETAUDIOTRACK) = 0x%lx\n", rc);
82         return -1;
83     }
84
85     vcd->msfCurrent = sData.msfStart;
86
87     return VCD_SECTOR_DATA * vcd_get_msf(vcd);
88 }
89
90 static int vcd_get_track_end(mp_vcd_priv_t *vcd, int track)
91 {
92     if (track < vcd->iLastTrack)
93         return vcd_seek_to_track(vcd, track + 1);
94
95     vcd->msfCurrent = vcd->msfLeadOut;
96
97     return VCD_SECTOR_DATA * vcd_get_msf(vcd);
98 }
99
100 static mp_vcd_priv_t *vcd_read_toc(int fd)
101 {
102     mp_vcd_priv_t *vcd;
103
104     UCHAR auchParamDisk[4] = {'C', 'D', '0', '1'};
105
106     struct {
107         BYTE       bFirstTrack;
108         BYTE       bLastTrack;
109         struct msf msfLeadOut;
110     } __attribute__((packed)) sDataDisk;
111
112     struct {
113         UCHAR auchSign[4];
114         BYTE  bTrack;
115     } __attribute__((packed)) sParamTrack = {{'C', 'D', '0', '1'},};
116
117     struct {
118         struct msf msfStart;
119         BYTE       bControlInfo;
120     } __attribute__((packed)) sDataTrack;
121
122     ULONG ulParamLen;
123     ULONG ulDataLen;
124     ULONG rc;
125     int   i, iMinute = 0, iSecond = 0, iFrame = 0;
126
127     rc = DosDevIOCtl(fd, IOCTL_CDROMAUDIO, CDROMAUDIO_GETAUDIODISK,
128                      auchParamDisk, sizeof(auchParamDisk), &ulParamLen,
129                      &sDataDisk, sizeof(sDataDisk), &ulDataLen);
130     if (rc) {
131         mp_msg(MSGT_OPEN, MSGL_ERR, "DosDevIOCtl(GETAUDIODISK) = 0x%lx\n", rc);
132         return NULL;
133     }
134
135     mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VCD_START_TRACK=%d\n", sDataDisk.bFirstTrack);
136     mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VCD_END_TRACK=%d\n", sDataDisk.bLastTrack);
137
138     for (i = sDataDisk.bFirstTrack; i <= sDataDisk.bLastTrack + 1; i++) {
139         if (i <= sDataDisk.bLastTrack) {
140             sParamTrack.bTrack = i;
141             rc = DosDevIOCtl(fd, IOCTL_CDROMAUDIO, CDROMAUDIO_GETAUDIOTRACK,
142                              &sParamTrack, sizeof(sParamTrack), &ulParamLen,
143                              &sDataTrack, sizeof(sDataTrack), &ulDataLen);
144             if (rc) {
145                 mp_msg(MSGT_OPEN, MSGL_ERR, "DosDevIOCtl(GETAUDIOTRACK) = 0x%lx\n", rc);
146                 return NULL;
147             }
148
149             mp_msg(MSGT_OPEN, MSGL_INFO, "track %02d:  adr=%d  ctrl=%d  %02d:%02d:%02d\n",
150                    i,
151                    sDataTrack.bControlInfo & 0x0F,
152                    sDataTrack.bControlInfo >> 4,
153                    sDataTrack.msfStart.bMinute,
154                    sDataTrack.msfStart.bSecond,
155                    sDataTrack.msfStart.bFrame);
156         } else
157             sDataTrack.msfStart = sDataDisk.msfLeadOut;
158
159         if (mp_msg_test(MSGT_IDENTIFY, MSGL_INFO)) {
160             if (i > sDataDisk.bFirstTrack) {
161                 iMinute = sDataTrack.msfStart.bMinute - iMinute;
162                 iSecond = sDataTrack.msfStart.bSecond - iSecond;
163                 iFrame  = sDataTrack.msfStart.bFrame  - iFrame;
164                 if (iFrame < 0) {
165                     iFrame += 75;
166                     iSecond--;
167                 }
168                 if (iSecond < 0) {
169                     iSecond += 60;
170                     iMinute--;
171                 }
172                 mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VCD_TRACK_%d_MSF=%02d:%02d:%02d\n",
173                        i - 1, iMinute, iSecond, iFrame);
174             }
175
176             iMinute = sDataTrack.msfStart.bMinute;
177             iSecond = sDataTrack.msfStart.bSecond;
178             iFrame  = sDataTrack.msfStart.bFrame;
179         }
180     }
181
182     vcd                 = calloc(1, sizeof(mp_vcd_priv_t));
183     vcd->hcd            = fd;
184     vcd->iFirstTrack    = sDataDisk.bFirstTrack;
185     vcd->iLastTrack     = sDataDisk.bLastTrack;
186     vcd->msfLeadOut     = sDataDisk.msfLeadOut;
187
188     return vcd;
189 }
190
191 static int vcd_end_track(mp_vcd_priv_t* vcd)
192 {
193     return vcd->iLastTrack;
194 }
195
196 static int vcd_read(mp_vcd_priv_t *vcd, char *mem)
197 {
198     struct {
199         UCHAR      auchSign[4];
200         BYTE       bAddrMode;
201         USHORT     usSectors;
202         struct msf msfStart;
203         BYTE       bReserved;
204         BYTE       bInterleavedSize;
205     } __attribute__((packed)) sParam = {{'C', 'D', '0', '1'}, 1, 1,};
206
207     ULONG ulParamLen;
208     ULONG ulDataLen;
209     ULONG rc;
210
211     /* lead-out ? */
212     if (vcd->msfCurrent.bMinute == vcd->msfLeadOut.bMinute &&
213         vcd->msfCurrent.bSecond == vcd->msfLeadOut.bSecond &&
214         vcd->msfCurrent.bFrame  == vcd->msfLeadOut.bFrame)
215         return 0;
216
217     sParam.msfStart = vcd->msfCurrent;
218     rc = DosDevIOCtl(vcd->hcd, IOCTL_CDROMDISK, CDROMDISK_READLONG,
219                      &sParam, sizeof(sParam), &ulParamLen,
220                      vcd->abVCDSector, sizeof(vcd->abVCDSector), &ulDataLen);
221     if (rc) {
222         mp_msg(MSGT_STREAM, MSGL_ERR, "DosDevIOCtl(READLONG) = 0x%lx\n", rc);
223         return 0;
224     }
225
226     memcpy(mem, &vcd->abVCDSector[VCD_SECTOR_OFFS], VCD_SECTOR_DATA);
227
228     vcd->msfCurrent.bFrame++;
229     if (vcd->msfCurrent.bFrame == 75) {
230         vcd->msfCurrent.bFrame = 0;
231         vcd->msfCurrent.bSecond++;
232         if (vcd->msfCurrent.bSecond == 60) {
233             vcd->msfCurrent.bSecond = 0;
234             vcd->msfCurrent.bMinute++;
235         }
236     }
237
238     return VCD_SECTOR_DATA;
239 }
240
241 #endif /* MPLAYER_VCD_READ_OS2_H */
242