rmmux: improve the audio packet timestamp handling
[nihav.git] / nihav-realmedia / src / muxers / rmvb / audiostream.rs
CommitLineData
9dc1fb4b
KS
1use nihav_core::frame::*;
2use nihav_core::muxers::*;
3use super::RMStreamWriter;
4
5// fourcc, codec name, interleaver, version
6static AUDIO_CODEC_REGISTRY: &[(&[u8;4], &str, &[u8;4], u8)] = &[
7 (b"lpcJ", "ra14.4", b"Int0", 3),
8 (b"28_8", "ra28.8", b"Int4", 4),
9 (b"cook", "cook", b"genr", 5),
10 (b"dnet", "ac3", b"Int0", 4),
11 (b"sipr", "sipro", b"sipr", 4),
12 (b"atrc", "atrac3", b"genr", 5),
13 (b"LSD:", "ralf", b"Int0", 6),
14 (b"raac", "aac", b"vbrs", 5),
15 (b"racp", "aac", b"vbrf", 5),
16];
17
18struct InterleaveParams {
19 block_size: usize,
20 factor: usize,
21 frames_per_blk: usize,
22}
23
24trait Interleaver {
25 fn get_flavor(&self) -> usize;
26 fn get_block_size(&self) -> usize;
27 fn get_factor(&self) -> usize;
28 fn get_frames_per_block(&self) -> usize;
c5963b17 29 fn is_empty(&self) -> bool;
9dc1fb4b
KS
30 fn add_packet(&mut self, src: &[u8]) -> bool;
31 fn get_packet(&mut self) -> Option<(Vec<u8>, bool)>;
32 fn flush(&mut self);
33
34 fn get_frame_size(&self) -> usize { self.get_block_size() / self.get_frames_per_block() }
35}
36
37struct NoInterleaver {
38 frame_size: usize,
39 pkt: Option<Vec<u8>>,
40}
41impl Interleaver for NoInterleaver {
42 fn get_flavor(&self) -> usize { 0 }
43 fn get_block_size(&self) -> usize { self.frame_size }
44 fn get_factor(&self) -> usize { 1 }
45 fn get_frames_per_block(&self) -> usize { 1 }
c5963b17 46 fn is_empty(&self) -> bool { self.pkt.is_none() }
9dc1fb4b
KS
47 fn add_packet(&mut self, src: &[u8]) -> bool {
48 if self.pkt.is_none() {
49 self.pkt = Some(src.to_vec());
50 true
51 } else {
52 false
53 }
54 }
55 fn get_packet(&mut self) -> Option<(Vec<u8>, bool)> {
56 let mut ret = None;
57 std::mem::swap(&mut self.pkt, &mut ret);
58 if let Some(pkt) = ret {
59 Some((pkt, true))
60 } else {
61 None
62 }
63 }
64 fn flush(&mut self) {}
65}
66
67struct Int4Interleaver {
68 flavor: usize,
69 factor: usize,
70 frame_size: usize,
71 block_size: usize,
72 fpb: usize,
73 cur_frame: usize,
74 rd_block: usize,
75 buf: Vec<u8>,
76 map: Vec<usize>,
77}
78impl Int4Interleaver {
79 fn new(frame_size: usize) -> MuxerResult<Self> {
80 let params = RA_28_8_INTERLEAVE_PARAMS;
81 for (flavor, entry) in params.iter().enumerate() {
82 if entry.block_size / entry.frames_per_blk == frame_size {
83 let full_size = entry.frames_per_blk * entry.factor;
84 let mut map = vec![0; full_size];
85 for i in 0..full_size {
86 let fval = i * entry.factor;
87 let mapped = (fval % full_size) + fval / full_size;
88 map[mapped] = i;
89 }
90
91 return Ok(Self {
92 flavor,
93 frame_size,
94 map,
95 factor: entry.factor,
96 block_size: entry.block_size,
97 fpb: entry.frames_per_blk,
98 cur_frame: 0,
99 rd_block: 0,
100 buf: vec![0; entry.block_size * entry.factor],
101 });
102 }
103 }
104 Err(MuxerError::UnsupportedFormat)
105 }
106}
107impl Interleaver for Int4Interleaver {
108 fn get_flavor(&self) -> usize { self.flavor }
109 fn get_block_size(&self) -> usize { self.block_size }
110 fn get_factor(&self) -> usize { self.factor }
111 fn get_frames_per_block(&self) -> usize { self.fpb }
c5963b17 112 fn is_empty(&self) -> bool { self.cur_frame == 0 }
9dc1fb4b
KS
113 fn add_packet(&mut self, src: &[u8]) -> bool {
114 if self.cur_frame == self.factor * self.fpb {
115 return false;
116 }
117 let pos = self.map[self.cur_frame];
118 self.buf[pos * self.frame_size..][..self.frame_size].copy_from_slice(&src);
119 self.cur_frame += 1;
120 true
121 }
122 fn get_packet(&mut self) -> Option<(Vec<u8>, bool)> {
123 if self.cur_frame == self.factor * self.fpb {
124 let first = self.rd_block == 0;
125 let src = &self.buf[self.rd_block * self.block_size..][..self.block_size];
126 self.rd_block += 1;
127 if self.rd_block == self.factor {
128 self.rd_block = 0;
129 self.cur_frame = 0;
130 }
131 Some((src.to_vec(), first))
132 } else {
133 None
134 }
135 }
136 fn flush(&mut self) {
137 if self.cur_frame != 0 {
138 self.cur_frame = self.factor * self.fpb;
139 }
140 }
141}
142
143struct GenericInterleaver {
144 flavor: usize,
145 factor: usize,
146 frame_size: usize,
147 block_size: usize,
148 fpb: usize,
149 cur_frame: usize,
150 rd_block: usize,
151 buf: Vec<u8>,
152 map: Vec<usize>,
153}
154impl GenericInterleaver {
155 fn new(frame_size: usize, fcc: [u8; 4]) -> MuxerResult<Self> {
156 let params = match &fcc {
157 b"atrc" => ATRAC_INTERLEAVE_PARAMS,
158 b"cook" => COOK_INTERLEAVE_PARAMS,
159 b"sipr" => SIPRO_INTERLEAVE_PARAMS,
160 _ => return Err(MuxerError::UnsupportedFormat),
161 };
162 for (flavor, entry) in params.iter().enumerate() {
163 if entry.block_size / entry.frames_per_blk == frame_size {
164 let full_size = entry.frames_per_blk * entry.factor;
165 let mut map = vec![0; full_size];
166
167 let mut frm = 0;
168 let mut blk = 0;
169 let mut even = true;
170 for dst in map.iter_mut() {
171 let mapped = blk * entry.frames_per_blk + frm;
172 blk += 2;
173 if blk >= entry.factor {
174 if even {
175 blk = 1;
176 } else {
177 blk = 0;
178 frm += 1;
179 }
180 even = !even;
181 }
182 *dst = mapped;
183 }
184
185 return Ok(Self {
186 flavor,
187 frame_size,
188 map,
189 factor: entry.factor,
190 block_size: entry.block_size,
191 fpb: entry.frames_per_blk,
192 cur_frame: 0,
193 rd_block: 0,
194 buf: vec![0; entry.block_size * entry.factor],
195 });
196 }
197 }
198 Err(MuxerError::UnsupportedFormat)
199 }
200}
201impl Interleaver for GenericInterleaver {
202 fn get_flavor(&self) -> usize { self.flavor }
203 fn get_block_size(&self) -> usize { self.block_size }
204 fn get_factor(&self) -> usize { self.factor }
205 fn get_frames_per_block(&self) -> usize { self.fpb }
c5963b17 206 fn is_empty(&self) -> bool { self.cur_frame == 0 }
9dc1fb4b
KS
207 fn add_packet(&mut self, src: &[u8]) -> bool {
208 if self.cur_frame == self.factor * self.fpb {
209 return false;
210 }
211 let pos = self.map[self.cur_frame];
212 self.buf[pos * self.frame_size..][..self.frame_size].copy_from_slice(&src);
213 self.cur_frame += 1;
214 true
215 }
216 fn get_packet(&mut self) -> Option<(Vec<u8>, bool)> {
217 if self.cur_frame == self.factor * self.fpb {
218 let first = self.rd_block == 0;
219 let src = &self.buf[self.rd_block * self.block_size..][..self.block_size];
220 self.rd_block += 1;
221 if self.rd_block == self.factor {
222 self.rd_block = 0;
223 self.cur_frame = 0;
224 }
225 Some((src.to_vec(), first))
226 } else {
227 None
228 }
229 }
230 fn flush(&mut self) {
231 if self.cur_frame != 0 {
232 self.cur_frame = self.factor * self.fpb;
233 }
234 }
235}
236
237struct SiproInterleaver {
238 block_size: usize,
239 factor: usize,
240 flavor: usize,
241 buf: Vec<u8>,
242 wr_pos: usize,
243 rd_pos: usize,
244}
245impl SiproInterleaver {
246 fn new(mut frame_size: usize) -> MuxerResult<Self> {
247 if frame_size == 0 {
248 return Err(MuxerError::UnsupportedFormat);
249 }
250 while frame_size < 200 {
251 frame_size <<= 1;
252 }
253 for (flavor, entry) in SIPRO_INTERLEAVE_PARAMS.iter().enumerate() {
254 if entry.block_size == frame_size {
255 return Ok(Self {
256 block_size: entry.block_size,
257 factor: entry.factor,
258 flavor,
259 buf: vec![0; entry.block_size * entry.factor],
260 wr_pos: 0,
261 rd_pos: 0,
262 });
263 }
264 }
265 Err(MuxerError::UnsupportedFormat)
266 }
267}
268impl Interleaver for SiproInterleaver {
269 fn get_flavor(&self) -> usize { self.flavor }
270 fn get_block_size(&self) -> usize { self.block_size }
271 fn get_factor(&self) -> usize { self.factor }
272 fn get_frames_per_block(&self) -> usize { 1 }
c5963b17 273 fn is_empty(&self) -> bool { self.wr_pos == 0 }
9dc1fb4b
KS
274 fn add_packet(&mut self, src: &[u8]) -> bool {
275 if self.wr_pos < self.factor {
276 self.buf[self.wr_pos * self.block_size..][..self.block_size].copy_from_slice(src);
277 self.wr_pos += 1;
278 true
279 } else {
280 false
281 }
282 }
283 fn get_packet(&mut self) -> Option<(Vec<u8>, bool)> {
284 if self.wr_pos == self.factor {
285 let first = self.rd_pos == 0;
286 if self.rd_pos == 0 {
287 sipro_scramble(&mut self.buf, self.factor, self.block_size);
288 }
289 let ret = self.buf[self.rd_pos * self.block_size..][..self.block_size].to_vec();
290 self.rd_pos += 1;
291 if self.rd_pos == self.factor {
292 self.rd_pos = 0;
293 self.wr_pos = 0;
294 }
295 Some((ret, first))
296 } else {
297 None
298 }
299 }
300 fn flush(&mut self) {
301 if self.wr_pos != self.factor {
302 self.wr_pos = self.factor;
303 }
304 }
305}
306
307fn sipro_scramble(buf: &mut [u8], factor: usize, fsize: usize) {
308 let stride = factor * fsize * 2 / 96;
309 for &swap_pair in SIPRO_SWAPS.iter() {
310 let mut sidx = usize::from(swap_pair[0]) * stride;
311 let mut didx = usize::from(swap_pair[1]) * stride;
312 for _ in 0..stride {
313 let in0 = buf[sidx >> 1];
314 let in1 = buf[didx >> 1];
315 let nib0 = (in0 >> ((sidx & 1) * 4)) & 0xF;
316 let nib1 = (in1 >> ((didx & 1) * 4)) & 0xF;
317
318 buf[didx >> 1] = (nib0 << (4 * (didx & 1))) | (in1 & (0xF << (4 * (!didx & 1))));
319 buf[sidx >> 1] = (nib1 << (4 * (sidx & 1))) | (in0 & (0xF << (4 * (!sidx & 1))));
320
321 sidx += 1;
322 didx += 1;
323 }
324 }
325}
326
327struct AACInterleaver {
328 frame_size: usize,
329 data: Vec<u8>,
330 sizes: Vec<usize>,
331 full: bool,
332}
333impl AACInterleaver {
334 fn new(frame_size: usize) -> Self {
335 Self {
336 frame_size,
337 data: Vec::with_capacity(frame_size * 3 / 2),
338 sizes: Vec::with_capacity((frame_size / 128).max(8)),
339 full: false,
340 }
341 }
342}
343impl Interleaver for AACInterleaver {
344 fn get_flavor(&self) -> usize { 0 }
345 fn get_block_size(&self) -> usize { self.frame_size }
346 fn get_factor(&self) -> usize { 1 }
347 fn get_frames_per_block(&self) -> usize { 1 }
c5963b17 348 fn is_empty(&self) -> bool { self.data.is_empty() }
9dc1fb4b
KS
349 fn add_packet(&mut self, src: &[u8]) -> bool {
350 if !self.full {
351 self.data.extend_from_slice(src);
352 self.sizes.push(src.len());
353 if self.data.len() >= self.frame_size {
354 self.full = true;
355 }
356 true
357 } else {
358 false
359 }
360 }
361 fn get_packet(&mut self) -> Option<(Vec<u8>, bool)> {
362 if self.full {
363 let mut dst = Vec::with_capacity(self.frame_size);
364 let mut gw = GrowableMemoryWriter::new_write(&mut dst);
365 let mut bw = ByteWriter::new(&mut gw);
366 bw.write_u16be((self.sizes.len() * 16) as u16).unwrap();
367 for &pkt_size in self.sizes.iter() {
368 bw.write_u16be(pkt_size as u16).unwrap();
369 }
370 bw.write_buf(&self.data).unwrap();
371
372 self.data.clear();
373 self.sizes.clear();
374 self.full = false;
375
376 Some((dst, true))
377 } else {
378 None
379 }
380 }
381 fn flush(&mut self) {
382 if !self.sizes.is_empty() {
383 self.full = true;
384 }
385 }
386}
387
388struct InterleaveInfo {
389 fcc: [u8; 4],
390 il_fcc: [u8; 4],
391 block_size: usize,
392 frame_size: usize,
393 factor: usize,
394 flavor: usize,
395}
396
397struct AudioStreamWriter {
398 fcc: [u8; 4],
399 il_fcc: [u8; 4],
400 is_raw: bool,
401 version: u8,
402 header_pos: u64,
403 interleave: Box<dyn Interleaver>,
404 data_size: usize,
c5963b17
KS
405 first_time: u32,
406 last_time: u32,
407 size_in: usize,
408 size_out: usize,
9dc1fb4b
KS
409}
410
411impl RMStreamWriter for AudioStreamWriter {
412 fn write_header(&mut self, bw: &mut ByteWriter, astream: &NAStream) -> MuxerResult<()> {
413 self.header_pos = bw.tell();
414 if self.version < 6 {
415 bw.write_buf(b".ra\xFD")?;
416 bw.write_u16be(self.version.into())?;
417 }
418
419 let il_info = InterleaveInfo {
420 fcc: self.fcc,
421 il_fcc: self.il_fcc,
422 block_size: self.interleave.get_block_size(),
423 frame_size: self.interleave.get_frame_size(),
424 factor: self.interleave.get_factor(),
425 flavor: self.interleave.get_flavor(),
426 };
427
428 match self.version {
429 3 => write_aformat3(bw, astream, &il_info)?,
430 4 => write_aformat4(bw, astream, &il_info)?,
431 5 => write_aformat5(bw, astream, &il_info)?,
432 6 => write_lsd(bw, astream)?,
433 _ => unreachable!(),
434 }
435 Ok(())
436 }
c5963b17 437 fn queue_packet(&mut self, pkt: NAPacket, ms: u32) -> bool {
9dc1fb4b
KS
438 let src = pkt.get_buffer();
439 self.data_size += src.len();
440 let frame_size = self.interleave.get_frame_size();
c5963b17
KS
441 self.last_time = ms;
442 if self.interleave.is_empty() {
443 self.first_time = ms;
444 self.size_in = 0;
445 self.size_out = 0;
446 } else {
447 self.size_in += src.len() / frame_size;
448 }
9dc1fb4b
KS
449 if !self.is_raw {
450 let mut ret = false;
451 for frame in src.chunks(frame_size) {
452 ret = self.interleave.add_packet(frame);
453 }
454 ret
455 } else {
456 self.interleave.add_packet(&src)
457 }
458 }
c5963b17
KS
459 fn get_packet(&mut self) -> Option<(Vec<u8>, u32, bool)> {
460 if let Some((pkt, first)) = self.interleave.get_packet() {
461 let time_add = if self.last_time > self.first_time && self.size_in > 0 {
462 let size = pkt.len();
463 let time_add = (self.size_out * ((self.last_time - self.first_time) as usize) / self.size_in) as u32;
464 self.size_out += size / self.interleave.get_frame_size();
465 time_add
466 } else {
467 0
468 };
469 Some((pkt, self.first_time + time_add, first))
470 } else {
471 None
472 }
473 }
9dc1fb4b
KS
474 fn flush(&mut self) { self.interleave.flush() }
475 fn finish(&mut self, bw: &mut ByteWriter) -> MuxerResult<()> {
476 let cur_pos = bw.tell();
477 match self.version {
478 3 => {
479 bw.seek(SeekFrom::Start(self.header_pos + 18))?;
480 bw.write_u32be(self.data_size as u32)?;
481 },
482 4 | 5 => {
483 bw.seek(SeekFrom::Start(self.header_pos + 12))?;
484 bw.write_u32be(self.data_size/*+header_size*/ as u32)?;
485 bw.seek(SeekFrom::Current(12))?;
486 bw.write_u32be(self.data_size as u32)?;
487 },
488 6 => unimplemented!(),
489 _ => unreachable!(),
490 };
491 bw.seek(SeekFrom::Start(cur_pos))?;
492 Ok(())
493 }
494}
495
496fn write_audio_metadata(bw: &mut ByteWriter) -> MuxerResult<()> {
497 bw.write_byte(0)?; // title_string_length
498 bw.write_byte(0)?; // author_string_length
499 bw.write_byte(0)?; // copyright_string_length
500 bw.write_byte(0)?; // user_string_length
501 Ok(())
502}
503
504fn write_aformat3(bw: &mut ByteWriter, _stream: &NAStream, il_info: &InterleaveInfo) -> MuxerResult<()> {
505 let start = bw.tell();
506 bw.write_u16be(0)?; // header_bytes
507 bw.write_u16be(il_info.flavor as u16)?;
508 bw.write_u32be(il_info.frame_size as u32)?; // granularity
509 bw.write_u32be(0)?; // bytes per minute
510 bw.write_u32be(0)?; // total bytes
511 write_audio_metadata(bw)?;
512 bw.write_byte(0)?; //can_copy
513 bw.write_byte(4)?; // FCC length
514 bw.write_buf(&il_info.fcc)?;
515 let end = bw.tell();
516 bw.seek(SeekFrom::Start(start))?;
517 bw.write_u16be((end - start - 2) as u16)?;
518 bw.seek(SeekFrom::Start(end))?;
519
520 Ok(())
521}
522
523fn write_aformat4(bw: &mut ByteWriter, stream: &NAStream, il_info: &InterleaveInfo) -> MuxerResult<()> {
524 let info = stream.get_info().get_properties().get_audio_info().unwrap();
525
526 bw.write_u16be(0)?;
527 let start = bw.tell();
528 bw.write_buf(b".ra4")?;
529 bw.write_u32be(0)?; // data size
530 bw.write_u16be(4)?; // version
531 bw.write_u16be(0)?; // revision
532 bw.write_u16be(0)?; // header_bytes
533 bw.write_u16be(il_info.flavor as u16)?;
534 bw.write_u32be(il_info.frame_size as u32)?; // granularity
535 bw.write_u32be(0)?; // total bytes
536 bw.write_u32be(0)?; // bytes_per_minute
537 bw.write_u32be(0)?; // bytes_per_minute2
538 bw.write_u16be(il_info.factor as u16)?;
539 bw.write_u16be(il_info.block_size as u16)?;
540 bw.write_u16be(0)?; // user data
541 bw.write_u32be(info.sample_rate)?; // sample rate
542 bw.write_u32be(info.format.bits.into())?; // sample size
543 bw.write_u16be(info.channels.into())?; // num channels
544 bw.write_byte(4)?; // ileave ID len
545 bw.write_buf(&il_info.il_fcc)?;
546 bw.write_byte(4)?; // codec ID len
547 bw.write_buf(&il_info.fcc)?;
548 bw.write_byte(if &il_info.il_fcc == b"Int0" { 0 } else { 1 })?;
549 bw.write_byte(7)?; // can_copy
550 bw.write_byte(0)?; // stream_type
551 write_audio_metadata(bw)?;
552 let end = bw.tell();
553 bw.seek(SeekFrom::Start(start + 12))?;
554 bw.write_u16be((end - start - 4) as u16)?;
555 bw.seek(SeekFrom::Start(end))?;
556
557 Ok(())
558}
559
560fn write_aformat5(bw: &mut ByteWriter, stream: &NAStream, il_info: &InterleaveInfo) -> MuxerResult<()> {
561 let info = stream.get_info().get_properties().get_audio_info().unwrap();
562
563 bw.write_u16be(0)?;
564 let start = bw.tell();
565 bw.write_buf(b".ra5")?;
566 bw.write_u32be(0)?; // data size
567 bw.write_u16be(5)?; // version
568 bw.write_u16be(0)?; // revision
569 bw.write_u16be(0)?; // header_bytes
570 bw.write_u16be(il_info.flavor as u16)?;
571 bw.write_u32be(il_info.block_size as u32)?; // granularity
572 bw.write_u32be(0)?; // total bytes
573 bw.write_u32be(0)?; // bytes_per_minute
574 bw.write_u32be(0)?; // bytes_per_minute2
575 bw.write_u16be(il_info.factor as u16)?;
576 bw.write_u16be(il_info.block_size as u16)?;
577 bw.write_u16be(il_info.frame_size as u16)?;
578 bw.write_u16be(0)?; // user data
579 bw.write_u32be(info.sample_rate)?; // sample rate
580 bw.write_u32be(info.sample_rate)?; // actual sample rate
581 bw.write_u32be(info.format.bits.into())?; // sample size
582 bw.write_u16be(info.channels.into())?; // num channels
583 bw.write_buf(&il_info.il_fcc)?;
584 bw.write_buf(&il_info.fcc)?;
585 bw.write_byte(if &il_info.il_fcc == b"Int0" { 0 } else { 1 })?;
586 bw.write_byte(7)?; // can_copy
587 bw.write_byte(0)?; // stream_type
588 bw.write_byte(0)?; // has_interleave_pattern
589 if let Some(edata) = stream.get_info().get_extradata() {
590 if !matches!(&il_info.fcc, b"raac" | b"racp") {
591 bw.write_u32be(edata.len() as u32)?;
592 bw.write_buf(&edata)?;
593 } else {
594 bw.write_u32be((edata.len() + 1) as u32)?;
595 bw.write_byte(2)?;
596 bw.write_buf(&edata)?;
597 }
598 } else {
599 bw.write_u32be(0)?;
600 }
601 let end = bw.tell();
602 bw.seek(SeekFrom::Start(start + 12))?;
603 bw.write_u16be((end - start - 4) as u16)?;
604 bw.seek(SeekFrom::Start(end))?;
605
606 Ok(())
607}
608
609fn write_lsd(bw: &mut ByteWriter, stream: &NAStream) -> MuxerResult<()> {
610 if let Some(edata) = stream.get_info().get_extradata() {
611 bw.write_buf(&edata)?;
612 }
613 Ok(())
614}
615
616fn create_interleaver(id: [u8; 4], fcc: [u8; 4], ainfo: NAAudioInfo) -> MuxerResult<Box<dyn Interleaver>> {
617 let frame_size = ainfo.block_len;
618 match &id {
619 b"Int0" => Ok(Box::new(NoInterleaver{ frame_size, pkt: None })),
620 b"Int4" => Ok(Box::new(Int4Interleaver::new(frame_size)?)),
621 b"sipr" => Ok(Box::new(SiproInterleaver::new(frame_size)?)),
622 b"genr" => Ok(Box::new(GenericInterleaver::new(frame_size, fcc)?)),
623 b"vbrs" | b"vbrf" => Ok(Box::new(AACInterleaver::new(1024))),
624 _ => unimplemented!(),
625 }
626}
627
628pub fn create_audio_stream(stream: &NAStream) -> MuxerResult<Box<dyn RMStreamWriter>> {
629 let info = stream.get_info();
630 let cname = info.get_name();
631 let mut fourcc = [0u8; 4];
632 let mut ileave = [0u8; 4];
633 let mut version = 0;
634 for &(fcc, name, ileaver, cversion) in AUDIO_CODEC_REGISTRY.iter() {
635 if name == cname {
636 fourcc = *fcc;
637 ileave = *ileaver;
638 version = cversion;
639 break;
640 }
641 }
642 if version > 0 {
643 let ainfo = info.get_properties().get_audio_info().unwrap();
644 Ok(Box::new(AudioStreamWriter {
645 fcc: fourcc,
646 il_fcc: ileave,
647 is_raw: &ileave == b"Int0",
648 version,
649 interleave: create_interleaver(ileave, fourcc, ainfo)?,
650 header_pos: 0,
651 data_size: 0,
c5963b17
KS
652 first_time: 0,
653 last_time: 0,
654 size_in: 0,
655 size_out: 0,
9dc1fb4b
KS
656 }))
657 } else {
658 Err(MuxerError::UnsupportedFormat)
659 }
660}
661
662const SIPRO_SWAPS: [[u8; 2]; 38] = [
663 [ 0, 63 ], [ 1, 22 ], [ 2, 44 ], [ 3, 90 ],
664 [ 5, 81 ], [ 7, 31 ], [ 8, 86 ], [ 9, 58 ],
665 [ 10, 36 ], [ 12, 68 ], [ 13, 39 ], [ 14, 73 ],
666 [ 15, 53 ], [ 16, 69 ], [ 17, 57 ], [ 19, 88 ],
667 [ 20, 34 ], [ 21, 71 ], [ 24, 46 ], [ 25, 94 ],
668 [ 26, 54 ], [ 28, 75 ], [ 29, 50 ], [ 32, 70 ],
669 [ 33, 92 ], [ 35, 74 ], [ 38, 85 ], [ 40, 56 ],
670 [ 42, 87 ], [ 43, 65 ], [ 45, 59 ], [ 48, 79 ],
671 [ 49, 93 ], [ 51, 89 ], [ 55, 95 ], [ 61, 76 ],
672 [ 67, 83 ], [ 77, 80 ]
673];
674
675const RA_28_8_INTERLEAVE_PARAMS: &[InterleaveParams] = &[
676 InterleaveParams { block_size: 228, factor: 12, frames_per_blk: 6 },
677];
678const SIPRO_INTERLEAVE_PARAMS: &[InterleaveParams] = &[
679 InterleaveParams { block_size: 232, factor: 6, frames_per_blk: 16 },
680 InterleaveParams { block_size: 304, factor: 6, frames_per_blk: 16 },
681 InterleaveParams { block_size: 296, factor: 6, frames_per_blk: 16 },
682 InterleaveParams { block_size: 320, factor: 6, frames_per_blk: 16 }
683];
684const ATRAC_INTERLEAVE_PARAMS: &[InterleaveParams] = &[
685 InterleaveParams { block_size: 768, factor: 20, frames_per_blk: 4 },
686 InterleaveParams { block_size: 1088, factor: 20, frames_per_blk: 4 },
687 InterleaveParams { block_size: 912, factor: 30, frames_per_blk: 3 },
688 InterleaveParams { block_size: 1152, factor: 30, frames_per_blk: 3 },
689 InterleaveParams { block_size: 1272, factor: 30, frames_per_blk: 3 },
690 InterleaveParams { block_size: 1024, factor: 30, frames_per_blk: 2 },
691 InterleaveParams { block_size: 768, factor: 10, frames_per_blk: 1 },
692 InterleaveParams { block_size: 1024, factor: 10, frames_per_blk: 1 }
693];
694const COOK_INTERLEAVE_PARAMS: &[InterleaveParams] = &[
695 InterleaveParams { block_size: 288, factor: 8, frames_per_blk: 9 },
696 InterleaveParams { block_size: 352, factor: 8, frames_per_blk: 11 },
697 InterleaveParams { block_size: 564, factor: 8, frames_per_blk: 12 },
698 InterleaveParams { block_size: 600, factor: 9, frames_per_blk: 10 },
699 InterleaveParams { block_size: 651, factor: 14, frames_per_blk: 7 },
700 InterleaveParams { block_size: 640, factor: 15, frames_per_blk: 5 },
701 InterleaveParams { block_size: 744, factor: 20, frames_per_blk: 4 },
702 InterleaveParams { block_size: 558, factor: 16, frames_per_blk: 6 },
703 InterleaveParams { block_size: 288, factor: 6, frames_per_blk: 12 },
704 InterleaveParams { block_size: 580, factor: 10, frames_per_blk: 10 },
705 InterleaveParams { block_size: 564, factor: 14, frames_per_blk: 6 },
706 InterleaveParams { block_size: 640, factor: 16, frames_per_blk: 5 },
707 InterleaveParams { block_size: 744, factor: 20, frames_per_blk: 4 },
708 InterleaveParams { block_size: 834, factor: 30, frames_per_blk: 3 },
709 InterleaveParams { block_size: 644, factor: 20, frames_per_blk: 4 },
710 InterleaveParams { block_size: 600, factor: 9, frames_per_blk: 10 },
711 InterleaveParams { block_size: 651, factor: 14, frames_per_blk: 7 },
712 InterleaveParams { block_size: 528, factor: 8, frames_per_blk: 11 },
713 InterleaveParams { block_size: 600, factor: 10, frames_per_blk: 10 },
714 InterleaveParams { block_size: 600, factor: 10, frames_per_blk: 10 },
715 InterleaveParams { block_size: 465, factor: 16, frames_per_blk: 5 },
716 InterleaveParams { block_size: 465, factor: 16, frames_per_blk: 5 },
717 InterleaveParams { block_size: 640, factor: 16, frames_per_blk: 5 },
718 InterleaveParams { block_size: 640, factor: 16, frames_per_blk: 5 },
719 InterleaveParams { block_size: 930, factor: 16, frames_per_blk: 5 },
720 InterleaveParams { block_size: 1400, factor: 16, frames_per_blk: 5 },
721 InterleaveParams { block_size: 376, factor: 8, frames_per_blk: 11 },
722 InterleaveParams { block_size: 930, factor: 16, frames_per_blk: 5 },
723 InterleaveParams { block_size: 1400, factor: 16, frames_per_blk: 5 },
724 InterleaveParams { block_size: 640, factor: 16, frames_per_blk: 5 },
725 InterleaveParams { block_size: 1395, factor: 16, frames_per_blk: 5 },
726 InterleaveParams { block_size: 1143, factor: 10, frames_per_blk: 3 },
727 InterleaveParams { block_size: 1064, factor: 10, frames_per_blk: 2 },
728 InterleaveParams { block_size: 778, factor: 1, frames_per_blk: 1 }
729];