Line | Branch | Exec | Source |
---|---|---|---|
1 | /* | ||
2 | * Copyright (c) 2007 Nicolas George <nicolas.george@normalesup.org> | ||
3 | * Copyright (c) 2011 Stefano Sabatini | ||
4 | * Copyright (c) 2012 Paul B Mahol | ||
5 | * | ||
6 | * This file is part of FFmpeg. | ||
7 | * | ||
8 | * FFmpeg is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU Lesser General Public | ||
10 | * License as published by the Free Software Foundation; either | ||
11 | * version 2.1 of the License, or (at your option) any later version. | ||
12 | * | ||
13 | * FFmpeg is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * Lesser General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU Lesser General Public | ||
19 | * License along with FFmpeg; if not, write to the Free Software | ||
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
21 | */ | ||
22 | |||
23 | /** | ||
24 | * @file | ||
25 | * Misc test sources. | ||
26 | * | ||
27 | * testsrc is based on the test pattern generator demuxer by Nicolas George: | ||
28 | * http://lists.ffmpeg.org/pipermail/ffmpeg-devel/2007-October/037845.html | ||
29 | * | ||
30 | * rgbtestsrc is ported from MPlayer libmpcodecs/vf_rgbtest.c by | ||
31 | * Michael Niedermayer. | ||
32 | * | ||
33 | * allyuv, smptebars and smptehdbars are by Paul B Mahol. | ||
34 | */ | ||
35 | |||
36 | #include "config_components.h" | ||
37 | |||
38 | #include "libavutil/avassert.h" | ||
39 | #include "libavutil/common.h" | ||
40 | #include "libavutil/ffmath.h" | ||
41 | #include "libavutil/mem.h" | ||
42 | #include "libavutil/opt.h" | ||
43 | #include "libavutil/imgutils.h" | ||
44 | #include "libavutil/intreadwrite.h" | ||
45 | #include "libavutil/xga_font_data.h" | ||
46 | #include "avfilter.h" | ||
47 | #include "drawutils.h" | ||
48 | #include "filters.h" | ||
49 | #include "filters.h" | ||
50 | #include "formats.h" | ||
51 | #include "video.h" | ||
52 | |||
53 | typedef struct TestSourceContext { | ||
54 | const AVClass *class; | ||
55 | int w, h; | ||
56 | int pw, ph; | ||
57 | unsigned int nb_frame; | ||
58 | AVRational time_base, frame_rate; | ||
59 | int64_t pts; | ||
60 | int64_t duration; ///< duration expressed in microseconds | ||
61 | AVRational sar; ///< sample aspect ratio | ||
62 | int draw_once; ///< draw only the first frame, always put out the same picture | ||
63 | int draw_once_reset; ///< draw only the first frame or in case of reset | ||
64 | AVFrame *picref; ///< cached reference containing the painted picture | ||
65 | |||
66 | void (* fill_picture_fn)(AVFilterContext *ctx, AVFrame *frame); | ||
67 | |||
68 | /* only used by testsrc */ | ||
69 | int nb_decimals; | ||
70 | |||
71 | /* only used by testsrc2 */ | ||
72 | int alpha; | ||
73 | |||
74 | /* only used by yuvtest */ | ||
75 | uint8_t ayuv_map[4]; | ||
76 | |||
77 | /* only used by colorspectrum */ | ||
78 | int type; | ||
79 | |||
80 | /* only used by color */ | ||
81 | FFDrawContext draw; | ||
82 | FFDrawColor color; | ||
83 | uint8_t color_rgba[4]; | ||
84 | |||
85 | /* only used by rgbtest */ | ||
86 | uint8_t rgba_map[4]; | ||
87 | int complement; | ||
88 | int depth; | ||
89 | |||
90 | /* only used by haldclut */ | ||
91 | int level; | ||
92 | |||
93 | /* only used by zoneplate */ | ||
94 | int k0, kx, ky, kt; | ||
95 | int kxt, kyt, kxy; | ||
96 | int kx2, ky2, kt2; | ||
97 | int xo, yo, to, kU, kV; | ||
98 | int lut_precision; | ||
99 | uint8_t *lut; | ||
100 | int (*fill_slice_fn)(AVFilterContext *ctx, void *arg, int job, int nb_jobs); | ||
101 | } TestSourceContext; | ||
102 | |||
103 | #define OFFSET(x) offsetof(TestSourceContext, x) | ||
104 | #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM | ||
105 | #define FLAGSR AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM | ||
106 | |||
107 | #define SIZE_OPTIONS \ | ||
108 | { "size", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "320x240"}, 0, 0, FLAGS },\ | ||
109 | { "s", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "320x240"}, 0, 0, FLAGS },\ | ||
110 | |||
111 | #define COMMON_OPTIONS_NOSIZE \ | ||
112 | { "rate", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, INT_MAX, FLAGS },\ | ||
113 | { "r", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, INT_MAX, FLAGS },\ | ||
114 | { "duration", "set video duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = -1}, -1, INT64_MAX, FLAGS },\ | ||
115 | { "d", "set video duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = -1}, -1, INT64_MAX, FLAGS },\ | ||
116 | { "sar", "set video sample aspect ratio", OFFSET(sar), AV_OPT_TYPE_RATIONAL, {.dbl= 1}, 0, INT_MAX, FLAGS }, | ||
117 | |||
118 | #define COMMON_OPTIONS SIZE_OPTIONS COMMON_OPTIONS_NOSIZE | ||
119 | |||
120 | #define NOSIZE_OPTIONS_OFFSET 2 | ||
121 | /* Filters using COMMON_OPTIONS_NOSIZE also use the following options | ||
122 | * via &options[NOSIZE_OPTIONS_OFFSET]. So don't break it. */ | ||
123 | static const AVOption options[] = { | ||
124 | COMMON_OPTIONS | ||
125 | { NULL } | ||
126 | }; | ||
127 | |||
128 | 2270 | static av_cold int init(AVFilterContext *ctx) | |
129 | { | ||
130 | 2270 | TestSourceContext *test = ctx->priv; | |
131 | |||
132 | 2270 | test->time_base = av_inv_q(test->frame_rate); | |
133 | 2270 | test->nb_frame = 0; | |
134 | 2270 | test->pts = 0; | |
135 | |||
136 | 2270 | av_log(ctx, AV_LOG_VERBOSE, "size:%dx%d rate:%d/%d duration:%f sar:%d/%d\n", | |
137 | test->w, test->h, test->frame_rate.num, test->frame_rate.den, | ||
138 |
2/2✓ Branch 0 taken 164 times.
✓ Branch 1 taken 2106 times.
|
2270 | test->duration < 0 ? -1 : (double)test->duration/1000000, |
139 | test->sar.num, test->sar.den); | ||
140 | 2270 | return 0; | |
141 | } | ||
142 | |||
143 | 2270 | static av_cold void uninit(AVFilterContext *ctx) | |
144 | { | ||
145 | 2270 | TestSourceContext *test = ctx->priv; | |
146 | |||
147 | 2270 | av_frame_free(&test->picref); | |
148 | 2270 | av_freep(&test->lut); | |
149 | 2270 | } | |
150 | |||
151 | 1139 | static int config_props(AVFilterLink *outlink) | |
152 | { | ||
153 | 1139 | TestSourceContext *test = outlink->src->priv; | |
154 | 1139 | FilterLink *l = ff_filter_link(outlink); | |
155 | |||
156 | 1139 | outlink->w = test->w; | |
157 | 1139 | outlink->h = test->h; | |
158 | 1139 | outlink->sample_aspect_ratio = test->sar; | |
159 | 1139 | l->frame_rate = test->frame_rate; | |
160 | 1139 | outlink->time_base = test->time_base; | |
161 | |||
162 | 1139 | return 0; | |
163 | } | ||
164 | |||
165 | static const AVFilterPad outputs[] = { | ||
166 | { | ||
167 | .name = "default", | ||
168 | .type = AVMEDIA_TYPE_VIDEO, | ||
169 | .config_props = config_props, | ||
170 | }, | ||
171 | }; | ||
172 | |||
173 | 29000 | static int activate(AVFilterContext *ctx) | |
174 | { | ||
175 | 29000 | AVFilterLink *outlink = ctx->outputs[0]; | |
176 | 29000 | TestSourceContext *test = ctx->priv; | |
177 | AVFrame *frame; | ||
178 | |||
179 |
2/2✓ Branch 1 taken 23 times.
✓ Branch 2 taken 28977 times.
|
29000 | if (!ff_outlink_frame_wanted(outlink)) |
180 | 23 | return FFERROR_NOT_READY; | |
181 |
2/2✓ Branch 0 taken 1891 times.
✓ Branch 1 taken 27086 times.
|
28977 | if (test->duration >= 0 && |
182 |
2/2✓ Branch 0 taken 82 times.
✓ Branch 1 taken 1809 times.
|
1891 | av_rescale_q(test->pts, test->time_base, AV_TIME_BASE_Q) >= test->duration) { |
183 | 82 | ff_outlink_set_status(outlink, AVERROR_EOF, test->pts); | |
184 | 82 | return 0; | |
185 | } | ||
186 | |||
187 |
2/2✓ Branch 0 taken 27623 times.
✓ Branch 1 taken 1272 times.
|
28895 | if (test->draw_once) { |
188 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 27623 times.
|
27623 | if (test->draw_once_reset) { |
189 | ✗ | av_frame_free(&test->picref); | |
190 | ✗ | test->draw_once_reset = 0; | |
191 | } | ||
192 |
2/2✓ Branch 0 taken 1083 times.
✓ Branch 1 taken 26540 times.
|
27623 | if (!test->picref) { |
193 | 1083 | test->picref = | |
194 | 1083 | ff_get_video_buffer(outlink, test->w, test->h); | |
195 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1083 times.
|
1083 | if (!test->picref) |
196 | ✗ | return AVERROR(ENOMEM); | |
197 | 1083 | test->fill_picture_fn(outlink->src, test->picref); | |
198 | } | ||
199 | 27623 | frame = av_frame_clone(test->picref); | |
200 | } else | ||
201 | 1272 | frame = ff_get_video_buffer(outlink, test->w, test->h); | |
202 | |||
203 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 28895 times.
|
28895 | if (!frame) |
204 | ✗ | return AVERROR(ENOMEM); | |
205 | 28895 | frame->pts = test->pts; | |
206 | 28895 | frame->duration = 1; | |
207 | 28895 | frame->flags |= AV_FRAME_FLAG_KEY; | |
208 | 28895 | frame->flags &= ~AV_FRAME_FLAG_INTERLACED; | |
209 | 28895 | frame->pict_type = AV_PICTURE_TYPE_I; | |
210 | 28895 | frame->sample_aspect_ratio = test->sar; | |
211 |
2/2✓ Branch 0 taken 1272 times.
✓ Branch 1 taken 27623 times.
|
28895 | if (!test->draw_once) |
212 | 1272 | test->fill_picture_fn(outlink->src, frame); | |
213 | |||
214 | 28895 | test->pts++; | |
215 | 28895 | test->nb_frame++; | |
216 | |||
217 | 28895 | return ff_filter_frame(outlink, frame); | |
218 | } | ||
219 | |||
220 | #if CONFIG_COLOR_FILTER | ||
221 | |||
222 | static const AVOption color_options[] = { | ||
223 | { "color", "set color", OFFSET(color_rgba), AV_OPT_TYPE_COLOR, {.str = "black"}, 0, 0, FLAGSR }, | ||
224 | { "c", "set color", OFFSET(color_rgba), AV_OPT_TYPE_COLOR, {.str = "black"}, 0, 0, FLAGSR }, | ||
225 | COMMON_OPTIONS | ||
226 | { NULL } | ||
227 | }; | ||
228 | |||
229 | AVFILTER_DEFINE_CLASS(color); | ||
230 | |||
231 | 15 | static void color_fill_picture(AVFilterContext *ctx, AVFrame *picref) | |
232 | { | ||
233 | 15 | TestSourceContext *test = ctx->priv; | |
234 | 15 | ff_fill_rectangle(&test->draw, &test->color, | |
235 | 15 | picref->data, picref->linesize, | |
236 | 0, 0, test->w, test->h); | ||
237 | 15 | } | |
238 | |||
239 | 28 | static av_cold int color_init(AVFilterContext *ctx) | |
240 | { | ||
241 | 28 | TestSourceContext *test = ctx->priv; | |
242 | 28 | test->fill_picture_fn = color_fill_picture; | |
243 | 28 | test->draw_once = 1; | |
244 | 28 | return init(ctx); | |
245 | } | ||
246 | |||
247 | 15 | static int color_query_formats(const AVFilterContext *ctx, | |
248 | AVFilterFormatsConfig **cfg_in, | ||
249 | AVFilterFormatsConfig **cfg_out) | ||
250 | { | ||
251 | 15 | return ff_set_common_formats2(ctx, cfg_in, cfg_out, ff_draw_supported_pixel_formats(0)); | |
252 | } | ||
253 | |||
254 | 15 | static int color_config_props(AVFilterLink *inlink) | |
255 | { | ||
256 | 15 | AVFilterContext *ctx = inlink->src; | |
257 | 15 | TestSourceContext *test = ctx->priv; | |
258 | int ret; | ||
259 | |||
260 | 15 | ret = ff_draw_init2(&test->draw, inlink->format, inlink->colorspace, | |
261 | inlink->color_range, 0); | ||
262 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
|
15 | if (ret < 0) { |
263 | ✗ | av_log(ctx, AV_LOG_ERROR, "Failed to initialize FFDrawContext\n"); | |
264 | ✗ | return ret; | |
265 | } | ||
266 | |||
267 | 15 | ff_draw_color(&test->draw, &test->color, test->color_rgba); | |
268 | |||
269 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 15 times.
|
15 | if (av_image_check_size(test->w, test->h, 0, ctx) < 0) |
270 | ✗ | return AVERROR(EINVAL); | |
271 | |||
272 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 15 times.
|
15 | if ((ret = config_props(inlink)) < 0) |
273 | ✗ | return ret; | |
274 | |||
275 | 15 | return 0; | |
276 | } | ||
277 | |||
278 | ✗ | static int color_process_command(AVFilterContext *ctx, const char *cmd, const char *args, | |
279 | char *res, int res_len, int flags) | ||
280 | { | ||
281 | ✗ | TestSourceContext *test = ctx->priv; | |
282 | int ret; | ||
283 | |||
284 | ✗ | ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags); | |
285 | ✗ | if (ret < 0) | |
286 | ✗ | return ret; | |
287 | |||
288 | ✗ | ff_draw_color(&test->draw, &test->color, test->color_rgba); | |
289 | ✗ | test->draw_once_reset = 1; | |
290 | ✗ | return 0; | |
291 | } | ||
292 | |||
293 | static const AVFilterPad color_outputs[] = { | ||
294 | { | ||
295 | .name = "default", | ||
296 | .type = AVMEDIA_TYPE_VIDEO, | ||
297 | .config_props = color_config_props, | ||
298 | }, | ||
299 | }; | ||
300 | |||
301 | const FFFilter ff_vsrc_color = { | ||
302 | .p.name = "color", | ||
303 | .p.description = NULL_IF_CONFIG_SMALL("Provide an uniformly colored input."), | ||
304 | .p.priv_class = &color_class, | ||
305 | .priv_size = sizeof(TestSourceContext), | ||
306 | .init = color_init, | ||
307 | .uninit = uninit, | ||
308 | .activate = activate, | ||
309 | FILTER_OUTPUTS(color_outputs), | ||
310 | FILTER_QUERY_FUNC2(color_query_formats), | ||
311 | .process_command = color_process_command, | ||
312 | }; | ||
313 | |||
314 | #endif /* CONFIG_COLOR_FILTER */ | ||
315 | |||
316 | #if CONFIG_HALDCLUTSRC_FILTER | ||
317 | |||
318 | static const AVOption haldclutsrc_options[] = { | ||
319 | { "level", "set level", OFFSET(level), AV_OPT_TYPE_INT, {.i64 = 6}, 2, 16, FLAGS }, | ||
320 | COMMON_OPTIONS_NOSIZE | ||
321 | { NULL } | ||
322 | }; | ||
323 | |||
324 | AVFILTER_DEFINE_CLASS(haldclutsrc); | ||
325 | |||
326 | ✗ | static void haldclutsrc_fill_picture(AVFilterContext *ctx, AVFrame *frame) | |
327 | { | ||
328 | ✗ | int i, j, k, x = 0, y = 0, is16bit = 0, step; | |
329 | ✗ | uint32_t alpha = 0; | |
330 | ✗ | const TestSourceContext *hc = ctx->priv; | |
331 | ✗ | int level = hc->level; | |
332 | float scale; | ||
333 | ✗ | const int w = frame->width; | |
334 | ✗ | const int h = frame->height; | |
335 | ✗ | uint8_t *data = frame->data[0]; | |
336 | ✗ | const ptrdiff_t linesize = frame->linesize[0]; | |
337 | ✗ | const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format); | |
338 | ✗ | const int depth = desc->comp[0].depth; | |
339 | ✗ | const int planar = desc->flags & AV_PIX_FMT_FLAG_PLANAR; | |
340 | ✗ | const int planes = av_pix_fmt_count_planes(frame->format); | |
341 | uint8_t rgba_map[4]; | ||
342 | |||
343 | ✗ | av_assert0(w == h && w == level*level*level); | |
344 | |||
345 | ✗ | ff_fill_rgba_map(rgba_map, frame->format); | |
346 | |||
347 | ✗ | alpha = (1 << depth) - 1; | |
348 | ✗ | is16bit = depth > 8; | |
349 | |||
350 | ✗ | step = av_get_padded_bits_per_pixel(desc) >> (3 + is16bit); | |
351 | ✗ | scale = ((float)alpha) / (level*level - 1); | |
352 | |||
353 | #define LOAD_CLUT(nbits) do { \ | ||
354 | uint##nbits##_t *dst = ((uint##nbits##_t *)(data + y*linesize)) + x*step; \ | ||
355 | dst[rgba_map[0]] = av_clip_uint##nbits(i * scale); \ | ||
356 | dst[rgba_map[1]] = av_clip_uint##nbits(j * scale); \ | ||
357 | dst[rgba_map[2]] = av_clip_uint##nbits(k * scale); \ | ||
358 | if (step == 4) \ | ||
359 | dst[rgba_map[3]] = alpha; \ | ||
360 | } while (0) | ||
361 | |||
362 | #define LOAD_CLUT_PLANAR(type, nbits) do { \ | ||
363 | type *dst = ((type *)(frame->data[2] + y*frame->linesize[2])) + x; \ | ||
364 | dst[0] = av_clip_uintp2(i * scale, nbits); \ | ||
365 | dst = ((type *)(frame->data[0] + y*frame->linesize[0])) + x; \ | ||
366 | dst[0] = av_clip_uintp2(j * scale, nbits); \ | ||
367 | dst = ((type *)(frame->data[1] + y*frame->linesize[1])) + x; \ | ||
368 | dst[0] = av_clip_uintp2(k * scale, nbits); \ | ||
369 | if (planes == 4) { \ | ||
370 | dst = ((type *)(frame->data[3] + y*linesize)) + x; \ | ||
371 | dst[0] = alpha; \ | ||
372 | } \ | ||
373 | } while (0) | ||
374 | |||
375 | ✗ | level *= level; | |
376 | ✗ | for (k = 0; k < level; k++) { | |
377 | ✗ | for (j = 0; j < level; j++) { | |
378 | ✗ | for (i = 0; i < level; i++) { | |
379 | ✗ | if (!planar) { | |
380 | ✗ | if (!is16bit) | |
381 | ✗ | LOAD_CLUT(8); | |
382 | else | ||
383 | ✗ | LOAD_CLUT(16); | |
384 | } else { | ||
385 | ✗ | switch (depth) { | |
386 | ✗ | case 8: LOAD_CLUT_PLANAR(uint8_t, 8); break; | |
387 | ✗ | case 9: LOAD_CLUT_PLANAR(uint16_t, 9); break; | |
388 | ✗ | case 10: LOAD_CLUT_PLANAR(uint16_t,10); break; | |
389 | ✗ | case 12: LOAD_CLUT_PLANAR(uint16_t,12); break; | |
390 | ✗ | case 14: LOAD_CLUT_PLANAR(uint16_t,14); break; | |
391 | ✗ | case 16: LOAD_CLUT_PLANAR(uint16_t,16); break; | |
392 | } | ||
393 | } | ||
394 | ✗ | if (++x == w) { | |
395 | ✗ | x = 0; | |
396 | ✗ | y++; | |
397 | } | ||
398 | } | ||
399 | } | ||
400 | } | ||
401 | ✗ | } | |
402 | |||
403 | ✗ | static av_cold int haldclutsrc_init(AVFilterContext *ctx) | |
404 | { | ||
405 | ✗ | TestSourceContext *hc = ctx->priv; | |
406 | ✗ | hc->fill_picture_fn = haldclutsrc_fill_picture; | |
407 | ✗ | hc->draw_once = 1; | |
408 | ✗ | return init(ctx); | |
409 | } | ||
410 | |||
411 | static const enum AVPixelFormat haldclutsrc_pix_fmts[] = { | ||
412 | AV_PIX_FMT_RGB24, AV_PIX_FMT_BGR24, | ||
413 | AV_PIX_FMT_RGBA, AV_PIX_FMT_BGRA, | ||
414 | AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR, | ||
415 | AV_PIX_FMT_0RGB, AV_PIX_FMT_0BGR, | ||
416 | AV_PIX_FMT_RGB0, AV_PIX_FMT_BGR0, | ||
417 | AV_PIX_FMT_RGB48, AV_PIX_FMT_BGR48, | ||
418 | AV_PIX_FMT_RGBA64, AV_PIX_FMT_BGRA64, | ||
419 | AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP, | ||
420 | AV_PIX_FMT_GBRP9, | ||
421 | AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRAP10, | ||
422 | AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRAP12, | ||
423 | AV_PIX_FMT_GBRP14, | ||
424 | AV_PIX_FMT_GBRP16, AV_PIX_FMT_GBRAP16, | ||
425 | AV_PIX_FMT_NONE, | ||
426 | }; | ||
427 | |||
428 | ✗ | static int haldclutsrc_config_props(AVFilterLink *outlink) | |
429 | { | ||
430 | ✗ | AVFilterContext *ctx = outlink->src; | |
431 | ✗ | TestSourceContext *hc = ctx->priv; | |
432 | |||
433 | ✗ | hc->w = hc->h = hc->level * hc->level * hc->level; | |
434 | ✗ | return config_props(outlink); | |
435 | } | ||
436 | |||
437 | static const AVFilterPad haldclutsrc_outputs[] = { | ||
438 | { | ||
439 | .name = "default", | ||
440 | .type = AVMEDIA_TYPE_VIDEO, | ||
441 | .config_props = haldclutsrc_config_props, | ||
442 | }, | ||
443 | }; | ||
444 | |||
445 | const FFFilter ff_vsrc_haldclutsrc = { | ||
446 | .p.name = "haldclutsrc", | ||
447 | .p.description = NULL_IF_CONFIG_SMALL("Provide an identity Hald CLUT."), | ||
448 | .p.priv_class = &haldclutsrc_class, | ||
449 | .priv_size = sizeof(TestSourceContext), | ||
450 | .init = haldclutsrc_init, | ||
451 | .uninit = uninit, | ||
452 | .activate = activate, | ||
453 | FILTER_OUTPUTS(haldclutsrc_outputs), | ||
454 | FILTER_PIXFMTS_ARRAY(haldclutsrc_pix_fmts), | ||
455 | }; | ||
456 | #endif /* CONFIG_HALDCLUTSRC_FILTER */ | ||
457 | |||
458 | AVFILTER_DEFINE_CLASS_EXT(nullsrc_yuvtestsrc, "nullsrc/yuvtestsrc", options); | ||
459 | |||
460 | #if CONFIG_NULLSRC_FILTER | ||
461 | |||
462 | ✗ | static void nullsrc_fill_picture(AVFilterContext *ctx, AVFrame *picref) { } | |
463 | |||
464 | ✗ | static av_cold int nullsrc_init(AVFilterContext *ctx) | |
465 | { | ||
466 | ✗ | TestSourceContext *test = ctx->priv; | |
467 | |||
468 | ✗ | test->fill_picture_fn = nullsrc_fill_picture; | |
469 | ✗ | return init(ctx); | |
470 | } | ||
471 | |||
472 | const FFFilter ff_vsrc_nullsrc = { | ||
473 | .p.name = "nullsrc", | ||
474 | .p.description= NULL_IF_CONFIG_SMALL("Null video source, return unprocessed video frames."), | ||
475 | .p.priv_class= &nullsrc_yuvtestsrc_class, | ||
476 | .init = nullsrc_init, | ||
477 | .uninit = uninit, | ||
478 | .activate = activate, | ||
479 | .priv_size = sizeof(TestSourceContext), | ||
480 | FILTER_OUTPUTS(outputs), | ||
481 | }; | ||
482 | |||
483 | #endif /* CONFIG_NULLSRC_FILTER */ | ||
484 | |||
485 | #if CONFIG_TESTSRC_FILTER | ||
486 | |||
487 | static const AVOption testsrc_options[] = { | ||
488 | COMMON_OPTIONS | ||
489 | { "decimals", "set number of decimals to show", OFFSET(nb_decimals), AV_OPT_TYPE_INT, {.i64=0}, 0, 17, FLAGS }, | ||
490 | { "n", "set number of decimals to show", OFFSET(nb_decimals), AV_OPT_TYPE_INT, {.i64=0}, 0, 17, FLAGS }, | ||
491 | { NULL } | ||
492 | }; | ||
493 | |||
494 | AVFILTER_DEFINE_CLASS(testsrc); | ||
495 | |||
496 | /** | ||
497 | * Fill a rectangle with value val. | ||
498 | * | ||
499 | * @param val the RGB value to set | ||
500 | * @param dst pointer to the destination buffer to fill | ||
501 | * @param dst_linesize linesize of destination | ||
502 | * @param segment_width width of the segment | ||
503 | * @param x horizontal coordinate where to draw the rectangle in the destination buffer | ||
504 | * @param y horizontal coordinate where to draw the rectangle in the destination buffer | ||
505 | * @param w width of the rectangle to draw, expressed as a number of segment_width units | ||
506 | * @param h height of the rectangle to draw, expressed as a number of segment_width units | ||
507 | */ | ||
508 | 4240 | static void draw_rectangle(unsigned val, uint8_t *dst, ptrdiff_t dst_linesize, int segment_width, | |
509 | int x, int y, int w, int h) | ||
510 | { | ||
511 | int i; | ||
512 | 4240 | int step = 3; | |
513 | |||
514 | 4240 | dst += segment_width * (step * x + y * dst_linesize); | |
515 | 4240 | w *= segment_width * step; | |
516 | 4240 | h *= segment_width; | |
517 |
2/2✓ Branch 0 taken 86765 times.
✓ Branch 1 taken 4240 times.
|
91005 | for (i = 0; i < h; i++) { |
518 | 86765 | memset(dst, val, w); | |
519 | 86765 | dst += dst_linesize; | |
520 | } | ||
521 | 4240 | } | |
522 | |||
523 | 775 | static void draw_digit(int digit, uint8_t *dst, ptrdiff_t dst_linesize, | |
524 | int segment_width) | ||
525 | { | ||
526 | #define TOP_HBAR 1 | ||
527 | #define MID_HBAR 2 | ||
528 | #define BOT_HBAR 4 | ||
529 | #define LEFT_TOP_VBAR 8 | ||
530 | #define LEFT_BOT_VBAR 16 | ||
531 | #define RIGHT_TOP_VBAR 32 | ||
532 | #define RIGHT_BOT_VBAR 64 | ||
533 | struct segments { | ||
534 | int x, y, w, h; | ||
535 | 775 | } segments[] = { | |
536 | { 1, 0, 5, 1 }, /* TOP_HBAR */ | ||
537 | { 1, 6, 5, 1 }, /* MID_HBAR */ | ||
538 | { 1, 12, 5, 1 }, /* BOT_HBAR */ | ||
539 | { 0, 1, 1, 5 }, /* LEFT_TOP_VBAR */ | ||
540 | { 0, 7, 1, 5 }, /* LEFT_BOT_VBAR */ | ||
541 | { 6, 1, 1, 5 }, /* RIGHT_TOP_VBAR */ | ||
542 | { 6, 7, 1, 5 } /* RIGHT_BOT_VBAR */ | ||
543 | }; | ||
544 | static const unsigned char masks[10] = { | ||
545 | /* 0 */ TOP_HBAR |BOT_HBAR|LEFT_TOP_VBAR|LEFT_BOT_VBAR|RIGHT_TOP_VBAR|RIGHT_BOT_VBAR, | ||
546 | /* 1 */ RIGHT_TOP_VBAR|RIGHT_BOT_VBAR, | ||
547 | /* 2 */ TOP_HBAR|MID_HBAR|BOT_HBAR|LEFT_BOT_VBAR |RIGHT_TOP_VBAR, | ||
548 | /* 3 */ TOP_HBAR|MID_HBAR|BOT_HBAR |RIGHT_TOP_VBAR|RIGHT_BOT_VBAR, | ||
549 | /* 4 */ MID_HBAR |LEFT_TOP_VBAR |RIGHT_TOP_VBAR|RIGHT_BOT_VBAR, | ||
550 | /* 5 */ TOP_HBAR|BOT_HBAR|MID_HBAR|LEFT_TOP_VBAR |RIGHT_BOT_VBAR, | ||
551 | /* 6 */ TOP_HBAR|BOT_HBAR|MID_HBAR|LEFT_TOP_VBAR|LEFT_BOT_VBAR |RIGHT_BOT_VBAR, | ||
552 | /* 7 */ TOP_HBAR |RIGHT_TOP_VBAR|RIGHT_BOT_VBAR, | ||
553 | /* 8 */ TOP_HBAR|BOT_HBAR|MID_HBAR|LEFT_TOP_VBAR|LEFT_BOT_VBAR|RIGHT_TOP_VBAR|RIGHT_BOT_VBAR, | ||
554 | /* 9 */ TOP_HBAR|BOT_HBAR|MID_HBAR|LEFT_TOP_VBAR |RIGHT_TOP_VBAR|RIGHT_BOT_VBAR, | ||
555 | }; | ||
556 | 775 | unsigned mask = masks[digit]; | |
557 | int i; | ||
558 | |||
559 | 775 | draw_rectangle(0, dst, dst_linesize, segment_width, 0, 0, 8, 13); | |
560 |
2/2✓ Branch 0 taken 5425 times.
✓ Branch 1 taken 775 times.
|
6200 | for (i = 0; i < FF_ARRAY_ELEMS(segments); i++) |
561 |
2/2✓ Branch 0 taken 3465 times.
✓ Branch 1 taken 1960 times.
|
5425 | if (mask & (1<<i)) |
562 | 3465 | draw_rectangle(255, dst, dst_linesize, segment_width, | |
563 | segments[i].x, segments[i].y, segments[i].w, segments[i].h); | ||
564 | 775 | } | |
565 | |||
566 | #define GRADIENT_SIZE (6 * 256) | ||
567 | |||
568 | 316 | static void test_fill_picture(AVFilterContext *ctx, AVFrame *frame) | |
569 | { | ||
570 | 316 | TestSourceContext *test = ctx->priv; | |
571 | uint8_t *p, *p0; | ||
572 | int x, y; | ||
573 | int color, color_rest; | ||
574 | int icolor; | ||
575 | int radius; | ||
576 | int quad0, quad; | ||
577 | int dquad_x, dquad_y; | ||
578 | int grad, dgrad, rgrad, drgrad; | ||
579 | int seg_size; | ||
580 | int second; | ||
581 | int i; | ||
582 | 316 | uint8_t *data = frame->data[0]; | |
583 | 316 | int width = frame->width; | |
584 | 316 | int height = frame->height; | |
585 | |||
586 | /* draw colored bars and circle */ | ||
587 | 316 | radius = (width + height) / 4; | |
588 | 316 | quad0 = width * width / 4 + height * height / 4 - radius * radius; | |
589 | 316 | dquad_y = 1 - height; | |
590 | 316 | p0 = data; | |
591 |
2/2✓ Branch 0 taken 68610 times.
✓ Branch 1 taken 316 times.
|
68926 | for (y = 0; y < height; y++) { |
592 | 68610 | p = p0; | |
593 | 68610 | color = 0; | |
594 | 68610 | color_rest = 0; | |
595 | 68610 | quad = quad0; | |
596 | 68610 | dquad_x = 1 - width; | |
597 |
2/2✓ Branch 0 taken 22239140 times.
✓ Branch 1 taken 68610 times.
|
22307750 | for (x = 0; x < width; x++) { |
598 | 22239140 | icolor = color; | |
599 |
2/2✓ Branch 0 taken 16639285 times.
✓ Branch 1 taken 5599855 times.
|
22239140 | if (quad < 0) |
600 | 16639285 | icolor ^= 7; | |
601 | 22239140 | quad += dquad_x; | |
602 | 22239140 | dquad_x += 2; | |
603 |
2/2✓ Branch 0 taken 11100343 times.
✓ Branch 1 taken 11138797 times.
|
22239140 | *(p++) = icolor & 1 ? 255 : 0; |
604 |
2/2✓ Branch 0 taken 11057169 times.
✓ Branch 1 taken 11181971 times.
|
22239140 | *(p++) = icolor & 2 ? 255 : 0; |
605 |
2/2✓ Branch 0 taken 11050989 times.
✓ Branch 1 taken 11188151 times.
|
22239140 | *(p++) = icolor & 4 ? 255 : 0; |
606 | 22239140 | color_rest += 8; | |
607 |
2/2✓ Branch 0 taken 548580 times.
✓ Branch 1 taken 21690560 times.
|
22239140 | if (color_rest >= width) { |
608 | 548580 | color_rest -= width; | |
609 | 548580 | color++; | |
610 | } | ||
611 | } | ||
612 | 68610 | quad0 += dquad_y; | |
613 | 68610 | dquad_y += 2; | |
614 | 68610 | p0 += frame->linesize[0]; | |
615 | } | ||
616 | |||
617 | /* draw sliding color line */ | ||
618 | 316 | p0 = p = data + frame->linesize[0] * (height * 3/4); | |
619 | 316 | grad = (256 * test->nb_frame * test->time_base.num / test->time_base.den) % | |
620 | GRADIENT_SIZE; | ||
621 | 316 | rgrad = 0; | |
622 | 316 | dgrad = GRADIENT_SIZE / width; | |
623 | 316 | drgrad = GRADIENT_SIZE % width; | |
624 |
2/2✓ Branch 0 taken 92130 times.
✓ Branch 1 taken 316 times.
|
92446 | for (x = 0; x < width; x++) { |
625 |
6/6✓ Branch 0 taken 77983 times.
✓ Branch 1 taken 14147 times.
✓ Branch 2 taken 48285 times.
✓ Branch 3 taken 15493 times.
✓ Branch 4 taken 15493 times.
✓ Branch 5 taken 16259 times.
|
233891 | *(p++) = |
626 |
2/2✓ Branch 0 taken 63778 times.
✓ Branch 1 taken 14205 times.
|
77983 | grad < 256 || grad >= 5 * 256 ? 255 : |
627 |
2/2✓ Branch 0 taken 16259 times.
✓ Branch 1 taken 32026 times.
|
48285 | grad >= 2 * 256 && grad < 4 * 256 ? 0 : |
628 | 15493 | grad < 2 * 256 ? 2 * 256 - 1 - grad : grad - 4 * 256; | |
629 |
6/6✓ Branch 0 taken 61666 times.
✓ Branch 1 taken 30464 times.
✓ Branch 2 taken 47519 times.
✓ Branch 3 taken 14147 times.
✓ Branch 4 taken 16107 times.
✓ Branch 5 taken 14147 times.
|
155756 | *(p++) = |
630 | grad >= 4 * 256 ? 0 : | ||
631 |
2/2✓ Branch 0 taken 16107 times.
✓ Branch 1 taken 31412 times.
|
47519 | grad >= 1 * 256 && grad < 3 * 256 ? 255 : |
632 | 16107 | grad < 1 * 256 ? grad : 4 * 256 - 1 - grad; | |
633 |
6/6✓ Branch 0 taken 62490 times.
✓ Branch 1 taken 29640 times.
✓ Branch 2 taken 46571 times.
✓ Branch 3 taken 15919 times.
✓ Branch 4 taken 15919 times.
✓ Branch 5 taken 14205 times.
|
152906 | *(p++) = |
634 | grad < 2 * 256 ? 0 : | ||
635 |
2/2✓ Branch 0 taken 14205 times.
✓ Branch 1 taken 32366 times.
|
46571 | grad >= 3 * 256 && grad < 5 * 256 ? 255 : |
636 | 14205 | grad < 3 * 256 ? grad - 2 * 256 : 6 * 256 - 1 - grad; | |
637 | 92130 | grad += dgrad; | |
638 | 92130 | rgrad += drgrad; | |
639 |
2/2✓ Branch 0 taken 15004 times.
✓ Branch 1 taken 77126 times.
|
92130 | if (rgrad >= GRADIENT_SIZE) { |
640 | 15004 | grad++; | |
641 | 15004 | rgrad -= GRADIENT_SIZE; | |
642 | } | ||
643 |
2/2✓ Branch 0 taken 225 times.
✓ Branch 1 taken 91905 times.
|
92130 | if (grad >= GRADIENT_SIZE) |
644 | 225 | grad -= GRADIENT_SIZE; | |
645 | } | ||
646 | 316 | p = p0; | |
647 |
2/2✓ Branch 0 taken 8568 times.
✓ Branch 1 taken 316 times.
|
8884 | for (y = height / 8; y > 0; y--) { |
648 | 8568 | memcpy(p+frame->linesize[0], p, 3 * width); | |
649 | 8568 | p += frame->linesize[0]; | |
650 | } | ||
651 | |||
652 | /* draw digits */ | ||
653 | 316 | seg_size = width / 80; | |
654 |
3/4✓ Branch 0 taken 291 times.
✓ Branch 1 taken 25 times.
✓ Branch 2 taken 291 times.
✗ Branch 3 not taken.
|
316 | if (seg_size >= 1 && height >= 13 * seg_size) { |
655 | 291 | int64_t p10decimals = 1; | |
656 | 291 | double time = av_q2d(test->time_base) * test->nb_frame * | |
657 | 291 | ff_exp10(test->nb_decimals); | |
658 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 291 times.
|
291 | if (time >= INT_MAX) |
659 | ✗ | return; | |
660 | |||
661 |
2/2✓ Branch 0 taken 473 times.
✓ Branch 1 taken 291 times.
|
764 | for (x = 0; x < test->nb_decimals; x++) |
662 | 473 | p10decimals *= 10; | |
663 | |||
664 | 291 | second = av_rescale_rnd(test->nb_frame * test->time_base.num, p10decimals, test->time_base.den, AV_ROUND_ZERO); | |
665 | 291 | x = width - (width - seg_size * 64) / 2; | |
666 | 291 | y = (height - seg_size * 13) / 2; | |
667 | 291 | p = data + (x*3 + y * frame->linesize[0]); | |
668 |
1/2✓ Branch 0 taken 775 times.
✗ Branch 1 not taken.
|
775 | for (i = 0; i < 8; i++) { |
669 | 775 | p -= 3 * 8 * seg_size; | |
670 | 775 | draw_digit(second % 10, p, frame->linesize[0], seg_size); | |
671 | 775 | second /= 10; | |
672 |
2/2✓ Branch 0 taken 291 times.
✓ Branch 1 taken 484 times.
|
775 | if (second == 0) |
673 | 291 | break; | |
674 | } | ||
675 | } | ||
676 | } | ||
677 | |||
678 | 24 | static av_cold int test_init(AVFilterContext *ctx) | |
679 | { | ||
680 | 24 | TestSourceContext *test = ctx->priv; | |
681 | |||
682 | 24 | test->fill_picture_fn = test_fill_picture; | |
683 | 24 | return init(ctx); | |
684 | } | ||
685 | |||
686 | const FFFilter ff_vsrc_testsrc = { | ||
687 | .p.name = "testsrc", | ||
688 | .p.description = NULL_IF_CONFIG_SMALL("Generate test pattern."), | ||
689 | .p.priv_class = &testsrc_class, | ||
690 | .priv_size = sizeof(TestSourceContext), | ||
691 | .init = test_init, | ||
692 | .uninit = uninit, | ||
693 | .activate = activate, | ||
694 | FILTER_OUTPUTS(outputs), | ||
695 | FILTER_SINGLE_PIXFMT(AV_PIX_FMT_RGB24), | ||
696 | }; | ||
697 | |||
698 | #endif /* CONFIG_TESTSRC_FILTER */ | ||
699 | |||
700 | 209428 | static void av_unused set_color(TestSourceContext *s, FFDrawColor *color, uint32_t argb) | |
701 | { | ||
702 | 209428 | uint8_t rgba[4] = { (argb >> 16) & 0xFF, | |
703 | 209428 | (argb >> 8) & 0xFF, | |
704 | (argb >> 0) & 0xFF, | ||
705 | 209428 | (argb >> 24) & 0xFF, }; | |
706 | 209428 | ff_draw_color(&s->draw, color, rgba); | |
707 | 209428 | } | |
708 | |||
709 | #if CONFIG_TESTSRC2_FILTER | ||
710 | |||
711 | static const AVOption testsrc2_options[] = { | ||
712 | COMMON_OPTIONS | ||
713 | { "alpha", "set global alpha (opacity)", OFFSET(alpha), AV_OPT_TYPE_INT, {.i64 = 255}, 0, 255, FLAGS }, | ||
714 | { NULL } | ||
715 | }; | ||
716 | |||
717 | AVFILTER_DEFINE_CLASS(testsrc2); | ||
718 | |||
719 | 190120 | static uint32_t color_gradient(unsigned index) | |
720 | { | ||
721 | 190120 | unsigned si = index & 0xFF, sd = 0xFF - si; | |
722 |
6/7✓ Branch 0 taken 31685 times.
✓ Branch 1 taken 31698 times.
✓ Branch 2 taken 31677 times.
✓ Branch 3 taken 31685 times.
✓ Branch 4 taken 31698 times.
✓ Branch 5 taken 31677 times.
✗ Branch 6 not taken.
|
190120 | switch (index >> 8) { |
723 | 31685 | case 0: return 0xFF0000 + (si << 8); | |
724 | 31698 | case 1: return 0x00FF00 + (sd << 16); | |
725 | 31677 | case 2: return 0x00FF00 + (si << 0); | |
726 | 31685 | case 3: return 0x0000FF + (sd << 8); | |
727 | 31698 | case 4: return 0x0000FF + (si << 16); | |
728 | 31677 | case 5: return 0xFF0000 + (sd << 0); | |
729 | ✗ | default: av_assert0(0); return 0; | |
730 | } | ||
731 | } | ||
732 | |||
733 | 956 | static void draw_text(TestSourceContext *s, AVFrame *frame, FFDrawColor *color, | |
734 | int x0, int y0, const uint8_t *text) | ||
735 | { | ||
736 | 956 | int x = x0; | |
737 | |||
738 |
2/2✓ Branch 0 taken 23900 times.
✓ Branch 1 taken 956 times.
|
24856 | for (; *text; text++) { |
739 |
2/2✓ Branch 0 taken 956 times.
✓ Branch 1 taken 22944 times.
|
23900 | if (*text == '\n') { |
740 | 956 | x = x0; | |
741 | 956 | y0 += 16; | |
742 | 956 | continue; | |
743 | } | ||
744 | 22944 | ff_blend_mask(&s->draw, color, frame->data, frame->linesize, | |
745 | frame->width, frame->height, | ||
746 | 22944 | avpriv_vga16_font + *text * 16, 1, 8, 16, 0, 0, x, y0); | |
747 | 22944 | x += 8; | |
748 | } | ||
749 | 956 | } | |
750 | |||
751 | 956 | static void test2_fill_picture(AVFilterContext *ctx, AVFrame *frame) | |
752 | { | ||
753 | 956 | TestSourceContext *s = ctx->priv; | |
754 | FFDrawColor color; | ||
755 | 956 | unsigned alpha = (uint32_t)s->alpha << 24; | |
756 | |||
757 | /* colored background */ | ||
758 | { | ||
759 | 956 | unsigned i, x = 0, x2; | |
760 | |||
761 | 956 | x = 0; | |
762 |
2/2✓ Branch 0 taken 5736 times.
✓ Branch 1 taken 956 times.
|
6692 | for (i = 1; i < 7; i++) { |
763 | 5736 | x2 = av_rescale(i, s->w, 6); | |
764 | 5736 | x2 = ff_draw_round_to_sub(&s->draw, 0, 0, x2); | |
765 |
2/2✓ Branch 0 taken 2868 times.
✓ Branch 1 taken 2868 times.
|
5736 | set_color(s, &color, ((i & 1) ? 0xFF0000 : 0) | |
766 |
2/2✓ Branch 0 taken 2868 times.
✓ Branch 1 taken 2868 times.
|
11472 | ((i & 2) ? 0x00FF00 : 0) | |
767 |
2/2✓ Branch 0 taken 2868 times.
✓ Branch 1 taken 2868 times.
|
5736 | ((i & 4) ? 0x0000FF : 0) | |
768 | alpha); | ||
769 | 5736 | ff_fill_rectangle(&s->draw, &color, frame->data, frame->linesize, | |
770 | 5736 | x, 0, x2 - x, frame->height); | |
771 | 5736 | x = x2; | |
772 | } | ||
773 | } | ||
774 | |||
775 | /* oblique gradient */ | ||
776 | /* note: too slow if using blending */ | ||
777 |
1/2✓ Branch 0 taken 956 times.
✗ Branch 1 not taken.
|
956 | if (s->h >= 64) { |
778 | unsigned x, dx, y0, y, g0, g; | ||
779 | |||
780 | 956 | dx = ff_draw_round_to_sub(&s->draw, 0, +1, 1); | |
781 | 956 | y0 = av_rescale_q(s->pts, s->time_base, av_make_q(2, s->h - 16)); | |
782 | 956 | g0 = av_rescale_q(s->pts, s->time_base, av_make_q(1, 128)); | |
783 |
2/2✓ Branch 0 taken 190120 times.
✓ Branch 1 taken 956 times.
|
191076 | for (x = 0; x < s->w; x += dx) { |
784 | 190120 | g = (av_rescale(x, 6 * 256, s->w) + g0) % (6 * 256); | |
785 | 190120 | set_color(s, &color, color_gradient(g) | alpha); | |
786 | 190120 | y = y0 + av_rescale(x, s->h / 2, s->w); | |
787 | 190120 | y %= 2 * (s->h - 16); | |
788 |
2/2✓ Branch 0 taken 70012 times.
✓ Branch 1 taken 120108 times.
|
190120 | if (y > s->h - 16) |
789 | 70012 | y = 2 * (s->h - 16) - y; | |
790 | 190120 | y = ff_draw_round_to_sub(&s->draw, 1, 0, y); | |
791 | 190120 | ff_fill_rectangle(&s->draw, &color, frame->data, frame->linesize, | |
792 | x, y, dx, 16); | ||
793 | } | ||
794 | } | ||
795 | |||
796 | /* top right: draw clock hands */ | ||
797 |
2/4✓ Branch 0 taken 956 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 956 times.
✗ Branch 3 not taken.
|
956 | if (s->w >= 64 && s->h >= 64) { |
798 | 956 | int l = (FFMIN(s->w, s->h) - 32) >> 1; | |
799 | 956 | int steps = FFMAX(4, l >> 5); | |
800 | 956 | int xc = (s->w >> 2) + (s->w >> 1); | |
801 | 956 | int yc = (s->h >> 2); | |
802 | 956 | int cycle = l << 2; | |
803 | int pos, xh, yh; | ||
804 | int c, i; | ||
805 | |||
806 |
2/2✓ Branch 0 taken 2868 times.
✓ Branch 1 taken 956 times.
|
3824 | for (c = 0; c < 3; c++) { |
807 | 2868 | set_color(s, &color, (0xBBBBBB ^ (0xFF << (c << 3))) | alpha); | |
808 | 2868 | pos = av_rescale_q(s->pts, s->time_base, av_make_q(64 >> (c << 1), cycle)) % cycle; | |
809 |
2/2✓ Branch 0 taken 875 times.
✓ Branch 1 taken 1993 times.
|
3743 | xh = pos < 1 * l ? pos : |
810 |
2/2✓ Branch 0 taken 409 times.
✓ Branch 1 taken 466 times.
|
1284 | pos < 2 * l ? l : |
811 |
2/2✓ Branch 0 taken 268 times.
✓ Branch 1 taken 141 times.
|
409 | pos < 3 * l ? 3 * l - pos : 0; |
812 |
2/2✓ Branch 0 taken 875 times.
✓ Branch 1 taken 1993 times.
|
3743 | yh = pos < 1 * l ? 0 : |
813 |
2/2✓ Branch 0 taken 466 times.
✓ Branch 1 taken 409 times.
|
1284 | pos < 2 * l ? pos - l : |
814 |
2/2✓ Branch 0 taken 141 times.
✓ Branch 1 taken 268 times.
|
409 | pos < 3 * l ? l : |
815 | cycle - pos; | ||
816 | 2868 | xh -= l >> 1; | |
817 | 2868 | yh -= l >> 1; | |
818 |
2/2✓ Branch 0 taken 11508 times.
✓ Branch 1 taken 2868 times.
|
14376 | for (i = 1; i <= steps; i++) { |
819 | 11508 | int x = av_rescale(xh, i, steps) + xc; | |
820 | 11508 | int y = av_rescale(yh, i, steps) + yc; | |
821 | 11508 | x = ff_draw_round_to_sub(&s->draw, 0, -1, x); | |
822 | 11508 | y = ff_draw_round_to_sub(&s->draw, 1, -1, y); | |
823 | 11508 | ff_fill_rectangle(&s->draw, &color, frame->data, frame->linesize, | |
824 | x, y, 8, 8); | ||
825 | } | ||
826 | } | ||
827 | } | ||
828 | |||
829 | /* bottom left: beating rectangles */ | ||
830 |
2/4✓ Branch 0 taken 956 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 956 times.
✗ Branch 3 not taken.
|
956 | if (s->w >= 64 && s->h >= 64) { |
831 | 956 | int l = (FFMIN(s->w, s->h) - 16) >> 2; | |
832 | 956 | int cycle = l << 3; | |
833 | 956 | int xc = (s->w >> 2); | |
834 | 956 | int yc = (s->h >> 2) + (s->h >> 1); | |
835 | 956 | int xm1 = ff_draw_round_to_sub(&s->draw, 0, -1, xc - 8); | |
836 | 956 | int xm2 = ff_draw_round_to_sub(&s->draw, 0, +1, xc + 8); | |
837 | 956 | int ym1 = ff_draw_round_to_sub(&s->draw, 1, -1, yc - 8); | |
838 | 956 | int ym2 = ff_draw_round_to_sub(&s->draw, 1, +1, yc + 8); | |
839 | int size, step, x1, x2, y1, y2; | ||
840 | |||
841 | 956 | size = av_rescale_q(s->pts, s->time_base, av_make_q(4, cycle)); | |
842 | 956 | step = size / l; | |
843 | 956 | size %= l; | |
844 |
2/2✓ Branch 0 taken 410 times.
✓ Branch 1 taken 546 times.
|
956 | if (step & 1) |
845 | 410 | size = l - size; | |
846 | 956 | step = (step >> 1) & 3; | |
847 | 956 | set_color(s, &color, 0xFF808080); | |
848 | 956 | x1 = ff_draw_round_to_sub(&s->draw, 0, -1, xc - 4 - size); | |
849 | 956 | x2 = ff_draw_round_to_sub(&s->draw, 0, +1, xc + 4 + size); | |
850 | 956 | y1 = ff_draw_round_to_sub(&s->draw, 1, -1, yc - 4 - size); | |
851 | 956 | y2 = ff_draw_round_to_sub(&s->draw, 1, +1, yc + 4 + size); | |
852 |
4/4✓ Branch 0 taken 530 times.
✓ Branch 1 taken 426 times.
✓ Branch 2 taken 156 times.
✓ Branch 3 taken 374 times.
|
956 | if (step == 0 || step == 2) |
853 | 582 | ff_fill_rectangle(&s->draw, &color, frame->data, frame->linesize, | |
854 | x1, ym1, x2 - x1, ym2 - ym1); | ||
855 |
4/4✓ Branch 0 taken 723 times.
✓ Branch 1 taken 233 times.
✓ Branch 2 taken 156 times.
✓ Branch 3 taken 567 times.
|
956 | if (step == 1 || step == 2) |
856 | 389 | ff_fill_rectangle(&s->draw, &color, frame->data, frame->linesize, | |
857 | xm1, y1, xm2 - xm1, y2 - y1); | ||
858 |
2/2✓ Branch 0 taken 141 times.
✓ Branch 1 taken 815 times.
|
956 | if (step == 3) |
859 | 141 | ff_fill_rectangle(&s->draw, &color, frame->data, frame->linesize, | |
860 | x1, y1, x2 - x1, y2 - y1); | ||
861 | } | ||
862 | |||
863 | /* bottom right: checker with random noise */ | ||
864 | { | ||
865 | 956 | unsigned xmin = av_rescale(5, s->w, 8); | |
866 | 956 | unsigned xmax = av_rescale(7, s->w, 8); | |
867 | 956 | unsigned ymin = av_rescale(5, s->h, 8); | |
868 | 956 | unsigned ymax = av_rescale(7, s->h, 8); | |
869 | unsigned x, y, i, r; | ||
870 | uint8_t alpha[256]; | ||
871 | |||
872 | 956 | r = s->pts; | |
873 |
2/2✓ Branch 0 taken 2881 times.
✓ Branch 1 taken 956 times.
|
3837 | for (y = ymin; y + 15 < ymax; y += 16) { |
874 |
2/2✓ Branch 0 taken 14670 times.
✓ Branch 1 taken 2881 times.
|
17551 | for (x = xmin; x + 15 < xmax; x += 16) { |
875 |
2/2✓ Branch 0 taken 7790 times.
✓ Branch 1 taken 6880 times.
|
14670 | if ((x ^ y) & 16) |
876 | 7790 | continue; | |
877 |
2/2✓ Branch 0 taken 1761280 times.
✓ Branch 1 taken 6880 times.
|
1768160 | for (i = 0; i < 256; i++) { |
878 | 1761280 | r = r * 1664525 + 1013904223; | |
879 | 1761280 | alpha[i] = r >> 24; | |
880 | } | ||
881 | 6880 | set_color(s, &color, 0xFF00FF80); | |
882 | 6880 | ff_blend_mask(&s->draw, &color, frame->data, frame->linesize, | |
883 | frame->width, frame->height, | ||
884 | alpha, 16, 16, 16, 3, 0, x, y); | ||
885 | } | ||
886 | } | ||
887 | } | ||
888 | |||
889 | /* bouncing square */ | ||
890 |
2/4✓ Branch 0 taken 956 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 956 times.
✗ Branch 3 not taken.
|
956 | if (s->w >= 16 && s->h >= 16) { |
891 | 956 | unsigned w = s->w - 8; | |
892 | 956 | unsigned h = s->h - 8; | |
893 | 956 | unsigned x = av_rescale_q(s->pts, s->time_base, av_make_q(233, 55 * w)) % (w << 1); | |
894 | 956 | unsigned y = av_rescale_q(s->pts, s->time_base, av_make_q(233, 89 * h)) % (h << 1); | |
895 |
2/2✓ Branch 0 taken 238 times.
✓ Branch 1 taken 718 times.
|
956 | if (x > w) |
896 | 238 | x = (w << 1) - x; | |
897 |
2/2✓ Branch 0 taken 308 times.
✓ Branch 1 taken 648 times.
|
956 | if (y > h) |
898 | 308 | y = (h << 1) - y; | |
899 | 956 | x = ff_draw_round_to_sub(&s->draw, 0, -1, x); | |
900 | 956 | y = ff_draw_round_to_sub(&s->draw, 1, -1, y); | |
901 | 956 | set_color(s, &color, 0xFF8000FF); | |
902 | 956 | ff_fill_rectangle(&s->draw, &color, frame->data, frame->linesize, | |
903 | x, y, 8, 8); | ||
904 | } | ||
905 | |||
906 | /* top right: draw frame time and frame number */ | ||
907 | { | ||
908 | char buf[256]; | ||
909 | unsigned time; | ||
910 | |||
911 | 956 | time = av_rescale_q(s->pts, s->time_base, av_make_q(1, 1000)) % 86400000; | |
912 | 956 | set_color(s, &color, 0xC0000000); | |
913 | 956 | ff_blend_rectangle(&s->draw, &color, frame->data, frame->linesize, | |
914 | frame->width, frame->height, | ||
915 | 2, 2, 100, 36); | ||
916 | 956 | set_color(s, &color, 0xFFFF8000); | |
917 | 956 | snprintf(buf, sizeof(buf), "%02d:%02d:%02d.%03d\n%12"PRIi64, | |
918 | 956 | time / 3600000, (time / 60000) % 60, (time / 1000) % 60, | |
919 | time % 1000, s->pts); | ||
920 | 956 | draw_text(s, frame, &color, 4, 4, buf); | |
921 | } | ||
922 | 956 | } | |
923 | 82 | static av_cold int test2_init(AVFilterContext *ctx) | |
924 | { | ||
925 | 82 | TestSourceContext *s = ctx->priv; | |
926 | |||
927 | 82 | s->fill_picture_fn = test2_fill_picture; | |
928 | 82 | return init(ctx); | |
929 | } | ||
930 | |||
931 | 41 | static int test2_query_formats(const AVFilterContext *ctx, | |
932 | AVFilterFormatsConfig **cfg_in, | ||
933 | AVFilterFormatsConfig **cfg_out) | ||
934 | { | ||
935 | 41 | return ff_set_common_formats2(ctx, cfg_in, cfg_out, ff_draw_supported_pixel_formats(0)); | |
936 | } | ||
937 | |||
938 | 41 | static int test2_config_props(AVFilterLink *inlink) | |
939 | { | ||
940 | 41 | AVFilterContext *ctx = inlink->src; | |
941 | 41 | TestSourceContext *s = ctx->priv; | |
942 | |||
943 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 41 times.
|
41 | av_assert0(ff_draw_init2(&s->draw, inlink->format, inlink->colorspace, |
944 | inlink->color_range, 0) >= 0); | ||
945 | 41 | s->w = ff_draw_round_to_sub(&s->draw, 0, -1, s->w); | |
946 | 41 | s->h = ff_draw_round_to_sub(&s->draw, 1, -1, s->h); | |
947 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 41 times.
|
41 | if (av_image_check_size(s->w, s->h, 0, ctx) < 0) |
948 | ✗ | return AVERROR(EINVAL); | |
949 | 41 | return config_props(inlink); | |
950 | } | ||
951 | |||
952 | static const AVFilterPad avfilter_vsrc_testsrc2_outputs[] = { | ||
953 | { | ||
954 | .name = "default", | ||
955 | .type = AVMEDIA_TYPE_VIDEO, | ||
956 | .config_props = test2_config_props, | ||
957 | }, | ||
958 | }; | ||
959 | |||
960 | const FFFilter ff_vsrc_testsrc2 = { | ||
961 | .p.name = "testsrc2", | ||
962 | .p.description = NULL_IF_CONFIG_SMALL("Generate another test pattern."), | ||
963 | .p.priv_class = &testsrc2_class, | ||
964 | .priv_size = sizeof(TestSourceContext), | ||
965 | .init = test2_init, | ||
966 | .uninit = uninit, | ||
967 | .activate = activate, | ||
968 | FILTER_OUTPUTS(avfilter_vsrc_testsrc2_outputs), | ||
969 | FILTER_QUERY_FUNC2(test2_query_formats), | ||
970 | }; | ||
971 | |||
972 | #endif /* CONFIG_TESTSRC2_FILTER */ | ||
973 | |||
974 | #if CONFIG_RGBTESTSRC_FILTER | ||
975 | |||
976 | static const AVOption rgbtestsrc_options[] = { | ||
977 | COMMON_OPTIONS | ||
978 | { "complement", "set complement colors", OFFSET(complement), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS }, | ||
979 | { "co", "set complement colors", OFFSET(complement), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS }, | ||
980 | { NULL } | ||
981 | }; | ||
982 | |||
983 | AVFILTER_DEFINE_CLASS(rgbtestsrc); | ||
984 | |||
985 | #define R 0 | ||
986 | #define G 1 | ||
987 | #define B 2 | ||
988 | #define A 3 | ||
989 | |||
990 | 48691200 | static void rgbtest_put_pixel(uint8_t *dstp[4], int dst_linesizep[4], | |
991 | int x, int y, unsigned r, unsigned g, unsigned b, unsigned a, enum AVPixelFormat fmt, | ||
992 | uint8_t rgba_map[4]) | ||
993 | { | ||
994 | 48691200 | const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt); | |
995 | 48691200 | uint8_t *dst = dstp[0]; | |
996 | 48691200 | ptrdiff_t dst_linesize = dst_linesizep[0]; | |
997 | uint32_t v; | ||
998 | uint64_t v16; | ||
999 | uint8_t *p; | ||
1000 | uint16_t *p16; | ||
1001 | |||
1002 |
8/16✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 9302016 times.
✓ Branch 7 taken 9225216 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 76800 times.
✓ Branch 10 taken 76800 times.
✓ Branch 11 taken 76800 times.
✓ Branch 12 taken 9302016 times.
✓ Branch 13 taken 76800 times.
✓ Branch 14 taken 20554752 times.
✗ Branch 15 not taken.
|
48691200 | switch (fmt) { |
1003 | ✗ | case AV_PIX_FMT_BGR444: ((uint16_t*)(dst + y*dst_linesize))[x] = ((r >> 4) << 8) | ((g >> 4) << 4) | (b >> 4); break; | |
1004 | ✗ | case AV_PIX_FMT_RGB444: ((uint16_t*)(dst + y*dst_linesize))[x] = ((b >> 4) << 8) | ((g >> 4) << 4) | (r >> 4); break; | |
1005 | ✗ | case AV_PIX_FMT_BGR555: ((uint16_t*)(dst + y*dst_linesize))[x] = ((r>>3)<<10) | ((g>>3)<<5) | (b>>3); break; | |
1006 | ✗ | case AV_PIX_FMT_RGB555: ((uint16_t*)(dst + y*dst_linesize))[x] = ((b>>3)<<10) | ((g>>3)<<5) | (r>>3); break; | |
1007 | ✗ | case AV_PIX_FMT_BGR565: ((uint16_t*)(dst + y*dst_linesize))[x] = ((r>>3)<<11) | ((g>>2)<<5) | (b>>3); break; | |
1008 | ✗ | case AV_PIX_FMT_RGB565: ((uint16_t*)(dst + y*dst_linesize))[x] = ((b>>3)<<11) | ((g>>2)<<5) | (r>>3); break; | |
1009 | 9302016 | case AV_PIX_FMT_RGB24: | |
1010 | case AV_PIX_FMT_BGR24: | ||
1011 | 9302016 | v = (r << (rgba_map[R]*8)) + (g << (rgba_map[G]*8)) + (b << (rgba_map[B]*8)); | |
1012 | 9302016 | p = dst + 3*x + y*dst_linesize; | |
1013 | 9302016 | AV_WL24(p, v); | |
1014 | 9302016 | break; | |
1015 | 9225216 | case AV_PIX_FMT_RGB48: | |
1016 | case AV_PIX_FMT_BGR48: | ||
1017 | 9225216 | v16 = ((uint64_t)r << (rgba_map[R]*16)) + ((uint64_t)g << (rgba_map[G]*16)) + ((uint64_t)b << (rgba_map[B]*16)); | |
1018 | 9225216 | p16 = (uint16_t *)(dst + 6*x + y*dst_linesize); | |
1019 | 9225216 | *p16++ = v16 >> 32; | |
1020 | 9225216 | *p16++ = v16 >> 16; | |
1021 | 9225216 | *p16++ = v16; | |
1022 | 9225216 | break; | |
1023 | ✗ | case AV_PIX_FMT_RGBA64: | |
1024 | case AV_PIX_FMT_BGRA64: | ||
1025 | ✗ | v16 = ((uint64_t)r << (rgba_map[R]*16)) + ((uint64_t)g << (rgba_map[G]*16)) + ((uint64_t)b << (rgba_map[B]*16)); | |
1026 | ✗ | p16 = (uint16_t *)(dst + 8*x + y*dst_linesize); | |
1027 | ✗ | *p16++ = v16 >> 32; | |
1028 | ✗ | *p16++ = v16 >> 16; | |
1029 | ✗ | *p16++ = v16; | |
1030 | ✗ | *p16++ = a; | |
1031 | ✗ | break; | |
1032 | 76800 | case AV_PIX_FMT_RGBA: | |
1033 | case AV_PIX_FMT_BGRA: | ||
1034 | case AV_PIX_FMT_ARGB: | ||
1035 | case AV_PIX_FMT_ABGR: | ||
1036 | 76800 | v = (r << (rgba_map[R]*8)) + (g << (rgba_map[G]*8)) + (b << (rgba_map[B]*8)) + (a << (rgba_map[A]*8)); | |
1037 | 76800 | p = dst + 4*x + y*dst_linesize; | |
1038 | 76800 | AV_WL32A(p, v); | |
1039 | 76800 | break; | |
1040 | 76800 | case AV_PIX_FMT_X2RGB10LE: | |
1041 | case AV_PIX_FMT_X2BGR10LE: | ||
1042 | 76800 | v = (r << ((desc->comp[0].offset*8) + desc->comp[0].shift)) + | |
1043 | 76800 | (g << ((desc->comp[1].offset*8) + desc->comp[1].shift)) + | |
1044 | 76800 | (b << ((desc->comp[2].offset*8) + desc->comp[2].shift)) + | |
1045 | 76800 | (3U << ((desc->comp[3].offset*8) + desc->comp[3].shift)); | |
1046 | 76800 | p = dst + 4*x + y*dst_linesize; | |
1047 | 76800 | AV_WL32A(p, v); | |
1048 | 76800 | break; | |
1049 | 76800 | case AV_PIX_FMT_GBRAP: | |
1050 | 76800 | p = dstp[3] + x + y * dst_linesizep[3]; | |
1051 | 76800 | p[0] = a; | |
1052 | // fall-through | ||
1053 | 9378816 | case AV_PIX_FMT_GBRP: | |
1054 | 9378816 | p = dstp[0] + x + y * dst_linesize; | |
1055 | 9378816 | p[0] = g; | |
1056 | 9378816 | p = dstp[1] + x + y * dst_linesizep[1]; | |
1057 | 9378816 | p[0] = b; | |
1058 | 9378816 | p = dstp[2] + x + y * dst_linesizep[2]; | |
1059 | 9378816 | p[0] = r; | |
1060 | 9378816 | break; | |
1061 | 76800 | case AV_PIX_FMT_GBRAP10: | |
1062 | case AV_PIX_FMT_GBRAP12: | ||
1063 | case AV_PIX_FMT_GBRAP14: | ||
1064 | case AV_PIX_FMT_GBRAP16: | ||
1065 | 76800 | p16 = (uint16_t *)(dstp[3] + x*2 + y * dst_linesizep[3]); | |
1066 | 76800 | p16[0] = a; | |
1067 | // fall-through | ||
1068 | 20631552 | case AV_PIX_FMT_GBRP9: | |
1069 | case AV_PIX_FMT_GBRP10: | ||
1070 | case AV_PIX_FMT_GBRP12: | ||
1071 | case AV_PIX_FMT_GBRP14: | ||
1072 | case AV_PIX_FMT_GBRP16: | ||
1073 | 20631552 | p16 = (uint16_t *)(dstp[0] + x*2 + y * dst_linesizep[0]); | |
1074 | 20631552 | p16[0] = g; | |
1075 | 20631552 | p16 = (uint16_t *)(dstp[1] + x*2 + y * dst_linesizep[1]); | |
1076 | 20631552 | p16[0] = b; | |
1077 | 20631552 | p16 = (uint16_t *)(dstp[2] + x*2 + y * dst_linesizep[2]); | |
1078 | 20631552 | p16[0] = r; | |
1079 | 20631552 | break; | |
1080 | } | ||
1081 | 48691200 | } | |
1082 | |||
1083 | ✗ | static void rgbtest_fill_picture_complement(AVFilterContext *ctx, AVFrame *frame) | |
1084 | { | ||
1085 | ✗ | TestSourceContext *test = ctx->priv; | |
1086 | ✗ | int x, y, w = frame->width, h = frame->height; | |
1087 | |||
1088 | ✗ | for (y = 0; y < h; y++) { | |
1089 | ✗ | for (x = 0; x < w; x++) { | |
1090 | ✗ | int c = (1 << FFMAX(test->depth, 8))*x/w; | |
1091 | ✗ | int r = 0, g = 0, b = 0; | |
1092 | |||
1093 | ✗ | if (6*y < h ) r = c; | |
1094 | ✗ | else if (6*y < 2*h) g = c, b = c; | |
1095 | ✗ | else if (6*y < 3*h) g = c; | |
1096 | ✗ | else if (6*y < 4*h) r = c, b = c; | |
1097 | ✗ | else if (6*y < 5*h) b = c; | |
1098 | ✗ | else r = c, g = c; | |
1099 | |||
1100 | ✗ | rgbtest_put_pixel(frame->data, frame->linesize, x, y, r, g, b, c, | |
1101 | ✗ | ctx->outputs[0]->format, test->rgba_map); | |
1102 | } | ||
1103 | } | ||
1104 | ✗ | } | |
1105 | |||
1106 | 482 | static void rgbtest_fill_picture(AVFilterContext *ctx, AVFrame *frame) | |
1107 | { | ||
1108 | 482 | TestSourceContext *test = ctx->priv; | |
1109 | 482 | int x, y, w = frame->width, h = frame->height; | |
1110 | |||
1111 |
2/2✓ Branch 0 taken 138480 times.
✓ Branch 1 taken 482 times.
|
138962 | for (y = 0; y < h; y++) { |
1112 |
2/2✓ Branch 0 taken 48691200 times.
✓ Branch 1 taken 138480 times.
|
48829680 | for (x = 0; x < w; x++) { |
1113 | 48691200 | int c = (1 << FFMAX(test->depth, 8))*x/w; | |
1114 | 48691200 | int r = 0, g = 0, b = 0; | |
1115 | |||
1116 |
2/2✓ Branch 0 taken 16230400 times.
✓ Branch 1 taken 32460800 times.
|
48691200 | if (3*y < h ) r = c; |
1117 |
2/2✓ Branch 0 taken 16230400 times.
✓ Branch 1 taken 16230400 times.
|
32460800 | else if (3*y < 2*h) g = c; |
1118 | 16230400 | else b = c; | |
1119 | |||
1120 | 48691200 | rgbtest_put_pixel(frame->data, frame->linesize, x, y, r, g, b, c, | |
1121 | 48691200 | ctx->outputs[0]->format, test->rgba_map); | |
1122 | } | ||
1123 | } | ||
1124 | 482 | } | |
1125 | |||
1126 | 964 | static av_cold int rgbtest_init(AVFilterContext *ctx) | |
1127 | { | ||
1128 | 964 | TestSourceContext *test = ctx->priv; | |
1129 | |||
1130 | 964 | test->draw_once = 1; | |
1131 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 964 times.
|
964 | test->fill_picture_fn = test->complement ? rgbtest_fill_picture_complement : rgbtest_fill_picture; |
1132 | 964 | return init(ctx); | |
1133 | } | ||
1134 | |||
1135 | static const enum AVPixelFormat rgbtest_pix_fmts[] = { | ||
1136 | AV_PIX_FMT_RGBA, AV_PIX_FMT_ARGB, AV_PIX_FMT_BGRA, AV_PIX_FMT_ABGR, | ||
1137 | AV_PIX_FMT_BGR24, AV_PIX_FMT_RGB24, | ||
1138 | AV_PIX_FMT_RGB444, AV_PIX_FMT_BGR444, | ||
1139 | AV_PIX_FMT_RGB565, AV_PIX_FMT_BGR565, | ||
1140 | AV_PIX_FMT_RGB555, AV_PIX_FMT_BGR555, | ||
1141 | AV_PIX_FMT_RGB48, AV_PIX_FMT_BGR48, | ||
1142 | AV_PIX_FMT_RGBA64, AV_PIX_FMT_BGRA64, | ||
1143 | AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, | ||
1144 | AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16, | ||
1145 | AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRAP10, | ||
1146 | AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRAP14, AV_PIX_FMT_GBRAP16, | ||
1147 | AV_PIX_FMT_X2RGB10LE, AV_PIX_FMT_X2BGR10LE, | ||
1148 | AV_PIX_FMT_NONE | ||
1149 | }; | ||
1150 | |||
1151 | 482 | static int rgbtest_config_props(AVFilterLink *outlink) | |
1152 | { | ||
1153 | 482 | TestSourceContext *test = outlink->src->priv; | |
1154 | 482 | const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(outlink->format); | |
1155 | |||
1156 | 482 | test->depth = desc->comp[0].depth; | |
1157 | 482 | ff_fill_rgba_map(test->rgba_map, outlink->format); | |
1158 | 482 | return config_props(outlink); | |
1159 | } | ||
1160 | |||
1161 | static const AVFilterPad avfilter_vsrc_rgbtestsrc_outputs[] = { | ||
1162 | { | ||
1163 | .name = "default", | ||
1164 | .type = AVMEDIA_TYPE_VIDEO, | ||
1165 | .config_props = rgbtest_config_props, | ||
1166 | }, | ||
1167 | }; | ||
1168 | |||
1169 | const FFFilter ff_vsrc_rgbtestsrc = { | ||
1170 | .p.name = "rgbtestsrc", | ||
1171 | .p.description = NULL_IF_CONFIG_SMALL("Generate RGB test pattern."), | ||
1172 | .p.priv_class = &rgbtestsrc_class, | ||
1173 | .priv_size = sizeof(TestSourceContext), | ||
1174 | .init = rgbtest_init, | ||
1175 | .uninit = uninit, | ||
1176 | .activate = activate, | ||
1177 | FILTER_OUTPUTS(avfilter_vsrc_rgbtestsrc_outputs), | ||
1178 | FILTER_PIXFMTS_ARRAY(rgbtest_pix_fmts), | ||
1179 | }; | ||
1180 | |||
1181 | #undef R | ||
1182 | #undef G | ||
1183 | #undef B | ||
1184 | #undef A | ||
1185 | |||
1186 | #endif /* CONFIG_RGBTESTSRC_FILTER */ | ||
1187 | |||
1188 | #if CONFIG_YUVTESTSRC_FILTER | ||
1189 | |||
1190 | #define Y 0 | ||
1191 | #define U 1 | ||
1192 | #define V 2 | ||
1193 | #define A 3 | ||
1194 | |||
1195 | 58454016 | static void yuvtest_put_pixel(uint8_t *dstp[4], int dst_linesizep[4], | |
1196 | int i, int j, unsigned y, unsigned u, unsigned v, unsigned a, enum AVPixelFormat fmt, | ||
1197 | uint8_t ayuv_map[4]) | ||
1198 | { | ||
1199 | 58454016 | const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt); | |
1200 | uint32_t n; | ||
1201 | |||
1202 |
11/14✓ Branch 0 taken 76800 times.
✓ Branch 1 taken 153600 times.
✓ Branch 2 taken 153600 times.
✓ Branch 3 taken 76800 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 153600 times.
✓ Branch 6 taken 76800 times.
✓ Branch 7 taken 9302016 times.
✓ Branch 8 taken 76800 times.
✓ Branch 9 taken 18527232 times.
✓ Branch 10 taken 9302016 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 20554752 times.
✗ Branch 13 not taken.
|
58454016 | switch (fmt) { |
1203 | 76800 | case AV_PIX_FMT_VYU444: | |
1204 | 76800 | n = (y << (ayuv_map[Y]*8)) + (u << (ayuv_map[U]*8)) + (v << (ayuv_map[V]*8)); | |
1205 | 76800 | AV_WL24(&dstp[0][i*3 + j*dst_linesizep[0]], n); | |
1206 | 76800 | break; | |
1207 | 153600 | case AV_PIX_FMT_V30XLE: | |
1208 | case AV_PIX_FMT_XV30LE: | ||
1209 | 153600 | n = (y << ((desc->comp[0].offset*8) + desc->comp[0].shift)) + | |
1210 | 153600 | (u << ((desc->comp[1].offset*8) + desc->comp[1].shift)) + | |
1211 | 153600 | (v << ((desc->comp[2].offset*8) + desc->comp[2].shift)) + | |
1212 | 153600 | (3U << ((desc->comp[3].offset*8) + desc->comp[3].shift)); | |
1213 | 153600 | AV_WL32A(&dstp[0][i*4 + j*dst_linesizep[0]], n); | |
1214 | 153600 | break; | |
1215 | 153600 | case AV_PIX_FMT_XV36: | |
1216 | case AV_PIX_FMT_XV48: | ||
1217 | 153600 | a = UINT16_MAX; | |
1218 | // fall-through | ||
1219 | 230400 | case AV_PIX_FMT_AYUV64: | |
1220 | 230400 | AV_WN16A(&dstp[0][i*8 + ayuv_map[Y]*2 + j*dst_linesizep[0]], y << desc->comp[0].shift); | |
1221 | 230400 | AV_WN16A(&dstp[0][i*8 + ayuv_map[U]*2 + j*dst_linesizep[0]], u << desc->comp[1].shift); | |
1222 | 230400 | AV_WN16A(&dstp[0][i*8 + ayuv_map[V]*2 + j*dst_linesizep[0]], v << desc->comp[2].shift); | |
1223 | 230400 | AV_WN16A(&dstp[0][i*8 + ayuv_map[A]*2 + j*dst_linesizep[0]], a << desc->comp[3].shift); | |
1224 | 230400 | break; | |
1225 | ✗ | case AV_PIX_FMT_VUYX: | |
1226 | ✗ | a = UINT8_MAX; | |
1227 | // fall-through | ||
1228 | 153600 | case AV_PIX_FMT_UYVA: | |
1229 | case AV_PIX_FMT_VUYA: | ||
1230 | case AV_PIX_FMT_AYUV: | ||
1231 | 153600 | n = (y << (ayuv_map[Y]*8)) + (u << (ayuv_map[U]*8)) + (v << (ayuv_map[V]*8)) + (a << (ayuv_map[A]*8)); | |
1232 | 153600 | AV_WL32A(&dstp[0][i*4 + j*dst_linesizep[0]], n); | |
1233 | 153600 | break; | |
1234 | 76800 | case AV_PIX_FMT_YUVA444P: | |
1235 | 76800 | dstp[3][i + j*dst_linesizep[3]] = a; | |
1236 | // fall-through | ||
1237 | 9378816 | case AV_PIX_FMT_YUV444P: | |
1238 | case AV_PIX_FMT_YUVJ444P: | ||
1239 | 9378816 | dstp[0][i + j*dst_linesizep[0]] = y; | |
1240 | 9378816 | dstp[1][i + j*dst_linesizep[1]] = u; | |
1241 | 9378816 | dstp[2][i + j*dst_linesizep[2]] = v; | |
1242 | 9378816 | break; | |
1243 | 76800 | case AV_PIX_FMT_YUVA444P9: | |
1244 | case AV_PIX_FMT_YUVA444P10: | ||
1245 | case AV_PIX_FMT_YUVA444P12: | ||
1246 | case AV_PIX_FMT_YUVA444P16: | ||
1247 | 76800 | AV_WN16A(&dstp[3][i*2 + j*dst_linesizep[3]], a); | |
1248 | // fall-through | ||
1249 | 18604032 | case AV_PIX_FMT_YUV444P9: | |
1250 | case AV_PIX_FMT_YUV444P10: | ||
1251 | case AV_PIX_FMT_YUV444P12: | ||
1252 | case AV_PIX_FMT_YUV444P14: | ||
1253 | case AV_PIX_FMT_YUV444P16: | ||
1254 | 18604032 | AV_WN16A(&dstp[0][i*2 + j*dst_linesizep[0]], y); | |
1255 | 18604032 | AV_WN16A(&dstp[1][i*2 + j*dst_linesizep[1]], u); | |
1256 | 18604032 | AV_WN16A(&dstp[2][i*2 + j*dst_linesizep[2]], v); | |
1257 | 18604032 | break; | |
1258 | 9302016 | case AV_PIX_FMT_NV24: | |
1259 | 9302016 | dstp[0][i + j*dst_linesizep[0] + 0] = y; | |
1260 | 9302016 | dstp[1][i*2 + j*dst_linesizep[1] + 0] = u; | |
1261 | 9302016 | dstp[1][i*2 + j*dst_linesizep[1] + 1] = v; | |
1262 | 9302016 | break; | |
1263 | ✗ | case AV_PIX_FMT_NV42: | |
1264 | ✗ | dstp[0][i + j*dst_linesizep[0] + 0] = y; | |
1265 | ✗ | dstp[1][i*2 + j*dst_linesizep[1] + 1] = u; | |
1266 | ✗ | dstp[1][i*2 + j*dst_linesizep[1] + 0] = v; | |
1267 | ✗ | break; | |
1268 | 20554752 | case AV_PIX_FMT_P410: | |
1269 | case AV_PIX_FMT_P412: | ||
1270 | case AV_PIX_FMT_P416: | ||
1271 | 20554752 | AV_WN16A(&dstp[0][i*2 + j*dst_linesizep[0] + 0], y << (16 - desc->comp[0].depth)); | |
1272 | 20554752 | AV_WN16A(&dstp[1][i*4 + j*dst_linesizep[1] + 0], u << (16 - desc->comp[1].depth)); | |
1273 | 20554752 | AV_WN16A(&dstp[1][i*4 + j*dst_linesizep[1] + 2], v << (16 - desc->comp[1].depth)); | |
1274 | 20554752 | break; | |
1275 | } | ||
1276 | 58454016 | } | |
1277 | |||
1278 | 580 | static void yuvtest_fill_picture(AVFilterContext *ctx, AVFrame *frame) | |
1279 | { | ||
1280 | 580 | TestSourceContext *test = ctx->priv; | |
1281 | 580 | int i, j, w = frame->width, h = frame->height; | |
1282 | 580 | const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(ctx->outputs[0]->format); | |
1283 | 580 | const int factor = 1 << desc->comp[0].depth; | |
1284 | 580 | const int mid = 1 << (desc->comp[0].depth - 1); | |
1285 | |||
1286 |
2/2✓ Branch 0 taken 166368 times.
✓ Branch 1 taken 580 times.
|
166948 | for (j = 0; j < h; j++) { |
1287 |
2/2✓ Branch 0 taken 58454016 times.
✓ Branch 1 taken 166368 times.
|
58620384 | for (i = 0; i < w; i++) { |
1288 | 58454016 | int c = factor * i / w; | |
1289 | 58454016 | int y = mid, u = mid, v = mid; | |
1290 | |||
1291 |
2/2✓ Branch 0 taken 19484672 times.
✓ Branch 1 taken 38969344 times.
|
58454016 | if (3*j < h ) y = c; |
1292 |
2/2✓ Branch 0 taken 19484672 times.
✓ Branch 1 taken 19484672 times.
|
38969344 | else if (3*j < 2*h) u = c; |
1293 | 19484672 | else v = c; | |
1294 | |||
1295 | 58454016 | yuvtest_put_pixel(frame->data, frame->linesize, i, j, y, u, v, c, | |
1296 | 58454016 | ctx->outputs[0]->format, test->ayuv_map); | |
1297 | } | ||
1298 | } | ||
1299 | 580 | } | |
1300 | |||
1301 | 1160 | static av_cold int yuvtest_init(AVFilterContext *ctx) | |
1302 | { | ||
1303 | 1160 | TestSourceContext *test = ctx->priv; | |
1304 | |||
1305 | 1160 | test->draw_once = 1; | |
1306 | 1160 | test->fill_picture_fn = yuvtest_fill_picture; | |
1307 | 1160 | return init(ctx); | |
1308 | } | ||
1309 | |||
1310 | static const enum AVPixelFormat yuvtest_pix_fmts[] = { | ||
1311 | AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVJ444P, | ||
1312 | AV_PIX_FMT_YUV444P9, AV_PIX_FMT_YUV444P10, | ||
1313 | AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV444P14, | ||
1314 | AV_PIX_FMT_YUV444P16, AV_PIX_FMT_VYU444, | ||
1315 | AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUVA444P9, | ||
1316 | AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_YUVA444P12, AV_PIX_FMT_YUVA444P16, | ||
1317 | AV_PIX_FMT_AYUV, AV_PIX_FMT_UYVA, AV_PIX_FMT_AYUV64, | ||
1318 | AV_PIX_FMT_VUYA, AV_PIX_FMT_VUYX, AV_PIX_FMT_XV48, | ||
1319 | AV_PIX_FMT_XV30LE, AV_PIX_FMT_V30XLE, AV_PIX_FMT_XV36, | ||
1320 | AV_PIX_FMT_NV24, AV_PIX_FMT_NV42, | ||
1321 | AV_PIX_FMT_P410, AV_PIX_FMT_P412, AV_PIX_FMT_P416, | ||
1322 | AV_PIX_FMT_NONE | ||
1323 | }; | ||
1324 | |||
1325 | 580 | static int yuvtest_config_props(AVFilterLink *outlink) | |
1326 | { | ||
1327 | 580 | TestSourceContext *test = outlink->src->priv; | |
1328 | |||
1329 | 580 | ff_fill_ayuv_map(test->ayuv_map, outlink->format); | |
1330 | 580 | return config_props(outlink); | |
1331 | } | ||
1332 | |||
1333 | static const AVFilterPad avfilter_vsrc_yuvtestsrc_outputs[] = { | ||
1334 | { | ||
1335 | .name = "default", | ||
1336 | .type = AVMEDIA_TYPE_VIDEO, | ||
1337 | .config_props = yuvtest_config_props, | ||
1338 | }, | ||
1339 | }; | ||
1340 | |||
1341 | const FFFilter ff_vsrc_yuvtestsrc = { | ||
1342 | .p.name = "yuvtestsrc", | ||
1343 | .p.description = NULL_IF_CONFIG_SMALL("Generate YUV test pattern."), | ||
1344 | .p.priv_class = &nullsrc_yuvtestsrc_class, | ||
1345 | .priv_size = sizeof(TestSourceContext), | ||
1346 | .init = yuvtest_init, | ||
1347 | .uninit = uninit, | ||
1348 | .activate = activate, | ||
1349 | FILTER_OUTPUTS(avfilter_vsrc_yuvtestsrc_outputs), | ||
1350 | FILTER_PIXFMTS_ARRAY(yuvtest_pix_fmts), | ||
1351 | }; | ||
1352 | |||
1353 | #undef Y | ||
1354 | #undef U | ||
1355 | #undef V | ||
1356 | #undef A | ||
1357 | |||
1358 | #endif /* CONFIG_YUVTESTSRC_FILTER */ | ||
1359 | |||
1360 | #if CONFIG_PAL75BARS_FILTER || CONFIG_PAL100BARS_FILTER || CONFIG_SMPTEBARS_FILTER || CONFIG_SMPTEHDBARS_FILTER | ||
1361 | |||
1362 | static const uint8_t rainbow[7][4] = { | ||
1363 | { 180, 128, 128, 255 }, /* 75% white */ | ||
1364 | { 162, 44, 142, 255 }, /* 75% yellow */ | ||
1365 | { 131, 156, 44, 255 }, /* 75% cyan */ | ||
1366 | { 112, 72, 58, 255 }, /* 75% green */ | ||
1367 | { 84, 184, 198, 255 }, /* 75% magenta */ | ||
1368 | { 65, 100, 212, 255 }, /* 75% red */ | ||
1369 | { 35, 212, 114, 255 }, /* 75% blue */ | ||
1370 | }; | ||
1371 | |||
1372 | static const uint8_t rainbow100[7][4] = { | ||
1373 | { 235, 128, 128, 255 }, /* 100% white */ | ||
1374 | { 210, 16, 146, 255 }, /* 100% yellow */ | ||
1375 | { 170, 166, 16, 255 }, /* 100% cyan */ | ||
1376 | { 145, 54, 34, 255 }, /* 100% green */ | ||
1377 | { 106, 202, 222, 255 }, /* 100% magenta */ | ||
1378 | { 81, 90, 240, 255 }, /* 100% red */ | ||
1379 | { 41, 240, 110, 255 }, /* 100% blue */ | ||
1380 | }; | ||
1381 | |||
1382 | static const uint8_t rainbowhd[7][4] = { | ||
1383 | { 180, 128, 128, 255 }, /* 75% white */ | ||
1384 | { 168, 44, 136, 255 }, /* 75% yellow */ | ||
1385 | { 145, 147, 44, 255 }, /* 75% cyan */ | ||
1386 | { 133, 63, 52, 255 }, /* 75% green */ | ||
1387 | { 63, 193, 204, 255 }, /* 75% magenta */ | ||
1388 | { 51, 109, 212, 255 }, /* 75% red */ | ||
1389 | { 28, 212, 120, 255 }, /* 75% blue */ | ||
1390 | }; | ||
1391 | |||
1392 | static const uint8_t wobnair[7][4] = { | ||
1393 | { 35, 212, 114, 255 }, /* 75% blue */ | ||
1394 | { 19, 128, 128, 255 }, /* 7.5% intensity black */ | ||
1395 | { 84, 184, 198, 255 }, /* 75% magenta */ | ||
1396 | { 19, 128, 128, 255 }, /* 7.5% intensity black */ | ||
1397 | { 131, 156, 44, 255 }, /* 75% cyan */ | ||
1398 | { 19, 128, 128, 255 }, /* 7.5% intensity black */ | ||
1399 | { 180, 128, 128, 255 }, /* 75% white */ | ||
1400 | }; | ||
1401 | |||
1402 | static const uint8_t white[4] = { 235, 128, 128, 255 }; | ||
1403 | |||
1404 | /* pluge pulses */ | ||
1405 | static const uint8_t neg4ire[4] = { 7, 128, 128, 255 }; | ||
1406 | static const uint8_t pos4ire[4] = { 24, 128, 128, 255 }; | ||
1407 | |||
1408 | /* fudged Q/-I */ | ||
1409 | static const uint8_t i_pixel[4] = { 57, 156, 97, 255 }; | ||
1410 | static const uint8_t q_pixel[4] = { 44, 171, 147, 255 }; | ||
1411 | |||
1412 | static const uint8_t gray40[4] = { 104, 128, 128, 255 }; | ||
1413 | static const uint8_t gray15[4] = { 49, 128, 128, 255 }; | ||
1414 | static const uint8_t cyan[4] = { 188, 154, 16, 255 }; | ||
1415 | static const uint8_t yellow[4] = { 219, 16, 138, 255 }; | ||
1416 | static const uint8_t blue[4] = { 32, 240, 118, 255 }; | ||
1417 | static const uint8_t red[4] = { 63, 102, 240, 255 }; | ||
1418 | static const uint8_t black0[4] = { 16, 128, 128, 255 }; | ||
1419 | static const uint8_t black2[4] = { 20, 128, 128, 255 }; | ||
1420 | static const uint8_t black4[4] = { 25, 128, 128, 255 }; | ||
1421 | static const uint8_t neg2[4] = { 12, 128, 128, 255 }; | ||
1422 | |||
1423 | 269 | static void draw_bar(TestSourceContext *test, const uint8_t color[4], | |
1424 | int x, int y, int w, int h, | ||
1425 | AVFrame *frame) | ||
1426 | { | ||
1427 | 269 | const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format); | |
1428 | uint8_t *p, *p0; | ||
1429 | int plane; | ||
1430 | |||
1431 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 269 times.
|
269 | x = FFMIN(x, test->w - 1); |
1432 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 269 times.
|
269 | y = FFMIN(y, test->h - 1); |
1433 | 269 | w = FFMAX(FFMIN(w, test->w - x), 0); | |
1434 | 269 | h = FFMAX(FFMIN(h, test->h - y), 0); | |
1435 | |||
1436 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 269 times.
|
269 | av_assert0(x + w <= test->w); |
1437 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 269 times.
|
269 | av_assert0(y + h <= test->h); |
1438 | |||
1439 |
2/2✓ Branch 0 taken 807 times.
✓ Branch 1 taken 269 times.
|
1076 | for (plane = 0; frame->data[plane]; plane++) { |
1440 | 807 | const int c = color[plane]; | |
1441 | 807 | const ptrdiff_t linesize = frame->linesize[plane]; | |
1442 | int i, px, py, pw, ph; | ||
1443 | |||
1444 |
4/4✓ Branch 0 taken 538 times.
✓ Branch 1 taken 269 times.
✓ Branch 2 taken 269 times.
✓ Branch 3 taken 269 times.
|
807 | if (plane == 1 || plane == 2) { |
1445 | 538 | px = x >> desc->log2_chroma_w; | |
1446 | 538 | pw = AV_CEIL_RSHIFT(w, desc->log2_chroma_w); | |
1447 | 538 | py = y >> desc->log2_chroma_h; | |
1448 | 538 | ph = AV_CEIL_RSHIFT(h, desc->log2_chroma_h); | |
1449 | } else { | ||
1450 | 269 | px = x; | |
1451 | 269 | pw = w; | |
1452 | 269 | py = y; | |
1453 | 269 | ph = h; | |
1454 | } | ||
1455 | |||
1456 | 807 | p0 = p = frame->data[plane] + py * linesize + px; | |
1457 | 807 | memset(p, c, pw); | |
1458 | 807 | p += linesize; | |
1459 |
2/2✓ Branch 0 taken 28773 times.
✓ Branch 1 taken 807 times.
|
29580 | for (i = 1; i < ph; i++, p += linesize) |
1460 | 28773 | memcpy(p, p0, pw); | |
1461 | } | ||
1462 | 269 | } | |
1463 | |||
1464 | static const enum AVPixelFormat smptebars_pix_fmts[] = { | ||
1465 | AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, | ||
1466 | AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV444P, | ||
1467 | AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P, | ||
1468 | AV_PIX_FMT_NONE, | ||
1469 | }; | ||
1470 | |||
1471 | 4 | static int smptebars_query_formats(const AVFilterContext *ctx, | |
1472 | AVFilterFormatsConfig **cfg_in, | ||
1473 | AVFilterFormatsConfig **cfg_out) | ||
1474 | { | ||
1475 | enum AVColorSpace csp; | ||
1476 | int ret; | ||
1477 | |||
1478 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if (!strcmp(ctx->name, "smptehdbars")) { |
1479 | ✗ | csp = AVCOL_SPC_BT709; | |
1480 | } else { | ||
1481 | 4 | csp = AVCOL_SPC_BT470BG; | |
1482 | } | ||
1483 | |||
1484 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
|
4 | if ((ret = ff_set_common_color_spaces2(ctx, cfg_in, cfg_out, |
1485 | ff_make_formats_list_singleton(csp)))) | ||
1486 | ✗ | return ret; | |
1487 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
|
4 | if ((ret = ff_set_common_color_ranges2(ctx, cfg_in, cfg_out, |
1488 | ff_make_formats_list_singleton(AVCOL_RANGE_MPEG)))) | ||
1489 | ✗ | return ret; | |
1490 | 4 | return ff_set_common_formats_from_list2(ctx, cfg_in, cfg_out, smptebars_pix_fmts); | |
1491 | } | ||
1492 | |||
1493 | AVFILTER_DEFINE_CLASS_EXT(palbars, "pal(75|100)bars", options); | ||
1494 | |||
1495 | #if CONFIG_PAL75BARS_FILTER | ||
1496 | |||
1497 | 1 | static void pal75bars_fill_picture(AVFilterContext *ctx, AVFrame *picref) | |
1498 | { | ||
1499 | 1 | TestSourceContext *test = ctx->priv; | |
1500 | 1 | int r_w, i, x = 0; | |
1501 | 1 | const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(picref->format); | |
1502 | |||
1503 | 1 | r_w = FFALIGN((test->w + 7) / 8, 1 << pixdesc->log2_chroma_w); | |
1504 | |||
1505 | 1 | draw_bar(test, white, x, 0, r_w, test->h, picref); | |
1506 | 1 | x += r_w; | |
1507 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 1 times.
|
7 | for (i = 1; i < 7; i++) { |
1508 | 6 | draw_bar(test, rainbow[i], x, 0, r_w, test->h, picref); | |
1509 | 6 | x += r_w; | |
1510 | } | ||
1511 | 1 | draw_bar(test, black0, x, 0, r_w, test->h, picref); | |
1512 | 1 | } | |
1513 | |||
1514 | 2 | static av_cold int pal75bars_init(AVFilterContext *ctx) | |
1515 | { | ||
1516 | 2 | TestSourceContext *test = ctx->priv; | |
1517 | |||
1518 | 2 | test->fill_picture_fn = pal75bars_fill_picture; | |
1519 | 2 | test->draw_once = 1; | |
1520 | 2 | return init(ctx); | |
1521 | } | ||
1522 | |||
1523 | const FFFilter ff_vsrc_pal75bars = { | ||
1524 | .p.name = "pal75bars", | ||
1525 | .p.description = NULL_IF_CONFIG_SMALL("Generate PAL 75% color bars."), | ||
1526 | .p.priv_class = &palbars_class, | ||
1527 | .priv_size = sizeof(TestSourceContext), | ||
1528 | .init = pal75bars_init, | ||
1529 | .uninit = uninit, | ||
1530 | .activate = activate, | ||
1531 | FILTER_OUTPUTS(outputs), | ||
1532 | FILTER_QUERY_FUNC2(smptebars_query_formats), | ||
1533 | }; | ||
1534 | |||
1535 | #endif /* CONFIG_PAL75BARS_FILTER */ | ||
1536 | |||
1537 | #if CONFIG_PAL100BARS_FILTER | ||
1538 | |||
1539 | 1 | static void pal100bars_fill_picture(AVFilterContext *ctx, AVFrame *picref) | |
1540 | { | ||
1541 | 1 | TestSourceContext *test = ctx->priv; | |
1542 | 1 | int r_w, i, x = 0; | |
1543 | 1 | const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(picref->format); | |
1544 | |||
1545 | 1 | r_w = FFALIGN((test->w + 7) / 8, 1 << pixdesc->log2_chroma_w); | |
1546 | |||
1547 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1 times.
|
8 | for (i = 0; i < 7; i++) { |
1548 | 7 | draw_bar(test, rainbow100[i], x, 0, r_w, test->h, picref); | |
1549 | 7 | x += r_w; | |
1550 | } | ||
1551 | 1 | draw_bar(test, black0, x, 0, r_w, test->h, picref); | |
1552 | 1 | } | |
1553 | |||
1554 | 2 | static av_cold int pal100bars_init(AVFilterContext *ctx) | |
1555 | { | ||
1556 | 2 | TestSourceContext *test = ctx->priv; | |
1557 | |||
1558 | 2 | test->fill_picture_fn = pal100bars_fill_picture; | |
1559 | 2 | test->draw_once = 1; | |
1560 | 2 | return init(ctx); | |
1561 | } | ||
1562 | |||
1563 | const FFFilter ff_vsrc_pal100bars = { | ||
1564 | .p.name = "pal100bars", | ||
1565 | .p.description = NULL_IF_CONFIG_SMALL("Generate PAL 100% color bars."), | ||
1566 | .p.priv_class = &palbars_class, | ||
1567 | .priv_size = sizeof(TestSourceContext), | ||
1568 | .init = pal100bars_init, | ||
1569 | .uninit = uninit, | ||
1570 | .activate = activate, | ||
1571 | FILTER_OUTPUTS(outputs), | ||
1572 | FILTER_QUERY_FUNC2(smptebars_query_formats), | ||
1573 | }; | ||
1574 | |||
1575 | #endif /* CONFIG_PAL100BARS_FILTER */ | ||
1576 | |||
1577 | AVFILTER_DEFINE_CLASS_EXT(smptebars, "smpte(hd)bars", options); | ||
1578 | |||
1579 | #if CONFIG_SMPTEBARS_FILTER | ||
1580 | |||
1581 | 1 | static void smptebars_fill_picture(AVFilterContext *ctx, AVFrame *picref) | |
1582 | { | ||
1583 | 1 | TestSourceContext *test = ctx->priv; | |
1584 | 1 | int r_w, r_h, w_h, p_w, p_h, i, tmp, x = 0; | |
1585 | 1 | const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(picref->format); | |
1586 | |||
1587 | 1 | r_w = FFALIGN((test->w + 6) / 7, 1 << pixdesc->log2_chroma_w); | |
1588 | 1 | r_h = FFALIGN(test->h * 2 / 3, 1 << pixdesc->log2_chroma_h); | |
1589 | 1 | w_h = FFALIGN(test->h * 3 / 4 - r_h, 1 << pixdesc->log2_chroma_h); | |
1590 | 1 | p_w = FFALIGN(r_w * 5 / 4, 1 << pixdesc->log2_chroma_w); | |
1591 | 1 | p_h = test->h - w_h - r_h; | |
1592 | |||
1593 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1 times.
|
8 | for (i = 0; i < 7; i++) { |
1594 | 7 | draw_bar(test, rainbow[i], x, 0, r_w, r_h, picref); | |
1595 | 7 | draw_bar(test, wobnair[i], x, r_h, r_w, w_h, picref); | |
1596 | 7 | x += r_w; | |
1597 | } | ||
1598 | 1 | x = 0; | |
1599 | 1 | draw_bar(test, i_pixel, x, r_h + w_h, p_w, p_h, picref); | |
1600 | 1 | x += p_w; | |
1601 | 1 | draw_bar(test, white, x, r_h + w_h, p_w, p_h, picref); | |
1602 | 1 | x += p_w; | |
1603 | 1 | draw_bar(test, q_pixel, x, r_h + w_h, p_w, p_h, picref); | |
1604 | 1 | x += p_w; | |
1605 | 1 | tmp = FFALIGN(5 * r_w - x, 1 << pixdesc->log2_chroma_w); | |
1606 | 1 | draw_bar(test, black0, x, r_h + w_h, tmp, p_h, picref); | |
1607 | 1 | x += tmp; | |
1608 | 1 | tmp = FFALIGN(r_w / 3, 1 << pixdesc->log2_chroma_w); | |
1609 | 1 | draw_bar(test, neg4ire, x, r_h + w_h, tmp, p_h, picref); | |
1610 | 1 | x += tmp; | |
1611 | 1 | draw_bar(test, black0, x, r_h + w_h, tmp, p_h, picref); | |
1612 | 1 | x += tmp; | |
1613 | 1 | draw_bar(test, pos4ire, x, r_h + w_h, tmp, p_h, picref); | |
1614 | 1 | x += tmp; | |
1615 | 1 | draw_bar(test, black0, x, r_h + w_h, test->w - x, p_h, picref); | |
1616 | 1 | } | |
1617 | |||
1618 | 2 | static av_cold int smptebars_init(AVFilterContext *ctx) | |
1619 | { | ||
1620 | 2 | TestSourceContext *test = ctx->priv; | |
1621 | |||
1622 | 2 | test->fill_picture_fn = smptebars_fill_picture; | |
1623 | 2 | test->draw_once = 1; | |
1624 | 2 | return init(ctx); | |
1625 | } | ||
1626 | |||
1627 | const FFFilter ff_vsrc_smptebars = { | ||
1628 | .p.name = "smptebars", | ||
1629 | .p.description = NULL_IF_CONFIG_SMALL("Generate SMPTE color bars."), | ||
1630 | .p.priv_class = &smptebars_class, | ||
1631 | .priv_size = sizeof(TestSourceContext), | ||
1632 | .init = smptebars_init, | ||
1633 | .uninit = uninit, | ||
1634 | .activate = activate, | ||
1635 | FILTER_OUTPUTS(outputs), | ||
1636 | FILTER_QUERY_FUNC2(smptebars_query_formats), | ||
1637 | }; | ||
1638 | |||
1639 | #endif /* CONFIG_SMPTEBARS_FILTER */ | ||
1640 | |||
1641 | #if CONFIG_SMPTEHDBARS_FILTER | ||
1642 | |||
1643 | 1 | static void smptehdbars_fill_picture(AVFilterContext *ctx, AVFrame *picref) | |
1644 | { | ||
1645 | 1 | TestSourceContext *test = ctx->priv; | |
1646 | 1 | int d_w, r_w, r_h, l_w, i, tmp, x = 0, y = 0; | |
1647 | 1 | const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(picref->format); | |
1648 | |||
1649 | 1 | d_w = FFALIGN(test->w / 8, 1 << pixdesc->log2_chroma_w); | |
1650 | 1 | r_h = FFALIGN(test->h * 7 / 12, 1 << pixdesc->log2_chroma_h); | |
1651 | 1 | draw_bar(test, gray40, x, 0, d_w, r_h, picref); | |
1652 | 1 | x += d_w; | |
1653 | |||
1654 | 1 | r_w = FFALIGN((((test->w + 3) / 4) * 3) / 7, 1 << pixdesc->log2_chroma_w); | |
1655 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1 times.
|
8 | for (i = 0; i < 7; i++) { |
1656 | 7 | draw_bar(test, rainbowhd[i], x, 0, r_w, r_h, picref); | |
1657 | 7 | x += r_w; | |
1658 | } | ||
1659 | 1 | draw_bar(test, gray40, x, 0, test->w - x, r_h, picref); | |
1660 | 1 | y = r_h; | |
1661 | 1 | r_h = FFALIGN(test->h / 12, 1 << pixdesc->log2_chroma_h); | |
1662 | 1 | draw_bar(test, cyan, 0, y, d_w, r_h, picref); | |
1663 | 1 | x = d_w; | |
1664 | 1 | draw_bar(test, i_pixel, x, y, r_w, r_h, picref); | |
1665 | 1 | x += r_w; | |
1666 | 1 | tmp = r_w * 6; | |
1667 | 1 | draw_bar(test, rainbowhd[0], x, y, tmp, r_h, picref); | |
1668 | 1 | x += tmp; | |
1669 | 1 | l_w = x; | |
1670 | 1 | draw_bar(test, blue, x, y, test->w - x, r_h, picref); | |
1671 | 1 | y += r_h; | |
1672 | 1 | draw_bar(test, yellow, 0, y, d_w, r_h, picref); | |
1673 | 1 | x = d_w; | |
1674 | 1 | draw_bar(test, q_pixel, x, y, r_w, r_h, picref); | |
1675 | 1 | x += r_w; | |
1676 | |||
1677 |
2/2✓ Branch 0 taken 204 times.
✓ Branch 1 taken 1 times.
|
205 | for (i = 0; i < tmp; i += 1 << pixdesc->log2_chroma_w) { |
1678 | 204 | uint8_t yramp[4] = {0}; | |
1679 | |||
1680 | 204 | yramp[0] = i * 255 / tmp; | |
1681 | 204 | yramp[1] = 128; | |
1682 | 204 | yramp[2] = 128; | |
1683 | 204 | yramp[3] = 255; | |
1684 | |||
1685 | 204 | draw_bar(test, yramp, x, y, 1 << pixdesc->log2_chroma_w, r_h, picref); | |
1686 | 204 | x += 1 << pixdesc->log2_chroma_w; | |
1687 | } | ||
1688 | 1 | draw_bar(test, red, x, y, test->w - x, r_h, picref); | |
1689 | 1 | y += r_h; | |
1690 | 1 | draw_bar(test, gray15, 0, y, d_w, test->h - y, picref); | |
1691 | 1 | x = d_w; | |
1692 | 1 | tmp = FFALIGN(r_w * 3 / 2, 1 << pixdesc->log2_chroma_w); | |
1693 | 1 | draw_bar(test, black0, x, y, tmp, test->h - y, picref); | |
1694 | 1 | x += tmp; | |
1695 | 1 | tmp = FFALIGN(r_w * 2, 1 << pixdesc->log2_chroma_w); | |
1696 | 1 | draw_bar(test, white, x, y, tmp, test->h - y, picref); | |
1697 | 1 | x += tmp; | |
1698 | 1 | tmp = FFALIGN(r_w * 5 / 6, 1 << pixdesc->log2_chroma_w); | |
1699 | 1 | draw_bar(test, black0, x, y, tmp, test->h - y, picref); | |
1700 | 1 | x += tmp; | |
1701 | 1 | tmp = FFALIGN(r_w / 3, 1 << pixdesc->log2_chroma_w); | |
1702 | 1 | draw_bar(test, neg2, x, y, tmp, test->h - y, picref); | |
1703 | 1 | x += tmp; | |
1704 | 1 | draw_bar(test, black0, x, y, tmp, test->h - y, picref); | |
1705 | 1 | x += tmp; | |
1706 | 1 | draw_bar(test, black2, x, y, tmp, test->h - y, picref); | |
1707 | 1 | x += tmp; | |
1708 | 1 | draw_bar(test, black0, x, y, tmp, test->h - y, picref); | |
1709 | 1 | x += tmp; | |
1710 | 1 | draw_bar(test, black4, x, y, tmp, test->h - y, picref); | |
1711 | 1 | x += tmp; | |
1712 | 1 | r_w = l_w - x; | |
1713 | 1 | draw_bar(test, black0, x, y, r_w, test->h - y, picref); | |
1714 | 1 | x += r_w; | |
1715 | 1 | draw_bar(test, gray15, x, y, test->w - x, test->h - y, picref); | |
1716 | 1 | } | |
1717 | |||
1718 | 2 | static av_cold int smptehdbars_init(AVFilterContext *ctx) | |
1719 | { | ||
1720 | 2 | TestSourceContext *test = ctx->priv; | |
1721 | |||
1722 | 2 | test->fill_picture_fn = smptehdbars_fill_picture; | |
1723 | 2 | test->draw_once = 1; | |
1724 | 2 | return init(ctx); | |
1725 | } | ||
1726 | |||
1727 | const FFFilter ff_vsrc_smptehdbars = { | ||
1728 | .p.name = "smptehdbars", | ||
1729 | .p.description = NULL_IF_CONFIG_SMALL("Generate SMPTE HD color bars."), | ||
1730 | .p.priv_class = &smptebars_class, | ||
1731 | .priv_size = sizeof(TestSourceContext), | ||
1732 | .init = smptehdbars_init, | ||
1733 | .uninit = uninit, | ||
1734 | .activate = activate, | ||
1735 | FILTER_OUTPUTS(outputs), | ||
1736 | FILTER_QUERY_FUNC2(smptebars_query_formats), | ||
1737 | }; | ||
1738 | |||
1739 | #endif /* CONFIG_SMPTEHDBARS_FILTER */ | ||
1740 | #endif /* CONFIG_SMPTEBARS_FILTER || CONFIG_SMPTEHDBARS_FILTER */ | ||
1741 | |||
1742 | AVFILTER_DEFINE_CLASS_EXT(allyuv_allrgb, "allyuv/allrgb", | ||
1743 | &options[NOSIZE_OPTIONS_OFFSET]); | ||
1744 | |||
1745 | #if CONFIG_ALLYUV_FILTER | ||
1746 | |||
1747 | 1 | static void allyuv_fill_picture(AVFilterContext *ctx, AVFrame *frame) | |
1748 | { | ||
1749 | 1 | const ptrdiff_t ys = frame->linesize[0]; | |
1750 | 1 | const ptrdiff_t us = frame->linesize[1]; | |
1751 | 1 | const ptrdiff_t vs = frame->linesize[2]; | |
1752 | int x, y, j; | ||
1753 | |||
1754 |
2/2✓ Branch 0 taken 4096 times.
✓ Branch 1 taken 1 times.
|
4097 | for (y = 0; y < 4096; y++) { |
1755 |
2/2✓ Branch 0 taken 8388608 times.
✓ Branch 1 taken 4096 times.
|
8392704 | for (x = 0; x < 2048; x++) { |
1756 | 8388608 | frame->data[0][y * ys + x] = ((x / 8) % 256); | |
1757 | 8388608 | frame->data[0][y * ys + 4095 - x] = ((x / 8) % 256); | |
1758 | } | ||
1759 | |||
1760 |
2/2✓ Branch 0 taken 1048576 times.
✓ Branch 1 taken 4096 times.
|
1052672 | for (x = 0; x < 2048; x+=8) { |
1761 |
2/2✓ Branch 0 taken 8388608 times.
✓ Branch 1 taken 1048576 times.
|
9437184 | for (j = 0; j < 8; j++) { |
1762 | 8388608 | frame->data[1][vs * y + x + j] = (y%16 + (j % 8) * 16); | |
1763 | 8388608 | frame->data[1][vs * y + 4095 - x - j] = (128 + y%16 + (j % 8) * 16); | |
1764 | } | ||
1765 | } | ||
1766 | |||
1767 |
2/2✓ Branch 0 taken 16777216 times.
✓ Branch 1 taken 4096 times.
|
16781312 | for (x = 0; x < 4096; x++) |
1768 | 16777216 | frame->data[2][y * us + x] = 256 * y / 4096; | |
1769 | } | ||
1770 | 1 | } | |
1771 | |||
1772 | 2 | static av_cold int allyuv_init(AVFilterContext *ctx) | |
1773 | { | ||
1774 | 2 | TestSourceContext *test = ctx->priv; | |
1775 | |||
1776 | 2 | test->w = test->h = 4096; | |
1777 | 2 | test->draw_once = 1; | |
1778 | 2 | test->fill_picture_fn = allyuv_fill_picture; | |
1779 | 2 | return init(ctx); | |
1780 | } | ||
1781 | |||
1782 | const FFFilter ff_vsrc_allyuv = { | ||
1783 | .p.name = "allyuv", | ||
1784 | .p.description = NULL_IF_CONFIG_SMALL("Generate all yuv colors."), | ||
1785 | .p.priv_class = &allyuv_allrgb_class, | ||
1786 | .priv_size = sizeof(TestSourceContext), | ||
1787 | .init = allyuv_init, | ||
1788 | .uninit = uninit, | ||
1789 | .activate = activate, | ||
1790 | FILTER_OUTPUTS(outputs), | ||
1791 | FILTER_PIXFMTS(AV_PIX_FMT_YUV444P, AV_PIX_FMT_GBRP), | ||
1792 | }; | ||
1793 | |||
1794 | #endif /* CONFIG_ALLYUV_FILTER */ | ||
1795 | |||
1796 | #if CONFIG_ALLRGB_FILTER | ||
1797 | |||
1798 | 1 | static void allrgb_fill_picture(AVFilterContext *ctx, AVFrame *frame) | |
1799 | { | ||
1800 | unsigned x, y; | ||
1801 | 1 | const ptrdiff_t linesize = frame->linesize[0]; | |
1802 | 1 | uint8_t *line = frame->data[0]; | |
1803 | |||
1804 |
2/2✓ Branch 0 taken 4096 times.
✓ Branch 1 taken 1 times.
|
4097 | for (y = 0; y < 4096; y++) { |
1805 | 4096 | uint8_t *dst = line; | |
1806 | |||
1807 |
2/2✓ Branch 0 taken 16777216 times.
✓ Branch 1 taken 4096 times.
|
16781312 | for (x = 0; x < 4096; x++) { |
1808 | 16777216 | *dst++ = x; | |
1809 | 16777216 | *dst++ = y; | |
1810 | 16777216 | *dst++ = (x >> 8) | ((y >> 8) << 4); | |
1811 | } | ||
1812 | 4096 | line += linesize; | |
1813 | } | ||
1814 | 1 | } | |
1815 | |||
1816 | 2 | static av_cold int allrgb_init(AVFilterContext *ctx) | |
1817 | { | ||
1818 | 2 | TestSourceContext *test = ctx->priv; | |
1819 | |||
1820 | 2 | test->w = test->h = 4096; | |
1821 | 2 | test->draw_once = 1; | |
1822 | 2 | test->fill_picture_fn = allrgb_fill_picture; | |
1823 | 2 | return init(ctx); | |
1824 | } | ||
1825 | |||
1826 | 1 | static int allrgb_config_props(AVFilterLink *outlink) | |
1827 | { | ||
1828 | 1 | TestSourceContext *test = outlink->src->priv; | |
1829 | |||
1830 | 1 | ff_fill_rgba_map(test->rgba_map, outlink->format); | |
1831 | 1 | return config_props(outlink); | |
1832 | } | ||
1833 | |||
1834 | static const AVFilterPad avfilter_vsrc_allrgb_outputs[] = { | ||
1835 | { | ||
1836 | .name = "default", | ||
1837 | .type = AVMEDIA_TYPE_VIDEO, | ||
1838 | .config_props = allrgb_config_props, | ||
1839 | }, | ||
1840 | }; | ||
1841 | |||
1842 | const FFFilter ff_vsrc_allrgb = { | ||
1843 | .p.name = "allrgb", | ||
1844 | .p.description = NULL_IF_CONFIG_SMALL("Generate all RGB colors."), | ||
1845 | .p.priv_class = &allyuv_allrgb_class, | ||
1846 | .priv_size = sizeof(TestSourceContext), | ||
1847 | .init = allrgb_init, | ||
1848 | .uninit = uninit, | ||
1849 | .activate = activate, | ||
1850 | FILTER_OUTPUTS(avfilter_vsrc_allrgb_outputs), | ||
1851 | FILTER_SINGLE_PIXFMT(AV_PIX_FMT_RGB24), | ||
1852 | }; | ||
1853 | |||
1854 | #endif /* CONFIG_ALLRGB_FILTER */ | ||
1855 | |||
1856 | #if CONFIG_COLORSPECTRUM_FILTER | ||
1857 | |||
1858 | static const AVOption colorspectrum_options[] = { | ||
1859 | COMMON_OPTIONS | ||
1860 | { "type", "set the color spectrum type", OFFSET(type), AV_OPT_TYPE_INT, {.i64=0}, 0, 2, FLAGS, .unit = "type" }, | ||
1861 | { "black","fade to black", 0, AV_OPT_TYPE_CONST,{.i64=0},0, 0, FLAGS, .unit = "type" }, | ||
1862 | { "white","fade to white", 0, AV_OPT_TYPE_CONST,{.i64=1},0, 0, FLAGS, .unit = "type" }, | ||
1863 | { "all", "white to black", 0, AV_OPT_TYPE_CONST,{.i64=2},0, 0, FLAGS, .unit = "type" }, | ||
1864 | { NULL } | ||
1865 | }; | ||
1866 | |||
1867 | AVFILTER_DEFINE_CLASS(colorspectrum); | ||
1868 | |||
1869 | ✗ | static inline float mix(float a, float b, float mix) | |
1870 | { | ||
1871 | ✗ | return a * mix + b * (1.f - mix); | |
1872 | } | ||
1873 | |||
1874 | ✗ | static void hsb2rgb(const float *c, float *rgb) | |
1875 | { | ||
1876 | ✗ | rgb[0] = av_clipf(fabsf(fmodf(c[0] * 6.f + 0.f, 6.f) - 3.f) - 1.f, 0.f, 1.f); | |
1877 | ✗ | rgb[1] = av_clipf(fabsf(fmodf(c[0] * 6.f + 4.f, 6.f) - 3.f) - 1.f, 0.f, 1.f); | |
1878 | ✗ | rgb[2] = av_clipf(fabsf(fmodf(c[0] * 6.f + 2.f, 6.f) - 3.f) - 1.f, 0.f, 1.f); | |
1879 | ✗ | rgb[0] = mix(c[3], (rgb[0] * rgb[0] * (3.f - 2.f * rgb[0])), c[1]) * c[2]; | |
1880 | ✗ | rgb[1] = mix(c[3], (rgb[1] * rgb[1] * (3.f - 2.f * rgb[1])), c[1]) * c[2]; | |
1881 | ✗ | rgb[2] = mix(c[3], (rgb[2] * rgb[2] * (3.f - 2.f * rgb[2])), c[1]) * c[2]; | |
1882 | ✗ | } | |
1883 | |||
1884 | ✗ | static void colorspectrum_fill_picture(AVFilterContext *ctx, AVFrame *frame) | |
1885 | { | ||
1886 | ✗ | TestSourceContext *test = ctx->priv; | |
1887 | ✗ | const float w = frame->width - 1.f; | |
1888 | ✗ | const float h = frame->height - 1.f; | |
1889 | float c[4]; | ||
1890 | |||
1891 | ✗ | for (int y = 0; y < frame->height; y++) { | |
1892 | ✗ | float *r = (float *)(frame->data[2] + y * frame->linesize[2]); | |
1893 | ✗ | float *g = (float *)(frame->data[0] + y * frame->linesize[0]); | |
1894 | ✗ | float *b = (float *)(frame->data[1] + y * frame->linesize[1]); | |
1895 | ✗ | const float yh = y / h; | |
1896 | |||
1897 | ✗ | c[1] = test->type == 2 ? yh > 0.5f ? 2.f * (yh - 0.5f) : 1.f - 2.f * yh : test->type == 1 ? 1.f - yh : yh; | |
1898 | ✗ | c[2] = 1.f; | |
1899 | ✗ | c[3] = test->type == 1 ? 1.f : test->type == 2 ? (yh > 0.5f ? 0.f : 1.f): 0.f; | |
1900 | ✗ | for (int x = 0; x < frame->width; x++) { | |
1901 | float rgb[3]; | ||
1902 | |||
1903 | ✗ | c[0] = x / w; | |
1904 | ✗ | hsb2rgb(c, rgb); | |
1905 | |||
1906 | ✗ | r[x] = rgb[0]; | |
1907 | ✗ | g[x] = rgb[1]; | |
1908 | ✗ | b[x] = rgb[2]; | |
1909 | } | ||
1910 | } | ||
1911 | ✗ | } | |
1912 | |||
1913 | ✗ | static av_cold int colorspectrum_init(AVFilterContext *ctx) | |
1914 | { | ||
1915 | ✗ | TestSourceContext *test = ctx->priv; | |
1916 | |||
1917 | ✗ | test->draw_once = 1; | |
1918 | ✗ | test->fill_picture_fn = colorspectrum_fill_picture; | |
1919 | ✗ | return init(ctx); | |
1920 | } | ||
1921 | |||
1922 | const FFFilter ff_vsrc_colorspectrum = { | ||
1923 | .p.name = "colorspectrum", | ||
1924 | .p.description = NULL_IF_CONFIG_SMALL("Generate colors spectrum."), | ||
1925 | .p.priv_class = &colorspectrum_class, | ||
1926 | .priv_size = sizeof(TestSourceContext), | ||
1927 | .init = colorspectrum_init, | ||
1928 | .uninit = uninit, | ||
1929 | .activate = activate, | ||
1930 | FILTER_OUTPUTS(outputs), | ||
1931 | FILTER_SINGLE_PIXFMT(AV_PIX_FMT_GBRPF32), | ||
1932 | }; | ||
1933 | |||
1934 | #endif /* CONFIG_COLORSPECTRUM_FILTER */ | ||
1935 | |||
1936 | #if CONFIG_COLORCHART_FILTER | ||
1937 | |||
1938 | static const AVOption colorchart_options[] = { | ||
1939 | COMMON_OPTIONS_NOSIZE | ||
1940 | { "patch_size", "set the single patch size", OFFSET(pw), AV_OPT_TYPE_IMAGE_SIZE, {.str="64x64"}, 0, 0, FLAGS }, | ||
1941 | { "preset", "set the color checker chart preset", OFFSET(type), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, .unit = "preset" }, | ||
1942 | { "reference", "reference", 0, AV_OPT_TYPE_CONST,{.i64=0}, 0, 0, FLAGS, .unit = "preset" }, | ||
1943 | { "skintones", "skintones", 0, AV_OPT_TYPE_CONST,{.i64=1}, 0, 0, FLAGS, .unit = "preset" }, | ||
1944 | { NULL } | ||
1945 | }; | ||
1946 | |||
1947 | AVFILTER_DEFINE_CLASS(colorchart); | ||
1948 | |||
1949 | static const uint8_t reference_colors[][3] = { | ||
1950 | { 115, 82, 68 }, // dark skin | ||
1951 | { 194, 150, 130 }, // light skin | ||
1952 | { 98, 122, 157 }, // blue sky | ||
1953 | { 87, 108, 67 }, // foliage | ||
1954 | { 133, 128, 177 }, // blue flower | ||
1955 | { 103, 189, 170 }, // bluish green | ||
1956 | |||
1957 | { 214, 126, 44 }, // orange | ||
1958 | { 80, 91, 166 }, // purple red | ||
1959 | { 193, 90, 99 }, // moderate red | ||
1960 | { 94, 60, 108 }, // purple | ||
1961 | { 157, 188, 64 }, // yellow green | ||
1962 | { 224, 163, 46 }, // orange yellow | ||
1963 | |||
1964 | { 56, 61, 150 }, // blue | ||
1965 | { 70, 148, 73 }, // green | ||
1966 | { 175, 54, 60 }, // red | ||
1967 | { 231, 199, 31 }, // yellow | ||
1968 | { 187, 86, 149 }, // magenta | ||
1969 | { 8, 133, 161 }, // cyan | ||
1970 | |||
1971 | { 243, 243, 242 }, // white | ||
1972 | { 200, 200, 200 }, // neutral 8 | ||
1973 | { 160, 160, 160 }, // neutral 65 | ||
1974 | { 122, 122, 121 }, // neutral 5 | ||
1975 | { 85, 85, 85 }, // neutral 35 | ||
1976 | { 52, 52, 52 }, // black | ||
1977 | }; | ||
1978 | |||
1979 | static const uint8_t skintones_colors[][3] = { | ||
1980 | { 54, 38, 43 }, | ||
1981 | { 105, 43, 42 }, | ||
1982 | { 147, 43, 43 }, | ||
1983 | { 77, 41, 42 }, | ||
1984 | { 134, 43, 41 }, | ||
1985 | { 201, 134, 118 }, | ||
1986 | |||
1987 | { 59, 41, 41 }, | ||
1988 | { 192, 103, 76 }, | ||
1989 | { 208, 156, 141 }, | ||
1990 | { 152, 82, 61 }, | ||
1991 | { 162, 132, 118 }, | ||
1992 | { 212, 171, 150 }, | ||
1993 | |||
1994 | { 205, 91, 31 }, | ||
1995 | { 164, 100, 55 }, | ||
1996 | { 204, 136, 95 }, | ||
1997 | { 178, 142, 116 }, | ||
1998 | { 210, 152, 108 }, | ||
1999 | { 217, 167, 131 }, | ||
2000 | |||
2001 | { 206, 166, 126 }, | ||
2002 | { 208, 163, 97 }, | ||
2003 | { 245, 180, 0 }, | ||
2004 | { 212, 184, 125 }, | ||
2005 | { 179, 165, 150 }, | ||
2006 | { 196, 184, 105 }, | ||
2007 | }; | ||
2008 | |||
2009 | typedef struct ColorChartPreset { | ||
2010 | int w, h; | ||
2011 | const uint8_t (*colors)[3]; | ||
2012 | } ColorChartPreset; | ||
2013 | |||
2014 | static const ColorChartPreset colorchart_presets[] = { | ||
2015 | { 6, 4, reference_colors, }, | ||
2016 | { 6, 4, skintones_colors, }, | ||
2017 | }; | ||
2018 | |||
2019 | ✗ | static int colorchart_config_props(AVFilterLink *inlink) | |
2020 | { | ||
2021 | ✗ | AVFilterContext *ctx = inlink->src; | |
2022 | ✗ | TestSourceContext *s = ctx->priv; | |
2023 | |||
2024 | ✗ | av_assert0(ff_draw_init2(&s->draw, inlink->format, inlink->colorspace, | |
2025 | inlink->color_range, 0) >= 0); | ||
2026 | ✗ | if (av_image_check_size(s->w, s->h, 0, ctx) < 0) | |
2027 | ✗ | return AVERROR(EINVAL); | |
2028 | ✗ | return config_props(inlink); | |
2029 | } | ||
2030 | |||
2031 | ✗ | static void colorchart_fill_picture(AVFilterContext *ctx, AVFrame *frame) | |
2032 | { | ||
2033 | ✗ | TestSourceContext *test = ctx->priv; | |
2034 | ✗ | const int preset = test->type; | |
2035 | ✗ | const int w = colorchart_presets[preset].w; | |
2036 | ✗ | const int h = colorchart_presets[preset].h; | |
2037 | ✗ | const int pw = test->pw; | |
2038 | ✗ | const int ph = test->ph; | |
2039 | |||
2040 | ✗ | for (int y = 0; y < h; y++) { | |
2041 | ✗ | for (int x = 0; x < w; x++) { | |
2042 | ✗ | uint32_t pc = AV_RB24(colorchart_presets[preset].colors[y * w + x]); | |
2043 | FFDrawColor color; | ||
2044 | |||
2045 | ✗ | set_color(test, &color, pc); | |
2046 | ✗ | ff_fill_rectangle(&test->draw, &color, frame->data, frame->linesize, | |
2047 | x * pw, y * ph, pw, ph); | ||
2048 | } | ||
2049 | } | ||
2050 | ✗ | } | |
2051 | |||
2052 | ✗ | static av_cold int colorchart_init(AVFilterContext *ctx) | |
2053 | { | ||
2054 | ✗ | TestSourceContext *test = ctx->priv; | |
2055 | ✗ | const int preset = test->type; | |
2056 | ✗ | const int w = colorchart_presets[preset].w; | |
2057 | ✗ | const int h = colorchart_presets[preset].h; | |
2058 | |||
2059 | ✗ | test->w = w * test->pw; | |
2060 | ✗ | test->h = h * test->ph; | |
2061 | ✗ | test->draw_once = 1; | |
2062 | ✗ | test->fill_picture_fn = colorchart_fill_picture; | |
2063 | ✗ | return init(ctx); | |
2064 | } | ||
2065 | |||
2066 | static const AVFilterPad avfilter_vsrc_colorchart_outputs[] = { | ||
2067 | { | ||
2068 | .name = "default", | ||
2069 | .type = AVMEDIA_TYPE_VIDEO, | ||
2070 | .config_props = colorchart_config_props, | ||
2071 | }, | ||
2072 | }; | ||
2073 | |||
2074 | const FFFilter ff_vsrc_colorchart = { | ||
2075 | .p.name = "colorchart", | ||
2076 | .p.description = NULL_IF_CONFIG_SMALL("Generate color checker chart."), | ||
2077 | .p.priv_class = &colorchart_class, | ||
2078 | .priv_size = sizeof(TestSourceContext), | ||
2079 | .init = colorchart_init, | ||
2080 | .uninit = uninit, | ||
2081 | .activate = activate, | ||
2082 | FILTER_OUTPUTS(avfilter_vsrc_colorchart_outputs), | ||
2083 | FILTER_SINGLE_PIXFMT(AV_PIX_FMT_GBRP), | ||
2084 | }; | ||
2085 | |||
2086 | #endif /* CONFIG_COLORCHART_FILTER */ | ||
2087 | |||
2088 | #if CONFIG_ZONEPLATE_FILTER | ||
2089 | |||
2090 | static const AVOption zoneplate_options[] = { | ||
2091 | COMMON_OPTIONS | ||
2092 | { "precision", "set LUT precision", OFFSET(lut_precision), AV_OPT_TYPE_INT, {.i64=10}, 4, 16, FLAGS }, | ||
2093 | { "xo", "set X-axis offset", OFFSET(xo), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR }, | ||
2094 | { "yo", "set Y-axis offset", OFFSET(yo), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR }, | ||
2095 | { "to", "set T-axis offset", OFFSET(to), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR }, | ||
2096 | { "k0", "set 0-order phase", OFFSET(k0), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR }, | ||
2097 | { "kx", "set 1-order X-axis phase", OFFSET(kx), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR }, | ||
2098 | { "ky", "set 1-order Y-axis phase", OFFSET(ky), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR }, | ||
2099 | { "kt", "set 1-order T-axis phase", OFFSET(kt), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR }, | ||
2100 | { "kxt", "set X-axis*T-axis product phase", OFFSET(kxt), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR }, | ||
2101 | { "kyt", "set Y-axis*T-axis product phase", OFFSET(kyt), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR }, | ||
2102 | { "kxy", "set X-axis*Y-axis product phase", OFFSET(kxy), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR }, | ||
2103 | { "kx2", "set 2-order X-axis phase", OFFSET(kx2), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR }, | ||
2104 | { "ky2", "set 2-order Y-axis phase", OFFSET(ky2), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR }, | ||
2105 | { "kt2", "set 2-order T-axis phase", OFFSET(kt2), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR }, | ||
2106 | { "ku", "set 0-order U-color phase", OFFSET(kU), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR }, | ||
2107 | { "kv", "set 0-order V-color phase", OFFSET(kV), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGSR }, | ||
2108 | { NULL } | ||
2109 | }; | ||
2110 | |||
2111 | AVFILTER_DEFINE_CLASS(zoneplate); | ||
2112 | |||
2113 | #define ZONEPLATE_SLICE(name, type) \ | ||
2114 | static int zoneplate_fill_slice_##name(AVFilterContext *ctx, \ | ||
2115 | void *arg, int job, \ | ||
2116 | int nb_jobs) \ | ||
2117 | { \ | ||
2118 | TestSourceContext *test = ctx->priv; \ | ||
2119 | AVFrame *frame = arg; \ | ||
2120 | const int w = frame->width; \ | ||
2121 | const int h = frame->height; \ | ||
2122 | const int kxt = test->kxt, kyt = test->kyt, kx2 = test->kx2; \ | ||
2123 | const int t = test->pts + test->to, k0 = test->k0; \ | ||
2124 | const int kt = test->kt, kt2 = test->kt2, ky2 = test->ky2; \ | ||
2125 | const int ky = test->ky, kx = test->kx, kxy = test->kxy; \ | ||
2126 | const int lut_mask = (1 << test->lut_precision) - 1; \ | ||
2127 | const int nkt2t = kt2 * t * t, nktt = kt * t; \ | ||
2128 | const int start = (h * job ) / nb_jobs; \ | ||
2129 | const int end = (h * (job+1)) / nb_jobs; \ | ||
2130 | const ptrdiff_t ylinesize = frame->linesize[0] / sizeof(type); \ | ||
2131 | const ptrdiff_t ulinesize = frame->linesize[1] / sizeof(type); \ | ||
2132 | const ptrdiff_t vlinesize = frame->linesize[2] / sizeof(type); \ | ||
2133 | const int xreset = -(w / 2) - test->xo; \ | ||
2134 | const int yreset = -(h / 2) - test->yo + start; \ | ||
2135 | const int kU = test->kU, kV = test->kV; \ | ||
2136 | const int skxy = 0xffff / (w / 2); \ | ||
2137 | const int skx2 = 0xffff / w; \ | ||
2138 | const int dkxt = kxt * t; \ | ||
2139 | type *ydst = ((type *)frame->data[0]) + start * ylinesize; \ | ||
2140 | type *udst = ((type *)frame->data[1]) + start * ulinesize; \ | ||
2141 | type *vdst = ((type *)frame->data[2]) + start * vlinesize; \ | ||
2142 | const type *lut = (const type *)test->lut; \ | ||
2143 | int akx, akxt, aky, akyt; \ | ||
2144 | \ | ||
2145 | aky = start * ky; \ | ||
2146 | akyt = start * kyt * t; \ | ||
2147 | \ | ||
2148 | for (int j = start, y = yreset; j < end; j++, y++) { \ | ||
2149 | const int dkxy = kxy * y * skxy; \ | ||
2150 | const int nky2kt2 = (ky2 * y * y) / h + (nkt2t >> 1); \ | ||
2151 | int akxy = dkxy * xreset; \ | ||
2152 | \ | ||
2153 | akx = 0; \ | ||
2154 | akxt = 0; \ | ||
2155 | aky += ky; \ | ||
2156 | akyt += kyt * t; \ | ||
2157 | \ | ||
2158 | for (int i = 0, x = xreset; i < w; i++, x++) { \ | ||
2159 | int phase = k0, uphase = kU, vphase = kV; \ | ||
2160 | \ | ||
2161 | akx += kx; \ | ||
2162 | phase += akx + aky + nktt; \ | ||
2163 | \ | ||
2164 | akxt += dkxt; \ | ||
2165 | akxy += dkxy; \ | ||
2166 | phase += akxt + akyt; \ | ||
2167 | phase += akxy >> 16; \ | ||
2168 | phase += ((kx2 * x * x * skx2) >> 16) + nky2kt2; \ | ||
2169 | uphase += phase; \ | ||
2170 | vphase += phase; \ | ||
2171 | \ | ||
2172 | ydst[i] = lut[phase & lut_mask]; \ | ||
2173 | udst[i] = lut[uphase & lut_mask]; \ | ||
2174 | vdst[i] = lut[vphase & lut_mask]; \ | ||
2175 | } \ | ||
2176 | \ | ||
2177 | ydst += ylinesize; \ | ||
2178 | udst += ulinesize; \ | ||
2179 | vdst += vlinesize; \ | ||
2180 | } \ | ||
2181 | \ | ||
2182 | return 0; \ | ||
2183 | } | ||
2184 | |||
2185 | ✗ | ZONEPLATE_SLICE( 8, uint8_t) | |
2186 | ✗ | ZONEPLATE_SLICE( 9, uint16_t) | |
2187 | ✗ | ZONEPLATE_SLICE(10, uint16_t) | |
2188 | ✗ | ZONEPLATE_SLICE(12, uint16_t) | |
2189 | ✗ | ZONEPLATE_SLICE(14, uint16_t) | |
2190 | ✗ | ZONEPLATE_SLICE(16, uint16_t) | |
2191 | |||
2192 | ✗ | static void zoneplate_fill_picture(AVFilterContext *ctx, AVFrame *frame) | |
2193 | { | ||
2194 | ✗ | TestSourceContext *test = ctx->priv; | |
2195 | ✗ | ff_filter_execute(ctx, test->fill_slice_fn, frame, NULL, | |
2196 | ✗ | FFMIN(frame->height, ff_filter_get_nb_threads(ctx))); | |
2197 | ✗ | } | |
2198 | |||
2199 | ✗ | static int zoneplate_config_props(AVFilterLink *outlink) | |
2200 | { | ||
2201 | ✗ | AVFilterContext *ctx = outlink->src; | |
2202 | ✗ | TestSourceContext *test = ctx->priv; | |
2203 | ✗ | const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(outlink->format); | |
2204 | ✗ | const int lut_size = 1 << test->lut_precision; | |
2205 | ✗ | const int depth = desc->comp[0].depth; | |
2206 | uint16_t *lut16; | ||
2207 | uint8_t *lut8; | ||
2208 | |||
2209 | ✗ | if (av_image_check_size(test->w, test->h, 0, ctx) < 0) | |
2210 | ✗ | return AVERROR(EINVAL); | |
2211 | |||
2212 | ✗ | test->lut = av_calloc(lut_size, sizeof(*test->lut) * ((depth + 7) / 8)); | |
2213 | ✗ | if (!test->lut) | |
2214 | ✗ | return AVERROR(ENOMEM); | |
2215 | |||
2216 | ✗ | lut8 = test->lut; | |
2217 | ✗ | lut16 = (uint16_t *)test->lut; | |
2218 | ✗ | switch (depth) { | |
2219 | ✗ | case 8: | |
2220 | ✗ | for (int i = 0; i < lut_size; i++) | |
2221 | ✗ | lut8[i] = lrintf(255.f * (0.5f + 0.5f * sinf((2.f * M_PI * i) / lut_size))); | |
2222 | ✗ | break; | |
2223 | ✗ | default: | |
2224 | ✗ | for (int i = 0; i < lut_size; i++) | |
2225 | ✗ | lut16[i] = lrintf(((1 << depth) - 1) * (0.5f + 0.5f * sinf((2.f * M_PI * i) / lut_size))); | |
2226 | ✗ | break; | |
2227 | } | ||
2228 | |||
2229 | ✗ | test->draw_once = 0; | |
2230 | ✗ | test->fill_picture_fn = zoneplate_fill_picture; | |
2231 | |||
2232 | ✗ | switch (depth) { | |
2233 | ✗ | case 8: test->fill_slice_fn = zoneplate_fill_slice_8; break; | |
2234 | ✗ | case 9: test->fill_slice_fn = zoneplate_fill_slice_9; break; | |
2235 | ✗ | case 10: test->fill_slice_fn = zoneplate_fill_slice_10; break; | |
2236 | ✗ | case 12: test->fill_slice_fn = zoneplate_fill_slice_12; break; | |
2237 | ✗ | case 14: test->fill_slice_fn = zoneplate_fill_slice_14; break; | |
2238 | ✗ | case 16: test->fill_slice_fn = zoneplate_fill_slice_16; break; | |
2239 | } | ||
2240 | ✗ | return config_props(outlink); | |
2241 | } | ||
2242 | |||
2243 | static const enum AVPixelFormat zoneplate_pix_fmts[] = { | ||
2244 | AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV444P9, | ||
2245 | AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUV444P12, | ||
2246 | AV_PIX_FMT_YUV444P14, AV_PIX_FMT_YUV444P16, | ||
2247 | AV_PIX_FMT_NONE, | ||
2248 | }; | ||
2249 | |||
2250 | ✗ | static int zoneplate_query_formats(const AVFilterContext *ctx, | |
2251 | AVFilterFormatsConfig **cfg_in, | ||
2252 | AVFilterFormatsConfig **cfg_out) | ||
2253 | { | ||
2254 | int ret; | ||
2255 | ✗ | if ((ret = ff_set_common_color_ranges2(ctx, cfg_in, cfg_out, | |
2256 | ff_make_formats_list_singleton(AVCOL_RANGE_JPEG)))) | ||
2257 | ✗ | return ret; | |
2258 | ✗ | return ff_set_common_formats_from_list2(ctx, cfg_in, cfg_out, zoneplate_pix_fmts); | |
2259 | } | ||
2260 | |||
2261 | static const AVFilterPad avfilter_vsrc_zoneplate_outputs[] = { | ||
2262 | { | ||
2263 | .name = "default", | ||
2264 | .type = AVMEDIA_TYPE_VIDEO, | ||
2265 | .config_props = zoneplate_config_props, | ||
2266 | }, | ||
2267 | }; | ||
2268 | |||
2269 | const FFFilter ff_vsrc_zoneplate = { | ||
2270 | .p.name = "zoneplate", | ||
2271 | .p.description = NULL_IF_CONFIG_SMALL("Generate zone-plate."), | ||
2272 | .p.priv_class = &zoneplate_class, | ||
2273 | .p.flags = AVFILTER_FLAG_SLICE_THREADS, | ||
2274 | .priv_size = sizeof(TestSourceContext), | ||
2275 | .init = init, | ||
2276 | .uninit = uninit, | ||
2277 | .activate = activate, | ||
2278 | FILTER_OUTPUTS(avfilter_vsrc_zoneplate_outputs), | ||
2279 | FILTER_QUERY_FUNC2(zoneplate_query_formats), | ||
2280 | .process_command = ff_filter_process_command, | ||
2281 | }; | ||
2282 | |||
2283 | #endif /* CONFIG_ZONEPLATE_FILTER */ | ||
2284 |