Skip to content

Commit 0633d39

Browse files
authored
Merge pull request #23 from quietvoid/fix_deband
Modernize placebo code and fix conflicting function names
2 parents 36c6177 + 01f2378 commit 0633d39

11 files changed

+371
-327
lines changed

README.md

+7
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,13 @@ using the supplied filter options, which are identical to ``Resample``’s.
8484

8585
 
8686

87+
### Debugging `libplacebo` processing
88+
89+
All the filters can take a `log_level` argument corresponding to a `pl_log_level`.
90+
Defaults to 2, meaning only errors are logged.
91+
92+
 
93+
8794
### Installing
8895

8996
If you’re on Arch, just do

src/deband.c

+98-127
Original file line numberDiff line numberDiff line change
@@ -16,86 +16,39 @@ typedef struct {
1616
int dither;
1717
struct pl_dither_params *ditherParams;
1818
struct pl_deband_params *debandParams;
19-
int renderer; // for debugging purposes
2019
uint8_t frame_index;
20+
2121
pthread_mutex_t lock;
22-
} MData;
22+
} DebandData;
2323

24-
bool do_plane(struct priv *p, void* data, int chroma)
24+
bool vspl_deband_do_plane(struct priv *p, void* data)
2525
{
26-
MData* d = (MData*) data;
27-
28-
if (!d->renderer) {
29-
30-
struct pl_shader *sh = pl_dispatch_begin(p->dp);
31-
pl_shader_reset(sh, &(struct pl_shader_params) {
32-
.gpu = p->gpu,
33-
.index = d->frame_index++,
34-
});
35-
36-
int new_depth = p->tex_out[0]->params.format->component_depth[0];
37-
pl_shader_deband(sh, &(struct pl_sample_src) {.tex = p->tex_in[0]},
38-
d->debandParams);
39-
if (d->dither)
40-
pl_shader_dither(sh, new_depth, &p->dither_state, d->ditherParams);
41-
return pl_dispatch_finish(p->dp, &(struct pl_dispatch_params) {
42-
.shader = &sh,
43-
.target = p->tex_out[0],
44-
});
45-
46-
} else {
47-
struct pl_color_repr crpr = {
48-
.bits = {
49-
.sample_depth = d->vi->format->bytesPerSample * 8,
50-
.color_depth = d->vi->format->bytesPerSample * 8,
51-
.bit_shift = 0
52-
},
53-
.levels = PL_COLOR_LEVELS_UNKNOWN,
54-
.alpha = PL_ALPHA_UNKNOWN,
55-
.sys = PL_COLOR_SYSTEM_UNKNOWN
56-
};
57-
58-
int src_w = d->vi->width >> (chroma ? d->vi->format->subSamplingW : 0);
59-
int src_h = d->vi->height >> (chroma ? d->vi->format->subSamplingH : 0);
60-
61-
struct pl_color_space color = (struct pl_color_space) {0};
62-
63-
struct pl_frame img = {
64-
.num_planes = 1,
65-
.planes = {{
66-
.texture = p->tex_in[0],
67-
.components = p->tex_in[0]->params.format->num_components,
68-
.component_mapping = {0, 1, 2, 3},
69-
}},
70-
.repr = crpr,
71-
.color = color,
72-
.crop = {0, 0, src_w, src_h},
73-
};
74-
75-
struct pl_frame out = {
76-
.num_planes = 1,
77-
.planes = {{
78-
.texture = p->tex_out[0],
79-
.components = p->tex_out[0]->params.format->num_components,
80-
.component_mapping = {0, 1, 2, 3},
81-
}},
82-
.repr = crpr,
83-
.color = color,
84-
.crop = {0, 0, src_w, src_h},
85-
};
86-
87-
pl_rect2df_aspect_copy(&out.crop, &img.crop, 0.0);
88-
89-
struct pl_render_params par = pl_render_default_params;
90-
par.deband_params = d->debandParams;
91-
par.dither_params = d->dither ? d->ditherParams : NULL;
92-
93-
return pl_render_image(p->rr, &img, &out, &par);
26+
DebandData* d = (DebandData*) data;
9427

95-
}
28+
pl_shader sh = pl_dispatch_begin(p->dp);
29+
pl_shader_reset(sh, pl_shader_params(
30+
.gpu = p->gpu,
31+
.index = d->frame_index++,
32+
));
33+
34+
struct pl_sample_src *src = pl_sample_src(
35+
.tex = p->tex_in[0]
36+
);
37+
38+
int new_depth = p->tex_out[0]->params.format->component_depth[0];
39+
40+
pl_shader_deband(sh, src, d->debandParams);
41+
42+
if (d->dither)
43+
pl_shader_dither(sh, new_depth, &p->dither_state, d->ditherParams);
44+
45+
return pl_dispatch_finish(p->dp, pl_dispatch_params(
46+
.target = p->tex_out[0],
47+
.shader = &sh,
48+
));
9649
}
9750

