1mod tremor_sys;
2extern crate libc;
3extern crate ogg_sys;
4
5use std::io::{self, Read, Seek};
6use std::mem::MaybeUninit;
7
8pub struct Decoder<R>
10where
11 R: Read + Seek,
12{
13 data: Box<DecoderData<R>>,
15}
16
17pub struct PacketsIter<'a, R: 'a + Read + Seek>(&'a mut Decoder<R>);
19
20pub struct PacketsIntoIter<R: Read + Seek>(Decoder<R>);
22
23#[derive(Debug)]
25pub enum VorbisError {
26 ReadError(io::Error),
27 NotVorbis,
28 VersionMismatch,
29 BadHeader,
30 InitialFileHeadersCorrupt,
31 Hole,
32}
33
34impl std::error::Error for VorbisError {
35 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
36 match self {
37 VorbisError::ReadError(ref err) => Some(err),
38 _ => None,
39 }
40 }
41}
42
43impl std::fmt::Display for VorbisError {
44 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
45 let description = match self {
46 VorbisError::ReadError(_) => "A read from media returned an error",
47 VorbisError::NotVorbis => "Bitstream does not contain any Vorbis data",
48 VorbisError::VersionMismatch => "Vorbis version mismatch",
49 VorbisError::BadHeader => "Invalid Vorbis bitstream header",
50 VorbisError::InitialFileHeadersCorrupt => "Initial file headers are corrupt",
51 VorbisError::Hole => "Interruption of data",
52 };
53
54 fmt.write_str(description)
55 }
56}
57
58impl From<io::Error> for VorbisError {
59 fn from(err: io::Error) -> VorbisError {
60 VorbisError::ReadError(err)
61 }
62}
63
64#[repr(C)]
65struct DecoderData<R>
66where
67 R: Read + Seek,
68{
69 vorbis: tremor_sys::OggVorbis_File,
70 reader: R,
71 current_logical_bitstream: libc::c_int,
72 read_error: Option<io::Error>,
73}
74
75#[repr(C)]
76struct DecoderDataUninit<R>
77where
78 R: Read + Seek,
79{
80 vorbis: MaybeUninit<tremor_sys::OggVorbis_File>,
81 reader: R,
82 current_logical_bitstream: libc::c_int,
83 read_error: Option<io::Error>,
84}
85
86unsafe impl<R: Read + Seek + Send> Send for DecoderData<R> {}
87
88#[derive(Clone, Debug)]
95pub struct Packet {
96 pub data: Vec<i16>,
97 pub channels: u16,
98 pub rate: u64,
99 pub bitrate_upper: u64,
100 pub bitrate_nominal: u64,
101 pub bitrate_lower: u64,
102 pub bitrate_window: u64,
103}
104
105impl<R> Decoder<R>
106where
107 R: Read + Seek,
108{
109 pub fn new(input: R) -> Result<Decoder<R>, VorbisError> {
110 extern "C" fn read_func<R>(
111 ptr: *mut libc::c_void,
112 size: libc::size_t,
113 nmemb: libc::size_t,
114 datasource: *mut libc::c_void,
115 ) -> libc::size_t
116 where
117 R: Read + Seek,
118 {
119 use std::slice;
120
121 assert_eq!(size, 1);
126
127 let ptr = ptr as *mut u8;
128
129 let data: &mut DecoderData<R> = unsafe { &mut *(datasource as *mut _) };
130
131 let buffer = unsafe { slice::from_raw_parts_mut(ptr as *mut u8, nmemb as usize) };
132
133 loop {
134 match data.reader.read(buffer) {
135 Ok(nb) => return nb as libc::size_t,
136 Err(ref e) if e.kind() == io::ErrorKind::Interrupted => (),
137 Err(e) => {
138 data.read_error = Some(e);
139 return 0;
140 }
141 }
142 }
143 }
144
145 extern "C" fn seek_func<R>(
146 datasource: *mut libc::c_void,
147 offset: tremor_sys::ogg_int64_t,
148 whence: libc::c_int,
149 ) -> libc::c_int
150 where
151 R: Read + Seek,
152 {
153 let data: &mut DecoderData<R> = unsafe { &mut *(datasource as *mut _) };
154
155 let result = match whence {
156 libc::SEEK_SET => data.reader.seek(io::SeekFrom::Start(offset as u64)),
157 libc::SEEK_CUR => data.reader.seek(io::SeekFrom::Current(offset)),
158 libc::SEEK_END => data.reader.seek(io::SeekFrom::End(offset)),
159 _ => unreachable!(),
160 };
161
162 match result {
163 Ok(_) => 0,
164 Err(_) => -1,
165 }
166 }
167
168 extern "C" fn tell_func<R>(datasource: *mut libc::c_void) -> libc::c_long
169 where
170 R: Read + Seek,
171 {
172 let data: &mut DecoderData<R> = unsafe { &mut *(datasource as *mut DecoderData<R>) };
173 data.reader
174 .seek(io::SeekFrom::Current(0))
175 .map(|v| v as libc::c_long)
176 .unwrap_or(-1)
177 }
178
179 extern "C" fn close_func<R>(_datasource: *mut libc::c_void) -> libc::c_int
180 where
181 R: Read + Seek,
182 {
183 0
184 }
185
186 let callbacks = tremor_sys::ov_callbacks {
187 read_func: read_func::<R>,
188 seek_func: seek_func::<R>,
189 tell_func: tell_func::<R>,
190 close_func: close_func::<R>,
191 };
192
193 let mut data = Box::new(DecoderDataUninit {
194 vorbis: MaybeUninit::uninit(),
195 reader: input,
196 current_logical_bitstream: 0,
197 read_error: None,
198 });
199
200 unsafe {
202 let data_ptr = data.vorbis.as_mut_ptr();
203 check_errors(tremor_sys::ov_open_callbacks(
204 data_ptr as *mut libc::c_void,
205 data_ptr,
206 std::ptr::null(),
207 0,
208 callbacks,
209 ))?;
210 }
211
212 let data: Box<DecoderData<R>> = unsafe { std::mem::transmute(data) };
213
214 Ok(Decoder { data })
215 }
216
217 pub fn time_seek(&mut self, s: i64) -> Result<(), VorbisError> {
218 unsafe { check_errors(tremor_sys::ov_time_seek(&mut self.data.vorbis, s)) }
219 }
220
221 pub fn time_tell(&mut self) -> Result<i64, VorbisError> {
222 unsafe { Ok(tremor_sys::ov_time_tell(&mut self.data.vorbis)) }
223 }
224
225 pub fn packets(&mut self) -> PacketsIter<R> {
226 PacketsIter(self)
227 }
228
229 pub fn into_packets(self) -> PacketsIntoIter<R> {
230 PacketsIntoIter(self)
231 }
232
233 fn next_packet(&mut self) -> Option<Result<Packet, VorbisError>> {
234 let mut buffer = std::iter::repeat(0i16).take(2048).collect::<Vec<_>>();
235 let buffer_len = buffer.len() * 2;
236
237 match unsafe {
238 tremor_sys::ov_read(
239 &mut self.data.vorbis,
240 buffer.as_mut_ptr() as *mut libc::c_char,
241 buffer_len as libc::c_int,
242 0,
243 2,
244 1,
245 &mut self.data.current_logical_bitstream,
246 )
247 } {
248 0 => match self.data.read_error.take() {
249 Some(err) => Some(Err(VorbisError::ReadError(err))),
250 None => None,
251 },
252
253 err if err < 0 => match check_errors(err as libc::c_int) {
254 Err(e) => Some(Err(e)),
255 Ok(_) => unreachable!(),
256 },
257
258 len => {
259 buffer.truncate(len as usize / 2);
260
261 let infos = unsafe {
262 tremor_sys::ov_info(&mut self.data.vorbis, self.data.current_logical_bitstream)
263 };
264
265 let infos: &tremor_sys::vorbis_info = unsafe { &*infos };
266
267 Some(Ok(Packet {
268 data: buffer,
269 channels: infos.channels as u16,
270 rate: infos.rate as u64,
271 bitrate_upper: infos.bitrate_upper as u64,
272 bitrate_nominal: infos.bitrate_nominal as u64,
273 bitrate_lower: infos.bitrate_lower as u64,
274 bitrate_window: infos.bitrate_window as u64,
275 }))
276 }
277 }
278 }
279}
280
281impl<'a, R> Iterator for PacketsIter<'a, R>
282where
283 R: 'a + Read + Seek,
284{
285 type Item = Result<Packet, VorbisError>;
286
287 fn next(&mut self) -> Option<Result<Packet, VorbisError>> {
288 self.0.next_packet()
289 }
290}
291
292impl<R> Iterator for PacketsIntoIter<R>
293where
294 R: Read + Seek,
295{
296 type Item = Result<Packet, VorbisError>;
297
298 fn next(&mut self) -> Option<Result<Packet, VorbisError>> {
299 self.0.next_packet()
300 }
301}
302
303impl<R> Drop for Decoder<R>
304where
305 R: Read + Seek,
306{
307 fn drop(&mut self) {
308 unsafe {
309 tremor_sys::ov_clear(&mut self.data.vorbis);
310 }
311 }
312}
313
314fn check_errors(code: libc::c_int) -> Result<(), VorbisError> {
315 match code {
316 0 => Ok(()),
317
318 tremor_sys::OV_ENOTVORBIS => Err(VorbisError::NotVorbis),
319 tremor_sys::OV_EVERSION => Err(VorbisError::VersionMismatch),
320 tremor_sys::OV_EBADHEADER => Err(VorbisError::BadHeader),
321 tremor_sys::OV_EINVAL => Err(VorbisError::InitialFileHeadersCorrupt),
322 tremor_sys::OV_HOLE => Err(VorbisError::Hole),
323
324 tremor_sys::OV_EREAD => unimplemented!(),
325
326 tremor_sys::OV_EFAULT => panic!("Internal libvorbis error"),
328 _ => panic!("Unknown vorbis error {}", code),
329 }
330}