Apply Plorkyeran's patch to close #843.

Originally committed to SVN as r2938.
This commit is contained in:
Niels Martin Hansen 2009-05-15 12:44:36 +00:00
parent 5bb56ae5d4
commit a6c7a8a724
14 changed files with 10 additions and 223 deletions

View file

@ -417,9 +417,6 @@ DialogOptions::DialogOptions(wxWindow *parent)
Bind(control,_T("Allow Ancient Avisynth")); Bind(control,_T("Allow Ancient Avisynth"));
videoSizer4->Add(control,1,wxEXPAND); videoSizer4->Add(control,1,wxEXPAND);
videoSizer4->AddGrowableCol(1,1); 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 #endif
// Sizers // Sizers

View file

@ -54,9 +54,6 @@ class SubtitlesProvider {
public: public:
virtual ~SubtitlesProvider(); virtual ~SubtitlesProvider();
virtual bool CanRaster() { return false; }
virtual bool LockedToVideo() { return false; }
virtual void LoadSubtitles(AssFile *subs)=0; virtual void LoadSubtitles(AssFile *subs)=0;
virtual void DrawSubtitles(AegiVideoFrame &dst,double time) {} virtual void DrawSubtitles(AegiVideoFrame &dst,double time) {}
}; };

View file

@ -44,12 +44,6 @@
#include "aegisub.h" #include "aegisub.h"
#include "vfr.h" #include "vfr.h"
//////////////
// Prototypes
class SubtitlesProvider;
//////////////////////////// ////////////////////////////
// Video Provider interface // Video Provider interface
class VideoProvider { class VideoProvider {
@ -83,9 +77,6 @@ public:
// For providers that are natively time-based (e.g. DirectShow) // For providers that are natively time-based (e.g. DirectShow)
virtual bool IsNativelyByFrames() { return true; } virtual bool IsNativelyByFrames() { return true; }
virtual void OverrideFrameTimeList(Aegisub::IntArray list) {} // Override the list with the provided one, for VFR handling 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; }
}; };

View file

@ -172,8 +172,6 @@ void OptionsManager::LoadDefaults(bool onlyDefaults,bool doOverride) {
SetBool(_T("FFmpeg allow unsafe seeking"),false); SetBool(_T("FFmpeg allow unsafe seeking"),false);
SetInt(_T("FFmpegSource decoding threads"),1); SetInt(_T("FFmpegSource decoding threads"),1);
SetBool(_T("Allow Ancient Avisynth"),false,1700); 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__ #ifdef __WINDOWS__
SetText(_T("Subtitles Provider"),_T("csri/vsfilter_textsub"),1700); SetText(_T("Subtitles Provider"),_T("csri/vsfilter_textsub"),1700);
#else #else

View file

@ -152,7 +152,7 @@ void SubtitlesPreview::UpdateBitmap(int w,int h) {
} }
// Provider OK // Provider OK
if (provider && provider->CanRaster()) { if (provider) {
// Generate subtitles // Generate subtitles
AssFile *subs = new AssFile(); AssFile *subs = new AssFile();
subs->LoadDefault(); subs->LoadDefault();
@ -169,8 +169,8 @@ void SubtitlesPreview::UpdateBitmap(int w,int h) {
provider->DrawSubtitles(frame,0.1); provider->DrawSubtitles(frame,0.1);
} }
catch (...) {} catch (...) {}
delete provider;
} }
if (provider) delete provider;
// Convert frame to bitmap // Convert frame to bitmap
wxMemoryDC dc(*bmp); wxMemoryDC dc(*bmp);

View file

@ -62,8 +62,6 @@ public:
CSRISubtitlesProvider(wxString subType); CSRISubtitlesProvider(wxString subType);
~CSRISubtitlesProvider(); ~CSRISubtitlesProvider();
bool CanRaster() { return true; }
void LoadSubtitles(AssFile *subs); void LoadSubtitles(AssFile *subs);
void DrawSubtitles(AegiVideoFrame &dst,double time); void DrawSubtitles(AegiVideoFrame &dst,double time);
}; };

