Mercurial > mplayer.hg
annotate stream/vcd_read_win32.h @ 26877:4ab1cfcee430
Add a slave command to stop stream playback.
Mostly useful when used with -idle mode.
Patch by Mathieu Schroeter ( mathieu dot schroeter at gamesover dot ch )
author | ben |
---|---|
date | Tue, 27 May 2008 18:39:57 +0000 |
parents | 7ee4ae1648e6 |
children | b4cbeff5153e |
rev | line source |
---|---|
26029 | 1 #ifndef MPLAYER_VCD_READ_WIN32_H |
2 #define MPLAYER_VCD_READ_WIN32_H | |
26013 | 3 |
22508 | 4 #include <ddk/ntddcdrm.h> |
26184
7ee4ae1648e6
Add missing header #includes to fix 'make checkheaders'.
diego
parents:
26029
diff
changeset
|
5 #include "mp_msg.h" |
22508 | 6 |
7 typedef struct mp_vcd_priv_st mp_vcd_priv_t; | |
8 | |
9 /* | |
10 Unlike Unices, upon reading TOC, Windows will retrieve information for | |
11 all tracks, so we don't need to call DeviceIoControl() in functions | |
12 like vcd_seek_to_track() and vcd_get_track_end() for each track. Instead | |
13 we cache the information in mp_vcd_priv_st. | |
14 */ | |
15 struct mp_vcd_priv_st { | |
16 HANDLE hd; | |
17 CDROM_TOC toc; | |
18 unsigned sect; | |
19 char buf[VCD_SECTOR_SIZE]; | |
20 }; | |
21 | |
22 static inline void vcd_set_msf(mp_vcd_priv_t* vcd, unsigned sect) | |
23 { | |
24 vcd->sect = sect; | |
25 } | |
26 | |
27 static inline unsigned vcd_get_msf(mp_vcd_priv_t* vcd, int track){ | |
25160 | 28 int index = track - vcd->toc.FirstTrack; |
22508 | 29 /* -150 to compensate the 2-second pregap */ |
30 return vcd->toc.TrackData[index].Address[3] + | |
31 (vcd->toc.TrackData[index].Address[2] + | |
32 vcd->toc.TrackData[index].Address[1] * 60) * 75 - 150; | |
33 } | |
34 | |
35 int vcd_seek_to_track(mp_vcd_priv_t* vcd, int track) | |
36 { | |
37 unsigned sect; | |
38 if (track < vcd->toc.FirstTrack || track > vcd->toc.LastTrack) | |
39 return -1; | |
40 sect = vcd_get_msf(vcd, track); | |
41 vcd_set_msf(vcd, sect); | |
42 return VCD_SECTOR_DATA * (sect + 2); | |
43 } | |
44 | |
45 int vcd_get_track_end(mp_vcd_priv_t* vcd, int track) | |
46 { | |
47 if (track < vcd->toc.FirstTrack || track > vcd->toc.LastTrack) | |
48 return -1; | |
49 return VCD_SECTOR_DATA * (vcd_get_msf(vcd, track + 1)); | |
50 } | |
51 | |
52 mp_vcd_priv_t* vcd_read_toc(int fd) | |
53 { | |
54 DWORD dwBytesReturned; | |
55 HANDLE hd; | |
56 int i, min = 0, sec = 0, frame = 0; | |
57 mp_vcd_priv_t* vcd = malloc(sizeof(mp_vcd_priv_t)); | |
58 if (!vcd) | |
59 return NULL; | |
60 | |
61 hd = (HANDLE)_get_osfhandle(fd); | |
62 if (!DeviceIoControl(hd, IOCTL_CDROM_READ_TOC, NULL, 0, &vcd->toc, | |
63 sizeof(CDROM_TOC), &dwBytesReturned, NULL)) { | |
25159 | 64 mp_msg(MSGT_OPEN, MSGL_ERR, "read CDROM toc header: %lu\n", |
22508 | 65 GetLastError()); |
66 free(vcd); | |
67 return NULL; | |
68 } | |
69 | |
70 mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VCD_START_TRACK=%d\n", | |
71 vcd->toc.FirstTrack); | |
72 mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VCD_END_TRACK=%d\n", | |
73 vcd->toc.LastTrack); | |
74 | |
75 for (i = vcd->toc.FirstTrack; i <= vcd->toc.LastTrack + 1; i++) { | |
76 int index = i - vcd->toc.FirstTrack; | |
77 if (i <= vcd->toc.LastTrack) { | |
78 mp_msg(MSGT_OPEN, MSGL_INFO, "track %02d: adr=%d ctrl=%d" | |
79 " %02d:%02d:%02d\n", | |
80 vcd->toc.TrackData[index].TrackNumber, | |
81 vcd->toc.TrackData[index].Adr, | |
82 vcd->toc.TrackData[index].Control, | |
83 vcd->toc.TrackData[index].Address[1], | |
84 vcd->toc.TrackData[index].Address[2], | |
85 vcd->toc.TrackData[index].Address[3]); | |
86 } | |
87 | |
88 if (mp_msg_test(MSGT_IDENTIFY, MSGL_INFO)) { | |
89 if (i > vcd->toc.FirstTrack) { | |
90 min = vcd->toc.TrackData[index].Address[1] - min; | |
25158 | 91 sec = vcd->toc.TrackData[index].Address[2] - sec; |
92 frame = vcd->toc.TrackData[index].Address[3] - frame; | |
22508 | 93 if (frame < 0) { |
94 frame += 75; | |
95 sec--; | |
96 } | |
97 if (sec < 0) { | |
98 sec += 60; | |
99 min--; | |
100 } | |
101 mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VCD_TRACK_%d_MSF=" | |
102 "%02d:%02d:%02d\n", i - 1, min, sec, frame); | |
103 min = vcd->toc.TrackData[index].Address[1]; | |
104 sec = vcd->toc.TrackData[index].Address[2]; | |
105 frame = vcd->toc.TrackData[index].Address[3]; | |
106 } | |
107 } | |
108 } | |
109 | |
110 vcd->hd = hd; | |
111 return vcd; | |
112 } | |
113 | |
114 static int vcd_read(mp_vcd_priv_t* vcd, char *mem) | |
115 { | |
116 DWORD dwBytesReturned; | |
117 RAW_READ_INFO cdrom_raw; | |
118 | |
119 /* 2048 isn't a typo: it's the Windows way. */ | |
120 cdrom_raw.DiskOffset.QuadPart = (long long)(2048 * vcd->sect); | |
121 cdrom_raw.SectorCount = 1; | |
122 cdrom_raw.TrackMode = XAForm2; | |
123 | |
124 if (!DeviceIoControl(vcd->hd, IOCTL_CDROM_RAW_READ, &cdrom_raw, | |
125 sizeof(RAW_READ_INFO), vcd->buf, sizeof(vcd->buf), | |
126 &dwBytesReturned, NULL)) | |
127 return 0; | |
128 | |
129 vcd->sect++; | |
130 memcpy(mem, &vcd->buf[VCD_SECTOR_OFFS], VCD_SECTOR_DATA); | |
131 return VCD_SECTOR_DATA; | |
132 } | |
133 | |
26029 | 134 #endif /* MPLAYER_VCD_READ_WIN32_H */ |
26013 | 135 |
22508 | 136 /* |
137 vim:noet:sw=4:cino=\:0,g0 | |
138 */ |