diff --git a/symphonia-format-isomp4/src/atoms/moov.rs b/symphonia-format-isomp4/src/atoms/moov.rs index 98bb7b62..b503a190 100644 --- a/symphonia-format-isomp4/src/atoms/moov.rs +++ b/symphonia-format-isomp4/src/atoms/moov.rs @@ -69,9 +69,10 @@ impl Atom for MoovAtom { } } - if mvhd.is_none() { + let Some(mvhd) = mvhd + else { return decode_error("isomp4: missing mvhd atom"); - } + }; // If fragmented, the mvex atom should contain a trex atom for each trak atom in moov. if let Some(mvex) = mvex.as_ref() { @@ -85,6 +86,14 @@ impl Atom for MoovAtom { } } - Ok(MoovAtom { mvhd: mvhd.unwrap(), traks, mvex, udta }) + // If trak.mdia.mdhd.duration is 0, set it to trak.tkhd.duration converted to trak.mdia.mdhd.timescale + for trak in traks.iter_mut() { + if trak.mdia.mdhd.duration == 0 { + trak.mdia.mdhd.duration = + trak.tkhd.duration * trak.mdia.mdhd.timescale as u64 / mvhd.timescale as u64; + } + } + + Ok(MoovAtom { mvhd, traks, mvex, udta }) } } diff --git a/symphonia-format-isomp4/src/atoms/trak.rs b/symphonia-format-isomp4/src/atoms/trak.rs index 01204174..8d7e96a5 100644 --- a/symphonia-format-isomp4/src/atoms/trak.rs +++ b/symphonia-format-isomp4/src/atoms/trak.rs @@ -20,8 +20,6 @@ pub struct TrakAtom { pub edts: Option, /// Media atom. pub mdia: MdiaAtom, - /// Duration, equal to mdia.mdhd.duration unless it is zero, in which case it is equal to tkhd.duration. - pub duration: u64, } impl Atom for TrakAtom { @@ -47,19 +45,16 @@ impl Atom for TrakAtom { } } - let Some(tkhd_atom) = tkhd + let Some(tkhd) = tkhd else { return decode_error("isomp4: missing tkhd atom"); }; - let Some(mdia_atom) = mdia + let Some(mdia) = mdia else { return decode_error("isomp4: missing mdia atom"); }; - let duration = - if mdia_atom.mdhd.duration != 0 { mdia_atom.mdhd.duration } else { tkhd_atom.duration }; - - Ok(TrakAtom { tkhd: tkhd_atom, edts, mdia: mdia_atom, duration }) + Ok(TrakAtom { tkhd, edts, mdia }) } } diff --git a/symphonia-format-isomp4/src/demuxer.rs b/symphonia-format-isomp4/src/demuxer.rs index c87ae348..b3de13ab 100644 --- a/symphonia-format-isomp4/src/demuxer.rs +++ b/symphonia-format-isomp4/src/demuxer.rs @@ -56,7 +56,7 @@ impl TrackState { track .with_time_base(TimeBase::new(1, trak.mdia.mdhd.timescale)) - .with_num_frames(trak.duration); + .with_num_frames(trak.mdia.mdhd.duration); let state = Self { track_num, diff --git a/symphonia-format-isomp4/src/stream.rs b/symphonia-format-isomp4/src/stream.rs index d764e73b..82cc6806 100644 --- a/symphonia-format-isomp4/src/stream.rs +++ b/symphonia-format-isomp4/src/stream.rs @@ -146,7 +146,7 @@ impl StreamSegment for MoofSegment { } // If a track does NOT end in this segment, then this cannot be the last segment. - if seq.first_ts + seq.total_sample_duration < trak.duration { + if seq.first_ts + seq.total_sample_duration < trak.mdia.mdhd.duration { return false; } } @@ -349,7 +349,7 @@ impl StreamSegment for MoovSegment { fn all_tracks_ended(&self) -> bool { // If a track does not end in this segment, then this cannot be the last segment. for trak in &self.moov.traks { - if trak.mdia.minf.stbl.stts.total_duration < trak.duration { + if trak.mdia.minf.stbl.stts.total_duration < trak.mdia.mdhd.duration { return false; } }