From 95914161ee6a4544ebe1ac8a4eace1fcd82787cd Mon Sep 17 00:00:00 2001
From: odrling <florianbadie@odrling.xyz>
Date: Sat, 9 Jan 2021 05:03:30 +0100
Subject: [PATCH] normalize timecodes for every formats except matroska

---
 libaegisub/common/vfr.cpp           | 22 ++++++++++++++++++----
 libaegisub/include/libaegisub/vfr.h |  4 +++-
 src/video_provider_ffmpegsource.cpp | 10 ++++++++--
 3 files changed, 29 insertions(+), 7 deletions(-)

diff --git a/libaegisub/common/vfr.cpp b/libaegisub/common/vfr.cpp
index 49ba8fe0e..5a8ec76be 100644
--- a/libaegisub/common/vfr.cpp
+++ b/libaegisub/common/vfr.cpp
@@ -151,23 +151,37 @@ Framerate::Framerate(int64_t numerator, int64_t denominator, bool drop)
 	timecodes.push_back(0);
 }
 
-void Framerate::SetFromTimecodes() {
+void Framerate::SetFromTimecodes(bool normalize) {
 	validate_timecodes(timecodes);
+	if (normalize)
+		normalize_timecodes(timecodes);
 	denominator = default_denominator;
 	numerator = (timecodes.size() - 1) * denominator * 1000 / timecodes.back();
 	last = (timecodes.size() - 1) * denominator * 1000;
 }
 
+Framerate::Framerate(std::vector<int> timecodes, bool normalize)
+: timecodes(std::move(timecodes))
+{
+	SetFromTimecodes(normalize);
+}
+
 Framerate::Framerate(std::vector<int> timecodes)
 : timecodes(std::move(timecodes))
 {
-	SetFromTimecodes();
+	SetFromTimecodes(false);
+}
+
+Framerate::Framerate(std::initializer_list<int> timecodes, bool normalize)
+: timecodes(timecodes)
+{
+	SetFromTimecodes(normalize);
 }
 
 Framerate::Framerate(std::initializer_list<int> timecodes)
 : timecodes(timecodes)
 {
-	SetFromTimecodes();
+	SetFromTimecodes(false);
 }
 
 Framerate::Framerate(fs::path const& filename)
@@ -178,7 +192,7 @@ Framerate::Framerate(fs::path const& filename)
 	auto line = *line_iterator<std::string>(*file, encoding);
 	if (line == "# timecode format v2") {
 		copy(line_iterator<int>(*file, encoding), line_iterator<int>(), back_inserter(timecodes));
-		SetFromTimecodes();
+		SetFromTimecodes(false);
 		return;
 	}
 	if (line == "# timecode format v1" || line.substr(0, 7) == "Assume ") {
diff --git a/libaegisub/include/libaegisub/vfr.h b/libaegisub/include/libaegisub/vfr.h
index 4f6e1b15d..11adead71 100644
--- a/libaegisub/include/libaegisub/vfr.h
+++ b/libaegisub/include/libaegisub/vfr.h
@@ -74,7 +74,7 @@ class Framerate {
 	bool drop = false;
 
 	/// Set FPS properties from the timecodes vector
-	void SetFromTimecodes();
+	void SetFromTimecodes(bool normalize);
 public:
 	Framerate(Framerate const&) = default;
 	Framerate& operator=(Framerate const&) = default;
@@ -107,6 +107,8 @@ public:
 	/// @param timecodes Vector of frame start times in milliseconds
 	Framerate(std::vector<int> timecodes);
 	Framerate(std::initializer_list<int> timecodes);
+	Framerate(std::vector<int> timecodes, bool normalize);
+	Framerate(std::initializer_list<int> timecodes, bool normalize);
 
 	/// @brief Get the frame visible at a given time
 	/// @param ms Time in milliseconds
diff --git a/src/video_provider_ffmpegsource.cpp b/src/video_provider_ffmpegsource.cpp
index 0b4853c21..0f46b5c11 100644
--- a/src/video_provider_ffmpegsource.cpp
+++ b/src/video_provider_ffmpegsource.cpp
@@ -43,6 +43,8 @@
 #include <libaegisub/fs.h>
 #include <libaegisub/make_unique.h>
 
+#include <boost/algorithm/string.hpp>
+
 namespace {
 typedef enum AGI_ColorSpaces {
 	AGI_CS_RGB = 0,
@@ -160,6 +162,8 @@ void FFmpegSourceVideoProvider::LoadVideo(agi::fs::path const& filename, std::st
 			throw VideoNotSupported(ErrInfo.Buffer);
 	}
 
+	const char* container = FFMS_GetFormatNameI(Indexer);
+
 	std::map<int, std::string> TrackList = GetTracksOfType(Indexer, FFMS_TYPE_VIDEO);
 	if (TrackList.size() <= 0)
 		throw VideoNotSupported("no video tracks found");
@@ -294,8 +298,10 @@ void FFmpegSourceVideoProvider::LoadVideo(agi::fs::path const& filename, std::st
 	}
 	if (TimecodesVector.size() < 2)
 		Timecodes = 25.0;
-	else
-		Timecodes = agi::vfr::Framerate(TimecodesVector);
+	else {
+		bool normalize = !boost::algorithm::contains(container, "matroska");
+		Timecodes = agi::vfr::Framerate(TimecodesVector, normalize);
+	}
 }
 
 void FFmpegSourceVideoProvider::GetFrame(int n, VideoFrame &out) {
-- 
GitLab