Re: [FFmpeg-devel] [PATCH v2] avfilter/vf_lut3d: prelut support for 3d cinespace luts
On Sat, May 30, 2020 at 09:59:35AM +0200, Paul B Mahol wrote: > LGTM will apply thx [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Many things microsoft did are stupid, but not doing something just because microsoft did it is even more stupid. If everything ms did were stupid they would be bankrupt already. signature.asc Description: PGP signature ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v2] avfilter/vf_lut3d: prelut support for 3d cinespace luts
LGTM On 5/24/20, mindm...@gmail.com wrote: > From: Mark Reid > > changes since v1: > * cleaned up code style > * slightly reworked apply_lut functions to feel more consistent with code > > --- > libavfilter/vf_lut3d.c | 372 +++-- > 1 file changed, 317 insertions(+), 55 deletions(-) > > diff --git a/libavfilter/vf_lut3d.c b/libavfilter/vf_lut3d.c > index 482e2394a7..e5d9fcc068 100644 > --- a/libavfilter/vf_lut3d.c > +++ b/libavfilter/vf_lut3d.c > @@ -59,6 +59,15 @@ struct rgbvec { > /* 3D LUT don't often go up to level 32, but it is common to have a Hald > CLUT > * of 512x512 (64x64x64) */ > #define MAX_LEVEL 256 > +#define PRELUT_SIZE 65536 > + > +typedef struct Lut3DPreLut { > +int size; > +float min[3]; > +float max[3]; > +float scale[3]; > +float* lut[3]; > +} Lut3DPreLut; > > typedef struct LUT3DContext { > const AVClass *class; > @@ -71,6 +80,7 @@ typedef struct LUT3DContext { > struct rgbvec *lut; > int lutsize; > int lutsize2; > +Lut3DPreLut prelut; > #if CONFIG_HALDCLUT_FILTER > uint8_t clut_rgba_map[4]; > int clut_step; > @@ -234,11 +244,39 @@ static inline struct rgbvec interp_tetrahedral(const > LUT3DContext *lut3d, > return c; > } > > +static inline float prelut_interp_1d_linear(const Lut3DPreLut *prelut, > +int idx, const float s) > +{ > +const int lut_max = prelut->size - 1; > +const float scaled = (s - prelut->min[idx]) * prelut->scale[idx]; > +const float x = av_clipf(scaled, 0.0f, lut_max); > +const int prev = PREV(x); > +const int next = FFMIN((int)(x) + 1, lut_max); > +const float p = prelut->lut[idx][prev]; > +const float n = prelut->lut[idx][next]; > +const float d = x - (float)prev; > +return lerpf(p, n, d); > +} > + > +static inline struct rgbvec apply_prelut(const Lut3DPreLut *prelut, > + const struct rgbvec *s) > +{ > +if (prelut->size <= 0) > +return *s; > + > +struct rgbvec c; > +c.r = prelut_interp_1d_linear(prelut, 0, s->r); > +c.g = prelut_interp_1d_linear(prelut, 1, s->g); > +c.b = prelut_interp_1d_linear(prelut, 2, s->b); > +return c; > +} > + > #define DEFINE_INTERP_FUNC_PLANAR(name, nbits, depth) >\ > static int interp_##nbits##_##name##_p##depth(AVFilterContext *ctx, void > *arg, int jobnr, int nb_jobs) \ > { >\ > int x, y; >\ > const LUT3DContext *lut3d = ctx->priv; >\ > +const Lut3DPreLut *prelut = >prelut; >\ > const ThreadData *td = arg; >\ > const AVFrame *in = td->in; >\ > const AVFrame *out = td->out; >\ > @@ -253,9 +291,11 @@ static int > interp_##nbits##_##name##_p##depth(AVFilterContext *ctx, void *arg, i > const uint8_t *srcbrow = in->data[1] + slice_start * in->linesize[1]; >\ > const uint8_t *srcrrow = in->data[2] + slice_start * in->linesize[2]; >\ > const uint8_t *srcarow = in->data[3] + slice_start * in->linesize[3]; >\ > -const float scale_r = (lut3d->scale.r / ((1< (lut3d->lutsize - 1); \ > -const float scale_g = (lut3d->scale.g / ((1< (lut3d->lutsize - 1); \ > -const float scale_b = (lut3d->scale.b / ((1< (lut3d->lutsize - 1); \ > +const float lut_max = lut3d->lutsize - 1; >\ > +const float scale_f = 1.0f / ((1<\ > +const float scale_r = lut3d->scale.r * lut_max; >\ > +const float scale_g = lut3d->scale.g * lut_max; >\ > +const float scale_b = lut3d->scale.b * lut_max; >\ > >\ > for (y = slice_start; y < slice_end; y++) { >\ > uint##nbits##_t *dstg = (uint##nbits##_t *)grow; >\ > @@ -267,9 +307,13 @@ static int > interp_##nbits##_##name##_p##depth(AVFilterContext *ctx, void *arg, i > const uint##nbits##_t *srcr = (const uint##nbits##_t *)srcrrow; >\ > const uint##nbits##_t *srca = (const uint##nbits##_t *)srcarow; >\ > for (x = 0; x < in->width; x++) { >\ > -const struct rgbvec scaled_rgb = {srcr[x] * scale_r, >\ > - srcg[x] * scale_g, >\ > - srcb[x] * scale_b}; >\ > +const struct rgbvec rgb = {srcr[x] * scale_f, >
Re: [FFmpeg-devel] [PATCH v2] avfilter/vf_lut3d: prelut support for 3d cinespace luts
On Sat, May 23, 2020 at 7:04 PM wrote: > From: Mark Reid > > changes since v1: > * cleaned up code style > * slightly reworked apply_lut functions to feel more consistent with code > > --- > libavfilter/vf_lut3d.c | 372 +++-- > 1 file changed, 317 insertions(+), 55 deletions(-) > > diff --git a/libavfilter/vf_lut3d.c b/libavfilter/vf_lut3d.c > index 482e2394a7..e5d9fcc068 100644 > --- a/libavfilter/vf_lut3d.c > +++ b/libavfilter/vf_lut3d.c > @@ -59,6 +59,15 @@ struct rgbvec { > /* 3D LUT don't often go up to level 32, but it is common to have a Hald > CLUT > * of 512x512 (64x64x64) */ > #define MAX_LEVEL 256 > +#define PRELUT_SIZE 65536 > + > +typedef struct Lut3DPreLut { > +int size; > +float min[3]; > +float max[3]; > +float scale[3]; > +float* lut[3]; > +} Lut3DPreLut; > > typedef struct LUT3DContext { > const AVClass *class; > @@ -71,6 +80,7 @@ typedef struct LUT3DContext { > struct rgbvec *lut; > int lutsize; > int lutsize2; > +Lut3DPreLut prelut; > #if CONFIG_HALDCLUT_FILTER > uint8_t clut_rgba_map[4]; > int clut_step; > @@ -234,11 +244,39 @@ static inline struct rgbvec interp_tetrahedral(const > LUT3DContext *lut3d, > return c; > } > > +static inline float prelut_interp_1d_linear(const Lut3DPreLut *prelut, > +int idx, const float s) > +{ > +const int lut_max = prelut->size - 1; > +const float scaled = (s - prelut->min[idx]) * prelut->scale[idx]; > +const float x = av_clipf(scaled, 0.0f, lut_max); > +const int prev = PREV(x); > +const int next = FFMIN((int)(x) + 1, lut_max); > +const float p = prelut->lut[idx][prev]; > +const float n = prelut->lut[idx][next]; > +const float d = x - (float)prev; > +return lerpf(p, n, d); > +} > + > +static inline struct rgbvec apply_prelut(const Lut3DPreLut *prelut, > + const struct rgbvec *s) > +{ > +if (prelut->size <= 0) > +return *s; > + > +struct rgbvec c; > +c.r = prelut_interp_1d_linear(prelut, 0, s->r); > +c.g = prelut_interp_1d_linear(prelut, 1, s->g); > +c.b = prelut_interp_1d_linear(prelut, 2, s->b); > +return c; > +} > + > #define DEFINE_INTERP_FUNC_PLANAR(name, nbits, depth) > \ > static int interp_##nbits##_##name##_p##depth(AVFilterContext *ctx, void > *arg, int jobnr, int nb_jobs) \ > { > \ > int x, y; > \ > const LUT3DContext *lut3d = ctx->priv; > \ > +const Lut3DPreLut *prelut = >prelut; > \ > const ThreadData *td = arg; > \ > const AVFrame *in = td->in; > \ > const AVFrame *out = td->out; > \ > @@ -253,9 +291,11 @@ static int > interp_##nbits##_##name##_p##depth(AVFilterContext *ctx, void *arg, i > const uint8_t *srcbrow = in->data[1] + slice_start * > in->linesize[1]; \ > const uint8_t *srcrrow = in->data[2] + slice_start * > in->linesize[2]; \ > const uint8_t *srcarow = in->data[3] + slice_start * > in->linesize[3]; \ > -const float scale_r = (lut3d->scale.r / ((1< (lut3d->lutsize - 1); \ > -const float scale_g = (lut3d->scale.g / ((1< (lut3d->lutsize - 1); \ > -const float scale_b = (lut3d->scale.b / ((1< (lut3d->lutsize - 1); \ > +const float lut_max = lut3d->lutsize - 1; > \ > +const float scale_f = 1.0f / ((1< \ > +const float scale_r = lut3d->scale.r * lut_max; > \ > +const float scale_g = lut3d->scale.g * lut_max; > \ > +const float scale_b = lut3d->scale.b * lut_max; > \ > > \ > for (y = slice_start; y < slice_end; y++) { > \ > uint##nbits##_t *dstg = (uint##nbits##_t *)grow; > \ > @@ -267,9 +307,13 @@ static int > interp_##nbits##_##name##_p##depth(AVFilterContext *ctx, void *arg, i > const uint##nbits##_t *srcr = (const uint##nbits##_t *)srcrrow; > \ > const uint##nbits##_t *srca = (const uint##nbits##_t *)srcarow; > \ > for (x = 0; x < in->width; x++) { > \ > -const struct rgbvec scaled_rgb = {srcr[x] * scale_r, > \ > - srcg[x] * scale_g, > \ > - srcb[x] * scale_b}; > \ > +
[FFmpeg-devel] [PATCH v2] avfilter/vf_lut3d: prelut support for 3d cinespace luts
From: Mark Reid changes since v1: * cleaned up code style * slightly reworked apply_lut functions to feel more consistent with code --- libavfilter/vf_lut3d.c | 372 +++-- 1 file changed, 317 insertions(+), 55 deletions(-) diff --git a/libavfilter/vf_lut3d.c b/libavfilter/vf_lut3d.c index 482e2394a7..e5d9fcc068 100644 --- a/libavfilter/vf_lut3d.c +++ b/libavfilter/vf_lut3d.c @@ -59,6 +59,15 @@ struct rgbvec { /* 3D LUT don't often go up to level 32, but it is common to have a Hald CLUT * of 512x512 (64x64x64) */ #define MAX_LEVEL 256 +#define PRELUT_SIZE 65536 + +typedef struct Lut3DPreLut { +int size; +float min[3]; +float max[3]; +float scale[3]; +float* lut[3]; +} Lut3DPreLut; typedef struct LUT3DContext { const AVClass *class; @@ -71,6 +80,7 @@ typedef struct LUT3DContext { struct rgbvec *lut; int lutsize; int lutsize2; +Lut3DPreLut prelut; #if CONFIG_HALDCLUT_FILTER uint8_t clut_rgba_map[4]; int clut_step; @@ -234,11 +244,39 @@ static inline struct rgbvec interp_tetrahedral(const LUT3DContext *lut3d, return c; } +static inline float prelut_interp_1d_linear(const Lut3DPreLut *prelut, +int idx, const float s) +{ +const int lut_max = prelut->size - 1; +const float scaled = (s - prelut->min[idx]) * prelut->scale[idx]; +const float x = av_clipf(scaled, 0.0f, lut_max); +const int prev = PREV(x); +const int next = FFMIN((int)(x) + 1, lut_max); +const float p = prelut->lut[idx][prev]; +const float n = prelut->lut[idx][next]; +const float d = x - (float)prev; +return lerpf(p, n, d); +} + +static inline struct rgbvec apply_prelut(const Lut3DPreLut *prelut, + const struct rgbvec *s) +{ +if (prelut->size <= 0) +return *s; + +struct rgbvec c; +c.r = prelut_interp_1d_linear(prelut, 0, s->r); +c.g = prelut_interp_1d_linear(prelut, 1, s->g); +c.b = prelut_interp_1d_linear(prelut, 2, s->b); +return c; +} + #define DEFINE_INTERP_FUNC_PLANAR(name, nbits, depth) \ static int interp_##nbits##_##name##_p##depth(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) \ { \ int x, y; \ const LUT3DContext *lut3d = ctx->priv; \ +const Lut3DPreLut *prelut = >prelut; \ const ThreadData *td = arg; \ const AVFrame *in = td->in; \ const AVFrame *out = td->out; \ @@ -253,9 +291,11 @@ static int interp_##nbits##_##name##_p##depth(AVFilterContext *ctx, void *arg, i const uint8_t *srcbrow = in->data[1] + slice_start * in->linesize[1]; \ const uint8_t *srcrrow = in->data[2] + slice_start * in->linesize[2]; \ const uint8_t *srcarow = in->data[3] + slice_start * in->linesize[3]; \ -const float scale_r = (lut3d->scale.r / ((1scale.g / ((1 scale.b / ((1 lutsize - 1; \ +const float scale_f = 1.0f / ((1 scale.g * lut_max; \ +const float scale_b = lut3d->scale.b * lut_max; \ \ for (y = slice_start; y < slice_end; y++) { \ uint##nbits##_t *dstg = (uint##nbits##_t *)grow; \ @@ -267,9 +307,13 @@ static int interp_##nbits##_##name##_p##depth(AVFilterContext *ctx, void *arg, i const uint##nbits##_t *srcr = (const uint##nbits##_t *)srcrrow; \ const uint##nbits##_t *srca = (const uint##nbits##_t *)srcarow; \ for (x = 0; x < in->width; x++) { \ -const struct rgbvec scaled_rgb = {srcr[x] * scale_r, \