[FFmpeg-user] Dropping 1 frame every n seconds

Moritz Barsnick barsnick at gmx.net
Mon Jun 1 15:07:30 CEST 2015


Hi Steve,

On Sun, May 31, 2015 at 23:51:54 +0100, Steve wrote:

> Sorry I probably should have explained better, I don’t just want to
> drop the frame and leave it blank or adjust the frame rate from 25 to
> 24fps. Essentially I want to remove it, then bring the following
> frames forward one frame to fill it’s place. So the 25fps rate is
> maintained, but every nth second, one frame is dropped and the
> adjacent frames brought forward by one frame. I hope this will allow
> the picture to keep in sync with the sound once the audio is speeded
> up.

I think I understood quite well from the fact that you wish to speed up
your video and audio by 2 or 4 percent. But please be more precise,
even if the answers can be generic. What are you actually trying to
achieve? What's the purpose?

May I guess this: For whatever reason, you want to speed up your video,
e.g. by two or four percent. You want video and audio to keep in sync,
and you want to retain the original frame rate. Right?

General examples are given here:
https://trac.ffmpeg.org/wiki/How%20to%20speed%20up%20/%20slow%20down%20a%20video

The first thing to note - which those examples hint at - it that ffmpeg
apparently retains the frame rate automatically, if not told otherwise
by "-r".

Why I chose to suggest:
  setpts=24/25*PTS
is because you were suggesting to drop 1 in 25 frames. I was only
showing how to speed up the remaining 24 frames, by achieving 25/24ths
of the rate. Now, mathematically speaking, if you speed up audio by 4%,
you would have to choose 26/25ths of the speed, dropping one in 26
frames! ;-) Important math for sync.

So you probably want:
  setpts=25/26*PTS

ffmpeg automatically (in my experiments) tries to retain the rate of 25
fps, and does this by dropping or adding frames as necessary. (Doc for
"-r" says: "As an output option, duplicate or drop input frames to
achieve constant output frame rate fps.") What I don't know is
_exactly_ which frames ffmpeg drops. I assume those of which the PTS is
too far off 1/fps. But the results should be fine for you. I
experimented with a 25fps video with atempo=2.0 and setpts=0.5*PTS, and
the result was fine, i.e. had 25fps, was in sync, was double speed, and
had half the amount of frames of the original video.

> I guess I could a/ export to an image sequence b/ delete the relevant
> frames c/ renumber the remaining frames to be sequential and then d/
> re-encode it at 25fps with the modified audio but I wonder if that
> approach is overkill and whether a filter can be configured to do it?

That's what you would do if you dropped frames with the select filter
and let setpts calculate new consecutive PTS for you:

  select=mod(n\,26),setpts=N/(25*TB)

(Untested.)
The video would look jumpy once per second (missing frame), but PTS
would be exactly 1/25 second apart for each frame. I don't know whether
that's important for any formats or players.

> One other thing I forgot to add, the source is all i-frame only so no
> problem with dropping or moving p or b frames

No, frame dropping and/or recalculation of PTS means re-encoding
anyway, so the original structure is not taken into consideration.

HTH,
Moritz

P.S.: Question to the developers: Is PTS really to do with frame
      encoding, or could it also be a bitstream filter, and thereby
      applicable with stream copy?


More information about the ffmpeg-user mailing list