Skip to content

Commit

Permalink
shift DTS & CTS by minimum CTS
Browse files Browse the repository at this point in the history
  • Loading branch information
Wumpf committed Nov 13, 2024
1 parent 8fa1613 commit a0dad5b
Showing 1 changed file with 21 additions and 0 deletions.
21 changes: 21 additions & 0 deletions src/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,17 @@ impl Mp4 {
let mut ctts_run_index = -1i64;
let mut dts_shift = 0;

// The smallest presentation timestamp observed in this stream.
//
// This is typically 0, but in the presence of sample reordering (caused by AVC/HVC b-frames), it may be non-zero.
// In fact, many formats don't require this to be zero, but video players typically
// normalize the shown time to start at zero.
// This is roughly equivalent to FFmpeg's internal `min_corrected_pts`
// https://github.com/FFmpeg/FFmpeg/blob/4047b887fc44b110bccb1da09bcb79d6e454b88b/libavformat/isom.h#L202
// To learn more about this I recommend reading the patch that introduced this in FFmpeg:
// https://patchwork.ffmpeg.org/project/ffmpeg/patch/[email protected]/#12592
let mut min_composition_timestamp = i64::MAX;

let mut samples = Vec::<Sample>::new();

fn get_sample_chunk_offset(stbl: &StblBox, chunk_index: u64) -> u64 {
Expand Down Expand Up @@ -231,6 +242,7 @@ impl Mp4 {
} else {
decode_timestamp
};
min_composition_timestamp = min_composition_timestamp.min(composition_timestamp);

let is_sync = if let Some(stss) = &stbl.stss {
if last_stss_index < stss.entries.len()
Expand Down Expand Up @@ -271,6 +283,15 @@ impl Mp4 {
}
}

// Shift both DTS & CTS by the smallest CTS.
// For details, see declaration of `min_composition_timestamp` above.
if min_composition_timestamp != 0 {
for sample in &mut samples {
sample.decode_timestamp -= min_composition_timestamp;
sample.composition_timestamp -= min_composition_timestamp;
}
}

tracks.insert(
trak.tkhd.track_id,
Track {
Expand Down

0 comments on commit a0dad5b

Please sign in to comment.