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 timecodes, bool normalize) +: timecodes(std::move(timecodes)) +{ + SetFromTimecodes(normalize); +} + Framerate::Framerate(std::vector timecodes) : timecodes(std::move(timecodes)) { - SetFromTimecodes(); + SetFromTimecodes(false); +} + +Framerate::Framerate(std::initializer_list timecodes, bool normalize) +: timecodes(timecodes) +{ + SetFromTimecodes(normalize); } Framerate::Framerate(std::initializer_list 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(*file, encoding); if (line == "# timecode format v2") { copy(line_iterator(*file, encoding), line_iterator(), 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 timecodes); Framerate(std::initializer_list timecodes); + Framerate(std::vector timecodes, bool normalize); + Framerate(std::initializer_list 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 #include +#include + 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 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) {