17

I have an MP4 file containing H264 video (25 FPS). Some timestamps are not correct (for reasons...). Can I process the file and have only the timestamps regenerated without reencoding? I've tried this

ffmpeg -r 25 -i infile -c copy outfile

but the timestamps in outfile are still like in the original even though the documentation for"-r" says:

As an input option, ignore any timestamps stored in the file and instead generate timestamps assuming constant frame rate fps.

I've also tried the suggestion mentioned here at the bottom:

ffmpeg -fflags +genpts -i infile -c copy outfile

This also doesn't change the timestamps in the outfile. Any other way to perform this task? Timestamps are kind of metadata, so I think it should be possible somehow.

  • Show the full console output of your first command. – Gyan Dec 22 '16 at 05:58
  • After hours of trying everything up&down, I don't have the raw material anymore. However, I think it's an abstract question and doesn't require specific material to answer. So, would you say the command line _should_ work? Though, maybe I will try to recreate the scenario to provide the console output. Thanks anyway. –  Dec 22 '16 at 12:40
  • No. In copy mode, ffmpeg does not rescale the input PTS of packetized streams, like those in MP4. Adding an extra step by extracting a raw stream and retiming that will work. – Gyan Dec 22 '16 at 13:02
  • Finally it worked this way. But I only succeeded with mp4box, not with ffmpeg. Finally, the result is perfect. Thanks. –  Dec 23 '16 at 13:53
  • It can be done with ffmpeg but if you extract a raw stream. – Gyan Dec 23 '16 at 13:56
  • 4
    @CryGuy Can you please post the solution with a tad more detail? – Linef4ult Jul 27 '17 at 13:29

2 Answers2

16

It turns out that the -r option only works for raw stream data. (This can be an H.264 stream... it does not have to be just pixel data.)

In this example, I'm using MP4 containers. First, extract the stream:

ffmpeg -i source.mp4 -map 0:v -vcodec copy -bsf:v h264_mp4toannexb source-video.h264

Next, take that stream and re-mux it, but with a specific frame rate and generated timestamps.

ffmpeg -fflags +genpts -r 60 -i source-video.h264 -vcodec copy output.mp4
Brad
  • 5,686
  • 8
  • 52
  • 83
  • 13
    What exactly `-bsf:v h264_mp4toannexb` does here ? And 2ndly what happens if `+genpts` is not applied ? – the kamilz Nov 30 '18 at 07:27
  • 3
    an h264 decoder needs to know where the "pieces" (NALU's) start in the bitstream. When the h264 data is inside an MP4 container, the MP4 container takes care of this (with the sample table). If you want "raw" h264 without container, you need to add additional "start codes" to each NALU, as defined in annex B of the h.264 standard. the h264_mp4toannexb bitstream filter does exactly this: add start-codes to every NALU. – Niobos Jan 26 '21 at 11:30
  • Hi, This speeds up the video – pentanol Mar 22 '22 at 04:01
  • @pentanol I'd imagine so, since we're purposefully extracting raw video, nuking its timestamps, and making our own. – Brad Mar 22 '22 at 04:02
  • @Brad Is it possible to do the same by replicating the frame rate of the source (the input) rather than speicfying it (the 60) manually? – pentanol Mar 22 '22 at 04:06
  • @pentanol You could note the frame rate of the source on the first run, but keep in mind that the frame rate can change as you go. If you had a perfectly timed source video, it'd be fine (or close to it). But, I suspect your source is missing frames here and there, or isn't at the frame rate specified. This probably isn't a good solution for you unless you have to deal with the raw video like this. – Brad Mar 22 '22 at 04:13
7

The -fps_mode option is used to control output timestamps, not the -r option.  The drop parameter resets input timestamps and generates new ones.

ffmpeg -i source.mp4 -fps_mode drop -map 0:v -vcodec copy output.mp4

The -r option before the input tells FFmpeg to read the specified number of frames in constant mode. FFmpeg sometimes has a hard time figuring out the input frames count.  By specifying the exact number, you eliminate misunderstandings.

The -r option works with all type of data, raw or encoded.

By the way H.264 is the exact opposite of raw.

Camille Goudeseune
  • 2,297
  • 4
  • 32
  • 41
Pistacio
  • 119
  • 1
  • 3