Browse Source

normalize timecodes for every formats except matroska

master
odrling 9 months ago
parent
commit
95914161ee
  1. 22
      libaegisub/common/vfr.cpp
  2. 4
      libaegisub/include/libaegisub/vfr.h
  3. 10
      src/video_provider_ffmpegsource.cpp

22
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 ") {

4
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

10
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) {

Loading…
Cancel
Save