Skip to content

Commit

Permalink
Stop shifting timecodes to start at 0ms
Browse files Browse the repository at this point in the history
This reverts commit 1dedfb1.
Such files exist in the wild (one example being a large set of old CR
rips, see https://redvice.org/2018/crunchyroll-83ms-delay/) and players
like mpv also respect this video delay (at least they do now, they might
not have when the linked commit was made).

Fixes TypesettingTools#21.
Fixes TypesettingTools#169.
  • Loading branch information
arch1t3cht authored and odrling committed Dec 19, 2024
1 parent 921249c commit 9b5a41e
Show file tree
Hide file tree
Showing 2 changed files with 4 additions and 30 deletions.
16 changes: 4 additions & 12 deletions libaegisub/common/vfr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,6 @@ void validate_timecodes(std::vector<int> const& timecodes) {
throw InvalidFramerate("Timecodes are all identical");
}

/// @brief Shift timecodes so that frame 0 starts at time 0
/// @param timecodes List of timecodes to normalize
void normalize_timecodes(std::vector<int> &timecodes) {
if (int front = timecodes.front())
boost::for_each(timecodes, [=](int &tc) { tc -= front; });
}

// A "start,end,fps" line in a v1 timecode file
struct TimecodeRange {
int start;
Expand Down Expand Up @@ -153,9 +146,8 @@ Framerate::Framerate(int64_t numerator, int64_t denominator, bool drop)

void Framerate::SetFromTimecodes() {
validate_timecodes(timecodes);
normalize_timecodes(timecodes);
denominator = default_denominator;
numerator = (timecodes.size() - 1) * denominator * 1000 / timecodes.back();
numerator = (timecodes.size() - 1) * denominator * 1000 / (timecodes.back() - timecodes.front());
last = (timecodes.size() - 1) * denominator * 1000;
}

Expand Down Expand Up @@ -221,8 +213,8 @@ int Framerate::FrameAtTime(int ms, Time type) const {
if (type == END)
return FrameAtTime(ms - 1);

if (ms < 0)
return int((ms * numerator / denominator - 999) / 1000);
if (ms < timecodes.front())
return int(((ms - timecodes.front()) * numerator / denominator - 999) / 1000);

if (ms > timecodes.back())
return ((ms + 1) * numerator - last - numerator / 2 + (1000 * denominator - 1)) / (1000 * denominator) + timecodes.size() - 2;
Expand All @@ -245,7 +237,7 @@ int Framerate::TimeAtFrame(int frame, Time type) const {
}

if (frame < 0)
return (int)(frame * denominator * 1000 / numerator);
return (int)(frame * denominator * 1000 / numerator) + timecodes.front();

if (frame >= (signed)timecodes.size()) {
int64_t frames_past_end = frame - (int)timecodes.size() + 1;
Expand Down
18 changes: 0 additions & 18 deletions tests/tests/vfr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -394,24 +394,6 @@ TEST(lagi_vfr, load_v1_save_v2_ovr) {
EXPECT_TRUE(validate_save("data/vfr/in/v2_100_frames_30_with_override.txt", "data/vfr/out/v2_100_frames_30_with_override.txt"));
}

TEST(lagi_vfr, nonzero_start_time) {
Framerate fps;

ASSERT_NO_THROW(fps = Framerate({ 10, 20, 30, 40, 50 }));
EXPECT_EQ(0, fps.TimeAtFrame(0, EXACT));
EXPECT_EQ(10, fps.TimeAtFrame(1, EXACT));
EXPECT_EQ(20, fps.TimeAtFrame(2, EXACT));
EXPECT_EQ(30, fps.TimeAtFrame(3, EXACT));
EXPECT_EQ(40, fps.TimeAtFrame(4, EXACT));

ASSERT_NO_THROW(fps = Framerate({ -10, 20, 30, 40, 50 }));
EXPECT_EQ(0, fps.TimeAtFrame(0, EXACT));
EXPECT_EQ(30, fps.TimeAtFrame(1, EXACT));
EXPECT_EQ(40, fps.TimeAtFrame(2, EXACT));
EXPECT_EQ(50, fps.TimeAtFrame(3, EXACT));
EXPECT_EQ(60, fps.TimeAtFrame(4, EXACT));
}

TEST(lagi_vfr, rational_timebase) {
Framerate fps;

Expand Down

0 comments on commit 9b5a41e

Please sign in to comment.