Repository navigation
pmp4: support tracks longer than 2^32 ticks - #377
Merged
Merged
Conversation
Sample durations were summed into a 32-bit integer and mdhd was always written with version 0, therefore the duration of tracks longer than 2^32 ticks (13.25h at 90kHz) wrapped around in mdhd, tkhd and elst: a 14h presentation was reported as 44m38s, and players that honour edit lists stopped there. Sum durations with 64 bits and write mdhd with version 1 when the duration does not fit into 32 bits (ISO/IEC 14496-12, 8.4.2). Read the version 1 duration too, and return an error when it is not consistent with the sample durations. Version 0 durations are still read as before, so that files written by previous versions of Marshal, whose duration may have wrapped around, keep working.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #377 +/- ##
==========================================
+ Coverage 91.02% 91.35% +0.32%
==========================================
Files 98 98
Lines 5472 5482 +10
==========================================
+ Hits 4981 5008 +27
+ Misses 491 474 -17 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Member
|
merged, thanks |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Presentation.Marshalsummed sample durations into auint32and always wrote mdhd with version 0. The duration of tracks longer than 2^32 ticks (13.25h at 90kHz, 24.8h at 48kHz) therefore wrapped around in mdhd, tkhd and elst. For example, a 14h 25fps H264 track is reported by ffprobe as 2678s instead of 50400s, and players that honour edit lists stop playback at 44:38. MediaMTX builds these files in playback/get?format=mp4, so this hits exports longer than about 13h.Durations are now summed with 64 bits, and mdhd is written with version 1 only when the duration does not fit into 32 bits (ISO/IEC 14496-12, 8.4.2), so existing output is unchanged. tkhd, mvhd and elst stay at version 0 because they use the 1000Hz movie timescale. This means that presentations longer than 49.7 days (2^32 ms) still wrap in those three boxes.
The reader now reads the version 1 duration too. Before, a version 1 mdhd was read as a duration of 0, so the time offset came out wrong (1294967296 instead of 0 for an FFmpeg file with
-video_track_timescale 1500000000). Version 1 durations are range-checked:invalid durationis returned when the time offset (mdhd duration minus the sum of the sample durations) does not fit into an int32, instead of wrapping silently. Version 0 durations keep their current behaviour, so files that were written by the current version ofMarshalwith a wrapped duration still read with the right time offset.Add a round-trip test case with a 14h track (two samples of 7h at 90kHz, plus a 1s time offset) that covers the version 1 write and read, a test case with the same track as written by the current
Marshal(wrapped version 0 mdhd), and a fuzz seed with a version 1 mdhd duration inconsistent with the samples. The existing test bytes are unchanged.