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_DARWIN_H
20 #define MPLAYER_VCD_READ_DARWIN_H
22 #define _XOPEN_SOURCE 500
27 #include <sys/types.h>
30 #include <CoreFoundation/CFBase.h>
31 #include <IOKit/IOKitLib.h>
32 #include <IOKit/storage/IOCDTypes.h>
33 #include <IOKit/storage/IOCDMedia.h>
34 #include <IOKit/storage/IOCDMediaBSDClient.h>
39 //=================== VideoCD ==========================
40 #define CDROM_LEADOUT 0xAA
46 uint8_t subheader
[8];
51 typedef struct mp_vcd_priv_st
55 dk_cd_read_track_info_t entry
;
56 struct CDDiscInfo hdr
;
60 static inline void vcd_set_msf(mp_vcd_priv_t
* vcd
, unsigned int sect
)
62 vcd
->msf
= CDConvertLBAToMSF(sect
);
65 static inline unsigned int vcd_get_msf(mp_vcd_priv_t
* vcd
)
67 return CDConvertMSFToLBA(vcd
->msf
);
70 static int vcd_seek_to_track(mp_vcd_priv_t
* vcd
, int track
)
72 struct CDTrackInfo entry
;
74 memset( &vcd
->entry
, 0, sizeof(vcd
->entry
));
75 vcd
->entry
.addressType
= kCDTrackInfoAddressTypeTrackNumber
;
76 vcd
->entry
.address
= track
;
77 vcd
->entry
.bufferLength
= sizeof(entry
);
78 vcd
->entry
.buffer
= &entry
;
80 if (ioctl(vcd
->fd
, DKIOCCDREADTRACKINFO
, &vcd
->entry
))
82 mp_msg(MSGT_STREAM
,MSGL_ERR
,"ioctl dif1: %s\n",strerror(errno
));
85 vcd
->msf
= CDConvertLBAToMSF(be2me_32(entry
.trackStartAddress
));
86 return VCD_SECTOR_DATA
*vcd_get_msf(vcd
);
89 static int vcd_get_track_end(mp_vcd_priv_t
* vcd
, int track
)
91 struct CDTrackInfo entry
;
93 if (track
> vcd
->hdr
.lastTrackNumberInLastSessionLSB
) {
94 mp_msg(MSGT_OPEN
, MSGL_ERR
,
95 "track number %d greater than last track number %d\n",
96 track
, vcd
->hdr
.lastTrackNumberInLastSessionLSB
);
101 memset( &vcd
->entry
, 0, sizeof(vcd
->entry
));
102 vcd
->entry
.addressType
= kCDTrackInfoAddressTypeTrackNumber
;
103 vcd
->entry
.address
= track
<vcd
->hdr
.lastTrackNumberInLastSessionLSB
?track
+1:vcd
->hdr
.lastTrackNumberInLastSessionLSB
;
104 vcd
->entry
.bufferLength
= sizeof(entry
);
105 vcd
->entry
.buffer
= &entry
;
107 if (ioctl(vcd
->fd
, DKIOCCDREADTRACKINFO
, &vcd
->entry
))
109 mp_msg(MSGT_STREAM
,MSGL_ERR
,"ioctl dif2: %s\n",strerror(errno
));
112 if (track
== vcd
->hdr
.lastTrackNumberInLastSessionLSB
)
113 vcd
->msf
= CDConvertLBAToMSF(be2me_32(entry
.trackStartAddress
) +
114 be2me_32(entry
.trackSize
));
116 vcd
->msf
= CDConvertLBAToMSF(be2me_32(entry
.trackStartAddress
));
117 return VCD_SECTOR_DATA
*vcd_get_msf(vcd
);
120 static mp_vcd_priv_t
* vcd_read_toc(int fd
)
122 dk_cd_read_disc_info_t tochdr
;
123 struct CDDiscInfo hdr
;
125 dk_cd_read_track_info_t tocentry
;
126 struct CDTrackInfo entry
;
130 int i
, min
= 0, sec
= 0, frame
= 0;
133 memset(&tochdr
, 0, sizeof(tochdr
));
134 tochdr
.buffer
= &hdr
;
135 tochdr
.bufferLength
= sizeof(hdr
);
137 if (ioctl(fd
, DKIOCCDREADDISCINFO
, &tochdr
) < 0)
139 mp_msg(MSGT_OPEN
,MSGL_ERR
,"read CDROM toc header: %s\n",strerror(errno
));
143 //print all track info
144 mp_msg(MSGT_IDENTIFY
, MSGL_INFO
, "ID_VCD_START_TRACK=%d\n", hdr
.firstTrackNumberInLastSessionLSB
);
145 mp_msg(MSGT_IDENTIFY
, MSGL_INFO
, "ID_VCD_END_TRACK=%d\n", hdr
.lastTrackNumberInLastSessionLSB
);
146 for (i
=hdr
.firstTrackNumberInLastSessionLSB
; i
<=hdr
.lastTrackNumberInLastSessionLSB
+ 1; i
++)
148 if (i
<= hdr
.lastTrackNumberInLastSessionLSB
) {
149 memset( &tocentry
, 0, sizeof(tocentry
));
150 tocentry
.addressType
= kCDTrackInfoAddressTypeTrackNumber
;
151 tocentry
.address
= i
;
152 tocentry
.bufferLength
= sizeof(entry
);
153 tocentry
.buffer
= &entry
;
155 if (ioctl(fd
,DKIOCCDREADTRACKINFO
,&tocentry
)==-1)
157 mp_msg(MSGT_OPEN
,MSGL_ERR
,"read CDROM toc entry: %s\n",strerror(errno
));
161 trackMSF
= CDConvertLBAToMSF(be2me_32(entry
.trackStartAddress
));
164 trackMSF
= CDConvertLBAToMSF(be2me_32(entry
.trackStartAddress
)
165 + be2me_32(entry
.trackSize
));
167 //mp_msg(MSGT_OPEN,MSGL_INFO,"track %02d: adr=%d ctrl=%d format=%d %02d:%02d:%02d\n",
168 if (i
<=hdr
.lastTrackNumberInLastSessionLSB
)
169 mp_msg(MSGT_OPEN
,MSGL_INFO
,"track %02d: format=%d %02d:%02d:%02d\n",
170 (int)tocentry
.address
,
171 //(int)tocentry.entry.addr_type,
172 //(int)tocentry.entry.control,
173 (int)tocentry
.addressType
,
174 (int)trackMSF
.minute
,
175 (int)trackMSF
.second
,
179 if (mp_msg_test(MSGT_IDENTIFY
, MSGL_INFO
))
181 if (i
> hdr
.firstTrackNumberInLastSessionLSB
)
183 min
= trackMSF
.minute
- min
;
184 sec
= trackMSF
.second
- sec
;
185 frame
= trackMSF
.frame
- frame
;
196 mp_msg(MSGT_IDENTIFY
, MSGL_INFO
, "ID_VCD_TRACK_%d_MSF=%02d:%02d:%02d\n", i
- 1, min
, sec
, frame
);
198 min
= trackMSF
.minute
;
199 sec
= trackMSF
.second
;
200 frame
= trackMSF
.frame
;
204 vcd
= malloc(sizeof(mp_vcd_priv_t
));
211 static int vcd_end_track(mp_vcd_priv_t
* vcd
)
213 return vcd
->hdr
.lastTrackNumberInLastSessionLSB
;
216 static int vcd_read(mp_vcd_priv_t
* vcd
,char *mem
)
218 if (pread(vcd
->fd
,&vcd
->buf
,VCD_SECTOR_SIZE
,vcd_get_msf(vcd
)*VCD_SECTOR_SIZE
) != VCD_SECTOR_SIZE
)
222 if (vcd
->msf
.frame
==75)
227 if (vcd
->msf
.second
==60)
234 memcpy(mem
,vcd
->buf
.data
,VCD_SECTOR_DATA
);
235 return VCD_SECTOR_DATA
;
238 #endif /* MPLAYER_VCD_READ_DARWIN_H */