Move the serialization for the subtitles providers to SubtitlesProvider

This commit is contained in:
Thomas Goyne 2014-05-02 10:39:38 -07:00
parent b40370c93d
commit 6a1321e1df
9 changed files with 51 additions and 60 deletions

View File

@ -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"

View File

@ -42,9 +42,12 @@ class AssFile;
struct VideoFrame;
class SubtitlesProvider {
std::vector<char> 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;
};

View File

@ -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());
}
}

View File

@ -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);
};

View File

@ -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<SubtitlesProvider> 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());
}

View File

@ -41,7 +41,6 @@
#include <libaegisub/make_unique.h>
#include <boost/interprocess/streams/vectorstream.hpp>
#include <mutex>
#ifdef WIN32
@ -63,17 +62,18 @@ class CSRISubtitlesProvider final : public SubtitlesProvider {
std::unique_ptr<csri_inst, closer> instance;
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:
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<std::mutex> 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<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) {
if (!instance) return;

View File

@ -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 <libaegisub/background_runner.h>
@ -51,8 +50,6 @@
#include <atomic>
#include <boost/gil/gil_all.hpp>
#include <boost/interprocess/streams/vectorstream.hpp>
#include <boost/range/algorithm_ext/push_back.hpp>
#include <memory>
#include <mutex>
@ -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<char *>(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<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 _g(c) (((c)>>16)&0xFF)
#define _b(c) (((c)>>8)&0xFF)

View File

@ -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());
}

View File

@ -32,12 +32,10 @@ namespace agi {
class TextFileWriter {
std::unique_ptr<agi::io::Save> file;
std::unique_ptr<agi::charset::IconvWrapper> 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);