... | ... |
@@ -7401,10 +7401,12 @@ ffplay -f lavfi life=s=300x200:mold=10:r=60:ratio=0.1:death_color=#C83232:life_c |
7401 | 7401 |
@end example |
7402 | 7402 |
@end itemize |
7403 | 7403 |
|
7404 |
-@section color, nullsrc, rgbtestsrc, smptebars, smptehdbars, testsrc |
|
7404 |
+@section color, haldclutsrc, nullsrc, rgbtestsrc, smptebars, smptehdbars, testsrc |
|
7405 | 7405 |
|
7406 | 7406 |
The @code{color} source provides an uniformly colored input. |
7407 | 7407 |
|
7408 |
+The @code{haldclutsrc} source provides an identity Hald CLUT. |
|
7409 |
+ |
|
7408 | 7410 |
The @code{nullsrc} source returns unprocessed video frames. It is |
7409 | 7411 |
mainly useful to be employed in analysis / debugging tools, or as the |
7410 | 7412 |
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 | 7433 |
0xRRGGBB[AA] sequence, possibly followed by an alpha specifier. The |
7434 | 7434 |
default value is "black". |
7435 | 7435 |
|
7436 |
+@item level |
|
7437 |
+Specify the level of the Hald CLUT, only available in the @code{haldclutsrc} |
|
7438 |
+source. A level of @code{N} generates a picture of @code{N*N*N} by @code{N*N*N} |
|
7439 |
+pixels to be used as identity matrix for 3D lookup tables. Each component is |
|
7440 |
+coded on a @code{1/(N*N)} scale. |
|
7441 |
+ |
|
7436 | 7442 |
@item size, s |
7437 | 7443 |
Specify the size of the sourced video, it may be a string of the form |
7438 | 7444 |
@var{width}x@var{height}, or the name of a size abbreviation. The |
7439 | 7445 |
default value is "320x240". |
7440 | 7446 |
|
7447 |
+This option is not available with the @code{haldclutsrc} filter. |
|
7448 |
+ |
|
7441 | 7449 |
@item rate, r |
7442 | 7450 |
Specify the frame rate of the sourced video, as the number of frames |
7443 | 7451 |
generated per second. It has to be a string in the format |
... | ... |
@@ -196,6 +196,7 @@ OBJS-$(CONFIG_ZMQ_FILTER) += f_zmq.o |
196 | 196 |
OBJS-$(CONFIG_CELLAUTO_FILTER) += vsrc_cellauto.o |
197 | 197 |
OBJS-$(CONFIG_COLOR_FILTER) += vsrc_testsrc.o |
198 | 198 |
OBJS-$(CONFIG_FREI0R_SRC_FILTER) += vf_frei0r.o |
199 |
+OBJS-$(CONFIG_HALDCLUTSRC_FILTER) += vsrc_testsrc.o |
|
199 | 200 |
OBJS-$(CONFIG_LIFE_FILTER) += vsrc_life.o |
200 | 201 |
OBJS-$(CONFIG_MANDELBROT_FILTER) += vsrc_mandelbrot.o |
201 | 202 |
OBJS-$(CONFIG_MPTESTSRC_FILTER) += vsrc_mptestsrc.o |
... | ... |
@@ -193,6 +193,7 @@ void avfilter_register_all(void) |
193 | 193 |
REGISTER_FILTER(CELLAUTO, cellauto, vsrc); |
194 | 194 |
REGISTER_FILTER(COLOR, color, vsrc); |
195 | 195 |
REGISTER_FILTER(FREI0R, frei0r_src, vsrc); |
196 |
+ REGISTER_FILTER(HALDCLUTSRC, haldclutsrc, vsrc); |
|
196 | 197 |
REGISTER_FILTER(LIFE, life, vsrc); |
197 | 198 |
REGISTER_FILTER(MANDELBROT, mandelbrot, vsrc); |
198 | 199 |
REGISTER_FILTER(MPTESTSRC, mptestsrc, vsrc); |
... | ... |
@@ -30,8 +30,8 @@ |
30 | 30 |
#include "libavutil/avutil.h" |
31 | 31 |
|
32 | 32 |
#define LIBAVFILTER_VERSION_MAJOR 3 |
33 |
-#define LIBAVFILTER_VERSION_MINOR 70 |
|
34 |
-#define LIBAVFILTER_VERSION_MICRO 101 |
|
33 |
+#define LIBAVFILTER_VERSION_MINOR 71 |
|
34 |
+#define LIBAVFILTER_VERSION_MICRO 100 |
|
35 | 35 |
|
36 | 36 |
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ |
37 | 37 |
LIBAVFILTER_VERSION_MINOR, \ |
... | ... |
@@ -71,20 +71,26 @@ typedef struct { |
71 | 71 |
|
72 | 72 |
/* only used by rgbtest */ |
73 | 73 |
uint8_t rgba_map[4]; |
74 |
+ |
|
75 |
+ /* only used by haldclut */ |
|
76 |
+ int level; |
|
74 | 77 |
} TestSourceContext; |
75 | 78 |
|
76 | 79 |
#define OFFSET(x) offsetof(TestSourceContext, x) |
77 | 80 |
#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM |
78 | 81 |
|
79 |
-#define COMMON_OPTIONS \ |
|
82 |
+#define SIZE_OPTIONS \ |
|
80 | 83 |
{ "size", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "320x240"}, 0, 0, FLAGS },\ |
81 | 84 |
{ "s", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "320x240"}, 0, 0, FLAGS },\ |
85 |
+ |
|
86 |
+#define COMMON_OPTIONS_NOSIZE \ |
|
82 | 87 |
{ "rate", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0, FLAGS },\ |
83 | 88 |
{ "r", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0, FLAGS },\ |
84 | 89 |
{ "duration", "set video duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = -1}, -1, INT64_MAX, FLAGS },\ |
85 | 90 |
{ "d", "set video duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = -1}, -1, INT64_MAX, FLAGS },\ |
86 | 91 |
{ "sar", "set video sample aspect ratio", OFFSET(sar), AV_OPT_TYPE_RATIONAL, {.dbl= 1}, 0, INT_MAX, FLAGS }, |
87 | 92 |
|
93 |
+#define COMMON_OPTIONS SIZE_OPTIONS COMMON_OPTIONS_NOSIZE |
|
88 | 94 |
|
89 | 95 |
static const AVOption options[] = { |
90 | 96 |
COMMON_OPTIONS |
... | ... |
@@ -269,6 +275,135 @@ AVFilter avfilter_vsrc_color = { |
269 | 269 |
|
270 | 270 |
#endif /* CONFIG_COLOR_FILTER */ |
271 | 271 |
|
272 |
+#if CONFIG_HALDCLUTSRC_FILTER |
|
273 |
+ |
|
274 |
+static const AVOption haldclutsrc_options[] = { |
|
275 |
+ { "level", "set level", OFFSET(level), AV_OPT_TYPE_INT, {.i64 = 6}, 2, 8, FLAGS }, |
|
276 |
+ COMMON_OPTIONS |
|
277 |
+ { NULL } |
|
278 |
+}; |
|
279 |
+ |
|
280 |
+AVFILTER_DEFINE_CLASS(haldclutsrc); |
|
281 |
+ |
|
282 |
+static void haldclutsrc_fill_picture(AVFilterContext *ctx, AVFrame *frame) |
|
283 |
+{ |
|
284 |
+ int i, j, k, x = 0, y = 0, is16bit = 0, step; |
|
285 |
+ uint32_t alpha = 0; |
|
286 |
+ const TestSourceContext *hc = ctx->priv; |
|
287 |
+ int level = hc->level; |
|
288 |
+ float scale; |
|
289 |
+ const int w = frame->width; |
|
290 |
+ const int h = frame->height; |
|
291 |
+ const uint8_t *data = frame->data[0]; |
|
292 |
+ const int linesize = frame->linesize[0]; |
|
293 |
+ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format); |
|
294 |
+ uint8_t rgba_map[4]; |
|
295 |
+ |
|
296 |
+ av_assert0(w == h && w == level*level*level); |
|
297 |
+ |
|
298 |
+ ff_fill_rgba_map(rgba_map, frame->format); |
|
299 |
+ |
|
300 |
+ switch (frame->format) { |
|
301 |
+ case AV_PIX_FMT_RGB48: |
|
302 |
+ case AV_PIX_FMT_BGR48: |
|
303 |
+ case AV_PIX_FMT_RGBA64: |
|
304 |
+ case AV_PIX_FMT_BGRA64: |
|
305 |
+ is16bit = 1; |
|
306 |
+ alpha = 0xffff; |
|
307 |
+ break; |
|
308 |
+ case AV_PIX_FMT_RGBA: |
|
309 |
+ case AV_PIX_FMT_BGRA: |
|
310 |
+ case AV_PIX_FMT_ARGB: |
|
311 |
+ case AV_PIX_FMT_ABGR: |
|
312 |
+ alpha = 0xff; |
|
313 |
+ break; |
|
314 |
+ } |
|
315 |
+ |
|
316 |
+ step = av_get_padded_bits_per_pixel(desc) >> (3 + is16bit); |
|
317 |
+ scale = ((float)(1 << (8*(is16bit+1))) - 1) / (level*level - 1); |
|
318 |
+ |
|
319 |
+#define LOAD_CLUT(nbits) do { \ |
|
320 |
+ uint##nbits##_t *dst = ((uint##nbits##_t *)(data + y*linesize)) + x*step; \ |
|
321 |
+ dst[rgba_map[0]] = av_clip_uint##nbits(i * scale); \ |
|
322 |
+ dst[rgba_map[1]] = av_clip_uint##nbits(j * scale); \ |
|
323 |
+ dst[rgba_map[2]] = av_clip_uint##nbits(k * scale); \ |
|
324 |
+ if (step == 4) \ |
|
325 |
+ dst[rgba_map[3]] = alpha; \ |
|
326 |
+} while (0) |
|
327 |
+ |
|
328 |
+ level *= level; |
|
329 |
+ for (k = 0; k < level; k++) { |
|
330 |
+ for (j = 0; j < level; j++) { |
|
331 |
+ for (i = 0; i < level; i++) { |
|
332 |
+ if (!is16bit) |
|
333 |
+ LOAD_CLUT(8); |
|
334 |
+ else |
|
335 |
+ LOAD_CLUT(16); |
|
336 |
+ if (++x == w) { |
|
337 |
+ x = 0; |
|
338 |
+ y++; |
|
339 |
+ } |
|
340 |
+ } |
|
341 |
+ } |
|
342 |
+ } |
|
343 |
+} |
|
344 |
+ |
|
345 |
+static av_cold int haldclutsrc_init(AVFilterContext *ctx) |
|
346 |
+{ |
|
347 |
+ TestSourceContext *hc = ctx->priv; |
|
348 |
+ hc->fill_picture_fn = haldclutsrc_fill_picture; |
|
349 |
+ hc->draw_once = 1; |
|
350 |
+ return init(ctx); |
|
351 |
+} |
|
352 |
+ |
|
353 |
+static int haldclutsrc_query_formats(AVFilterContext *ctx) |
|
354 |
+{ |
|
355 |
+ static const enum AVPixelFormat pix_fmts[] = { |
|
356 |
+ AV_PIX_FMT_RGB24, AV_PIX_FMT_BGR24, |
|
357 |
+ AV_PIX_FMT_RGBA, AV_PIX_FMT_BGRA, |
|
358 |
+ AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR, |
|
359 |
+ AV_PIX_FMT_0RGB, AV_PIX_FMT_0BGR, |
|
360 |
+ AV_PIX_FMT_RGB0, AV_PIX_FMT_BGR0, |
|
361 |
+ AV_PIX_FMT_RGB48, AV_PIX_FMT_BGR48, |
|
362 |
+ AV_PIX_FMT_RGBA64, AV_PIX_FMT_BGRA64, |
|
363 |
+ AV_PIX_FMT_NONE, |
|
364 |
+ }; |
|
365 |
+ ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); |
|
366 |
+ return 0; |
|
367 |
+} |
|
368 |
+ |
|
369 |
+static int haldclutsrc_config_props(AVFilterLink *outlink) |
|
370 |
+{ |
|
371 |
+ AVFilterContext *ctx = outlink->src; |
|
372 |
+ TestSourceContext *hc = ctx->priv; |
|
373 |
+ |
|
374 |
+ hc->w = hc->h = hc->level * hc->level * hc->level; |
|
375 |
+ return config_props(outlink); |
|
376 |
+} |
|
377 |
+ |
|
378 |
+static const AVFilterPad haldclutsrc_outputs[] = { |
|
379 |
+ { |
|
380 |
+ .name = "default", |
|
381 |
+ .type = AVMEDIA_TYPE_VIDEO, |
|
382 |
+ .request_frame = request_frame, |
|
383 |
+ .config_props = haldclutsrc_config_props, |
|
384 |
+ }, |
|
385 |
+ { NULL } |
|
386 |
+}; |
|
387 |
+ |
|
388 |
+AVFilter avfilter_vsrc_haldclutsrc = { |
|
389 |
+ .name = "haldclutsrc", |
|
390 |
+ .description = NULL_IF_CONFIG_SMALL("Provide an identity Hald CLUT."), |
|
391 |
+ .priv_class = &haldclutsrc_class, |
|
392 |
+ .priv_size = sizeof(TestSourceContext), |
|
393 |
+ .init = haldclutsrc_init, |
|
394 |
+ .uninit = uninit, |
|
395 |
+ .query_formats = haldclutsrc_query_formats, |
|
396 |
+ .inputs = NULL, |
|
397 |
+ .outputs = haldclutsrc_outputs, |
|
398 |
+}; |
|
399 |
+#endif /* CONFIG_HALDCLUTSRC_FILTER */ |
|
400 |
+ |
|
272 | 401 |
#if CONFIG_NULLSRC_FILTER |
273 | 402 |
|
274 | 403 |
#define nullsrc_options options |