1 use nihav_core::frame::*;
2 use nihav_core::demuxers::*;
4 struct FLACDemuxer<'a> {
5 src: &'a mut ByteReader<'a>,
17 impl<'a> FLACDemuxer<'a> {
18 fn new(io: &'a mut ByteReader<'a>) -> Self {
34 impl<'a> RawDemuxCore<'a> for FLACDemuxer<'a> {
35 fn open(&mut self, strmgr: &mut StreamManager, seek_index: &mut SeekIndex) -> DemuxerResult<()> {
36 let tag = self.src.read_tag()?;
37 validate!(&tag == b"fLaC");
38 let mut streaminfo: Vec<u8> = Vec::new();
40 let mut channels = 0u8;
42 let id1 = self.src.read_byte()?;
43 let len = self.src.read_u24be()? as usize;
49 streaminfo = vec![0u8; len];
50 self.src.read_buf(&mut streaminfo)?;
51 let min_bs = read_u16be(&streaminfo[0..])?;
52 let max_bs = read_u16be(&streaminfo[2..])?;
54 self.blk_samples = max_bs;
56 self.min_samples = min_bs;
57 self.min_size = read_u24be(&streaminfo[4..])? as usize;
58 self.max_size = read_u24be(&streaminfo[7..])? as usize;
59 let word = read_u24be(&streaminfo[10..])?;
61 channels = (((word >> 1) & 7) + 1) as u8;
62 self.tot_samples = (u64::from(streaminfo[13] & 0xF) << 32) | u64::from(read_u32be(&streaminfo[14..])?);
65 validate!((len % 18) == 0);
66 seek_index.mode = SeekIndexMode::Present;
67 for _ in 0..len / 18 {
68 let sample = self.src.read_u64be()?;
69 let offset = self.src.read_u64be()?;
70 let _nsamps = self.src.read_u16be()?;
71 let time = sample * 1000 / u64::from(srate.max(1000));
72 seek_index.add_entry(0, SeekEntry { time, pts: sample, pos: offset });
75 _ => self.src.read_skip(len)?,
78 if (id1 & 0x80) != 0 {
82 if seek_index.mode != SeekIndexMode::Present {
83 seek_index.mode = SeekIndexMode::Automatic;
84 self.build_index = true;
86 self.build_index = false;
88 self.data_start = self.src.tell();
89 validate!(srate != 0);
92 let base = if self.blk_samples != 0 { u32::from(self.blk_samples) } else { 1 };
93 let ahdr = NAAudioInfo::new(srate, channels as u8, SND_S16P_FORMAT, base as usize);
94 let ainfo = NACodecInfo::new("flac", NACodecTypeInfo::Audio(ahdr), Some(streaminfo));
95 strmgr.add_stream(NAStream::new(StreamType::Audio, 0, ainfo, base, srate, 0)).unwrap();
99 fn get_data(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<NARawData> {
100 let stream = strmgr.get_stream(0).unwrap();
101 let mut buf = vec![0; 8192];
102 let size = self.src.read_buf_some(&mut buf)?;
104 Ok(NARawData::new(stream, buf))
106 fn seek(&mut self, time: NATimePoint, seek_index: &SeekIndex) -> DemuxerResult<()> {
107 if seek_index.mode == SeekIndexMode::Present {
108 let ret = seek_index.find_pos(time);
110 return Err(DemuxerError::SeekError);
112 let seek_info = ret.unwrap();
113 self.cur_samples = seek_info.pts;
114 self.src.seek(SeekFrom::Start(self.data_start + seek_info.pos))?;
117 Err(DemuxerError::NotPossible)
120 fn get_duration(&self) -> u64 { self.tot_samples * 1000 / u64::from(self.srate) }
123 impl<'a> NAOptionHandler for FLACDemuxer<'a> {
124 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
125 fn set_options(&mut self, _options: &[NAOption]) { }
126 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
129 pub struct FLACDemuxerCreator { }
131 impl RawDemuxerCreator for FLACDemuxerCreator {
132 fn new_demuxer<'a>(&self, br: &'a mut ByteReader<'a>) -> Box<dyn RawDemuxCore<'a> + 'a> {
133 Box::new(FLACDemuxer::new(br))
135 fn get_name(&self) -> &'static str { "flac" }
136 fn check_format(&self, br: &mut ByteReader) -> bool {
137 if br.seek(SeekFrom::Start(0)).is_err() {
140 if let Ok([b'f', b'L', b'a', b'C']) = br.read_tag() {
150 use nihav_core::codecs::*;
152 use crate::llaudio_register_all_packetisers;
156 fn test_flac_raw_demux() {
157 let mut file = File::open("assets/LLaudio/luckynight.flac").unwrap();
158 let mut fr = FileReader::new_read(&mut file);
159 let mut br = ByteReader::new(&mut fr);
160 let mut dmx = FLACDemuxer::new(&mut br);
161 let mut sm = StreamManager::new();
162 let mut si = SeekIndex::new();
163 dmx.open(&mut sm, &mut si).unwrap();
164 let stream = sm.get_stream(0).unwrap();
165 let mut pkt_reg = RegisteredPacketisers::new();
166 llaudio_register_all_packetisers(&mut pkt_reg);
167 let creator = pkt_reg.find_packetiser("flac").unwrap();
168 let mut pkts = (creator)();
169 let mut tot_size = 0;
170 while let Ok(pkt) = dmx.get_data(&mut sm) {
171 tot_size += pkt.get_buffer().len();
172 pkts.add_data(&pkt.get_buffer());
174 let mut tot_size2 = 0;
176 while let Ok(Some(pkt)) = pkts.get_packet(stream.clone()) {
177 tot_size2 += pkt.get_buffer().len();
180 assert_eq!(npkts, 579);
181 assert_eq!(tot_size, tot_size2);