introduce stream and container duration
[nihav.git] / nihav-llaudio / src / demuxers / flac.rs
CommitLineData
87927c57
KS
1use nihav_core::frame::*;
2use nihav_core::demuxers::*;
3
1fb2da78
KS
4#[derive(Clone,Copy,Default)]
5struct FrameSeekInfo {
6 off: u64,
7 size: u64,
8 samplepos: u64,
9 sampleend: u64,
10}
11
87927c57
KS
12struct FLACDemuxer<'a> {
13 src: &'a mut ByteReader<'a>,
14 data_start: u64,
15 tot_samples: u64,
16 cur_samples: u64,
17 blk_samples: u16,
1fb2da78 18 min_samples: u16,
87927c57
KS
19 min_size: usize,
20 max_size: usize,
1fb2da78
KS
21 srate: u32,
22 known_frames: Vec<FrameSeekInfo>,
23 build_index: bool,
87927c57
KS
24}
25
26impl<'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,
1fb2da78 34 min_samples: 0,
87927c57
KS
35 min_size: 0,
36 max_size: 0,
1fb2da78
KS
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 });
87927c57 90 }
1fb2da78
KS
91
92 self.cur_samples += duration;
93
94 Ok((buf, pts, duration))
87927c57
KS
95 }
96}
97
98fn update_crc16(crc: u16, byte: u8) -> u16 {
99 (crc << 8) ^ CRC16_TABLE[(((crc >> 8) as u8) ^ byte) as usize]
100}
101
102fn 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
116impl<'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 }
1fb2da78 138 self.min_samples = min_bs;
87927c57
KS
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 }
1fb2da78
KS
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 }
87927c57
KS
173 self.data_start = self.src.tell();
174 validate!(srate != 0);
1fb2da78 175 self.srate = srate;
87927c57
KS
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));
a480a0de 180 strmgr.add_stream(NAStream::new(StreamType::Audio, 0, ainfo, base, srate, 0)).unwrap();
87927c57
KS
181
182 Ok(())
183 }
184 fn get_frame(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<NAPacket> {
1fb2da78 185 let (buf, pts, duration) = self.read_frame()?;
87927c57
KS
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
87927c57
KS
192 Ok(pkt)
193 }
194 fn seek(&mut self, time: NATimePoint, seek_index: &SeekIndex) -> DemuxerResult<()> {
1fb2da78
KS
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)
87927c57 240 }
87927c57 241 }
a480a0de 242 fn get_duration(&self) -> u64 { self.tot_samples * 1000 / u64::from(self.srate) }
87927c57
KS
243}
244
245impl<'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
251pub struct FLACDemuxerCreator { }
252
253impl 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)]
261mod 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
286const 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];