Commit 3cec29cf authored by Clément Bœsch's avatar Clément Bœsch

lavfi: add haldclutsrc filter.

parent 1bbb46ff
...@@ -7401,10 +7401,12 @@ ffplay -f lavfi life=s=300x200:mold=10:r=60:ratio=0.1:death_color=#C83232:life_c ...@@ -7401,10 +7401,12 @@ ffplay -f lavfi life=s=300x200:mold=10:r=60:ratio=0.1:death_color=#C83232:life_c
@end example @end example
@end itemize @end itemize
@section color, nullsrc, rgbtestsrc, smptebars, smptehdbars, testsrc @section color, haldclutsrc, nullsrc, rgbtestsrc, smptebars, smptehdbars, testsrc
The @code{color} source provides an uniformly colored input. The @code{color} source provides an uniformly colored input.
The @code{haldclutsrc} source provides an identity Hald CLUT.
The @code{nullsrc} source returns unprocessed video frames. It is The @code{nullsrc} source returns unprocessed video frames. It is
mainly useful to be employed in analysis / debugging tools, or as the mainly useful to be employed in analysis / debugging tools, or as the
source for filters which ignore the input data. source for filters which ignore the input data.
...@@ -7433,11 +7435,19 @@ source. It can be the name of a color (case insensitive match) or a ...@@ -7433,11 +7435,19 @@ source. It can be the name of a color (case insensitive match) or a
0xRRGGBB[AA] sequence, possibly followed by an alpha specifier. The 0xRRGGBB[AA] sequence, possibly followed by an alpha specifier. The
default value is "black". default value is "black".
@item level
Specify the level of the Hald CLUT, only available in the @code{haldclutsrc}
source. A level of @code{N} generates a picture of @code{N*N*N} by @code{N*N*N}
pixels to be used as identity matrix for 3D lookup tables. Each component is
coded on a @code{1/(N*N)} scale.
@item size, s @item size, s
Specify the size of the sourced video, it may be a string of the form Specify the size of the sourced video, it may be a string of the form
@var{width}x@var{height}, or the name of a size abbreviation. The @var{width}x@var{height}, or the name of a size abbreviation. The
default value is "320x240". default value is "320x240".
This option is not available with the @code{haldclutsrc} filter.
@item rate, r @item rate, r
Specify the frame rate of the sourced video, as the number of frames Specify the frame rate of the sourced video, as the number of frames
generated per second. It has to be a string in the format generated per second. It has to be a string in the format
......
...@@ -196,6 +196,7 @@ OBJS-$(CONFIG_ZMQ_FILTER) += f_zmq.o ...@@ -196,6 +196,7 @@ OBJS-$(CONFIG_ZMQ_FILTER) += f_zmq.o
OBJS-$(CONFIG_CELLAUTO_FILTER) += vsrc_cellauto.o OBJS-$(CONFIG_CELLAUTO_FILTER) += vsrc_cellauto.o
OBJS-$(CONFIG_COLOR_FILTER) += vsrc_testsrc.o OBJS-$(CONFIG_COLOR_FILTER) += vsrc_testsrc.o
OBJS-$(CONFIG_FREI0R_SRC_FILTER) += vf_frei0r.o OBJS-$(CONFIG_FREI0R_SRC_FILTER) += vf_frei0r.o
OBJS-$(CONFIG_HALDCLUTSRC_FILTER) += vsrc_testsrc.o
OBJS-$(CONFIG_LIFE_FILTER) += vsrc_life.o OBJS-$(CONFIG_LIFE_FILTER) += vsrc_life.o
OBJS-$(CONFIG_MANDELBROT_FILTER) += vsrc_mandelbrot.o OBJS-$(CONFIG_MANDELBROT_FILTER) += vsrc_mandelbrot.o
OBJS-$(CONFIG_MPTESTSRC_FILTER) += vsrc_mptestsrc.o OBJS-$(CONFIG_MPTESTSRC_FILTER) += vsrc_mptestsrc.o
......
...@@ -193,6 +193,7 @@ void avfilter_register_all(void) ...@@ -193,6 +193,7 @@ void avfilter_register_all(void)
REGISTER_FILTER(CELLAUTO, cellauto, vsrc); REGISTER_FILTER(CELLAUTO, cellauto, vsrc);
REGISTER_FILTER(COLOR, color, vsrc); REGISTER_FILTER(COLOR, color, vsrc);
REGISTER_FILTER(FREI0R, frei0r_src, vsrc); REGISTER_FILTER(FREI0R, frei0r_src, vsrc);
REGISTER_FILTER(HALDCLUTSRC, haldclutsrc, vsrc);
REGISTER_FILTER(LIFE, life, vsrc); REGISTER_FILTER(LIFE, life, vsrc);
REGISTER_FILTER(MANDELBROT, mandelbrot, vsrc); REGISTER_FILTER(MANDELBROT, mandelbrot, vsrc);
REGISTER_FILTER(MPTESTSRC, mptestsrc, vsrc); REGISTER_FILTER(MPTESTSRC, mptestsrc, vsrc);
......
...@@ -30,8 +30,8 @@ ...@@ -30,8 +30,8 @@
#include "libavutil/avutil.h" #include "libavutil/avutil.h"
#define LIBAVFILTER_VERSION_MAJOR 3 #define LIBAVFILTER_VERSION_MAJOR 3
#define LIBAVFILTER_VERSION_MINOR 70 #define LIBAVFILTER_VERSION_MINOR 71
#define LIBAVFILTER_VERSION_MICRO 101 #define LIBAVFILTER_VERSION_MICRO 100
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
LIBAVFILTER_VERSION_MINOR, \ LIBAVFILTER_VERSION_MINOR, \
......
...@@ -71,20 +71,26 @@ typedef struct { ...@@ -71,20 +71,26 @@ typedef struct {
/* only used by rgbtest */ /* only used by rgbtest */
uint8_t rgba_map[4]; uint8_t rgba_map[4];
/* only used by haldclut */
int level;
} TestSourceContext; } TestSourceContext;
#define OFFSET(x) offsetof(TestSourceContext, x) #define OFFSET(x) offsetof(TestSourceContext, x)
#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
#define COMMON_OPTIONS \ #define SIZE_OPTIONS \
{ "size", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "320x240"}, 0, 0, FLAGS },\ { "size", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "320x240"}, 0, 0, FLAGS },\
{ "s", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "320x240"}, 0, 0, FLAGS },\ { "s", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "320x240"}, 0, 0, FLAGS },\
#define COMMON_OPTIONS_NOSIZE \
{ "rate", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0, FLAGS },\ { "rate", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0, FLAGS },\
{ "r", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0, FLAGS },\ { "r", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0, FLAGS },\
{ "duration", "set video duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = -1}, -1, INT64_MAX, FLAGS },\ { "duration", "set video duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = -1}, -1, INT64_MAX, FLAGS },\
{ "d", "set video duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = -1}, -1, INT64_MAX, FLAGS },\ { "d", "set video duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = -1}, -1, INT64_MAX, FLAGS },\
{ "sar", "set video sample aspect ratio", OFFSET(sar), AV_OPT_TYPE_RATIONAL, {.dbl= 1}, 0, INT_MAX, FLAGS }, { "sar", "set video sample aspect ratio", OFFSET(sar), AV_OPT_TYPE_RATIONAL, {.dbl= 1}, 0, INT_MAX, FLAGS },
#define COMMON_OPTIONS SIZE_OPTIONS COMMON_OPTIONS_NOSIZE
static const AVOption options[] = { static const AVOption options[] = {
COMMON_OPTIONS COMMON_OPTIONS
...@@ -269,6 +275,135 @@ AVFilter avfilter_vsrc_color = { ...@@ -269,6 +275,135 @@ AVFilter avfilter_vsrc_color = {
#endif /* CONFIG_COLOR_FILTER */ #endif /* CONFIG_COLOR_FILTER */
#if CONFIG_HALDCLUTSRC_FILTER
static const AVOption haldclutsrc_options[] = {
{ "level", "set level", OFFSET(level), AV_OPT_TYPE_INT, {.i64 = 6}, 2, 8, FLAGS },
COMMON_OPTIONS
{ NULL }
};
AVFILTER_DEFINE_CLASS(haldclutsrc);
static void haldclutsrc_fill_picture(AVFilterContext *ctx, AVFrame *frame)
{
int i, j, k, x = 0, y = 0, is16bit = 0, step;
uint32_t alpha = 0;
const TestSourceContext *hc = ctx->priv;
int level = hc->level;
float scale;
const int w = frame->width;
const int h = frame->height;
const uint8_t *data = frame->data[0];
const int linesize = frame->linesize[0];
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
uint8_t rgba_map[4];
av_assert0(w == h && w == level*level*level);
ff_fill_rgba_map(rgba_map, frame->format);
switch (frame->format) {
case AV_PIX_FMT_RGB48:
case AV_PIX_FMT_BGR48:
case AV_PIX_FMT_RGBA64:
case AV_PIX_FMT_BGRA64:
is16bit = 1;
alpha = 0xffff;
break;
case AV_PIX_FMT_RGBA:
case AV_PIX_FMT_BGRA:
case AV_PIX_FMT_ARGB:
case AV_PIX_FMT_ABGR:
alpha = 0xff;
break;
}
step = av_get_padded_bits_per_pixel(desc) >> (3 + is16bit);
scale = ((float)(1 << (8*(is16bit+1))) - 1) / (level*level - 1);
#define LOAD_CLUT(nbits) do { \
uint##nbits##_t *dst = ((uint##nbits##_t *)(data + y*linesize)) + x*step; \
dst[rgba_map[0]] = av_clip_uint##nbits(i * scale); \
dst[rgba_map[1]] = av_clip_uint##nbits(j * scale); \
dst[rgba_map[2]] = av_clip_uint##nbits(k * scale); \
if (step == 4) \
dst[rgba_map[3]] = alpha; \
} while (0)
level *= level;
for (k = 0; k < level; k++) {
for (j = 0; j < level; j++) {
for (i = 0; i < level; i++) {
if (!is16bit)
LOAD_CLUT(8);
else
LOAD_CLUT(16);
if (++x == w) {
x = 0;
y++;
}
}
}
}
}
static av_cold int haldclutsrc_init(AVFilterContext *ctx)
{
TestSourceContext *hc = ctx->priv;
hc->fill_picture_fn = haldclutsrc_fill_picture;
hc->draw_once = 1;
return init(ctx);
}
static int haldclutsrc_query_formats(AVFilterContext *ctx)
{
static const enum AVPixelFormat pix_fmts[] = {
AV_PIX_FMT_RGB24, AV_PIX_FMT_BGR24,
AV_PIX_FMT_RGBA, AV_PIX_FMT_BGRA,
AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR,
AV_PIX_FMT_0RGB, AV_PIX_FMT_0BGR,
AV_PIX_FMT_RGB0, AV_PIX_FMT_BGR0,
AV_PIX_FMT_RGB48, AV_PIX_FMT_BGR48,
AV_PIX_FMT_RGBA64, AV_PIX_FMT_BGRA64,
AV_PIX_FMT_NONE,
};
ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
return 0;
}
static int haldclutsrc_config_props(AVFilterLink *outlink)
{
AVFilterContext *ctx = outlink->src;
TestSourceContext *hc = ctx->priv;
hc->w = hc->h = hc->level * hc->level * hc->level;
return config_props(outlink);
}
static const AVFilterPad haldclutsrc_outputs[] = {
{
.name = "default",
.type = AVMEDIA_TYPE_VIDEO,
.request_frame = request_frame,
.config_props = haldclutsrc_config_props,
},
{ NULL }
};
AVFilter avfilter_vsrc_haldclutsrc = {
.name = "haldclutsrc",
.description = NULL_IF_CONFIG_SMALL("Provide an identity Hald CLUT."),
.priv_class = &haldclutsrc_class,
.priv_size = sizeof(TestSourceContext),
.init = haldclutsrc_init,
.uninit = uninit,
.query_formats = haldclutsrc_query_formats,
.inputs = NULL,
.outputs = haldclutsrc_outputs,
};
#endif /* CONFIG_HALDCLUTSRC_FILTER */
#if CONFIG_NULLSRC_FILTER #if CONFIG_NULLSRC_FILTER
#define nullsrc_options options #define nullsrc_options options
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment