aboutsummaryrefslogtreecommitdiffstats
path: root/libavfilter/vsrc_testsrc.c
diff options
context:
space:
mode:
authorClément Bœsch <ubitux@gmail.com>2013-05-23 10:13:35 +0200
committerClément Bœsch <ubitux@gmail.com>2013-05-27 20:32:28 +0200
commit3cec29cf5981c35cfbe2b43fcdea3f6b9bb108b9 (patch)
tree18b86dd3e5703b1903e75e18c80103d42bc10209 /libavfilter/vsrc_testsrc.c
parent1bbb46ff7126d71256b710645acf6cbfad857a23 (diff)
downloadffmpeg-3cec29cf5981c35cfbe2b43fcdea3f6b9bb108b9.tar.gz
lavfi: add haldclutsrc filter.
Diffstat (limited to 'libavfilter/vsrc_testsrc.c')
-rw-r--r--libavfilter/vsrc_testsrc.c137
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