Mercurial > mplayer.hg
annotate libmpdemux/vcd_read_nbsd.h @ 12337:6f1b4c989914
soft skipping for mencoder. rather than skipping decoding/filtering
frames that will be skipped, mencoded tells vf_softskip (if present)
that it should drop the next frame. this allows filters that need to
see every input frame (inverse telecine, denoise3d, ...) to see
skipped frames before they get dropped.
in principle, a smarter softskip filter could be written that would
buffer frames and choose to drop the one with least change, rather
than strictly dropping the next one.
author | rfelker |
---|---|
date | Wed, 28 Apr 2004 04:29:17 +0000 |
parents | d862231858d5 |
children | b2419eef04da |
rev | line source |
---|---|
5872 | 1 |
2 #include <sys/types.h> | |
3 #include <sys/inttypes.h> | |
4 #include <sys/cdio.h> | |
5 #include <sys/scsiio.h> | |
6 | |
7 #define CDROM_LEADOUT 0xAA | |
8 | |
9887 | 9 typedef struct mp_vcd_priv_st { |
10 int fd; | |
11 struct ioc_read_toc_entry entry; | |
12 struct cd_toc_entry entry_data; | |
13 } mp_vcd_priv_t; | |
5872 | 14 |
15 static inline void | |
9887 | 16 vcd_set_msf(mp_vcd_priv_t* vcd, unsigned int sect) |
5872 | 17 { |
9887 | 18 vcd->entry_data.addr.msf.frame = sect % 75; |
5872 | 19 sect = sect / 75; |
9887 | 20 vcd->entry_data.addr.msf.second = sect % 60; |
5872 | 21 sect = sect / 60; |
9887 | 22 vcd->entry_data.addr.msf.minute = sect; |
5872 | 23 } |
24 | |
8532
9688aa033083
fix VCD playback - this is a patch from the netbsd pkgsrc tree,
arpi
parents:
7406
diff
changeset
|
25 static inline void |
9887 | 26 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
|
27 { |
9887 | 28 vcd->entry_data.addr.msf.frame++; |
29 if (vcd->entry_data.addr.msf.frame==75){ | |
30 vcd->entry_data.addr.msf.frame=0; | |
31 vcd->entry_data.addr.msf.second++; | |
32 if (vcd->entry_data.addr.msf.second==60){ | |
33 vcd->entry_data.addr.msf.second=0; | |
34 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
|
35 } |
9688aa033083
fix VCD playback - this is a patch from the netbsd pkgsrc tree,
arpi
parents:
7406
diff
changeset
|
36 } |
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 |
5872 | 39 static inline unsigned int |
9887 | 40 vcd_get_msf(mp_vcd_priv_t* vcd) |
5872 | 41 { |
9887 | 42 return vcd->entry_data.addr.msf.frame + |
43 (vcd->entry_data.addr.msf.second + | |
44 vcd->entry_data.addr.msf.minute * 60) * 75; | |
5872 | 45 } |
46 | |
47 int | |
9887 | 48 vcd_seek_to_track(mp_vcd_priv_t* vcd, int track) |
5872 | 49 { |
9887 | 50 vcd->entry.address_format = CD_MSF_FORMAT; |
51 vcd->entry.starting_track = track; | |
52 vcd->entry.data_len = sizeof(struct cd_toc_entry); | |
53 vcd->entry.data = &vcd->entry_data; | |
54 if (ioctl(vcd->fd, CDIOREADTOCENTRIES, &vcd->entry)) { | |
55 mp_msg(MSGT_STREAM,MSGL_ERR,"ioctl dif1: %s\n",strerror(errno)); | |
5872 | 56 return -1; |
57 } | |
9887 | 58 return VCD_SECTOR_DATA * vcd_get_msf(vcd); |
5872 | 59 } |
60 | |
61 int | |
9887 | 62 vcd_get_track_end(mp_vcd_priv_t* vcd, int track) |
5872 | 63 { |
64 struct ioc_toc_header tochdr; | |
9887 | 65 if (ioctl(vcd->fd, CDIOREADTOCHEADER, &tochdr) == -1) { |
66 mp_msg(MSGT_STREAM,MSGL_ERR,"read CDROM toc header: %s\n",strerror(errno)); | |
5872 | 67 return -1; |
68 } | |
9887 | 69 vcd->entry.address_format = CD_MSF_FORMAT; |
70 vcd->entry.starting_track = track < tochdr.ending_track ? (track + 1) : CDROM_LEADOUT; | |
71 vcd->entry.data_len = sizeof(struct cd_toc_entry); | |
72 vcd->entry.data = &vcd->entry_data; | |
73 if (ioctl(vcd->fd, CDIOREADTOCENTRYS, &vcd->entry)) { | |
74 mp_msg(MSGT_STREAM,MSGL_ERR,"ioctl dif2: %s\n",strerror(errno)); | |
5872 | 75 return -1; |
76 } | |
9887 | 77 return VCD_SECTOR_DATA * vcd_get_msf(vcd); |
5872 | 78 } |
79 | |
9887 | 80 mp_vcd_priv_t* |
5872 | 81 vcd_read_toc(int fd) |
82 { | |
83 struct ioc_toc_header tochdr; | |
9887 | 84 mp_vcd_priv_t* vcd; |
5872 | 85 int i; |
86 if (ioctl(fd, CDIOREADTOCHEADER, &tochdr) == -1) { | |
9887 | 87 mp_msg(MSGT_OPEN,MSGL_ERR,"read CDROM toc header: %s\n",strerror(errno)); |
5872 | 88 return; |
89 } | |
90 for (i = tochdr.starting_track; i <= tochdr.ending_track; i++) { | |
91 struct ioc_read_toc_entry tocentry; | |
92 struct cd_toc_entry tocentry_data; | |
93 | |
94 tocentry.starting_track = i; | |
95 tocentry.address_format = CD_MSF_FORMAT; | |
96 tocentry.data_len = sizeof(struct cd_toc_entry); | |
97 tocentry.data = &tocentry_data; | |
98 | |
99 if (ioctl(fd, CDIOREADTOCENTRYS, &tocentry) == -1) { | |
9887 | 100 mp_msg(MSGT_OPEN,MSGL_ERR,"read CDROM toc entry: %s\n",strerror(errno)); |
101 return NULL; | |
5872 | 102 } |
9887 | 103 mp_msg(MSGT_OPEN,MSGL_INFO,"track %02d: adr=%d ctrl=%d format=%d %02d:%02d:%02d\n", |
5872 | 104 (int) tocentry.starting_track, |
105 (int) tocentry.data->addr_type, | |
106 (int) tocentry.data->control, | |
107 (int) tocentry.address_format, | |
108 (int) tocentry.data->addr.msf.minute, | |
109 (int) tocentry.data->addr.msf.second, | |
110 (int) tocentry.data->addr.msf.frame | |
111 ); | |
112 } | |
9887 | 113 vcd = malloc(sizeof(mp_vcd_priv_t)); |
114 vcd->fd = fd; | |
115 return vcd; | |
5872 | 116 } |
117 | |
118 static int | |
9887 | 119 vcd_read(mp_vcd_priv_t* vcd, char *mem) |
5872 | 120 { |
121 struct scsireq sc; | |
9887 | 122 int lba = vcd_get_msf(vcd); |
5872 | 123 int blocks; |
124 int sector_type; | |
125 int sync, header_code, user_data, edc_ecc, error_field; | |
126 int sub_channel; | |
127 int rc; | |
128 | |
129 blocks = 1; | |
130 sector_type = 5; /* mode2/form2 */ | |
131 sync = 0; | |
132 header_code = 0; | |
133 user_data = 1; | |
134 edc_ecc = 0; | |
135 error_field = 0; | |
136 sub_channel = 0; | |
137 | |
138 memset(&sc, 0, sizeof(sc)); | |
139 sc.cmd[0] = 0xBE; | |
140 sc.cmd[1] = (sector_type) << 2; | |
141 sc.cmd[2] = (lba >> 24) & 0xff; | |
142 sc.cmd[3] = (lba >> 16) & 0xff; | |
143 sc.cmd[4] = (lba >> 8) & 0xff; | |
144 sc.cmd[5] = lba & 0xff; | |
145 sc.cmd[6] = (blocks >> 16) & 0xff; | |
146 sc.cmd[7] = (blocks >> 8) & 0xff; | |
147 sc.cmd[8] = blocks & 0xff; | |
148 sc.cmd[9] = (sync << 7) | (header_code << 5) | (user_data << 4) | | |
149 (edc_ecc << 3) | (error_field << 1); | |
150 sc.cmd[10] = sub_channel; | |
151 sc.cmdlen = 12; | |
152 sc.databuf = (caddr_t) mem; | |
153 sc.datalen = 2328; | |
154 sc.senselen = sizeof(sc.sense); | |
155 sc.flags = SCCMD_READ; | |
156 sc.timeout = 10000; | |
9887 | 157 rc = ioctl(vcd->fd, SCIOCCOMMAND, &sc); |
5872 | 158 if (rc == -1) { |
9887 | 159 mp_msg(MSGT_STREAM,MSGL_ERR,"SCIOCCOMMAND: %s\n",strerror(errno)); |
5872 | 160 return -1; |
161 } | |
162 if (sc.retsts || sc.error) { | |
9887 | 163 mp_msg(MSGT_STREAM,MSGL_ERR,"scsi command failed: status %d error %d\n", |
164 sc.retsts,sc.error); | |
5872 | 165 return -1; |
166 } | |
9887 | 167 vcd_inc_msf(vcd); |
5872 | 168 return VCD_SECTOR_DATA; |
169 } | |
170 |