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>,
27 fn 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
37 impl<'a> FLACDemuxer<'a> {
38 fn new(io: &'a mut ByteReader<'a>) -> Self {
49 known_frames: Vec::new(),
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);
58 let frame_start = self.src.tell();
60 let byte = self.src.read_byte()?;
62 crc = update_crc16(crc, byte);
64 if self.frame_hdr == 0 {
65 self.frame_hdr = read_u32be(&buf).unwrap_or(0);
67 let mut ref_crc = self.src.read_u16be()?;
69 let byte = self.src.read_byte()?;
70 let old_byte = (ref_crc >> 8) as u8;
72 ref_crc = (ref_crc << 8) | u16::from(byte);
73 crc = update_crc16(crc, old_byte);
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)) {
77 buf.push((ref_crc >> 8) as u8);
78 buf.push(ref_crc as u8);
82 if (self.max_size > 0) && (buf.len() > self.max_size) {
83 return Err(DemuxerError::InvalidData);
85 if buf.len() > (1 << 23) {
86 return Err(DemuxerError::InvalidData);
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)
97 while idx < buf.len() && (buf[idx] & 0x80) != 0 {
101 let bsz_id = buf[2] >> 4;
102 let blksamps = match bsz_id {
103 0 => return Err(DemuxerError::InvalidData),
105 2..=5 => 576 << (bsz_id - 2),
107 validate!(idx < buf.len());
108 u64::from(buf[idx]) + 1
111 validate!(idx + 2 <= buf.len());
112 u64::from(buf[idx]) * 256 + u64::from(buf[idx + 1]) + 1
114 _ => 256 << (bsz_id - 8),
116 let pts = u64::from(read_utf8(&buf[4..])?);
118 validate!(idx < buf.len());
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 });
129 self.cur_samples += duration;
131 Ok((buf, pts, duration))
135 fn update_crc16(crc: u16, byte: u8) -> u16 {
136 (crc << 8) ^ CRC16_TABLE[(((crc >> 8) as u8) ^ byte) as usize]
139 fn read_utf8(src: &[u8]) -> DemuxerResult<u32> {
140 if (src[0] & 0x80) == 0 {
141 return Ok(u32::from(src[0]));
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);
153 impl<'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;
161 let id1 = self.src.read_byte()?;
162 let len = self.src.read_u24be()? as usize;
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;
175 self.min_samples = min_bs;
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..])?;
180 channels = (((word >> 1) & 7) + 1) as u8;
181 self.tot_samples = (u64::from(streaminfo[13] & 0xF) << 32) | u64::from(read_u32be(&streaminfo[14..])?);
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 });
194 _ => self.src.read_skip(len)?,
197 if (id1 & 0x80) != 0 {
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;
208 self.build_index = false;
210 self.data_start = self.src.tell();
211 validate!(srate != 0);
214 let base = if self.blk_samples != 0 { u32::from(self.blk_samples) } else { 1 };
215 let ahdr = NAAudioInfo::new(srate, channels as u8, SND_S16P_FORMAT, base as usize);
216 let ainfo = NACodecInfo::new("flac", NACodecTypeInfo::Audio(ahdr), Some(streaminfo));
217 strmgr.add_stream(NAStream::new(StreamType::Audio, 0, ainfo, base, srate, 0)).unwrap();
221 fn get_frame(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<NAPacket> {
222 let (buf, pts, duration) = self.read_frame()?;
224 let stream = strmgr.get_stream(0).unwrap();
225 let ts = stream.make_ts(Some(pts), None, Some(duration));
226 let pkt = NAPacket::new(stream, ts, true, buf);
230 fn seek(&mut self, time: NATimePoint, seek_index: &SeekIndex) -> DemuxerResult<()> {
231 if seek_index.mode == SeekIndexMode::Present {
232 let ret = seek_index.find_pos(time);
234 return Err(DemuxerError::SeekError);
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))?;
240 } else if let NATimePoint::Milliseconds(ms) = time {
241 let samppos = NATimeInfo::time_to_ts(ms, 1000, 1, self.srate);
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;
251 let startinfo = FrameSeekInfo { off: self.data_start, size: 0, samplepos: 0, sampleend: 0 };
252 let lentry = self.known_frames.last().unwrap_or(&startinfo);
254 self.src.seek(SeekFrom::Start(lentry.off + lentry.size))?;
255 self.cur_samples = lentry.sampleend;
257 let frame_start = self.src.tell();
258 let ret = self.read_frame();
260 return Err(DemuxerError::SeekError);
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);
267 if self.cur_samples <= samppos && self.cur_samples + duration >= samppos {
268 self.src.seek(SeekFrom::Start(frame_start))?;
273 Err(DemuxerError::SeekError)
275 Err(DemuxerError::NotPossible)
278 fn get_duration(&self) -> u64 { self.tot_samples * 1000 / u64::from(self.srate) }
281 impl<'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 }
287 pub struct FLACDemuxerCreator { }
289 impl 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))
293 fn get_name(&self) -> &'static str { "flac" }
302 fn test_flac_demux() {
303 // sample: https://samples.mplayerhq.hu/A-codecs/lossless/luckynight.flac
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();
312 let pktres = dmx.get_frame(&mut sm);
313 if let Err(e) = pktres {
314 if (e as i32) == (DemuxerError::EOF as i32) { break; }
317 let pkt = pktres.unwrap();
318 println!("Got {}", pkt);
323 const 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