diff --git a/symphonia-format-isomp4/src/atoms/trak.rs b/symphonia-format-isomp4/src/atoms/trak.rs index 818654e7..01204174 100644 --- a/symphonia-format-isomp4/src/atoms/trak.rs +++ b/symphonia-format-isomp4/src/atoms/trak.rs @@ -20,6 +20,8 @@ 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 { @@ -45,14 +47,19 @@ impl Atom for TrakAtom { } } - if tkhd.is_none() { + let Some(tkhd_atom) = tkhd + else { return decode_error("isomp4: missing tkhd atom"); - } + }; - if mdia.is_none() { + let Some(mdia_atom) = 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.unwrap(), edts, mdia: mdia.unwrap() }) + Ok(TrakAtom { tkhd: tkhd_atom, edts, mdia: mdia_atom, duration }) } } diff --git a/symphonia-format-isomp4/src/demuxer.rs b/symphonia-format-isomp4/src/demuxer.rs index 46b09067..270517d6 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.mdia.mdhd.duration); + .with_num_frames(trak.duration); track } @@ -523,8 +523,9 @@ impl FormatReader for IsoMp4Reader<'_> { } else { // No more segments. If the stream is unseekable, it may be the case that there are - // more segments coming. Iterate atoms until a new segment is found or the - // end-of-stream is reached. + // more segments coming. If the stream is seekable it might be fragmented and no segments are found in + // the moov atom. Iterate atoms until a new segment is found or the + // end-of-stream is reached if !self.try_read_more_segments()? { return Ok(None); } diff --git a/symphonia-format-isomp4/src/stream.rs b/symphonia-format-isomp4/src/stream.rs index 82cc6806..d764e73b 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.mdia.mdhd.duration { + if seq.first_ts + seq.total_sample_duration < trak.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.mdia.mdhd.duration { + if trak.mdia.minf.stbl.stts.total_duration < trak.duration { return false; } }