mirror of https://github.com/odrling/Aegisub
Move the serialization for the subtitles providers to SubtitlesProvider
This commit is contained in:
parent
b40370c93d
commit
6a1321e1df
|
@ -41,7 +41,6 @@
|
||||||
#include "dialog_style_editor.h"
|
#include "dialog_style_editor.h"
|
||||||
#include "help_button.h"
|
#include "help_button.h"
|
||||||
#include "include/aegisub/context.h"
|
#include "include/aegisub/context.h"
|
||||||
#include "include/aegisub/subtitles_provider.h"
|
|
||||||
#include "libresrc/libresrc.h"
|
#include "libresrc/libresrc.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "persist_location.h"
|
#include "persist_location.h"
|
||||||
|
|
|
@ -42,9 +42,12 @@ class AssFile;
|
||||||
struct VideoFrame;
|
struct VideoFrame;
|
||||||
|
|
||||||
class SubtitlesProvider {
|
class SubtitlesProvider {
|
||||||
|
std::vector<char> buffer;
|
||||||
|
virtual void LoadSubtitles(const char *data, size_t len)=0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~SubtitlesProvider() = default;
|
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;
|
virtual void DrawSubtitles(VideoFrame &dst, double time)=0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -67,10 +67,6 @@ struct Writer {
|
||||||
TextFileWriter file;
|
TextFileWriter file;
|
||||||
AssEntryGroup group = AssEntryGroup::INFO;
|
AssEntryGroup group = AssEntryGroup::INFO;
|
||||||
|
|
||||||
Writer(std::ostream &ostr) : file(ostr) {
|
|
||||||
file.WriteLineToFile("[Script Info]");
|
|
||||||
}
|
|
||||||
|
|
||||||
Writer(agi::fs::path const& filename, std::string const& encoding)
|
Writer(agi::fs::path const& filename, std::string const& encoding)
|
||||||
: file(filename, encoding)
|
: file(filename, encoding)
|
||||||
{
|
{
|
||||||
|
@ -134,15 +130,3 @@ void AssSubtitleFormat::WriteFile(const AssFile *src, agi::fs::path const& filen
|
||||||
writer.Write(src->Events);
|
writer.Write(src->Events);
|
||||||
writer.WriteExtradata(src->Extradata);
|
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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -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 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, int time);
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,6 +16,10 @@
|
||||||
|
|
||||||
#include "include/aegisub/subtitles_provider.h"
|
#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 "factory_manager.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "subtitles_provider_csri.h"
|
#include "subtitles_provider_csri.h"
|
||||||
|
@ -63,3 +67,31 @@ std::unique_ptr<SubtitlesProvider> SubtitlesProviderFactory::GetProvider(agi::Ba
|
||||||
|
|
||||||
throw error;
|
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());
|
||||||
|
}
|
||||||
|
|
|
@ -41,7 +41,6 @@
|
||||||
|
|
||||||
#include <libaegisub/make_unique.h>
|
#include <libaegisub/make_unique.h>
|
||||||
|
|
||||||
#include <boost/interprocess/streams/vectorstream.hpp>
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
@ -63,17 +62,18 @@ class CSRISubtitlesProvider final : public SubtitlesProvider {
|
||||||
std::unique_ptr<csri_inst, closer> instance;
|
std::unique_ptr<csri_inst, closer> instance;
|
||||||
csri_rend *renderer = nullptr;
|
csri_rend *renderer = nullptr;
|
||||||
|
|
||||||
boost::interprocess::basic_ovectorstream<std::vector<char>> ostr;
|
void LoadSubtitles(const char *data, size_t len) override {
|
||||||
|
std::lock_guard<std::mutex> lock(csri_mutex);
|
||||||
|
instance.reset(csri_open_mem(renderer, data, len, nullptr));
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CSRISubtitlesProvider(std::string subType);
|
CSRISubtitlesProvider(std::string subType);
|
||||||
|
|
||||||
void LoadSubtitles(AssFile *subs, int time);
|
void DrawSubtitles(VideoFrame &dst, double time) override;
|
||||||
void DrawSubtitles(VideoFrame &dst, double time);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
CSRISubtitlesProvider::CSRISubtitlesProvider(std::string type) {
|
CSRISubtitlesProvider::CSRISubtitlesProvider(std::string type) {
|
||||||
ostr.reserve(0x10000);
|
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(csri_mutex);
|
std::lock_guard<std::mutex> lock(csri_mutex);
|
||||||
for (csri_rend *cur = csri_renderer_default(); cur; cur = csri_renderer_next(cur)) {
|
for (csri_rend *cur = csri_renderer_default(); cur; cur = csri_renderer_next(cur)) {
|
||||||
if (type == csri_renderer_info(cur)->name) {
|
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);
|
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<std::mutex> lock(csri_mutex);
|
|
||||||
instance.reset(csri_open_mem(renderer, ostr.vector().data(), ostr.vector().size(), nullptr));
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSRISubtitlesProvider::DrawSubtitles(VideoFrame &dst, double time) {
|
void CSRISubtitlesProvider::DrawSubtitles(VideoFrame &dst, double time) {
|
||||||
if (!instance) return;
|
if (!instance) return;
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,6 @@
|
||||||
#include "ass_style.h"
|
#include "ass_style.h"
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
#include "include/aegisub/subtitles_provider.h"
|
#include "include/aegisub/subtitles_provider.h"
|
||||||
#include "subtitle_format_ass.h"
|
|
||||||
#include "video_frame.h"
|
#include "video_frame.h"
|
||||||
|
|
||||||
#include <libaegisub/background_runner.h>
|
#include <libaegisub/background_runner.h>
|
||||||
|
@ -51,8 +50,6 @@
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <boost/gil/gil_all.hpp>
|
#include <boost/gil/gil_all.hpp>
|
||||||
#include <boost/interprocess/streams/vectorstream.hpp>
|
|
||||||
#include <boost/range/algorithm_ext/push_back.hpp>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
|
@ -131,7 +128,12 @@ public:
|
||||||
LibassSubtitlesProvider(agi::BackgroundRunner *br);
|
LibassSubtitlesProvider(agi::BackgroundRunner *br);
|
||||||
~LibassSubtitlesProvider();
|
~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<char *>(data), len, nullptr);
|
||||||
|
if (!ass_track) throw "libass failed to load subtitles.";
|
||||||
|
}
|
||||||
|
|
||||||
void DrawSubtitles(VideoFrame &dst, double time) override;
|
void DrawSubtitles(VideoFrame &dst, double time) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -155,16 +157,6 @@ LibassSubtitlesProvider::~LibassSubtitlesProvider() {
|
||||||
if (ass_track) ass_free_track(ass_track);
|
if (ass_track) ass_free_track(ass_track);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LibassSubtitlesProvider::LoadSubtitles(AssFile *subs, int time) {
|
|
||||||
boost::interprocess::basic_ovectorstream<std::vector<char>> 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<char *>(ostr.vector().data()), ostr.vector().size(), nullptr);
|
|
||||||
if (!ass_track) throw "libass failed to load subtitles.";
|
|
||||||
}
|
|
||||||
|
|
||||||
#define _r(c) ((c)>>24)
|
#define _r(c) ((c)>>24)
|
||||||
#define _g(c) (((c)>>16)&0xFF)
|
#define _g(c) (((c)>>16)&0xFF)
|
||||||
#define _b(c) (((c)>>8)&0xFF)
|
#define _b(c) (((c)>>8)&0xFF)
|
||||||
|
|
|
@ -38,7 +38,6 @@
|
||||||
|
|
||||||
TextFileWriter::TextFileWriter(agi::fs::path const& filename, std::string encoding)
|
TextFileWriter::TextFileWriter(agi::fs::path const& filename, std::string encoding)
|
||||||
: file(new agi::io::Save(filename, true))
|
: file(new agi::io::Save(filename, true))
|
||||||
, ostr(file->Get())
|
|
||||||
, newline(NEWLINE)
|
, newline(NEWLINE)
|
||||||
{
|
{
|
||||||
if (encoding.empty())
|
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() {
|
TextFileWriter::~TextFileWriter() {
|
||||||
// Explicit empty destructor required with a unique_ptr to an incomplete class
|
// 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) {
|
void TextFileWriter::WriteLineToFile(std::string const& line, bool addLineBreak) {
|
||||||
if (conv) {
|
if (conv) {
|
||||||
auto converted = conv->Convert(line);
|
auto converted = conv->Convert(line);
|
||||||
ostr.write(converted.data(), converted.size());
|
file->Get().write(converted.data(), converted.size());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ostr.write(line.data(), line.size());
|
file->Get().write(line.data(), line.size());
|
||||||
|
|
||||||
if (addLineBreak)
|
if (addLineBreak)
|
||||||
ostr.write(newline.data(), newline.size());
|
file->Get().write(newline.data(), newline.size());
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,12 +32,10 @@ namespace agi {
|
||||||
class TextFileWriter {
|
class TextFileWriter {
|
||||||
std::unique_ptr<agi::io::Save> file;
|
std::unique_ptr<agi::io::Save> file;
|
||||||
std::unique_ptr<agi::charset::IconvWrapper> conv;
|
std::unique_ptr<agi::charset::IconvWrapper> conv;
|
||||||
std::ostream &ostr;
|
|
||||||
std::string newline;
|
std::string newline;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TextFileWriter(agi::fs::path const& filename, std::string encoding="");
|
TextFileWriter(agi::fs::path const& filename, std::string encoding="");
|
||||||
TextFileWriter(std::ostream &ostr);
|
|
||||||
~TextFileWriter();
|
~TextFileWriter();
|
||||||
|
|
||||||
void WriteLineToFile(std::string const& line, bool addLineBreak=true);
|
void WriteLineToFile(std::string const& line, bool addLineBreak=true);
|
||||||
|
|
Loading…
Reference in New Issue