1

I have noticed that ffmpeg sometimes writes invalid PTS timestamps when using -t on a M2TS input. Is this my mistake or is it a bug in ffmpeg?

Steps to reproduce:

Download this M2TS file and save it as 1.m2ts. This file contains one video stream with 25 fps (that is, one video frame takes exactly 0.04 s (40 ms)) and one audio stream that isn't interesting for the purpose of this post.

Open the terminal, navigate into the directory that contains the file, and execute the following command:

ffmpeg.exe -i 1.m2ts -codec copy -map 0 -t 2 2.m2ts

Now examine the output file, 2.m2ts, and observe that the latest video frame's PTS is 3.560, and that the PTS of the previous video frame is 3.480.

This obviously is wrong. After the frame at 3.480, the next frame should be presented at 3.520, not 3.560. Either ffmpeg has dropped the video frame that should come at 3.520, or it has written a wrong PTS to the last video frame (3.560 instead of 3.520).

Of course, when talking about "last" or "before", I am referring to the order of the frames in time (more precisely, I have ordered the video frames by PTS), not the order of the frames in the file.

Question:

Is this a bug in ffmpeg, or is there a mistake in my command above?

ffmpeg version:

ffmpeg version 2024-01-14-git-34a47b97de-full_build-www.gyan.dev on Windows 10 x64 Enterprise

Further remarks:

I have noticed the problem with several of my M2TS files; I don't have the time to test other formats. Unfortunately, I cannot provide my files for download. That's the reason why I have linked to another file.

In other words: The problem is not specific for the file I have linked. Rather, I have encountered it with various video frame rates and audio tracks in various M2TS files from different sources.

I didn't investigate the audio tracks with respect to similar gaps yet.

Binarus
  • 2,039
  • 14
  • 27

1 Answers1

2

This not a bug, just a result of B-frames dependency.

The video stream has has 3 types of frames:

  • I-Frame - not dependent on any frame.
  • P-Frame - dependent only on frames before it.
  • B-Frame - dependent on frames before and on frames after the encoded frame.

The last encoded video frame that matches 2 seconds duration is a B-Frame.
The first frame in 2.m2ts has pts_time=1.48.
The last frame in 2.m2ts supposed to have pts_time=3.48.

Since the frame with pts_time=3.48 is a B-Frame, it depends on the P-Frame that encoded after it.
The P-Frame that comes after has pts_time=3.56.
Without that P-Frame, it is impossible to decode the B-Frame, so the muxer keeps that last extra P-Frame.


Analyzing the video frames using FFprobe:

We may use FFprobe for getting the pts_time and pict_type of the video streams of the 2 files.

ffprobe -select_streams v -of default=noprint_wrappers=1:nokey=1 -show_entries frame=pts_time,pict_type 1.m2ts > 1.txt

ffprobe -select_streams v -of default=noprint_wrappers=1:nokey=1 -show_entries frame=pts_time,pict_type 2.m2ts > 2.txt

Comparing the files using comparing tool, gives the following result:

1.txt       2.txt
------      ------

1.480000 1.480000 I I ... B B 3.040000 3.040000 B B 3.080000 3.080000 P P 3.120000 3.120000 B B 3.160000 3.160000 B B 3.200000 3.200000 B B 3.240000 3.240000 P P 3.280000 3.280000 B B 3.320000 3.320000 B B 3.360000 3.360000 B B 3.400000 3.400000 P P 3.440000 3.440000 B B 3.480000 3.480000 B B 3.520000
B
3.560000 3.560000 P P

Note that the B-Frame with pts_time=3.52 is not required for decoding 3.48 (3.48 is dependent on the 3.56 P-Frame but not on that 3.52 B-Frame), so 3.52 is skipped.

Rotem
  • 3,346