2 * This file is part of MPlayer.
4 * MPlayer is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * MPlayer is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 #ifndef MPLAYER_VCD_READ_WIN32_H
20 #define MPLAYER_VCD_READ_WIN32_H
25 #include <ddk/ntddcdrm.h>
28 typedef struct mp_vcd_priv_st mp_vcd_priv_t
;
31 Unlike Unices, upon reading TOC, Windows will retrieve information for
32 all tracks, so we don't need to call DeviceIoControl() in functions
33 like vcd_seek_to_track() and vcd_get_track_end() for each track. Instead
34 we cache the information in mp_vcd_priv_st.
36 struct mp_vcd_priv_st
{
40 char buf
[VCD_SECTOR_SIZE
];
43 static inline void vcd_set_msf(mp_vcd_priv_t
* vcd
, unsigned sect
)
48 static inline unsigned vcd_get_msf(mp_vcd_priv_t
* vcd
, int track
){
49 int index
= track
- vcd
->toc
.FirstTrack
;
50 /* -150 to compensate the 2-second pregap */
51 return vcd
->toc
.TrackData
[index
].Address
[3] +
52 (vcd
->toc
.TrackData
[index
].Address
[2] +
53 vcd
->toc
.TrackData
[index
].Address
[1] * 60) * 75 - 150;
56 static int vcd_seek_to_track(mp_vcd_priv_t
* vcd
, int track
)
59 if (track
< vcd
->toc
.FirstTrack
|| track
> vcd
->toc
.LastTrack
)
61 sect
= vcd_get_msf(vcd
, track
);
62 vcd_set_msf(vcd
, sect
);
63 return VCD_SECTOR_DATA
* (sect
+ 2);
66 static int vcd_get_track_end(mp_vcd_priv_t
* vcd
, int track
)
68 if (track
< vcd
->toc
.FirstTrack
|| track
> vcd
->toc
.LastTrack
)
70 return VCD_SECTOR_DATA
* (vcd_get_msf(vcd
, track
+ 1));
73 static mp_vcd_priv_t
* vcd_read_toc(int fd
)
75 DWORD dwBytesReturned
;
77 int i
, min
= 0, sec
= 0, frame
= 0;
78 mp_vcd_priv_t
* vcd
= malloc(sizeof(mp_vcd_priv_t
));
82 hd
= (HANDLE
)_get_osfhandle(fd
);
83 if (!DeviceIoControl(hd
, IOCTL_CDROM_READ_TOC
, NULL
, 0, &vcd
->toc
,
84 sizeof(CDROM_TOC
), &dwBytesReturned
, NULL
)) {
85 mp_msg(MSGT_OPEN
, MSGL_ERR
, "read CDROM toc header: %lu\n",
91 mp_msg(MSGT_IDENTIFY
, MSGL_INFO
, "ID_VCD_START_TRACK=%d\n",
93 mp_msg(MSGT_IDENTIFY
, MSGL_INFO
, "ID_VCD_END_TRACK=%d\n",
96 for (i
= vcd
->toc
.FirstTrack
; i
<= vcd
->toc
.LastTrack
+ 1; i
++) {
97 int index
= i
- vcd
->toc
.FirstTrack
;
98 if (i
<= vcd
->toc
.LastTrack
) {
99 mp_msg(MSGT_OPEN
, MSGL_INFO
, "track %02d: adr=%d ctrl=%d"
101 vcd
->toc
.TrackData
[index
].TrackNumber
,
102 vcd
->toc
.TrackData
[index
].Adr
,
103 vcd
->toc
.TrackData
[index
].Control
,
104 vcd
->toc
.TrackData
[index
].Address
[1],
105 vcd
->toc
.TrackData
[index
].Address
[2],
106 vcd
->toc
.TrackData
[index
].Address
[3]);
109 if (mp_msg_test(MSGT_IDENTIFY
, MSGL_INFO
)) {
110 if (i
> vcd
->toc
.FirstTrack
) {
111 min
= vcd
->toc
.TrackData
[index
].Address
[1] - min
;
112 sec
= vcd
->toc
.TrackData
[index
].Address
[2] - sec
;
113 frame
= vcd
->toc
.TrackData
[index
].Address
[3] - frame
;
122 mp_msg(MSGT_IDENTIFY
, MSGL_INFO
, "ID_VCD_TRACK_%d_MSF="
123 "%02d:%02d:%02d\n", i
- 1, min
, sec
, frame
);
124 min
= vcd
->toc
.TrackData
[index
].Address
[1];
125 sec
= vcd
->toc
.TrackData
[index
].Address
[2];
126 frame
= vcd
->toc
.TrackData
[index
].Address
[3];
135 static int vcd_end_track(mp_vcd_priv_t
* vcd
)
137 return vcd
->toc
.LastTrack
;
140 static int vcd_read(mp_vcd_priv_t
* vcd
, char *mem
)
142 DWORD dwBytesReturned
;
143 RAW_READ_INFO cdrom_raw
;
145 /* 2048 isn't a typo: it's the Windows way. */
146 cdrom_raw
.DiskOffset
.QuadPart
= (long long)(2048 * vcd
->sect
);
147 cdrom_raw
.SectorCount
= 1;
148 cdrom_raw
.TrackMode
= XAForm2
;
150 if (!DeviceIoControl(vcd
->hd
, IOCTL_CDROM_RAW_READ
, &cdrom_raw
,
151 sizeof(RAW_READ_INFO
), vcd
->buf
, sizeof(vcd
->buf
),
152 &dwBytesReturned
, NULL
))
156 memcpy(mem
, &vcd
->buf
[VCD_SECTOR_OFFS
], VCD_SECTOR_DATA
);
157 return VCD_SECTOR_DATA
;
160 #endif /* MPLAYER_VCD_READ_WIN32_H */