Skip to content

Commit

Permalink
isomp4: fix zero track duration for fragmented mp4
Browse files Browse the repository at this point in the history
  • Loading branch information
sscobici committed Oct 6, 2024
1 parent dd61030 commit e2e97de
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 10 deletions.
17 changes: 12 additions & 5 deletions symphonia-format-isomp4/src/atoms/trak.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ pub struct TrakAtom {
pub edts: Option<EdtsAtom>,
/// 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 {
Expand All @@ -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 })
}
}
7 changes: 4 additions & 3 deletions symphonia-format-isomp4/src/demuxer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down Expand Up @@ -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);
}
Expand Down
4 changes: 2 additions & 2 deletions symphonia-format-isomp4/src/stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -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;
}
}
Expand Down

0 comments on commit e2e97de

Please sign in to comment.