History

avfilter: add zoneplate video test source

Paul B Mahol committed 3 years ago

Commit 3475c831 parent 086a0f36 files · +300 −2Browse files

Showing the changes to libavfilter (4 of 6 files). Show all

Unified · Split

4 files
  1. libavfilter/Makefile +1 −0
  2. libavfilter/allfilters.c +1 −0
  3. libavfilter/version.h +2 −2
  4. libavfilter/vsrc_testsrc.c +197 −0
libavfilter/Makefile+1−0
@@ -592,6 +592,7 @@ OBJS-$(CONFIG_SMPTEHDBARS_FILTER) += vsrc_testsrc.o · 591 unmodified lines
592OBJS-$(CONFIG_TESTSRC_FILTER) += vsrc_testsrc.o592OBJS-$(CONFIG_TESTSRC_FILTER) += vsrc_testsrc.o
593OBJS-$(CONFIG_TESTSRC2_FILTER) += vsrc_testsrc.o593OBJS-$(CONFIG_TESTSRC2_FILTER) += vsrc_testsrc.o
594OBJS-$(CONFIG_YUVTESTSRC_FILTER) += vsrc_testsrc.o594OBJS-$(CONFIG_YUVTESTSRC_FILTER) += vsrc_testsrc.o
595OBJS-$(CONFIG_ZONEPLATE_FILTER) += vsrc_testsrc.o
595 596
596OBJS-$(CONFIG_NULLSINK_FILTER) += vsink_nullsink.o597OBJS-$(CONFIG_NULLSINK_FILTER) += vsink_nullsink.o
597 598
libavfilter/allfilters.c+1−0
@@ -557,6 +557,7 @@ extern const AVFilter ff_vsrc_smptehdbars; · 556 unmodified lines
557extern const AVFilter ff_vsrc_testsrc;557extern const AVFilter ff_vsrc_testsrc;
558extern const AVFilter ff_vsrc_testsrc2;558extern const AVFilter ff_vsrc_testsrc2;
559extern const AVFilter ff_vsrc_yuvtestsrc;559extern const AVFilter ff_vsrc_yuvtestsrc;
560extern const AVFilter ff_vsrc_zoneplate;
560 561
561extern const AVFilter ff_vsink_nullsink;562extern const AVFilter ff_vsink_nullsink;
562 563
libavfilter/version.h+2−2
@@ -31,8 +31,8 @@ · 30 unmodified lines
31 31
32#include "version_major.h"32#include "version_major.h"
33 33
34#define LIBAVFILTER_VERSION_MINOR 734#define LIBAVFILTER_VERSION_MINOR 8
35#define LIBAVFILTER_VERSION_MICRO 10235#define LIBAVFILTER_VERSION_MICRO 100
36 36
37 37
38#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \38#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
libavfilter/vsrc_testsrc.c+197−0
@@ -88,6 +88,15 @@ typedef struct TestSourceContext { · 87 unmodified lines
88 88
89 /* only used by haldclut */89 /* only used by haldclut */
90 int level;90 int level;
91
92 /* only used by zoneplate */
93 int k0, kx, ky, kt;
94 int kxt, kyt, kxy;
95 int kx2, ky2, kt2;
96 int xo, yo, to, kU, kV;
97 int lut_precision;
98 uint8_t *lut;
99 int (*fill_slice_fn)(AVFilterContext *ctx, void *arg, int job, int nb_jobs);
91} TestSourceContext;100} TestSourceContext;
92 101
93#define OFFSET(x) offsetof(TestSourceContext, x)102#define OFFSET(x) offsetof(TestSourceContext, x)
@@ -135,6 +144,7 @@ static av_cold void uninit(AVFilterContext *ctx) · 41 unmodified lines
135 TestSourceContext *test = ctx->priv;144 TestSourceContext *test = ctx->priv;
136 145
137 av_frame_free(&test->picref);146 av_frame_free(&test->picref);
147 av_freep(&test->lut);
138}148}
139 149
140static int config_props(AVFilterLink *outlink)150static int config_props(AVFilterLink *outlink)
@@ -2049,3 +2059,190 @@ const AVFilter ff_vsrc_colorchart = { · 1908 unmodified lines
2049};2059};
2050 2060
2051#endif /* CONFIG_COLORCHART_FILTER */2061#endif /* CONFIG_COLORCHART_FILTER */
2062
2063#if CONFIG_ZONEPLATE_FILTER
2064
2065static const AVOption zoneplate_options[] = {
2066 COMMON_OPTIONS
2067 { "precision", "set LUT precision", OFFSET(lut_precision), AV_OPT_TYPE_INT, {.i64=10}, 4, 16, FLAGS },
2068 { "xo", "set X-axis offset", OFFSET(xo), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR },
2069 { "yo", "set Y-axis offset", OFFSET(yo), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR },
2070 { "to", "set T-axis offset", OFFSET(to), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR },
2071 { "k0", "set 0-order phase", OFFSET(k0), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR },
2072 { "kx", "set 1-order X-axis phase", OFFSET(kx), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR },
2073 { "ky", "set 1-order Y-axis phase", OFFSET(ky), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR },
2074 { "kt", "set 1-order T-axis phase", OFFSET(kt), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR },
2075 { "kxt", "set X-axis*T-axis product phase", OFFSET(kxt), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR },
2076 { "kyt", "set Y-axis*T-axis product phase", OFFSET(kyt), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR },
2077 { "kxy", "set X-axis*Y-axis product phase", OFFSET(kxy), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR },
2078 { "kx2", "set 2-order X-axis phase", OFFSET(kx2), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR },
2079 { "ky2", "set 2-order Y-axis phase", OFFSET(ky2), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR },
2080 { "kt2", "set 2-order T-axis phase", OFFSET(kt2), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR },
2081 { "ku", "set 0-order U-color phase", OFFSET(kU), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR },
2082 { "kv", "set 0-order V-color phase", OFFSET(kV), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR },
2083 { NULL }
2084};
2085
2086AVFILTER_DEFINE_CLASS(zoneplate);
2087
2088#define ZONEPLATE_SLICE(name, type) \
2089static int zoneplate_fill_slice_##name(AVFilterContext *ctx, \
2090 void *arg, int job, \
2091 int nb_jobs) \
2092{ \
2093 TestSourceContext *test = ctx->priv; \
2094 AVFrame *frame = arg; \
2095 const int w = frame->width; \
2096 const int h = frame->height; \
2097 const int kxt = test->kxt, kyt = test->kyt, kx2 = test->kx2; \
2098 const int t = test->pts + test->to, k0 = test->k0; \
2099 const int kt = test->kt, kt2 = test->kt2, ky2 = test->ky2; \
2100 const int ky = test->ky, kx = test->kx, kxy = test->kxy; \
2101 const int lut_mask = (1 << test->lut_precision) - 1; \
2102 const int nkt2t = kt2 * t * t, nktt = kt * t; \
2103 const int start = (h * job ) / nb_jobs; \
2104 const int end = (h * (job+1)) / nb_jobs; \
2105 const int ylinesize = frame->linesize[0] / sizeof(type); \
2106 const int ulinesize = frame->linesize[1] / sizeof(type); \
2107 const int vlinesize = frame->linesize[2] / sizeof(type); \
2108 const int xreset = -(w / 2) - test->xo; \
2109 const int yreset = -(h / 2) - test->yo + start; \
2110 const int kU = test->kU, kV = test->kV; \
2111 const int skxy = 0xffff / (w / 2); \
2112 const int skx2 = 0xffff / w; \
2113 const int dkxt = kxt * t; \
2114 type *ydst = ((type *)frame->data[0]) + start * ylinesize; \
2115 type *udst = ((type *)frame->data[1]) + start * ulinesize; \
2116 type *vdst = ((type *)frame->data[2]) + start * vlinesize; \
2117 const type *lut = (const type *)test->lut; \
2118 int akx, akxt, aky, akyt; \
2119 \
2120 aky = start * ky; \
2121 akyt = start * kyt * t; \
2122 \
2123 for (int j = start, y = yreset; j < end; j++, y++) { \
2124 const int dkxy = kxy * y * skxy; \
2125 const int nky2kt2 = (ky2 * y * y) / h + (nkt2t >> 1); \
2126 int akxy = dkxy * xreset; \
2127 \
2128 akx = 0; \
2129 akxt = 0; \
2130 aky += ky; \
2131 akyt += kyt * t; \
2132 \
2133 for (int i = 0, x = xreset; i < w; i++, x++) { \
2134 int phase = k0, uphase = kU, vphase = kV; \
2135 \
2136 akx += kx; \
2137 phase += akx + aky + nktt; \
2138 \
2139 akxt += dkxt; \
2140 akxy += dkxy; \
2141 phase += akxt + akyt; \
2142 phase += akxy >> 16; \
2143 phase += ((kx2 * x * x * skx2) >> 16) + nky2kt2; \
2144 uphase += phase; \
2145 vphase += phase; \
2146 \
2147 ydst[i] = lut[phase & lut_mask]; \
2148 udst[i] = lut[uphase & lut_mask]; \
2149 vdst[i] = lut[vphase & lut_mask]; \
2150 } \
2151 \
2152 ydst += ylinesize; \
2153 udst += ulinesize; \
2154 vdst += vlinesize; \
2155 } \
2156 \
2157 return 0; \
2158}
2159
2160ZONEPLATE_SLICE( 8, uint8_t)
2161ZONEPLATE_SLICE( 9, uint16_t)
2162ZONEPLATE_SLICE(10, uint16_t)
2163ZONEPLATE_SLICE(12, uint16_t)
2164ZONEPLATE_SLICE(14, uint16_t)
2165ZONEPLATE_SLICE(16, uint16_t)
2166
2167static void zoneplate_fill_picture(AVFilterContext *ctx, AVFrame *frame)
2168{
2169 TestSourceContext *test = ctx->priv;
2170 ff_filter_execute(ctx, test->fill_slice_fn, frame, NULL,
2171 FFMIN(frame->height, ff_filter_get_nb_threads(ctx)));
2172}
2173
2174static int zoneplate_config_props(AVFilterLink *outlink)
2175{
2176 AVFilterContext *ctx = outlink->src;
2177 TestSourceContext *test = ctx->priv;
2178 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(outlink->format);
2179 const int lut_size = 1 << test->lut_precision;
2180 const int depth = desc->comp[0].depth;
2181 uint16_t *lut16;
2182 uint8_t *lut8;
2183
2184 if (av_image_check_size(test->w, test->h, 0, ctx) < 0)
2185 return AVERROR(EINVAL);
2186
2187 test->lut = av_calloc(lut_size, sizeof(*test->lut) * ((depth + 7) / 8));
2188 if (!test->lut)
2189 return AVERROR(ENOMEM);
2190
2191 lut8 = test->lut;
2192 lut16 = (uint16_t *)test->lut;
2193 switch (depth) {
2194 case 8:
2195 for (int i = 0; i < lut_size; i++)
2196 lut8[i] = lrintf(255.f * (0.5f + 0.5f * sinf((2.f * M_PI * i) / lut_size)));
2197 break;
2198 default:
2199 for (int i = 0; i < lut_size; i++)
2200 lut16[i] = lrintf(((1 << depth) - 1) * (0.5f + 0.5f * sinf((2.f * M_PI * i) / lut_size)));
2201 break;
2202 }
2203
2204 test->draw_once = 0;
2205 test->fill_picture_fn = zoneplate_fill_picture;
2206
2207 switch (depth) {
2208 case 8: test->fill_slice_fn = zoneplate_fill_slice_8; break;
2209 case 9: test->fill_slice_fn = zoneplate_fill_slice_9; break;
2210 case 10: test->fill_slice_fn = zoneplate_fill_slice_10; break;
2211 case 12: test->fill_slice_fn = zoneplate_fill_slice_12; break;
2212 case 14: test->fill_slice_fn = zoneplate_fill_slice_14; break;
2213 case 16: test->fill_slice_fn = zoneplate_fill_slice_16; break;
2214 }
2215 return config_props(outlink);
2216}
2217
2218static const enum AVPixelFormat zoneplate_pix_fmts[] = {
2219 AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV444P9,
2220 AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUV444P12,
2221 AV_PIX_FMT_YUV444P14, AV_PIX_FMT_YUV444P16,
2222 AV_PIX_FMT_NONE,
2223};
2224
2225static const AVFilterPad avfilter_vsrc_zoneplate_outputs[] = {
2226 {
2227 .name = "default",
2228 .type = AVMEDIA_TYPE_VIDEO,
2229 .config_props = zoneplate_config_props,
2230 },
2231};
2232
2233const AVFilter ff_vsrc_zoneplate = {
2234 .name = "zoneplate",
2235 .description = NULL_IF_CONFIG_SMALL("Generate zone-plate."),
2236 .priv_size = sizeof(TestSourceContext),
2237 .priv_class = &zoneplate_class,
2238 .init = init,
2239 .uninit = uninit,
2240 .activate = activate,
2241 .inputs = NULL,
2242 FILTER_OUTPUTS(avfilter_vsrc_zoneplate_outputs),
2243 FILTER_PIXFMTS_ARRAY(zoneplate_pix_fmts),
2244 .flags = AVFILTER_FLAG_SLICE_THREADS,
2245 .process_command = ff_filter_process_command,
2246};
2247
2248#endif /* CONFIG_ZONEPLATE_FILTER */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t