Appending: Wrong timestamp offset
Hello,
I think I have found two bugs a) (this one) and b); a) can trigger b) as in the example that accompanies this issue, but b) can also be triggered by other means so I'll open a separate issue for b).
The problem is basically here: The first (read: lowest) timestamp of a file needn't be the cluster timestamp of the first cluster. This is usually the case for files produced by mkvmerge, but it is not a requirement according to the specifications and other muxers behave differently, e.g. ffmpeg's muxer does it differently.
I have uploaded several files to your ftp-server. All files only contain a video track. Anfang.mkv is a regular file produced with mkvmerge from a transport stream; ffmpeg.mkv is a Matroska file produced with ffmpeg that contains content immediately following anfang.mkv (i.e. if one appends ffmpeg.mkv to Anfang.mkv, the result should play the same way as if one had directly remuxed the content from the transport stream). ffmpeg.mkv begins with an open GOP and it's first cluster timestamp is not its lowest timestamp:
|+ Cluster
| + Cluster timestamp: 00:00:00.200000000
| + Simple block: key, track number 1, 1 frame(s), timestamp 00:00:00.200000000
| + Frame with size 100742
| + Simple block: track number 1, 1 frame(s), timestamp 00:00:00.120000000
| + Frame with size 16398
| + Simple block: track number 1, 1 frame(s), timestamp 00:00:00.060000000
| + Frame with size 3877
| + Simple block: track number 1, 1 frame(s), timestamp 00:00:00.080000000
| + Frame with size 4695
| + Simple block: track number 1, 1 frame(s), timestamp 00:00:00.100000000
| + Frame with size 4491
| + Simple block: track number 1, 1 frame(s), timestamp 00:00:00.140000000
| + Frame with size 4405
| + Simple block: track number 1, 1 frame(s), timestamp 00:00:00.160000000
| + Frame with size 5351
| + Simple block: track number 1, 1 frame(s), timestamp 00:00:00.180000000
| + Frame with size 4956
| + Simple block: track number 1, 1 frame(s), timestamp 00:00:00.360000000
| + Frame with size 41861
| + Simple block: track number 1, 1 frame(s), timestamp 00:00:00.280000000
| + Frame with size 20028
| + Simple block: track number 1, 1 frame(s), timestamp 00:00:00.220000000
| + Frame with size 4731
| + Simple block: track number 1, 1 frame(s), timestamp 00:00:00.240000000
| + Frame with size 5700
| + Simple block: track number 1, 1 frame(s), timestamp 00:00:00.260000000
| + Frame with size 5713
| + Simple block: track number 1, 1 frame(s), timestamp 00:00:00.300000000
| + Frame with size 5574
| + Simple block: track number 1, 1 frame(s), timestamp 00:00:00.320000000
| + Frame with size 5828
| + Simple block: track number 1, 1 frame(s), timestamp 00:00:00.340000000
| + Frame with size 5756
...
The end of Anfang.mkv is at 1280ms. If one simply appends (as there is only one track, it doesn't matter whether one appends in track or file mode), the relevant timestamps look like this:
...
| + Simple block: track number 1, 1 frame(s), timestamp 00:00:01.260000000
| + Frame with size 37099
| + Simple block: track number 1, 1 frame(s), timestamp 00:00:01.180000000
| + Frame with size 14449
| + Simple block: discardable, track number 1, 1 frame(s), timestamp 00:00:01.120000000
| + Frame with size 3621
| + Simple block: discardable, track number 1, 1 frame(s), timestamp 00:00:01.140000000
| + Frame with size 3770
| + Simple block: discardable, track number 1, 1 frame(s), timestamp 00:00:01.160000000
| + Frame with size 3871
| + Simple block: discardable, track number 1, 1 frame(s), timestamp 00:00:01.200000000
| + Frame with size 3532
| + Simple block: discardable, track number 1, 1 frame(s), timestamp 00:00:01.220000000
| + Frame with size 3821
| + Simple block: discardable, track number 1, 1 frame(s), timestamp 00:00:01.240000000
| + Frame with size 3803
|+ Cluster
| + Cluster timestamp: 00:00:01.140000000
| + Simple block: key, track number 1, 1 frame(s), timestamp 00:00:01.280000000
| + Frame with size 100742
| + Simple block: track number 1, 1 frame(s), timestamp 00:00:01.200000000
| + Frame with size 16398
| + Simple block: track number 1, 1 frame(s), timestamp 00:00:01.140000000
| + Frame with size 3877
|+ Cluster
| + Cluster timestamp: 00:00:01.160000000
| + Simple block: track number 1, 1 frame(s), timestamp 00:00:01.160000000
| + Frame with size 4695
|+ Cluster
| + Cluster timestamp: 00:00:01.180000000
| + Simple block: track number 1, 1 frame(s), timestamp 00:00:01.180000000
| + Frame with size 4491
|+ Cluster
| + Cluster timestamp: 00:00:01.220000000
| + Simple block: track number 1, 1 frame(s), timestamp 00:00:01.220000000
| + Frame with size 4405
|+ Cluster
| + Cluster timestamp: 00:00:01.240000000
| + Simple block: track number 1, 1 frame(s), timestamp 00:00:01.240000000
| + Frame with size 5351
|+ Cluster
| + Cluster timestamp: 00:00:01.260000000
| + Simple block: track number 1, 1 frame(s), timestamp 00:00:01.260000000
| + Frame with size 4956
|+ Cluster
| + Cluster timestamp: 00:00:01.300000000
| + Simple block: track number 1, 1 frame(s), timestamp 00:00:01.440000000
| + Frame with size 41861
| + Simple block: track number 1, 1 frame(s), timestamp 00:00:01.360000000
| + Frame with size 20028
| + Simple block: track number 1, 1 frame(s), timestamp 00:00:01.300000000
| + Frame with size 4731
| + Simple block: track number 1, 1 frame(s), timestamp 00:00:01.320000000
| + Frame with size 5700
| + Simple block: track number 1, 1 frame(s), timestamp 00:00:01.340000000
| + Frame with size 5713
...
As one sees, the offset for the timestamps of the second file was too low; it was too low by the amount the cluster timestamp of the first cluster of ffmpeg.mkv differed from the lowest timestamp of ffmpeg.mkv (140ms). As a result, several frames are skipped over when playing Appended.mkv.
A possible solution for this is simple to describe: Analyze the beginning (say, the first GOP) of the second (and every further) file and use the lowest timestamp found so to shift the second file to zero before further offseting the second and every further file for appending. But in a similar issue (#1170 (closed)) you said that it would be very difficult to implement (despite the solution being simple to describe, too) and this issue might be of the same sort.
Gruß Andi