X-Git-Url: https://git.nihav.org/?a=blobdiff_plain;f=nihav-realmedia%2Fsrc%2Fmuxers%2Frmvb%2Faudiostream.rs;h=0e174a2729099524613bfbedf210cb69e78aa012;hb=353373a32fcbf842efb6fb11462b5c757b0d382e;hp=fcb3d9c83cbd54bee91c98f3fdd9229870c7f8f2;hpb=9dc1fb4be1d02a1d1c1ea85340f49151e00ecad2;p=nihav.git diff --git a/nihav-realmedia/src/muxers/rmvb/audiostream.rs b/nihav-realmedia/src/muxers/rmvb/audiostream.rs index fcb3d9c..0e174a2 100644 --- a/nihav-realmedia/src/muxers/rmvb/audiostream.rs +++ b/nihav-realmedia/src/muxers/rmvb/audiostream.rs @@ -16,6 +16,8 @@ static AUDIO_CODEC_REGISTRY: &[(&[u8;4], &str, &[u8;4], u8)] = &[ ]; struct InterleaveParams { + sample_rate: u32, + channels: u8, block_size: usize, factor: usize, frames_per_blk: usize, @@ -26,6 +28,7 @@ trait Interleaver { fn get_block_size(&self) -> usize; fn get_factor(&self) -> usize; fn get_frames_per_block(&self) -> usize; + fn is_empty(&self) -> bool; fn add_packet(&mut self, src: &[u8]) -> bool; fn get_packet(&mut self) -> Option<(Vec, bool)>; fn flush(&mut self); @@ -42,6 +45,7 @@ impl Interleaver for NoInterleaver { fn get_block_size(&self) -> usize { self.frame_size } fn get_factor(&self) -> usize { 1 } fn get_frames_per_block(&self) -> usize { 1 } + fn is_empty(&self) -> bool { self.pkt.is_none() } fn add_packet(&mut self, src: &[u8]) -> bool { if self.pkt.is_none() { self.pkt = Some(src.to_vec()); @@ -107,6 +111,7 @@ impl Interleaver for Int4Interleaver { fn get_block_size(&self) -> usize { self.block_size } fn get_factor(&self) -> usize { self.factor } fn get_frames_per_block(&self) -> usize { self.fpb } + fn is_empty(&self) -> bool { self.cur_frame == 0 } fn add_packet(&mut self, src: &[u8]) -> bool { if self.cur_frame == self.factor * self.fpb { return false; @@ -149,7 +154,7 @@ struct GenericInterleaver { map: Vec, } impl GenericInterleaver { - fn new(frame_size: usize, fcc: [u8; 4]) -> MuxerResult { + fn new(ainfo: NAAudioInfo, frame_size: usize, fcc: [u8; 4]) -> MuxerResult { let params = match &fcc { b"atrc" => ATRAC_INTERLEAVE_PARAMS, b"cook" => COOK_INTERLEAVE_PARAMS, @@ -157,6 +162,12 @@ impl GenericInterleaver { _ => return Err(MuxerError::UnsupportedFormat), }; for (flavor, entry) in params.iter().enumerate() { + if entry.sample_rate != 0 && entry.sample_rate != ainfo.sample_rate { + continue; + } + if entry.channels != 0 && entry.channels != ainfo.channels { + continue; + } if entry.block_size / entry.frames_per_blk == frame_size { let full_size = entry.frames_per_blk * entry.factor; let mut map = vec![0; full_size]; @@ -200,6 +211,7 @@ impl Interleaver for GenericInterleaver { fn get_block_size(&self) -> usize { self.block_size } fn get_factor(&self) -> usize { self.factor } fn get_frames_per_block(&self) -> usize { self.fpb } + fn is_empty(&self) -> bool { self.cur_frame == 0 } fn add_packet(&mut self, src: &[u8]) -> bool { if self.cur_frame == self.factor * self.fpb { return false; @@ -266,6 +278,7 @@ impl Interleaver for SiproInterleaver { fn get_block_size(&self) -> usize { self.block_size } fn get_factor(&self) -> usize { self.factor } fn get_frames_per_block(&self) -> usize { 1 } + fn is_empty(&self) -> bool { self.wr_pos == 0 } fn add_packet(&mut self, src: &[u8]) -> bool { if self.wr_pos < self.factor { self.buf[self.wr_pos * self.block_size..][..self.block_size].copy_from_slice(src); @@ -340,6 +353,7 @@ impl Interleaver for AACInterleaver { fn get_block_size(&self) -> usize { self.frame_size } fn get_factor(&self) -> usize { 1 } fn get_frames_per_block(&self) -> usize { 1 } + fn is_empty(&self) -> bool { self.data.is_empty() } fn add_packet(&mut self, src: &[u8]) -> bool { if !self.full { self.data.extend_from_slice(src); @@ -396,6 +410,10 @@ struct AudioStreamWriter { header_pos: u64, interleave: Box, data_size: usize, + first_time: u32, + last_time: u32, + size_in: usize, + size_out: usize, } impl RMStreamWriter for AudioStreamWriter { @@ -424,10 +442,18 @@ impl RMStreamWriter for AudioStreamWriter { } Ok(()) } - fn queue_packet(&mut self, pkt: NAPacket) -> bool { + fn queue_packet(&mut self, pkt: NAPacket, ms: u32) -> bool { let src = pkt.get_buffer(); self.data_size += src.len(); let frame_size = self.interleave.get_frame_size(); + self.last_time = ms; + if self.interleave.is_empty() { + self.first_time = ms; + self.size_in = 0; + self.size_out = 0; + } else { + self.size_in += src.len() / frame_size; + } if !self.is_raw { let mut ret = false; for frame in src.chunks(frame_size) { @@ -438,7 +464,21 @@ impl RMStreamWriter for AudioStreamWriter { self.interleave.add_packet(&src) } } - fn get_packet(&mut self) -> Option<(Vec, bool)> { self.interleave.get_packet() } + fn get_packet(&mut self) -> Option<(Vec, u32, bool)> { + if let Some((pkt, first)) = self.interleave.get_packet() { + let time_add = if self.last_time > self.first_time && self.size_in > 0 { + let size = pkt.len(); + let time_add = (self.size_out * ((self.last_time - self.first_time) as usize) / self.size_in) as u32; + self.size_out += size / self.interleave.get_frame_size(); + time_add + } else { + 0 + }; + Some((pkt, self.first_time + time_add, first)) + } else { + None + } + } fn flush(&mut self) { self.interleave.flush() } fn finish(&mut self, bw: &mut ByteWriter) -> MuxerResult<()> { let cur_pos = bw.tell(); @@ -459,6 +499,7 @@ impl RMStreamWriter for AudioStreamWriter { bw.seek(SeekFrom::Start(cur_pos))?; Ok(()) } + fn set_pkt_size(&mut self, _pkt_size: usize) {} } fn write_audio_metadata(bw: &mut ByteWriter) -> MuxerResult<()> { @@ -587,7 +628,7 @@ fn create_interleaver(id: [u8; 4], fcc: [u8; 4], ainfo: NAAudioInfo) -> MuxerRes b"Int0" => Ok(Box::new(NoInterleaver{ frame_size, pkt: None })), b"Int4" => Ok(Box::new(Int4Interleaver::new(frame_size)?)), b"sipr" => Ok(Box::new(SiproInterleaver::new(frame_size)?)), - b"genr" => Ok(Box::new(GenericInterleaver::new(frame_size, fcc)?)), + b"genr" => Ok(Box::new(GenericInterleaver::new(ainfo, frame_size, fcc)?)), b"vbrs" | b"vbrf" => Ok(Box::new(AACInterleaver::new(1024))), _ => unimplemented!(), } @@ -617,6 +658,10 @@ pub fn create_audio_stream(stream: &NAStream) -> MuxerResult { + InterleaveParams { + sample_rate: $rate, + channels: $ch, + block_size: $bsize, + factor: $factor, + frames_per_blk: $frm_per_blk, + } + } +} + const RA_28_8_INTERLEAVE_PARAMS: &[InterleaveParams] = &[ - InterleaveParams { block_size: 228, factor: 12, frames_per_blk: 6 }, + int_params!(0, 1, 228, 12, 6) ]; -const SIPRO_INTERLEAVE_PARAMS: &[InterleaveParams] = &[ - InterleaveParams { block_size: 232, factor: 6, frames_per_blk: 16 }, - InterleaveParams { block_size: 304, factor: 6, frames_per_blk: 16 }, - InterleaveParams { block_size: 296, factor: 6, frames_per_blk: 16 }, - InterleaveParams { block_size: 320, factor: 6, frames_per_blk: 16 } +const SIPRO_INTERLEAVE_PARAMS: &[InterleaveParams] = &[ //2,1,3,0 + int_params!( 8000, 1, 232, 6, 16), + int_params!( 8000, 1, 304, 6, 16), + int_params!( 8000, 1, 296, 6, 16), + int_params!(16000, 1, 320, 6, 16), ]; const ATRAC_INTERLEAVE_PARAMS: &[InterleaveParams] = &[ - InterleaveParams { block_size: 768, factor: 20, frames_per_blk: 4 }, - InterleaveParams { block_size: 1088, factor: 20, frames_per_blk: 4 }, - InterleaveParams { block_size: 912, factor: 30, frames_per_blk: 3 }, - InterleaveParams { block_size: 1152, factor: 30, frames_per_blk: 3 }, - InterleaveParams { block_size: 1272, factor: 30, frames_per_blk: 3 }, - InterleaveParams { block_size: 1024, factor: 30, frames_per_blk: 2 }, - InterleaveParams { block_size: 768, factor: 10, frames_per_blk: 1 }, - InterleaveParams { block_size: 1024, factor: 10, frames_per_blk: 1 } + int_params!(0, 0, 768, 20, 4), + int_params!(0, 0, 1088, 20, 4), + int_params!(0, 0, 912, 30, 3), + int_params!(0, 0, 1152, 30, 3), + int_params!(0, 0, 1272, 30, 3), + int_params!(0, 0, 1024, 30, 2), + int_params!(0, 0, 768, 10, 1), + int_params!(0, 0, 1024, 10, 1), ]; const COOK_INTERLEAVE_PARAMS: &[InterleaveParams] = &[ - InterleaveParams { block_size: 288, factor: 8, frames_per_blk: 9 }, - InterleaveParams { block_size: 352, factor: 8, frames_per_blk: 11 }, - InterleaveParams { block_size: 564, factor: 8, frames_per_blk: 12 }, - InterleaveParams { block_size: 600, factor: 9, frames_per_blk: 10 }, - InterleaveParams { block_size: 651, factor: 14, frames_per_blk: 7 }, - InterleaveParams { block_size: 640, factor: 15, frames_per_blk: 5 }, - InterleaveParams { block_size: 744, factor: 20, frames_per_blk: 4 }, - InterleaveParams { block_size: 558, factor: 16, frames_per_blk: 6 }, - InterleaveParams { block_size: 288, factor: 6, frames_per_blk: 12 }, - InterleaveParams { block_size: 580, factor: 10, frames_per_blk: 10 }, - InterleaveParams { block_size: 564, factor: 14, frames_per_blk: 6 }, - InterleaveParams { block_size: 640, factor: 16, frames_per_blk: 5 }, - InterleaveParams { block_size: 744, factor: 20, frames_per_blk: 4 }, - InterleaveParams { block_size: 834, factor: 30, frames_per_blk: 3 }, - InterleaveParams { block_size: 644, factor: 20, frames_per_blk: 4 }, - InterleaveParams { block_size: 600, factor: 9, frames_per_blk: 10 }, - InterleaveParams { block_size: 651, factor: 14, frames_per_blk: 7 }, - InterleaveParams { block_size: 528, factor: 8, frames_per_blk: 11 }, - InterleaveParams { block_size: 600, factor: 10, frames_per_blk: 10 }, - InterleaveParams { block_size: 600, factor: 10, frames_per_blk: 10 }, - InterleaveParams { block_size: 465, factor: 16, frames_per_blk: 5 }, - InterleaveParams { block_size: 465, factor: 16, frames_per_blk: 5 }, - InterleaveParams { block_size: 640, factor: 16, frames_per_blk: 5 }, - InterleaveParams { block_size: 640, factor: 16, frames_per_blk: 5 }, - InterleaveParams { block_size: 930, factor: 16, frames_per_blk: 5 }, - InterleaveParams { block_size: 1400, factor: 16, frames_per_blk: 5 }, - InterleaveParams { block_size: 376, factor: 8, frames_per_blk: 11 }, - InterleaveParams { block_size: 930, factor: 16, frames_per_blk: 5 }, - InterleaveParams { block_size: 1400, factor: 16, frames_per_blk: 5 }, - InterleaveParams { block_size: 640, factor: 16, frames_per_blk: 5 }, - InterleaveParams { block_size: 1395, factor: 16, frames_per_blk: 5 }, - InterleaveParams { block_size: 1143, factor: 10, frames_per_blk: 3 }, - InterleaveParams { block_size: 1064, factor: 10, frames_per_blk: 2 }, - InterleaveParams { block_size: 778, factor: 1, frames_per_blk: 1 } + int_params!( 8000, 1, 288, 8, 9), + int_params!(11025, 1, 352, 8, 11), + int_params!(22050, 1, 564, 8, 12), + int_params!(22050, 1, 600, 9, 10), + int_params!(44100, 1, 651, 14, 7), + int_params!(44100, 1, 640, 15, 5), + int_params!(44100, 1, 744, 20, 4), + int_params!(22050, 1, 558, 16, 6), + int_params!( 8000, 1, 288, 6, 12), + int_params!(11025, 2, 580, 10, 10), + int_params!(22050, 2, 564, 14, 6), + int_params!(22050, 2, 640, 16, 5), + int_params!(44100, 2, 744, 20, 4), + int_params!(44100, 2, 834, 30, 3), + int_params!(44100, 1, 644, 20, 4), + int_params!(44100, 1, 600, 9, 10), + int_params!(44100, 1, 651, 14, 7), + int_params!(22050, 2, 528, 10, 10), + int_params!(22050, 2, 600, 10, 10), + int_params!(22050, 2, 600, 10, 10), + int_params!(22050, 2, 465, 16, 5), + int_params!(44100, 2, 465, 16, 5), + int_params!(44100, 2, 640, 16, 5), + int_params!(44100, 2, 640, 16, 5), + int_params!(44100, 2, 930, 16, 5), + int_params!(44100, 2, 1400, 16, 5), + int_params!(11025, 2, 376, 8, 11), + int_params!(44100, 2, 930, 16, 5), + int_params!(44100, 2, 1400, 16, 5), + int_params!(22050, 2, 640, 16, 5), + int_params!(44100, 5, 1395, 16, 5), + int_params!(44100, 6, 1143, 10, 3), + int_params!(44100, 6, 1064, 10, 2), + int_params!(44100, 6, 778, 1, 1), ];