Skip to content

Commit

Permalink
Resample: Add support for linearization/sigmoidization
Browse files Browse the repository at this point in the history
  • Loading branch information
Lypheo committed May 12, 2020
1 parent ebd485e commit bdc4478
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 23 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
build/
libplacebo/
libplacebo
16 changes: 11 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,20 @@ For example, to map from [BT.2020, PQ\] (HDR) to traditional [BT.709, BT.1886\]
- ``tone_mapping_algo, tone_mapping_param, desaturation_strength, desaturation_exponent, desaturation_base, max_boost, gamut_warning``:
[Color mapping params](https://github.com/haasn/libplacebo/blob/master/src/include/libplacebo/shaders/colorspace.h#L199).

#### ``placebo.Resample(clip clip[, int width, int height, string filter = "ewa_lanczos", float radius, float clamp, float taper, float blur, float param1, float param2, float sx = 0.0, float sy = 0.0, float antiring = 0.0, int lut_entries = 64, float cutoff = 0.001])``
**Don’t use with non-polar (i.e. not prefixed with “ewa\_”) filters!** Currently they output a slightly shifted image for unknown reasons
(though only for large frames, which makes me suspect a libplacebo bug, but what do I know).
#### ``placebo.Resample(clip clip[, int width, int height, string filter = "ewa_lanczos", float radius, float clamp, float taper, float blur, float param1, float param2, float sx = 0.0, float sy = 0.0, float antiring = 0.0, int lut_entries = 64, float cutoff = 0.001, bool sigmoidize = 1, bool linearize = 1, float sigmoid_center = 0.75, float sigmoid_slope = 6.5, int trc = 1])``

Input needs to be 8 or 16 bit Integer or 32 bit Float

- ``filter``: See [the header](https://github.com/haasn/libplacebo/blob/210131146739e4e84d689f32c17a97b27a6550bd/src/include/libplacebo/filters.h#L187) for possible values (remove the “pl_filter” before the filter name, e.g. ``filter="lanczos"``).
- ``sx``, ``sy``: Top left corner of the source region. Can be used for subpixel shifts
- ``float clamp, float taper, float blur``: [Filter config](https://github.com/haasn/libplacebo/blob/885e89bccfb932d9e8c8659039ab6975e885e996/src/include/libplacebo/filters.h#L148).
- ``clamp, taper, blur``: [Filter config](https://github.com/haasn/libplacebo/blob/885e89bccfb932d9e8c8659039ab6975e885e996/src/include/libplacebo/filters.h#L148).

- ``float radius, float param1, float param2``: [Kernel config](https://github.com/haasn/libplacebo/blob/885e89bccfb932d9e8c8659039ab6975e885e996/src/include/libplacebo/filters.h#L30-L131).
- ``radius, param1, param2``: [Kernel config](https://github.com/haasn/libplacebo/blob/885e89bccfb932d9e8c8659039ab6975e885e996/src/include/libplacebo/filters.h#L30-L131).
- ``sigmoidize, linearize``: Whether to linearize/sigmoidize before scaling.
When sigmodizing, ``linearize`` should be True as well. (Currently mangles HDR video, so disable for that.)
- ``sigmoid_center, sigmoid_slope``: Sigmoid curve parameters.
- ``trc``: The transfer curve to use for linearizing.

In theory, ewa_* filters should be significantly slower than seperable ones,
and disabling linearization/sigmoidization should provide a speed-up,
however in practice they all perform equally since they’re bottlenecked by GPU transfers.
93 changes: 76 additions & 17 deletions resample.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <libplacebo/dispatch.h>
#include <libplacebo/utils/upload.h>
#include <libplacebo/filters.h>
#include <libplacebo/colorspace.h>

typedef struct {
VSNodeRef *node;
Expand All @@ -18,24 +19,57 @@ typedef struct {
struct pl_shader_obj *lut;
float src_x;
float src_y;
struct pl_sigmoid_params * sigmoid_params;
enum pl_color_transfer trc;
bool linear;
} RData;

bool do_plane_R(struct priv *p, void* data, int w, int h, const VSAPI *vsapi, float sx, float sy)
{
RData* d = (RData*) data;
struct pl_shader *sh = pl_dispatch_begin(p->dp);
const struct pl_tex *sample_fbo = NULL;
const struct pl_tex *sep_fbo = NULL;
struct pl_sample_src src = (struct pl_sample_src){ .tex = p->tex_in[0], .new_h = h, .new_w = w,
.rect = {
sx,
sy,
p->tex_in[0]->params.w + sx,
p->tex_in[0]->params.h + sy,
}
};
struct pl_sample_src src = (struct pl_sample_src){ .tex = p->tex_in[0]};
struct pl_sample_filter_params sampleFilterParams = *d->sampleParams;
sampleFilterParams.lut = &d->lut;

//
// linearization and sigmoidization
//

struct pl_shader *ish = pl_dispatch_begin(p->dp);
struct pl_tex_params tex_params = {.w = src.tex->params.w, .h = src.tex->params.h, .renderable = true, .sampleable = true, .format = src.tex->params.format, .sample_mode = PL_TEX_SAMPLE_LINEAR};

if (!pl_tex_recreate(p->gpu, &sample_fbo, &tex_params))
vsapi->logMessage(mtCritical, "failed creating intermediate color texture!\n");

pl_shader_sample_direct(ish, &src);
if (d->linear)
pl_shader_linearize(ish, d->trc);

if (d->sigmoid_params)
pl_shader_sigmoidize(ish, d->sigmoid_params);

if (!pl_dispatch_finish(p->dp, &ish, sample_fbo, NULL, NULL)) {
vsapi->logMessage(mtCritical, "Failed linearizing/sigmoidizing! \n");
return false;
}

//
// sampling
//

struct pl_rect2df rect = {
sx,
sy,
p->tex_in[0]->params.w + sx,
p->tex_in[0]->params.h + sy,
};
src.tex = sample_fbo;
src.rect = rect;
src.new_h = h; src.new_w = w;

if (d->sampleParams->filter.polar) {
if (!pl_shader_sample_polar(sh, &src, &sampleFilterParams))
vsapi->logMessage(mtCritical, "Failed dispatching scaler...\n");
Expand All @@ -62,9 +96,19 @@ bool do_plane_R(struct priv *p, void* data, int w, int h, const VSAPI *vsapi, fl
if (!pl_shader_sample_ortho(sh, PL_SEP_HORIZ, &src2, &sampleFilterParams))
vsapi->logMessage(mtCritical, "Failed dispatching horizontal pass! \n");
}

if (d->sigmoid_params)
pl_shader_unsigmoidize(sh, d->sigmoid_params);

if (d->linear)
pl_shader_delinearize(sh, d->trc);


bool ok = pl_dispatch_finish(p->dp, &sh, p->tex_out[0], NULL, NULL);
pl_tex_destroy(p->gpu, &sep_fbo);

pl_tex_destroy(p->gpu, &sample_fbo);
return ok;
//
// struct pl_plane plane = (struct pl_plane) {.texture = p->tex_in[0], .components = 1, .component_mapping[0] = 0};
//
// struct pl_color_repr crpr = {.bits = {.sample_depth = d->vi->format->bytesPerSample * 8, .color_depth =
Expand All @@ -75,13 +119,14 @@ bool do_plane_R(struct priv *p, void* data, int w, int h, const VSAPI *vsapi, fl
// .planes[0] = plane,
// .repr = crpr, .color = (struct pl_color_space) {0}};
// struct pl_render_target out = {.color = (struct pl_color_space) {0}, .repr = crpr, .fbo = p->tex_out[0]};
// struct pl_render_params par = pl_render_default_params;
// par.skip_redraw_caching = true;
// par.downscaler = &d->sampleParams->filter;
// par.deband_params = NULL;
// struct pl_render_params par = {
// .downscaler = &d->sampleParams->filter,
// .upscaler = &d->sampleParams->filter,
// .sigmoid_params = d->sigmoid_params,
// .disable_linear_scaling = 0
// };
// return pl_render_image(p->rr, &img, &out, &par);

return ok;
}

bool reconfig_R(void *priv, struct pl_plane_data *data, int w, int h, const VSAPI *vsapi)
Expand Down Expand Up @@ -212,6 +257,7 @@ static void VS_CC ResampleFree(void *instanceData, VSCore *core, const VSAPI *vs
pl_shader_obj_destroy(&d->lut);
free(d->sampleParams->filter.kernel);
free(d->sampleParams);
free(d->sigmoid_params);
uninit(d->vf);
free(d);
}
Expand All @@ -225,7 +271,7 @@ void VS_CC ResampleCreate(const VSMap *in, VSMap *out, void *userData, VSCore *c
d.vi = vsapi->getVideoInfo(d.node);

if ((d.vi->format->bitsPerSample != 8 && d.vi->format->bitsPerSample != 16 && d.vi->format->bitsPerSample != 32)) {
vsapi->setError(out, "placebo.Rsample: Input bitdepth should be 8, 16 (Integer) or 32 (Float)!.");
vsapi->setError(out, "placebo.Resample: Input bitdepth should be 8, 16 (Integer) or 32 (Float)!.");
vsapi->freeNode(d.node);
}

Expand All @@ -241,9 +287,22 @@ void VS_CC ResampleCreate(const VSMap *in, VSMap *out, void *userData, VSCore *c

d.src_x = vsapi->propGetFloat(in, "sx", 0, &err);
d.src_y = vsapi->propGetFloat(in, "sy", 0, &err);
d.linear = vsapi->propGetInt(in, "linearize", 0, &err);
if (err) d.linear = 1;
d.trc = vsapi->propGetInt(in, "trc", 0, &err);
if (err) d.trc = 1;

struct pl_sigmoid_params *sigmoidParams = malloc(sizeof(struct pl_sigmoid_params));
sigmoidParams->center = vsapi->propGetFloat(in, "sigmoid_center", 0, &err);
if (err) sigmoidParams->center = pl_sigmoid_default_params.center;
sigmoidParams->slope = vsapi->propGetFloat(in, "sigmoid_slope", 0, &err);
if (err) sigmoidParams->slope = pl_sigmoid_default_params.slope;
bool sigm = vsapi->propGetInt(in, "sigmoidize", 0, &err);
if (err) sigm = true;
d.sigmoid_params = sigm ? sigmoidParams : NULL;


struct pl_sample_filter_params *sampleFilterParams = malloc(sizeof(struct pl_sample_filter_params));;
struct pl_sample_filter_params *sampleFilterParams = calloc(1, sizeof(struct pl_sample_filter_params));;

d.lut = NULL;
sampleFilterParams->no_widening = false;
Expand Down Expand Up @@ -282,7 +341,7 @@ void VS_CC ResampleCreate(const VSMap *in, VSMap *out, void *userData, VSCore *c
sampleFilterParams->filter.clamp = vsapi->propGetFloat(in, "clamp", 0, &err);
sampleFilterParams->filter.blur = vsapi->propGetFloat(in, "blur", 0, &err);
sampleFilterParams->filter.taper = vsapi->propGetFloat(in, "taper", 0, &err);
struct pl_filter_function *f = malloc(sizeof(struct pl_filter_function));
struct pl_filter_function *f = calloc(1, sizeof(struct pl_filter_function));
*f = *sampleFilterParams->filter.kernel;
if (f->resizable) {
vsapi->propGetFloat(in, "radius", 0, &err);
Expand Down
3 changes: 2 additions & 1 deletion vs-placebo.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ VS_EXTERNAL_API(void) VapourSynthPluginInit(VSConfigPlugin configFunc, VSRegiste
configFunc("com.vs.placebo", "placebo", "libplacebo plugin for VapourSynth", VAPOURSYNTH_API_VERSION, 1, plugin);
registerFunc("Deband", "clip:clip;planes:int:opt;iterations:int:opt;threshold:float:opt;radius:float:opt;grain:float:opt;dither:int:opt;dither_algo:int:opt;renderer_api:int:opt", DebandCreate, 0, plugin);
registerFunc("Resample", "clip:clip;width:int;height:int;filter:data:opt;clamp:float:opt;blur:float:opt;taper:float:opt;radius:float:opt;param1:float:opt;param2:float:opt;"
"sx:float:opt;sy:float:opt;antiring:float:opt;lut_entries:int:opt;cutoff:float:opt", ResampleCreate, 0, plugin);
"sx:float:opt;sy:float:opt;antiring:float:opt;lut_entries:int:opt;cutoff:float:opt;"
"sigmoidize:int:opt;sigmoid_center:float:opt;sigmoid_slope:float:opt;linearize:int:opt;trc:int:opt", ResampleCreate, 0, plugin);
registerFunc("Tonemap", "clip:clip;"
"srcp:int:opt;srct:int:opt;srcl:int:opt;src_peak:float:opt;src_avg:float:opt;src_scale:float:opt;"
"dstp:int:opt;dstt:int:opt;dstl:int:opt;dst_peak:float:opt;dst_avg:float:opt;dst_scale:float:opt;"
Expand Down

0 comments on commit bdc4478

Please sign in to comment.