avfilter: add colorspectrum source video filter

This commit is contained in:
Paul B Mahol 2021-11-14 00:17:10 +01:00
parent 08b4716a9e
commit d401b1ccec
6 changed files with 111 additions and 3 deletions

View File

@ -30,6 +30,7 @@ version <next>:
- xcorrelate video filter
- varblur video filter
- huesaturation video filter
- colorspectrum source video filter
version 4.4:

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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, \

View File

@ -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 */