int wmain(int argc, wchar_t **argv) { if (_setmode(_fileno(stdout), _O_BINARY) == -1) fprintf(stderr, "Failed to set stdout to binary mode\n"); SetConsoleCtrlHandler(HandlerRoutine, TRUE); #else int main(int argc, char **argv) { #endif if (argc == 2) { if (nstring(argv[1]) == NSTRING("-version")) { if (!vsscript_init()) { fprintf(stderr, "Failed to initialize VapourSynth environment\n"); return 1; } vsapi = vsscript_getVSApi(); if (!vsapi) { fprintf(stderr, "Failed to get VapourSynth API pointer\n"); vsscript_finalize(); return 1; } VSCore *core = vsapi->createCore(0); if (!core) { fprintf(stderr, "Failed to create core\n"); vsscript_finalize(); return 1; } const VSCoreInfo *info = vsapi->getCoreInfo(core); printf("%s", info->versionString); vsapi->freeCore(core); return 0; } } if (argc < 3) { fprintf(stderr, "VSPipe usage:\n"); fprintf(stderr, "Show version info: vspipe -version\n"); fprintf(stderr, "Show script info: vspipe script.vpy - -info\n"); fprintf(stderr, "Write to stdout: vspipe script.vpy - [options]\n"); fprintf(stderr, "Write to file: vspipe script.vpy <outFile> [options]\n"); fprintf(stderr, "Available options:\n"); fprintf(stderr, "Select output index: -index N\n"); fprintf(stderr, "Set number of concurrent frame requests: -requests N\n"); fprintf(stderr, "Add YUV4MPEG headers: -y4m\n"); fprintf(stderr, "Print progress to stderr: -progress\n"); fprintf(stderr, "Show video info: -info (overrides other options)\n"); return 1; } nstring outputFilename = argv[2]; if (outputFilename == NSTRING("-")) { outFile = stdout; } else { #ifdef VS_TARGET_OS_WINDOWS outFile = _wfopen(outputFilename.c_str(), L"wb"); #else outFile = fopen(outputFilename.c_str(), "wb"); #endif if (!outFile) { fprintf(stderr, "Failed to open output for writing\n"); return 1; } } for (int arg = 3; arg < argc; arg++) { nstring argString = argv[arg]; if (argString == NSTRING("-y4m")) { y4m = true; } else if (argString == NSTRING("-info")) { showInfo = true; } else if (argString == NSTRING("-index")) { bool ok = false; if (argc <= arg + 1) { fprintf(stderr, "No index number specified\n"); return 1; } if (!nstringToInt(argv[arg + 1], outputIndex)) { fprintf(stderr, "Couldn't convert %s to an integer\n", nstringToUtf8(argv[arg + 1]).c_str()); return 1; } arg++; } else if (argString == NSTRING("-requests")) { bool ok = false; if (argc <= arg + 1) { fprintf(stderr, "No request number specified\n"); return 1; } if (!nstringToInt(argv[arg + 1], requests)) { fprintf(stderr, "Couldn't convert %s to an integer\n", nstringToUtf8(argv[arg + 1]).c_str()); return 1; } arg++; } else if (argString == NSTRING("-progress")) { printFrameNumber = true; } else { fprintf(stderr, "Unknown argument: %s\n", nstringToUtf8(argString).c_str()); return 1; } } if (!vsscript_init()) { fprintf(stderr, "Failed to initialize VapourSynth environment\n"); return 1; } vsapi = vsscript_getVSApi(); if (!vsapi) { fprintf(stderr, "Failed to get VapourSynth API pointer\n"); vsscript_finalize(); return 1; } std::chrono::time_point<std::chrono::high_resolution_clock> start(std::chrono::high_resolution_clock::now()); if (vsscript_evaluateFile(&se, nstringToUtf8(argv[1]).c_str(), efSetWorkingDir)) { fprintf(stderr, "Script evaluation failed:\n%s\n", vsscript_getError(se)); vsscript_freeScript(se); vsscript_finalize(); return 1; } node = vsscript_getOutput(se, outputIndex); if (!node) { fprintf(stderr, "Failed to retrieve output node. Invalid index specified?\n"); vsscript_freeScript(se); vsscript_finalize(); return 1; } bool error = false; const VSVideoInfo *vi = vsapi->getVideoInfo(node); if (showInfo) { fprintf(outFile, "Width: %d\n", vi->width); fprintf(outFile, "Height: %d\n", vi->height); fprintf(outFile, "Frames: %d\n", vi->numFrames); fprintf(outFile, "FPS: %" PRId64 "/%" PRId64 "\n", vi->fpsNum, vi->fpsDen); if (vi->format) { fprintf(outFile, "Format Name: %s\n", vi->format->name); fprintf(outFile, "Color Family: %s\n", colorFamilyToString(vi->format->colorFamily)); fprintf(outFile, "Bits: %d\n", vi->format->bitsPerSample); fprintf(outFile, "SubSampling W: %d\n", vi->format->subSamplingW); fprintf(outFile, "SubSampling H: %d\n", vi->format->subSamplingH); } else { fprintf(outFile, "Format Name: Variable\n"); } } else { if (!isConstantFormat(vi) || vi->numFrames == 0) { fprintf(stderr, "Cannot output clips with varying dimensions or unknown length\n"); vsapi->freeNode(node); vsscript_freeScript(se); vsscript_finalize(); return 1; } lastFpsReportTime = std::chrono::high_resolution_clock::now(); error = outputNode(); } fflush(outFile); std::chrono::time_point<std::chrono::high_resolution_clock> end(std::chrono::high_resolution_clock::now()); std::chrono::duration<double> elapsedSeconds = end - start; fprintf(stderr, "Output %d frames in %.2f seconds (%.2f fps)\n", outputFrames, elapsedSeconds.count(), outputFrames / elapsedSeconds.count()); vsapi->freeNode(node); vsscript_freeScript(se); vsscript_finalize(); return error; }
int wmain(int argc, wchar_t **argv) { #else int main(int argc, char **argv) { #endif if (argc < 3) { fprintf(stderr, "VSPipe usage:\n"); fprintf(stderr, "Show script info: vspipe script.vpy - -info\n"); fprintf(stderr, "Write to stdout: vspipe script.vpy - [options]\n"); fprintf(stderr, "Write to file: vspipe script.vpy <outFile> [options]\n"); fprintf(stderr, "Available options:\n"); fprintf(stderr, "Select output index: -index N\n"); fprintf(stderr, "Set number of concurrent frame requests: -requests N\n"); fprintf(stderr, "Add YUV4MPEG headers: -y4m\n"); fprintf(stderr, "Show video info: -info (overrides other options)\n"); return 1; } QFile scriptFile(nativeToQString(argv[1])); if (!scriptFile.open(QIODevice::ReadOnly)) { fprintf(stderr, "Failed to to open script file for reading\n"); return 1; } if (scriptFile.size() > 1024*1024*16) { fprintf(stderr, "Script files bigger than 16MB not allowed\n"); return 1; } QByteArray scriptData = scriptFile.readAll(); scriptFile.close(); if (scriptData.isEmpty()) { fprintf(stderr, "Failed to read script file or file is empty\n"); return 1; } QString outputFilename = nativeToQString(argv[2]); if (outputFilename == "-") { outFile = stdout; } else { #ifdef VS_TARGET_OS_WINDOWS outFile = _wfopen(outputFilename.toStdWString().c_str(), L"wb"); #else outFile = fopen(outputFilename.toLocal8Bit(), "wb"); #endif if (!outFile) { fprintf(stderr, "Failed to open output for writing\n"); return 1; } } for (int arg = 3; arg < argc; arg++) { QString argString = nativeToQString(argv[arg]); if (argString == "-y4m") { y4m = true; } else if (argString == "-info") { showInfo = true; } else if (argString == "-index") { bool ok = false; if (argc <= arg + 1) { fprintf(stderr, "No index number specified"); return 1; } QString numString = nativeToQString(argv[arg+1]); outputIndex = numString.toInt(&ok); if (!ok) { fprintf(stderr, "Couldn't convert %s to an integer", numString.toUtf8().constData()); return 1; } arg++; } else if (argString == "-requests") { bool ok = false; if (argc <= arg + 1) { fprintf(stderr, "No request number specified"); return 1; } QString numString = nativeToQString(argv[arg+1]); requests = numString.toInt(&ok); if (!ok) { fprintf(stderr, "Couldn't convert %s to an integer", numString.toUtf8().constData()); return 1; } arg++; } else { fprintf(stderr, "Unknown argument: %s\n", argString.toUtf8().constData()); return 1; } } if (!vseval_init()) { fprintf(stderr, "Failed to initialize VapourSynth environment\n"); return 1; } vsapi = vseval_getVSApi(); if (!vsapi) { fprintf(stderr, "Failed to get VapourSynth API pointer\n"); vseval_finalize(); return 1; } if (vseval_evaluateScript(&se, scriptData.constData(), nativeToQString(argv[1]).toUtf8())) { fprintf(stderr, "Script evaluation failed:\n%s", vseval_getError(se)); vseval_freeScript(se); vseval_finalize(); return 1; } node = vseval_getOutput(se, outputIndex); if (!node) { fprintf(stderr, "Failed to retrieve output node. Invalid index specified?\n"); vseval_freeScript(se); vseval_finalize(); return 1; } bool error = false; const VSVideoInfo *vi = vsapi->getVideoInfo(node); if (showInfo) { fprintf(outFile, "Width: %d\n", vi->width); fprintf(outFile, "Height: %d\n", vi->height); fprintf(outFile, "Frames: %d\n", vi->numFrames); fprintf(outFile, "FPS: %" PRId64 "/%" PRId64 "\n", vi->fpsNum, vi->fpsDen); if (vi->format) { fprintf(outFile, "Format Name: %s\n", vi->format->name); fprintf(outFile, "Color Family: %s\n", colorFamilyToString(vi->format->colorFamily)); fprintf(outFile, "Bits: %d\n", vi->format->bitsPerSample); fprintf(outFile, "SubSampling W: %d\n", vi->format->subSamplingW); fprintf(outFile, "SubSampling H: %d\n", vi->format->subSamplingH); } else { fprintf(outFile, "Format Name: Variable\n"); } } else { if (!isConstantFormat(vi) || vi->numFrames == 0) { fprintf(stderr, "Cannot output clips with varying dimensions or unknown length\n"); vsapi->freeNode(node); vseval_freeScript(se); vseval_finalize(); return 1; } error = outputNode(); } fflush(outFile); vsapi->freeNode(node); vseval_freeScript(se); vseval_finalize(); return error; }
static const VSFrameRef *VS_CC textGetFrame(int n, int activationReason, void **instanceData, void **frameData, VSFrameContext *frameCtx, VSCore *core, const VSAPI *vsapi) { TextData *d = static_cast<TextData *>(*instanceData); if (activationReason == arInitial) { vsapi->requestFrameFilter(n, d->node, frameCtx); } else if (activationReason == arAllFramesReady) { const VSFrameRef *src = vsapi->getFrameFilter(n, d->node, frameCtx); const VSFormat *frame_format = vsapi->getFrameFormat(src); if ((frame_format->sampleType == stInteger && frame_format->bitsPerSample > 16) || (frame_format->sampleType == stFloat && frame_format->bitsPerSample != 32)) { vsapi->freeFrame(src); vsapi->setFilterError((d->instanceName + ": Only 8..16 bit integer and 32 bit float formats supported").c_str(), frameCtx); return nullptr; } VSFrameRef *dst = vsapi->copyFrame(src, core); if (d->filter == FILTER_FRAMENUM) { scrawl_text(std::to_string(n), d->alignment, dst, vsapi); } else if (d->filter == FILTER_FRAMEPROPS) { const VSMap *props = vsapi->getFramePropsRO(dst); int numKeys = vsapi->propNumKeys(props); int i; std::string text = "Frame properties:\n"; if (!d->props.empty()) { for (const auto &iter : d->props) { append_prop(text, iter, props, vsapi); } } else { for (i = 0; i < numKeys; i++) { const char *key = vsapi->propGetKey(props, i); append_prop(text, key, props, vsapi); } } scrawl_text(text, d->alignment, dst, vsapi); } else if (d->filter == FILTER_COREINFO) { const VSCoreInfo *ci = vsapi->getCoreInfo(core); std::string text; text.append(ci->versionString).append("\n"); text.append("Threads: ").append(std::to_string(ci->numThreads)).append("\n"); text.append("Maximum framebuffer cache size: ").append(std::to_string(ci->maxFramebufferSize)).append(" bytes\n"); text.append("Used framebuffer cache size: ").append(std::to_string(ci->usedFramebufferSize)).append(" bytes"); scrawl_text(text, d->alignment, dst, vsapi); } else if (d->filter == FILTER_CLIPINFO) { const VSMap *props = vsapi->getFramePropsRO(src); std::string text = "Clip info:\n"; if (d->vi->width) { text += "Width: " + std::to_string(vsapi->getFrameWidth(dst, 0)) + " px\n"; text += "Height: " + std::to_string(vsapi->getFrameHeight(dst, 0)) + " px\n"; } else { text += "Width: " + std::to_string(vsapi->getFrameWidth(dst, 0)) + " px (may vary)\n"; text += "Height: " + std::to_string(vsapi->getFrameHeight(dst, 0)) + " px (may vary)\n"; } int snerr, sderr; int sn = int64ToIntS(vsapi->propGetInt(props, "_SARNum", 0, &snerr)); int sd = int64ToIntS(vsapi->propGetInt(props, "_SARDen", 0, &sderr)); if (snerr || sderr) text += "Aspect ratio: Unknown\n"; else text += "Sample aspect ratio: " + std::to_string(sn) + ":" + std::to_string(sd) + "\n"; text += "Length: " + std::to_string(d->vi->numFrames) + " frames\n"; text += "Format name: " + std::string(frame_format->name) + (d->vi->format ? "\n" : " (may vary)\n"); text += "Color family: " + colorFamilyToString(frame_format->colorFamily) + "\n"; text += "Sample type: " + std::string(frame_format->sampleType == stInteger ? "Integer" : "Float") + "\n"; text += "Bits per sample: " + std::to_string(frame_format->bitsPerSample) + "\n"; text += "Subsampling Height/Width: " + std::to_string(1 << frame_format->subSamplingH) + "x/" + std::to_string(1 << frame_format->subSamplingW) + "x\n"; int err; int matrix = int64ToIntS(vsapi->propGetInt(props, "_Matrix", 0, &err)); if (err) matrix = -1; int primaries = int64ToIntS(vsapi->propGetInt(props, "_Primaries", 0, &err)); if (err) primaries = -1; int transfer = int64ToIntS(vsapi->propGetInt(props, "_Transfer", 0, &err)); if (err) transfer = -1; int range = int64ToIntS(vsapi->propGetInt(props, "_ColorRange", 0, &err)); if (err) range = -1; int location = int64ToIntS(vsapi->propGetInt(props, "_ChromaLocation", 0, &err)); if (err) location = -1; int field = int64ToIntS(vsapi->propGetInt(props, "_FieldBased", 0, &err)); if (err) field = -1; const char *picttype = vsapi->propGetData(props, "_PictType", 0, &err); text += "Matrix: " + matrixToString(matrix) + "\n"; text += "Primaries: " + primariesToString(primaries) + "\n"; text += "Transfer: " + transferToString(transfer) + "\n"; text += "Range: " + rangeToString(range) + "\n"; text += "Chroma Location: " + chromaLocationToString(location) + "\n"; text += "Field handling: " + fieldBasedToString(field) + "\n"; text += "Picture type: " + std::string(picttype ? picttype : "Unknown") + "\n"; if (d->vi->fpsNum && d->vi->fpsDen) { text += "Fps: " + std::to_string(d->vi->fpsNum) + "/" + std::to_string(d->vi->fpsDen) + " (" + std::to_string(static_cast<double>(d->vi->fpsNum) / d->vi->fpsDen) + ")\n"; } else { text += "Fps: Unknown\n"; } int fnerr, fderr; int fn = int64ToIntS(vsapi->propGetInt(props, "_DurationNum", 0, &fnerr)); int fd = int64ToIntS(vsapi->propGetInt(props, "_DurationDen", 0, &fderr)); if (fnerr || fderr) { text += "Frame duration: Unknown\n"; } else { text += "Frame duration: " + std::to_string(fn) + "/" + std::to_string(fd) + " (" + std::to_string(static_cast<double>(fn) / fd) + ")\n"; } scrawl_text(text, d->alignment, dst, vsapi); } else { scrawl_text(d->text, d->alignment, dst, vsapi); } vsapi->freeFrame(src); return dst; } return nullptr; }
int wmain(int argc, wchar_t **argv) { if (_setmode(_fileno(stdout), _O_BINARY) == -1) fprintf(stderr, "Failed to set stdout to binary mode\n"); SetConsoleCtrlHandler(HandlerRoutine, TRUE); #else int main(int argc, char **argv) { #endif nstring outputFilename, scriptFilename; bool showHelp = false; std::map<std::string, std::string> scriptArgs; int startFrame = 0; for (int arg = 1; arg < argc; arg++) { nstring argString = argv[arg]; if (argString == NSTRING("-v") || argString == NSTRING("--version")) { showVersion = true; } else if (argString == NSTRING("-y") || argString == NSTRING("--y4m")) { y4m = true; } else if (argString == NSTRING("-p") || argString == NSTRING("--progress")) { printFrameNumber = true; } else if (argString == NSTRING("-i") || argString == NSTRING("--info")) { showInfo = true; } else if (argString == NSTRING("-h") || argString == NSTRING("--help")) { showHelp = true; } else if (argString == NSTRING("-s") || argString == NSTRING("--start")) { if (argc <= arg + 1) { fprintf(stderr, "No start frame specified\n"); return 1; } if (!nstringToInt(argv[arg + 1], startFrame)) { fprintf(stderr, "Couldn't convert %s to an integer (start)\n", nstringToUtf8(argv[arg + 1]).c_str()); return 1; } if (startFrame < 0) { fprintf(stderr, "Negative start frame specified\n"); return 1; } completedFrames = startFrame; outputFrames = startFrame; requestedFrames = startFrame; lastFpsReportFrame = startFrame; arg++; } else if (argString == NSTRING("-e") || argString == NSTRING("--end")) { if (argc <= arg + 1) { fprintf(stderr, "No end frame specified\n"); return 1; } if (!nstringToInt(argv[arg + 1], totalFrames)) { fprintf(stderr, "Couldn't convert %s to an integer (end)\n", nstringToUtf8(argv[arg + 1]).c_str()); return 1; } if (totalFrames < 0) { fprintf(stderr, "Negative end frame specified\n"); return 1; } totalFrames++; arg++; } else if (argString == NSTRING("-o") || argString == NSTRING("--outputindex")) { if (argc <= arg + 1) { fprintf(stderr, "No output index specified\n"); return 1; } if (!nstringToInt(argv[arg + 1], outputIndex)) { fprintf(stderr, "Couldn't convert %s to an integer (index)\n", nstringToUtf8(argv[arg + 1]).c_str()); return 1; } arg++; } else if (argString == NSTRING("-r") || argString == NSTRING("--requests")) { if (argc <= arg + 1) { fprintf(stderr, "Number of requests not specified\n"); return 1; } if (!nstringToInt(argv[arg + 1], requests)) { fprintf(stderr, "Couldn't convert %s to an integer (requests)\n", nstringToUtf8(argv[arg + 1]).c_str()); return 1; } arg++; } else if (argString == NSTRING("-a") || argString == NSTRING("--arg")) { if (argc <= arg + 1) { fprintf(stderr, "No argument specified\n"); return 1; } std::string aLine = nstringToUtf8(argv[arg + 1]).c_str(); size_t equalsPos = aLine.find("="); if (equalsPos == std::string::npos) { fprintf(stderr, "No value specified for argument: %s\n", aLine.c_str()); return 1; } scriptArgs[aLine.substr(0, equalsPos)] = aLine.substr(equalsPos + 1); arg++; } else if (scriptFilename.empty() && !argString.empty() && argString.substr(0, 1) != NSTRING("-")) { scriptFilename = argString; } else if (outputFilename.empty() && !argString.empty() && (argString == NSTRING("-") || (argString.substr(0, 1) != NSTRING("-")))) { outputFilename = argString; } else { fprintf(stderr, "Unknown argument: %s\n", nstringToUtf8(argString).c_str()); return 1; } } if (showVersion && argc > 2) { fprintf(stderr, "Cannot combine version information with other options\n"); return 1; } else if (showVersion) { return printVersion() ? 0 : 1; } else if (showHelp || argc <= 1) { printHelp(); return 1; } else if (scriptFilename.empty()) { fprintf(stderr, "No script file specified\n"); return 1; } else if (outputFilename.empty()) { fprintf(stderr, "No output file specified\n"); return 1; } if (outputFilename == NSTRING("-")) { outFile = stdout; } else { #ifdef VS_TARGET_OS_WINDOWS outFile = _wfopen(outputFilename.c_str(), L"wb"); #else outFile = fopen(outputFilename.c_str(), "wb"); #endif if (!outFile) { fprintf(stderr, "Failed to open output for writing\n"); return 1; } } if (!vsscript_init()) { fprintf(stderr, "Failed to initialize VapourSynth environment\n"); return 1; } vsapi = vsscript_getVSApi(); if (!vsapi) { fprintf(stderr, "Failed to get VapourSynth API pointer\n"); vsscript_finalize(); return 1; } // Should always succeed if (vsscript_createScript(&se)) { fprintf(stderr, "Script environment initialization failed:\n%s\n", vsscript_getError(se)); vsscript_freeScript(se); vsscript_finalize(); return 1; } { VSMap *foldedArgs = vsapi->createMap(); for (const auto &iter : scriptArgs) vsapi->propSetData(foldedArgs, iter.first.c_str(), iter.second.c_str(), static_cast<int>(iter.second.size()), paAppend); vsscript_setVariable(se, foldedArgs); vsapi->freeMap(foldedArgs); } start = std::chrono::high_resolution_clock::now(); if (vsscript_evaluateFile(&se, nstringToUtf8(scriptFilename).c_str(), efSetWorkingDir)) { fprintf(stderr, "Script evaluation failed:\n%s\n", vsscript_getError(se)); vsscript_freeScript(se); vsscript_finalize(); return 1; } node = vsscript_getOutput(se, outputIndex); if (!node) { fprintf(stderr, "Failed to retrieve output node. Invalid index specified?\n"); vsscript_freeScript(se); vsscript_finalize(); return 1; } bool error = false; const VSVideoInfo *vi = vsapi->getVideoInfo(node); if (showInfo) { if (vi->width && vi->height) { fprintf(outFile, "Width: %d\n", vi->width); fprintf(outFile, "Height: %d\n", vi->height); } else { fprintf(outFile, "Width: Variable\n"); fprintf(outFile, "Height: Variable\n"); } if (vi->numFrames) fprintf(outFile, "Frames: %d\n", vi->numFrames); else fprintf(outFile, "Frames: Unknown\n"); if (vi->fpsNum && vi->fpsDen) fprintf(outFile, "FPS: %" PRId64 "/%" PRId64 " (%.3f fps)\n", vi->fpsNum, vi->fpsDen, vi->fpsNum/(double)vi->fpsDen); else fprintf(outFile, "FPS: Variable\n"); if (vi->format) { fprintf(outFile, "Format Name: %s\n", vi->format->name); fprintf(outFile, "Color Family: %s\n", colorFamilyToString(vi->format->colorFamily)); fprintf(outFile, "Bits: %d\n", vi->format->bitsPerSample); fprintf(outFile, "SubSampling W: %d\n", vi->format->subSamplingW); fprintf(outFile, "SubSampling H: %d\n", vi->format->subSamplingH); } else { fprintf(outFile, "Format Name: Variable\n"); } } else { const VSVideoInfo *vi = vsapi->getVideoInfo(node); if (totalFrames == -1) totalFrames = vi->numFrames; if ((vi->numFrames && vi->numFrames < totalFrames) || completedFrames >= totalFrames) { fprintf(stderr, "Invalid range of frames to output specified:\nfirst: %d\nlast: %d\nclip length: %d\nframes to output: %d\n", completedFrames, totalFrames, vi->numFrames, totalFrames - completedFrames); vsapi->freeNode(node); vsscript_freeScript(se); vsscript_finalize(); return 1; } if (!isConstantFormat(vi) || !totalFrames) { fprintf(stderr, "Cannot output clips with varying dimensions or unknown length\n"); vsapi->freeNode(node); vsscript_freeScript(se); vsscript_finalize(); return 1; } lastFpsReportTime = std::chrono::high_resolution_clock::now();; error = outputNode(); } fflush(outFile); if (!showInfo) { int totalFrames = outputFrames - startFrame; std::chrono::duration<double> elapsedSeconds = std::chrono::high_resolution_clock::now() - start; fprintf(stderr, "Output %d frames in %.2f seconds (%.2f fps)\n", totalFrames, elapsedSeconds.count(), totalFrames / elapsedSeconds.count()); } vsapi->freeNode(node); vsscript_freeScript(se); vsscript_finalize(); return error ? 1 : 0; }