Mercurial > mplayer.hg
annotate libmpdemux/vcd_read_nbsd.h @ 18077:cede662f40a5
timestamps are 33 bits long, so they don't fit in an unsigned int; 10l
author | nicodvb |
---|---|
date | Tue, 11 Apr 2006 20:05:24 +0000 |
parents | aa15d627a00b |
children | 4231482179b6 |
rev | line source |
---|---|
5872 | 1 |
2 #include <sys/types.h> | |
12797
b2419eef04da
OpenBSD portability patches from the OpenBSD ports tree
diego
parents:
9887
diff
changeset
|
3 #ifdef __NetBSD__ |
5872 | 4 #include <sys/inttypes.h> |
12797
b2419eef04da
OpenBSD portability patches from the OpenBSD ports tree
diego
parents:
9887
diff
changeset
|
5 #endif |
5872 | 6 #include <sys/cdio.h> |
7 #include <sys/scsiio.h> | |
8 | |
9 #define CDROM_LEADOUT 0xAA | |
10 | |
9887 | 11 typedef struct mp_vcd_priv_st { |
12 int fd; | |
13 struct ioc_read_toc_entry entry; | |
14 struct cd_toc_entry entry_data; | |
15 } mp_vcd_priv_t; | |
5872 | 16 |
17 static inline void | |
9887 | 18 vcd_set_msf(mp_vcd_priv_t* vcd, unsigned int sect) |
5872 | 19 { |
9887 | 20 vcd->entry_data.addr.msf.frame = sect % 75; |
5872 | 21 sect = sect / 75; |
9887 | 22 vcd->entry_data.addr.msf.second = sect % 60; |
5872 | 23 sect = sect / 60; |
9887 | 24 vcd->entry_data.addr.msf.minute = sect; |
5872 | 25 } |
26 | |
8532
9688aa033083
fix VCD playback - this is a patch from the netbsd pkgsrc tree,
arpi
parents:
7406
diff
changeset
|
27 static inline void |
9887 | 28 vcd_inc_msf(mp_vcd_priv_t* vcd) |
8532
9688aa033083
fix VCD playback - this is a patch from the netbsd pkgsrc tree,
arpi
parents:
7406
diff
changeset
|
29 { |
9887 | 30 vcd->entry_data.addr.msf.frame++; |
31 if (vcd->entry_data.addr.msf.frame==75){ | |
32 vcd->entry_data.addr.msf.frame=0; | |
33 vcd->entry_data.addr.msf.second++; | |
34 if (vcd->entry_data.addr.msf.second==60){ | |
35 vcd->entry_data.addr.msf.second=0; | |
36 vcd->entry_data.addr.msf.minute++; | |
8532
9688aa033083
fix VCD playback - this is a patch from the netbsd pkgsrc tree,
arpi
parents:
7406
diff
changeset
|
37 } |
9688aa033083
fix VCD playback - this is a patch from the netbsd pkgsrc tree,
arpi
parents:
7406
diff
changeset
|
38 } |
9688aa033083
fix VCD playback - this is a patch from the netbsd pkgsrc tree,
arpi
parents:
7406
diff
changeset
|
39 } |
9688aa033083
fix VCD playback - this is a patch from the netbsd pkgsrc tree,
arpi
parents:
7406
diff
changeset
|
40 |
5872 | 41 static inline unsigned int |
9887 | 42 vcd_get_msf(mp_vcd_priv_t* vcd) |
5872 | 43 { |
9887 | 44 return vcd->entry_data.addr.msf.frame + |
45 (vcd->entry_data.addr.msf.second + | |
46 vcd->entry_data.addr.msf.minute * 60) * 75; | |
5872 | 47 } |
48 | |
49 int | |
9887 | 50 vcd_seek_to_track(mp_vcd_priv_t* vcd, int track) |
5872 | 51 { |
9887 | 52 vcd->entry.address_format = CD_MSF_FORMAT; |
53 vcd->entry.starting_track = track; | |
54 vcd->entry.data_len = sizeof(struct cd_toc_entry); | |
55 vcd->entry.data = &vcd->entry_data; | |
56 if (ioctl(vcd->fd, CDIOREADTOCENTRIES, &vcd->entry)) { | |
57 mp_msg(MSGT_STREAM,MSGL_ERR,"ioctl dif1: %s\n",strerror(errno)); | |
5872 | 58 return -1; |
59 } | |
9887 | 60 return VCD_SECTOR_DATA * vcd_get_msf(vcd); |
5872 | 61 } |
62 | |
63 int | |
9887 | 64 vcd_get_track_end(mp_vcd_priv_t* vcd, int track) |
5872 | 65 { |
66 struct ioc_toc_header tochdr; | |
9887 | 67 if (ioctl(vcd->fd, CDIOREADTOCHEADER, &tochdr) == -1) { |
68 mp_msg(MSGT_STREAM,MSGL_ERR,"read CDROM toc header: %s\n",strerror(errno)); | |
5872 | 69 return -1; |
70 } | |
9887 | 71 vcd->entry.address_format = CD_MSF_FORMAT; |
72 vcd->entry.starting_track = track < tochdr.ending_track ? (track + 1) : CDROM_LEADOUT; | |
73 vcd->entry.data_len = sizeof(struct cd_toc_entry); | |
74 vcd->entry.data = &vcd->entry_data; | |
75 if (ioctl(vcd->fd, CDIOREADTOCENTRYS, &vcd->entry)) { | |
76 mp_msg(MSGT_STREAM,MSGL_ERR,"ioctl dif2: %s\n",strerror(errno)); | |
5872 | 77 return -1; |
78 } | |
9887 | 79 return VCD_SECTOR_DATA * vcd_get_msf(vcd); |
5872 | 80 } |
81 | |
9887 | 82 mp_vcd_priv_t* |
5872 | 83 vcd_read_toc(int fd) |
84 { | |
85 struct ioc_toc_header tochdr; | |
9887 | 86 mp_vcd_priv_t* vcd; |
16547
aa15d627a00b
Prints the numbers of start and end tracks and MSF length for each
gpoirier
parents:
12797
diff
changeset
|
87 int i, min = 0, sec = 0, frame = 0; |
5872 | 88 if (ioctl(fd, CDIOREADTOCHEADER, &tochdr) == -1) { |
9887 | 89 mp_msg(MSGT_OPEN,MSGL_ERR,"read CDROM toc header: %s\n",strerror(errno)); |
5872 | 90 return; |
91 } | |
16547
aa15d627a00b
Prints the numbers of start and end tracks and MSF length for each
gpoirier
parents:
12797
diff
changeset
|
92 if (identify) |
aa15d627a00b
Prints the numbers of start and end tracks and MSF length for each
gpoirier
parents:
12797
diff
changeset
|
93 { |
aa15d627a00b
Prints the numbers of start and end tracks and MSF length for each
gpoirier
parents:
12797
diff
changeset
|
94 mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_VCD_START_TRACK=%d\n", tochdr.starting_track); |
aa15d627a00b
Prints the numbers of start and end tracks and MSF length for each
gpoirier
parents:
12797
diff
changeset
|
95 mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_VCD_END_TRACK=%d\n", tochdr.ending_track); |
aa15d627a00b
Prints the numbers of start and end tracks and MSF length for each
gpoirier
parents:
12797
diff
changeset
|
96 } |
aa15d627a00b
Prints the numbers of start and end tracks and MSF length for each
gpoirier
parents:
12797
diff
changeset
|
97 for (i = tochdr.starting_track; i <= tochdr.ending_track + 1; i++) { |
5872 | 98 struct ioc_read_toc_entry tocentry; |
99 struct cd_toc_entry tocentry_data; | |
100 | |
16547
aa15d627a00b
Prints the numbers of start and end tracks and MSF length for each
gpoirier
parents:
12797
diff
changeset
|
101 tocentry.starting_track = i<=tochdr.ending_track ? i : CDROM_LEADOUT; |
5872 | 102 tocentry.address_format = CD_MSF_FORMAT; |
103 tocentry.data_len = sizeof(struct cd_toc_entry); | |
104 tocentry.data = &tocentry_data; | |
105 | |
106 if (ioctl(fd, CDIOREADTOCENTRYS, &tocentry) == -1) { | |
9887 | 107 mp_msg(MSGT_OPEN,MSGL_ERR,"read CDROM toc entry: %s\n",strerror(errno)); |
108 return NULL; | |
5872 | 109 } |
16547
aa15d627a00b
Prints the numbers of start and end tracks and MSF length for each
gpoirier
parents:
12797
diff
changeset
|
110 if (i <= tochdr.ending_track) |
9887 | 111 mp_msg(MSGT_OPEN,MSGL_INFO,"track %02d: adr=%d ctrl=%d format=%d %02d:%02d:%02d\n", |
5872 | 112 (int) tocentry.starting_track, |
113 (int) tocentry.data->addr_type, | |
114 (int) tocentry.data->control, | |
115 (int) tocentry.address_format, | |
116 (int) tocentry.data->addr.msf.minute, | |
117 (int) tocentry.data->addr.msf.second, | |
118 (int) tocentry.data->addr.msf.frame | |
119 ); | |
16547
aa15d627a00b
Prints the numbers of start and end tracks and MSF length for each
gpoirier
parents:
12797
diff
changeset
|
120 |
aa15d627a00b
Prints the numbers of start and end tracks and MSF length for each
gpoirier
parents:
12797
diff
changeset
|
121 if (identify) |
aa15d627a00b
Prints the numbers of start and end tracks and MSF length for each
gpoirier
parents:
12797
diff
changeset
|
122 { |
aa15d627a00b
Prints the numbers of start and end tracks and MSF length for each
gpoirier
parents:
12797
diff
changeset
|
123 if (i > tochdr.starting_track) |
aa15d627a00b
Prints the numbers of start and end tracks and MSF length for each
gpoirier
parents:
12797
diff
changeset
|
124 { |
aa15d627a00b
Prints the numbers of start and end tracks and MSF length for each
gpoirier
parents:
12797
diff
changeset
|
125 min = tocentry.data->addr.msf.minute - min; |
aa15d627a00b
Prints the numbers of start and end tracks and MSF length for each
gpoirier
parents:
12797
diff
changeset
|
126 sec = tocentry.data->addr.msf.second - sec; |
aa15d627a00b
Prints the numbers of start and end tracks and MSF length for each
gpoirier
parents:
12797
diff
changeset
|
127 frame = tocentry.data->addr.msf.frame - frame; |
aa15d627a00b
Prints the numbers of start and end tracks and MSF length for each
gpoirier
parents:
12797
diff
changeset
|
128 if ( frame < 0 ) |
aa15d627a00b
Prints the numbers of start and end tracks and MSF length for each
gpoirier
parents:
12797
diff
changeset
|
129 { |
aa15d627a00b
Prints the numbers of start and end tracks and MSF length for each
gpoirier
parents:
12797
diff
changeset
|
130 frame += 75; |
aa15d627a00b
Prints the numbers of start and end tracks and MSF length for each
gpoirier
parents:
12797
diff
changeset
|
131 sec --; |
aa15d627a00b
Prints the numbers of start and end tracks and MSF length for each
gpoirier
parents:
12797
diff
changeset
|
132 } |
aa15d627a00b
Prints the numbers of start and end tracks and MSF length for each
gpoirier
parents:
12797
diff
changeset
|
133 if ( sec < 0 ) |
aa15d627a00b
Prints the numbers of start and end tracks and MSF length for each
gpoirier
parents:
12797
diff
changeset
|
134 { |
aa15d627a00b
Prints the numbers of start and end tracks and MSF length for each
gpoirier
parents:
12797
diff
changeset
|
135 sec += 60; |
aa15d627a00b
Prints the numbers of start and end tracks and MSF length for each
gpoirier
parents:
12797
diff
changeset
|
136 min --; |
aa15d627a00b
Prints the numbers of start and end tracks and MSF length for each
gpoirier
parents:
12797
diff
changeset
|
137 } |
aa15d627a00b
Prints the numbers of start and end tracks and MSF length for each
gpoirier
parents:
12797
diff
changeset
|
138 mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_VCD_TRACK_%d_MSF=%02d:%02d:%02d\n", i - 1, min, sec, frame); |
aa15d627a00b
Prints the numbers of start and end tracks and MSF length for each
gpoirier
parents:
12797
diff
changeset
|
139 } |
aa15d627a00b
Prints the numbers of start and end tracks and MSF length for each
gpoirier
parents:
12797
diff
changeset
|
140 min = tocentry.data->addr.msf.minute; |
aa15d627a00b
Prints the numbers of start and end tracks and MSF length for each
gpoirier
parents:
12797
diff
changeset
|
141 sec = tocentry.data->addr.msf.second; |
aa15d627a00b
Prints the numbers of start and end tracks and MSF length for each
gpoirier
parents:
12797
diff
changeset
|
142 frame = tocentry.data->addr.msf.frame; |
aa15d627a00b
Prints the numbers of start and end tracks and MSF length for each
gpoirier
parents:
12797
diff
changeset
|
143 } |
5872 | 144 } |
9887 | 145 vcd = malloc(sizeof(mp_vcd_priv_t)); |
146 vcd->fd = fd; | |
147 return vcd; | |
5872 | 148 } |
149 | |
150 static int | |
9887 | 151 vcd_read(mp_vcd_priv_t* vcd, char *mem) |
5872 | 152 { |
153 struct scsireq sc; | |
9887 | 154 int lba = vcd_get_msf(vcd); |
5872 | 155 int blocks; |
156 int sector_type; | |
157 int sync, header_code, user_data, edc_ecc, error_field; | |
158 int sub_channel; | |
159 int rc; | |
160 | |
161 blocks = 1; | |
162 sector_type = 5; /* mode2/form2 */ | |
163 sync = 0; | |
164 header_code = 0; | |
165 user_data = 1; | |
166 edc_ecc = 0; | |
167 error_field = 0; | |
168 sub_channel = 0; | |
169 | |
170 memset(&sc, 0, sizeof(sc)); | |
171 sc.cmd[0] = 0xBE; | |
172 sc.cmd[1] = (sector_type) << 2; | |
173 sc.cmd[2] = (lba >> 24) & 0xff; | |
174 sc.cmd[3] = (lba >> 16) & 0xff; | |
175 sc.cmd[4] = (lba >> 8) & 0xff; | |
176 sc.cmd[5] = lba & 0xff; | |
177 sc.cmd[6] = (blocks >> 16) & 0xff; | |
178 sc.cmd[7] = (blocks >> 8) & 0xff; | |
179 sc.cmd[8] = blocks & 0xff; | |
180 sc.cmd[9] = (sync << 7) | (header_code << 5) | (user_data << 4) | | |
181 (edc_ecc << 3) | (error_field << 1); | |
182 sc.cmd[10] = sub_channel; | |
183 sc.cmdlen = 12; | |
184 sc.databuf = (caddr_t) mem; | |
185 sc.datalen = 2328; | |
186 sc.senselen = sizeof(sc.sense); | |
187 sc.flags = SCCMD_READ; | |
188 sc.timeout = 10000; | |
9887 | 189 rc = ioctl(vcd->fd, SCIOCCOMMAND, &sc); |
5872 | 190 if (rc == -1) { |
9887 | 191 mp_msg(MSGT_STREAM,MSGL_ERR,"SCIOCCOMMAND: %s\n",strerror(errno)); |
5872 | 192 return -1; |
193 } | |
194 if (sc.retsts || sc.error) { | |
9887 | 195 mp_msg(MSGT_STREAM,MSGL_ERR,"scsi command failed: status %d error %d\n", |
196 sc.retsts,sc.error); | |
5872 | 197 return -1; |
198 } | |
9887 | 199 vcd_inc_msf(vcd); |
5872 | 200 return VCD_SECTOR_DATA; |
201 } | |
202 |