introduce stream and container duration
[nihav.git] / nihav-llaudio / src / demuxers / flac.rs
1 use nihav_core::frame::*;
2 use nihav_core::demuxers::*;
3
4 #[derive(Clone,Copy,Default)]
5 struct FrameSeekInfo {
6 off: u64,
7 size: u64,
8 samplepos: u64,
9 sampleend: u64,
10 }
11
12 struct FLACDemuxer<'a> {
13 src: &'a mut ByteReader<'a>,
14 data_start: u64,
15 tot_samples: u64,
16 cur_samples: u64,
17 blk_samples: u16,
18 min_samples: u16,
19 min_size: usize,
20 max_size: usize,
21 srate: u32,
22 known_frames: Vec<FrameSeekInfo>,
23 build_index: bool,
24 }
25
26 impl<'a> FLACDemuxer<'a> {
27 fn new(io: &'a mut ByteReader<'a>) -> Self {
28 Self {
29 src: io,
30 data_start: 0,
31 tot_samples: 0,
32 cur_samples: 0,
33 blk_samples: 0,
34 min_samples: 0,
35 min_size: 0,
36 max_size: 0,
37 srate: 0,
38 known_frames: Vec::new(),
39 build_index: false,
40 }
41 }
42 fn read_frame(&mut self) -> DemuxerResult<(Vec<u8>, u64, u64)> {
43 if self.src.is_eof() || (self.tot_samples != 0 && self.cur_samples == self.tot_samples) { return Err(DemuxerError::EOF); }
44 let mut buf = Vec::with_capacity(self.min_size);
45 let mut crc = 0;
46 let frame_start = self.src.tell();
47 for _ in 0..5 {
48 let byte = self.src.read_byte()?;
49 buf.push(byte);
50 crc = update_crc16(crc, byte);
51 }
52 let mut ref_crc = self.src.read_u16be()?;
53 loop {
54 let byte = self.src.read_byte()?;
55 let old_byte = (ref_crc >> 8) as u8;
56 buf.push(old_byte);
57 ref_crc = (ref_crc << 8) | u16::from(byte);
58 crc = update_crc16(crc, old_byte);
59 if buf.len() + 2 >= self.min_size && crc == ref_crc {
60 let ret = self.src.peek_u16be();
61 if ret.is_err() || ((ret.unwrap_or(0) & 0xFFFE) == 0xFFF8) {
62 buf.push((ref_crc >> 8) as u8);
63 buf.push(ref_crc as u8);
64 break;
65 }
66 }
67 if (self.max_size > 0) && (buf.len() > self.max_size) {
68 return Err(DemuxerError::InvalidData);
69 }
70 if buf.len() > (1 << 23) {
71 return Err(DemuxerError::InvalidData);
72 }
73 }
74
75 let (duration, pts) = if self.blk_samples != 0 {
76 validate!((buf[1] & 1) == 0);
77 let blkno = u64::from(read_utf8(&buf[4..])?);
78 self.cur_samples = blkno * u64::from(self.blk_samples);
79 (u64::from(self.blk_samples), blkno)
80 } else {
81 validate!((buf[1] & 1) != 0);
82 let blksamps = u64::from(read_utf8(&buf[4..])?);
83 (blksamps, self.cur_samples)
84 };
85
86 let spos = if self.blk_samples != 0 { pts * u64::from(self.blk_samples) } else { pts };
87 if self.build_index && (self.known_frames.is_empty() || self.known_frames.last().unwrap_or(&FrameSeekInfo::default()).samplepos < spos) {
88 let sampleend = spos + duration;
89 self.known_frames.push(FrameSeekInfo{off: frame_start, size: buf.len() as u64, samplepos: spos, sampleend });
90 }
91
92 self.cur_samples += duration;
93
94 Ok((buf, pts, duration))
95 }
96 }
97
98 fn update_crc16(crc: u16, byte: u8) -> u16 {
99 (crc << 8) ^ CRC16_TABLE[(((crc >> 8) as u8) ^ byte) as usize]
100 }
101
102 fn read_utf8(src: &[u8]) -> DemuxerResult<u32> {
103 if (src[0] & 0x80) == 0 {
104 return Ok(u32::from(src[0]));
105 }
106 let len = (!src[0]).leading_zeros() as usize;
107 validate!(len != 1 && len <= 5 && src.len() >= len);
108 let mut val = u32::from(src[0] & 0x1F);
109 for byte in src.iter().take(len).skip(1) {
110 validate!((*byte & 0xC0) == 0x80);
111 val = (val << 6) | u32::from(*byte & 0x3F);
112 }
113 Ok(val)
114 }
115
116 impl<'a> DemuxCore<'a> for FLACDemuxer<'a> {
117 fn open(&mut self, strmgr: &mut StreamManager, seek_index: &mut SeekIndex) -> DemuxerResult<()> {
118 let tag = self.src.read_tag()?;
119 validate!(&tag == b"fLaC");
120 let mut streaminfo: Vec<u8> = Vec::new();
121 let mut srate = 0u32;
122 let mut channels = 0u8;
123 loop {
124 let id1 = self.src.read_byte()?;
125 let len = self.src.read_u24be()? as usize;
126 let id = id1 & 0x7F;
127
128 match id {
129 0x00 => {
130 validate!(len >= 34);
131 streaminfo = vec![0u8; len];
132 self.src.read_buf(&mut streaminfo)?;
133 let min_bs = read_u16be(&streaminfo[0..])?;
134 let max_bs = read_u16be(&streaminfo[2..])?;
135 if min_bs == max_bs {
136 self.blk_samples = max_bs;
137 }
138 self.min_samples = min_bs;
139 self.min_size = read_u24be(&streaminfo[4..])? as usize;
140 self.max_size = read_u24be(&streaminfo[7..])? as usize;
141 let word = read_u24be(&streaminfo[10..])?;
142 srate = word >> 4;
143 channels = (((word >> 1) & 7) + 1) as u8;
144 self.tot_samples = (u64::from(streaminfo[13] & 0xF) << 32) | u64::from(read_u32be(&streaminfo[14..])?);
145 },
146 0x03 => {
147 validate!((len % 18) == 0);
148 seek_index.mode = SeekIndexMode::Present;
149 for _ in 0..len / 18 {
150 let sample = self.src.read_u64be()?;
151 let offset = self.src.read_u64be()?;
152 let _nsamps = self.src.read_u16be()?;
153 let time = sample * 1000 / u64::from(srate.max(1000));
154 seek_index.add_entry(0, SeekEntry { time, pts: sample, pos: offset });
155 }
156 },
157 _ => self.src.read_skip(len)?,
158 };
159
160 if (id1 & 0x80) != 0 {
161 break;
162 }
163 }
164 if seek_index.mode != SeekIndexMode::Present {
165 let min_size = if self.min_samples != 0 { self.min_samples } else { 2048 };
166 let nframes = self.tot_samples as usize / (min_size as usize);
167 self.known_frames = Vec::with_capacity(nframes.max(1));
168 seek_index.mode = SeekIndexMode::Automatic;
169 self.build_index = true;
170 } else {
171 self.build_index = false;
172 }
173 self.data_start = self.src.tell();
174 validate!(srate != 0);
175 self.srate = srate;
176
177 let base = if self.blk_samples != 0 { u32::from(self.blk_samples) } else { 1 };
178 let ahdr = NAAudioInfo::new(srate, channels as u8, SND_S16P_FORMAT, base as usize);
179 let ainfo = NACodecInfo::new("flac", NACodecTypeInfo::Audio(ahdr), Some(streaminfo));
180 strmgr.add_stream(NAStream::new(StreamType::Audio, 0, ainfo, base, srate, 0)).unwrap();
181
182 Ok(())
183 }
184 fn get_frame(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<NAPacket> {
185 let (buf, pts, duration) = self.read_frame()?;
186
187 let stream = strmgr.get_stream(0).unwrap();
188 let (tb_num, tb_den) = stream.get_timebase();
189 let ts = NATimeInfo::new(Some(pts), None, Some(duration), tb_num, tb_den);
190 let pkt = NAPacket::new(stream, ts, true, buf);
191
192 Ok(pkt)
193 }
194 fn seek(&mut self, time: NATimePoint, seek_index: &SeekIndex) -> DemuxerResult<()> {
195 if seek_index.mode == SeekIndexMode::Present {
196 let ret = seek_index.find_pos(time);
197 if ret.is_none() {
198 return Err(DemuxerError::SeekError);
199 }
200 let seek_info = ret.unwrap();
201 self.cur_samples = seek_info.pts;
202 self.src.seek(SeekFrom::Start(self.data_start + seek_info.pos))?;
203 Ok(())
204 } else if let NATimePoint::Milliseconds(ms) = time {
205 let samppos = NATimeInfo::time_to_ts(ms, 1000, self.srate, 1);
206 if self.known_frames.last().unwrap_or(&FrameSeekInfo::default()).sampleend >= samppos {
207 for point in self.known_frames.iter().rev() {
208 if point.samplepos <= samppos {
209 self.src.seek(SeekFrom::Start(point.off))?;
210 self.cur_samples = point.samplepos;
211 return Ok(());
212 }
213 }
214 } else {
215 let startinfo = FrameSeekInfo { off: self.data_start, size: 0, samplepos: 0, sampleend: 0 };
216 let lentry = self.known_frames.last().unwrap_or(&startinfo);
217
218 self.src.seek(SeekFrom::Start(lentry.off + lentry.size))?;
219 self.cur_samples = lentry.sampleend;
220 loop {
221 let frame_start = self.src.tell();
222 let ret = self.read_frame();
223 if ret.is_err() {
224 return Err(DemuxerError::SeekError);
225 }
226 let (_, pts, duration) = ret.unwrap();
227 self.cur_samples = pts;
228 if self.blk_samples != 0 {
229 self.cur_samples *= u64::from(self.blk_samples);
230 }
231 if self.cur_samples <= samppos && self.cur_samples + duration >= samppos {
232 self.src.seek(SeekFrom::Start(frame_start))?;
233 return Ok(());
234 }
235 }
236 }
237 Err(DemuxerError::SeekError)
238 } else {
239 Err(DemuxerError::NotPossible)
240 }
241 }
242 fn get_duration(&self) -> u64 { self.tot_samples * 1000 / u64::from(self.srate) }
243 }
244
245 impl<'a> NAOptionHandler for FLACDemuxer<'a> {
246 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
247 fn set_options(&mut self, _options: &[NAOption]) { }
248 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
249 }
250
251 pub struct FLACDemuxerCreator { }
252
253 impl DemuxerCreator for FLACDemuxerCreator {
254 fn new_demuxer<'a>(&self, br: &'a mut ByteReader<'a>) -> Box<dyn DemuxCore<'a> + 'a> {
255 Box::new(FLACDemuxer::new(br))
256 }
257 fn get_name(&self) -> &'static str { "flac" }
258 }
259
260 #[cfg(test)]
261 mod test {
262 use super::*;
263 use std::fs::File;
264
265 #[test]
266 fn test_flac_demux() {
267 let mut file = File::open("assets/LLaudio/luckynight.flac").unwrap();
268 let mut fr = FileReader::new_read(&mut file);
269 let mut br = ByteReader::new(&mut fr);
270 let mut dmx = FLACDemuxer::new(&mut br);
271 let mut sm = StreamManager::new();
272 let mut si = SeekIndex::new();
273 dmx.open(&mut sm, &mut si).unwrap();
274 loop {
275 let pktres = dmx.get_frame(&mut sm);
276 if let Err(e) = pktres {
277 if (e as i32) == (DemuxerError::EOF as i32) { break; }
278 panic!("error");
279 }
280 let pkt = pktres.unwrap();
281 println!("Got {}", pkt);
282 }
283 }
284 }
285
286 const CRC16_TABLE: [u16; 256] = [
287 0x0000, 0x8005, 0x800F, 0x000A, 0x801B, 0x001E, 0x0014, 0x8011,
288 0x8033, 0x0036, 0x003C, 0x8039, 0x0028, 0x802D, 0x8027, 0x0022,
289 0x8063, 0x0066, 0x006C, 0x8069, 0x0078, 0x807D, 0x8077, 0x0072,
290 0x0050, 0x8055, 0x805F, 0x005A, 0x804B, 0x004E, 0x0044, 0x8041,
291 0x80C3, 0x00C6, 0x00CC, 0x80C9, 0x00D8, 0x80DD, 0x80D7, 0x00D2,
292 0x00F0, 0x80F5, 0x80FF, 0x00FA, 0x80EB, 0x00EE, 0x00E4, 0x80E1,
293 0x00A0, 0x80A5, 0x80AF, 0x00AA, 0x80BB, 0x00BE, 0x00B4, 0x80B1,
294 0x8093, 0x0096, 0x009C, 0x8099, 0x0088, 0x808D, 0x8087, 0x0082,
295 0x8183, 0x0186, 0x018C, 0x8189, 0x0198, 0x819D, 0x8197, 0x0192,
296 0x01B0, 0x81B5, 0x81BF, 0x01BA, 0x81AB, 0x01AE, 0x01A4, 0x81A1,
297 0x01E0, 0x81E5, 0x81EF, 0x01EA, 0x81FB, 0x01FE, 0x01F4, 0x81F1,
298 0x81D3, 0x01D6, 0x01DC, 0x81D9, 0x01C8, 0x81CD, 0x81C7, 0x01C2,
299 0x0140, 0x8145, 0x814F, 0x014A, 0x815B, 0x015E, 0x0154, 0x8151,
300 0x8173, 0x0176, 0x017C, 0x8179, 0x0168, 0x816D, 0x8167, 0x0162,
301 0x8123, 0x0126, 0x012C, 0x8129, 0x0138, 0x813D, 0x8137, 0x0132,
302 0x0110, 0x8115, 0x811F, 0x011A, 0x810B, 0x010E, 0x0104, 0x8101,
303 0x8303, 0x0306, 0x030C, 0x8309, 0x0318, 0x831D, 0x8317, 0x0312,
304 0x0330, 0x8335, 0x833F, 0x033A, 0x832B, 0x032E, 0x0324, 0x8321,
305 0x0360, 0x8365, 0x836F, 0x036A, 0x837B, 0x037E, 0x0374, 0x8371,
306 0x8353, 0x0356, 0x035C, 0x8359, 0x0348, 0x834D, 0x8347, 0x0342,
307 0x03C0, 0x83C5, 0x83CF, 0x03CA, 0x83DB, 0x03DE, 0x03D4, 0x83D1,
308 0x83F3, 0x03F6, 0x03FC, 0x83F9, 0x03E8, 0x83ED, 0x83E7, 0x03E2,
309 0x83A3, 0x03A6, 0x03AC, 0x83A9, 0x03B8, 0x83BD, 0x83B7, 0x03B2,
310 0x0390, 0x8395, 0x839F, 0x039A, 0x838B, 0x038E, 0x0384, 0x8381,
311 0x0280, 0x8285, 0x828F, 0x028A, 0x829B, 0x029E, 0x0294, 0x8291,
312 0x82B3, 0x02B6, 0x02BC, 0x82B9, 0x02A8, 0x82AD, 0x82A7, 0x02A2,
313 0x82E3, 0x02E6, 0x02EC, 0x82E9, 0x02F8, 0x82FD, 0x82F7, 0x02F2,
314 0x02D0, 0x82D5, 0x82DF, 0x02DA, 0x82CB, 0x02CE, 0x02C4, 0x82C1,
315 0x8243, 0x0246, 0x024C, 0x8249, 0x0258, 0x825D, 0x8257, 0x0252,
316 0x0270, 0x8275, 0x827F, 0x027A, 0x826B, 0x026E, 0x0264, 0x8261,
317 0x0220, 0x8225, 0x822F, 0x022A, 0x823B, 0x023E, 0x0234, 0x8231,
318 0x8213, 0x0216, 0x021C, 0x8219, 0x0208, 0x820D, 0x8207, 0x0202
319 ];