1 use nihav_core::frame::*;
2 use nihav_core::demuxers::*;
11 struct APEDemuxer<'a> {
12 src: &'a mut ByteReader<'a>,
21 impl<'a> APEDemuxer<'a> {
22 fn new(io: &'a mut ByteReader<'a>) -> Self {
35 impl<'a> DemuxCore<'a> for APEDemuxer<'a> {
36 fn open(&mut self, strmgr: &mut StreamManager, seek_index: &mut SeekIndex) -> DemuxerResult<()> {
37 let src = &mut self.src;
39 let tag = src.read_tag()?;
40 validate!(&tag == b"MAC ");
41 let version = src.read_u16le()?;
42 validate!((3800..=3990).contains(&version));
56 let descriptor_len = src.read_u32le()? as usize;
57 let header_len = src.read_u32le()? as usize;
58 validate!(header_len == 24);
59 seektab_len = src.read_u32le()? as usize;
60 let _wavheader_len = src.read_u32le()? as usize;
61 let _audio_len = src.read_u64le()?;
62 _wavtail_len = src.read_u32le()? as usize;
63 src.read_skip(16)?; // unpacked data MD5
64 if descriptor_len > 52 {
65 src.read_skip(descriptor_len - 52)?;
68 compr_type = src.read_u16le()?;
69 flags = src.read_u16le()?;
70 blocksperframe = src.read_u32le()?;
71 finalblocks = src.read_u32le()?;
72 nframes = src.read_u32le()? as usize;
73 bits = src.read_u16le()?;
74 channels = src.read_u16le()?;
75 srate = src.read_u32le()?;
77 compr_type = src.read_u16le()?;
78 flags = src.read_u16le()?;
79 channels = src.read_u16le()?;
80 srate = src.read_u32le()?;
82 let wavheader_len = src.read_u32le()? as usize;
83 _wavtail_len = src.read_u32le()? as usize;
84 nframes = src.read_u32le()? as usize;
85 finalblocks = src.read_u32le()?;
86 if (flags & 0x04) != 0 {
87 src.read_u32le()?; // peak level
89 if (flags & 0x10) != 0 {
90 seektab_len = src.read_u32le()? as usize * 4;
92 seektab_len = nframes * 4;
95 if (flags & 0x01) != 0 {
97 } else if (flags & 0x08) != 0 {
103 blocksperframe = 9216 * if version >= 3950 {
105 } else if (version >= 3900) || ((version >= 3800) && (compr_type >= 4000)) {
111 if (flags & 0x20) == 0 {
112 src.read_skip(wavheader_len)?;
115 validate!(srate > 0);
116 validate!(channels > 0 && channels < 256);
117 validate!(bits > 0 && bits <= 32);
118 validate!(nframes > 0 && nframes < (1 << 28));
119 validate!(seektab_len >= nframes * 4);
121 self.frames = Vec::with_capacity(nframes);
122 self.normal_blocks = blocksperframe;
123 self.last_blocks = finalblocks;
124 self.duration = (((nframes - 1) as u64) * u64::from(blocksperframe) + u64::from(finalblocks)) * 1000 / u64::from(srate);
126 seek_index.mode = SeekIndexMode::Present;
127 let first_off = src.peek_u32le()?;
128 validate!(u64::from(first_off) >= src.tell() + ((nframes * 4) as u64));
129 let mut last_off = first_off - 1;
130 for i in 0..nframes {
131 let off = src.read_u32le()?;
132 validate!(off > last_off);
133 let diff = (off - first_off) & 3;
134 self.frames.push(Frame {
137 bits_off: (diff as u8) * 8,
142 let time = (i as u64) * u64::from(blocksperframe) * 1000 / u64::from(srate);
143 seek_index.add_entry(0, SeekEntry { time, pts: i as u64, pos: i as u64 });
146 for frame in self.frames.iter_mut() {
147 let bits = src.read_byte()?;
148 validate!(bits < 32);
149 frame.bits_off += bits;
152 src.seek(SeekFrom::End(0))?;
153 let fsize = src.tell();
154 validate!(fsize > u64::from(self.frames[0].off));
155 self.truncated = u64::from(self.frames[self.frames.len() - 1].off) >= fsize;
157 let mut valid_frames = self.frames.len();
158 for frame in self.frames.iter_mut().rev() {
159 if u64::from(frame.off) >= fsize {
163 self.frames.truncate(valid_frames);
164 validate!(!self.frames.is_empty());
165 self.truncated = true;
167 let mut last_off = fsize as u32;
168 for frame in self.frames.iter_mut().rev() {
169 frame.size = last_off - frame.off;
170 last_off = frame.off + (if frame.bits_off > 0 { 4 } else { 0 });
173 let mut hdr = vec![0u8; 16];
174 write_u16le(&mut hdr[0..], version)?;
175 write_u16le(&mut hdr[2..], compr_type)?;
176 write_u16le(&mut hdr[4..], flags)?;
177 hdr[6] = channels as u8;
179 write_u32le(&mut hdr[8..], srate)?;
180 write_u32le(&mut hdr[12..], blocksperframe)?;
182 let ahdr = NAAudioInfo::new(srate, channels as u8, SND_S16P_FORMAT, 1);
183 let ainfo = NACodecInfo::new("ape", NACodecTypeInfo::Audio(ahdr), Some(hdr));
184 strmgr.add_stream(NAStream::new(StreamType::Audio, 0, ainfo, blocksperframe, srate, nframes as u64)).unwrap();
190 fn get_frame(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<NAPacket> {
191 if self.cur_frame >= self.frames.len() {
192 return Err(DemuxerError::EOF);
195 let size = self.frames[self.cur_frame].size as usize;
196 let off = self.frames[self.cur_frame].off;
197 let bits = self.frames[self.cur_frame].bits_off;
198 let nblocks = if (self.cur_frame < self.frames.len() - 1) || self.truncated { self.normal_blocks } else { self.last_blocks };
200 self.src.seek(SeekFrom::Start(off.into()))?;
202 let mut buf = vec![0u8; size + 8];
203 write_u32le(&mut buf[0..], nblocks)?;
205 self.src.read_buf(&mut buf[8..])?;
207 let stream = strmgr.get_stream(0).unwrap();
208 let ts = stream.make_ts(Some(self.cur_frame as u64), None, None);
209 let pkt = NAPacket::new(stream, ts, true, buf);
215 fn seek(&mut self, time: NATimePoint, seek_index: &SeekIndex) -> DemuxerResult<()> {
216 let ret = seek_index.find_pos(time);
218 return Err(DemuxerError::SeekError);
220 let seek_info = ret.unwrap();
221 self.cur_frame = seek_info.pts as usize;
222 if self.cur_frame >= self.frames.len() {
223 return Err(DemuxerError::SeekError);
228 fn get_duration(&self) -> u64 { self.duration }
231 impl<'a> NAOptionHandler for APEDemuxer<'a> {
232 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
233 fn set_options(&mut self, _options: &[NAOption]) { }
234 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
237 pub struct APEDemuxerCreator { }
239 impl DemuxerCreator for APEDemuxerCreator {
240 fn new_demuxer<'a>(&self, br: &'a mut ByteReader<'a>) -> Box<dyn DemuxCore<'a> + 'a> {
241 Box::new(APEDemuxer::new(br))
243 fn get_name(&self) -> &'static str { "ape" }
252 fn test_ape_demux() {
253 // sample: https://samples.mplayerhq.hu/A-codecs/lossless/luckynight.ape
254 let mut file = File::open("assets/LLaudio/ape/luckynight.ape").unwrap();
255 let mut fr = FileReader::new_read(&mut file);
256 let mut br = ByteReader::new(&mut fr);
257 let mut dmx = APEDemuxer::new(&mut br);
258 let mut sm = StreamManager::new();
259 let mut si = SeekIndex::new();
260 dmx.open(&mut sm, &mut si).unwrap();
262 let pktres = dmx.get_frame(&mut sm);
263 if let Err(e) = pktres {
264 if (e as i32) == (DemuxerError::EOF as i32) { break; }
267 let pkt = pktres.unwrap();
268 println!("Got {}", pkt);