Skip to content

Commit 4dfe3db

Browse files
committed
Update to VS APIv4
1 parent ed8ecd5 commit 4dfe3db

23 files changed

Lines changed: 1591 additions & 980 deletions

banding/cambifilter.c

Lines changed: 38 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,33 +6,28 @@
66
#include "libvmaf/picture.h"
77
#include "libvmaf/cambi.h"
88

9-
#include "VapourSynth.h"
10-
#include "VSHelper.h"
9+
#include "VapourSynth4.h"
10+
#include "VSHelper4.h"
1111

1212
typedef struct {
13-
VSNodeRef *node;
13+
VSNode *node;
1414
VSVideoInfo vi;
1515
CambiState s;
1616
int bpc;
1717
int scores;
1818
float scaling;
1919
} CambiData;
2020

21-
static void VS_CC cambiInit(VSMap *in, VSMap *out, void **instanceData, VSNode *node, VSCore *core, const VSAPI *vsapi) {
22-
CambiData *d = (CambiData *) *instanceData;
23-
vsapi->setVideoInfo(&d->vi, 1, node);
24-
}
25-
26-
static const VSFrameRef *VS_CC cambiGetFrame(int n, int activationReason, void **instanceData, void **frameData, VSFrameContext *frameCtx, VSCore *core, const VSAPI *vsapi) {
27-
CambiData *d = (CambiData *) *instanceData;
21+
static const VSFrame *VS_CC cambiGetFrame(int n, int activationReason, void *instanceData, void **frameData, VSFrameContext *frameCtx, VSCore *core, const VSAPI *vsapi) {
22+
CambiData *d = (CambiData *) instanceData;
2823

2924
if (activationReason == arInitial) {
3025
vsapi->requestFrameFilter(n, d->node, frameCtx);
3126
} else if (activationReason == arAllFramesReady) {
32-
const VSFrameRef *src = vsapi->getFrameFilter(n, d->node, frameCtx);
27+
const VSFrame *src = vsapi->getFrameFilter(n, d->node, frameCtx);
3328
const unsigned int width = vsapi->getFrameWidth(src, 0);
3429
const unsigned int height = vsapi->getFrameHeight(src, 0);
35-
VSFrameRef *dst = vsapi->copyFrame(src, core);
30+
VSFrame *dst = vsapi->copyFrame(src, core);
3631

3732
VmafPicture pic; // shares memory with src
3833
pic.pix_fmt = VMAF_PIX_FMT_YUV400P; // GRAY
@@ -60,12 +55,13 @@ static const VSFrameRef *VS_CC cambiGetFrame(int n, int activationReason, void *
6055
err = cambi_extract(&s, &pic, &score, d->scores ? c_values : NULL);
6156
cambi_close(&s);
6257

63-
VSMap *prop = vsapi->getFramePropsRW(dst);
58+
VSMap *prop = vsapi->getFramePropertiesRW(dst);
6459
if (d->scores) {
65-
const VSFormat *grays = vsapi->getFormatPreset(pfGrayS, core);
60+
VSVideoFormat grays;
61+
vsapi->getVideoFormatByID(&grays, pfGrayS, core);
6662
unsigned int w = width, h = height;
6763
for (int i = 0; i < NUM_SCALES; i++) {
68-
VSFrameRef *f = vsapi->newVideoFrame(grays, w, h, src, core);
64+
VSFrame *f = vsapi->newVideoFrame(&grays, w, h, src, core);
6965
float *dst = (float *)vsapi->getWritePtr(f, 0);
7066
float *src = c_values[i];
7167
uintptr_t stride = vsapi->getStride(f, 0) / sizeof *dst;
@@ -80,14 +76,14 @@ static const VSFrameRef *VS_CC cambiGetFrame(int n, int activationReason, void *
8076
scale_dimension(&h, 1);
8177
char name[16];
8278
sprintf(name, "CAMBI_SCALE%d", i);
83-
vsapi->propSetFrame(prop, name, f, paReplace);
79+
vsapi->mapSetFrame(prop, name, f, maReplace);
8480
vsapi->freeFrame(f);
8581
}
8682
}
8783
vsapi->freeFrame(src);
8884
assert(err == 0);
8985

90-
err = vsapi->propSetFloat(prop, "CAMBI", score, paReplace);
86+
err = vsapi->mapSetFloat(prop, "CAMBI", score, maReplace);
9187
assert(err == 0);
9288

9389
return dst;
@@ -107,17 +103,17 @@ static void VS_CC cambiFree(void *instanceData, VSCore *core, const VSAPI *vsapi
107103
static void VS_CC cambiCreate(const VSMap *in, VSMap *out, void *userData, VSCore *core, const VSAPI *vsapi) {
108104
CambiData d;
109105

110-
d.node = vsapi->propGetNode(in, "clip", 0, 0);
106+
d.node = vsapi->mapGetNode(in, "clip", 0, 0);
111107
d.vi = *vsapi->getVideoInfo(d.node);
112108

113-
if (!isConstantFormat(&d.vi) || d.vi.format->sampleType != stInteger ||
114-
(d.vi.format->colorFamily != cmGray && d.vi.format->colorFamily != cmYUV) ||
115-
(d.vi.format->bitsPerSample != 8 && d.vi.format->bitsPerSample != 10)) {
116-
vsapi->setError(out, "Cambi: only constant Gray/YUV format with 8/10bit integer samples supported");
109+
if (!vsh_isConstantVideoFormat(&d.vi) || d.vi.format.sampleType != stInteger ||
110+
(d.vi.format.colorFamily != cfGray && d.vi.format.colorFamily != cfYUV) ||
111+
(d.vi.format.bitsPerSample != 8 && d.vi.format.bitsPerSample != 10)) {
112+
vsapi->mapSetError(out, "Cambi: only constant Gray/YUV format with 8/10bit integer samples supported");
117113
vsapi->freeNode(d.node);
118114
return;
119115
}
120-
d.bpc = d.vi.format->bitsPerSample;
116+
d.bpc = d.vi.format.bitsPerSample;
121117

122118
cambi_config(&d.s);
123119
#define GETARG(type, var, name, api, min, max) \
@@ -128,34 +124,43 @@ static void VS_CC cambiCreate(const VSMap *in, VSMap *out, void *userData, VSCor
128124
if (x < min || x > max) { \
129125
char errmsg[256]; \
130126
snprintf(errmsg, sizeof errmsg, "Cambi: argument %s=%f is out of range [%f,%f] (default=%f)", #name, (double)x, (double)min, (double)max, (double)var.name); \
131-
vsapi->setError(out, errmsg); \
127+
vsapi->mapSetError(out, errmsg); \
132128
vsapi->freeNode(d.node); \
133129
return; \
134130
} \
135131
var.name = x; \
136132
} while (0)
137-
GETARG(int, d.s, window_size, propGetInt, 15, 127);
138-
GETARG(double, d.s, topk, propGetFloat, 0.0001, 1);
139-
GETARG(double, d.s, tvi_threshold, propGetFloat, 0.0001, 1);
133+
GETARG(int, d.s, window_size, mapGetInt, 15, 127);
134+
GETARG(double, d.s, topk, mapGetFloat, 0.0001, 1);
135+
GETARG(double, d.s, tvi_threshold, mapGetFloat, 0.0001, 1);
140136
d.scores = 0;
141-
GETARG(int, d, scores, propGetInt, 0, 1);
137+
GETARG(int, d, scores, mapGetInt, 0, 1);
142138
d.scaling = 1.0f / d.s.window_size;
143-
GETARG(int, d, scaling, propGetFloat, 0, 1);
139+
GETARG(int, d, scaling, mapGetFloat, 0, 1);
144140
#undef GETARG
145141

146142
int err = cambi_init(&d.s, d.vi.width, d.vi.height);
147143
if (err != 0) {
148-
vsapi->setError(out, "cambi_init failure");
144+
vsapi->mapSetError(out, "cambi_init failure");
149145
vsapi->freeNode(d.node);
150146
return;
151147
}
152148

153149
CambiData *data = malloc(sizeof(d));
154150
*data = d;
155151

156-
vsapi->createFilter(in, out, "Cambi", cambiInit, cambiGetFrame, cambiFree, fmParallel, 0, data, core);
152+
VSFilterDependency deps[] = {{d.node, rpStrictSpatial}};
153+
154+
vsapi->createVideoFilter(out, "Cambi", &d.vi, cambiGetFrame, cambiFree, fmParallel, deps, 1, data, core);
157155
}
158156

159-
void bandingInitialize(VSConfigPlugin configFunc, VSRegisterFunction registerFunc, VSPlugin *plugin) {
160-
registerFunc("Cambi", "clip:clip;window_size:int:opt;topk:float:opt;tvi_threshold:float:opt;scores:int:opt;scaling:float:opt;", cambiCreate, 0, plugin);
157+
void bandingInitialize(VSPlugin *plugin, const VSPLUGINAPI *vsapi) {
158+
vsapi->registerFunction(
159+
"Cambi",
160+
"clip:vnode;window_size:int:opt;topk:float:opt;tvi_threshold:float:opt;scores:int:opt;scaling:float:opt;",
161+
"clip:vnode",
162+
cambiCreate,
163+
0,
164+
plugin
165+
);
161166
}

banding/internalfilters.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
#ifndef BANDING_INTERNALFILTERS_H
22
#define BANDING_INTERNALFILTERS_H
33

4-
#include "VapourSynth.h"
4+
#include "VapourSynth4.h"
55

66
#ifdef __cplusplus
77
extern "C" {
88
#endif
99

10-
void VS_CC bandingInitialize(VSConfigPlugin configFunc, VSRegisterFunction registerFunc, VSPlugin *plugin);
10+
void VS_CC bandingInitialize(VSPlugin *plugin, const VSPLUGINAPI *vsapi);
1111

1212
#ifdef __cplusplus
1313
}

expr/exprfilter.cpp

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@
3535
#include <unordered_map>
3636
#include <unordered_set>
3737
#include <vector>
38-
#include "VapourSynth.h"
39-
#include "VSHelper.h"
38+
#include "VapourSynth4.h"
39+
#include "VSHelper4.h"
4040
#include "cpufeatures.h"
4141
#include "internalfilters.h"
4242
#include "vslog.h"
@@ -184,7 +184,7 @@ enum PlaneOp {
184184
};
185185

186186
struct ExprData {
187-
VSNodeRef *node[MAX_EXPR_INPUTS];
187+
VSNode *node[MAX_EXPR_INPUTS];
188188
VSVideoInfo vi;
189189
std::vector<ExprInstruction> bytecode[3];
190190
std::vector<PropAccess> pa[3];
@@ -3735,24 +3735,24 @@ static void VS_CC exprInit(VSMap *in, VSMap *out, void **instanceData, VSNode *n
37353735
vsapi->setVideoInfo(&d->vi, 1, node);
37363736
}
37373737

3738-
static const VSFrameRef *VS_CC exprGetFrame(int n, int activationReason, void **instanceData, void **frameData, VSFrameContext *frameCtx, VSCore *core, const VSAPI *vsapi) {
3738+
static const VSFrame *VS_CC exprGetFrame(int n, int activationReason, void **instanceData, void **frameData, VSFrameContext *frameCtx, VSCore *core, const VSAPI *vsapi) {
37393739
ExprData *d = static_cast<ExprData *>(*instanceData);
37403740
int numInputs = d->numInputs;
37413741

37423742
if (activationReason == arInitial) {
37433743
for (int i = 0; i < numInputs; i++)
37443744
vsapi->requestFrameFilter(n, d->node[i], frameCtx);
37453745
} else if (activationReason == arAllFramesReady) {
3746-
const VSFrameRef *src[MAX_EXPR_INPUTS] = {};
3746+
const VSFrame *src[MAX_EXPR_INPUTS] = {};
37473747
for (int i = 0; i < numInputs; i++)
37483748
src[i] = vsapi->getFrameFilter(n, d->node[i], frameCtx);
37493749

37503750
const VSFormat *fi = d->vi.format;
37513751
int height = vsapi->getFrameHeight(src[0], 0);
37523752
int width = vsapi->getFrameWidth(src[0], 0);
37533753
int planes[3] = { 0, 1, 2 };
3754-
const VSFrameRef *srcf[3] = { d->plane[0] != poCopy ? nullptr : src[0], d->plane[1] != poCopy ? nullptr : src[0], d->plane[2] != poCopy ? nullptr : src[0] };
3755-
VSFrameRef *dst = vsapi->newVideoFrame2(fi, width, height, srcf, planes, src[0], core);
3754+
const VSFrame *srcf[3] = { d->plane[0] != poCopy ? nullptr : src[0], d->plane[1] != poCopy ? nullptr : src[0], d->plane[2] != poCopy ? nullptr : src[0] };
3755+
VSFrame *dst = vsapi->newVideoFrame2(fi, width, height, srcf, planes, src[0], core);
37563756

37573757
const uint8_t *srcp[MAX_EXPR_INPUTS] = {};
37583758
int src_stride[MAX_EXPR_INPUTS] = {};
@@ -3853,7 +3853,7 @@ static void VS_CC exprCreate(const VSMap *in, VSMap *out, void *userData, VSCore
38533853
#endif
38543854

38553855
try {
3856-
d->numInputs = vsapi->propNumElements(in, "clips");
3856+
d->numInputs = vsapi->mapNumElements(in, "clips");
38573857
if (d->numInputs > 26)
38583858
throw std::runtime_error("More than 26 input clips provided");
38593859

@@ -3903,13 +3903,13 @@ static void VS_CC exprCreate(const VSMap *in, VSMap *out, void *userData, VSCore
39033903
}
39043904
}
39053905

3906-
int nexpr = vsapi->propNumElements(in, "expr");
3906+
int nexpr = vsapi->mapNumElements(in, "expr");
39073907
if (nexpr > d->vi.format->numPlanes)
39083908
throw std::runtime_error("More expressions given than there are planes");
39093909

39103910
std::string expr[3];
39113911
for (int i = 0; i < nexpr; i++) {
3912-
expr[i] = vsapi->propGetData(in, "expr", i, nullptr);
3912+
expr[i] = vsapi->mapGetData(in, "expr", i, nullptr);
39133913
}
39143914
for (int i = nexpr; i < 3; ++i) {
39153915
expr[i] = expr[nexpr - 1];
@@ -3957,9 +3957,9 @@ static void VS_CC exprCreate(const VSMap *in, VSMap *out, void *userData, VSCore
39573957

39583958
void VS_CC versionCreate(const VSMap *in, VSMap *out, void *user_data, VSCore *core, const VSAPI *vsapi)
39593959
{
3960-
vsapi->propSetData(out, "expr_backend", "jitasm", -1, paAppend);
3960+
vsapi->mapSetData(out, "expr_backend", "jitasm", -1, maAppend);
39613961
for (const auto &f : features)
3962-
vsapi->propSetData(out, "expr_features", f.c_str(), -1, paAppend);
3962+
vsapi->mapSetData(out, "expr_features", f.c_str(), -1, maAppend);
39633963
}
39643964

39653965
} // namespace
@@ -3968,9 +3968,8 @@ void VS_CC versionCreate(const VSMap *in, VSMap *out, void *user_data, VSCore *c
39683968
//////////////////////////////////////////
39693969
// Init
39703970

3971-
void VS_CC exprInitialize(VSConfigPlugin configFunc, VSRegisterFunction registerFunc, VSPlugin *plugin) {
3972-
//configFunc("com.vapoursynth.expr", "expr", "VapourSynth Expr Filter", VAPOURSYNTH_API_VERSION, 1, plugin);
3973-
registerFunc("Expr", "clips:clip[];expr:data[];format:int:opt;", exprCreate, nullptr, plugin);
3971+
void VS_CC exprInitialize(VSPlugin *plugin, const VSPLUGINAPI *vsapi) {
3972+
vsapi->registerFunction("Expr", "clips:vnode[];expr:data[];format:int:opt;", "clip:vnode;", exprCreate, nullptr, plugin);
39743973

39753974
registerVersionFunc(versionCreate);
39763975
}

expr/internalfilters.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@
2121
#ifndef EXPR_INTERNALFILTERS_H
2222
#define EXPR_INTERNALFILTERS_H
2323

24-
#include "VapourSynth.h"
24+
#include "VapourSynth4.h"
2525

26-
void VS_CC exprInitialize(VSConfigPlugin configFunc, VSRegisterFunction registerFunc, VSPlugin *plugin);
26+
void VS_CC exprInitialize(VSPlugin *plugin, const VSPLUGINAPI *vsapi);
2727

2828
#endif // INTERNALFILTERS_H

expr/vslog.cpp

Lines changed: 96 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,100 @@
1-
#include <stdio.h>
2-
#include <stdarg.h>
3-
#include <stdlib.h>
1+
/*
2+
* Copyright (c) 2012-2013 Fredrik Mellbin
3+
*
4+
* This file is part of VapourSynth.
5+
*
6+
* VapourSynth is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU Lesser General Public
8+
* License as published by the Free Software Foundation; either
9+
* version 2.1 of the License, or (at your option) any later version.
10+
*
11+
* VapourSynth is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
* Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public
17+
* License along with VapourSynth; if not, write to the Free Software
18+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19+
*/
20+
21+
// This file only exists for V3 compatibility
422

523
#include "vslog.h"
24+
#include <cassert>
25+
#include <cstdlib>
26+
#include <cstdio>
27+
#include <cstdarg>
28+
#include <mutex>
29+
#include <map>
30+
#include <vector>
31+
32+
struct MessageHandler {
33+
vs3::VSMessageHandler handler;
34+
vs3::VSMessageHandlerFree free;
35+
void *userData;
36+
};
37+
38+
static std::map<int, MessageHandler> messageHandlers;
39+
static int currentHandlerId = 0;
40+
static int globalMessageHandler = -1;
41+
static std::mutex logMutex;
42+
43+
static int vsRemoveMessageHandlerInternal(int id) {
44+
if (messageHandlers.count(id)) {
45+
if (messageHandlers[id].free)
46+
messageHandlers[id].free(messageHandlers[id].userData);
47+
messageHandlers.erase(id);
48+
return 1;
49+
}
50+
return 0;
51+
}
52+
53+
void vsSetMessageHandler3(vs3::VSMessageHandler handler, void *userData) {
54+
std::lock_guard<std::mutex> lock(logMutex);
55+
if (globalMessageHandler >= 0) {
56+
vsRemoveMessageHandlerInternal(globalMessageHandler);
57+
globalMessageHandler = -1;
58+
}
59+
if (handler) {
60+
messageHandlers.emplace(currentHandlerId, MessageHandler{ handler, nullptr, userData });
61+
globalMessageHandler = currentHandlerId++;
62+
}
63+
}
64+
65+
int vsAddMessageHandler3(vs3::VSMessageHandler handler, vs3::VSMessageHandlerFree free, void *userData) {
66+
assert(handler);
67+
std::lock_guard<std::mutex> lock(logMutex);
68+
messageHandlers.emplace(currentHandlerId, MessageHandler{ handler, free, userData });
69+
return currentHandlerId++;
70+
}
71+
72+
int vsRemoveMessageHandler3(int id) {
73+
std::lock_guard<std::mutex> lock(logMutex);
74+
return vsRemoveMessageHandlerInternal(id);
75+
}
676

7-
void vsLog(const char *file, long line, VSMessageType type, const char *msg, ...) {
8-
const char *typs = nullptr;
9-
switch (type) {
10-
case mtDebug: typs = "DBG"; break;
11-
case mtWarning: typs = "WARN"; break;
12-
case mtCritical: typs = "CRIT"; break;
13-
case mtFatal: typs = "FATAL"; break;
14-
default: typs = "???"; break;
15-
}
16-
17-
va_list va;
18-
va_start(va, msg);
19-
fprintf(stderr, "[%s] %s:%ld: ", typs, file, line);
20-
vfprintf(stderr, msg, va);
21-
va_end(va);
22-
23-
if (type == mtFatal)
24-
abort();
77+
void vsLog3(vs3::VSMessageType type, const char *msg, ...) {
78+
std::lock_guard<std::mutex> lock(logMutex);
79+
if (!messageHandlers.empty()) {
80+
try {
81+
va_list alist;
82+
va_start(alist, msg);
83+
int size = vsnprintf(nullptr, 0, msg, alist);
84+
va_end(alist);
85+
std::vector<char> buf(size+1);
86+
va_start(alist, msg);
87+
vsnprintf(buf.data(), buf.size(), msg, alist);
88+
va_end(alist);
89+
for (const auto &iter : messageHandlers)
90+
iter.second.handler(type, buf.data(), iter.second.userData);
91+
} catch (std::bad_alloc &) {
92+
fprintf(stderr, "Bad alloc exception in log handler\n");
93+
va_list alist;
94+
va_start(alist, msg);
95+
vfprintf(stderr, msg, alist);
96+
va_end(alist);
97+
fprintf(stderr, "\n");
98+
}
99+
}
25100
}

0 commit comments

Comments
 (0)