Attached.
From 7b0a8586adc0a142f0b7afcdbdf36ce526f4cd34 Mon Sep 17 00:00:00 2001 From: Paul B Mahol <one...@gmail.com> Date: Sat, 6 May 2023 22:52:47 +0200 Subject: [PATCH] avfilter: add zoneplate video test source
Signed-off-by: Paul B Mahol <one...@gmail.com> --- libavfilter/Makefile | 1 + libavfilter/allfilters.c | 1 + libavfilter/vsrc_testsrc.c | 142 +++++++++++++++++++++++++++++++++++++ 3 files changed, 144 insertions(+) diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 93c614eeb7..9fb9a1095f 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -598,6 +598,7 @@ OBJS-$(CONFIG_SMPTEHDBARS_FILTER) += vsrc_testsrc.o OBJS-$(CONFIG_TESTSRC_FILTER) += vsrc_testsrc.o OBJS-$(CONFIG_TESTSRC2_FILTER) += vsrc_testsrc.o OBJS-$(CONFIG_YUVTESTSRC_FILTER) += vsrc_testsrc.o +OBJS-$(CONFIG_ZONEPLATE_FILTER) += vsrc_testsrc.o OBJS-$(CONFIG_NULLSINK_FILTER) += vsink_nullsink.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index 1c0bc12a92..025966dc45 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -563,6 +563,7 @@ extern const AVFilter ff_vsrc_smptehdbars; extern const AVFilter ff_vsrc_testsrc; extern const AVFilter ff_vsrc_testsrc2; extern const AVFilter ff_vsrc_yuvtestsrc; +extern const AVFilter ff_vsrc_zoneplate; extern const AVFilter ff_vsink_nullsink; diff --git a/libavfilter/vsrc_testsrc.c b/libavfilter/vsrc_testsrc.c index f391ac02e0..b1f7873a9c 100644 --- a/libavfilter/vsrc_testsrc.c +++ b/libavfilter/vsrc_testsrc.c @@ -88,6 +88,14 @@ typedef struct TestSourceContext { /* only used by haldclut */ int level; + + /* only used by zoneplate */ + int k0, kx, ky, kt; + int kxt, kyt, kxy; + int kx2, ky2, kt2; + int xo, yo, kU, kV; + int lut_precision; + uint8_t *lut; } TestSourceContext; #define OFFSET(x) offsetof(TestSourceContext, x) @@ -135,6 +143,7 @@ static av_cold void uninit(AVFilterContext *ctx) TestSourceContext *test = ctx->priv; av_frame_free(&test->picref); + av_freep(&test->lut); } static int config_props(AVFilterLink *outlink) @@ -2049,3 +2058,136 @@ const AVFilter ff_vsrc_colorchart = { }; #endif /* CONFIG_COLORCHART_FILTER */ + +#if CONFIG_COLORCHART_FILTER + +static const AVOption zoneplate_options[] = { + COMMON_OPTIONS + { "precision", "set LUT precision", OFFSET(lut_precision), AV_OPT_TYPE_INT, {.i64=10}, 4, 16, FLAGS }, + { "xo", "set x-axis offset", OFFSET(xo), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR }, + { "yo", "set y-axis offset", OFFSET(yo), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR }, + { "k0", "set zero order phase", OFFSET(k0), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR }, + { "kx", "set 1st order x-axis phase", OFFSET(kx), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR }, + { "ky", "set 1st order y-axis phase", OFFSET(ky), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR }, + { "kt", "set 1st order t-axis phase", OFFSET(kt), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR }, + { "kxt", "set x*t product phase", OFFSET(kxt), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR }, + { "kyt", "set y*t product phase", OFFSET(kyt), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR }, + { "kxy", "set x*y product phase", OFFSET(kxy), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR }, + { "kx2", "set 2nd order x-axis phase", OFFSET(kx2), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR }, + { "ky2", "set 2nd order y-axis phase", OFFSET(ky2), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR }, + { "kt2", "set 2nd order t-axis phase", OFFSET(kt2), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR }, + { "kU", "set zero order U-color phase", OFFSET(kU), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR }, + { "kV", "set zero order V-color phase", OFFSET(kV), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR }, + { NULL } +}; + +AVFILTER_DEFINE_CLASS(zoneplate); + +static int zoneplate_config_props(AVFilterLink *inlink) +{ + AVFilterContext *ctx = inlink->src; + TestSourceContext *s = ctx->priv; + + if (av_image_check_size(s->w, s->h, 0, ctx) < 0) + return AVERROR(EINVAL); + return config_props(inlink); +} + +static void zoneplate_fill_picture(AVFilterContext *ctx, AVFrame *frame) +{ + TestSourceContext *test = ctx->priv; + const int w = frame->width; + const int h = frame->height; + const int kxt = test->kxt, kyt = test->kyt, kx2 = test->kx2; + const int t = test->pts, k0 = test->k0; + const int kt = test->kt, kt2 = test->kt2, ky2 = test->ky2; + const int ky = test->ky, kx = test->kx, kxy = test->kxy; + const int lut_mask = (1 << test->lut_precision) - 1; + int akx, akxt, aky, akyt, akxy, nky2kt2; + const int nkt2 = kt2 * t * t, nkt = kt * t; + const int xreset = -(w / 2) - test->xo; + const int yreset = -(h / 2) - test->yo; + const int kU = test->kU, kV = test->kV; + const int dkxt = kxt * t; + int skxy = 0xffff / (w / 2); + int skx2 = 0xffff / w; + uint8_t *ydst = frame->data[0]; + uint8_t *udst = frame->data[1]; + uint8_t *vdst = frame->data[2]; + const uint8_t *lut = test->lut; + + aky = 0; + akyt = 0; + for (int j = 0, y = yreset; j < h; j++, y++) { + const int dkxy = kxy * y * skxy; + akx = 0; + akxt = 0; + aky += ky; + akyt += kyt * t; + akxy = dkxy * xreset; + nky2kt2 = (ky2 * y * y) / h + (nkt2 >> 1); + for (int i = 0, x = xreset; i < w; i++, x++) { + int phase = k0, uphase = kU, vphase = kV; + + akx += kx; + phase += akx + aky + nkt; + + akxt += dkxt; + akxy += dkxy; + phase += akxt + akyt; + phase += akxy >> 16; + phase += ((kx2 * x * x * skx2) >> 16) + nky2kt2; + uphase += phase; + vphase += phase; + + ydst[i] = lut[phase & lut_mask]; + udst[i] = lut[uphase & lut_mask]; + vdst[i] = lut[vphase & lut_mask]; + } + + ydst += frame->linesize[0]; + udst += frame->linesize[1]; + vdst += frame->linesize[2]; + } +} + +static av_cold int zoneplate_init(AVFilterContext *ctx) +{ + TestSourceContext *test = ctx->priv; + const int lut_size = 1 << test->lut_precision; + + test->lut = av_calloc(lut_size, sizeof(*test->lut)); + if (!test->lut) + return AVERROR(ENOMEM); + + for (int i = 0; i < lut_size; i++) + test->lut[i] = lrintf(255.f * (0.5f + 0.5f * sinf((2.f * M_PI * i) / lut_size))); + + test->draw_once = 0; + test->fill_picture_fn = zoneplate_fill_picture; + return init(ctx); +} + +static const AVFilterPad avfilter_vsrc_zoneplate_outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .config_props = zoneplate_config_props, + }, +}; + +const AVFilter ff_vsrc_zoneplate = { + .name = "zoneplate", + .description = NULL_IF_CONFIG_SMALL("Generate zone-plate."), + .priv_size = sizeof(TestSourceContext), + .priv_class = &zoneplate_class, + .init = zoneplate_init, + .uninit = uninit, + .activate = activate, + .inputs = NULL, + FILTER_OUTPUTS(avfilter_vsrc_zoneplate_outputs), + FILTER_SINGLE_PIXFMT(AV_PIX_FMT_YUV444P), + .process_command = ff_filter_process_command, +}; + +#endif /* CONFIG_COLORCHART_FILTER */ -- 2.39.1
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".