98-
bool reconfig(void *priv, struct pl_plane_data *data, const VSAPI *vsapi)
51+
bool vspl_deband_reconfig(void *priv, const struct pl_plane_data *data, const VSAPI *vsapi, VSFrameRef *dst, int planeIdx)
9952
{
10053
struct priv *p = priv;
10154

@@ -106,21 +59,21 @@ bool reconfig(void *priv, struct pl_plane_data *data, const VSAPI *vsapi)
10659
}
10760

10861
bool ok = true;
109-
ok &= pl_tex_recreate(p->gpu, &p->tex_in[0], &(struct pl_tex_params) {
110-
.w = data->width,
111-
.h = data->height,
112-
.format = fmt,
113-
.sampleable = true,
114-
.host_writable = true,
115-
});
116-
117-
ok &= pl_tex_recreate(p->gpu, &p->tex_out[0], &(struct pl_tex_params) {
118-
.w = data->width,
119-
.h = data->height,
120-
.format = fmt,
121-
.renderable = true,
122-
.host_readable = true,
123-
});
62+
ok &= pl_tex_recreate(p->gpu, &p->tex_in[0], pl_tex_params(
63+
.w = data->width,
64+
.h = data->height,
65+
.format = fmt,
66+
.sampleable = true,
67+
.host_writable = true,
68+
));
69+
70+
ok &= pl_tex_recreate(p->gpu, &p->tex_out[0], pl_tex_params(
71+
.w = vsapi->getFrameWidth(dst, planeIdx),
72+
.h = vsapi->getFrameHeight(dst, planeIdx),
73+
.format = fmt,
74+
.renderable = true,
75+
.host_readable = true,
76+
));
12477

12578
if (!ok) {
12679
vsapi->logMessage(mtCritical, "Failed creating GPU textures!\n");
@@ -130,35 +83,40 @@ bool reconfig(void *priv, struct pl_plane_data *data, const VSAPI *vsapi)
13083
return true;
13184
}
13285

