Re: [FFmpeg-devel] [PATCH] avfilter: add lut1d filter

2018-09-07 Thread Paul B Mahol
On 8/23/18, Paul B Mahol  wrote:
> Signed-off-by: Paul B Mahol 
> ---
>  doc/filters.texi |  31 +++
>  libavfilter/Makefile |   1 +
>  libavfilter/allfilters.c |   1 +
>  libavfilter/vf_lut3d.c   | 438 +++
>  4 files changed, 471 insertions(+)
>

Will apply.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH] avfilter: add lut1d filter

2018-08-23 Thread Paul B Mahol
Signed-off-by: Paul B Mahol 
---
 doc/filters.texi |  31 +++
 libavfilter/Makefile |   1 +
 libavfilter/allfilters.c |   1 +
 libavfilter/vf_lut3d.c   | 438 +++
 4 files changed, 471 insertions(+)

diff --git a/doc/filters.texi b/doc/filters.texi
index 32c95b591c..37e79d34e1 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -10962,6 +10962,37 @@ Set maximal size in number of frames. Default is 0.
 Set first frame of loop. Default is 0.
 @end table
 
+@section lut1d
+
+Apply a 1D LUT to an input video.
+
+The filter accepts the following options:
+
+@table @option
+@item file
+Set the 1D LUT file name.
+
+Currently supported formats:
+@table @samp
+@item cube
+Iridas
+@end table
+
+@item interp
+Select interpolation mode.
+
+Available values are:
+
+@table @samp
+@item nearest
+Use values from the nearest defined point.
+@item linear
+Interpolate values using the linear interpolation.
+@item cubic
+Interpolate values using the cubic interpolation.
+@end table
+@end table
+
 @anchor{lut3d}
 @section lut3d
 
diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index e5d3a57af7..e412000c8f 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -258,6 +258,7 @@ OBJS-$(CONFIG_LIBVMAF_FILTER)+= 
vf_libvmaf.o framesync.o
 OBJS-$(CONFIG_LIMITER_FILTER)+= vf_limiter.o
 OBJS-$(CONFIG_LOOP_FILTER)   += f_loop.o
 OBJS-$(CONFIG_LUMAKEY_FILTER)+= vf_lumakey.o
+OBJS-$(CONFIG_LUT1D_FILTER)  += vf_lut3d.o
 OBJS-$(CONFIG_LUT_FILTER)+= vf_lut.o
 OBJS-$(CONFIG_LUT2_FILTER)   += vf_lut2.o framesync.o
 OBJS-$(CONFIG_LUT3D_FILTER)  += vf_lut3d.o
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index 9732ae5345..2fa9460335 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -246,6 +246,7 @@ extern AVFilter ff_vf_limiter;
 extern AVFilter ff_vf_loop;
 extern AVFilter ff_vf_lumakey;
 extern AVFilter ff_vf_lut;
+extern AVFilter ff_vf_lut1d;
 extern AVFilter ff_vf_lut2;
 extern AVFilter ff_vf_lut3d;
 extern AVFilter ff_vf_lutrgb;
diff --git a/libavfilter/vf_lut3d.c b/libavfilter/vf_lut3d.c
index 27b79b860b..6ec0cad650 100644
--- a/libavfilter/vf_lut3d.c
+++ b/libavfilter/vf_lut3d.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2013 Clément Bœsch
+ * Copyright (c) 2018 Paul B Mahol
  *
  * This file is part of FFmpeg.
  *
@@ -975,3 +976,440 @@ AVFilter ff_vf_haldclut = {
 .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | 
AVFILTER_FLAG_SLICE_THREADS,
 };
 #endif
