Push the dropping of non-visible lines into the serialization logic
Makes things way less gross and trivially faster.
This commit is contained in:
parent
7a5c92aaee
commit
af20d31699
6 changed files with 16 additions and 34 deletions
|
@ -44,7 +44,7 @@ struct VideoFrame;
|
||||||
class SubtitlesProvider {
|
class SubtitlesProvider {
|
||||||
public:
|
public:
|
||||||
virtual ~SubtitlesProvider() = default;
|
virtual ~SubtitlesProvider() = default;
|
||||||
virtual void LoadSubtitles(AssFile *subs)=0;
|
virtual void LoadSubtitles(AssFile *subs, int time = -1)=0;
|
||||||
virtual void DrawSubtitles(VideoFrame &dst, double time)=0;
|
virtual void DrawSubtitles(VideoFrame &dst, double time)=0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -135,9 +135,14 @@ void AssSubtitleFormat::WriteFile(const AssFile *src, agi::fs::path const& filen
|
||||||
writer.WriteExtradata(src->Extradata);
|
writer.WriteExtradata(src->Extradata);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssSubtitleFormat::WriteToStream(const AssFile *src, std::ostream &ostr) {
|
void AssSubtitleFormat::WriteToStream(const AssFile *src, std::ostream &ostr, int time) {
|
||||||
Writer writer(ostr);
|
Writer writer(ostr);
|
||||||
writer.Write(src->Info);
|
writer.Write(src->Info);
|
||||||
writer.Write(src->Styles);
|
writer.Write(src->Styles);
|
||||||
writer.Write(src->Events);
|
|
||||||
|
writer.file.WriteLineToFile("[Events]");
|
||||||
|
for (auto const& line : src->Events) {
|
||||||
|
if (!line.Comment && time < 0 || !(line.Start > time || line.End <= time))
|
||||||
|
writer.file.WriteLineToFile(line.GetEntryData());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,5 +28,5 @@ public:
|
||||||
|
|
||||||
void ReadFile(AssFile *target, agi::fs::path const& filename, agi::vfr::Framerate const& fps, std::string const& forceEncoding) const override;
|
void ReadFile(AssFile *target, agi::fs::path const& filename, agi::vfr::Framerate const& fps, std::string const& forceEncoding) const override;
|
||||||
void WriteFile(const AssFile *src, agi::fs::path const& filename, agi::vfr::Framerate const& fps, std::string const& encoding) const override;
|
void WriteFile(const AssFile *src, agi::fs::path const& filename, agi::vfr::Framerate const& fps, std::string const& encoding) const override;
|
||||||
static void WriteToStream(const AssFile *src, std::ostream &ostr);
|
static void WriteToStream(const AssFile *src, std::ostream &ostr, int time);
|
||||||
};
|
};
|
||||||
|
|
|
@ -73,7 +73,7 @@ class CSRISubtitlesProvider final : public SubtitlesProvider {
|
||||||
public:
|
public:
|
||||||
CSRISubtitlesProvider(std::string subType);
|
CSRISubtitlesProvider(std::string subType);
|
||||||
|
|
||||||
void LoadSubtitles(AssFile *subs);
|
void LoadSubtitles(AssFile *subs, int time);
|
||||||
void DrawSubtitles(VideoFrame &dst, double time);
|
void DrawSubtitles(VideoFrame &dst, double time);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -92,9 +92,9 @@ CSRISubtitlesProvider::CSRISubtitlesProvider(std::string type) {
|
||||||
throw agi::InternalError("CSRI renderer vanished between initial list and creation?", 0);
|
throw agi::InternalError("CSRI renderer vanished between initial list and creation?", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSRISubtitlesProvider::LoadSubtitles(AssFile *subs) {
|
void CSRISubtitlesProvider::LoadSubtitles(AssFile *subs, int time) {
|
||||||
ostr.rdbuf()->clear();
|
ostr.rdbuf()->clear();
|
||||||
AssSubtitleFormat::WriteToStream(subs, ostr);
|
AssSubtitleFormat::WriteToStream(subs, ostr, time);
|
||||||
|
|
||||||
if (tempfile.empty())
|
if (tempfile.empty())
|
||||||
tempfile = unique_path(config::path->Decode("?temp/csri-%%%%-%%%%-%%%%-%%%%.ass"));
|
tempfile = unique_path(config::path->Decode("?temp/csri-%%%%-%%%%-%%%%-%%%%.ass"));
|
||||||
|
|
|
@ -131,7 +131,7 @@ public:
|
||||||
LibassSubtitlesProvider(agi::BackgroundRunner *br);
|
LibassSubtitlesProvider(agi::BackgroundRunner *br);
|
||||||
~LibassSubtitlesProvider();
|
~LibassSubtitlesProvider();
|
||||||
|
|
||||||
void LoadSubtitles(AssFile *subs) override;
|
void LoadSubtitles(AssFile *subs, int time) override;
|
||||||
void DrawSubtitles(VideoFrame &dst, double time) override;
|
void DrawSubtitles(VideoFrame &dst, double time) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -155,10 +155,10 @@ LibassSubtitlesProvider::~LibassSubtitlesProvider() {
|
||||||
if (ass_track) ass_free_track(ass_track);
|
if (ass_track) ass_free_track(ass_track);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LibassSubtitlesProvider::LoadSubtitles(AssFile *subs) {
|
void LibassSubtitlesProvider::LoadSubtitles(AssFile *subs, int time) {
|
||||||
boost::interprocess::basic_ovectorstream<std::vector<char>> ostr;
|
boost::interprocess::basic_ovectorstream<std::vector<char>> ostr;
|
||||||
ostr.reserve(0x4000);
|
ostr.reserve(0x4000);
|
||||||
AssSubtitleFormat::WriteToStream(subs, ostr);
|
AssSubtitleFormat::WriteToStream(subs, ostr, time);
|
||||||
|
|
||||||
if (ass_track) ass_free_track(ass_track);
|
if (ass_track) ass_free_track(ass_track);
|
||||||
ass_track = ass_read_memory(library, const_cast<char *>(ostr.vector().data()), ostr.vector().size(), nullptr);
|
ass_track = ass_read_memory(library, const_cast<char *>(ostr.vector().data()), ostr.vector().size(), nullptr);
|
||||||
|
|
|
@ -29,11 +29,8 @@
|
||||||
#include "video_frame.h"
|
#include "video_frame.h"
|
||||||
#include "video_provider_manager.h"
|
#include "video_provider_manager.h"
|
||||||
|
|
||||||
#include <libaegisub/address_of_adaptor.h>
|
|
||||||
#include <libaegisub/dispatch.h>
|
#include <libaegisub/dispatch.h>
|
||||||
|
|
||||||
#include <boost/range/adaptor/indirected.hpp>
|
|
||||||
#include <boost/range/algorithm_ext.hpp>
|
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
@ -67,28 +64,8 @@ std::shared_ptr<VideoFrame> ThreadedFrameSource::ProcFrame(int frame_number, dou
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
AssFixStylesFilter().ProcessSubs(subs.get(), nullptr);
|
AssFixStylesFilter().ProcessSubs(subs.get(), nullptr);
|
||||||
|
|
||||||
single_frame = frame_number;
|
single_frame = frame_number;
|
||||||
// Copying a nontrivially sized AssFile is fairly slow, so
|
subs_provider->LoadSubtitles(subs.get(), time);
|
||||||
// instead muck around with its innards to just temporarily
|
|
||||||
// remove the non-visible lines without deleting them
|
|
||||||
std::deque<AssDialogue*> full;
|
|
||||||
boost::push_back(full, subs->Events | agi::address_of);
|
|
||||||
subs->Events.remove_if([=](AssDialogue const& diag) {
|
|
||||||
return diag.Start > time || diag.End <= time;
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
subs_provider->LoadSubtitles(subs.get());
|
|
||||||
|
|
||||||
subs->Events.clear();
|
|
||||||
boost::push_back(subs->Events, full | boost::adaptors::indirected);
|
|
||||||
}
|
|
||||||
catch (...) {
|
|
||||||
subs->Events.clear();
|
|
||||||
boost::push_back(subs->Events, full | boost::adaptors::indirected);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue