fn flush_chunks(&mut self, _bw: &mut dyn ByteIO, _ca: &mut ChunkAccount) -> MuxerResult<()> { Ok(()) }
fn get_time_info(&self) -> (u64, u32) { (self.pts, self.ainfo.sample_rate) }
fn get_dimensions(&self) -> (usize, usize) { (0, 0) }
+ fn get_pkt_duration(&self) -> u64 {
+ if self.frm_sz != 0 && self.frameno > 2 {
+ self.last_ts / u64::from(self.frameno - 2)
+ } else {
+ 1
+ }
+ }
fn write_media_info(&mut self, bw: &mut dyn ByteIO) -> MuxerResult<()> {
let smhd = AtomMarker::start(bw, b"smhd")?;
bw.write_byte(0)?; // version
bw.write_u32be(0)?; // vendor
bw.write_u16be(u16::from(self.ainfo.channels))?;
bw.write_u16be(u16::from(self.ainfo.format.bits))?;
- bw.write_u16be(0xFFFE)?; // compression ID
+ bw.write_u16be(if self.frm_sz != 0 { 0 } else { 0xFFFE })?; // compression ID
bw.write_u16be(0)?; // packet size
bw.write_u32be(self.ainfo.sample_rate << 16)?;
- bw.write_u32be(0)?; // samples per packet
- bw.write_u32be(self.frm_sz as u32)?; // bytes per packet
- bw.write_u32be(0)?; // bytes per frame
- bw.write_u32be(0)?; // bytes per sample
+ if self.frm_sz != 0 { // CBR audio
+ let samples_per_pkt = if self.frameno > 2 {
+ self.last_ts / u64::from(self.frameno - 2)
+ } else { 0 };
+ bw.write_u32be(samples_per_pkt as u32)?; // samples per packet
+ bw.write_u32be(self.frm_sz as u32 / u32::from(self.ainfo.channels))?; // bytes per packet
+ bw.write_u32be(self.frm_sz as u32)?; // bytes per frame
+ bw.write_u32be(2)?; // bytes per sample
+ } else {
+ bw.write_u32be(0)?; // samples per packet
+ bw.write_u32be(0)?; // bytes per packet
+ bw.write_u32be(0)?; // bytes per frame
+ bw.write_u32be(0)?; // bytes per sample
+ }
if let Some(edata) = &self.edata {
bw.write_u32be(edata.len() as u32 + 20)?;
bw.write_buf(b"wave")?;
self.cmap.push(count as u32);
}
- fn write_stts(&mut self, bw: &mut dyn ByteIO, raw_audio: bool) -> MuxerResult<()> {
+ fn write_stts(&mut self, bw: &mut dyn ByteIO, raw_audio: bool, pktd: u64) -> MuxerResult<()> {
if !raw_audio {
let mut nentries = 1;
let mut prev_delta = self.pts[1] - self.pts[0];
for w in self.pts.windows(2).skip(1) {
let delta = w[1] - w[0];
if delta != prev_delta {
- bw.write_u32be(run)?;
- bw.write_u32be(prev_delta as u32)?;
+ bw.write_u32be(run * (pktd as u32))?;
+ bw.write_u32be((prev_delta / pktd) as u32)?;
run = 1;
prev_delta = delta;
} else {
run += 1;
}
}
- bw.write_u32be(run + 1)?;
- bw.write_u32be(prev_delta as u32)?;
+ bw.write_u32be((run + 1) * (pktd as u32))?;
+ bw.write_u32be((prev_delta / pktd) as u32)?;
} else {
bw.write_u32be(1)?;
bw.write_u32be((*self.pts.last().unwrap_or(&0)) as u32)?;
fn flush_chunks(&mut self, bw: &mut dyn ByteIO, ca: &mut ChunkAccount) -> MuxerResult<()>;
fn get_time_info(&self) -> (u64, u32);
fn get_dimensions(&self) -> (usize, usize);
+ fn get_pkt_duration(&self) -> u64;
fn write_media_info(&mut self, bw: &mut dyn ByteIO) -> MuxerResult<()>;
fn write_descriptor(&mut self, bw: &mut dyn ByteIO) -> MuxerResult<()>;
}
self.handler.write_descriptor(bw)?;
stsd.end(bw)?;
+ let pktd = self.handler.get_pkt_duration();
let stts = AtomMarker::start(bw, b"stts")?;
bw.write_byte(0)?; // version
bw.write_u24be(0)?; // flags
- self.ca.write_stts(bw, self.raw_audio)?;
+ self.ca.write_stts(bw, self.raw_audio, pktd)?;
stts.end(bw)?;
let stsc = AtomMarker::start(bw, b"stsc")?;
let mut mux_reg = RegisteredMuxers::new();
generic_register_all_muxers(&mut mux_reg);
test_remuxing_md5(&dec_config, "mov", &mux_reg,
- [0xeb99a547, 0xd6c1a4ce, 0xc12d3451, 0x096639c5]);
+ [0x3d030f10, 0x842de3e2, 0xb6a5ae89, 0x30d9b05f]);
}
}
}
fn get_time_info(&self) -> (u64, u32) { (self.sample, self.rate) }
fn get_dimensions(&self) -> (usize, usize) { (0, 0) }
+ fn get_pkt_duration(&self) -> u64 { 1 }
fn write_media_info(&mut self, bw: &mut dyn ByteIO) -> MuxerResult<()> {
let smhd = AtomMarker::start(bw, b"smhd")?;
bw.write_byte(0)?; // version
fn get_dimensions(&self) -> (usize, usize) {
(self.vinfo.width, self.vinfo.height)
}
+ fn get_pkt_duration(&self) -> u64 { 1 }
fn write_media_info(&mut self, bw: &mut dyn ByteIO) -> MuxerResult<()> {
let vmhd = AtomMarker::start(bw, b"vmhd")?;
bw.write_byte(0)?; // version