mirror of https://github.com/odrling/Aegisub
Redesign export filters to not be static singletons, removing the need to jump through hoops to avoid static initialization order issues
Originally committed to SVN as r5258.
This commit is contained in:
parent
83a461ca63
commit
af92002d8c
|
@ -39,178 +39,53 @@
|
|||
#include "ass_export_filter.h"
|
||||
#include "ass_file.h"
|
||||
|
||||
|
||||
/// @brief Constructor
|
||||
///
|
||||
AssExportFilter::AssExportFilter() {
|
||||
hidden = false;
|
||||
autoExporter = false;
|
||||
initialized = false;
|
||||
FilterList *fil = AssExportFilterChain::GetUnpreparedFilterList();
|
||||
fil->push_back(this);
|
||||
AssExportFilter::AssExportFilter(wxString const& name, wxString const& description, int priority)
|
||||
: name(name)
|
||||
, priority(priority)
|
||||
, autoExporter(false)
|
||||
, hidden(false)
|
||||
, description(description)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// @brief Destructor
|
||||
///
|
||||
AssExportFilter::~AssExportFilter() {
|
||||
try {
|
||||
Unregister();
|
||||
}
|
||||
catch (...) {
|
||||
// Ignore error
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// @brief Register
|
||||
/// @param name
|
||||
/// @param priority
|
||||
///
|
||||
void AssExportFilter::Register (wxString name,int priority) {
|
||||
// Check if it's registered
|
||||
// Changed this to an assert, since this kind of error should really only happen during dev. -jfs
|
||||
// (Actually the list of regged filters should rather be looped through and check that this object isn't in.)
|
||||
assert(RegisterName == _T(""));
|
||||
|
||||
void AssExportFilterChain::Register(AssExportFilter *filter) {
|
||||
// Remove pipes from name
|
||||
name.Replace(_T("|"),_T(""));
|
||||
filter->name.Replace("|", "");
|
||||
|
||||
FilterList::iterator begin = GetFilterList()->begin();
|
||||
FilterList::iterator end = GetFilterList()->end();
|
||||
|
||||
int filter_copy = 0;
|
||||
wxString tmpnam;
|
||||
if (filter_copy == 0) {
|
||||
tmpnam = name;
|
||||
} else {
|
||||
wxString tmpnam = filter->name;
|
||||
if (false) {
|
||||
try_new_name:
|
||||
tmpnam = wxString::Format(_T("%s (%d)"), name.c_str(), filter_copy);
|
||||
tmpnam = wxString::Format("%s (%d)", filter->name, filter_copy);
|
||||
}
|
||||
|
||||
// Check if name exists
|
||||
FilterList::iterator begin = AssExportFilterChain::GetFilterList()->begin();
|
||||
FilterList::iterator end = AssExportFilterChain::GetFilterList()->end();
|
||||
for (FilterList::iterator cur=begin;cur!=end;cur++) {
|
||||
if ((*cur)->RegisterName == tmpnam) {
|
||||
if ((*cur)->name == tmpnam) {
|
||||
// Instead of just failing and making a big noise about it, let multiple filters share name, but append something to the later arrivals -jfs
|
||||
filter_copy++;
|
||||
goto try_new_name;
|
||||
}
|
||||
}
|
||||
|
||||
// Set name
|
||||
RegisterName = tmpnam;
|
||||
Priority = priority;
|
||||
filter->name = tmpnam;
|
||||
|
||||
// Look for place to insert
|
||||
bool inserted = false;
|
||||
for (FilterList::iterator cur=begin;cur!=end;cur++) {
|
||||
if ((*cur)->Priority < Priority) {
|
||||
AssExportFilterChain::GetFilterList()->insert(cur,this);
|
||||
inserted = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!inserted) AssExportFilterChain::GetFilterList()->push_back(this);
|
||||
while (begin != end && (*begin)->priority >= filter->priority) ++begin;
|
||||
GetFilterList()->insert(begin, filter);
|
||||
}
|
||||
|
||||
void AssExportFilterChain::Unregister(AssExportFilter *filter) {
|
||||
if (find(GetFilterList()->begin(), GetFilterList()->end(), filter) == GetFilterList()->end())
|
||||
throw wxString::Format("Unregister export filter: name \"%s\" is not registered.", filter->name);
|
||||
|
||||
|
||||
/// @brief Unregister
|
||||
///
|
||||
void AssExportFilter::Unregister () {
|
||||
// Check if it's registered
|
||||
if (!IsRegistered()) throw wxString::Format(_T("Unregister export filter: name \"%s\" is not registered."), RegisterName.c_str());
|
||||
|
||||
// Unregister
|
||||
RegisterName = _T("");
|
||||
AssExportFilterChain::GetFilterList()->remove(this);
|
||||
GetFilterList()->remove(filter);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// @brief Checks if it's registered
|
||||
/// @return
|
||||
///
|
||||
bool AssExportFilter::IsRegistered() {
|
||||
// Check name
|
||||
if (RegisterName.IsEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check list
|
||||
bool found = false;
|
||||
FilterList::iterator begin = AssExportFilterChain::GetFilterList()->begin();
|
||||
FilterList::iterator end = AssExportFilterChain::GetFilterList()->end();
|
||||
for (FilterList::iterator cur=begin;cur!=end;cur++) {
|
||||
if ((*cur) == this) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// @brief Get sizer
|
||||
/// @param parent
|
||||
/// @return
|
||||
///
|
||||
wxWindow *AssExportFilter::GetConfigDialogWindow(wxWindow *parent) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// @brief Config dialog OK
|
||||
/// @param IsDefault
|
||||
///
|
||||
void AssExportFilter::LoadSettings(bool IsDefault) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// @brief Description reader
|
||||
/// @return
|
||||
///
|
||||
const wxString& AssExportFilter::GetDescription() const {
|
||||
return description;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// DOCME
|
||||
std::auto_ptr<AssExportFilterChain> AssExportFilterChain::instance;
|
||||
|
||||
|
||||
|
||||
/// @brief Get list
|
||||
/// @return
|
||||
///
|
||||
FilterList *AssExportFilterChain::GetFilterList() {
|
||||
if (!instance.get()) instance.reset(new AssExportFilterChain());
|
||||
return &(instance->Filters);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// @brief Get unprepared list
|
||||
/// @return
|
||||
///
|
||||
FilterList *AssExportFilterChain::GetUnpreparedFilterList() {
|
||||
if (!instance.get()) instance.reset(new AssExportFilterChain());
|
||||
return &(instance->Unprepared);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// @brief Prepare filters
|
||||
///
|
||||
void AssExportFilterChain::PrepareFilters() {
|
||||
if (!instance.get()) instance.reset(new AssExportFilterChain());
|
||||
for (FilterList::iterator cur=instance->Unprepared.begin();cur!=instance->Unprepared.end();cur++) {
|
||||
(*cur)->Init();
|
||||
}
|
||||
instance->Unprepared.clear();
|
||||
static FilterList instance;
|
||||
return &instance;
|
||||
}
|
||||
|
|
|
@ -58,24 +58,19 @@ typedef std::list<AssExportFilter*> FilterList;
|
|||
///
|
||||
/// DOCME
|
||||
class AssExportFilterChain {
|
||||
friend class AssExportFilter;
|
||||
friend class AssExporter;
|
||||
|
||||
private:
|
||||
|
||||
/// DOCME
|
||||
/// The list of registered filters
|
||||
FilterList Filters;
|
||||
|
||||
/// DOCME
|
||||
FilterList Unprepared;
|
||||
|
||||
/// DOCME
|
||||
static std::auto_ptr<AssExportFilterChain> instance;
|
||||
/// Get the singleton instance
|
||||
static FilterList *GetFilterList();
|
||||
static FilterList *GetUnpreparedFilterList();
|
||||
|
||||
AssExportFilterChain() { }
|
||||
public:
|
||||
static void PrepareFilters();
|
||||
/// Register an export filter
|
||||
static void Register(AssExportFilter *filter);
|
||||
/// Unregister an export filter; must have been registered
|
||||
static void Unregister(AssExportFilter *filter);
|
||||
};
|
||||
|
||||
/// DOCME
|
||||
|
@ -87,41 +82,33 @@ class AssExportFilter {
|
|||
friend class AssExporter;
|
||||
friend class AssExportFilterChain;
|
||||
|
||||
private:
|
||||
/// This filter's name
|
||||
wxString name;
|
||||
|
||||
/// DOCME
|
||||
wxString RegisterName;
|
||||
|
||||
/// DOCME
|
||||
int Priority;
|
||||
/// Higher priority = run earlier
|
||||
int priority;
|
||||
|
||||
protected:
|
||||
|
||||
/// DOCME
|
||||
/// Should this filter be used when sending subtitles to the subtitle provider
|
||||
bool autoExporter;
|
||||
|
||||
/// DOCME
|
||||
/// Should this filter be hidden from the user
|
||||
bool hidden;
|
||||
|
||||
/// DOCME
|
||||
bool initialized;
|
||||
|
||||
/// DOCME
|
||||
/// User-visible description of this filter
|
||||
wxString description;
|
||||
|
||||
void Register(wxString name,int priority=0); // Register the filter with specific name. Higher priority filters get the file to process first.
|
||||
void Unregister(); // Unregister the filter instance
|
||||
bool IsRegistered(); // Is this instance registered as a filter?
|
||||
virtual void Init()=0; // Tell it to initialize itself
|
||||
|
||||
public:
|
||||
AssExportFilter();
|
||||
virtual ~AssExportFilter();
|
||||
AssExportFilter(wxString const& name, wxString const& description, int priority = 0);
|
||||
virtual ~AssExportFilter() { };
|
||||
|
||||
const wxString& GetDescription() const;
|
||||
const wxString& GetDescription() const { return description; }
|
||||
|
||||
virtual void ProcessSubs(AssFile *subs, wxWindow *export_dialog=0)=0; // Process subtitles - this function must be overriden.
|
||||
virtual wxWindow *GetConfigDialogWindow(wxWindow *parent); // Draw setup controls - this function may optionally be overridden.
|
||||
virtual void LoadSettings(bool IsDefault); // Config dialog is done - extract data now.
|
||||
/// Process subtitles
|
||||
virtual void ProcessSubs(AssFile *subs, wxWindow *export_dialog=0)=0;
|
||||
/// Draw setup controls
|
||||
virtual wxWindow *GetConfigDialogWindow(wxWindow *parent) { return 0; }
|
||||
/// Config dialog is done - extract data now.
|
||||
virtual void LoadSettings(bool IsDefault) { }
|
||||
};
|
||||
|
||||
|
|
|
@ -67,13 +67,13 @@ void AssExporter::DrawSettings(wxWindow *parent,wxSizer *AddTo) {
|
|||
for (FilterList::iterator cur=begin;cur!=end;cur++) {
|
||||
// Make sure to construct static box sizer first, so it won't overlap
|
||||
// the controls on wxMac.
|
||||
box = new wxStaticBoxSizer(wxVERTICAL,parent,(*cur)->RegisterName);
|
||||
box = new wxStaticBoxSizer(wxVERTICAL,parent,(*cur)->name);
|
||||
window = (*cur)->GetConfigDialogWindow(parent);
|
||||
if (window) {
|
||||
box->Add(window,0,wxEXPAND,0);
|
||||
AddTo->Add(box,0,wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM,5);
|
||||
AddTo->Show(box,false);
|
||||
Sizers[(*cur)->RegisterName] = box;
|
||||
Sizers[(*cur)->name] = box;
|
||||
}
|
||||
else {
|
||||
delete box;
|
||||
|
@ -90,13 +90,14 @@ void AssExporter::AddFilter(wxString name) {
|
|||
FilterList::iterator begin = AssExportFilterChain::GetFilterList()->begin();
|
||||
FilterList::iterator end = AssExportFilterChain::GetFilterList()->end();
|
||||
for (FilterList::iterator cur=begin;cur!=end;cur++) {
|
||||
if ((*cur)->RegisterName == name) {
|
||||
if ((*cur)->name == name) {
|
||||
filter = *cur;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check
|
||||
if (!filter) throw wxString::Format(_T("Filter not found: %s"), name.c_str());
|
||||
if (!filter) throw wxString::Format("Filter not found: %s", name.c_str());
|
||||
|
||||
// Add to list
|
||||
Filters.push_back(filter);
|
||||
|
@ -122,7 +123,7 @@ wxArrayString AssExporter::GetAllFilterNames() {
|
|||
FilterList::iterator begin = AssExportFilterChain::GetFilterList()->begin();
|
||||
FilterList::iterator end = AssExportFilterChain::GetFilterList()->end();
|
||||
for (FilterList::iterator cur=begin;cur!=end;cur++) {
|
||||
if (!(*cur)->hidden) names.Add((*cur)->RegisterName);
|
||||
if (!(*cur)->hidden) names.Add((*cur)->name);
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
@ -172,9 +173,9 @@ wxString AssExporter::GetDescription(wxString name) {
|
|||
FilterList::iterator begin = AssExportFilterChain::GetFilterList()->begin();
|
||||
FilterList::iterator end = AssExportFilterChain::GetFilterList()->end();
|
||||
for (FilterList::iterator cur=begin;cur!=end;cur++) {
|
||||
if ((*cur)->RegisterName == name) {
|
||||
if ((*cur)->name == name) {
|
||||
return (*cur)->GetDescription();
|
||||
}
|
||||
}
|
||||
throw wxString::Format(_T("Filter not found: %s"), name.c_str());
|
||||
throw wxString::Format("Filter not found: %s", name.c_str());
|
||||
}
|
||||
|
|
|
@ -291,11 +291,10 @@ namespace Automation4 {
|
|||
///
|
||||
FeatureFilter::FeatureFilter(const wxString &_name, const wxString &_description, int _priority)
|
||||
: Feature(SCRIPTFEATURE_FILTER, _name)
|
||||
, AssExportFilter()
|
||||
, AssExportFilter(_name, _description, _priority)
|
||||
, config_dialog(0)
|
||||
{
|
||||
description = _description; // from AssExportFilter
|
||||
Register(_name, _priority);
|
||||
AssExportFilterChain::Register(this);
|
||||
}
|
||||
|
||||
|
||||
|
@ -303,7 +302,7 @@ namespace Automation4 {
|
|||
///
|
||||
FeatureFilter::~FeatureFilter()
|
||||
{
|
||||
Unregister();
|
||||
AssExportFilterChain::Unregister(this);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -34,9 +34,6 @@
|
|||
/// @ingroup export
|
||||
///
|
||||
|
||||
|
||||
///////////
|
||||
// Headers
|
||||
#include "config.h"
|
||||
|
||||
#include "ass_dialogue.h"
|
||||
|
@ -44,33 +41,12 @@
|
|||
#include "ass_override.h"
|
||||
#include "export_clean_info.h"
|
||||
|
||||
|
||||
/// @brief Constructor
|
||||
///
|
||||
AssTransformCleanInfoFilter::AssTransformCleanInfoFilter() {
|
||||
initialized = false;
|
||||
AssTransformCleanInfoFilter::AssTransformCleanInfoFilter()
|
||||
: AssExportFilter(_("Clean Script Info"), _("Removes all but the absolutely required fields from the Script Info section. You might want to run this on files that you plan to distribute in original form."))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// @brief Init
|
||||
/// @return
|
||||
///
|
||||
void AssTransformCleanInfoFilter::Init() {
|
||||
if (initialized) return;
|
||||
initialized = true;
|
||||
autoExporter = false;
|
||||
Register(_("Clean Script Info"),0);
|
||||
description = _("Removes all but the absolutely required fields from the Script Info section. You might want to run this on files that you plan to distribute in original form.");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// @brief Process
|
||||
/// @param subs
|
||||
/// @param export_dialog
|
||||
///
|
||||
void AssTransformCleanInfoFilter::ProcessSubs(AssFile *subs, wxWindow *export_dialog) {
|
||||
void AssTransformCleanInfoFilter::ProcessSubs(AssFile *subs, wxWindow *) {
|
||||
using std::list;
|
||||
AssEntry *curEntry;
|
||||
entryIter cur, next = subs->Line.begin();
|
||||
|
@ -78,53 +54,28 @@ void AssTransformCleanInfoFilter::ProcessSubs(AssFile *subs, wxWindow *export_di
|
|||
cur = next++;
|
||||
|
||||
curEntry = *cur;
|
||||
if (curEntry->group != _T("[Script Info]")) {
|
||||
if (curEntry->group != "[Script Info]") {
|
||||
continue;
|
||||
}
|
||||
if (curEntry->GetEntryData().IsEmpty()) {
|
||||
if (curEntry->GetEntryData().empty()) {
|
||||
continue;
|
||||
}
|
||||
if (curEntry->GetEntryData() == _T("[Script Info]")) {
|
||||
if (curEntry->GetEntryData() == "[Script Info]") {
|
||||
continue;
|
||||
}
|
||||
if (curEntry->GetEntryData().Left(1) == _T(";")) {
|
||||
if (curEntry->GetEntryData().Left(1) == ";") {
|
||||
continue;
|
||||
}
|
||||
|
||||
wxString field = curEntry->GetEntryData().Left(curEntry->GetEntryData().Find(_T(':'))).Lower();
|
||||
if (field != _T("scripttype") &&
|
||||
field != _T("collisions") &&
|
||||
field != _T("playresx") &&
|
||||
field != _T("playresy") &&
|
||||
field != _T("wrapstyle") &&
|
||||
field != _T("scaledborderandshadow")) {
|
||||
if (field != "scripttype" &&
|
||||
field != "collisions" &&
|
||||
field != "playresx" &&
|
||||
field != "playresy" &&
|
||||
field != "wrapstyle" &&
|
||||
field != "scaledborderandshadow") {
|
||||
delete curEntry;
|
||||
subs->Line.erase(cur);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// @brief Get dialog
|
||||
/// @param parent
|
||||
/// @return
|
||||
///
|
||||
wxWindow *AssTransformCleanInfoFilter::GetConfigDialogWindow(wxWindow *parent) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// @brief Load settings
|
||||
/// @param IsDefault
|
||||
///
|
||||
void AssTransformCleanInfoFilter::LoadSettings(bool IsDefault) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// DOCME
|
||||
AssTransformCleanInfoFilter AssTransformCleanInfoFilter::instance;
|
||||
|
||||
|
||||
|
|
|
@ -34,32 +34,16 @@
|
|||
/// @ingroup export
|
||||
///
|
||||
|
||||
|
||||
|
||||
|
||||
///////////
|
||||
// Headers
|
||||
#include "ass_export_filter.h"
|
||||
|
||||
|
||||
/// DOCME
|
||||
/// @class AssTransformCleanInfoFilter
|
||||
/// @brief DOCME
|
||||
/// @brief Removes all but the absolutely required fields from the Script Info section
|
||||
///
|
||||
/// DOCME
|
||||
class AssTransformCleanInfoFilter : public AssExportFilter {
|
||||
private:
|
||||
|
||||
/// DOCME
|
||||
static AssTransformCleanInfoFilter instance;
|
||||
|
||||
AssTransformCleanInfoFilter();
|
||||
void Init();
|
||||
|
||||
public:
|
||||
void ProcessSubs(AssFile *subs, wxWindow *export_dialog);
|
||||
wxWindow *GetConfigDialogWindow(wxWindow *parent);
|
||||
void LoadSettings(bool IsDefault);
|
||||
AssTransformCleanInfoFilter();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -46,37 +46,22 @@
|
|||
#include "ass_dialogue.h"
|
||||
#include "ass_style.h"
|
||||
|
||||
/// @brief Constructor
|
||||
AssFixStylesFilter::AssFixStylesFilter() {
|
||||
initialized = false;
|
||||
}
|
||||
|
||||
/// @brief Init
|
||||
void AssFixStylesFilter::Init() {
|
||||
if (initialized) return;
|
||||
initialized = true;
|
||||
AssFixStylesFilter::AssFixStylesFilter()
|
||||
: AssExportFilter(_("Fix Styles"), _("Fixes styles by replacing any style that isn't available on file with Default."), -5000)
|
||||
{
|
||||
autoExporter = true;
|
||||
Register(_("Fix Styles"),-5000);
|
||||
description = _("Fixes styles by replacing any style that isn't available on file with Default.");
|
||||
}
|
||||
|
||||
/// @brief Process
|
||||
/// @param subs
|
||||
/// @param export_dialog
|
||||
void AssFixStylesFilter::ProcessSubs(AssFile *subs, wxWindow *export_dialog) {
|
||||
void AssFixStylesFilter::ProcessSubs(AssFile *subs, wxWindow *) {
|
||||
wxArrayString styles = subs->GetStyles();
|
||||
std::for_each(styles.begin(), styles.end(), std::mem_fun_ref(&wxString::MakeLower));
|
||||
for_each(styles.begin(), styles.end(), std::mem_fun_ref(&wxString::MakeLower));
|
||||
styles.Sort();
|
||||
|
||||
for (entryIter cur=subs->Line.begin();cur!=subs->Line.end();cur++) {
|
||||
AssDialogue *diag = dynamic_cast<AssDialogue*>(*cur);
|
||||
if (diag) {
|
||||
if (AssDialogue *diag = dynamic_cast<AssDialogue*>(*cur)) {
|
||||
if (!std::binary_search(styles.begin(), styles.end(), diag->Style.Lower())) {
|
||||
diag->Style = L"Default";
|
||||
diag->Style = "Default";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// DOCME
|
||||
AssFixStylesFilter AssFixStylesFilter::instance;
|
||||
|
|
|
@ -34,29 +34,18 @@
|
|||
/// @ingroup export
|
||||
///
|
||||
|
||||
|
||||
|
||||
|
||||
///////////
|
||||
// Headers
|
||||
#include "ass_export_filter.h"
|
||||
|
||||
|
||||
/// DOCME
|
||||
/// @class AssFixStylesFilter
|
||||
/// @brief DOCME
|
||||
/// @brief Fixes styles by replacing any style that isn't available on file with Default
|
||||
///
|
||||
/// DOCME
|
||||
class AssFixStylesFilter : public AssExportFilter {
|
||||
private:
|
||||
|
||||
/// DOCME
|
||||
static AssFixStylesFilter instance;
|
||||
AssFixStylesFilter();
|
||||
void Init();
|
||||
|
||||
public:
|
||||
void ProcessSubs(AssFile *subs, wxWindow *export_dialog);
|
||||
AssFixStylesFilter();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -55,36 +55,16 @@
|
|||
#include "utils.h"
|
||||
#include "video_context.h"
|
||||
|
||||
/// DOCME
|
||||
/// @class LineData
|
||||
/// @brief DOCME
|
||||
///
|
||||
/// DOCME
|
||||
struct LineData {
|
||||
AssDialogue *line;
|
||||
int newStart;
|
||||
int newEnd;
|
||||
int newK;
|
||||
int oldK;
|
||||
};
|
||||
|
||||
/// IDs
|
||||
enum {
|
||||
Get_Input_From_Video = 2000
|
||||
};
|
||||
|
||||
AssTransformFramerateFilter::AssTransformFramerateFilter() {
|
||||
initialized = false;
|
||||
}
|
||||
|
||||
void AssTransformFramerateFilter::Init() {
|
||||
if (initialized) return;
|
||||
initialized = true;
|
||||
autoExporter = true;
|
||||
Register(_("Transform Framerate"),1000);
|
||||
description = _("Transform subtitle times, including those in override tags, from an input framerate to an output framerate.\n\nThis is useful for converting regular time subtitles to VFRaC time subtitles for hardsubbing.\nIt can also be used to convert subtitles to a different speed video, such as NTSC to PAL speedup.");
|
||||
Input = NULL;
|
||||
Output = NULL;
|
||||
AssTransformFramerateFilter::AssTransformFramerateFilter()
|
||||
: AssExportFilter(_("Transform Framerate"), _("Transform subtitle times, including those in override tags, from an input framerate to an output framerate.\n\nThis is useful for converting regular time subtitles to VFRaC time subtitles for hardsubbing.\nIt can also be used to convert subtitles to a different speed video, such as NTSC to PAL speedup."), 1000)
|
||||
, Input(0)
|
||||
, Output(0)
|
||||
{
|
||||
}
|
||||
|
||||
void AssTransformFramerateFilter::ProcessSubs(AssFile *subs, wxWindow *export_dialog) {
|
||||
|
@ -100,9 +80,10 @@ wxWindow *AssTransformFramerateFilter::GetConfigDialogWindow(wxWindow *parent) {
|
|||
wxSizer *InputSizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxString initialInput;
|
||||
wxButton *FromVideo = new wxButton(base,Get_Input_From_Video,_("From Video"));
|
||||
if (Input->IsLoaded()) initialInput = wxString::Format(_T("%2.3f"),Input->FPS());
|
||||
if (Input->IsLoaded())
|
||||
initialInput = wxString::Format("%2.3f",Input->FPS());
|
||||
else {
|
||||
initialInput = _T("23.976");
|
||||
initialInput = "23.976";
|
||||
FromVideo->Enable(false);
|
||||
}
|
||||
InputFramerate = new wxTextCtrl(base,-1,initialInput,wxDefaultPosition,wxSize(60,20));
|
||||
|
@ -179,18 +160,18 @@ int FORCEINLINE trunc_cs(int time) {
|
|||
return (time / 10) * 10;
|
||||
}
|
||||
|
||||
void AssTransformFramerateFilter::TransformTimeTags (wxString name,int n,AssOverrideParameter *curParam,void *curData) {
|
||||
void AssTransformFramerateFilter::TransformTimeTags(wxString name,int n,AssOverrideParameter *curParam,void *curData) {
|
||||
VariableDataType type = curParam->GetType();
|
||||
if (type != VARDATA_INT && type != VARDATA_FLOAT) return;
|
||||
|
||||
LineData *lineData = static_cast<LineData*>(curData);
|
||||
AssDialogue *curDiag = lineData->line;
|
||||
AssTransformFramerateFilter *instance = static_cast<AssTransformFramerateFilter*>(curData);
|
||||
AssDialogue *curDiag = instance->line;
|
||||
|
||||
int parVal = curParam->Get<int>();
|
||||
|
||||
switch (curParam->classification) {
|
||||
case PARCLASS_RELATIVE_TIME_START: {
|
||||
int value = instance.ConvertTime(trunc_cs(curDiag->Start.GetMS()) + parVal) - lineData->newStart;
|
||||
int value = instance->ConvertTime(trunc_cs(curDiag->Start.GetMS()) + parVal) - instance->newStart;
|
||||
|
||||
// An end time of 0 is actually the end time of the line, so ensure
|
||||
// nonzero is never converted to 0
|
||||
|
@ -202,13 +183,13 @@ void AssTransformFramerateFilter::TransformTimeTags (wxString name,int n,AssOver
|
|||
break;
|
||||
}
|
||||
case PARCLASS_RELATIVE_TIME_END:
|
||||
curParam->Set(lineData->newEnd - instance.ConvertTime(trunc_cs(curDiag->End.GetMS()) - parVal));
|
||||
curParam->Set(instance->newEnd - instance->ConvertTime(trunc_cs(curDiag->End.GetMS()) - parVal));
|
||||
break;
|
||||
case PARCLASS_KARAOKE: {
|
||||
int start = curDiag->Start.GetMS() / 10 + lineData->oldK + parVal;
|
||||
int value = (instance.ConvertTime(start * 10) - lineData->newStart) / 10 - lineData->newK;
|
||||
lineData->oldK += parVal;
|
||||
lineData->newK += value;
|
||||
int start = curDiag->Start.GetMS() / 10 + instance->oldK + parVal;
|
||||
int value = (instance->ConvertTime(start * 10) - instance->newStart) / 10 - instance->newK;
|
||||
instance->oldK += parVal;
|
||||
instance->newK += value;
|
||||
curParam->Set(value);
|
||||
break;
|
||||
}
|
||||
|
@ -223,18 +204,17 @@ void AssTransformFramerateFilter::TransformFrameRate(AssFile *subs) {
|
|||
AssDialogue *curDialogue = dynamic_cast<AssDialogue*>(*cur);
|
||||
|
||||
if (curDialogue) {
|
||||
LineData data;
|
||||
data.line = curDialogue;
|
||||
data.newK = 0;
|
||||
data.oldK = 0;
|
||||
data.newStart = trunc_cs(ConvertTime(curDialogue->Start.GetMS()));
|
||||
data.newEnd = trunc_cs(ConvertTime(curDialogue->End.GetMS()) + 9);
|
||||
line = curDialogue;
|
||||
newK = 0;
|
||||
oldK = 0;
|
||||
newStart = trunc_cs(ConvertTime(curDialogue->Start.GetMS()));
|
||||
newEnd = trunc_cs(ConvertTime(curDialogue->End.GetMS()) + 9);
|
||||
|
||||
// Process stuff
|
||||
curDialogue->ParseASSTags();
|
||||
curDialogue->ProcessParameters(TransformTimeTags,&data);
|
||||
curDialogue->Start.SetMS(data.newStart);
|
||||
curDialogue->End.SetMS(data.newEnd);
|
||||
curDialogue->ProcessParameters(TransformTimeTags, this);
|
||||
curDialogue->Start.SetMS(newStart);
|
||||
curDialogue->End.SetMS(newEnd);
|
||||
curDialogue->UpdateText();
|
||||
curDialogue->ClearBlocks();
|
||||
}
|
||||
|
@ -254,5 +234,3 @@ int AssTransformFramerateFilter::ConvertTime(int time) {
|
|||
|
||||
return newStart + newDur * dist;
|
||||
}
|
||||
|
||||
AssTransformFramerateFilter AssTransformFramerateFilter::instance;
|
||||
|
|
|
@ -45,38 +45,36 @@ class wxTextCtrl;
|
|||
|
||||
/// DOCME
|
||||
/// @class AssTransformFramerateFilter
|
||||
/// @brief DOCME
|
||||
/// @brief Transform subtitle times, including those in override tags, from an input framerate to an output framerate
|
||||
class AssTransformFramerateFilter : public AssExportFilter {
|
||||
/// The singleton instance of this filter
|
||||
static AssTransformFramerateFilter instance;
|
||||
AssDialogue *line;
|
||||
int newStart;
|
||||
int newEnd;
|
||||
int newK;
|
||||
int oldK;
|
||||
|
||||
// Yes, these are backwards
|
||||
const agi::vfr::Framerate *Input; /// Destination frame rate
|
||||
const agi::vfr::Framerate *Output; /// Source frame rate
|
||||
const agi::vfr::Framerate *Input; ///< Destination frame rate
|
||||
const agi::vfr::Framerate *Output; ///< Source frame rate
|
||||
|
||||
agi::vfr::Framerate t1,t2;
|
||||
|
||||
wxTextCtrl *InputFramerate; /// Input frame rate text box
|
||||
wxTextCtrl *OutputFramerate; /// Output frame rate text box
|
||||
wxTextCtrl *InputFramerate; ///< Input frame rate text box
|
||||
wxTextCtrl *OutputFramerate; ///< Output frame rate text box
|
||||
|
||||
wxRadioButton *RadioOutputCFR; /// CFR radio control
|
||||
wxRadioButton *RadioOutputVFR; /// VFR radio control
|
||||
wxRadioButton *RadioOutputCFR; ///< CFR radio control
|
||||
wxRadioButton *RadioOutputVFR; ///< VFR radio control
|
||||
|
||||
wxCheckBox *Reverse; /// Switch input and output
|
||||
wxCheckBox *Reverse; ///< Switch input and output
|
||||
|
||||
/// Constructor
|
||||
AssTransformFramerateFilter();
|
||||
|
||||
/// @brief Apply the transformation to a file
|
||||
/// @param subs File to process
|
||||
void TransformFrameRate(AssFile *subs);
|
||||
/// @brief Transform a single tag
|
||||
/// @param name Name of the tag
|
||||
/// @param curParam Current parameter being processed
|
||||
/// @param userdata LineData passed
|
||||
/// @param userdata Filter instance
|
||||
static void TransformTimeTags(wxString name,int,AssOverrideParameter *curParam,void *userdata);
|
||||
/// Initialize the singleton instance
|
||||
void Init();
|
||||
|
||||
/// @brief Convert a time from the input frame rate to the output frame rate
|
||||
/// @param time Time in ms to convert
|
||||
|
@ -88,6 +86,8 @@ class AssTransformFramerateFilter : public AssExportFilter {
|
|||
/// is in and the beginning of the next frame
|
||||
int ConvertTime(int time);
|
||||
public:
|
||||
/// Constructor
|
||||
AssTransformFramerateFilter();
|
||||
void ProcessSubs(AssFile *subs, wxWindow *export_dialog);
|
||||
wxWindow *GetConfigDialogWindow(wxWindow *parent);
|
||||
void LoadSettings(bool IsDefault);
|
||||
|
|
|
@ -67,6 +67,8 @@
|
|||
#endif
|
||||
#include "charset_conv.h"
|
||||
#include "compat.h"
|
||||
#include "export_clean_info.h"
|
||||
#include "export_fixstyle.h"
|
||||
#include "export_framerate.h"
|
||||
#include "frame_main.h"
|
||||
#include "main.h"
|
||||
|
@ -285,8 +287,10 @@ bool AegisubApp::OnInit() {
|
|||
#endif
|
||||
|
||||
// Load export filters
|
||||
StartupLog(_T("Prepare export filters"));
|
||||
AssExportFilterChain::PrepareFilters();
|
||||
StartupLog(L"Register export filters");
|
||||
AssExportFilterChain::Register(new AssFixStylesFilter);
|
||||
AssExportFilterChain::Register(new AssTransformCleanInfoFilter);
|
||||
AssExportFilterChain::Register(new AssTransformFramerateFilter);
|
||||
|
||||
// Get parameter subs
|
||||
StartupLog(_T("Parse command line"));
|
||||
|
|
Loading…
Reference in New Issue