Browse code

lavfi: add haldclutsrc filter.

Clément Bœsch authored on 2013/05/23 17:13:35
Showing 5 changed files
... ...
@@ -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