13842
|
1 #include <sys/types.h>
|
|
2 #include <CoreFoundation/CFBase.h>
|
|
3 #include <IOKit/IOKitLib.h>
|
|
4 #include <IOKit/storage/IOCDTypes.h>
|
|
5 #include <IOKit/storage/IOCDMedia.h>
|
13682
|
6 #include <IOKit/storage/IOCDMediaBSDClient.h>
|
|
7
|
|
8 //=================== VideoCD ==========================
|
|
9 #define CDROM_LEADOUT 0xAA
|
|
10
|
|
11 typedef struct
|
|
12 {
|
|
13 uint8_t sync [12];
|
|
14 uint8_t header [4];
|
|
15 uint8_t subheader [8];
|
|
16 uint8_t data [2324];
|
|
17 uint8_t spare [4];
|
|
18 } cdsector_t;
|
|
19
|
|
20 typedef struct mp_vcd_priv_st
|
|
21 {
|
|
22 int fd;
|
|
23 dk_cd_read_track_info_t entry;
|
|
24 CDMSF msf;
|
|
25 cdsector_t buf;
|
|
26 } mp_vcd_priv_t;
|
|
27
|
|
28 static inline void vcd_set_msf(mp_vcd_priv_t* vcd, unsigned int sect)
|
|
29 {
|
|
30 vcd->msf.frame=sect%75;
|
|
31 sect=sect/75;
|
|
32 vcd->msf.second=sect%60;
|
|
33 sect=sect/60;
|
|
34 vcd->msf.minute=sect;
|
|
35 }
|
|
36
|
|
37 static inline unsigned int vcd_get_msf(mp_vcd_priv_t* vcd)
|
|
38 {
|
|
39 return vcd->msf.frame +
|
|
40 (vcd->msf.second+
|
|
41 vcd->msf.minute*60)*75;
|
|
42
|
|
43 return 0;
|
|
44 }
|
|
45
|
|
46 int vcd_seek_to_track(mp_vcd_priv_t* vcd, int track)
|
|
47 {
|
|
48 dk_cd_read_track_info_t tocentry;
|
|
49 struct CDTrackInfo entry;
|
|
50
|
|
51 memset( &vcd->entry, 0, sizeof(vcd->entry));
|
|
52 vcd->entry.addressType = kCDTrackInfoAddressTypeTrackNumber;
|
|
53 vcd->entry.address = track;
|
|
54 vcd->entry.bufferLength = sizeof(entry);
|
|
55 vcd->entry.buffer = &entry;
|
|
56
|
|
57 if (ioctl(vcd->fd, DKIOCCDREADTRACKINFO, &vcd->entry))
|
|
58 {
|
|
59 mp_msg(MSGT_STREAM,MSGL_ERR,"ioctl dif1: %s\n",strerror(errno));
|
|
60 return -1;
|
|
61 }
|
|
62 return VCD_SECTOR_DATA*vcd_get_msf(vcd);
|
|
63
|
|
64 return -1;
|
|
65 }
|
|
66
|
|
67 int vcd_get_track_end(mp_vcd_priv_t* vcd, int track)
|
|
68 {
|
|
69 dk_cd_read_disc_info_t tochdr;
|
|
70 struct CDDiscInfo hdr;
|
|
71
|
|
72 dk_cd_read_track_info_t tocentry;
|
|
73 struct CDTrackInfo entry;
|
|
74
|
|
75 //read toc header
|
|
76 memset(&tochdr, 0, sizeof(tochdr));
|
|
77 tochdr.buffer = &hdr;
|
|
78 tochdr.bufferLength = sizeof(hdr);
|
|
79
|
|
80 if (ioctl(vcd->fd, DKIOCCDREADDISCINFO, &tochdr) < 0)
|
|
81 {
|
|
82 mp_msg(MSGT_OPEN,MSGL_ERR,"read CDROM toc header: %s\n",strerror(errno));
|
|
83 return NULL;
|
|
84 }
|
|
85
|
|
86 //read track info
|
|
87 memset( &vcd->entry, 0, sizeof(vcd->entry));
|
|
88 vcd->entry.addressType = kCDTrackInfoAddressTypeTrackNumber;
|
|
89 vcd->entry.address = track<(hdr.lastTrackNumberInLastSessionLSB+1)?(track):CDROM_LEADOUT;
|
|
90 vcd->entry.bufferLength = sizeof(entry);
|
|
91 vcd->entry.buffer = &entry;
|
|
92
|
|
93 if (ioctl(vcd->fd, DKIOCCDREADTRACKINFO, &vcd->entry))
|
|
94 {
|
|
95 mp_msg(MSGT_STREAM,MSGL_ERR,"ioctl dif2: %s\n",strerror(errno));
|
|
96 return -1;
|
|
97 }
|
|
98 return VCD_SECTOR_DATA*vcd_get_msf(vcd);
|
|
99
|
|
100 return -1;
|
|
101 }
|
|
102
|
|
103 mp_vcd_priv_t* vcd_read_toc(int fd)
|
|
104 {
|
|
105 dk_cd_read_disc_info_t tochdr;
|
|
106 struct CDDiscInfo hdr;
|
|
107
|
|
108 dk_cd_read_track_info_t tocentry;
|
|
109 struct CDTrackInfo entry;
|
|
110 CDMSF trackMSF;
|
|
111
|
|
112 mp_vcd_priv_t* vcd;
|
|
113 int i;
|
|
114
|
|
115 //read toc header
|
|
116 memset(&tochdr, 0, sizeof(tochdr));
|
|
117 tochdr.buffer = &hdr;
|
|
118 tochdr.bufferLength = sizeof(hdr);
|
|
119
|
|
120 if (ioctl(fd, DKIOCCDREADDISCINFO, &tochdr) < 0)
|
|
121 {
|
|
122 mp_msg(MSGT_OPEN,MSGL_ERR,"read CDROM toc header: %s\n",strerror(errno));
|
|
123 return NULL;
|
|
124 }
|
|
125
|
|
126 //print all track info
|
|
127 for (i=hdr.firstTrackNumberInLastSessionLSB ; i<=hdr.lastTrackNumberInLastSessionLSB ; i++)
|
|
128 {
|
|
129 memset( &tocentry, 0, sizeof(tocentry));
|
|
130 tocentry.addressType = kCDTrackInfoAddressTypeTrackNumber;
|
|
131 tocentry.address = i;
|
|
132 tocentry.bufferLength = sizeof(entry);
|
|
133 tocentry.buffer = &entry;
|
|
134
|
|
135 if (ioctl(fd,DKIOCCDREADTRACKINFO,&tocentry)==-1)
|
|
136 {
|
|
137 mp_msg(MSGT_OPEN,MSGL_ERR,"read CDROM toc entry: %s\n",strerror(errno));
|
|
138 return NULL;
|
|
139 }
|
|
140
|
|
141 trackMSF = CDConvertLBAToMSF(entry.trackStartAddress);
|
|
142
|
|
143 //mp_msg(MSGT_OPEN,MSGL_INFO,"track %02d: adr=%d ctrl=%d format=%d %02d:%02d:%02d\n",
|
|
144 mp_msg(MSGT_OPEN,MSGL_INFO,"track %02d: format=%d %02d:%02d:%02d\n",
|
|
145 (int)tocentry.address,
|
|
146 //(int)tocentry.entry.addr_type,
|
|
147 //(int)tocentry.entry.control,
|
|
148 (int)tocentry.addressType,
|
|
149 (int)trackMSF.minute,
|
|
150 (int)trackMSF.second,
|
|
151 (int)trackMSF.frame
|
|
152 );
|
|
153 }
|
|
154
|
|
155 vcd = malloc(sizeof(mp_vcd_priv_t));
|
|
156 vcd->fd = fd;
|
|
157 vcd->msf = trackMSF;
|
|
158 return vcd;
|
|
159
|
|
160 return NULL;
|
|
161 }
|
|
162
|
|
163 static int vcd_read(mp_vcd_priv_t* vcd,char *mem)
|
|
164 {
|
|
165 if (pread(vcd->fd,&vcd->buf,VCD_SECTOR_SIZE,vcd_get_msf(vcd)*VCD_SECTOR_SIZE) != VCD_SECTOR_SIZE)
|
|
166 return 0; // EOF?
|
|
167
|
|
168 vcd->msf.frame++;
|
|
169 if (vcd->msf.frame==75)
|
|
170 {
|
|
171 vcd->msf.frame=0;
|
|
172 vcd->msf.second++;
|
|
173
|
|
174 if (vcd->msf.second==60)
|
|
175 {
|
|
176 vcd->msf.second=0;
|
|
177 vcd->msf.minute++;
|
|
178 }
|
|
179 }
|
|
180
|
|
181 memcpy(mem,vcd->buf.data,VCD_SECTOR_DATA);
|
|
182 return VCD_SECTOR_DATA;
|
|
183 return 0;
|
|
184 }
|
|
185
|