+
+#if CONFIG_LUT1D_FILTER
+
+enum interp_1d_mode {
+INTERPOLATE_1D_NEAREST,
+INTERPOLATE_1D_LINEAR,
+INTERPOLATE_1D_CUBIC,
+NB_INTERP_1D_MODE
+};
+
+#define MAX_1D_LEVEL 65536
+
+typedef struct LUT1DContext {
+const AVClass *class;
+char *file;
+int interpolation;  ///lutsize = size;
+for (i = 0; i < size; i++) {
+lut1d->lut[0][i] = i * c;
+lut1d->lut[1][i] = i * c;
+lut1d->lut[2][i] = i * c;
+}
+}
+
+static int parse_cube_1d(AVFilterContext *ctx, FILE *f)
+{
+LUT1DContext *lut1d = ctx->priv;
+char line[MAX_LINE_SIZE];
+float min[3] = {0.0, 0.0, 0.0};
+float max[3] = {1.0, 1.0, 1.0};
+
+while (fgets(line, sizeof(line), f)) {
+if (!strncmp(line, "LUT_1D_SIZE ", 12)) {
+const int size = strtol(line + 12, NULL, 0);
+int i;
+
+if (size < 2 || size > MAX_1D_LEVEL) {
+av_log(ctx, AV_LOG_ERROR, "Too large or invalid 1D LUT 
size\n");
+return AVERROR(EINVAL);
+}
+lut1d->lutsize = size;
+for (i = 0; i < size; i++) {
+do {
+try_again:
+NEXT_LINE(0);
+if (!strncmp(line, "DOMAIN_", 7)) {
+float *vals = NULL;
+if  (!strncmp(line + 7, "MIN ", 4)) vals = min;
+else if (!strncmp(line + 7, "MAX ", 4)) vals = max;
+if (!vals)
+return AVERROR_INVALIDDATA;
+sscanf(line + 11, "%f %f %f", vals, vals + 1, vals + 
2);
+av_log(ctx, AV_LOG_DEBUG, "min: %f %f %f | max: %f %f 
%f\n",
+   min[0], min[1], min[2], max[0], max[1], max[2]);
+goto try_again;
+}
+} while (skip_line(line));
+if (sscanf(line, "%f %f %f", >lut[0][i], 
>lut[1][i], >lut[2][i]) != 3)
+return AVERROR_INVALIDDATA;
+lut1d->lut[0][i] *= max[0] - min[0];
+lut1d->lut[1][i] *= max[1] - min[1];
+lut1d->lut[2][i] *= max[2] - min[2];
+}
+break;
+}
+}
+return 0;
+}
+
+static const AVOption lut1d_options[] = {
+{ "file", "set 1D LUT file name", OFFSET(file), 

[FFmpeg-devel] [PATCH] avfilter: add lut1d filter

2018-08-23 Thread Paul B Mahol
Signed-off-by: Paul B Mahol 
---
 doc/filters.texi |  29 +++
 libavfilter/Makefile |   1 +
 libavfilter/allfilters.c |   1 +
 libavfilter/vf_lut3d.c   | 404 +++
 4 files changed, 435 insertions(+)

diff --git a/doc/filters.texi b/doc/filters.texi
index 32c95b591c..72ce95f94a 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -10962,6 +10962,35 @@ Set maximal size in number of frames. Default is 0.
 Set first frame of loop. Default is 0.
 @end table
 
+@section lut1d
+
+Apply a 1D LUT to an input video.
+
+The filter accepts the following options:
+
+@table @option
+@item file
+Set the 1D LUT file name.
+
+Currently supported formats:
+@table @samp
+@item cube
+Iridas
+@end table
+
+@item interp
+Select interpolation mode.
+
+Available values are:
+
+@table @samp
+@item nearest
+Use values from the nearest defined point.
+@item linear
+Interpolate values using the linear interpolation.
+@end table
+@end table
+
 @anchor{lut3d}
 @section lut3d
 
diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index e5d3a57af7..e412000c8f 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -258,6 +258,7 @@ OBJS-$(CONFIG_LIBVMAF_FILTER)+= 
vf_libvmaf.o framesync.o
 OBJS-$(CONFIG_LIMITER_FILTER)+= vf_limiter.o
 OBJS-$(CONFIG_LOOP_FILTER)   += f_loop.o
 OBJS-$(CONFIG_LUMAKEY_FILTER)+= vf_lumakey.o
+OBJS-$(CONFIG_LUT1D_FILTER)  += vf_lut3d.o
 OBJS-$(CONFIG_LUT_FILTER)+= vf_lut.o
 OBJS-$(CONFIG_LUT2_FILTER)   += vf_lut2.o framesync.o
 OBJS-$(CONFIG_LUT3D_FILTER)  += vf_lut3d.o
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index 9732ae5345..2fa9460335 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -246,6 +246,7 @@ extern AVFilter ff_vf_limiter;
 extern AVFilter ff_vf_loop;
 extern AVFilter ff_vf_lumakey;
 extern AVFilter ff_vf_lut;
+extern AVFilter ff_vf_lut1d;
 extern AVFilter ff_vf_lut2;
 extern AVFilter ff_vf_lut3d;
 extern AVFilter ff_vf_lutrgb;
diff --git a/libavfilter/vf_lut3d.c b/libavfilter/vf_lut3d.c
index 27b79b860b..b5673b82bf 100644
--- a/libavfilter/vf_lut3d.c
+++ b/libavfilter/vf_lut3d.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2013 Clément Bœsch
+ * Copyright (c) 2018 Paul B Mahol
  *
  * This file is part of FFmpeg.
  *
@@ -975,3 +976,406 @@ AVFilter ff_vf_haldclut = {
 .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | 
AVFILTER_FLAG_SLICE_THREADS,
 };
 #endif
+
+#if CONFIG_LUT1D_FILTER
+
+enum interp_1d_mode {
+INTERPOLATE_1D_NEAREST,
+INTERPOLATE_1D_LINEAR,
+NB_INTERP_1D_MODE
+};
+
+#define MAX_1D_LEVEL 65536
+
+typedef struct LUT1DContext {
+const AVClass *class;
+char *file;
+int interpolation;  ///lutsize = size;
+for (i = 0; i < size; i++) {
+lut1d->lut[0][i] = i * c;
+lut1d->lut[1][i] = i * c;
+lut1d->lut[2][i] = i * c;
+}
+}
+
+static int parse_cube_1d(AVFilterContext *ctx, FILE *f)
+{
+LUT1DContext *lut1d = ctx->priv;
+char line[MAX_LINE_SIZE];
+float min[3] = {0.0, 0.0, 0.0};
+float max[3] = {1.0, 1.0, 1.0};
+
+while (fgets(line, sizeof(line), f)) {
+if (!strncmp(line, "LUT_1D_SIZE ", 12)) {
+const int size = strtol(line + 12, NULL, 0);
+int i;
+
+if (size < 2 || size > MAX_1D_LEVEL) {
+av_log(ctx, AV_LOG_ERROR, "Too large or invalid 1D LUT 
size\n");
+return AVERROR(EINVAL);
+}
+lut1d->lutsize = size;
+for (i = 0; i < size; i++) {
+do {
+try_again:
+NEXT_LINE(0);
+if (!strncmp(line, "DOMAIN_", 7)) {
+float *vals = NULL;
+if  (!strncmp(line + 7, "MIN ", 4)) vals = min;
+else if (!strncmp(line + 7, "MAX ", 4)) vals = max;
+if (!vals)
+return AVERROR_INVALIDDATA;
+sscanf(line + 11, "%f %f %f", vals, vals + 1, vals + 
2);
+av_log(ctx, AV_LOG_DEBUG, "min: %f %f %f | max: %f %f 
%f\n",
+   min[0], min[1], min[2], max[0], max[1], max[2]);
+goto try_again;
+}
+} while (skip_line(line));
+if (sscanf(line, "%f %f %f", >lut[0][i], 
>lut[1][i], >lut[2][i]) != 3)
+return AVERROR_INVALIDDATA;
+lut1d->lut[0][i] *= max[0] - min[0];
+lut1d->lut[1][i] *= max[1] - min[1];
+lut1d->lut[2][i] *= max[2] - min[2];
+}
+break;
+}
+}
+return 0;
+}
+
+static const AVOption lut1d_options[] = {
+{ "file", "set 1D LUT file name", OFFSET(file), AV_OPT_TYPE_STRING, 
{.str=NULL}, .flags = FLAGS },
+{ "interp", "select interpolation mode",