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