forked from mia/Aegisub
Apply Plorkyeran's patch to close #843.
Originally committed to SVN as r2938.
This commit is contained in:
parent
1dbb23f106
commit
0d1b45f7d1
14 changed files with 10 additions and 223 deletions
|
@ -417,9 +417,6 @@ DialogOptions::DialogOptions(wxWindow *parent)
|
|||
Bind(control,_T("Allow Ancient Avisynth"));
|
||||
videoSizer4->Add(control,1,wxEXPAND);
|
||||
videoSizer4->AddGrowableCol(1,1);
|
||||
control = new wxCheckBox(videoPage,-1,_("Avisynth renders its own subs"));
|
||||
Bind(control,_T("Avisynth render own subs"));
|
||||
videoSizer4->Add(control,1,wxEXPAND);
|
||||
#endif
|
||||
|
||||
// Sizers
|
||||
|
|
|
@ -54,9 +54,6 @@ class SubtitlesProvider {
|
|||
public:
|
||||
virtual ~SubtitlesProvider();
|
||||
|
||||
virtual bool CanRaster() { return false; }
|
||||
virtual bool LockedToVideo() { return false; }
|
||||
|
||||
virtual void LoadSubtitles(AssFile *subs)=0;
|
||||
virtual void DrawSubtitles(AegiVideoFrame &dst,double time) {}
|
||||
};
|
||||
|
|
|
@ -44,12 +44,6 @@
|
|||
#include "aegisub.h"
|
||||
#include "vfr.h"
|
||||
|
||||
|
||||
//////////////
|
||||
// Prototypes
|
||||
class SubtitlesProvider;
|
||||
|
||||
|
||||
////////////////////////////
|
||||
// Video Provider interface
|
||||
class VideoProvider {
|
||||
|
@ -83,9 +77,6 @@ public:
|
|||
// For providers that are natively time-based (e.g. DirectShow)
|
||||
virtual bool IsNativelyByFrames() { return true; }
|
||||
virtual void OverrideFrameTimeList(Aegisub::IntArray list) {} // Override the list with the provided one, for VFR handling
|
||||
|
||||
// If this video provider has a built-in subtitles provider, return that
|
||||
virtual SubtitlesProvider *GetAsSubtitlesProvider() { return NULL; }
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -172,8 +172,6 @@ void OptionsManager::LoadDefaults(bool onlyDefaults,bool doOverride) {
|
|||
SetBool(_T("FFmpeg allow unsafe seeking"),false);
|
||||
SetInt(_T("FFmpegSource decoding threads"),1);
|
||||
SetBool(_T("Allow Ancient Avisynth"),false,1700);
|
||||
SetText(_T("Avisynth subs renderer"),_T("vsfilter"),1700);
|
||||
SetBool(_T("Avisynth render own subs"),true,1700);
|
||||
#ifdef __WINDOWS__
|
||||
SetText(_T("Subtitles Provider"),_T("csri/vsfilter_textsub"),1700);
|
||||
#else
|
||||
|
|
|
@ -152,7 +152,7 @@ void SubtitlesPreview::UpdateBitmap(int w,int h) {
|
|||
}
|
||||
|
||||
// Provider OK
|
||||
if (provider && provider->CanRaster()) {
|
||||
if (provider) {
|
||||
// Generate subtitles
|
||||
AssFile *subs = new AssFile();
|
||||
subs->LoadDefault();
|
||||
|
@ -169,8 +169,8 @@ void SubtitlesPreview::UpdateBitmap(int w,int h) {
|
|||
provider->DrawSubtitles(frame,0.1);
|
||||
}
|
||||
catch (...) {}
|
||||
delete provider;
|
||||
}
|
||||
if (provider) delete provider;
|
||||
|
||||
// Convert frame to bitmap
|
||||
wxMemoryDC dc(*bmp);
|
||||
|
|
|
@ -62,8 +62,6 @@ public:
|
|||
CSRISubtitlesProvider(wxString subType);
|
||||
~CSRISubtitlesProvider();
|
||||
|
||||
bool CanRaster() { return true; }
|
||||
|
||||
void LoadSubtitles(AssFile *subs);
|
||||
void DrawSubtitles(AegiVideoFrame &dst,double time);
|
||||
};
|
||||
|
|
|
@ -59,8 +59,6 @@ public:
|
|||
LibassSubtitlesProvider();
|
||||
~LibassSubtitlesProvider();
|
||||
|
||||
bool CanRaster() { return true; }
|
||||
|
||||
void LoadSubtitles(AssFile *subs);
|
||||
void DrawSubtitles(AegiVideoFrame &dst,double time);
|
||||
};
|
||||
|
|
|
@ -204,11 +204,10 @@ void VideoContext::Reset() {
|
|||
|
||||
// Remove provider
|
||||
if (provider) {
|
||||
if (subsProvider && !subsProvider->LockedToVideo()) delete subsProvider;
|
||||
delete provider;
|
||||
provider = NULL;
|
||||
}
|
||||
else delete subsProvider;
|
||||
delete subsProvider;
|
||||
subsProvider = NULL;
|
||||
}
|
||||
|
||||
|
@ -270,8 +269,7 @@ void VideoContext::SetVideo(const wxString &filename) {
|
|||
|
||||
// Get subtitles provider
|
||||
try {
|
||||
subsProvider = provider->GetAsSubtitlesProvider();
|
||||
if (!subsProvider) subsProvider = SubtitlesProviderFactoryManager::GetProvider();
|
||||
subsProvider = SubtitlesProviderFactoryManager::GetProvider();
|
||||
}
|
||||
catch (wxString err) { wxMessageBox(_T("Error while loading subtitles provider: ") + err,_T("Subtitles provider")); }
|
||||
catch (const wchar_t *err) { wxMessageBox(_T("Error while loading subtitles provider: ") + wxString(err),_T("Subtitles provider")); }
|
||||
|
@ -483,7 +481,7 @@ AegiVideoFrame VideoContext::GetFrame(int n,bool raw) {
|
|||
AegiVideoFrame frame = provider->GetFrame(n,formats);
|
||||
|
||||
// Raster subtitles if available/necessary
|
||||
if (!raw && subsProvider && subsProvider->CanRaster()) {
|
||||
if (!raw && subsProvider) {
|
||||
tempFrame.CopyFrom(frame);
|
||||
subsProvider->DrawSubtitles(tempFrame,VFR_Input.GetTimeAtFrame(n,true,true)/1000.0);
|
||||
return tempFrame;
|
||||
|
@ -863,13 +861,6 @@ void VideoContext::SetShader(bool enabled) {
|
|||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// Can draw subtitles independently from video?
|
||||
bool VideoContext::HasIndependentSubs() {
|
||||
return subsProvider && subsProvider->CanRaster();
|
||||
}
|
||||
|
||||
|
||||
//////////////////////
|
||||
// Thread constructor
|
||||
VideoContextThread::VideoContextThread(VideoContext *par)
|
||||
|
|
|
@ -146,7 +146,6 @@ public:
|
|||
VideoProvider *GetProvider() { return provider; }
|
||||
AegiVideoFrame GetFrame(int n,bool raw=false);
|
||||
|
||||
bool HasIndependentSubs();
|
||||
void SaveSnapshot(bool raw);
|
||||
|
||||
wxGLContext *GetGLContext(wxGLCanvas *canvas);
|
||||
|
|
|
@ -476,9 +476,8 @@ void VideoDisplay::OnMouseEvent(wxMouseEvent& event) {
|
|||
menu.Append(VIDEO_MENU_SAVE_SNAPSHOT,_("Save PNG snapshot"));
|
||||
menu.Append(VIDEO_MENU_COPY_TO_CLIPBOARD,_("Copy image to Clipboard"));
|
||||
menu.AppendSeparator();
|
||||
bool canDoRaw = VideoContext::Get()->HasIndependentSubs();
|
||||
menu.Append(VIDEO_MENU_SAVE_SNAPSHOT_RAW,_("Save PNG snapshot (no subtitles)"))->Enable(canDoRaw);
|
||||
menu.Append(VIDEO_MENU_COPY_TO_CLIPBOARD_RAW,_("Copy image to Clipboard (no subtitles)"))->Enable(canDoRaw);
|
||||
menu.Append(VIDEO_MENU_SAVE_SNAPSHOT_RAW,_("Save PNG snapshot (no subtitles)"));
|
||||
menu.Append(VIDEO_MENU_COPY_TO_CLIPBOARD_RAW,_("Copy image to Clipboard (no subtitles)"));
|
||||
menu.AppendSeparator();
|
||||
menu.Append(VIDEO_MENU_COPY_COORDS,_("Copy coordinates to Clipboard"));
|
||||
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
#include "options.h"
|
||||
#include "standard_paths.h"
|
||||
#include "vfr.h"
|
||||
#include "ass_file.h"
|
||||
#include "gl_wrap.h"
|
||||
#include "mkv_wrap.h"
|
||||
#include "vfw_wrap.h"
|
||||
|
@ -60,7 +59,6 @@ AvisynthVideoProvider::AvisynthVideoProvider(Aegisub::String _filename, double _
|
|||
AVSTRACE(wxString::Format(_T("AvisynthVideoProvider: Creating new AvisynthVideoProvider: \"%s\", \"%s\""), _filename, _subfilename));
|
||||
bool mpeg2dec3_priority = true;
|
||||
RGB32Video = NULL;
|
||||
SubtitledVideo = NULL;
|
||||
fps = _fps;
|
||||
num_frames = 0;
|
||||
last_fnum = -1;
|
||||
|
@ -69,18 +67,11 @@ AvisynthVideoProvider::AvisynthVideoProvider(Aegisub::String _filename, double _
|
|||
keyFramesLoaded = false;
|
||||
isVfr = false;
|
||||
|
||||
AVSTRACE(_T("AvisynthVideoProvider: Loading Subtitles Renderer"));
|
||||
LoadRenderer();
|
||||
AVSTRACE(_T("AvisynthVideoProvider: Subtitles Renderer loaded"));
|
||||
|
||||
AVSTRACE(_T("AvisynthVideoProvider: Opening video"));
|
||||
RGB32Video = OpenVideo(_filename,mpeg2dec3_priority);
|
||||
AVSTRACE(_T("AvisynthVideoProvider: Video opened"));
|
||||
|
||||
SubtitledVideo = RGB32Video;
|
||||
AVSTRACE(_T("AvisynthVideoProvider: Applied subtitles"));
|
||||
|
||||
vi = SubtitledVideo->GetVideoInfo();
|
||||
vi = RGB32Video->GetVideoInfo();
|
||||
AVSTRACE(_T("AvisynthVideoProvider: Got video info"));
|
||||
AVSTRACE(_T("AvisynthVideoProvider: Done creating AvisynthVideoProvider"));
|
||||
}
|
||||
|
@ -91,7 +82,6 @@ AvisynthVideoProvider::AvisynthVideoProvider(Aegisub::String _filename, double _
|
|||
AvisynthVideoProvider::~AvisynthVideoProvider() {
|
||||
AVSTRACE(_T("AvisynthVideoProvider: Destroying AvisynthVideoProvider"));
|
||||
RGB32Video = NULL;
|
||||
SubtitledVideo = NULL;
|
||||
AVSTRACE(_T("AvisynthVideoProvider: Destroying frame"));
|
||||
iframe.Clear();
|
||||
AVSTRACE(_T("AvisynthVideoProvider: AvisynthVideoProvider destroyed"));
|
||||
|
@ -351,9 +341,6 @@ PClip AvisynthVideoProvider::OpenVideo(Aegisub::String _filename, bool mpeg2dec3
|
|||
}
|
||||
|
||||
// Convert to RGB32
|
||||
// If "Avisynth renders its own subs" is enabled, this should always be done,
|
||||
// regardless of shaders being enabled or not. (Since VSFilter will convert
|
||||
// to RGB32 and back again itself either way.)
|
||||
if (!OpenGLWrapper::UseShaders()) {
|
||||
script = env->Invoke("ConvertToRGB32", script);
|
||||
AVSTRACE(_T("AvisynthVideoProvider::OpenVideo: Converted to RGB32"));
|
||||
|
@ -381,7 +368,7 @@ const AegiVideoFrame AvisynthVideoProvider::GetFrame(int _n,int formatMask) {
|
|||
// Get avs frame
|
||||
AVSTRACE(_T("AvisynthVideoProvider::GetFrame"));
|
||||
wxMutexLocker lock(AviSynthMutex);
|
||||
PVideoFrame frame = SubtitledVideo->GetFrame(n,env);
|
||||
PVideoFrame frame = RGB32Video->GetFrame(n,env);
|
||||
int Bpp = vi.BitsPerPixel() / 8;
|
||||
|
||||
// Aegisub's video frame
|
||||
|
@ -431,157 +418,6 @@ const AegiVideoFrame AvisynthVideoProvider::GetFrame(int _n,int formatMask) {
|
|||
return final;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
// Apply VSFilter subtitles, or whatever is appropriate
|
||||
PClip AvisynthVideoProvider::ApplySubtitles(Aegisub::String _filename, PClip videosource) {
|
||||
AVSTRACE(_T("AvisynthVideoProvider::ApplySutitles: Applying subtitles"));
|
||||
wxMutexLocker lock(AviSynthMutex);
|
||||
AVSTRACE(_T("AvisynthVideoProvider::ApplySutitles: Got AVS mutex"));
|
||||
|
||||
// Insert subs
|
||||
AVSValue script;
|
||||
char temp[512];
|
||||
wxFileName fname(_filename);
|
||||
strcpy(temp,fname.GetShortPath().mb_str(wxConvLocal));
|
||||
AVSValue args[2] = { videosource, temp };
|
||||
|
||||
try {
|
||||
AVSTRACE(_T("AvisynthVideoProvider::ApplySutitles: Now invoking ") + rendererCallString);
|
||||
script = env->Invoke(wxString(rendererCallString.c_str()).mb_str(wxConvUTF8), AVSValue(args,2));
|
||||
AVSTRACE(_T("AvisynthVideoProvider::ApplySutitles: Invoked successfully"));
|
||||
}
|
||||
catch (AvisynthError &err) {
|
||||
AVSTRACE(_T("AvisynthVideoProvider::ApplySutitles: Avisynth error: ") + wxString(err.msg,wxConvLocal));
|
||||
throw _T("AviSynth error: ") + wxString(err.msg,wxConvLocal);
|
||||
}
|
||||
|
||||
// Cache
|
||||
AVSTRACE(_T("AvisynthVideoProvider::ApplySutitles: Subtitles applied, AVS mutex will be released now"));
|
||||
return (env->Invoke("Cache", script)).AsClip();
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////// SUBTITLES PROVIDER //////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// Get as subtitles provider
|
||||
SubtitlesProvider *AvisynthVideoProvider::GetAsSubtitlesProvider() {
|
||||
if (Options.AsBool(_T("Avisynth render own subs"))) return this;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////
|
||||
// Refresh subtitles
|
||||
void AvisynthVideoProvider::LoadSubtitles(AssFile *subs) {
|
||||
// Reset
|
||||
AVSTRACE(_T("AvisynthVideoProvider::RefreshSubtitles: Refreshing subtitles"));
|
||||
SubtitledVideo = NULL;
|
||||
|
||||
// Dump subs to disk
|
||||
wxString subfilename = VideoContext::Get()->GetTempWorkFile();
|
||||
subs->Save(subfilename,false,false,_T("UTF-8"));
|
||||
delete subs;
|
||||
|
||||
// Load subtitles
|
||||
SubtitledVideo = ApplySubtitles(subfilename.c_str(), RGB32Video);
|
||||
AVSTRACE(_T("AvisynthVideoProvider::RefreshSubtitles: Subtitles refreshed"));
|
||||
vi = SubtitledVideo->GetVideoInfo();
|
||||
AVSTRACE(_T("AvisynthVideoProvider: Got video info"));
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// Load appropriate renderer
|
||||
void AvisynthVideoProvider::LoadRenderer() {
|
||||
// Get prefferred
|
||||
wxString prefferred = Options.AsText(_T("Avisynth subs renderer"));
|
||||
|
||||
// Load
|
||||
if (prefferred.Lower() == _T("asa")) LoadASA();
|
||||
else LoadVSFilter();
|
||||
}
|
||||
|
||||
|
||||
/////////////////
|
||||
// Load VSFilter
|
||||
void AvisynthVideoProvider::LoadVSFilter() {
|
||||
AVSTRACE(_T("AvisynthVideoProvider::LoadVSFilter: Loading VSFilter"));
|
||||
// Loading an avisynth plugin multiple times does almost nothing
|
||||
|
||||
wxFileName vsfilterPath(StandardPaths::DecodePath(_T("?data/csri/vsfilter.dll")));
|
||||
if (!vsfilterPath.FileExists())
|
||||
vsfilterPath = wxFileName(StandardPaths::DecodePath(_T("?data/vsfilter.dll")));
|
||||
rendererCallString = _T("TextSub");
|
||||
|
||||
if (vsfilterPath.FileExists()) {
|
||||
AVSTRACE(_T("AvisynthVideoProvider::LoadVSFilter: Invoking LoadPlugin"));
|
||||
env->Invoke("LoadPlugin",env->SaveString(vsfilterPath.GetFullPath().mb_str(wxConvLocal)));
|
||||
AVSTRACE(_T("AvisynthVideoProvider::LoadVSFilter: Loaded"));
|
||||
}
|
||||
else {
|
||||
AVSTRACE(_T("AvisynthVideoProvider::LoadVSFilter: VSFilter.dll not found in Aegisub dir, trying to locate registered DShow filter"));
|
||||
wxRegKey reg(_T("HKEY_CLASSES_ROOT\\CLSID\\{9852A670-F845-491B-9BE6-EBD841B8A613}\\InprocServer32"));
|
||||
if (reg.Exists()) {
|
||||
wxString fn;
|
||||
reg.QueryValue(_T(""),fn);
|
||||
|
||||
vsfilterPath = fn;
|
||||
|
||||
if (vsfilterPath.FileExists()) {
|
||||
AVSTRACE(_T("AvisynthVideoProvider::LoadVSFilter: Found as DShow filter, loading"));
|
||||
env->Invoke("LoadPlugin",env->SaveString(vsfilterPath.GetFullPath().mb_str(wxConvLocal)));
|
||||
AVSTRACE(_T("AvisynthVideoProvider::LoadVSFilter: Loaded"));
|
||||
return;
|
||||
}
|
||||
|
||||
vsfilterPath = _T("vsfilter.dll");
|
||||
}
|
||||
else if (vsfilterPath.FileExists()) {
|
||||
AVSTRACE(_T("AvisynthVideoProvider::LoadVSFilter: Found on system path, loading"));
|
||||
env->Invoke("LoadPlugin",env->SaveString(vsfilterPath.GetFullPath().mb_str(wxConvLocal)));
|
||||
AVSTRACE(_T("AvisynthVideoProvider::LoadVSFilter: Loaded"));
|
||||
}
|
||||
else if (!env->FunctionExists("TextSub")) {
|
||||
AVSTRACE(_T("AvisynthVideoProvider::LoadVSFilter: Couldn't locate VSFilter"));
|
||||
throw _T("Couldn't locate VSFilter for Avisynth internal subtitle rendering");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////
|
||||
// Load asa
|
||||
void AvisynthVideoProvider::LoadASA() {
|
||||
AVSTRACE(_T("AvisynthVideoProvider::LoadASA: Loading asa"));
|
||||
// Loading an avisynth plugin multiple times does almost nothing
|
||||
|
||||
wxFileName asaPath(StandardPaths::DecodePath(_T("?data/asa.dll")));
|
||||
rendererCallString = _T("asa");
|
||||
|
||||
if (asaPath.FileExists()) {
|
||||
AVSTRACE(_T("AvisynthVideoProvider::LoadASA: Invoking LoadPlugin"));
|
||||
env->Invoke("LoadPlugin",env->SaveString(asaPath.GetFullPath().mb_str(wxConvLocal)));
|
||||
AVSTRACE(_T("AvisynthVideoProvider::LoadASA: Loaded"));
|
||||
}
|
||||
else {
|
||||
asaPath = _T("asa.dll");
|
||||
if (asaPath.FileExists()) {
|
||||
AVSTRACE(_T("AvisynthVideoProvider::LoadASA: Invoking LoadPlugin"));
|
||||
env->Invoke("LoadPlugin",env->SaveString(asaPath.GetFullPath().mb_str(wxConvLocal)));
|
||||
AVSTRACE(_T("AvisynthVideoProvider::LoadASA: Loaded"));
|
||||
}
|
||||
else if (!env->FunctionExists("asa")) {
|
||||
AVSTRACE(_T("AvisynthVideoProvider::LoadASA: Couldn't locate asa"));
|
||||
throw _T("Couldn't locate asa for Avisynth internal subtitle rendering");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////
|
||||
// Override frame times
|
||||
void AvisynthVideoProvider::OverrideFrameTimeList(wxArrayInt list) {
|
||||
|
|
|
@ -40,12 +40,11 @@
|
|||
#ifdef WITH_AVISYNTH
|
||||
#include "avisynth_wrap.h"
|
||||
#include "include/aegisub/video_provider.h"
|
||||
#include "include/aegisub/subtitles_provider.h"
|
||||
|
||||
|
||||
////////////
|
||||
// Provider
|
||||
class AvisynthVideoProvider: public VideoProvider, SubtitlesProvider, AviSynthWrapper {
|
||||
class AvisynthVideoProvider: public VideoProvider, AviSynthWrapper {
|
||||
private:
|
||||
VideoInfo vi;
|
||||
AegiVideoFrame iframe;
|
||||
|
@ -67,23 +66,13 @@ private:
|
|||
FrameRate trueFrameRate;
|
||||
|
||||
PClip RGB32Video;
|
||||
PClip SubtitledVideo;
|
||||
|
||||
PClip OpenVideo(Aegisub::String _filename, bool mpeg2dec3_priority = true);
|
||||
PClip ApplySubtitles(Aegisub::String _filename, PClip videosource);
|
||||
|
||||
void LoadVSFilter();
|
||||
void LoadASA();
|
||||
void LoadRenderer();
|
||||
|
||||
public:
|
||||
AvisynthVideoProvider(Aegisub::String _filename, double fps=0.0);
|
||||
~AvisynthVideoProvider();
|
||||
|
||||
SubtitlesProvider *GetAsSubtitlesProvider();
|
||||
void LoadSubtitles(AssFile *subs);
|
||||
bool LockedToVideo() { return true; }
|
||||
|
||||
const AegiVideoFrame GetFrame(int n,int formatMask);
|
||||
void GetFloatFrame(float* Buffer, int n);
|
||||
|
||||
|
|
|
@ -146,9 +146,6 @@ void VideoProviderCache::ClearCache() {
|
|||
|
||||
///////////////////
|
||||
// Wrapper methods
|
||||
SubtitlesProvider *VideoProviderCache::GetAsSubtitlesProvider() {
|
||||
return master->GetAsSubtitlesProvider();
|
||||
}
|
||||
int VideoProviderCache::GetPosition() {
|
||||
return pos;
|
||||
}
|
||||
|
|
|
@ -78,9 +78,6 @@ public:
|
|||
VideoProviderCache(VideoProvider *master);
|
||||
virtual ~VideoProviderCache();
|
||||
|
||||
// Subtitles
|
||||
virtual SubtitlesProvider *GetAsSubtitlesProvider(); // Get subtitles provider
|
||||
|
||||
// Override the following methods:
|
||||
virtual int GetPosition(); // Get the number of the last frame loaded
|
||||
virtual int GetFrameCount(); // Get total number of frames
|
||||
|
|
Loading…
Reference in a new issue