Merge branch 'avisynth' into feature
This commit is contained in:
commit
53466be0ca
|
@ -224,9 +224,9 @@ foreach dep: [
|
||||||
endif
|
endif
|
||||||
endforeach
|
endforeach
|
||||||
|
|
||||||
if host_machine.system() == 'windows' and get_option('avisynth').enabled()
|
if get_option('avisynth').enabled()
|
||||||
conf.set('WITH_AVISYNTH', 1) # bundled separately with installer
|
conf.set('WITH_AVISYNTH', 1) # bundled separately with installer
|
||||||
deps += cc.find_library('avifil32', required: true)
|
dep_avail += 'AviSynth'
|
||||||
|
|
||||||
avs_opt = cmake.subproject_options()
|
avs_opt = cmake.subproject_options()
|
||||||
avs_opt.add_cmake_defines({
|
avs_opt.add_cmake_defines({
|
||||||
|
@ -235,6 +235,10 @@ if host_machine.system() == 'windows' and get_option('avisynth').enabled()
|
||||||
|
|
||||||
avs = cmake.subproject('avisynth', options: avs_opt)
|
avs = cmake.subproject('avisynth', options: avs_opt)
|
||||||
deps_inc += avs.include_directories('AviSynth-Headers')
|
deps_inc += avs.include_directories('AviSynth-Headers')
|
||||||
|
|
||||||
|
if host_machine.system() == 'windows'
|
||||||
|
deps += cc.find_library('avifil32', required: true)
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if host_machine.system() == 'windows' and not get_option('directsound').disabled()
|
if host_machine.system() == 'windows' and not get_option('directsound').disabled()
|
||||||
|
|
|
@ -63,7 +63,7 @@ public:
|
||||||
bool NeedsCache() const override { return true; }
|
bool NeedsCache() const override { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
AvisynthAudioProvider::AvisynthAudioProvider(agi::fs::path const& filename) {
|
AvisynthAudioProvider::AvisynthAudioProvider(agi::fs::path const& filename) try {
|
||||||
agi::acs::CheckFileRead(filename);
|
agi::acs::CheckFileRead(filename);
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(avs_wrapper.GetMutex());
|
std::lock_guard<std::mutex> lock(avs_wrapper.GetMutex());
|
||||||
|
@ -100,6 +100,9 @@ AvisynthAudioProvider::AvisynthAudioProvider(agi::fs::path const& filename) {
|
||||||
throw agi::AudioProviderError("Avisynth error: " + errmsg);
|
throw agi::AudioProviderError("Avisynth error: " + errmsg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (AvisynthError& err) {
|
||||||
|
throw agi::AudioProviderError("Avisynth error: " + std::string(err.msg));
|
||||||
|
}
|
||||||
|
|
||||||
void AvisynthAudioProvider::LoadFromClip(AVSValue clip) {
|
void AvisynthAudioProvider::LoadFromClip(AVSValue clip) {
|
||||||
// Check if it has audio
|
// Check if it has audio
|
||||||
|
@ -107,12 +110,15 @@ void AvisynthAudioProvider::LoadFromClip(AVSValue clip) {
|
||||||
if (!vi.HasAudio()) throw agi::AudioDataNotFound("No audio found.");
|
if (!vi.HasAudio()) throw agi::AudioDataNotFound("No audio found.");
|
||||||
|
|
||||||
IScriptEnvironment *env = avs_wrapper.GetEnv();
|
IScriptEnvironment *env = avs_wrapper.GetEnv();
|
||||||
|
AVSValue script;
|
||||||
|
|
||||||
// Convert to one channel
|
// Convert to one channel
|
||||||
AVSValue script = env->Invoke(OPT_GET("Audio/Downmixer")->GetString().c_str(), clip);
|
std::string downmixtype = OPT_GET("Audio/Downmixer")->GetString();
|
||||||
|
if (downmixtype == "ConvertToMono" || downmixtype == "GetLeftChannel" || downmixtype == "GetRightChannel")
|
||||||
|
script = env->Invoke(downmixtype.c_str(), clip);
|
||||||
|
else
|
||||||
|
script = clip;
|
||||||
|
|
||||||
// Convert to 16 bits per sample
|
|
||||||
script = env->Invoke("ConvertAudioTo16bit", script);
|
|
||||||
vi = script.AsClip()->GetVideoInfo();
|
vi = script.AsClip()->GetVideoInfo();
|
||||||
|
|
||||||
// Convert sample rate
|
// Convert sample rate
|
||||||
|
@ -132,8 +138,8 @@ void AvisynthAudioProvider::LoadFromClip(AVSValue clip) {
|
||||||
channels = vi.AudioChannels();
|
channels = vi.AudioChannels();
|
||||||
decoded_samples = num_samples = vi.num_audio_samples;
|
decoded_samples = num_samples = vi.num_audio_samples;
|
||||||
sample_rate = vi.SamplesPerSecond();
|
sample_rate = vi.SamplesPerSecond();
|
||||||
bytes_per_sample = vi.BytesPerAudioSample();
|
bytes_per_sample = vi.BytesPerChannelSample();
|
||||||
float_samples = false;
|
float_samples = vi.IsSampleType(SAMPLE_FLOAT);
|
||||||
|
|
||||||
this->clip = tempclip;
|
this->clip = tempclip;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,10 +40,24 @@
|
||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define AVISYNTH_SO "avisynth.dll"
|
||||||
|
#else
|
||||||
|
#define AVISYNTH_SO "libavisynth.so"
|
||||||
|
#endif
|
||||||
|
|
||||||
// Allocate storage for and initialise static members
|
// Allocate storage for and initialise static members
|
||||||
namespace {
|
namespace {
|
||||||
int avs_refcount = 0;
|
int avs_refcount = 0;
|
||||||
|
#ifdef _WIN32
|
||||||
HINSTANCE hLib = nullptr;
|
HINSTANCE hLib = nullptr;
|
||||||
|
#else
|
||||||
|
void* hLib = nullptr;
|
||||||
|
#endif
|
||||||
IScriptEnvironment *env = nullptr;
|
IScriptEnvironment *env = nullptr;
|
||||||
std::mutex AviSynthMutex;
|
std::mutex AviSynthMutex;
|
||||||
}
|
}
|
||||||
|
@ -54,14 +68,26 @@ typedef IScriptEnvironment* __stdcall FUNC(int);
|
||||||
|
|
||||||
AviSynthWrapper::AviSynthWrapper() {
|
AviSynthWrapper::AviSynthWrapper() {
|
||||||
if (!avs_refcount++) {
|
if (!avs_refcount++) {
|
||||||
hLib = LoadLibrary(L"avisynth.dll");
|
#ifdef _WIN32
|
||||||
|
#define CONCATENATE(x, y) x ## y
|
||||||
|
#define _Lstr(x) CONCATENATE(L, x)
|
||||||
|
hLib = LoadLibraryW(_Lstr(AVISYNTH_SO));
|
||||||
|
#undef _Lstr
|
||||||
|
#undef CONCATENATE
|
||||||
|
#else
|
||||||
|
hLib = dlopen(AVISYNTH_SO, RTLD_LAZY | RTLD_LOCAL | RTLD_DEEPBIND);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!hLib)
|
if (!hLib)
|
||||||
throw AvisynthError("Could not load avisynth.dll");
|
throw AvisynthError("Could not load " AVISYNTH_SO);
|
||||||
|
|
||||||
FUNC *CreateScriptEnv = (FUNC*)GetProcAddress(hLib, "CreateScriptEnvironment");
|
#ifdef _WIN32
|
||||||
|
FUNC* CreateScriptEnv = (FUNC*)GetProcAddress(hLib, "CreateScriptEnvironment");
|
||||||
|
#else
|
||||||
|
FUNC* CreateScriptEnv = (FUNC*)dlsym(hLib, "CreateScriptEnvironment");
|
||||||
|
#endif
|
||||||
if (!CreateScriptEnv)
|
if (!CreateScriptEnv)
|
||||||
throw AvisynthError("Failed to get address of CreateScriptEnv from avisynth.dll");
|
throw AvisynthError("Failed to get address of CreateScriptEnv from " AVISYNTH_SO);
|
||||||
|
|
||||||
env = CreateScriptEnv(AVISYNTH_INTERFACE_VERSION);
|
env = CreateScriptEnv(AVISYNTH_INTERFACE_VERSION);
|
||||||
|
|
||||||
|
@ -79,9 +105,13 @@ AviSynthWrapper::AviSynthWrapper() {
|
||||||
|
|
||||||
AviSynthWrapper::~AviSynthWrapper() {
|
AviSynthWrapper::~AviSynthWrapper() {
|
||||||
if (!--avs_refcount) {
|
if (!--avs_refcount) {
|
||||||
delete env;
|
env->DeleteScriptEnvironment();
|
||||||
AVS_linkage = nullptr;
|
#ifdef _WIN32
|
||||||
FreeLibrary(hLib);
|
FreeLibrary(hLib);
|
||||||
|
#else
|
||||||
|
dlclose(hLib);
|
||||||
|
#endif
|
||||||
|
AVS_linkage = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -339,7 +339,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Avisynth" : {
|
"Avisynth" : {
|
||||||
"Memory Max" : 128
|
"Memory Max" : 1024
|
||||||
},
|
},
|
||||||
"FFmpegSource" : {
|
"FFmpegSource" : {
|
||||||
"Cache" : {
|
"Cache" : {
|
||||||
|
|
|
@ -338,7 +338,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Avisynth" : {
|
"Avisynth" : {
|
||||||
"Memory Max" : 128
|
"Memory Max" : 1024
|
||||||
},
|
},
|
||||||
"FFmpegSource" : {
|
"FFmpegSource" : {
|
||||||
"Cache" : {
|
"Cache" : {
|
||||||
|
|
|
@ -174,11 +174,8 @@ if host_machine.system() == 'darwin'
|
||||||
)
|
)
|
||||||
elif host_machine.system() == 'windows'
|
elif host_machine.system() == 'windows'
|
||||||
aegisub_src += files(
|
aegisub_src += files(
|
||||||
'avisynth_wrap.cpp',
|
|
||||||
'font_file_lister_gdi.cpp',
|
'font_file_lister_gdi.cpp',
|
||||||
# 'libass_gdi_fontselect.cpp',
|
# 'libass_gdi_fontselect.cpp',
|
||||||
'audio_provider_avs.cpp',
|
|
||||||
'video_provider_avs.cpp',
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if cc.has_header('wingdi.h')
|
if cc.has_header('wingdi.h')
|
||||||
|
@ -241,6 +238,10 @@ opt_src = [
|
||||||
'video_provider_ffmpegsource.cpp',
|
'video_provider_ffmpegsource.cpp',
|
||||||
'ffmpegsource_common.cpp']],
|
'ffmpegsource_common.cpp']],
|
||||||
|
|
||||||
|
['AviSynth', ['avisynth_wrap.cpp',
|
||||||
|
'audio_provider_avs.cpp',
|
||||||
|
'video_provider_avs.cpp']],
|
||||||
|
|
||||||
['Hunspell', 'spellchecker_hunspell.cpp'],
|
['Hunspell', 'spellchecker_hunspell.cpp'],
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -399,8 +399,8 @@ void Advanced_Audio(wxTreebook *book, Preferences *parent) {
|
||||||
|
|
||||||
#ifdef WITH_AVISYNTH
|
#ifdef WITH_AVISYNTH
|
||||||
auto avisynth = p->PageSizer("Avisynth");
|
auto avisynth = p->PageSizer("Avisynth");
|
||||||
const wxString adm_arr[3] = { "ConvertToMono", "GetLeftChannel", "GetRightChannel" };
|
const wxString adm_arr[4] = { "None", "ConvertToMono", "GetLeftChannel", "GetRightChannel" };
|
||||||
wxArrayString adm_choice(3, adm_arr);
|
wxArrayString adm_choice(4, adm_arr);
|
||||||
p->OptionChoice(avisynth, _("Avisynth down-mixer"), adm_choice, "Audio/Downmixer");
|
p->OptionChoice(avisynth, _("Avisynth down-mixer"), adm_choice, "Audio/Downmixer");
|
||||||
p->OptionAdd(avisynth, _("Force sample rate"), "Provider/Audio/AVS/Sample Rate");
|
p->OptionAdd(avisynth, _("Force sample rate"), "Provider/Audio/AVS/Sample Rate");
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -93,7 +93,7 @@ public:
|
||||||
bool HasAudio() const override { return has_audio; }
|
bool HasAudio() const override { return has_audio; }
|
||||||
};
|
};
|
||||||
|
|
||||||
AvisynthVideoProvider::AvisynthVideoProvider(agi::fs::path const& filename, std::string const& colormatrix) {
|
AvisynthVideoProvider::AvisynthVideoProvider(agi::fs::path const& filename, std::string const& colormatrix) try {
|
||||||
agi::acs::CheckFileRead(filename);
|
agi::acs::CheckFileRead(filename);
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(avs.GetMutex());
|
std::lock_guard<std::mutex> lock(avs.GetMutex());
|
||||||
|
@ -182,6 +182,9 @@ file_exit:
|
||||||
throw VideoOpenError("Avisynth error: " + std::string(err.msg));
|
throw VideoOpenError("Avisynth error: " + std::string(err.msg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (AvisynthError const& err) {
|
||||||
|
throw VideoProviderError("Avisynth error: " + std::string(err.msg));
|
||||||
|
}
|
||||||
|
|
||||||
void AvisynthVideoProvider::Init(std::string const& colormatrix) {
|
void AvisynthVideoProvider::Init(std::string const& colormatrix) {
|
||||||
auto script = source_clip;
|
auto script = source_clip;
|
||||||
|
|
Loading…
Reference in a new issue