diff options
author | Clément Bœsch <ubitux@gmail.com> | 2013-05-23 10:13:35 +0200 |
---|---|---|
committer | Clément Bœsch <ubitux@gmail.com> | 2013-05-27 20:32:28 +0200 |
commit | 3cec29cf5981c35cfbe2b43fcdea3f6b9bb108b9 (patch) | |
tree | 18b86dd3e5703b1903e75e18c80103d42bc10209 /libavfilter/vsrc_testsrc.c | |
parent | 1bbb46ff7126d71256b710645acf6cbfad857a23 (diff) | |
download | ffmpeg-3cec29cf5981c35cfbe2b43fcdea3f6b9bb108b9.tar.gz |
lavfi: add haldclutsrc filter.
Diffstat (limited to 'libavfilter/vsrc_testsrc.c')
-rw-r--r-- | libavfilter/vsrc_testsrc.c | 137 |
1 files changed, 136 insertions, 1 deletions
diff --git a/libavfilter/vsrc_testsrc.c b/libavfilter/vsrc_testsrc.c index 075026d9ef..5d79b44283 100644 --- a/libavfilter/vsrc_testsrc.c +++ b/libavfilter/vsrc_testsrc.c @@ -71,20 +71,26 @@ typedef struct { /* only used by rgbtest */ uint8_t rgba_map[4]; + + /* only used by haldclut */ + int level; } TestSourceContext; #define OFFSET(x) offsetof(TestSourceContext, x) #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 },\ { "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 },\ { "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 },\ { "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 }, +#define COMMON_OPTIONS SIZE_OPTIONS COMMON_OPTIONS_NOSIZE static const AVOption options[] = { COMMON_OPTIONS @@ -269,6 +275,135 @@ AVFilter avfilter_vsrc_color = { #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 #define nullsrc_options options |