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