View file

@ -59,8 +59,6 @@ public:
LibassSubtitlesProvider(); LibassSubtitlesProvider();
~LibassSubtitlesProvider(); ~LibassSubtitlesProvider();
bool CanRaster() { return true; }
void LoadSubtitles(AssFile *subs); void LoadSubtitles(AssFile *subs);
void DrawSubtitles(AegiVideoFrame &dst,double time); void DrawSubtitles(AegiVideoFrame &dst,double time);
}; };

View file

@ -204,11 +204,10 @@ void VideoContext::Reset() {
// Remove provider // Remove provider
if (provider) { if (provider) {
if (subsProvider && !subsProvider->LockedToVideo()) delete subsProvider;
delete provider; delete provider;
provider = NULL; provider = NULL;
} }
else delete subsProvider; delete subsProvider;
subsProvider = NULL; subsProvider = NULL;
} }
@ -270,8 +269,7 @@ void VideoContext::SetVideo(const wxString &filename) {
// Get subtitles provider // Get subtitles provider
try { try {
subsProvider = provider->GetAsSubtitlesProvider(); subsProvider = SubtitlesProviderFactoryManager::GetProvider();
if (!subsProvider) subsProvider = SubtitlesProviderFactoryManager::GetProvider();
} }
catch (wxString err) { wxMessageBox(_T("Error while loading subtitles provider: ") + err,_T("Subtitles provider")); } 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")); } 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); AegiVideoFrame frame = provider->GetFrame(n,formats);
// Raster subtitles if available/necessary // Raster subtitles if available/necessary
if (!raw && subsProvider && subsProvider->CanRaster()) { if (!raw && subsProvider) {
tempFrame.CopyFrom(frame); tempFrame.CopyFrom(frame);
subsProvider->DrawSubtitles(tempFrame,VFR_Input.GetTimeAtFrame(n,true,true)/1000.0); subsProvider->DrawSubtitles(tempFrame,VFR_Input.GetTimeAtFrame(n,true,true)/1000.0);
return tempFrame; 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 // Thread constructor
VideoContextThread::VideoContextThread(VideoContext *par) VideoContextThread::VideoContextThread(VideoContext *par)

View file

@ -146,7 +146,6 @@ public:
VideoProvider *GetProvider() { return provider; } VideoProvider *GetProvider() { return provider; }
AegiVideoFrame GetFrame(int n,bool raw=false); AegiVideoFrame GetFrame(int n,bool raw=false);
bool HasIndependentSubs();
void SaveSnapshot(bool raw); void SaveSnapshot(bool raw);
wxGLContext *GetGLContext(wxGLCanvas *canvas); wxGLContext *GetGLContext(wxGLCanvas *canvas);

View file

@ -476,9 +476,8 @@ void VideoDisplay::OnMouseEvent(wxMouseEvent& event) {
menu.Append(VIDEO_MENU_SAVE_SNAPSHOT,_("Save PNG snapshot")); menu.Append(VIDEO_MENU_SAVE_SNAPSHOT,_("Save PNG snapshot"));
menu.Append(VIDEO_MENU_COPY_TO_CLIPBOARD,_("Copy image to Clipboard")); menu.Append(VIDEO_MENU_COPY_TO_CLIPBOARD,_("Copy image to Clipboard"));
menu.AppendSeparator(); menu.AppendSeparator();
bool canDoRaw = VideoContext::Get()->HasIndependentSubs(); menu.Append(VIDEO_MENU_SAVE_SNAPSHOT_RAW,_("Save PNG snapshot (no subtitles)"));
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)"));
menu.Append(VIDEO_MENU_COPY_TO_CLIPBOARD_RAW,_("Copy image to Clipboard (no subtitles)"))->Enable(canDoRaw);
menu.AppendSeparator(); menu.AppendSeparator();
menu.Append(VIDEO_MENU_COPY_COORDS,_("Copy coordinates to Clipboard")); menu.Append(VIDEO_MENU_COPY_COORDS,_("Copy coordinates to Clipboard"));

View file

@ -48,7 +48,6 @@
#include "options.h" #include "options.h"
#include "standard_paths.h" #include "standard_paths.h"
#include "vfr.h" #include "vfr.h"
#include "ass_file.h"
#include "gl_wrap.h" #include "gl_wrap.h"
#include "mkv_wrap.h" #include "mkv_wrap.h"
#include "vfw_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)); AVSTRACE(wxString::Format(_T("AvisynthVideoProvider: Creating new AvisynthVideoProvider: \"%s\", \"%s\""), _filename, _subfilename));
bool mpeg2dec3_priority = true; bool mpeg2dec3_priority = true;
RGB32Video = NULL; RGB32Video = NULL;
SubtitledVideo = NULL;
fps = _fps; fps = _fps;
num_frames = 0; num_frames = 0;
last_fnum = -1; last_fnum = -1;
@ -69,18 +67,11 @@ AvisynthVideoProvider::AvisynthVideoProvider(Aegisub::String _filename, double _
keyFramesLoaded = false; keyFramesLoaded = false;
isVfr = false; isVfr = false;
AVSTRACE(_T("AvisynthVideoProvider: Loading Subtitles Renderer"));
LoadRenderer();
AVSTRACE(_T("AvisynthVideoProvider: Subtitles Renderer loaded"));
AVSTRACE(_T("AvisynthVideoProvider: Opening video")); AVSTRACE(_T("AvisynthVideoProvider: Opening video"));
RGB32Video = OpenVideo(_filename,mpeg2dec3_priority); RGB32Video = OpenVideo(_filename,mpeg2dec3_priority);
AVSTRACE(_T("AvisynthVideoProvider: Video opened")); AVSTRACE(_T("AvisynthVideoProvider: Video opened"));
SubtitledVideo = RGB32Video; vi = RGB32Video->GetVideoInfo();
AVSTRACE(_T("AvisynthVideoProvider: Applied subtitles"));
vi = SubtitledVideo->GetVideoInfo();
AVSTRACE(_T("AvisynthVideoProvider: Got video info")); AVSTRACE(_T("AvisynthVideoProvider: Got video info"));
AVSTRACE(_T("AvisynthVideoProvider: Done creating AvisynthVideoProvider")); AVSTRACE(_T("AvisynthVideoProvider: Done creating AvisynthVideoProvider"));
} }
@ -91,7 +82,6 @@ AvisynthVideoProvider::AvisynthVideoProvider(Aegisub::String _filename, double _
AvisynthVideoProvider::~AvisynthVideoProvider() { AvisynthVideoProvider::~AvisynthVideoProvider() {
AVSTRACE(_T("AvisynthVideoProvider: Destroying AvisynthVideoProvider")); AVSTRACE(_T("AvisynthVideoProvider: Destroying AvisynthVideoProvider"));
RGB32Video = NULL; RGB32Video = NULL;
SubtitledVideo = NULL;
AVSTRACE(_T("AvisynthVideoProvider: Destroying frame")); AVSTRACE(_T("AvisynthVideoProvider: Destroying frame"));
iframe.Clear(); iframe.Clear();
AVSTRACE(_T("AvisynthVideoProvider: AvisynthVideoProvider destroyed")); AVSTRACE(_T("AvisynthVideoProvider: AvisynthVideoProvider destroyed"));
@ -351,9 +341,6 @@ PClip AvisynthVideoProvider::OpenVideo(Aegisub::String _filename, bool mpeg2dec3
} }
// Convert to RGB32 // 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()) { if (!OpenGLWrapper::UseShaders()) {
script = env->Invoke("ConvertToRGB32", script); script = env->Invoke("ConvertToRGB32", script);
AVSTRACE(_T("AvisynthVideoProvider::OpenVideo: Converted to RGB32")); AVSTRACE(_T("AvisynthVideoProvider::OpenVideo: Converted to RGB32"));
@ -381,7 +368,7 @@ const AegiVideoFrame AvisynthVideoProvider::GetFrame(int _n,int formatMask) {
// Get avs frame // Get avs frame
AVSTRACE(_T("AvisynthVideoProvider::GetFrame")); AVSTRACE(_T("AvisynthVideoProvider::GetFrame"));
wxMutexLocker lock(AviSynthMutex); wxMutexLocker lock(AviSynthMutex);
PVideoFrame frame = SubtitledVideo->GetFrame(n,env); PVideoFrame frame = RGB32Video->GetFrame(n,env);
int Bpp = vi.BitsPerPixel() / 8; int Bpp = vi.BitsPerPixel() / 8;
// Aegisub's video frame // Aegisub's video frame
@ -431,157 +418,6 @@ const AegiVideoFrame AvisynthVideoProvider::GetFrame(int _n,int formatMask) {
return final; 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 // Override frame times
void AvisynthVideoProvider::OverrideFrameTimeList(wxArrayInt list) { void AvisynthVideoProvider::OverrideFrameTimeList(wxArrayInt list) {

View file

@ -40,12 +40,11 @@
#ifdef WITH_AVISYNTH #ifdef WITH_AVISYNTH
#include "avisynth_wrap.h" #include "avisynth_wrap.h"
#include "include/aegisub/video_provider.h" #include "include/aegisub/video_provider.h"
#include "include/aegisub/subtitles_provider.h"
//////////// ////////////
// Provider // Provider
class AvisynthVideoProvider: public VideoProvider, SubtitlesProvider, AviSynthWrapper { class AvisynthVideoProvider: public VideoProvider, AviSynthWrapper {
private: private:
VideoInfo vi; VideoInfo vi;
AegiVideoFrame iframe; AegiVideoFrame iframe;
@ -67,23 +66,13 @@ private:
FrameRate trueFrameRate; FrameRate trueFrameRate;
PClip RGB32Video; PClip RGB32Video;
PClip SubtitledVideo;
PClip OpenVideo(Aegisub::String _filename, bool mpeg2dec3_priority = true); PClip OpenVideo(Aegisub::String _filename, bool mpeg2dec3_priority = true);
PClip ApplySubtitles(Aegisub::String _filename, PClip videosource);
void LoadVSFilter();
void LoadASA();
void LoadRenderer();
public: public:
AvisynthVideoProvider(Aegisub::String _filename, double fps=0.0); AvisynthVideoProvider(Aegisub::String _filename, double fps=0.0);
~AvisynthVideoProvider(); ~AvisynthVideoProvider();
SubtitlesProvider *GetAsSubtitlesProvider();
void LoadSubtitles(AssFile *subs);
bool LockedToVideo() { return true; }
const AegiVideoFrame GetFrame(int n,int formatMask); const AegiVideoFrame GetFrame(int n,int formatMask);
void GetFloatFrame(float* Buffer, int n); void GetFloatFrame(float* Buffer, int n);

View file

@ -146,9 +146,6 @@ void VideoProviderCache::ClearCache() {
/////////////////// ///////////////////
// Wrapper methods // Wrapper methods
SubtitlesProvider *VideoProviderCache::GetAsSubtitlesProvider() {
return master->GetAsSubtitlesProvider();
}
int VideoProviderCache::GetPosition() { int VideoProviderCache::GetPosition() {
return pos; return pos;
} }

View file

@ -78,9 +78,6 @@ public:
VideoProviderCache(VideoProvider *master); VideoProviderCache(VideoProvider *master);
virtual ~VideoProviderCache(); virtual ~VideoProviderCache();
// Subtitles
virtual SubtitlesProvider *GetAsSubtitlesProvider(); // Get subtitles provider
// Override the following methods: // Override the following methods:
virtual int GetPosition(); // Get the number of the last frame loaded virtual int GetPosition(); // Get the number of the last frame loaded
virtual int GetFrameCount(); // Get total number of frames virtual int GetFrameCount(); // Get total number of frames