Log in

View Full Version : Odd behaviour of ChangeFPS


neily
11th February 2005, 19:54
Hi,

On searching, I came across mention of the odd behaviour of ChangeFPS, but don't know whether it is a bug, a feature, or if there is a work around.

I have some collections of images that I want to animate. I know that I can do this in AVISynth, but it's pretty easy in VDub now. The target is PAL DVD. So I resize the images and save them at 1 fps in VDub using an MJPEG codec. I then feed the AVI into AVISynth, do ChangeFPS(12).AssumeFPS(25), with the expectation of getting a 25fps sequence with 12 duplicates of each original image in sequence. What you get is 6 dups of the first image, and 18 dups of the last image!

Have I missed a trick? If it's a bug/feature, is there another way to do this?

stickboy
11th February 2005, 20:41
It's a bug. You might want to try RepeatEveryFrame from my ApplyEvery plugin ([url=http://www.avisynth.org/stickboy/).

neily
11th February 2005, 22:36
@stickboy,

Thanks. RepeatEveryFrame seems to work a charm. There was I thinking I was going to have to resave all my images with 12 versions suffixed a to l to achieve my goal.

ChangeFPS has been around for ages. I can't believe it's buggy. I keep on trying to stray away from AVISynth because of all the bugs, but sadly I keep coming back to it as for some things it is the best or only tool for the job.

IanB
14th February 2005, 03:12
@Stickboy,

I'm not convinced it's a bug, but it is unexpected. The relevant code :-// src\filters\fps.cpp

a = __int64(vi.fps_numerator) * new_denominator;
b = __int64(vi.fps_denominator) * new_numerator;
vi.SetFPS(new_numerator, new_denominator);
...
int getframe = int(((__int64)n * a + (b>>1)) / b);
The example above :- a=1, b=12, (b>>1)=6 gives getframe = (n + 6) / 12

Please convince me it should be :- getframe = (n * a) / b in all cases.

IanB

stickboy
14th February 2005, 06:36
Originally posted by IanB
I'm not convinced it's a bug, but it is unexpected.Well, unexpected behavior is a bug. I don't think there's any question what should happen if you use ChangeFPS to increase the framerate by a whole multiple.Please convince me it should be :- getframe = (n * a) / b in all cases.I don't know that it should be. Probably not.

Perhaps ChangeFPS just should have a special case for this situation.

rawr
17th February 2005, 01:01
Even if that's not true in all cases IanB, do you deny the fact that in the case (new_fps % old_fps == 0) each frame should be duplicated an equal number of times? If you don't, that's a bug.

rawr.

IanB
20th February 2005, 06:46
C'mon guys,

Somebody please do the formal proof, I'd feel a lot happier "fixing" the code if someone independantly derived the answer I proposed (or proved it wrong).

Hints :-
1. Limit as a%b -> 0+
2. Limit as a%b -> 1-
3. Limit as a%b -> 0.5+/-

Special code always bites you sooner or later, best to just get the general case correct.

IanB