4 //=================== VideoCD ==========================
5 #define CDROM_LEADOUT 0xAA
10 uint8_t subheader
[8];
15 typedef struct mp_vcd_priv_st
{
17 struct ioc_read_toc_single_entry entry
;
21 static inline void vcd_set_msf(mp_vcd_priv_t
* vcd
, unsigned int sect
){
22 vcd
->entry
.entry
.addr
.msf
.frame
=sect
%75;
24 vcd
->entry
.entry
.addr
.msf
.second
=sect
%60;
26 vcd
->entry
.entry
.addr
.msf
.minute
=sect
;
29 static inline unsigned int vcd_get_msf(mp_vcd_priv_t
* vcd
){
30 return vcd
->entry
.entry
.addr
.msf
.frame
+
31 (vcd
->entry
.entry
.addr
.msf
.second
+
32 vcd
->entry
.entry
.addr
.msf
.minute
*60)*75;
35 int vcd_seek_to_track(mp_vcd_priv_t
* vcd
, int track
){
36 vcd
->entry
.address_format
= CD_MSF_FORMAT
;
37 vcd
->entry
.track
= track
;
38 if (ioctl(vcd
->fd
, CDIOREADTOCENTRY
, &vcd
->entry
)) {
39 mp_msg(MSGT_STREAM
,MSGL_ERR
,"ioctl dif1: %s\n",strerror(errno
));
42 return VCD_SECTOR_DATA
*vcd_get_msf(vcd
);
45 int vcd_get_track_end(mp_vcd_priv_t
* vcd
, int track
){
46 struct ioc_toc_header tochdr
;
47 if (ioctl(vcd
->fd
,CDIOREADTOCHEADER
,&tochdr
)==-1) {
48 mp_msg(MSGT_STREAM
,MSGL_ERR
,"read CDROM toc header: %s\n",strerror(errno
));
51 vcd
->entry
.address_format
= CD_MSF_FORMAT
;
52 vcd
->entry
.track
= track
<tochdr
.ending_track
?(track
+1):CDROM_LEADOUT
;
53 if (ioctl(vcd
->fd
, CDIOREADTOCENTRY
, &vcd
->entry
)) {
54 mp_msg(MSGT_STREAM
,MSGL_ERR
,"ioctl dif2: %s\n",strerror(errno
));
57 return VCD_SECTOR_DATA
*vcd_get_msf(vcd
);
60 mp_vcd_priv_t
* vcd_read_toc(int fd
){
61 struct ioc_toc_header tochdr
;
64 if (ioctl(fd
,CDIOREADTOCHEADER
,&tochdr
)==-1) {
65 mp_msg(MSGT_OPEN
,MSGL_ERR
,"read CDROM toc header: %s\n",strerror(errno
));
68 for (i
=tochdr
.starting_track
; i
<=tochdr
.ending_track
; i
++){
69 struct ioc_read_toc_single_entry tocentry
;
72 tocentry
.address_format
= CD_MSF_FORMAT
;
74 if (ioctl(fd
,CDIOREADTOCENTRY
,&tocentry
)==-1) {
75 mp_msg(MSGT_OPEN
,MSGL_ERR
,"read CDROM toc entry: %s\n",strerror(errno
));
79 mp_msg(MSGT_OPEN
,MSGL_INFO
,"track %02d: adr=%d ctrl=%d format=%d %02d:%02d:%02d\n",
81 (int)tocentry
.entry
.addr_type
,
82 (int)tocentry
.entry
.control
,
83 (int)tocentry
.address_format
,
84 (int)tocentry
.entry
.addr
.msf
.minute
,
85 (int)tocentry
.entry
.addr
.msf
.second
,
86 (int)tocentry
.entry
.addr
.msf
.frame
89 vcd
= malloc(sizeof(mp_vcd_priv_t
));
94 static int vcd_read(mp_vcd_priv_t
* vcd
,char *mem
){
96 if (pread(vcd
->fd
,&vcd
->buf
,VCD_SECTOR_SIZE
,vcd_get_msf(vcd
)*VCD_SECTOR_SIZE
)
97 != VCD_SECTOR_SIZE
) return 0; // EOF?
99 vcd
->entry
.entry
.addr
.msf
.frame
++;
100 if (vcd
->entry
.entry
.addr
.msf
.frame
==75){
101 vcd
->entry
.entry
.addr
.msf
.frame
=0;
102 vcd
->entry
.entry
.addr
.msf
.second
++;
103 if (vcd
->entry
.entry
.addr
.msf
.second
==60){
104 vcd
->entry
.entry
.addr
.msf
.second
=0;
105 vcd
->entry
.entry
.addr
.msf
.minute
++;
108 memcpy(mem
,vcd
->buf
.data
,VCD_SECTOR_DATA
);
109 return VCD_SECTOR_DATA
;