diff --git a/libaegisub/common/vfr.cpp b/libaegisub/common/vfr.cpp index c82fcdbee..377e29b34 100644 --- a/libaegisub/common/vfr.cpp +++ b/libaegisub/common/vfr.cpp @@ -225,7 +225,7 @@ int Framerate::FrameAtTime(int ms, Time type) const { return int((ms * numerator / denominator - 999) / 1000); if (ms > timecodes.back()) - return int((ms * numerator - last + denominator - 1) / denominator / 1000) + (int)timecodes.size() - 1; + return int((ms * numerator - numerator / 2 - last + numerator - 1) / denominator / 1000) + (int)timecodes.size() - 1; return (int)distance(lower_bound(timecodes.rbegin(), timecodes.rend(), ms, std::greater()), timecodes.rend()) - 1; } diff --git a/tests/tests/vfr.cpp b/tests/tests/vfr.cpp index a9b8f3acf..90a02d4c6 100644 --- a/tests/tests/vfr.cpp +++ b/tests/tests/vfr.cpp @@ -149,6 +149,12 @@ TEST(lagi_vfr, cfr_round_trip_exact) { for (int i = -10; i < 11; i++) { EXPECT_EQ(i, fps.FrameAtTime(fps.TimeAtFrame(i))); } + + ASSERT_NO_THROW(fps = Framerate(24000, 1001)); + int frames[] = {-100, -10, -1, 0, 1, 10, 100, 6820}; + for (int i : frames) { + EXPECT_EQ(i, fps.FrameAtTime(fps.TimeAtFrame(i))); + } } TEST(lagi_vfr, cfr_round_trip_start) { @@ -157,6 +163,12 @@ TEST(lagi_vfr, cfr_round_trip_start) { for (int i = -10; i < 11; i++) { EXPECT_EQ(i, fps.FrameAtTime(fps.TimeAtFrame(i, START), START)); } + + ASSERT_NO_THROW(fps = Framerate(24000, 1001)); + int frames[] = {-100, -10, -1, 0, 1, 10, 100, 6820}; + for (int i : frames) { + EXPECT_EQ(i, fps.FrameAtTime(fps.TimeAtFrame(i, START), START)); + } } TEST(lagi_vfr, cfr_round_trip_end) { @@ -165,6 +177,12 @@ TEST(lagi_vfr, cfr_round_trip_end) { for (int i = -10; i < 11; i++) { EXPECT_EQ(i, fps.FrameAtTime(fps.TimeAtFrame(i, END), END)); } + + ASSERT_NO_THROW(fps = Framerate(24000, 1001)); + int frames[] = {-100, -10, -1, 0, 1, 10, 100, 6820}; + for (int i : frames) { + EXPECT_EQ(i, fps.FrameAtTime(fps.TimeAtFrame(i, END), END)); + } } TEST(lagi_vfr, vfr_round_trip_exact) {