Make the avisynth providers store an AvisynthWrapper rather than inherit from it

Originally committed to SVN as r6307.
This commit is contained in:
Thomas Goyne 2012-01-18 20:08:32 +00:00
parent 46986c6944
commit b38851bb93
6 changed files with 45 additions and 55 deletions

View file

@ -62,12 +62,14 @@ AvisynthAudioProvider::AvisynthAudioProvider(wxString filename)
{ {
try { try {
AVSValue script; AVSValue script;
wxMutexLocker lock(AviSynthMutex); wxMutexLocker lock(avs_wrapper.GetMutex());
wxFileName fn(filename); wxFileName fn(filename);
if (!fn.FileExists()) if (!fn.FileExists())
throw agi::FileNotFoundError(STD_STR(filename)); throw agi::FileNotFoundError(STD_STR(filename));
IScriptEnvironment *env = avs_wrapper.GetEnv();
// Include // Include
if (filename.EndsWith(".avs")) { if (filename.EndsWith(".avs")) {
char *fname = env->SaveString(fn.GetShortPath().mb_str(csConvLocal)); char *fname = env->SaveString(fn.GetShortPath().mb_str(csConvLocal));
@ -116,6 +118,8 @@ void AvisynthAudioProvider::LoadFromClip(AVSValue _clip) {
VideoInfo vi = _clip.AsClip()->GetVideoInfo(); VideoInfo vi = _clip.AsClip()->GetVideoInfo();
if (!vi.HasAudio()) throw agi::AudioDataNotFoundError("No audio found.", 0); if (!vi.HasAudio()) throw agi::AudioDataNotFoundError("No audio found.", 0);
IScriptEnvironment *env = avs_wrapper.GetEnv();
// Convert to one channel // Convert to one channel
char buffer[1024]; char buffer[1024];
strcpy(buffer,lagi_wxString(OPT_GET("Audio/Downmixer")->GetString()).mb_str(csConvLocal)); strcpy(buffer,lagi_wxString(OPT_GET("Audio/Downmixer")->GetString()).mb_str(csConvLocal));
@ -174,7 +178,7 @@ void AvisynthAudioProvider::GetAudio(void *buf, int64_t start, int64_t count) co
} }
if (count) { if (count) {
clip->GetAudio(buf,start,count,env); clip->GetAudio(buf,start,count,avs_wrapper.GetEnv());
} }
} }
#endif #endif

View file

@ -36,6 +36,8 @@
#ifdef WITH_AVISYNTH #ifdef WITH_AVISYNTH
#include "include/aegisub/audio_provider.h" #include "include/aegisub/audio_provider.h"
#include "avisynth.h"
#include "avisynth_wrap.h" #include "avisynth_wrap.h"
@ -44,7 +46,9 @@
/// @brief DOCME /// @brief DOCME
/// ///
/// DOCME /// DOCME
class AvisynthAudioProvider : public AudioProvider, public AviSynthWrapper { class AvisynthAudioProvider : public AudioProvider {
AviSynthWrapper avs_wrapper;
/// DOCME /// DOCME
wxString filename; wxString filename;

View file

@ -38,30 +38,30 @@
#ifdef WITH_AVISYNTH #ifdef WITH_AVISYNTH
#include "avisynth_wrap.h" #include "avisynth_wrap.h"
#include "avisynth.h"
#include "main.h" #include "main.h"
// Allocate storage for and initialise static members // Allocate storage for and initialise static members
int AviSynthWrapper::avs_refcount = 0; namespace {
HINSTANCE AviSynthWrapper::hLib = NULL; int avs_refcount = 0;
IScriptEnvironment *AviSynthWrapper::env = NULL; HINSTANCE hLib = NULL;
wxMutex AviSynthWrapper::AviSynthMutex; IScriptEnvironment *env = NULL;
wxMutex AviSynthMutex;
}
typedef IScriptEnvironment* __stdcall FUNC(int);
/// @brief AviSynth constructor
///
AviSynthWrapper::AviSynthWrapper() { AviSynthWrapper::AviSynthWrapper() {
if (!avs_refcount) { if (!avs_refcount++) {
hLib=LoadLibrary(L"avisynth.dll"); hLib = LoadLibrary(L"avisynth.dll");
if (hLib == NULL) { if (!hLib)
throw wxString("Could not load avisynth.dll"); throw wxString("Could not load avisynth.dll");
}
FUNC *CreateScriptEnv = (FUNC*)GetProcAddress(hLib, "CreateScriptEnvironment"); FUNC *CreateScriptEnv = (FUNC*)GetProcAddress(hLib, "CreateScriptEnvironment");
if (!CreateScriptEnv)
if (CreateScriptEnv == NULL) {
throw wxString("Failed to get address of CreateScriptEnv from avisynth.dll"); throw wxString("Failed to get address of CreateScriptEnv from avisynth.dll");
}
// Require Avisynth 2.5.6+? // Require Avisynth 2.5.6+?
if (OPT_GET("Provider/Avisynth/Allow Ancient")->GetBool()) if (OPT_GET("Provider/Avisynth/Allow Ancient")->GetBool())
@ -69,21 +69,16 @@ AviSynthWrapper::AviSynthWrapper() {
else else
env = CreateScriptEnv(AVISYNTH_INTERFACE_VERSION); env = CreateScriptEnv(AVISYNTH_INTERFACE_VERSION);
if (env == NULL) { if (!env)
throw wxString("Failed to create a new avisynth script environment. Avisynth is too old?"); throw wxString("Failed to create a new avisynth script environment. Avisynth is too old?");
}
// Set memory limit // Set memory limit
const int memoryMax = OPT_GET("Provider/Avisynth/Memory Max")->GetInt(); const int memoryMax = OPT_GET("Provider/Avisynth/Memory Max")->GetInt();
if (memoryMax != 0) { if (memoryMax != 0)
env->SetMemoryMax(memoryMax); env->SetMemoryMax(memoryMax);
}
} }
avs_refcount++;
} }
/// @brief AviSynth destructor
///
AviSynthWrapper::~AviSynthWrapper() { AviSynthWrapper::~AviSynthWrapper() {
if (!--avs_refcount) { if (!--avs_refcount) {
delete env; delete env;
@ -91,10 +86,12 @@ AviSynthWrapper::~AviSynthWrapper() {
} }
} }
/// @brief Get environment wxMutex& AviSynthWrapper::GetMutex() const {
/// return AviSynthMutex;
IScriptEnvironment *AviSynthWrapper::GetEnv() { }
IScriptEnvironment *AviSynthWrapper::GetEnv() const {
return env; return env;
} }
#endif
#endif

View file

@ -35,14 +35,8 @@
/// ///
#ifdef WITH_AVISYNTH #ifdef WITH_AVISYNTH
#ifndef AGI_PRE
#include <windows.h>
#endif
#include "avisynth.h" class IScriptEnvironment;
/// DOCME
typedef IScriptEnvironment* __stdcall FUNC(int);
/// DOCME /// DOCME
/// @class AviSynthWrapper /// @class AviSynthWrapper
@ -50,23 +44,11 @@ typedef IScriptEnvironment* __stdcall FUNC(int);
/// ///
/// DOCME /// DOCME
class AviSynthWrapper { class AviSynthWrapper {
private: AviSynthWrapper(AviSynthWrapper const&);
/// DOCME
static int avs_refcount;
/// DOCME
static HINSTANCE hLib;
protected:
/// DOCME
static IScriptEnvironment *env;
public: public:
wxMutex& GetMutex() const;
IScriptEnvironment *GetEnv() const;
/// DOCME
static wxMutex AviSynthMutex;
IScriptEnvironment *GetEnv();
AviSynthWrapper(); AviSynthWrapper();
~AviSynthWrapper(); ~AviSynthWrapper();
}; };

View file

@ -59,7 +59,7 @@ AvisynthVideoProvider::AvisynthVideoProvider(wxString filename) try
iframe.flipped = true; iframe.flipped = true;
iframe.invertChannels = true; iframe.invertChannels = true;
wxMutexLocker lock(AviSynthMutex); wxMutexLocker lock(avs.GetMutex());
wxFileName fname(filename); wxFileName fname(filename);
if (!fname.FileExists()) if (!fname.FileExists())
@ -151,7 +151,7 @@ file_exit:
if (!script.IsClip() || !script.AsClip()->GetVideoInfo().HasVideo()) if (!script.IsClip() || !script.AsClip()->GetVideoInfo().HasVideo())
throw VideoNotSupported("No usable video found"); throw VideoNotSupported("No usable video found");
RGB32Video = (env->Invoke("Cache", env->Invoke("ConvertToRGB32", script))).AsClip(); RGB32Video = (avs.GetEnv()->Invoke("Cache", avs.GetEnv()->Invoke("ConvertToRGB32", script))).AsClip();
vi = RGB32Video->GetVideoInfo(); vi = RGB32Video->GetVideoInfo();
fps = (double)vi.fps_numerator / vi.fps_denominator; fps = (double)vi.fps_numerator / vi.fps_denominator;
} }
@ -164,6 +164,7 @@ AvisynthVideoProvider::~AvisynthVideoProvider() {
} }
AVSValue AvisynthVideoProvider::Open(wxFileName const& fname, wxString const& extension) { AVSValue AvisynthVideoProvider::Open(wxFileName const& fname, wxString const& extension) {
IScriptEnvironment *env = avs.GetEnv();
char *videoFilename = env->SaveString(fname.GetShortPath().mb_str(csConvLocal)); char *videoFilename = env->SaveString(fname.GetShortPath().mb_str(csConvLocal));
// Avisynth file, just import it // Avisynth file, just import it
@ -265,9 +266,9 @@ AVSValue AvisynthVideoProvider::Open(wxFileName const& fname, wxString const& ex
const AegiVideoFrame AvisynthVideoProvider::GetFrame(int n) { const AegiVideoFrame AvisynthVideoProvider::GetFrame(int n) {
if (n == last_fnum) return iframe; if (n == last_fnum) return iframe;
wxMutexLocker lock(AviSynthMutex); wxMutexLocker lock(avs.GetMutex());
PVideoFrame frame = RGB32Video->GetFrame(n,env); PVideoFrame frame = RGB32Video->GetFrame(n, avs.GetEnv());
iframe.pitch = frame->GetPitch(); iframe.pitch = frame->GetPitch();
iframe.w = frame->GetRowSize() / (vi.BitsPerPixel() / 8); iframe.w = frame->GetRowSize() / (vi.BitsPerPixel() / 8);
iframe.h = frame->GetHeight(); iframe.h = frame->GetHeight();

View file

@ -35,6 +35,7 @@
/// ///
#ifdef WITH_AVISYNTH #ifdef WITH_AVISYNTH
#include "avisynth.h"
#include "avisynth_wrap.h" #include "avisynth_wrap.h"
#include "include/aegisub/video_provider.h" #include "include/aegisub/video_provider.h"
@ -43,7 +44,8 @@
/// @brief DOCME /// @brief DOCME
/// ///
/// DOCME /// DOCME
class AvisynthVideoProvider: public VideoProvider, AviSynthWrapper { class AvisynthVideoProvider: public VideoProvider {
AviSynthWrapper avs;
AegiVideoFrame iframe; AegiVideoFrame iframe;
wxString decoderName; wxString decoderName;
agi::vfr::Framerate fps; agi::vfr::Framerate fps;