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