Skip to content
GitLab
    • GitLab: the DevOps platform
    • Explore GitLab
    • Install GitLab
    • How GitLab compares
    • Get started
    • GitLab docs
    • GitLab Learn
  • Pricing
  • Talk to an expert
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
    • Switch to GitLab Next
    Projects Groups Snippets
  • Register
  • Sign in
  • MKVToolNix MKVToolNix
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Locked Files
  • Issues 20
    • Issues 20
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 1
    • Merge requests 1
  • Deployments
    • Deployments
    • Releases
  • Analytics
    • Analytics
    • Value stream
    • Code review
    • Insights
    • Issue
    • Repository
  • Wiki
    • Wiki
  • Activity
  • Graph
  • Create a new issue
  • Commits
  • Issue Boards
Collapse sidebar
  • Moritz Bunkus
  • MKVToolNixMKVToolNix
  • Issues
  • #2085
Closed
Open
Issue created Aug 29, 2017 by Moritz Bunkus@mbunkusOwner

H.264 timestamps issue; source PTS not kept

Created by: mkver

Hello,

according to your explanation, MKVToolNix derives the display order for every GOP for unframed H.264 input. But when the source is actually a transport stream which contains proper PTS values, this is unnecessary; usually it is not wrong, but if the transport stream contains an error (I'm thinking of missing packets in the transport stream, not a broken transport stream created by a garbage application), then the recalculated PTS can differ from the original timestamps. I have uploaded such a file to your ftp-server. If I remux the video track with a delay of -897 ms (this delay is choosen so that the first frame has a timestamp of 500ms, the timestamp that ffmpeg assigns to the first frame if one copies only the video track with ffmpeg), I get the following timestamps (only the interesting part shown):

P frame, track 1, timecode 3580 (00:00:03.580), size 91708, adler 0x86402321
B frame, track 1, timecode 3520 (00:00:03.520), size 21314, adler 0x727a7584
B frame, track 1, timecode 3480 (00:00:03.480), size 534, adler 0xed30090d
P frame, track 1, timecode 3500 (00:00:03.500), size 347, adler 0x106ea381
P frame, track 1, timecode 3540 (00:00:03.540), size 4721, adler 0x65874240
P frame, track 1, timecode 3560 (00:00:03.560), size 4599, adler 0x8111e240
I frame, track 1, timecode 6760 (00:00:06.760), size 176644, adler 0x1f16b6fb
B frame, track 1, timecode 3760 (00:00:03.760), size 20123, adler 0x1d322edc
B frame, track 1, timecode 3640 (00:00:03.640), size 610, adler 0x3dac34c7
P frame, track 1, timecode 3680 (00:00:03.680), size 6388, adler 0xf3226982
P frame, track 1, timecode 3720 (00:00:03.720), size 6087, adler 0xe887cc95
P frame, track 1, timecode 3800 (00:00:03.800), size 272, adler 0x8cb8829a
P frame, track 1, timecode 7020 (00:00:07.020), size 92630, adler 0x0b9eab1f
B frame, track 1, timecode 6780 (00:00:06.780), size 46, adler 0xc3fa07b1
P frame, track 1, timecode 6840 (00:00:06.840), size 6491, adler 0x940aad54
P frame, track 1, timecode 6860 (00:00:06.860), size 5972, adler 0xbce79a45
P frame, track 1, timecode 6920 (00:00:06.920), size 5678, adler 0xdb37de7b
P frame, track 1, timecode 6980 (00:00:06.980), size 154368, adler 0xa77e7a0c
B frame, track 1, timecode 3700 (00:00:03.700), size 20200, adler 0x85ab75a5
B frame, track 1, timecode 3600 (00:00:03.600), size 743, adler 0x7fd8713c
P frame, track 1, timecode 3620 (00:00:03.620), size 4047, adler 0x9abcdd70
P frame, track 1, timecode 3660 (00:00:03.660), size 3691, adler 0x1f2843a9
P frame, track 1, timecode 3740 (00:00:03.740), size 455, adler 0xb3f2e459
P frame, track 1, timecode 3780 (00:00:03.780), size 3792, adler 0x7ae3549f
P frame, track 1, timecode 3820 (00:00:03.820), duration 2940.000, size 3219, adler 0xe1a739a8
P frame, track 1, timecode 7000 (00:00:07.000), size 84548, adler 0x0f630974
B frame, track 1, timecode 6800 (00:00:06.800), size 46, adler 0xc01a0791
P frame, track 1, timecode 6820 (00:00:06.820), size 4501, adler 0x379cbba7
P frame, track 1, timecode 6880 (00:00:06.880), duration 40.000, size 3935, adler 0x0ebba541
P frame, track 1, timecode 6940 (00:00:06.940), size 4644, adler 0xf8e00716
P frame, track 1, timecode 6960 (00:00:06.960), size 4107, adler 0xe57c0d13
P frame, track 1, timecode 7140 (00:00:07.140), size 134826, adler 0x01c4dfa5
B frame, track 1, timecode 7040 (00:00:07.040), size 832, adler 0x92e48e99
P frame, track 1, timecode 7060 (00:00:07.060), size 12933, adler 0xe8cd4abe
P frame, track 1, timecode 7080 (00:00:07.080), size 11360, adler 0xac24d034
P frame, track 1, timecode 7100 (00:00:07.100), size 10747, adler 0xa4ec1f07
P frame, track 1, timecode 7120 (00:00:07.120), size 9505, adler 0x5a9770dc
P frame, track 1, timecode 7260 (00:00:07.260), size 135307, adler 0x57b6a025
B frame, track 1, timecode 7160 (00:00:07.160), size 57, adler 0x02d10f51
P frame, track 1, timecode 7180 (00:00:07.180), size 10796, adler 0x9905c6f9
P frame, track 1, timecode 7200 (00:00:07.200), size 9605, adler 0xb892f139

The above looks erroneous: This file uses open-gop, but I have never ever seen such a large gap between the keyframe and the frames preceding it in display order (this stream contains a keyframe at least once every 640 ms). So it has to be wrong. If I remux with ffmpeg (and use the chomp bitstream filter to strip trailing zeros away (this was done in order to check if mkvmerge also changes the decoding order; the remaining difference of six bytes is due to ffmpeg not stripping access unit delimiters away)) I get the following timecodes:

P frame, track 1, timecode 3580 (00:00:03.580), size 91714, adler 0x1b3f235c
P frame, track 1, timecode 3520 (00:00:03.520), size 21320, adler 0x0d2075df
P frame, track 1, timecode 3480 (00:00:03.480), size 540, adler 0xab7f0968
P frame, track 1, timecode 3500 (00:00:03.500), size 353, adler 0x8c35a3dc
P frame, track 1, timecode 3540 (00:00:03.540), size 4727, adler 0xf47a429b
P frame, track 1, timecode 3560 (00:00:03.560), size 4605, adler 0xe4a6e29b
I frame, track 1, timecode 3700 (00:00:03.700), size 176650, adler 0xe9e8b716
P frame, track 1, timecode 3660 (00:00:03.660), size 20129, adler 0x105d2f37
P frame, track 1, timecode 3600 (00:00:03.600), size 616, adler 0x16ff3522
P frame, track 1, timecode 3620 (00:00:03.620), size 6394, adler 0xd2d369dd
P frame, track 1, timecode 3640 (00:00:03.640), size 6093, adler 0x5d39ccf0
P frame, track 1, timecode 3680 (00:00:03.680), size 278, adler 0xedd682f5
P frame, track 1, timecode 3820 (00:00:03.820), size 92636, adler 0x751bab5a
P frame, track 1, timecode 3720 (00:00:03.720), size 52, adler 0xd4c2080c
P frame, track 1, timecode 3740 (00:00:03.740), size 6497, adler 0x9858adaf
P frame, track 1, timecode 3760 (00:00:03.760), size 5978, adler 0x08b89aa0
P frame, track 1, timecode 3780 (00:00:03.780), size 5684, adler 0xbe77ded6
P frame, track 1, timecode 3800 (00:00:03.800), size 154374, adler 0x0d857a67
P frame, track 1, timecode 6820 (00:00:06.820), size 20206, adler 0x94357600
P frame, track 1, timecode 6760 (00:00:06.760), size 749, adler 0x88727197
P frame, track 1, timecode 6780 (00:00:06.780), size 4053, adler 0x3a19ddcb
P frame, track 1, timecode 6800 (00:00:06.800), size 3697, adler 0x3fea4404
P frame, track 1, timecode 6840 (00:00:06.840), size 461, adler 0x562ce4b4
P frame, track 1, timecode 6860 (00:00:06.860), size 3798, adler 0xbf8c54fa
P frame, track 1, timecode 6880 (00:00:06.880), size 3225, adler 0x5aa13a03
P frame, track 1, timecode 7020 (00:00:07.020), size 84554, adler 0x31d109af
P frame, track 1, timecode 6920 (00:00:06.920), size 52, adler 0xd0e207ec
P frame, track 1, timecode 6940 (00:00:06.940), size 4507, adler 0x785bbc02
P frame, track 1, timecode 6960 (00:00:06.960), size 3941, adler 0x8639a59c
P frame, track 1, timecode 6980 (00:00:06.980), size 4650, adler 0x6c830771
P frame, track 1, timecode 7000 (00:00:07.000), size 4113, adler 0x9a2d0d6e
P frame, track 1, timecode 7140 (00:00:07.140), size 134832, adler 0x6a57dfe0
P frame, track 1, timecode 7040 (00:00:07.040), size 838, adler 0xbb218ef4
P frame, track 1, timecode 7060 (00:00:07.060), size 12939, adler 0xdf904b19
P frame, track 1, timecode 7080 (00:00:07.080), size 11366, adler 0x73a2d08f
P frame, track 1, timecode 7100 (00:00:07.100), size 10753, adler 0x92741f62
P frame, track 1, timecode 7120 (00:00:07.120), size 9511, adler 0x8e837137
P frame, track 1, timecode 7260 (00:00:07.260), size 135313, adler 0x2f33a060
P frame, track 1, timecode 7160 (00:00:07.160), size 63, adler 0x17820fac
P frame, track 1, timecode 7180 (00:00:07.180), size 10802, adler 0x97f8c754
P frame, track 1, timecode 7200 (00:00:07.200), size 9611, adler 0x1019f194

This looks vastly better and totally in line with how I expect an open-gop to look. Given that ffmpeg is unable to mux elementary streams I expect these timestamps to be the ones from the transport stream. As has already been said, my the proposed change to keep the timestamps from the input container relies on these timestamps to be considered good. In order to handle situations with bad input timestamps, there should be an option to derive the timecodes just like now.

Greetings Andi

Edited Dec 16, 2017 by Moritz Bunkus
Assignee
Assign to
Time tracking