summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul B Mahol <onemda@gmail.com>2021-11-14 00:17:10 +0100
committerPaul B Mahol <onemda@gmail.com>2021-11-16 20:41:39 +0100
commitd401b1cceceacc93c90f6d239dd58e22632c013d (patch)
treeb184822880a3a26bcf6676c59b7c7d8928655cd2
parent08b4716a9ed277afb4af69b07b751c9bd046aa70 (diff)
avfilter: add colorspectrum source video filter
-rw-r--r--Changelog1
-rw-r--r--doc/filters.texi15
-rw-r--r--libavfilter/Makefile1
-rw-r--r--libavfilter/allfilters.c1
-rw-r--r--libavfilter/version.h4
-rw-r--r--libavfilter/vsrc_testsrc.c92
6 files changed, 111 insertions, 3 deletions
diff --git a/Changelog b/Changelog
index 765ec82915..31a0d5ef5d 100644
--- a/Changelog
+++ b/Changelog
@@ -30,6 +30,7 @@ version <next>:
- xcorrelate video filter
- varblur video filter
- huesaturation video filter
+- colorspectrum source video filter
version 4.4:
diff --git a/doc/filters.texi b/doc/filters.texi
index b4f888c14d..c3ccaf97c4 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -25257,6 +25257,7 @@ ffplay -f lavfi life=s=300x200:mold=10:r=60:ratio=0.1:death_color=#C83232:life_c
@anchor{allrgb}
@anchor{allyuv}
@anchor{color}
+@anchor{colorspectrum}
@anchor{haldclutsrc}
@anchor{nullsrc}
@anchor{pal75bars}
@@ -25267,7 +25268,7 @@ ffplay -f lavfi life=s=300x200:mold=10:r=60:ratio=0.1:death_color=#C83232:life_c
@anchor{testsrc}
@anchor{testsrc2}
@anchor{yuvtestsrc}
-@section allrgb, allyuv, color, haldclutsrc, nullsrc, pal75bars, pal100bars, rgbtestsrc, smptebars, smptehdbars, testsrc, testsrc2, yuvtestsrc
+@section allrgb, allyuv, color, colorspectrum, haldclutsrc, nullsrc, pal75bars, pal100bars, rgbtestsrc, smptebars, smptehdbars, testsrc, testsrc2, yuvtestsrc
The @code{allrgb} source returns frames of size 4096x4096 of all rgb colors.
@@ -25275,6 +25276,8 @@ The @code{allyuv} source returns frames of size 4096x4096 of all yuv colors.
The @code{color} source provides an uniformly colored input.
+The @code{colorspectrum} source provides a color spectrum input.
+
The @code{haldclutsrc} source provides an identity Hald CLUT. See also
@ref{haldclut} filter.
@@ -25366,6 +25369,16 @@ Set the number of decimals to show in the timestamp, only available in the
The displayed timestamp value will correspond to the original
timestamp value multiplied by the power of 10 of the specified
value. Default value is 0.
+
+@item type
+Set the type of the color spectrum, only available in the
+@code{colorspectrum} source. Can be one of the following:
+
+@table @samp
+@item black
+@item white
+@item all
+@end table
@end table
@subsection Examples
diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index 08edc92d8c..07b4a639ec 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -522,6 +522,7 @@ OBJS-$(CONFIG_ALLRGB_FILTER) += vsrc_testsrc.o
OBJS-$(CONFIG_ALLYUV_FILTER) += vsrc_testsrc.o
OBJS-$(CONFIG_CELLAUTO_FILTER) += vsrc_cellauto.o
OBJS-$(CONFIG_COLOR_FILTER) += vsrc_testsrc.o
+OBJS-$(CONFIG_COLORSPECTRUM_FILTER) += vsrc_testsrc.o
OBJS-$(CONFIG_COREIMAGESRC_FILTER) += vf_coreimage.o
OBJS-$(CONFIG_FREI0R_SRC_FILTER) += vf_frei0r.o
OBJS-$(CONFIG_GRADIENTS_FILTER) += vsrc_gradients.o
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index f250020159..29da7ef0d2 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -498,6 +498,7 @@ extern const AVFilter ff_vsrc_allrgb;
extern const AVFilter ff_vsrc_allyuv;
extern const AVFilter ff_vsrc_cellauto;
extern const AVFilter ff_vsrc_color;
+extern const AVFilter ff_vsrc_colorspectrum;
extern const AVFilter ff_vsrc_coreimagesrc;
extern const AVFilter ff_vsrc_frei0r_src;
extern const AVFilter ff_vsrc_gradients;
diff --git a/libavfilter/version.h b/libavfilter/version.h
index 0912af7afe..b9e610ea1f 100644
--- a/libavfilter/version.h
+++ b/libavfilter/version.h
@@ -30,8 +30,8 @@
#include "libavutil/version.h"
#define LIBAVFILTER_VERSION_MAJOR 8
-#define LIBAVFILTER_VERSION_MINOR 16
-#define LIBAVFILTER_VERSION_MICRO 102
+#define LIBAVFILTER_VERSION_MINOR 17
+#define LIBAVFILTER_VERSION_MICRO 100
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
diff --git a/libavfilter/vsrc_testsrc.c b/libavfilter/vsrc_testsrc.c
index 6f48a8f86c..20b915d472 100644
--- a/libavfilter/vsrc_testsrc.c
+++ b/libavfilter/vsrc_testsrc.c
@@ -70,6 +70,9 @@ typedef struct TestSourceContext {
/* only used by testsrc2 */
int alpha;
+ /* only used by colorspectrum */
+ int type;
+
/* only used by color */
FFDrawContext draw;
FFDrawColor color;
@@ -1791,3 +1794,92 @@ const AVFilter ff_vsrc_allrgb = {
};
#endif /* CONFIG_ALLRGB_FILTER */
+
+#if CONFIG_COLORSPECTRUM_FILTER
+
+static const AVOption colorspectrum_options[] = {
+ COMMON_OPTIONS
+ { "type", "set the color spectrum type", OFFSET(type), AV_OPT_TYPE_INT, {.i64=0}, 0, 2, FLAGS, "type" },
+ { "black","fade to black", 0, AV_OPT_TYPE_CONST,{.i64=0},0, 0, FLAGS, "type" },
+ { "white","fade to white", 0, AV_OPT_TYPE_CONST,{.i64=1},0, 0, FLAGS, "type" },
+ { "all", "white to black", 0, AV_OPT_TYPE_CONST,{.i64=2},0, 0, FLAGS, "type" },
+ { NULL }
+};
+
+AVFILTER_DEFINE_CLASS(colorspectrum);
+
+static inline float mix(float a, float b, float mix)
+{
+ return a * mix + b * (1.f - mix);
+}
+
+static void hsb2rgb(const float *c, float *rgb)
+{
+ rgb[0] = av_clipf(fabsf(fmodf(c[0] * 6.f + 0.f, 6.f) - 3.f) - 1.f, 0.f, 1.f);
+ rgb[1] = av_clipf(fabsf(fmodf(c[0] * 6.f + 4.f, 6.f) - 3.f) - 1.f, 0.f, 1.f);
+ rgb[2] = av_clipf(fabsf(fmodf(c[0] * 6.f + 2.f, 6.f) - 3.f) - 1.f, 0.f, 1.f);
+ rgb[0] = mix(c[3], (rgb[0] * rgb[0] * (3.f - 2.f * rgb[0])), c[1]) * c[2];
+ rgb[1] = mix(c[3], (rgb[1] * rgb[1] * (3.f - 2.f * rgb[1])), c[1]) * c[2];
+ rgb[2] = mix(c[3], (rgb[2] * rgb[2] * (3.f - 2.f * rgb[2])), c[1]) * c[2];
+}
+
+static void colorspectrum_fill_picture(AVFilterContext *ctx, AVFrame *frame)
+{
+ TestSourceContext *test = ctx->priv;
+ const float w = frame->width - 1.f;
+ const float h = frame->height - 1.f;
+ float c[4];
+
+ for (int y = 0; y < frame->height; y++) {
+ float *r = (float *)(frame->data[2] + y * frame->linesize[2]);
+ float *g = (float *)(frame->data[0] + y * frame->linesize[0]);
+ float *b = (float *)(frame->data[1] + y * frame->linesize[1]);
+ const float yh = y / h;
+
+ c[1] = test->type == 2 ? yh > 0.5f ? 2.f * (yh - 0.5f) : 1.f - 2.f * yh : test->type == 1 ? 1.f - yh : yh;
+ c[2] = 1.f;
+ c[3] = test->type == 1 ? 1.f : test->type == 2 ? (yh > 0.5f ? 0.f : 1.f): 0.f;
+ for (int x = 0; x < frame->width; x++) {
+ float rgb[3];
+
+ c[0] = x / w;
+ hsb2rgb(c, rgb);
+
+ r[x] = rgb[0];
+ g[x] = rgb[1];
+ b[x] = rgb[2];
+ }
+ }
+}
+
+static av_cold int colorspectrum_init(AVFilterContext *ctx)
+{
+ TestSourceContext *test = ctx->priv;
+
+ test->draw_once = 1;
+ test->fill_picture_fn = colorspectrum_fill_picture;
+ return init(ctx);
+}
+
+static const AVFilterPad avfilter_vsrc_colorspectrum_outputs[] = {
+ {
+ .name = "default",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .config_props = config_props,
+ },
+};
+
+const AVFilter ff_vsrc_colorspectrum = {
+ .name = "colorspectrum",
+ .description = NULL_IF_CONFIG_SMALL("Generate colors spectrum."),
+ .priv_size = sizeof(TestSourceContext),
+ .priv_class = &colorspectrum_class,
+ .init = colorspectrum_init,
+ .uninit = uninit,
+ .activate = activate,
+ .inputs = NULL,
+ FILTER_OUTPUTS(avfilter_vsrc_colorspectrum_outputs),
+ FILTER_SINGLE_PIXFMT(AV_PIX_FMT_GBRPF32),
+};
+
+#endif /* CONFIG_COLORSPECTRUM_FILTER */