Mercurial > mplayer.hg
comparison libmpdemux/vcd_read.h @ 2310:9e059416eea6
libdemuxer...
author | arpi |
---|---|
date | Sat, 20 Oct 2001 18:49:08 +0000 |
parents | vcd_read.h@d7920c8257e2 |
children | f51307170f69 |
comparison
equal
deleted
inserted
replaced
2309:3128b9d8b4ea | 2310:9e059416eea6 |
---|---|
1 //=================== VideoCD ========================== | |
2 #if defined(linux) || defined(sun) || defined(__bsdi__) | |
3 | |
4 #if defined(linux) | |
5 #include <linux/cdrom.h> | |
6 #elif defined(sun) | |
7 #include <sys/cdio.h> | |
8 static int sun_vcd_read(int, int*); | |
9 #elif defined(__bsdi__) | |
10 #include <dvd.h> | |
11 #endif | |
12 | |
13 | |
14 static struct cdrom_tocentry vcd_entry; | |
15 | |
16 static inline void vcd_set_msf(unsigned int sect){ | |
17 vcd_entry.cdte_addr.msf.frame=sect%75; | |
18 sect=sect/75; | |
19 vcd_entry.cdte_addr.msf.second=sect%60; | |
20 sect=sect/60; | |
21 vcd_entry.cdte_addr.msf.minute=sect; | |
22 } | |
23 | |
24 static inline unsigned int vcd_get_msf(){ | |
25 return vcd_entry.cdte_addr.msf.frame + | |
26 (vcd_entry.cdte_addr.msf.second+ | |
27 vcd_entry.cdte_addr.msf.minute*60)*75; | |
28 } | |
29 | |
30 int vcd_seek_to_track(int fd,int track){ | |
31 vcd_entry.cdte_format = CDROM_MSF; | |
32 vcd_entry.cdte_track = track; | |
33 if (ioctl(fd, CDROMREADTOCENTRY, &vcd_entry)) { | |
34 perror("ioctl dif1"); | |
35 return -1; | |
36 } | |
37 return VCD_SECTOR_DATA*vcd_get_msf(); | |
38 } | |
39 | |
40 int vcd_get_track_end(int fd,int track){ | |
41 struct cdrom_tochdr tochdr; | |
42 if (ioctl(fd,CDROMREADTOCHDR,&tochdr)==-1) | |
43 { perror("read CDROM toc header: "); return -1; } | |
44 vcd_entry.cdte_format = CDROM_MSF; | |
45 vcd_entry.cdte_track = track<tochdr.cdth_trk1?(track+1):CDROM_LEADOUT; | |
46 if (ioctl(fd, CDROMREADTOCENTRY, &vcd_entry)) { | |
47 perror("ioctl dif2"); | |
48 return -1; | |
49 } | |
50 return VCD_SECTOR_DATA*vcd_get_msf(); | |
51 } | |
52 | |
53 void vcd_read_toc(int fd){ | |
54 struct cdrom_tochdr tochdr; | |
55 int i; | |
56 if (ioctl(fd,CDROMREADTOCHDR,&tochdr)==-1) | |
57 { perror("read CDROM toc header: "); return; } | |
58 for (i=tochdr.cdth_trk0 ; i<=tochdr.cdth_trk1 ; i++){ | |
59 struct cdrom_tocentry tocentry; | |
60 | |
61 tocentry.cdte_track = i; | |
62 tocentry.cdte_format = CDROM_MSF; | |
63 | |
64 if (ioctl(fd,CDROMREADTOCENTRY,&tocentry)==-1) | |
65 { perror("read CDROM toc entry: "); return; } | |
66 | |
67 mp_msg(MSGT_OPEN,MSGL_INFO,"track %02d: adr=%d ctrl=%d format=%d %02d:%02d:%02d mode: %d\n", | |
68 (int)tocentry.cdte_track, | |
69 (int)tocentry.cdte_adr, | |
70 (int)tocentry.cdte_ctrl, | |
71 (int)tocentry.cdte_format, | |
72 (int)tocentry.cdte_addr.msf.minute, | |
73 (int)tocentry.cdte_addr.msf.second, | |
74 (int)tocentry.cdte_addr.msf.frame, | |
75 (int)tocentry.cdte_datamode | |
76 ); | |
77 } | |
78 } | |
79 | |
80 | |
81 static char vcd_buf[VCD_SECTOR_SIZE]; | |
82 | |
83 static int vcd_read(int fd,char *mem){ | |
84 #if defined(linux) || defined(__bsdi__) | |
85 memcpy(vcd_buf,&vcd_entry.cdte_addr.msf,sizeof(struct cdrom_msf)); | |
86 if(ioctl(fd,CDROMREADRAW,vcd_buf)==-1) return 0; // EOF? | |
87 memcpy(mem,&vcd_buf[VCD_SECTOR_OFFS],VCD_SECTOR_DATA); | |
88 #elif defined(sun) | |
89 { | |
90 int offset; | |
91 if (sun_vcd_read(fd, &offset) <= 0) return 0; | |
92 memcpy(mem,&vcd_buf[offset],VCD_SECTOR_DATA); | |
93 } | |
94 #endif | |
95 | |
96 vcd_entry.cdte_addr.msf.frame++; | |
97 if (vcd_entry.cdte_addr.msf.frame==75){ | |
98 vcd_entry.cdte_addr.msf.frame=0; | |
99 vcd_entry.cdte_addr.msf.second++; | |
100 if (vcd_entry.cdte_addr.msf.second==60){ | |
101 vcd_entry.cdte_addr.msf.second=0; | |
102 vcd_entry.cdte_addr.msf.minute++; | |
103 } | |
104 } | |
105 | |
106 return VCD_SECTOR_DATA; | |
107 } | |
108 | |
109 | |
110 #ifdef sun | |
111 #include <sys/scsi/generic/commands.h> | |
112 #include <sys/scsi/impl/uscsi.h> | |
113 | |
114 #define SUN_XAREAD 1 /*fails on atapi drives*/ | |
115 #define SUN_MODE2READ 2 /*fails on atapi drives*/ | |
116 #define SUN_SCSIREAD 3 | |
117 #define SUN_VCDREAD SUN_SCSIREAD | |
118 | |
119 static int sun_vcd_read(int fd, int *offset) | |
120 { | |
121 #if SUN_VCDREAD == SUN_XAREAD | |
122 struct cdrom_cdxa cdxa; | |
123 cdxa.cdxa_addr = vcd_get_msf(); | |
124 cdxa.cdxa_length = 1; | |
125 cdxa.cdxa_data = vcd_buf; | |
126 cdxa.cdxa_format = CDROM_XA_SECTOR_DATA; | |
127 | |
128 if(ioctl(fd,CDROMCDXA,&cdxa)==-1) { | |
129 perror("CDROMCDXA"); | |
130 return 0; | |
131 } | |
132 *offset = 0; | |
133 #elif SUN_VCDREAD == SUN_MODE2READ | |
134 struct cdrom_read cdread; | |
135 cdread.cdread_lba = 4*vcd_get_msf(); | |
136 cdread.cdread_bufaddr = vcd_buf; | |
137 cdread.cdread_buflen = 2336; | |
138 | |
139 if(ioctl(fd,CDROMREADMODE2,&cdread)==-1) { | |
140 perror("CDROMREADMODE2"); | |
141 return 0; | |
142 } | |
143 *offset = 8; | |
144 #elif SUN_VCDREAD == SUN_SCSIREAD | |
145 struct uscsi_cmd sc; | |
146 union scsi_cdb cdb; | |
147 int lba = vcd_get_msf(); | |
148 int blocks = 1; | |
149 int sector_type; | |
150 int sync, header_code, user_data, edc_ecc, error_field; | |
151 int sub_channel; | |
152 | |
153 /* sector_type = 3; *//* mode2 */ | |
154 sector_type = 5; /* mode2/form2 */ | |
155 sync = 0; | |
156 header_code = 0; | |
157 user_data = 1; | |
158 edc_ecc = 0; | |
159 error_field = 0; | |
160 sub_channel = 0; | |
161 | |
162 memset(&cdb, 0, sizeof(cdb)); | |
163 memset(&sc, 0, sizeof(sc)); | |
164 cdb.scc_cmd = 0xBE; | |
165 cdb.cdb_opaque[1] = (sector_type) << 2; | |
166 cdb.cdb_opaque[2] = (lba >> 24) & 0xff; | |
167 cdb.cdb_opaque[3] = (lba >> 16) & 0xff; | |
168 cdb.cdb_opaque[4] = (lba >> 8) & 0xff; | |
169 cdb.cdb_opaque[5] = lba & 0xff; | |
170 cdb.cdb_opaque[6] = (blocks >> 16) & 0xff; | |
171 cdb.cdb_opaque[7] = (blocks >> 8) & 0xff; | |
172 cdb.cdb_opaque[8] = blocks & 0xff; | |
173 cdb.cdb_opaque[9] = (sync << 7) | | |
174 (header_code << 5) | | |
175 (user_data << 4) | | |
176 (edc_ecc << 3) | | |
177 (error_field << 1); | |
178 cdb.cdb_opaque[10] = sub_channel; | |
179 | |
180 sc.uscsi_cdb = (caddr_t)&cdb; | |
181 sc.uscsi_cdblen = 12; | |
182 sc.uscsi_bufaddr = vcd_buf; | |
183 sc.uscsi_buflen = 2336; | |
184 sc.uscsi_flags = USCSI_ISOLATE | USCSI_READ; | |
185 sc.uscsi_timeout = 20; | |
186 if (ioctl(fd, USCSICMD, &sc)) { | |
187 perror("USCSICMD: READ CD"); | |
188 return -1; | |
189 } | |
190 if (sc.uscsi_status) { | |
191 fprintf(stderr, "scsi command failed with status %d\n", sc.uscsi_status); | |
192 return -1; | |
193 } | |
194 *offset = 0; | |
195 return 1; | |
196 #else | |
197 #error SUN_VCDREAD | |
198 #endif | |
199 } | |
200 #endif /*sun*/ | |
201 | |
202 | |
203 //================== VCD CACHE ======================= | |
204 #ifdef VCD_CACHE | |
205 | |
206 static int vcd_cache_size=0; | |
207 static char *vcd_cache_data=NULL; | |
208 static int *vcd_cache_sectors=NULL; | |
209 static int vcd_cache_index=0; // index to first free (or oldest) cache sector | |
210 static int vcd_cache_current=-1; | |
211 | |
212 void vcd_cache_init(int s){ | |
213 vcd_cache_size=s; | |
214 vcd_cache_sectors=malloc(s*sizeof(int)); | |
215 vcd_cache_data=malloc(s*VCD_SECTOR_SIZE); | |
216 memset(vcd_cache_sectors,255,s*sizeof(int)); | |
217 } | |
218 | |
219 static inline void vcd_cache_seek(int sect){ | |
220 vcd_cache_current=sect; | |
221 } | |
222 | |
223 int vcd_cache_read(int fd,char* mem){ | |
224 int i; | |
225 char* vcd_buf; | |
226 | |
227 for(i=0;i<vcd_cache_size;i++) | |
228 if(vcd_cache_sectors[i]==vcd_cache_current){ | |
229 // found in the cache! :) | |
230 vcd_buf=&vcd_cache_data[i*VCD_SECTOR_SIZE]; | |
231 ++vcd_cache_current; | |
232 memcpy(mem,&vcd_buf[VCD_SECTOR_OFFS],VCD_SECTOR_DATA); | |
233 return VCD_SECTOR_DATA; | |
234 } | |
235 // NEW cache entry: | |
236 vcd_buf=&vcd_cache_data[vcd_cache_index*VCD_SECTOR_SIZE]; | |
237 vcd_cache_sectors[vcd_cache_index]=vcd_cache_current; | |
238 ++vcd_cache_index;if(vcd_cache_index>=vcd_cache_size)vcd_cache_index=0; | |
239 // read data! | |
240 vcd_set_msf(vcd_cache_current); | |
241 #if defined(linux) || defined(__bsdi__) | |
242 memcpy(vcd_buf,&vcd_entry.cdte_addr.msf,sizeof(struct cdrom_msf)); | |
243 if(ioctl(fd,CDROMREADRAW,vcd_buf)==-1) return 0; // EOF? | |
244 memcpy(mem,&vcd_buf[VCD_SECTOR_OFFS],VCD_SECTOR_DATA); | |
245 #elif defined(sun) | |
246 { | |
247 int offset; | |
248 if (sun_vcd_read(fd, &offset) <= 0) return 0; | |
249 memcpy(mem,&vcd_buf[offset],VCD_SECTOR_DATA); | |
250 } | |
251 #endif | |
252 ++vcd_cache_current; | |
253 return VCD_SECTOR_DATA; | |
254 } | |
255 #endif | |
256 | |
257 #else /* linux || sun */ | |
258 | |
259 int vcd_seek_to_track(int fd,int track) | |
260 { | |
261 return -1; | |
262 } | |
263 | |
264 int vcd_get_track_end(int fd,int track) | |
265 { | |
266 return -1; | |
267 } | |
268 | |
269 void vcd_read_toc(int fd) | |
270 { | |
271 } | |
272 | |
273 static char vcd_buf[VCD_SECTOR_SIZE]; | |
274 | |
275 static int vcd_read(int fd,char *mem) | |
276 { | |
277 return -1; | |
278 } | |
279 | |
280 #endif /* !linux && !sun */ |