Mercurial > mplayer.hg
comparison stream/vcd_read_win32.h @ 22508:499052866262
add vcd:// for win32, patch by zuxy meng
split up into the following commits r22523, r22524, r22526
author | compn |
---|---|
date | Mon, 12 Mar 2007 15:57:01 +0000 |
parents | |
children | ad0ac6f589eb |
comparison
equal
deleted
inserted
replaced
22507:a46ab26b2d5e | 22508:499052866262 |
---|---|
1 #include <ddk/ntddcdrm.h> | |
2 | |
3 typedef struct mp_vcd_priv_st mp_vcd_priv_t; | |
4 | |
5 /* | |
6 Unlike Unices, upon reading TOC, Windows will retrieve information for | |
7 all tracks, so we don't need to call DeviceIoControl() in functions | |
8 like vcd_seek_to_track() and vcd_get_track_end() for each track. Instead | |
9 we cache the information in mp_vcd_priv_st. | |
10 */ | |
11 struct mp_vcd_priv_st { | |
12 HANDLE hd; | |
13 CDROM_TOC toc; | |
14 unsigned sect; | |
15 char buf[VCD_SECTOR_SIZE]; | |
16 }; | |
17 | |
18 static inline void vcd_set_msf(mp_vcd_priv_t* vcd, unsigned sect) | |
19 { | |
20 vcd->sect = sect; | |
21 } | |
22 | |
23 static inline unsigned vcd_get_msf(mp_vcd_priv_t* vcd, int track){ | |
24 int index = track + vcd->toc.FirstTrack - 1; | |
25 /* -150 to compensate the 2-second pregap */ | |
26 return vcd->toc.TrackData[index].Address[3] + | |
27 (vcd->toc.TrackData[index].Address[2] + | |
28 vcd->toc.TrackData[index].Address[1] * 60) * 75 - 150; | |
29 } | |
30 | |
31 int vcd_seek_to_track(mp_vcd_priv_t* vcd, int track) | |
32 { | |
33 unsigned sect; | |
34 if (track < vcd->toc.FirstTrack || track > vcd->toc.LastTrack) | |
35 return -1; | |
36 sect = vcd_get_msf(vcd, track); | |
37 vcd_set_msf(vcd, sect); | |
38 return VCD_SECTOR_DATA * (sect + 2); | |
39 } | |
40 | |
41 int vcd_get_track_end(mp_vcd_priv_t* vcd, int track) | |
42 { | |
43 if (track < vcd->toc.FirstTrack || track > vcd->toc.LastTrack) | |
44 return -1; | |
45 return VCD_SECTOR_DATA * (vcd_get_msf(vcd, track + 1)); | |
46 } | |
47 | |
48 mp_vcd_priv_t* vcd_read_toc(int fd) | |
49 { | |
50 DWORD dwBytesReturned; | |
51 HANDLE hd; | |
52 int i, min = 0, sec = 0, frame = 0; | |
53 mp_vcd_priv_t* vcd = malloc(sizeof(mp_vcd_priv_t)); | |
54 if (!vcd) | |
55 return NULL; | |
56 | |
57 hd = (HANDLE)_get_osfhandle(fd); | |
58 if (!DeviceIoControl(hd, IOCTL_CDROM_READ_TOC, NULL, 0, &vcd->toc, | |
59 sizeof(CDROM_TOC), &dwBytesReturned, NULL)) { | |
60 mp_msg(MSGT_OPEN, MSGL_ERR, "read CDROM toc header: %u\n", | |
61 GetLastError()); | |
62 free(vcd); | |
63 return NULL; | |
64 } | |
65 | |
66 mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VCD_START_TRACK=%d\n", | |
67 vcd->toc.FirstTrack); | |
68 mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VCD_END_TRACK=%d\n", | |
69 vcd->toc.LastTrack); | |
70 | |
71 for (i = vcd->toc.FirstTrack; i <= vcd->toc.LastTrack + 1; i++) { | |
72 int index = i - vcd->toc.FirstTrack; | |
73 if (i <= vcd->toc.LastTrack) { | |
74 mp_msg(MSGT_OPEN, MSGL_INFO, "track %02d: adr=%d ctrl=%d" | |
75 " %02d:%02d:%02d\n", | |
76 vcd->toc.TrackData[index].TrackNumber, | |
77 vcd->toc.TrackData[index].Adr, | |
78 vcd->toc.TrackData[index].Control, | |
79 vcd->toc.TrackData[index].Address[1], | |
80 vcd->toc.TrackData[index].Address[2], | |
81 vcd->toc.TrackData[index].Address[3]); | |
82 } | |
83 | |
84 if (mp_msg_test(MSGT_IDENTIFY, MSGL_INFO)) { | |
85 if (i > vcd->toc.FirstTrack) { | |
86 min = vcd->toc.TrackData[index].Address[1] - min; | |
87 if (frame < 0) { | |
88 frame += 75; | |
89 sec--; | |
90 } | |
91 if (sec < 0) { | |
92 sec += 60; | |
93 min--; | |
94 } | |
95 mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VCD_TRACK_%d_MSF=" | |
96 "%02d:%02d:%02d\n", i - 1, min, sec, frame); | |
97 min = vcd->toc.TrackData[index].Address[1]; | |
98 sec = vcd->toc.TrackData[index].Address[2]; | |
99 frame = vcd->toc.TrackData[index].Address[3]; | |
100 } | |
101 } | |
102 } | |
103 | |
104 vcd->hd = hd; | |
105 return vcd; | |
106 } | |
107 | |
108 static int vcd_read(mp_vcd_priv_t* vcd, char *mem) | |
109 { | |
110 DWORD dwBytesReturned; | |
111 RAW_READ_INFO cdrom_raw; | |
112 | |
113 /* 2048 isn't a typo: it's the Windows way. */ | |
114 cdrom_raw.DiskOffset.QuadPart = (long long)(2048 * vcd->sect); | |
115 cdrom_raw.SectorCount = 1; | |
116 cdrom_raw.TrackMode = XAForm2; | |
117 | |
118 if (!DeviceIoControl(vcd->hd, IOCTL_CDROM_RAW_READ, &cdrom_raw, | |
119 sizeof(RAW_READ_INFO), vcd->buf, sizeof(vcd->buf), | |
120 &dwBytesReturned, NULL)) | |
121 return 0; | |
122 | |
123 vcd->sect++; | |
124 memcpy(mem, &vcd->buf[VCD_SECTOR_OFFS], VCD_SECTOR_DATA); | |
125 return VCD_SECTOR_DATA; | |
126 } | |
127 | |
128 /* | |
129 vim:noet:sw=4:cino=\:0,g0 | |
130 */ |