From 691ab820b8dcec37154dc584c6f5cfac095edd16 Mon Sep 17 00:00:00 2001 From: wangqr Date: Tue, 13 Jul 2021 10:32:40 -0400 Subject: [PATCH 1/7] Handle exceptions from AviSynthWrapper ctor --- src/audio_provider_avs.cpp | 5 ++++- src/video_provider_avs.cpp | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/audio_provider_avs.cpp b/src/audio_provider_avs.cpp index b94cb4df4..35981b1d5 100644 --- a/src/audio_provider_avs.cpp +++ b/src/audio_provider_avs.cpp @@ -63,7 +63,7 @@ public: 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); std::lock_guard lock(avs_wrapper.GetMutex()); @@ -100,6 +100,9 @@ AvisynthAudioProvider::AvisynthAudioProvider(agi::fs::path const& filename) { throw agi::AudioProviderError("Avisynth error: " + errmsg); } } +catch (AvisynthError& err) { + throw agi::AudioProviderError("Avisynth error: " + std::string(err.msg)); +} void AvisynthAudioProvider::LoadFromClip(AVSValue clip) { // Check if it has audio diff --git a/src/video_provider_avs.cpp b/src/video_provider_avs.cpp index dabcdaa68..7c779e800 100644 --- a/src/video_provider_avs.cpp +++ b/src/video_provider_avs.cpp @@ -93,7 +93,7 @@ public: 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); std::lock_guard lock(avs.GetMutex()); @@ -182,6 +182,9 @@ file_exit: 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) { auto script = source_clip; From e2a49b3313d9961d58b3e0366fe59001302d1b5c Mon Sep 17 00:00:00 2001 From: wangqr Date: Sat, 2 Nov 2019 22:26:02 -0400 Subject: [PATCH 2/7] Avisynth audio provider: add option to allow no downmix --- src/audio_provider_avs.cpp | 12 +++++++----- src/preferences.cpp | 4 ++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/audio_provider_avs.cpp b/src/audio_provider_avs.cpp index 35981b1d5..d249aa3d3 100644 --- a/src/audio_provider_avs.cpp +++ b/src/audio_provider_avs.cpp @@ -110,12 +110,14 @@ void AvisynthAudioProvider::LoadFromClip(AVSValue clip) { if (!vi.HasAudio()) throw agi::AudioDataNotFound("No audio found."); IScriptEnvironment *env = avs_wrapper.GetEnv(); + AVSValue script; // Convert to one channel - AVSValue script = env->Invoke(OPT_GET("Audio/Downmixer")->GetString().c_str(), clip); + if (OPT_GET("Audio/Downmixer")->GetString() != "None") + script = env->Invoke(OPT_GET("Audio/Downmixer")->GetString().c_str(), clip); + else + script = clip; - // Convert to 16 bits per sample - script = env->Invoke("ConvertAudioTo16bit", script); vi = script.AsClip()->GetVideoInfo(); // Convert sample rate @@ -135,8 +137,8 @@ void AvisynthAudioProvider::LoadFromClip(AVSValue clip) { channels = vi.AudioChannels(); decoded_samples = num_samples = vi.num_audio_samples; sample_rate = vi.SamplesPerSecond(); - bytes_per_sample = vi.BytesPerAudioSample(); - float_samples = false; + bytes_per_sample = vi.BytesPerChannelSample(); + float_samples = vi.IsSampleType(SAMPLE_FLOAT); this->clip = tempclip; } diff --git a/src/preferences.cpp b/src/preferences.cpp index 38f1ac285..07a21a420 100644 --- a/src/preferences.cpp +++ b/src/preferences.cpp @@ -387,8 +387,8 @@ void Advanced_Audio(wxTreebook *book, Preferences *parent) { #ifdef WITH_AVISYNTH auto avisynth = p->PageSizer("Avisynth"); - const wxString adm_arr[3] = { "ConvertToMono", "GetLeftChannel", "GetRightChannel" }; - wxArrayString adm_choice(3, adm_arr); + const wxString adm_arr[4] = { "None", "ConvertToMono", "GetLeftChannel", "GetRightChannel" }; + wxArrayString adm_choice(4, adm_arr); p->OptionChoice(avisynth, _("Avisynth down-mixer"), adm_choice, "Audio/Downmixer"); p->OptionAdd(avisynth, _("Force sample rate"), "Provider/Audio/AVS/Sample Rate"); #endif From 663112ba03445b4dbfddabce6f01a03fd550b929 Mon Sep 17 00:00:00 2001 From: arch1t3cht Date: Mon, 8 Aug 2022 16:38:43 +0200 Subject: [PATCH 3/7] folding: Don't drop folds starting at the very first line --- src/ass_parser.cpp | 2 +- src/fold_controller.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ass_parser.cpp b/src/ass_parser.cpp index e9e3c7899..33e878b71 100644 --- a/src/ass_parser.cpp +++ b/src/ass_parser.cpp @@ -100,7 +100,7 @@ public: try_parse(parsed[2], &collapsed); fold.collapsed = !!collapsed; - if (fold.start > 0 && fold.end > fold.start) { + if (fold.start >= 0 && fold.end > fold.start) { folds.push_back(fold); } } diff --git a/src/fold_controller.cpp b/src/fold_controller.cpp index 56de5aaf4..ac1cd2084 100644 --- a/src/fold_controller.cpp +++ b/src/fold_controller.cpp @@ -104,7 +104,7 @@ void FoldController::MakeFoldsFromFile() { int numlines = context->ass->Events.size(); for (LineFold fold : context->ass->Properties.folds) { - if (fold.start > 0 && fold.start < fold.end && fold.end <= numlines) { + if (fold.start >= 0 && fold.start < fold.end && fold.end <= numlines) { auto opener = std::next(context->ass->Events.begin(), fold.start); RawAddFold(*opener, *std::next(opener, fold.end - fold.start), fold.collapsed); } From fe285678a397d28f791dfdbad8c1b64401788b6a Mon Sep 17 00:00:00 2001 From: arch1t3cht Date: Fri, 6 Mar 2020 00:15:07 -0500 Subject: [PATCH 4/7] avisynth: Allow compilation on Linux Co-authored-by: wangqr --- meson.build | 8 ++++-- src/avisynth_wrap.cpp | 40 ++++++++++++++++++++++++---- src/libresrc/default_config.json | 2 +- src/libresrc/osx/default_config.json | 2 +- src/meson.build | 7 ++--- 5 files changed, 47 insertions(+), 12 deletions(-) diff --git a/meson.build b/meson.build index 39cc7de00..50ec01dde 100644 --- a/meson.build +++ b/meson.build @@ -220,9 +220,9 @@ foreach dep: [ endif 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 - deps += cc.find_library('avifil32', required: true) + dep_avail += 'AviSynth' avs_opt = cmake.subproject_options() avs_opt.add_cmake_defines({ @@ -231,6 +231,10 @@ if host_machine.system() == 'windows' and get_option('avisynth').enabled() avs = cmake.subproject('avisynth', options: avs_opt) deps_inc += avs.include_directories('AviSynth-Headers') + + if host_machine.system() == 'windows' + deps += cc.find_library('avifil32', required: true) + endif endif if host_machine.system() == 'windows' and not get_option('directsound').disabled() diff --git a/src/avisynth_wrap.cpp b/src/avisynth_wrap.cpp index fd2246f77..a3b6a3de6 100644 --- a/src/avisynth_wrap.cpp +++ b/src/avisynth_wrap.cpp @@ -40,10 +40,24 @@ #include +#ifndef _WIN32 +#include +#endif + +#ifdef _WIN32 +#define AVISYNTH_SO "avisynth.dll" +#else +#define AVISYNTH_SO "libavisynth.so" +#endif + // Allocate storage for and initialise static members namespace { int avs_refcount = 0; +#ifdef _WIN32 HINSTANCE hLib = nullptr; +#else + void* hLib = nullptr; +#endif IScriptEnvironment *env = nullptr; std::mutex AviSynthMutex; } @@ -54,14 +68,26 @@ typedef IScriptEnvironment* __stdcall FUNC(int); AviSynthWrapper::AviSynthWrapper() { 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) - 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) - 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); @@ -80,8 +106,12 @@ AviSynthWrapper::AviSynthWrapper() { AviSynthWrapper::~AviSynthWrapper() { if (!--avs_refcount) { delete env; - AVS_linkage = nullptr; +#ifdef _WIN32 FreeLibrary(hLib); +#else + dlclose(hLib); +#endif + AVS_linkage = nullptr; } } diff --git a/src/libresrc/default_config.json b/src/libresrc/default_config.json index f83002436..fbc98dc2e 100644 --- a/src/libresrc/default_config.json +++ b/src/libresrc/default_config.json @@ -335,7 +335,7 @@ } }, "Avisynth" : { - "Memory Max" : 128 + "Memory Max" : 1024 }, "FFmpegSource" : { "Cache" : { diff --git a/src/libresrc/osx/default_config.json b/src/libresrc/osx/default_config.json index 66cecd520..7d0cb9b6a 100644 --- a/src/libresrc/osx/default_config.json +++ b/src/libresrc/osx/default_config.json @@ -335,7 +335,7 @@ } }, "Avisynth" : { - "Memory Max" : 128 + "Memory Max" : 1024 }, "FFmpegSource" : { "Cache" : { diff --git a/src/meson.build b/src/meson.build index 9592cf6e0..b5791e558 100644 --- a/src/meson.build +++ b/src/meson.build @@ -171,11 +171,8 @@ if host_machine.system() == 'darwin' ) elif host_machine.system() == 'windows' aegisub_src += files( - 'avisynth_wrap.cpp', 'font_file_lister_gdi.cpp', # 'libass_gdi_fontselect.cpp', - 'audio_provider_avs.cpp', - 'video_provider_avs.cpp', ) if cc.has_header('wingdi.h') @@ -238,6 +235,10 @@ opt_src = [ 'video_provider_ffmpegsource.cpp', 'ffmpegsource_common.cpp']], + ['AviSynth', ['avisynth_wrap.cpp', + 'audio_provider_avs.cpp', + 'video_provider_avs.cpp']], + ['Hunspell', 'spellchecker_hunspell.cpp'], ] From ce1b3a0158c5c6407e58d8ff46f7e5d30f397fa6 Mon Sep 17 00:00:00 2001 From: arch1t3cht Date: Tue, 9 Aug 2022 02:43:43 +0200 Subject: [PATCH 5/7] avisynth: Validate downmix option Because... let's maybe not let users make Aegisub call arbitrary symbols in avisynth.dll/so just by editing the config.json. --- src/audio_provider_avs.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/audio_provider_avs.cpp b/src/audio_provider_avs.cpp index d249aa3d3..0daa77e8e 100644 --- a/src/audio_provider_avs.cpp +++ b/src/audio_provider_avs.cpp @@ -113,8 +113,9 @@ void AvisynthAudioProvider::LoadFromClip(AVSValue clip) { AVSValue script; // Convert to one channel - if (OPT_GET("Audio/Downmixer")->GetString() != "None") - 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; From 0376c56a9505eabc9bcdd47c079a3e2f37f39007 Mon Sep 17 00:00:00 2001 From: arch1t3cht Date: Sat, 13 Aug 2022 21:00:13 +0200 Subject: [PATCH 6/7] Lua docs: Typo fix --- automation/v4-docs/gui.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/automation/v4-docs/gui.txt b/automation/v4-docs/gui.txt index f913e7040..83c145535 100644 --- a/automation/v4-docs/gui.txt +++ b/automation/v4-docs/gui.txt @@ -23,7 +23,7 @@ Returns: 1 number --- -function aegisub.get_selection() +function aegisub.gui.get_selection() Returns: 2 values, all numbers. 1. Starting position of the selection. From ad443dd1186226f9542e85524c2dda656a2efff6 Mon Sep 17 00:00:00 2001 From: arch1t3cht Date: Sat, 13 Aug 2022 22:53:58 +0200 Subject: [PATCH 7/7] avisynth: Properly destruct the IScriptEnvironment Starting with AVISYNTH_INTERFACE_VERSION=5, this is how script environments should be deleted. The previous code was causing crashes when unloading AviSynth in certain scenarios, such as when failing to open a file due to an incorrect path. --- src/avisynth_wrap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/avisynth_wrap.cpp b/src/avisynth_wrap.cpp index a3b6a3de6..eb957fa3c 100644 --- a/src/avisynth_wrap.cpp +++ b/src/avisynth_wrap.cpp @@ -105,7 +105,7 @@ AviSynthWrapper::AviSynthWrapper() { AviSynthWrapper::~AviSynthWrapper() { if (!--avs_refcount) { - delete env; + env->DeleteScriptEnvironment(); #ifdef _WIN32 FreeLibrary(hLib); #else