Skip to content

Commit

Permalink
Merge branch 'vapoursynth' into feature
Browse files Browse the repository at this point in the history
  • Loading branch information
arch1t3cht committed Oct 25, 2024
2 parents f67a8d7 + 2e52264 commit dc68cae
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 125 deletions.
31 changes: 9 additions & 22 deletions src/audio_provider_vs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <libaegisub/format.h>
#include <libaegisub/path.h>
#include <libaegisub/make_unique.h>
#include <libaegisub/scoped_ptr.h>

#include <mutex>

Expand All @@ -40,24 +41,27 @@
namespace {
class VapourSynthAudioProvider final : public agi::AudioProvider {
VapourSynthWrapper vs;
VSScript *script = nullptr;
VSNode *node = nullptr;
agi::scoped_holder<VSScript *> script;
agi::scoped_holder<VSNode *> node;
const VSAudioInfo *vi = nullptr;

void FillBufferWithFrame(void *buf, int frame, int64_t start, int64_t count) const;
void FillBuffer(void *buf, int64_t start, int64_t count) const override;
public:
VapourSynthAudioProvider(agi::fs::path const& filename);
~VapourSynthAudioProvider();

bool NeedsCache() const override { return true; }
};

VapourSynthAudioProvider::VapourSynthAudioProvider(agi::fs::path const& filename) try {
VapourSynthAudioProvider::VapourSynthAudioProvider(agi::fs::path const& filename) try
: vs()
, script(nullptr, vs.GetScriptAPI()->freeScript)
, node(nullptr, vs.GetAPI()->freeNode) {
std::lock_guard<std::mutex> lock(vs.GetMutex());

VSCleanCache();

// createScript takes ownership of the core so no need for a scoped_holder here
VSCore *core = vs.GetAPI()->createCore(OPT_GET("Provider/VapourSynth/Autoload User Plugins")->GetBool() ? 0 : VSCoreCreationFlags::ccfDisableAutoLoading);
if (core == nullptr) {
throw VapourSynthError("Error creating core");
Expand All @@ -69,17 +73,13 @@ VapourSynthAudioProvider::VapourSynthAudioProvider(agi::fs::path const& filename
vs.GetScriptAPI()->evalSetWorkingDir(script, 1);
if (OpenScriptOrVideo(vs.GetAPI(), vs.GetScriptAPI(), script, filename, OPT_GET("Provider/Audio/VapourSynth/Default Script")->GetString())) {
std::string msg = agi::format("Error executing VapourSynth script: %s", vs.GetScriptAPI()->getError(script));
vs.GetScriptAPI()->freeScript(script);
throw VapourSynthError(msg);
}
node = vs.GetScriptAPI()->getOutputNode(script, 0);
if (node == nullptr) {
vs.GetScriptAPI()->freeScript(script);
throw VapourSynthError("No output node set");
}
if (vs.GetAPI()->getNodeType(node) != mtAudio) {
vs.GetAPI()->freeNode(node);
vs.GetScriptAPI()->freeScript(script);
throw VapourSynthError("Output node isn't an audio node");
}
vi = vs.GetAPI()->getAudioInfo(node);
Expand All @@ -106,24 +106,21 @@ static void PackChannels(const uint8_t **Src, void *Dst, size_t Length, size_t C

void VapourSynthAudioProvider::FillBufferWithFrame(void *buf, int n, int64_t start, int64_t count) const {
char errorMsg[1024];
const VSFrame *frame = vs.GetAPI()->getFrame(n, node, errorMsg, sizeof(errorMsg));
agi::scoped_holder frame(vs.GetAPI()->getFrame(n, node, errorMsg, sizeof(errorMsg)), vs.GetAPI()->freeFrame);
if (frame == nullptr) {
throw VapourSynthError(agi::format("Error getting frame: %s", errorMsg));
}
if (vs.GetAPI()->getFrameLength(frame) < count) {
vs.GetAPI()->freeFrame(frame);
throw VapourSynthError("Audio frame too short");
}
if (vs.GetAPI()->getAudioFrameFormat(frame)->numChannels != channels || vs.GetAPI()->getAudioFrameFormat(frame)->bytesPerSample != bytes_per_sample) {
vs.GetAPI()->freeFrame(frame);
throw VapourSynthError("Audio format is not constant");
}

std::vector<const uint8_t *> planes(channels);
for (int c = 0; c < channels; c++) {
planes[c] = vs.GetAPI()->getReadPtr(frame, c) + bytes_per_sample * start;
if (planes[c] == nullptr) {
vs.GetAPI()->freeFrame(frame);
throw VapourSynthError("Failed to read audio channel");
}
}
Expand All @@ -136,8 +133,6 @@ void VapourSynthAudioProvider::FillBufferWithFrame(void *buf, int n, int64_t sta
PackChannels<uint32_t>(planes.data(), buf, count, channels);
else if (bytes_per_sample == 8)
PackChannels<uint64_t>(planes.data(), buf, count, channels);

vs.GetAPI()->freeFrame(frame);
}

void VapourSynthAudioProvider::FillBuffer(void *buf, int64_t start, int64_t count) const {
Expand All @@ -156,14 +151,6 @@ void VapourSynthAudioProvider::FillBuffer(void *buf, int64_t start, int64_t coun
}
}

VapourSynthAudioProvider::~VapourSynthAudioProvider() {
if (node != nullptr) {
vs.GetAPI()->freeNode(node);
}
if (script != nullptr) {
vs.GetScriptAPI()->freeScript(script);
}
}
}

std::unique_ptr<agi::AudioProvider> CreateVapourSynthAudioProvider(agi::fs::path const& file, agi::BackgroundRunner *) {
Expand Down
7 changes: 3 additions & 4 deletions src/vapoursynth_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <libaegisub/format.h>
#include <libaegisub/fs.h>
#include <libaegisub/path.h>
#include <libaegisub/scoped_ptr.h>
#include <libaegisub/util.h>

#include <boost/algorithm/string/replace.hpp>
Expand All @@ -38,7 +39,7 @@ int OpenScriptOrVideo(const VSAPI *api, const VSSCRIPTAPI *sapi, VSScript *scrip
if (agi::fs::HasExtension(filename, "py") || agi::fs::HasExtension(filename, "vpy")) {
result = sapi->evaluateFile(script, filename.string().c_str());
} else {
VSMap *map = api->createMap();
agi::scoped_holder<VSMap *> map(api->createMap(), api->freeMap);
if (map == nullptr)
throw VapourSynthError("Failed to create VSMap for script info");

Expand All @@ -58,12 +59,10 @@ int OpenScriptOrVideo(const VSAPI *api, const VSSCRIPTAPI *sapi, VSScript *scrip
if (sapi->setVariables(script, map))
throw VapourSynthError("Failed to set script info variables");

api->freeMap(map);

std::string vscript;
vscript += "import sys\n";
vscript += "sys.path.append(f'{__aegi_data}/automation/vapoursynth')\n";
vscript += "sys.path.append(f'{__aegi_user}/automation/vapoursynth')\n";
vscript += "sys.path.append(f'{__aegi_data}/automation/vapoursynth')\n";
vscript += default_script;
result = sapi->evaluateBuffer(script, vscript.c_str(), "aegisub");
}
Expand Down
Loading

0 comments on commit dc68cae

Please sign in to comment.