diff --git a/src/dialog_style_editor.cpp b/src/dialog_style_editor.cpp index c36050fac..fc80ef604 100644 --- a/src/dialog_style_editor.cpp +++ b/src/dialog_style_editor.cpp @@ -41,7 +41,6 @@ #include "dialog_style_editor.h" #include "help_button.h" #include "include/aegisub/context.h" -#include "include/aegisub/subtitles_provider.h" #include "libresrc/libresrc.h" #include "options.h" #include "persist_location.h" diff --git a/src/include/aegisub/subtitles_provider.h b/src/include/aegisub/subtitles_provider.h index 9fa9d8ace..532d94a3b 100644 --- a/src/include/aegisub/subtitles_provider.h +++ b/src/include/aegisub/subtitles_provider.h @@ -42,9 +42,12 @@ class AssFile; struct VideoFrame; class SubtitlesProvider { + std::vector buffer; + virtual void LoadSubtitles(const char *data, size_t len)=0; + public: virtual ~SubtitlesProvider() = default; - virtual void LoadSubtitles(AssFile *subs, int time = -1)=0; + void LoadSubtitles(AssFile *subs, int time = -1); virtual void DrawSubtitles(VideoFrame &dst, double time)=0; }; diff --git a/src/subtitle_format_ass.cpp b/src/subtitle_format_ass.cpp index 4f91bb162..83c2738cd 100644 --- a/src/subtitle_format_ass.cpp +++ b/src/subtitle_format_ass.cpp @@ -67,10 +67,6 @@ struct Writer { TextFileWriter file; AssEntryGroup group = AssEntryGroup::INFO; - Writer(std::ostream &ostr) : file(ostr) { - file.WriteLineToFile("[Script Info]"); - } - Writer(agi::fs::path const& filename, std::string const& encoding) : file(filename, encoding) { @@ -134,15 +130,3 @@ void AssSubtitleFormat::WriteFile(const AssFile *src, agi::fs::path const& filen writer.Write(src->Events); writer.WriteExtradata(src->Extradata); } - -void AssSubtitleFormat::WriteToStream(const AssFile *src, std::ostream &ostr, int time) { - Writer writer(ostr); - writer.Write(src->Info); - writer.Write(src->Styles); - - 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()); - } -} diff --git a/src/subtitle_format_ass.h b/src/subtitle_format_ass.h index 3c636a21b..61dfab131 100644 --- a/src/subtitle_format_ass.h +++ b/src/subtitle_format_ass.h @@ -28,5 +28,4 @@ public: 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; - static void WriteToStream(const AssFile *src, std::ostream &ostr, int time); }; diff --git a/src/subtitles_provider.cpp b/src/subtitles_provider.cpp index 4edf37507..fb443623d 100644 --- a/src/subtitles_provider.cpp +++ b/src/subtitles_provider.cpp @@ -16,6 +16,10 @@ #include "include/aegisub/subtitles_provider.h" +#include "ass_dialogue.h" +#include "ass_file.h" +#include "ass_info.h" +#include "ass_style.h" #include "factory_manager.h" #include "options.h" #include "subtitles_provider_csri.h" @@ -63,3 +67,31 @@ std::unique_ptr SubtitlesProviderFactory::GetProvider(agi::Ba throw error; } + +void SubtitlesProvider::LoadSubtitles(AssFile *subs, int time) { + buffer.clear(); + + auto push_header = [&](const char *str) { + buffer.insert(buffer.end(), str, str + strlen(str)); + }; + auto push_line = [&](std::string const& str) { + buffer.insert(buffer.end(), &str[0], &str[0] + str.size()); + buffer.push_back('\n'); + }; + + push_header("[Script Info]\n"); + for (auto const& line : subs->Info) + push_line(line.GetEntryData()); + + push_header("[V4+ Styles]\n"); + for (auto const& line : subs->Info) + push_line(line.GetEntryData()); + + push_header("[Events]\n"); + for (auto const& line : subs->Events) { + if (!line.Comment && time < 0 || !(line.Start > time || line.End <= time)) + push_line(line.GetEntryData()); + } + + LoadSubtitles(&buffer[0], buffer.size()); +} diff --git a/src/subtitles_provider_csri.cpp b/src/subtitles_provider_csri.cpp index 984ccb0c9..58eb0e33b 100644 --- a/src/subtitles_provider_csri.cpp +++ b/src/subtitles_provider_csri.cpp @@ -41,7 +41,6 @@ #include -#include #include #ifdef WIN32 @@ -63,17 +62,18 @@ class CSRISubtitlesProvider final : public SubtitlesProvider { std::unique_ptr instance; csri_rend *renderer = nullptr; - boost::interprocess::basic_ovectorstream> ostr; + void LoadSubtitles(const char *data, size_t len) override { + std::lock_guard lock(csri_mutex); + instance.reset(csri_open_mem(renderer, data, len, nullptr)); + } + public: CSRISubtitlesProvider(std::string subType); - void LoadSubtitles(AssFile *subs, int time); - void DrawSubtitles(VideoFrame &dst, double time); + void DrawSubtitles(VideoFrame &dst, double time) override; }; CSRISubtitlesProvider::CSRISubtitlesProvider(std::string type) { - ostr.reserve(0x10000); - std::lock_guard lock(csri_mutex); for (csri_rend *cur = csri_renderer_default(); cur; cur = csri_renderer_next(cur)) { if (type == csri_renderer_info(cur)->name) { @@ -86,14 +86,6 @@ CSRISubtitlesProvider::CSRISubtitlesProvider(std::string type) { throw agi::InternalError("CSRI renderer vanished between initial list and creation?", 0); } -void CSRISubtitlesProvider::LoadSubtitles(AssFile *subs, int time) { - ostr.rdbuf()->clear(); - AssSubtitleFormat::WriteToStream(subs, ostr, time); - - std::lock_guard lock(csri_mutex); - instance.reset(csri_open_mem(renderer, ostr.vector().data(), ostr.vector().size(), nullptr)); -} - void CSRISubtitlesProvider::DrawSubtitles(VideoFrame &dst, double time) { if (!instance) return; diff --git a/src/subtitles_provider_libass.cpp b/src/subtitles_provider_libass.cpp index 4f0766ee6..183fa236f 100644 --- a/src/subtitles_provider_libass.cpp +++ b/src/subtitles_provider_libass.cpp @@ -40,7 +40,6 @@ #include "ass_style.h" #include "compat.h" #include "include/aegisub/subtitles_provider.h" -#include "subtitle_format_ass.h" #include "video_frame.h" #include @@ -51,8 +50,6 @@ #include #include -#include -#include #include #include @@ -131,7 +128,12 @@ public: LibassSubtitlesProvider(agi::BackgroundRunner *br); ~LibassSubtitlesProvider(); - void LoadSubtitles(AssFile *subs, int time) override; + void LoadSubtitles(const char *data, size_t len) override { + if (ass_track) ass_free_track(ass_track); + ass_track = ass_read_memory(library, const_cast(data), len, nullptr); + if (!ass_track) throw "libass failed to load subtitles."; + } + void DrawSubtitles(VideoFrame &dst, double time) override; }; @@ -155,16 +157,6 @@ LibassSubtitlesProvider::~LibassSubtitlesProvider() { if (ass_track) ass_free_track(ass_track); } -void LibassSubtitlesProvider::LoadSubtitles(AssFile *subs, int time) { - boost::interprocess::basic_ovectorstream> ostr; - ostr.reserve(0x4000); - AssSubtitleFormat::WriteToStream(subs, ostr, time); - - if (ass_track) ass_free_track(ass_track); - ass_track = ass_read_memory(library, const_cast(ostr.vector().data()), ostr.vector().size(), nullptr); - if (!ass_track) throw "libass failed to load subtitles."; -} - #define _r(c) ((c)>>24) #define _g(c) (((c)>>16)&0xFF) #define _b(c) (((c)>>8)&0xFF) diff --git a/src/text_file_writer.cpp b/src/text_file_writer.cpp index 2a104ae7c..32d6bcfdd 100644 --- a/src/text_file_writer.cpp +++ b/src/text_file_writer.cpp @@ -38,7 +38,6 @@ TextFileWriter::TextFileWriter(agi::fs::path const& filename, std::string encoding) : file(new agi::io::Save(filename, true)) -, ostr(file->Get()) , newline(NEWLINE) { if (encoding.empty()) @@ -57,13 +56,6 @@ TextFileWriter::TextFileWriter(agi::fs::path const& filename, std::string encodi } } -TextFileWriter::TextFileWriter(std::ostream &ostr) -: ostr(ostr) -, newline(NEWLINE) -{ - WriteLineToFile("\xEF\xBB\xBF", false); -} - TextFileWriter::~TextFileWriter() { // Explicit empty destructor required with a unique_ptr to an incomplete class } @@ -71,11 +63,11 @@ TextFileWriter::~TextFileWriter() { void TextFileWriter::WriteLineToFile(std::string const& line, bool addLineBreak) { if (conv) { auto converted = conv->Convert(line); - ostr.write(converted.data(), converted.size()); + file->Get().write(converted.data(), converted.size()); } else - ostr.write(line.data(), line.size()); + file->Get().write(line.data(), line.size()); if (addLineBreak) - ostr.write(newline.data(), newline.size()); + file->Get().write(newline.data(), newline.size()); } diff --git a/src/text_file_writer.h b/src/text_file_writer.h index c1d7c8726..8aa3ea875 100644 --- a/src/text_file_writer.h +++ b/src/text_file_writer.h @@ -32,12 +32,10 @@ namespace agi { class TextFileWriter { std::unique_ptr file; std::unique_ptr conv; - std::ostream &ostr; std::string newline; public: TextFileWriter(agi::fs::path const& filename, std::string encoding=""); - TextFileWriter(std::ostream &ostr); ~TextFileWriter(); void WriteLineToFile(std::string const& line, bool addLineBreak=true);