[FFmpeg-user] Matroska (.mkv) time resolution [was: Re: How can I force a 360kHz time base? ]

Mark Filipak (ffmpeg) markfilipak at bog.us
Sat Feb 27 09:20:43 EET 2021


On 2021-02-27 01:37, Jim DeLaHunt wrote:
> 
> On 2021-02-26 22:08, Mark Filipak (ffmpeg) wrote:
>> On 2021-02-27 00:55, Jim DeLaHunt wrote:
>>> On 2021-02-26 18:36, Mark Filipak (ffmpeg) wrote:
>>>> That's exactly the point. It is not constant because ffmpeg calculates frame times in integer 
>>>> milliseconds, and thereby truncates or rounds.…
>>>
>>>
>>> Mark, what makes you so sure that it is FFmpeg which is truncating or rounding?
>>
>> The issue, Jim, is not with the MKV above. The issue is with the next video in the work flow: An 
>> MKV that was made from the MKV above but with '-vf settb=expr=1/360000,showinfo'. That 'showinfo' 
>> should have shown a 360000Hz time base. It does, but the PTSs are wrong.
> 
> 
> Well, you are spinning up multiple issues, Mark.

It's all aspects of one issue, Jim.

> Issue 1. Your contention that "ffmpeg calculates frame times in integer milliseconds". This branch 
> of the thread is about that claim of yours.

Not quite. When I explicitly set TB to 1/360000 via 'settb=expr=1/360000', the resulting PTSs are wrong.

> Answer: No, FFmpeg calculates frame times exactly. You authored the input file to millisecond time 
> resolution because that's what the format you chose encourages.

I did not author to millisecond resolution. The encoder did that. But that doesn't really matter, 
does it? If I take *any* video and 'settb=expr=1/360000', then the source's TB should be ignored, 
shouldn't it?

> Issue 2. Given an input file `input1.mkv`, which has varying frame times in millisecond resolution 
> which add up to 1001 ms per 30 frames, when you apply the FFmpeg `settb` filter, why are the output 
> Presentation Timestamp (PTS) values 11880, 24120, 36000, … instead of 12012, 24024, 36036, …?
> Answer: Because the input frame presentation times are 11,880/360,000 = 0.03300, 24,120/360,000 = 
> 0.06700, 36,000/360,000 = 0.10000, … which exactly matches the frame times of the input video, with 
> a 360kHz time base.

The PTSs should be 12012, 24024, 36036 because 1001/30000*360000=12012, 12012+12012=24024, and 
24024_12012=36036.

showinfo reports 11880, 24120, 36000 because that's what ffmpeg has calculated based on rounded ms 
(milliseconds).

Of course, (33ms/tick)*(360000ticks/s)=11880. That doesn't make it right. It's not 12012 because 
33.3[6..]ms has been rounded down to 33ms.

Imagine frame 1 of 4 videos:
            showinfo reports           actual PTS                        rounding bounds
            V                          V                                 V
video #1:  11880 pts_time: 0.033   ...11700 pts_time: 0.0325       <<== lower bound
video #2:  11880 pts_time: 0.033   ...11880 pts_time: 0.033        <<== ffmpeg uses
video #3:  11880 pts_time: 0.033   ...12012 pts_time: 0.0333[6..]  <<== actual video
video #4:  11880 pts_time: 0.033   ...12059 pts_time: 0.0334[9..]  <<== upper bound

FFmpeg assigns a deltaPTS of 11880 to all of them. That's what happens when actual frame periods are 
rounded to integer ms.

FFmpeg is taking the fps, turning it into rounded ms, then turning the rounded ms into PTSs. That's 
not right. It should take the fps, turn that into exact PTSs, and then turn exact PTSs into approx 
ms -- actually, ms is superfluous because codecs key into PTSs.

> Issue 3. What integer size does FFmpeg use to store PTS values? You initiated this thread with that 
> question, remember?

I know that MPEG PTS is 33 bits. I don't know for sure what ffmpeg does, except that it doesn't set 
PTSs properly.


More information about the ffmpeg-user mailing list