2 #include <CoreFoundation/CFBase.h>
3 #include <IOKit/IOKitLib.h>
4 #include <IOKit/storage/IOCDTypes.h>
5 #include <IOKit/storage/IOCDMedia.h>
6 #include <IOKit/storage/IOCDMediaBSDClient.h>
9 //=================== VideoCD ==========================
10 #define CDROM_LEADOUT 0xAA
16 uint8_t subheader
[8];
21 typedef struct mp_vcd_priv_st
25 dk_cd_read_track_info_t entry
;
26 struct CDDiscInfo hdr
;
30 static inline void vcd_set_msf(mp_vcd_priv_t
* vcd
, unsigned int sect
)
32 vcd
->msf
= CDConvertLBAToMSF(sect
);
35 static inline unsigned int vcd_get_msf(mp_vcd_priv_t
* vcd
)
37 return CDConvertMSFToLBA(vcd
->msf
);
40 int vcd_seek_to_track(mp_vcd_priv_t
* vcd
, int track
)
42 struct CDTrackInfo entry
;
44 memset( &vcd
->entry
, 0, sizeof(vcd
->entry
));
45 vcd
->entry
.addressType
= kCDTrackInfoAddressTypeTrackNumber
;
46 vcd
->entry
.address
= track
;
47 vcd
->entry
.bufferLength
= sizeof(entry
);
48 vcd
->entry
.buffer
= &entry
;
50 if (ioctl(vcd
->fd
, DKIOCCDREADTRACKINFO
, &vcd
->entry
))
52 mp_msg(MSGT_STREAM
,MSGL_ERR
,"ioctl dif1: %s\n",strerror(errno
));
55 vcd
->msf
= CDConvertLBAToMSF(be2me_32(entry
.trackStartAddress
));
56 return VCD_SECTOR_DATA
*vcd_get_msf(vcd
);
59 int vcd_get_track_end(mp_vcd_priv_t
* vcd
, int track
)
61 struct CDTrackInfo entry
;
63 if (track
> vcd
->hdr
.lastTrackNumberInLastSessionLSB
) {
64 mp_msg(MSGT_OPEN
, MSGL_ERR
,
65 "track number %d greater than last track number %d\n",
66 track
, vcd
->hdr
.lastTrackNumberInLastSessionLSB
);
71 memset( &vcd
->entry
, 0, sizeof(vcd
->entry
));
72 vcd
->entry
.addressType
= kCDTrackInfoAddressTypeTrackNumber
;
73 vcd
->entry
.address
= track
<vcd
->hdr
.lastTrackNumberInLastSessionLSB
?track
+1:vcd
->hdr
.lastTrackNumberInLastSessionLSB
;
74 vcd
->entry
.bufferLength
= sizeof(entry
);
75 vcd
->entry
.buffer
= &entry
;
77 if (ioctl(vcd
->fd
, DKIOCCDREADTRACKINFO
, &vcd
->entry
))
79 mp_msg(MSGT_STREAM
,MSGL_ERR
,"ioctl dif2: %s\n",strerror(errno
));
82 if (track
== vcd
->hdr
.lastTrackNumberInLastSessionLSB
)
83 vcd
->msf
= CDConvertLBAToMSF(be2me_32(entry
.trackStartAddress
) +
84 be2me_32(entry
.trackSize
));
86 vcd
->msf
= CDConvertLBAToMSF(be2me_32(entry
.trackStartAddress
));
87 return VCD_SECTOR_DATA
*vcd_get_msf(vcd
);
90 mp_vcd_priv_t
* vcd_read_toc(int fd
)
92 dk_cd_read_disc_info_t tochdr
;
93 struct CDDiscInfo hdr
;
95 dk_cd_read_track_info_t tocentry
;
96 struct CDTrackInfo entry
;
100 int i
, min
= 0, sec
= 0, frame
= 0;
103 memset(&tochdr
, 0, sizeof(tochdr
));
104 tochdr
.buffer
= &hdr
;
105 tochdr
.bufferLength
= sizeof(hdr
);
107 if (ioctl(fd
, DKIOCCDREADDISCINFO
, &tochdr
) < 0)
109 mp_msg(MSGT_OPEN
,MSGL_ERR
,"read CDROM toc header: %s\n",strerror(errno
));
113 //print all track info
114 mp_msg(MSGT_IDENTIFY
, MSGL_INFO
, "ID_VCD_START_TRACK=%d\n", hdr
.firstTrackNumberInLastSessionLSB
);
115 mp_msg(MSGT_IDENTIFY
, MSGL_INFO
, "ID_VCD_END_TRACK=%d\n", hdr
.lastTrackNumberInLastSessionLSB
);
116 for (i
=hdr
.firstTrackNumberInLastSessionLSB
; i
<=hdr
.lastTrackNumberInLastSessionLSB
+ 1; i
++)
118 if (i
<= hdr
.lastTrackNumberInLastSessionLSB
) {
119 memset( &tocentry
, 0, sizeof(tocentry
));
120 tocentry
.addressType
= kCDTrackInfoAddressTypeTrackNumber
;
121 tocentry
.address
= i
;
122 tocentry
.bufferLength
= sizeof(entry
);
123 tocentry
.buffer
= &entry
;
125 if (ioctl(fd
,DKIOCCDREADTRACKINFO
,&tocentry
)==-1)
127 mp_msg(MSGT_OPEN
,MSGL_ERR
,"read CDROM toc entry: %s\n",strerror(errno
));
131 trackMSF
= CDConvertLBAToMSF(be2me_32(entry
.trackStartAddress
));
134 trackMSF
= CDConvertLBAToMSF(be2me_32(entry
.trackStartAddress
)
135 + be2me_32(entry
.trackSize
));
137 //mp_msg(MSGT_OPEN,MSGL_INFO,"track %02d: adr=%d ctrl=%d format=%d %02d:%02d:%02d\n",
138 if (i
<=hdr
.lastTrackNumberInLastSessionLSB
)
139 mp_msg(MSGT_OPEN
,MSGL_INFO
,"track %02d: format=%d %02d:%02d:%02d\n",
140 (int)tocentry
.address
,
141 //(int)tocentry.entry.addr_type,
142 //(int)tocentry.entry.control,
143 (int)tocentry
.addressType
,
144 (int)trackMSF
.minute
,
145 (int)trackMSF
.second
,
149 if (mp_msg_test(MSGT_IDENTIFY
, MSGL_INFO
))
151 if (i
> hdr
.firstTrackNumberInLastSessionLSB
)
153 min
= trackMSF
.minute
- min
;
154 sec
= trackMSF
.second
- sec
;
155 frame
= trackMSF
.frame
- frame
;
166 mp_msg(MSGT_IDENTIFY
, MSGL_INFO
, "ID_VCD_TRACK_%d_MSF=%02d:%02d:%02d\n", i
- 1, min
, sec
, frame
);
168 min
= trackMSF
.minute
;
169 sec
= trackMSF
.second
;
170 frame
= trackMSF
.frame
;
174 vcd
= malloc(sizeof(mp_vcd_priv_t
));
181 static int vcd_read(mp_vcd_priv_t
* vcd
,char *mem
)
183 if (pread(vcd
->fd
,&vcd
->buf
,VCD_SECTOR_SIZE
,vcd_get_msf(vcd
)*VCD_SECTOR_SIZE
) != VCD_SECTOR_SIZE
)
187 if (vcd
->msf
.frame
==75)
192 if (vcd
->msf
.second
==60)
199 memcpy(mem
,vcd
->buf
.data
,VCD_SECTOR_DATA
);
200 return VCD_SECTOR_DATA
;