133-
bool filter(void *priv, void *dst, struct pl_plane_data *src, void* d, const VSAPI *vsapi, int chroma)
86+
bool vspl_deband_filter(void *priv, VSFrameRef *dst, const struct pl_plane_data *data, void* d, const VSAPI *vsapi, int planeIdx)
13487
{
13588
struct priv *p = priv;
89+
pl_fmt in_fmt = p->tex_in[0]->params.format;
90+
pl_fmt out_fmt = p->tex_out[0]->params.format;
13691

13792
// Upload planes
13893
bool ok = true;
139-
ok &= pl_tex_upload(p->gpu, &(struct pl_tex_transfer_params) {
94+
ok &= pl_tex_upload(p->gpu, pl_tex_transfer_params(
14095
.tex = p->tex_in[0],
141-
.stride_w = src->row_stride / src->pixel_stride,
142-
.ptr = (void *) src->pixels,
143-
});
96+
.row_pitch = (data->row_stride / data->pixel_stride) * in_fmt->texel_size,
97+
.ptr = (void *) data->pixels,
98+
));
14499

145100
if (!ok) {
146101
vsapi->logMessage(mtCritical, "Failed uploading data to the GPU!\n");
147102
return false;
148103
}
149104

150105
// Process plane
151-
if (!do_plane(p, d, chroma)) {
106+
if (!vspl_deband_do_plane(p, d)) {
152107
vsapi->logMessage(mtCritical, "Failed processing planes!\n");
153108
return false;
154109
}
155110

111+
uint8_t *dst_ptr = vsapi->getWritePtr(dst, planeIdx);
112+
int dst_row_pitch = (vsapi->getStride(dst, planeIdx) / data->pixel_stride) * out_fmt->texel_size;
113+
156114
// Download planes
157-
ok = pl_tex_download(p->gpu, &(struct pl_tex_transfer_params) {
115+
ok = pl_tex_download(p->gpu, pl_tex_transfer_params(
158116
.tex = p->tex_out[0],
159-
.stride_w = src->row_stride / src->pixel_stride,
160-
.ptr = dst,
161-
});
117+
.row_pitch = dst_row_pitch,
118+
.ptr = (void *) dst_ptr,
119+
));
162120

163121
if (!ok) {
164122
vsapi->logMessage(mtCritical, "Failed downloading data from the GPU!\n");
@@ -168,14 +126,14 @@ bool filter(void *priv, void *dst, struct pl_plane_data *src, void* d, const VSA
168126
return true;
169127
}
170128

171-
static void VS_CC DebandInit(VSMap *in, VSMap *out, void **instanceData, VSNode *node, VSCore *core, const VSAPI *vsapi) {
172-
MData *d = (MData *) * instanceData;
129+
static void VS_CC VSPlaceboDebandInit(VSMap *in, VSMap *out, void **instanceData, VSNode *node, VSCore *core, const VSAPI *vsapi) {
130+
DebandData *d = (DebandData *) * instanceData;
173131
VSVideoInfo new_vi = (VSVideoInfo) * (d->vi);
174132
vsapi->setVideoInfo(&new_vi, 1, node);
175133
}
176134

177-
static const VSFrameRef *VS_CC DebandGetFrame(int n, int activationReason, void **instanceData, void **frameData, VSFrameContext *frameCtx, VSCore *core, const VSAPI *vsapi) {
178-
MData *d = (MData *) * instanceData;
135+
static const VSFrameRef *VS_CC VSPlaceboDebandGetFrame(int n, int activationReason, void **instanceData, void **frameData, VSFrameContext *frameCtx, VSCore *core, const VSAPI *vsapi) {
136+
DebandData *d = (DebandData *) * instanceData;
179137

180138
if (activationReason == arInitial) {
181139
vsapi->requestFrameFilter(n, d->node, frameCtx);
@@ -185,32 +143,37 @@ static const VSFrameRef *VS_CC DebandGetFrame(int n, int activationReason, void
185143
int ih = vsapi->getFrameHeight(frame, 0);
186144
int iw = vsapi->getFrameWidth(frame, 0);
187145

188-
int copy[3];
146+
int copy[3] = {0};
189147
for (unsigned int j = 0; j < 3; ++j)
190148
copy[j] = ((1u << j) & d->planes) == 0;
191149

192-
VSFrameRef *dst = vsapi->newVideoFrame(d->vi->format, iw, ih, frame, core);
150+
const VSFormat *srcFmt = d->vi->format;
151+
VSFrameRef *dst = vsapi->newVideoFrame(srcFmt, iw, ih, frame, core);
193152

194-
for (int i=0; i<d->vi->format->numPlanes; i++) {
153+
for (unsigned int i = 0; i < srcFmt->numPlanes; i++) {
195154
if (copy[i]) {
196155
vs_bitblt(vsapi->getWritePtr(dst, i), vsapi->getStride(dst, i), vsapi->getWritePtr((VSFrameRef *) frame, i),
197156
vsapi->getStride(frame, i), vsapi->getFrameWidth(dst, i) * d->vi->format->bytesPerSample,
198157
vsapi->getFrameHeight(dst, i));
199158
} else {
200-
struct pl_plane_data plane = {
201-
.type = d->vi->format->sampleType == stInteger ? PL_FMT_UNORM : PL_FMT_FLOAT,
202-
.width = vsapi->getFrameWidth(frame, i),
203-
.height = vsapi->getFrameHeight(frame, i),
204-
.pixel_stride = 1 /* components */ * d->vi->format->bytesPerSample /* bytes per sample*/,
205-
.row_stride = vsapi->getStride(frame, i),
206-
.pixels = vsapi->getWritePtr((VSFrameRef *) frame, i),
207-
.component_size[0] = d->vi->format->bitsPerSample,
208-
.component_pad[0] = 0,
209-
.component_map[0] = 0,
159+
const struct pl_plane_data plane = {
160+
.type = srcFmt->sampleType == stInteger ? PL_FMT_UNORM : PL_FMT_FLOAT,
161+
.width = vsapi->getFrameWidth(frame, i),
162+
.height = vsapi->getFrameHeight(frame, i),
163+
.pixel_stride = srcFmt->bytesPerSample,
164+
.row_stride = vsapi->getStride(frame, i),
165+
.pixels = vsapi->getReadPtr((VSFrameRef *) frame, i),
166+
.component_size[0] = srcFmt->bitsPerSample,
167+
.component_pad[0] = 0,
168+
.component_map[0] = 0,
210169
};
170+
211171
pthread_mutex_lock(&d->lock); // libplacebo isn’t thread-safe
212-
if (reconfig(d->vf, &plane, vsapi))
213-
filter(d->vf, vsapi->getWritePtr(dst, i), &plane, d, vsapi, i != 0);
172+
173+
if (vspl_deband_reconfig(d->vf, &plane, vsapi, dst, i)) {
174+
vspl_deband_filter(d->vf, dst, &plane, d, vsapi, i);
175+
}
176+
214177
pthread_mutex_unlock(&d->lock);
215178
}
216179
}
@@ -222,27 +185,32 @@ static const VSFrameRef *VS_CC DebandGetFrame(int n, int activationReason, void
222185
return 0;
223186
}
224187

225-
static void VS_CC DebandFree(void *instanceData, VSCore *core, const VSAPI *vsapi) {
226-
MData *d = (MData *)instanceData;
188+
static void VS_CC VSPlaceboDebandFree(void *instanceData, VSCore *core, const VSAPI *vsapi) {
189+
DebandData *d = (DebandData *) instanceData;
227190
vsapi->freeNode(d->node);
228-
uninit(d->vf);
191+
VSPlaceboUninit(d->vf);
229192
free(d->ditherParams);
230193
free(d->debandParams);
231194
pthread_mutex_destroy(&d->lock);
232195
free(d);
233196
}
234197

235-
void VS_CC DebandCreate(const VSMap *in, VSMap *out, void *userData, VSCore *core, const VSAPI *vsapi) {
236-
MData d;
237-
MData *data;
198+
void VS_CC VSPlaceboDebandCreate(const VSMap *in, VSMap *out, void *userData, VSCore *core, const VSAPI *vsapi) {
199+
DebandData d;
200+
DebandData *data;
238201
int err;
202+
enum pl_log_level log_level;
239203

240204
if (pthread_mutex_init(&d.lock, NULL) != 0)
241205
{
242206
vsapi->setError(out, "placebo.Deband: mutex init failed\n");
243207
return;
244208
}
245209

210+
log_level = vsapi->propGetInt(in, "log_level", 0, &err);
211+
if (err)
212+
log_level = PL_LOG_ERR;
213+
246214
d.node = vsapi->propGetNode(in, "clip", 0, 0);
247215
d.vi = vsapi->getVideoInfo(d.node);
248216

@@ -251,9 +219,8 @@ void VS_CC DebandCreate(const VSMap *in, VSMap *out, void *userData, VSCore *cor
251219
vsapi->freeNode(d.node);
252220
}
253221

254-
d.vf = init();
222+
d.vf = VSPlaceboInit(log_level);
255223

256-
d.renderer = vsapi->propGetInt(in, "renderer_api", 0, &err);
257224
d.dither = vsapi->propGetInt(in, "dither", 0, &err) && d.vi->format->bitsPerSample == 8;
258225
if (err)
259226
d.dither = d.vi->format->bitsPerSample == 8;
@@ -263,24 +230,28 @@ void VS_CC DebandCreate(const VSMap *in, VSMap *out, void *userData, VSCore *cor
263230
d.planes = 1u;
264231

265232
struct pl_deband_params *debandParams = malloc(sizeof(struct pl_deband_params));
233+
*debandParams = pl_deband_default_params;
234+
266235
#define DB_PARAM(par, type) debandParams->par = vsapi->propGet##type(in, #par, 0, &err); \
267236
if (err) debandParams->par = pl_deband_default_params.par;
268237

269238
DB_PARAM(iterations, Int)
270239
DB_PARAM(threshold, Float)
271-
DB_PARAM(grain, Float)
272240
DB_PARAM(radius, Float)
241+
DB_PARAM(grain, Float)
273242

274243
struct pl_dither_params *plDitherParams = malloc(sizeof(struct pl_dither_params));
275244
*plDitherParams = pl_dither_default_params;
245+
276246
plDitherParams->method = vsapi->propGetInt(in, "dither_algo", 0, &err);
277247
if (err)
278248
plDitherParams->method = pl_dither_default_params.method;
279249

280250
d.ditherParams = plDitherParams;
281251
d.debandParams = debandParams;
252+
d.frame_index = 0;
282253
data = malloc(sizeof(d));
283254
*data = d;
284255

285-
vsapi->createFilter(in, out, "Deband", DebandInit, DebandGetFrame, DebandFree, fmParallel, 0, data, core);
256+
vsapi->createFilter(in, out, "Deband", VSPlaceboDebandInit, VSPlaceboDebandGetFrame, VSPlaceboDebandFree, fmParallel, 0, data, core);
286257
}

src/deband.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33

44
#include "VapourSynth.h"
55

6-
void VS_CC DebandCreate(const VSMap *in, VSMap *out, void *userData, VSCore *core, const VSAPI *vsapi);
6+
void VS_CC VSPlaceboDebandCreate(const VSMap *in, VSMap *out, void *userData, VSCore *core, const VSAPI *vsapi);
77

88
#endif //VS_PLACEBO_DEBAND_H

0 commit comments

Comments
 (0)