wav: generate PTS for demuxed blocks
[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));
180 strmgr.add_stream(NAStream::new(StreamType::Audio, 0, ainfo, base, srate)).unwrap();
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
KS
241 }
242}
243
244impl<'a> NAOptionHandler for FLACDemuxer<'a> {
245 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
246 fn set_options(&mut self, _options: &[NAOption]) { }
247 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
248}
249
250pub struct FLACDemuxerCreator { }
251
252impl DemuxerCreator for FLACDemuxerCreator {
253 fn new_demuxer<'a>(&self, br: &'a mut ByteReader<'a>) -> Box<dyn DemuxCore<'a> + 'a> {
254 Box::new(FLACDemuxer::new(br))
255 }
256 fn get_name(&self) -> &'static str { "flac" }
257}
258
259#[cfg(test)]
260mod test {
261 use super::*;
262 use std::fs::File;
263
264 #[test]
265 fn test_flac_demux() {
266 let mut file = File::open("assets/LLaudio/luckynight.flac").unwrap();
267 let mut fr = FileReader::new_read(&mut file);
268 let mut br = ByteReader::new(&mut fr);
269 let mut dmx = FLACDemuxer::new(&mut br);
270 let mut sm = StreamManager::new();
271 let mut si = SeekIndex::new();
272 dmx.open(&mut sm, &mut si).unwrap();
273 loop {
274 let pktres = dmx.get_frame(&mut sm);
275 if let Err(e) = pktres {
276 if (e as i32) == (DemuxerError::EOF as i32) { break; }
277 panic!("error");
278 }
279 let pkt = pktres.unwrap();
280 println!("Got {}", pkt);
281 }
282 }
283}
284
285const CRC16_TABLE: [u16; 256] = [
286 0x0000, 0x8005, 0x800F, 0x000A, 0x801B, 0x001E, 0x0014, 0x8011,
287 0x8033, 0x0036, 0x003C, 0x8039, 0x0028, 0x802D, 0x8027, 0x0022,
288 0x8063, 0x0066, 0x006C, 0x8069, 0x0078, 0x807D, 0x8077, 0x0072,
289 0x0050, 0x8055, 0x805F, 0x005A, 0x804B, 0x004E, 0x0044, 0x8041,
290 0x80C3, 0x00C6, 0x00CC, 0x80C9, 0x00D8, 0x80DD, 0x80D7, 0x00D2,
291 0x00F0, 0x80F5, 0x80FF, 0x00FA, 0x80EB, 0x00EE, 0x00E4, 0x80E1,
292 0x00A0, 0x80A5, 0x80AF, 0x00AA, 0x80BB, 0x00BE, 0x00B4, 0x80B1,
293 0x8093, 0x0096, 0x009C, 0x8099, 0x0088, 0x808D, 0x8087, 0x0082,
294 0x8183, 0x0186, 0x018C, 0x8189, 0x0198, 0x819D, 0x8197, 0x0192,
295 0x01B0, 0x81B5, 0x81BF, 0x01BA, 0x81AB, 0x01AE, 0x01A4, 0x81A1,
296 0x01E0, 0x81E5, 0x81EF, 0x01EA, 0x81FB, 0x01FE, 0x01F4, 0x81F1,
297 0x81D3, 0x01D6, 0x01DC, 0x81D9, 0x01C8, 0x81CD, 0x81C7, 0x01C2,
298 0x0140, 0x8145, 0x814F, 0x014A, 0x815B, 0x015E, 0x0154, 0x8151,
299 0x8173, 0x0176, 0x017C, 0x8179, 0x0168, 0x816D, 0x8167, 0x0162,
300 0x8123, 0x0126, 0x012C, 0x8129, 0x0138, 0x813D, 0x8137, 0x0132,
301 0x0110, 0x8115, 0x811F, 0x011A, 0x810B, 0x010E, 0x0104, 0x8101,
302 0x8303, 0x0306, 0x030C, 0x8309, 0x0318, 0x831D, 0x8317, 0x0312,
303 0x0330, 0x8335, 0x833F, 0x033A, 0x832B, 0x032E, 0x0324, 0x8321,
304 0x0360, 0x8365, 0x836F, 0x036A, 0x837B, 0x037E, 0x0374, 0x8371,
305 0x8353, 0x0356, 0x035C, 0x8359, 0x0348, 0x834D, 0x8347, 0x0342,
306 0x03C0, 0x83C5, 0x83CF, 0x03CA, 0x83DB, 0x03DE, 0x03D4, 0x83D1,
307 0x83F3, 0x03F6, 0x03FC, 0x83F9, 0x03E8, 0x83ED, 0x83E7, 0x03E2,
308 0x83A3, 0x03A6, 0x03AC, 0x83A9, 0x03B8, 0x83BD, 0x83B7, 0x03B2,
309 0x0390, 0x8395, 0x839F, 0x039A, 0x838B, 0x038E, 0x0384, 0x8381,
310 0x0280, 0x8285, 0x828F, 0x028A, 0x829B, 0x029E, 0x0294, 0x8291,
311 0x82B3, 0x02B6, 0x02BC, 0x82B9, 0x02A8, 0x82AD, 0x82A7, 0x02A2,
312 0x82E3, 0x02E6, 0x02EC, 0x82E9, 0x02F8, 0x82FD, 0x82F7, 0x02F2,
313 0x02D0, 0x82D5, 0x82DF, 0x02DA, 0x82CB, 0x02CE, 0x02C4, 0x82C1,
314 0x8243, 0x0246, 0x024C, 0x8249, 0x0258, 0x825D, 0x8257, 0x0252,
315 0x0270, 0x8275, 0x827F, 0x027A, 0x826B, 0x026E, 0x0264, 0x8261,
316 0x0220, 0x8225, 0x822F, 0x022A, 0x823B, 0x023E, 0x0234, 0x8231,
317 0x8213, 0x0216, 0x021C, 0x8219, 0x0208, 0x820D, 0x8207, 0x0202
318];