1 use nihav_core::frame::*;
2 use nihav_core::demuxers::*;
4 #[derive(Clone,Copy,Default)]
12 struct FLACDemuxer<'a> {
13 src: &'a mut ByteReader<'a>,
22 known_frames: Vec<FrameSeekInfo>,
26 impl<'a> FLACDemuxer<'a> {
27 fn new(io: &'a mut ByteReader<'a>) -> Self {
38 known_frames: Vec::new(),
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);
46 let frame_start = self.src.tell();
48 let byte = self.src.read_byte()?;
50 crc = update_crc16(crc, byte);
52 let mut ref_crc = self.src.read_u16be()?;
54 let byte = self.src.read_byte()?;
55 let old_byte = (ref_crc >> 8) as u8;
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);
67 if (self.max_size > 0) && (buf.len() > self.max_size) {
68 return Err(DemuxerError::InvalidData);
70 if buf.len() > (1 << 23) {
71 return Err(DemuxerError::InvalidData);
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)
82 while idx < buf.len() && (buf[idx] & 0x80) != 0 {
86 let bsz_id = buf[2] >> 4;
87 let blksamps = match bsz_id {
88 0 => return Err(DemuxerError::InvalidData),
90 2..=5 => 576 << (bsz_id - 2),
92 validate!(idx + 1 <= buf.len());
93 u64::from(buf[idx]) + 1
96 validate!(idx + 2 <= buf.len());
97 u64::from(buf[idx]) * 256 + u64::from(buf[idx + 1]) + 1
99 _ => 256 << (bsz_id - 8),
101 let pts = u64::from(read_utf8(&buf[4..])?);
103 validate!(idx < buf.len());
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 });
114 self.cur_samples += duration;
116 Ok((buf, pts, duration))
120 fn update_crc16(crc: u16, byte: u8) -> u16 {
121 (crc << 8) ^ CRC16_TABLE[(((crc >> 8) as u8) ^ byte) as usize]
124 fn read_utf8(src: &[u8]) -> DemuxerResult<u32> {
125 if (src[0] & 0x80) == 0 {
126 return Ok(u32::from(src[0]));
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);
138 impl<'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;
146 let id1 = self.src.read_byte()?;
147 let len = self.src.read_u24be()? as usize;
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;
160 self.min_samples = min_bs;
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..])?;
165 channels = (((word >> 1) & 7) + 1) as u8;
166 self.tot_samples = (u64::from(streaminfo[13] & 0xF) << 32) | u64::from(read_u32be(&streaminfo[14..])?);
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 });
179 _ => self.src.read_skip(len)?,
182 if (id1 & 0x80) != 0 {
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;
193 self.build_index = false;
195 self.data_start = self.src.tell();
196 validate!(srate != 0);
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));
202 strmgr.add_stream(NAStream::new(StreamType::Audio, 0, ainfo, base, srate, 0)).unwrap();
206 fn get_frame(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<NAPacket> {
207 let (buf, pts, duration) = self.read_frame()?;
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);
216 fn seek(&mut self, time: NATimePoint, seek_index: &SeekIndex) -> DemuxerResult<()> {
217 if seek_index.mode == SeekIndexMode::Present {
218 let ret = seek_index.find_pos(time);
220 return Err(DemuxerError::SeekError);
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))?;
226 } else if let NATimePoint::Milliseconds(ms) = time {
227 let samppos = NATimeInfo::time_to_ts(ms, 1000, 1, self.srate);
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;
237 let startinfo = FrameSeekInfo { off: self.data_start, size: 0, samplepos: 0, sampleend: 0 };
238 let lentry = self.known_frames.last().unwrap_or(&startinfo);
240 self.src.seek(SeekFrom::Start(lentry.off + lentry.size))?;
241 self.cur_samples = lentry.sampleend;
243 let frame_start = self.src.tell();
244 let ret = self.read_frame();
246 return Err(DemuxerError::SeekError);
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);
253 if self.cur_samples <= samppos && self.cur_samples + duration >= samppos {
254 self.src.seek(SeekFrom::Start(frame_start))?;
259 Err(DemuxerError::SeekError)
261 Err(DemuxerError::NotPossible)
264 fn get_duration(&self) -> u64 { self.tot_samples * 1000 / u64::from(self.srate) }
267 impl<'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 }
273 pub struct FLACDemuxerCreator { }
275 impl 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))
279 fn get_name(&self) -> &'static str { "flac" }
288 fn test_flac_demux() {
289 let mut file = File::open("assets/LLaudio/luckynight.flac").unwrap();
290 let mut fr = FileReader::new_read(&mut file);
291 let mut br = ByteReader::new(&mut fr);
292 let mut dmx = FLACDemuxer::new(&mut br);
293 let mut sm = StreamManager::new();
294 let mut si = SeekIndex::new();
295 dmx.open(&mut sm, &mut si).unwrap();
297 let pktres = dmx.get_frame(&mut sm);
298 if let Err(e) = pktres {
299 if (e as i32) == (DemuxerError::EOF as i32) { break; }
302 let pkt = pktres.unwrap();
303 println!("Got {}", pkt);
308 const CRC16_TABLE: [u16; 256] = [
309 0x0000, 0x8005, 0x800F, 0x000A, 0x801B, 0x001E, 0x0014, 0x8011,
310 0x8033, 0x0036, 0x003C, 0x8039, 0x0028, 0x802D, 0x8027, 0x0022,
311 0x8063, 0x0066, 0x006C, 0x8069, 0x0078, 0x807D, 0x8077, 0x0072,
312 0x0050, 0x8055, 0x805F, 0x005A, 0x804B, 0x004E, 0x0044, 0x8041,
313 0x80C3, 0x00C6, 0x00CC, 0x80C9, 0x00D8, 0x80DD, 0x80D7, 0x00D2,
314 0x00F0, 0x80F5, 0x80FF, 0x00FA, 0x80EB, 0x00EE, 0x00E4, 0x80E1,
315 0x00A0, 0x80A5, 0x80AF, 0x00AA, 0x80BB, 0x00BE, 0x00B4, 0x80B1,
316 0x8093, 0x0096, 0x009C, 0x8099, 0x0088, 0x808D, 0x8087, 0x0082,
317 0x8183, 0x0186, 0x018C, 0x8189, 0x0198, 0x819D, 0x8197, 0x0192,
318 0x01B0, 0x81B5, 0x81BF, 0x01BA, 0x81AB, 0x01AE, 0x01A4, 0x81A1,
319 0x01E0, 0x81E5, 0x81EF, 0x01EA, 0x81FB, 0x01FE, 0x01F4, 0x81F1,
320 0x81D3, 0x01D6, 0x01DC, 0x81D9, 0x01C8, 0x81CD, 0x81C7, 0x01C2,
321 0x0140, 0x8145, 0x814F, 0x014A, 0x815B, 0x015E, 0x0154, 0x8151,
322 0x8173, 0x0176, 0x017C, 0x8179, 0x0168, 0x816D, 0x8167, 0x0162,
323 0x8123, 0x0126, 0x012C, 0x8129, 0x0138, 0x813D, 0x8137, 0x0132,
324 0x0110, 0x8115, 0x811F, 0x011A, 0x810B, 0x010E, 0x0104, 0x8101,
325 0x8303, 0x0306, 0x030C, 0x8309, 0x0318, 0x831D, 0x8317, 0x0312,
326 0x0330, 0x8335, 0x833F, 0x033A, 0x832B, 0x032E, 0x0324, 0x8321,
327 0x0360, 0x8365, 0x836F, 0x036A, 0x837B, 0x037E, 0x0374, 0x8371,
328 0x8353, 0x0356, 0x035C, 0x8359, 0x0348, 0x834D, 0x8347, 0x0342,
329 0x03C0, 0x83C5, 0x83CF, 0x03CA, 0x83DB, 0x03DE, 0x03D4, 0x83D1,
330 0x83F3, 0x03F6, 0x03FC, 0x83F9, 0x03E8, 0x83ED, 0x83E7, 0x03E2,
331 0x83A3, 0x03A6, 0x03AC, 0x83A9, 0x03B8, 0x83BD, 0x83B7, 0x03B2,
332 0x0390, 0x8395, 0x839F, 0x039A, 0x838B, 0x038E, 0x0384, 0x8381,
333 0x0280, 0x8285, 0x828F, 0x028A, 0x829B, 0x029E, 0x0294, 0x8291,
334 0x82B3, 0x02B6, 0x02BC, 0x82B9, 0x02A8, 0x82AD, 0x82A7, 0x02A2,
335 0x82E3, 0x02E6, 0x02EC, 0x82E9, 0x02F8, 0x82FD, 0x82F7, 0x02F2,
336 0x02D0, 0x82D5, 0x82DF, 0x02DA, 0x82CB, 0x02CE, 0x02C4, 0x82C1,
337 0x8243, 0x0246, 0x024C, 0x8249, 0x0258, 0x825D, 0x8257, 0x0252,
338 0x0270, 0x8275, 0x827F, 0x027A, 0x826B, 0x026E, 0x0264, 0x8261,
339 0x0220, 0x8225, 0x822F, 0x022A, 0x823B, 0x023E, 0x0234, 0x8231,
340 0x8213, 0x0216, 0x021C, 0x8219, 0x0208, 0x820D, 0x8207, 0x0202