FFmpeg
vsrc_testsrc.c
Go to the documentation of this file.
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 <float.h>
37 
38 #include "libavutil/avassert.h"
39 #include "libavutil/common.h"
40 #include "libavutil/ffmath.h"
41 #include "libavutil/opt.h"
42 #include "libavutil/imgutils.h"
43 #include "libavutil/intreadwrite.h"
44 #include "libavutil/parseutils.h"
46 #include "avfilter.h"
47 #include "drawutils.h"
48 #include "filters.h"
49 #include "formats.h"
50 #include "internal.h"
51 #include "video.h"
52 
53 typedef struct TestSourceContext {
54  const AVClass *class;
55  int w, h;
56  unsigned int nb_frame;
58  int64_t pts;
59  int64_t duration; ///< duration expressed in microseconds
60  AVRational sar; ///< sample aspect ratio
61  int draw_once; ///< draw only the first frame, always put out the same picture
62  int draw_once_reset; ///< draw only the first frame or in case of reset
63  AVFrame *picref; ///< cached reference containing the painted picture
64 
66 
67  /* only used by testsrc */
69 
70  /* only used by testsrc2 */
71  int alpha;
72 
73  /* only used by colorspectrum */
74  int type;
75 
76  /* only used by color */
79  uint8_t color_rgba[4];
80 
81  /* only used by rgbtest */
82  uint8_t rgba_map[4];
84  int depth;
85 
86  /* only used by haldclut */
87  int level;
89 
90 #define OFFSET(x) offsetof(TestSourceContext, x)
91 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
92 #define FLAGSR AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
93 
94 #define SIZE_OPTIONS \
95  { "size", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "320x240"}, 0, 0, FLAGS },\
96  { "s", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "320x240"}, 0, 0, FLAGS },\
97 
98 #define COMMON_OPTIONS_NOSIZE \
99  { "rate", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, INT_MAX, FLAGS },\
100  { "r", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, INT_MAX, FLAGS },\
101  { "duration", "set video duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = -1}, -1, INT64_MAX, FLAGS },\
102  { "d", "set video duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = -1}, -1, INT64_MAX, FLAGS },\
103  { "sar", "set video sample aspect ratio", OFFSET(sar), AV_OPT_TYPE_RATIONAL, {.dbl= 1}, 0, INT_MAX, FLAGS },
104 
105 #define COMMON_OPTIONS SIZE_OPTIONS COMMON_OPTIONS_NOSIZE
106 
107 #define NOSIZE_OPTIONS_OFFSET 2
108 /* Filters using COMMON_OPTIONS_NOSIZE also use the following options
109  * via &options[NOSIZE_OPTIONS_OFFSET]. So don't break it. */
110 static const AVOption options[] = {
112  { NULL }
113 };
114 
116 {
117  TestSourceContext *test = ctx->priv;
118 
119  test->time_base = av_inv_q(test->frame_rate);
120  test->nb_frame = 0;
121  test->pts = 0;
122 
123  av_log(ctx, AV_LOG_VERBOSE, "size:%dx%d rate:%d/%d duration:%f sar:%d/%d\n",
124  test->w, test->h, test->frame_rate.num, test->frame_rate.den,
125  test->duration < 0 ? -1 : (double)test->duration/1000000,
126  test->sar.num, test->sar.den);
127  return 0;
128 }
129 
131 {
132  TestSourceContext *test = ctx->priv;
133 
134  av_frame_free(&test->picref);
135 }
136 
137 static int config_props(AVFilterLink *outlink)
138 {
139  TestSourceContext *test = outlink->src->priv;
140 
141  outlink->w = test->w;
142  outlink->h = test->h;
143  outlink->sample_aspect_ratio = test->sar;
144  outlink->frame_rate = test->frame_rate;
145  outlink->time_base = test->time_base;
146 
147  return 0;
148 }
149 
151 {
152  AVFilterLink *outlink = ctx->outputs[0];
153  TestSourceContext *test = ctx->priv;
154  AVFrame *frame;
155 
156  if (!ff_outlink_frame_wanted(outlink))
157  return FFERROR_NOT_READY;
158  if (test->duration >= 0 &&
159  av_rescale_q(test->pts, test->time_base, AV_TIME_BASE_Q) >= test->duration) {
160  ff_outlink_set_status(outlink, AVERROR_EOF, test->pts);
161  return 0;
162  }
163 
164  if (test->draw_once) {
165  if (test->draw_once_reset) {
166  av_frame_free(&test->picref);
167  test->draw_once_reset = 0;
168  }
169  if (!test->picref) {
170  test->picref =
171  ff_get_video_buffer(outlink, test->w, test->h);
172  if (!test->picref)
173  return AVERROR(ENOMEM);
174  test->fill_picture_fn(outlink->src, test->picref);
175  }
176  frame = av_frame_clone(test->picref);
177  } else
178  frame = ff_get_video_buffer(outlink, test->w, test->h);
179 
180  if (!frame)
181  return AVERROR(ENOMEM);
182  frame->pts = test->pts;
183  frame->key_frame = 1;
184  frame->interlaced_frame = 0;
185  frame->pict_type = AV_PICTURE_TYPE_I;
186  frame->sample_aspect_ratio = test->sar;
187  if (!test->draw_once)
188  test->fill_picture_fn(outlink->src, frame);
189 
190  test->pts++;
191  test->nb_frame++;
192 
193  return ff_filter_frame(outlink, frame);
194 }
195 
196 #if CONFIG_COLOR_FILTER
197 
198 static const AVOption color_options[] = {
199  { "color", "set color", OFFSET(color_rgba), AV_OPT_TYPE_COLOR, {.str = "black"}, 0, 0, FLAGSR },
200  { "c", "set color", OFFSET(color_rgba), AV_OPT_TYPE_COLOR, {.str = "black"}, 0, 0, FLAGSR },
202  { NULL }
203 };
204 
206 
207 static void color_fill_picture(AVFilterContext *ctx, AVFrame *picref)
208 {
209  TestSourceContext *test = ctx->priv;
210  ff_fill_rectangle(&test->draw, &test->color,
211  picref->data, picref->linesize,
212  0, 0, test->w, test->h);
213 }
214 
215 static av_cold int color_init(AVFilterContext *ctx)
216 {
217  TestSourceContext *test = ctx->priv;
218  test->fill_picture_fn = color_fill_picture;
219  test->draw_once = 1;
220  return init(ctx);
221 }
222 
223 static int color_query_formats(AVFilterContext *ctx)
224 {
226 }
227 
228 static int color_config_props(AVFilterLink *inlink)
229 {
230  AVFilterContext *ctx = inlink->src;
231  TestSourceContext *test = ctx->priv;
232  int ret;
233 
234  ff_draw_init(&test->draw, inlink->format, 0);
235  ff_draw_color(&test->draw, &test->color, test->color_rgba);
236 
237  test->w = ff_draw_round_to_sub(&test->draw, 0, -1, test->w);
238  test->h = ff_draw_round_to_sub(&test->draw, 1, -1, test->h);
239  if (av_image_check_size(test->w, test->h, 0, ctx) < 0)
240  return AVERROR(EINVAL);
241 
242  if ((ret = config_props(inlink)) < 0)
243  return ret;
244 
245  return 0;
246 }
247 
248 static int color_process_command(AVFilterContext *ctx, const char *cmd, const char *args,
249  char *res, int res_len, int flags)
250 {
251  TestSourceContext *test = ctx->priv;
252  int ret;
253 
254  ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags);
255  if (ret < 0)
256  return ret;
257 
258  ff_draw_color(&test->draw, &test->color, test->color_rgba);
259  test->draw_once_reset = 1;
260  return 0;
261 }
262 
263 static const AVFilterPad color_outputs[] = {
264  {
265  .name = "default",
266  .type = AVMEDIA_TYPE_VIDEO,
267  .config_props = color_config_props,
268  },
269 };
270 
271 const AVFilter ff_vsrc_color = {
272  .name = "color",
273  .description = NULL_IF_CONFIG_SMALL("Provide an uniformly colored input."),
274  .priv_class = &color_class,
275  .priv_size = sizeof(TestSourceContext),
276  .init = color_init,
277  .uninit = uninit,
278  .activate = activate,
279  .inputs = NULL,
280  FILTER_OUTPUTS(color_outputs),
281  FILTER_QUERY_FUNC(color_query_formats),
282  .process_command = color_process_command,
283 };
284 
285 #endif /* CONFIG_COLOR_FILTER */
286 
287 #if CONFIG_HALDCLUTSRC_FILTER
288 
289 static const AVOption haldclutsrc_options[] = {
290  { "level", "set level", OFFSET(level), AV_OPT_TYPE_INT, {.i64 = 6}, 2, 16, FLAGS },
292  { NULL }
293 };
294 
295 AVFILTER_DEFINE_CLASS(haldclutsrc);
296 
297 static void haldclutsrc_fill_picture(AVFilterContext *ctx, AVFrame *frame)
298 {
299  int i, j, k, x = 0, y = 0, is16bit = 0, step;
300  uint32_t alpha = 0;
301  const TestSourceContext *hc = ctx->priv;
302  int level = hc->level;
303  float scale;
304  const int w = frame->width;
305  const int h = frame->height;
306  const uint8_t *data = frame->data[0];
307  const int linesize = frame->linesize[0];
309  const int depth = desc->comp[0].depth;
310  const int planar = desc->flags & AV_PIX_FMT_FLAG_PLANAR;
311  const int planes = av_pix_fmt_count_planes(frame->format);
312  uint8_t rgba_map[4];
313 
314  av_assert0(w == h && w == level*level*level);
315 
316  ff_fill_rgba_map(rgba_map, frame->format);
317 
318  alpha = (1 << depth) - 1;
319  is16bit = depth > 8;
320 
321  step = av_get_padded_bits_per_pixel(desc) >> (3 + is16bit);
322  scale = ((float)alpha) / (level*level - 1);
323 
324 #define LOAD_CLUT(nbits) do { \
325  uint##nbits##_t *dst = ((uint##nbits##_t *)(data + y*linesize)) + x*step; \
326  dst[rgba_map[0]] = av_clip_uint##nbits(i * scale); \
327  dst[rgba_map[1]] = av_clip_uint##nbits(j * scale); \
328  dst[rgba_map[2]] = av_clip_uint##nbits(k * scale); \
329  if (step == 4) \
330  dst[rgba_map[3]] = alpha; \
331 } while (0)
332 
333 #define LOAD_CLUT_PLANAR(type, nbits) do { \
334  type *dst = ((type *)(frame->data[2] + y*frame->linesize[2])) + x; \
335  dst[0] = av_clip_uintp2(i * scale, nbits); \
336  dst = ((type *)(frame->data[0] + y*frame->linesize[0])) + x; \
337  dst[0] = av_clip_uintp2(j * scale, nbits); \
338  dst = ((type *)(frame->data[1] + y*frame->linesize[1])) + x; \
339  dst[0] = av_clip_uintp2(k * scale, nbits); \
340  if (planes == 4) { \
341  dst = ((type *)(frame->data[3] + y*linesize)) + x; \
342  dst[0] = alpha; \
343  } \
344 } while (0)
345 
346  level *= level;
347  for (k = 0; k < level; k++) {
348  for (j = 0; j < level; j++) {
349  for (i = 0; i < level; i++) {
350  if (!planar) {
351  if (!is16bit)
352  LOAD_CLUT(8);
353  else
354  LOAD_CLUT(16);
355  } else {
356  switch (depth) {
357  case 8: LOAD_CLUT_PLANAR(uint8_t, 8); break;
358  case 9: LOAD_CLUT_PLANAR(uint16_t, 9); break;
359  case 10: LOAD_CLUT_PLANAR(uint16_t,10); break;
360  case 12: LOAD_CLUT_PLANAR(uint16_t,12); break;
361  case 14: LOAD_CLUT_PLANAR(uint16_t,14); break;
362  case 16: LOAD_CLUT_PLANAR(uint16_t,16); break;
363  }
364  }
365  if (++x == w) {
366  x = 0;
367  y++;
368  }
369  }
370  }
371  }
372 }
373 
374 static av_cold int haldclutsrc_init(AVFilterContext *ctx)
375 {
376  TestSourceContext *hc = ctx->priv;
377  hc->fill_picture_fn = haldclutsrc_fill_picture;
378  hc->draw_once = 1;
379  return init(ctx);
380 }
381 
382 static const enum AVPixelFormat haldclutsrc_pix_fmts[] = {
397 };
398 
399 static int haldclutsrc_config_props(AVFilterLink *outlink)
400 {
401  AVFilterContext *ctx = outlink->src;
402  TestSourceContext *hc = ctx->priv;
403 
404  hc->w = hc->h = hc->level * hc->level * hc->level;
405  return config_props(outlink);
406 }
407 
408 static const AVFilterPad haldclutsrc_outputs[] = {
409  {
410  .name = "default",
411  .type = AVMEDIA_TYPE_VIDEO,
412  .config_props = haldclutsrc_config_props,
413  },
414 };
415 
417  .name = "haldclutsrc",
418  .description = NULL_IF_CONFIG_SMALL("Provide an identity Hald CLUT."),
419  .priv_class = &haldclutsrc_class,
420  .priv_size = sizeof(TestSourceContext),
421  .init = haldclutsrc_init,
422  .uninit = uninit,
423  .activate = activate,
424  .inputs = NULL,
425  FILTER_OUTPUTS(haldclutsrc_outputs),
426  FILTER_PIXFMTS_ARRAY(haldclutsrc_pix_fmts),
427 };
428 #endif /* CONFIG_HALDCLUTSRC_FILTER */
429 
430 AVFILTER_DEFINE_CLASS_EXT(nullsrc_yuvtestsrc, "nullsrc/yuvtestsrc", options);
431 
432 #if CONFIG_NULLSRC_FILTER
433 
434 static void nullsrc_fill_picture(AVFilterContext *ctx, AVFrame *picref) { }
435 
436 static av_cold int nullsrc_init(AVFilterContext *ctx)
437 {
438  TestSourceContext *test = ctx->priv;
439 
440  test->fill_picture_fn = nullsrc_fill_picture;
441  return init(ctx);
442 }
443 
444 static const AVFilterPad nullsrc_outputs[] = {
445  {
446  .name = "default",
447  .type = AVMEDIA_TYPE_VIDEO,
448  .config_props = config_props,
449  },
450 };
451 
452 const AVFilter ff_vsrc_nullsrc = {
453  .name = "nullsrc",
454  .description = NULL_IF_CONFIG_SMALL("Null video source, return unprocessed video frames."),
455  .priv_class = &nullsrc_yuvtestsrc_class,
456  .init = nullsrc_init,
457  .uninit = uninit,
458  .activate = activate,
459  .priv_size = sizeof(TestSourceContext),
460  .inputs = NULL,
461  FILTER_OUTPUTS(nullsrc_outputs),
462 };
463 
464 #endif /* CONFIG_NULLSRC_FILTER */
465 
466 #if CONFIG_TESTSRC_FILTER
467 
468 static const AVOption testsrc_options[] = {
470  { "decimals", "set number of decimals to show", OFFSET(nb_decimals), AV_OPT_TYPE_INT, {.i64=0}, 0, 17, FLAGS },
471  { "n", "set number of decimals to show", OFFSET(nb_decimals), AV_OPT_TYPE_INT, {.i64=0}, 0, 17, FLAGS },
472  { NULL }
473 };
474 
475 AVFILTER_DEFINE_CLASS(testsrc);
476 
477 /**
478  * Fill a rectangle with value val.
479  *
480  * @param val the RGB value to set
481  * @param dst pointer to the destination buffer to fill
482  * @param dst_linesize linesize of destination
483  * @param segment_width width of the segment
484  * @param x horizontal coordinate where to draw the rectangle in the destination buffer
485  * @param y horizontal coordinate where to draw the rectangle in the destination buffer
486  * @param w width of the rectangle to draw, expressed as a number of segment_width units
487  * @param h height of the rectangle to draw, expressed as a number of segment_width units
488  */
489 static void draw_rectangle(unsigned val, uint8_t *dst, int dst_linesize, int segment_width,
490  int x, int y, int w, int h)
491 {
492  int i;
493  int step = 3;
494 
495  dst += segment_width * (step * x + y * dst_linesize);
496  w *= segment_width * step;
497  h *= segment_width;
498  for (i = 0; i < h; i++) {
499  memset(dst, val, w);
500  dst += dst_linesize;
501  }
502 }
503 
504 static void draw_digit(int digit, uint8_t *dst, int dst_linesize,
505  int segment_width)
506 {
507 #define TOP_HBAR 1
508 #define MID_HBAR 2
509 #define BOT_HBAR 4
510 #define LEFT_TOP_VBAR 8
511 #define LEFT_BOT_VBAR 16
512 #define RIGHT_TOP_VBAR 32
513 #define RIGHT_BOT_VBAR 64
514  struct segments {
515  int x, y, w, h;
516  } segments[] = {
517  { 1, 0, 5, 1 }, /* TOP_HBAR */
518  { 1, 6, 5, 1 }, /* MID_HBAR */
519  { 1, 12, 5, 1 }, /* BOT_HBAR */
520  { 0, 1, 1, 5 }, /* LEFT_TOP_VBAR */
521  { 0, 7, 1, 5 }, /* LEFT_BOT_VBAR */
522  { 6, 1, 1, 5 }, /* RIGHT_TOP_VBAR */
523  { 6, 7, 1, 5 } /* RIGHT_BOT_VBAR */
524  };
525  static const unsigned char masks[10] = {
526  /* 0 */ TOP_HBAR |BOT_HBAR|LEFT_TOP_VBAR|LEFT_BOT_VBAR|RIGHT_TOP_VBAR|RIGHT_BOT_VBAR,
527  /* 1 */ RIGHT_TOP_VBAR|RIGHT_BOT_VBAR,
528  /* 2 */ TOP_HBAR|MID_HBAR|BOT_HBAR|LEFT_BOT_VBAR |RIGHT_TOP_VBAR,
529  /* 3 */ TOP_HBAR|MID_HBAR|BOT_HBAR |RIGHT_TOP_VBAR|RIGHT_BOT_VBAR,
530  /* 4 */ MID_HBAR |LEFT_TOP_VBAR |RIGHT_TOP_VBAR|RIGHT_BOT_VBAR,
531  /* 5 */ TOP_HBAR|BOT_HBAR|MID_HBAR|LEFT_TOP_VBAR |RIGHT_BOT_VBAR,
532  /* 6 */ TOP_HBAR|BOT_HBAR|MID_HBAR|LEFT_TOP_VBAR|LEFT_BOT_VBAR |RIGHT_BOT_VBAR,
533  /* 7 */ TOP_HBAR |RIGHT_TOP_VBAR|RIGHT_BOT_VBAR,
534  /* 8 */ TOP_HBAR|BOT_HBAR|MID_HBAR|LEFT_TOP_VBAR|LEFT_BOT_VBAR|RIGHT_TOP_VBAR|RIGHT_BOT_VBAR,
535  /* 9 */ TOP_HBAR|BOT_HBAR|MID_HBAR|LEFT_TOP_VBAR |RIGHT_TOP_VBAR|RIGHT_BOT_VBAR,
536  };
537  unsigned mask = masks[digit];
538  int i;
539 
540  draw_rectangle(0, dst, dst_linesize, segment_width, 0, 0, 8, 13);
541  for (i = 0; i < FF_ARRAY_ELEMS(segments); i++)
542  if (mask & (1<<i))
543  draw_rectangle(255, dst, dst_linesize, segment_width,
544  segments[i].x, segments[i].y, segments[i].w, segments[i].h);
545 }
546 
547 #define GRADIENT_SIZE (6 * 256)
548 
549 static void test_fill_picture(AVFilterContext *ctx, AVFrame *frame)
550 {
551  TestSourceContext *test = ctx->priv;
552  uint8_t *p, *p0;
553  int x, y;
554  int color, color_rest;
555  int icolor;
556  int radius;
557  int quad0, quad;
558  int dquad_x, dquad_y;
559  int grad, dgrad, rgrad, drgrad;
560  int seg_size;
561  int second;
562  int i;
563  uint8_t *data = frame->data[0];
564  int width = frame->width;
565  int height = frame->height;
566 
567  /* draw colored bars and circle */
568  radius = (width + height) / 4;
569  quad0 = width * width / 4 + height * height / 4 - radius * radius;
570  dquad_y = 1 - height;
571  p0 = data;
572  for (y = 0; y < height; y++) {
573  p = p0;
574  color = 0;
575  color_rest = 0;
576  quad = quad0;
577  dquad_x = 1 - width;
578  for (x = 0; x < width; x++) {
579  icolor = color;
580  if (quad < 0)
581  icolor ^= 7;
582  quad += dquad_x;
583  dquad_x += 2;
584  *(p++) = icolor & 1 ? 255 : 0;
585  *(p++) = icolor & 2 ? 255 : 0;
586  *(p++) = icolor & 4 ? 255 : 0;
587  color_rest += 8;
588  if (color_rest >= width) {
589  color_rest -= width;
590  color++;
591  }
592  }
593  quad0 += dquad_y;
594  dquad_y += 2;
595  p0 += frame->linesize[0];
596  }
597 
598  /* draw sliding color line */
599  p0 = p = data + frame->linesize[0] * (height * 3/4);
600  grad = (256 * test->nb_frame * test->time_base.num / test->time_base.den) %
601  GRADIENT_SIZE;
602  rgrad = 0;
603  dgrad = GRADIENT_SIZE / width;
604  drgrad = GRADIENT_SIZE % width;
605  for (x = 0; x < width; x++) {
606  *(p++) =
607  grad < 256 || grad >= 5 * 256 ? 255 :
608  grad >= 2 * 256 && grad < 4 * 256 ? 0 :
609  grad < 2 * 256 ? 2 * 256 - 1 - grad : grad - 4 * 256;
610  *(p++) =
611  grad >= 4 * 256 ? 0 :
612  grad >= 1 * 256 && grad < 3 * 256 ? 255 :
613  grad < 1 * 256 ? grad : 4 * 256 - 1 - grad;
614  *(p++) =
615  grad < 2 * 256 ? 0 :
616  grad >= 3 * 256 && grad < 5 * 256 ? 255 :
617  grad < 3 * 256 ? grad - 2 * 256 : 6 * 256 - 1 - grad;
618  grad += dgrad;
619  rgrad += drgrad;
620  if (rgrad >= GRADIENT_SIZE) {
621  grad++;
622  rgrad -= GRADIENT_SIZE;
623  }
624  if (grad >= GRADIENT_SIZE)
625  grad -= GRADIENT_SIZE;
626  }
627  p = p0;
628  for (y = height / 8; y > 0; y--) {
629  memcpy(p+frame->linesize[0], p, 3 * width);
630  p += frame->linesize[0];
631  }
632 
633  /* draw digits */
634  seg_size = width / 80;
635  if (seg_size >= 1 && height >= 13 * seg_size) {
636  int64_t p10decimals = 1;
637  double time = av_q2d(test->time_base) * test->nb_frame *
638  ff_exp10(test->nb_decimals);
639  if (time >= INT_MAX)
640  return;
641 
642  for (x = 0; x < test->nb_decimals; x++)
643  p10decimals *= 10;
644 
645  second = av_rescale_rnd(test->nb_frame * test->time_base.num, p10decimals, test->time_base.den, AV_ROUND_ZERO);
646  x = width - (width - seg_size * 64) / 2;
647  y = (height - seg_size * 13) / 2;
648  p = data + (x*3 + y * frame->linesize[0]);
649  for (i = 0; i < 8; i++) {
650  p -= 3 * 8 * seg_size;
651  draw_digit(second % 10, p, frame->linesize[0], seg_size);
652  second /= 10;
653  if (second == 0)
654  break;
655  }
656  }
657 }
658 
659 static av_cold int test_init(AVFilterContext *ctx)
660 {
661  TestSourceContext *test = ctx->priv;
662 
663  test->fill_picture_fn = test_fill_picture;
664  return init(ctx);
665 }
666 
667 static const AVFilterPad avfilter_vsrc_testsrc_outputs[] = {
668  {
669  .name = "default",
670  .type = AVMEDIA_TYPE_VIDEO,
671  .config_props = config_props,
672  },
673 };
674 
675 const AVFilter ff_vsrc_testsrc = {
676  .name = "testsrc",
677  .description = NULL_IF_CONFIG_SMALL("Generate test pattern."),
678  .priv_size = sizeof(TestSourceContext),
679  .priv_class = &testsrc_class,
680  .init = test_init,
681  .uninit = uninit,
682  .activate = activate,
683  .inputs = NULL,
684  FILTER_OUTPUTS(avfilter_vsrc_testsrc_outputs),
686 };
687 
688 #endif /* CONFIG_TESTSRC_FILTER */
689 
690 #if CONFIG_TESTSRC2_FILTER
691 
692 static const AVOption testsrc2_options[] = {
694  { "alpha", "set global alpha (opacity)", OFFSET(alpha), AV_OPT_TYPE_INT, {.i64 = 255}, 0, 255, FLAGS },
695  { NULL }
696 };
697 
698 AVFILTER_DEFINE_CLASS(testsrc2);
699 
700 static void set_color(TestSourceContext *s, FFDrawColor *color, uint32_t argb)
701 {
702  uint8_t rgba[4] = { (argb >> 16) & 0xFF,
703  (argb >> 8) & 0xFF,
704  (argb >> 0) & 0xFF,
705  (argb >> 24) & 0xFF, };
706  ff_draw_color(&s->draw, color, rgba);
707 }
708 
709 static uint32_t color_gradient(unsigned index)
710 {
711  unsigned si = index & 0xFF, sd = 0xFF - si;
712  switch (index >> 8) {
713  case 0: return 0xFF0000 + (si << 8);
714  case 1: return 0x00FF00 + (sd << 16);
715  case 2: return 0x00FF00 + (si << 0);
716  case 3: return 0x0000FF + (sd << 8);
717  case 4: return 0x0000FF + (si << 16);
718  case 5: return 0xFF0000 + (sd << 0);
719  default: av_assert0(0); return 0;
720  }
721 }
722 
724  int x0, int y0, const uint8_t *text)
725 {
726  int x = x0;
727 
728  for (; *text; text++) {
729  if (*text == '\n') {
730  x = x0;
731  y0 += 16;
732  continue;
733  }
734  ff_blend_mask(&s->draw, color, frame->data, frame->linesize,
735  frame->width, frame->height,
736  avpriv_vga16_font + *text * 16, 1, 8, 16, 0, 0, x, y0);
737  x += 8;
738  }
739 }
740 
741 static void test2_fill_picture(AVFilterContext *ctx, AVFrame *frame)
742 {
743  TestSourceContext *s = ctx->priv;
745  unsigned alpha = (uint32_t)s->alpha << 24;
746 
747  /* colored background */
748  {
749  unsigned i, x = 0, x2;
750 
751  x = 0;
752  for (i = 1; i < 7; i++) {
753  x2 = av_rescale(i, s->w, 6);
754  x2 = ff_draw_round_to_sub(&s->draw, 0, 0, x2);
755  set_color(s, &color, ((i & 1) ? 0xFF0000 : 0) |
756  ((i & 2) ? 0x00FF00 : 0) |
757  ((i & 4) ? 0x0000FF : 0) |
758  alpha);
759  ff_fill_rectangle(&s->draw, &color, frame->data, frame->linesize,
760  x, 0, x2 - x, frame->height);
761  x = x2;
762  }
763  }
764 
765  /* oblique gradient */
766  /* note: too slow if using blending */
767  if (s->h >= 64) {
768  unsigned x, dx, y0, y, g0, g;
769 
770  dx = ff_draw_round_to_sub(&s->draw, 0, +1, 1);
771  y0 = av_rescale_q(s->pts, s->time_base, av_make_q(2, s->h - 16));
772  g0 = av_rescale_q(s->pts, s->time_base, av_make_q(1, 128));
773  for (x = 0; x < s->w; x += dx) {
774  g = (av_rescale(x, 6 * 256, s->w) + g0) % (6 * 256);
775  set_color(s, &color, color_gradient(g) | alpha);
776  y = y0 + av_rescale(x, s->h / 2, s->w);
777  y %= 2 * (s->h - 16);
778  if (y > s->h - 16)
779  y = 2 * (s->h - 16) - y;
780  y = ff_draw_round_to_sub(&s->draw, 1, 0, y);
781  ff_fill_rectangle(&s->draw, &color, frame->data, frame->linesize,
782  x, y, dx, 16);
783  }
784  }
785 
786  /* top right: draw clock hands */
787  if (s->w >= 64 && s->h >= 64) {
788  int l = (FFMIN(s->w, s->h) - 32) >> 1;
789  int steps = FFMAX(4, l >> 5);
790  int xc = (s->w >> 2) + (s->w >> 1);
791  int yc = (s->h >> 2);
792  int cycle = l << 2;
793  int pos, xh, yh;
794  int c, i;
795 
796  for (c = 0; c < 3; c++) {
797  set_color(s, &color, (0xBBBBBB ^ (0xFF << (c << 3))) | alpha);
798  pos = av_rescale_q(s->pts, s->time_base, av_make_q(64 >> (c << 1), cycle)) % cycle;
799  xh = pos < 1 * l ? pos :
800  pos < 2 * l ? l :
801  pos < 3 * l ? 3 * l - pos : 0;
802  yh = pos < 1 * l ? 0 :
803  pos < 2 * l ? pos - l :
804  pos < 3 * l ? l :
805  cycle - pos;
806  xh -= l >> 1;
807  yh -= l >> 1;
808  for (i = 1; i <= steps; i++) {
809  int x = av_rescale(xh, i, steps) + xc;
810  int y = av_rescale(yh, i, steps) + yc;
811  x = ff_draw_round_to_sub(&s->draw, 0, -1, x);
812  y = ff_draw_round_to_sub(&s->draw, 1, -1, y);
813  ff_fill_rectangle(&s->draw, &color, frame->data, frame->linesize,
814  x, y, 8, 8);
815  }
816  }
817  }
818 
819  /* bottom left: beating rectangles */
820  if (s->w >= 64 && s->h >= 64) {
821  int l = (FFMIN(s->w, s->h) - 16) >> 2;
822  int cycle = l << 3;
823  int xc = (s->w >> 2);
824  int yc = (s->h >> 2) + (s->h >> 1);
825  int xm1 = ff_draw_round_to_sub(&s->draw, 0, -1, xc - 8);
826  int xm2 = ff_draw_round_to_sub(&s->draw, 0, +1, xc + 8);
827  int ym1 = ff_draw_round_to_sub(&s->draw, 1, -1, yc - 8);
828  int ym2 = ff_draw_round_to_sub(&s->draw, 1, +1, yc + 8);
829  int size, step, x1, x2, y1, y2;
830 
831  size = av_rescale_q(s->pts, s->time_base, av_make_q(4, cycle));
832  step = size / l;
833  size %= l;
834  if (step & 1)
835  size = l - size;
836  step = (step >> 1) & 3;
837  set_color(s, &color, 0xFF808080);
838  x1 = ff_draw_round_to_sub(&s->draw, 0, -1, xc - 4 - size);
839  x2 = ff_draw_round_to_sub(&s->draw, 0, +1, xc + 4 + size);
840  y1 = ff_draw_round_to_sub(&s->draw, 1, -1, yc - 4 - size);
841  y2 = ff_draw_round_to_sub(&s->draw, 1, +1, yc + 4 + size);
842  if (step == 0 || step == 2)
843  ff_fill_rectangle(&s->draw, &color, frame->data, frame->linesize,
844  x1, ym1, x2 - x1, ym2 - ym1);
845  if (step == 1 || step == 2)
846  ff_fill_rectangle(&s->draw, &color, frame->data, frame->linesize,
847  xm1, y1, xm2 - xm1, y2 - y1);
848  if (step == 3)
849  ff_fill_rectangle(&s->draw, &color, frame->data, frame->linesize,
850  x1, y1, x2 - x1, y2 - y1);
851  }
852 
853  /* bottom right: checker with random noise */
854  {
855  unsigned xmin = av_rescale(5, s->w, 8);
856  unsigned xmax = av_rescale(7, s->w, 8);
857  unsigned ymin = av_rescale(5, s->h, 8);
858  unsigned ymax = av_rescale(7, s->h, 8);
859  unsigned x, y, i, r;
860  uint8_t alpha[256];
861 
862  r = s->pts;
863  for (y = ymin; y + 15 < ymax; y += 16) {
864  for (x = xmin; x + 15 < xmax; x += 16) {
865  if ((x ^ y) & 16)
866  continue;
867  for (i = 0; i < 256; i++) {
868  r = r * 1664525 + 1013904223;
869  alpha[i] = r >> 24;
870  }
871  set_color(s, &color, 0xFF00FF80);
872  ff_blend_mask(&s->draw, &color, frame->data, frame->linesize,
873  frame->width, frame->height,
874  alpha, 16, 16, 16, 3, 0, x, y);
875  }
876  }
877  }
878 
879  /* bouncing square */
880  if (s->w >= 16 && s->h >= 16) {
881  unsigned w = s->w - 8;
882  unsigned h = s->h - 8;
883  unsigned x = av_rescale_q(s->pts, s->time_base, av_make_q(233, 55 * w)) % (w << 1);
884  unsigned y = av_rescale_q(s->pts, s->time_base, av_make_q(233, 89 * h)) % (h << 1);
885  if (x > w)
886  x = (w << 1) - x;
887  if (y > h)
888  y = (h << 1) - y;
889  x = ff_draw_round_to_sub(&s->draw, 0, -1, x);
890  y = ff_draw_round_to_sub(&s->draw, 1, -1, y);
891  set_color(s, &color, 0xFF8000FF);
892  ff_fill_rectangle(&s->draw, &color, frame->data, frame->linesize,
893  x, y, 8, 8);
894  }
895 
896  /* top right: draw frame time and frame number */
897  {
898  char buf[256];
899  unsigned time;
900 
901  time = av_rescale_q(s->pts, s->time_base, av_make_q(1, 1000)) % 86400000;
902  set_color(s, &color, 0xC0000000);
903  ff_blend_rectangle(&s->draw, &color, frame->data, frame->linesize,
904  frame->width, frame->height,
905  2, 2, 100, 36);
906  set_color(s, &color, 0xFFFF8000);
907  snprintf(buf, sizeof(buf), "%02d:%02d:%02d.%03d\n%12"PRIi64,
908  time / 3600000, (time / 60000) % 60, (time / 1000) % 60,
909  time % 1000, s->pts);
910  draw_text(s, frame, &color, 4, 4, buf);
911  }
912 }
913 static av_cold int test2_init(AVFilterContext *ctx)
914 {
915  TestSourceContext *s = ctx->priv;
916 
917  s->fill_picture_fn = test2_fill_picture;
918  return init(ctx);
919 }
920 
921 static int test2_query_formats(AVFilterContext *ctx)
922 {
924 }
925 
926 static int test2_config_props(AVFilterLink *inlink)
927 {
928  AVFilterContext *ctx = inlink->src;
929  TestSourceContext *s = ctx->priv;
930 
931  av_assert0(ff_draw_init(&s->draw, inlink->format, 0) >= 0);
932  s->w = ff_draw_round_to_sub(&s->draw, 0, -1, s->w);
933  s->h = ff_draw_round_to_sub(&s->draw, 1, -1, s->h);
934  if (av_image_check_size(s->w, s->h, 0, ctx) < 0)
935  return AVERROR(EINVAL);
936  return config_props(inlink);
937 }
938 
939 static const AVFilterPad avfilter_vsrc_testsrc2_outputs[] = {
940  {
941  .name = "default",
942  .type = AVMEDIA_TYPE_VIDEO,
943  .config_props = test2_config_props,
944  },
945 };
946 
947 const AVFilter ff_vsrc_testsrc2 = {
948  .name = "testsrc2",
949  .description = NULL_IF_CONFIG_SMALL("Generate another test pattern."),
950  .priv_size = sizeof(TestSourceContext),
951  .priv_class = &testsrc2_class,
952  .init = test2_init,
953  .uninit = uninit,
954  .activate = activate,
955  .inputs = NULL,
956  FILTER_OUTPUTS(avfilter_vsrc_testsrc2_outputs),
957  FILTER_QUERY_FUNC(test2_query_formats),
958 };
959 
960 #endif /* CONFIG_TESTSRC2_FILTER */
961 
962 #if CONFIG_RGBTESTSRC_FILTER
963 
964 static const AVOption rgbtestsrc_options[] = {
966  { "complement", "set complement colors", OFFSET(complement), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS },
967  { "co", "set complement colors", OFFSET(complement), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS },
968  { NULL }
969 };
970 
971 AVFILTER_DEFINE_CLASS(rgbtestsrc);
972 
973 #define R 0
974 #define G 1
975 #define B 2
976 #define A 3
977 
978 static void rgbtest_put_pixel(uint8_t *dstp[4], int dst_linesizep[4],
979  int x, int y, unsigned r, unsigned g, unsigned b, enum AVPixelFormat fmt,
980  uint8_t rgba_map[4])
981 {
982  uint8_t *dst = dstp[0];
983  int dst_linesize = dst_linesizep[0];
984  uint32_t v;
985  uint8_t *p;
986  uint16_t *p16;
987 
988  switch (fmt) {
989  case AV_PIX_FMT_BGR444: ((uint16_t*)(dst + y*dst_linesize))[x] = ((r >> 4) << 8) | ((g >> 4) << 4) | (b >> 4); break;
990  case AV_PIX_FMT_RGB444: ((uint16_t*)(dst + y*dst_linesize))[x] = ((b >> 4) << 8) | ((g >> 4) << 4) | (r >> 4); break;
991  case AV_PIX_FMT_BGR555: ((uint16_t*)(dst + y*dst_linesize))[x] = ((r>>3)<<10) | ((g>>3)<<5) | (b>>3); break;
992  case AV_PIX_FMT_RGB555: ((uint16_t*)(dst + y*dst_linesize))[x] = ((b>>3)<<10) | ((g>>3)<<5) | (r>>3); break;
993  case AV_PIX_FMT_BGR565: ((uint16_t*)(dst + y*dst_linesize))[x] = ((r>>3)<<11) | ((g>>2)<<5) | (b>>3); break;
994  case AV_PIX_FMT_RGB565: ((uint16_t*)(dst + y*dst_linesize))[x] = ((b>>3)<<11) | ((g>>2)<<5) | (r>>3); break;
995  case AV_PIX_FMT_RGB24:
996  case AV_PIX_FMT_BGR24:
997  v = (r << (rgba_map[R]*8)) + (g << (rgba_map[G]*8)) + (b << (rgba_map[B]*8));
998  p = dst + 3*x + y*dst_linesize;
999  AV_WL24(p, v);
1000  break;
1001  case AV_PIX_FMT_RGBA:
1002  case AV_PIX_FMT_BGRA:
1003  case AV_PIX_FMT_ARGB:
1004  case AV_PIX_FMT_ABGR:
1005  v = (r << (rgba_map[R]*8)) + (g << (rgba_map[G]*8)) + (b << (rgba_map[B]*8)) + (255U << (rgba_map[A]*8));
1006  p = dst + 4*x + y*dst_linesize;
1007  AV_WL32(p, v);
1008  break;
1009  case AV_PIX_FMT_GBRP:
1010  p = dstp[0] + x + y * dst_linesizep[0];
1011  p[0] = g;
1012  p = dstp[1] + x + y * dst_linesizep[1];
1013  p[0] = b;
1014  p = dstp[2] + x + y * dst_linesizep[2];
1015  p[0] = r;
1016  break;
1017  case AV_PIX_FMT_GBRP9:
1018  case AV_PIX_FMT_GBRP10:
1019  case AV_PIX_FMT_GBRP12:
1020  case AV_PIX_FMT_GBRP14:
1021  case AV_PIX_FMT_GBRP16:
1022  p16 = (uint16_t *)(dstp[0] + x*2 + y * dst_linesizep[0]);
1023  p16[0] = g;
1024  p16 = (uint16_t *)(dstp[1] + x*2 + y * dst_linesizep[1]);
1025  p16[0] = b;
1026  p16 = (uint16_t *)(dstp[2] + x*2 + y * dst_linesizep[2]);
1027  p16[0] = r;
1028  break;
1029  }
1030 }
1031 
1032 static void rgbtest_fill_picture_complement(AVFilterContext *ctx, AVFrame *frame)
1033 {
1034  TestSourceContext *test = ctx->priv;
1035  int x, y, w = frame->width, h = frame->height;
1036 
1037  for (y = 0; y < h; y++) {
1038  for (x = 0; x < w; x++) {
1039  int c = (1 << FFMAX(test->depth, 8))*x/w;
1040  int r = 0, g = 0, b = 0;
1041 
1042  if (6*y < h ) r = c;
1043  else if (6*y < 2*h) g = c, b = c;
1044  else if (6*y < 3*h) g = c;
1045  else if (6*y < 4*h) r = c, b = c;
1046  else if (6*y < 5*h) b = c;
1047  else r = c, g = c;
1048 
1049  rgbtest_put_pixel(frame->data, frame->linesize, x, y, r, g, b,
1050  ctx->outputs[0]->format, test->rgba_map);
1051  }
1052  }
1053 }
1054 
1055 static void rgbtest_fill_picture(AVFilterContext *ctx, AVFrame *frame)
1056 {
1057  TestSourceContext *test = ctx->priv;
1058  int x, y, w = frame->width, h = frame->height;
1059 
1060  for (y = 0; y < h; y++) {
1061  for (x = 0; x < w; x++) {
1062  int c = (1 << FFMAX(test->depth, 8))*x/w;
1063  int r = 0, g = 0, b = 0;
1064 
1065  if (3*y < h ) r = c;
1066  else if (3*y < 2*h) g = c;
1067  else b = c;
1068 
1069  rgbtest_put_pixel(frame->data, frame->linesize, x, y, r, g, b,
1070  ctx->outputs[0]->format, test->rgba_map);
1071  }
1072  }
1073 }
1074 
1075 static av_cold int rgbtest_init(AVFilterContext *ctx)
1076 {
1077  TestSourceContext *test = ctx->priv;
1078 
1079  test->draw_once = 1;
1080  test->fill_picture_fn = test->complement ? rgbtest_fill_picture_complement : rgbtest_fill_picture;
1081  return init(ctx);
1082 }
1083 
1084 static const enum AVPixelFormat rgbtest_pix_fmts[] = {
1093  };
1094 
1095 static int rgbtest_config_props(AVFilterLink *outlink)
1096 {
1097  TestSourceContext *test = outlink->src->priv;
1099 
1100  test->depth = desc->comp[0].depth;
1101  ff_fill_rgba_map(test->rgba_map, outlink->format);
1102  return config_props(outlink);
1103 }
1104 
1105 static const AVFilterPad avfilter_vsrc_rgbtestsrc_outputs[] = {
1106  {
1107  .name = "default",
1108  .type = AVMEDIA_TYPE_VIDEO,
1109  .config_props = rgbtest_config_props,
1110  },
1111 };
1112 
1113 const AVFilter ff_vsrc_rgbtestsrc = {
1114  .name = "rgbtestsrc",
1115  .description = NULL_IF_CONFIG_SMALL("Generate RGB test pattern."),
1116  .priv_size = sizeof(TestSourceContext),
1117  .priv_class = &rgbtestsrc_class,
1118  .init = rgbtest_init,
1119  .uninit = uninit,
1120  .activate = activate,
1121  .inputs = NULL,
1122  FILTER_OUTPUTS(avfilter_vsrc_rgbtestsrc_outputs),
1123  FILTER_PIXFMTS_ARRAY(rgbtest_pix_fmts),
1124 };
1125 
1126 #endif /* CONFIG_RGBTESTSRC_FILTER */
1127 
1128 #if CONFIG_YUVTESTSRC_FILTER
1129 
1130 static void yuvtest_fill_picture8(AVFilterContext *ctx, AVFrame *frame)
1131 {
1132  int x, y, w = frame->width, h = frame->height / 3;
1134  const int factor = 1 << desc->comp[0].depth;
1135  const int mid = 1 << (desc->comp[0].depth - 1);
1136  uint8_t *ydst = frame->data[0];
1137  uint8_t *udst = frame->data[1];
1138  uint8_t *vdst = frame->data[2];
1139  int ylinesize = frame->linesize[0];
1140  int ulinesize = frame->linesize[1];
1141  int vlinesize = frame->linesize[2];
1142 
1143  for (y = 0; y < h; y++) {
1144  for (x = 0; x < w; x++) {
1145  int c = factor * x / w;
1146 
1147  ydst[x] = c;
1148  udst[x] = mid;
1149  vdst[x] = mid;
1150  }
1151 
1152  ydst += ylinesize;
1153  udst += ulinesize;
1154  vdst += vlinesize;
1155  }
1156 
1157  h += h;
1158  for (; y < h; y++) {
1159  for (x = 0; x < w; x++) {
1160  int c = factor * x / w;
1161 
1162  ydst[x] = mid;
1163  udst[x] = c;
1164  vdst[x] = mid;
1165  }
1166 
1167  ydst += ylinesize;
1168  udst += ulinesize;
1169  vdst += vlinesize;
1170  }
1171 
1172  for (; y < frame->height; y++) {
1173  for (x = 0; x < w; x++) {
1174  int c = factor * x / w;
1175 
1176  ydst[x] = mid;
1177  udst[x] = mid;
1178  vdst[x] = c;
1179  }
1180 
1181  ydst += ylinesize;
1182  udst += ulinesize;
1183  vdst += vlinesize;
1184  }
1185 }
1186 
1187 static void yuvtest_fill_picture16(AVFilterContext *ctx, AVFrame *frame)
1188 {
1189  int x, y, w = frame->width, h = frame->height / 3;
1191  const int factor = 1 << desc->comp[0].depth;
1192  const int mid = 1 << (desc->comp[0].depth - 1);
1193  uint16_t *ydst = (uint16_t *)frame->data[0];
1194  uint16_t *udst = (uint16_t *)frame->data[1];
1195  uint16_t *vdst = (uint16_t *)frame->data[2];
1196  int ylinesize = frame->linesize[0] / 2;
1197  int ulinesize = frame->linesize[1] / 2;
1198  int vlinesize = frame->linesize[2] / 2;
1199 
1200  for (y = 0; y < h; y++) {
1201  for (x = 0; x < w; x++) {
1202  int c = factor * x / w;
1203 
1204  ydst[x] = c;
1205  udst[x] = mid;
1206  vdst[x] = mid;
1207  }
1208 
1209  ydst += ylinesize;
1210  udst += ulinesize;
1211  vdst += vlinesize;
1212  }
1213 
1214  h += h;
1215  for (; y < h; y++) {
1216  for (x = 0; x < w; x++) {
1217  int c = factor * x / w;
1218 
1219  ydst[x] = mid;
1220  udst[x] = c;
1221  vdst[x] = mid;
1222  }
1223 
1224  ydst += ylinesize;
1225  udst += ulinesize;
1226  vdst += vlinesize;
1227  }
1228 
1229  for (; y < frame->height; y++) {
1230  for (x = 0; x < w; x++) {
1231  int c = factor * x / w;
1232 
1233  ydst[x] = mid;
1234  udst[x] = mid;
1235  vdst[x] = c;
1236  }
1237 
1238  ydst += ylinesize;
1239  udst += ulinesize;
1240  vdst += vlinesize;
1241  }
1242 }
1243 
1244 static av_cold int yuvtest_init(AVFilterContext *ctx)
1245 {
1246  TestSourceContext *test = ctx->priv;
1247 
1248  test->draw_once = 1;
1249  return init(ctx);
1250 }
1251 
1252 static const enum AVPixelFormat yuvtest_pix_fmts[] = {
1258 };
1259 
1260 static int yuvtest_config_props(AVFilterLink *outlink)
1261 {
1262  TestSourceContext *test = outlink->src->priv;
1264 
1265  test->fill_picture_fn = desc->comp[0].depth > 8 ? yuvtest_fill_picture16 : yuvtest_fill_picture8;
1266  return config_props(outlink);
1267 }
1268 
1269 static const AVFilterPad avfilter_vsrc_yuvtestsrc_outputs[] = {
1270  {
1271  .name = "default",
1272  .type = AVMEDIA_TYPE_VIDEO,
1273  .config_props = yuvtest_config_props,
1274  },
1275 };
1276 
1277 const AVFilter ff_vsrc_yuvtestsrc = {
1278  .name = "yuvtestsrc",
1279  .description = NULL_IF_CONFIG_SMALL("Generate YUV test pattern."),
1280  .priv_size = sizeof(TestSourceContext),
1281  .priv_class = &nullsrc_yuvtestsrc_class,
1282  .init = yuvtest_init,
1283  .uninit = uninit,
1284  .activate = activate,
1285  .inputs = NULL,
1286  FILTER_OUTPUTS(avfilter_vsrc_yuvtestsrc_outputs),
1287  FILTER_PIXFMTS_ARRAY(yuvtest_pix_fmts),
1288 };
1289 
1290 #endif /* CONFIG_YUVTESTSRC_FILTER */
1291 
1292 #if CONFIG_PAL75BARS_FILTER || CONFIG_PAL100BARS_FILTER || CONFIG_SMPTEBARS_FILTER || CONFIG_SMPTEHDBARS_FILTER
1293 
1294 static const uint8_t rainbow[7][4] = {
1295  { 180, 128, 128, 255 }, /* 75% white */
1296  { 162, 44, 142, 255 }, /* 75% yellow */
1297  { 131, 156, 44, 255 }, /* 75% cyan */
1298  { 112, 72, 58, 255 }, /* 75% green */
1299  { 84, 184, 198, 255 }, /* 75% magenta */
1300  { 65, 100, 212, 255 }, /* 75% red */
1301  { 35, 212, 114, 255 }, /* 75% blue */
1302 };
1303 
1304 static const uint8_t rainbow100[7][4] = {
1305  { 235, 128, 128, 255 }, /* 100% white */
1306  { 210, 16, 146, 255 }, /* 100% yellow */
1307  { 170, 166, 16, 255 }, /* 100% cyan */
1308  { 145, 54, 34, 255 }, /* 100% green */
1309  { 106, 202, 222, 255 }, /* 100% magenta */
1310  { 81, 90, 240, 255 }, /* 100% red */
1311  { 41, 240, 110, 255 }, /* 100% blue */
1312 };
1313 
1314 static const uint8_t rainbowhd[7][4] = {
1315  { 180, 128, 128, 255 }, /* 75% white */
1316  { 168, 44, 136, 255 }, /* 75% yellow */
1317  { 145, 147, 44, 255 }, /* 75% cyan */
1318  { 133, 63, 52, 255 }, /* 75% green */
1319  { 63, 193, 204, 255 }, /* 75% magenta */
1320  { 51, 109, 212, 255 }, /* 75% red */
1321  { 28, 212, 120, 255 }, /* 75% blue */
1322 };
1323 
1324 static const uint8_t wobnair[7][4] = {
1325  { 35, 212, 114, 255 }, /* 75% blue */
1326  { 19, 128, 128, 255 }, /* 7.5% intensity black */
1327  { 84, 184, 198, 255 }, /* 75% magenta */
1328  { 19, 128, 128, 255 }, /* 7.5% intensity black */
1329  { 131, 156, 44, 255 }, /* 75% cyan */
1330  { 19, 128, 128, 255 }, /* 7.5% intensity black */
1331  { 180, 128, 128, 255 }, /* 75% white */
1332 };
1333 
1334 static const uint8_t white[4] = { 235, 128, 128, 255 };
1335 
1336 /* pluge pulses */
1337 static const uint8_t neg4ire[4] = { 7, 128, 128, 255 };
1338 static const uint8_t pos4ire[4] = { 24, 128, 128, 255 };
1339 
1340 /* fudged Q/-I */
1341 static const uint8_t i_pixel[4] = { 57, 156, 97, 255 };
1342 static const uint8_t q_pixel[4] = { 44, 171, 147, 255 };
1343 
1344 static const uint8_t gray40[4] = { 104, 128, 128, 255 };
1345 static const uint8_t gray15[4] = { 49, 128, 128, 255 };
1346 static const uint8_t cyan[4] = { 188, 154, 16, 255 };
1347 static const uint8_t yellow[4] = { 219, 16, 138, 255 };
1348 static const uint8_t blue[4] = { 32, 240, 118, 255 };
1349 static const uint8_t red[4] = { 63, 102, 240, 255 };
1350 static const uint8_t black0[4] = { 16, 128, 128, 255 };
1351 static const uint8_t black2[4] = { 20, 128, 128, 255 };
1352 static const uint8_t black4[4] = { 25, 128, 128, 255 };
1353 static const uint8_t neg2[4] = { 12, 128, 128, 255 };
1354 
1355 static void draw_bar(TestSourceContext *test, const uint8_t color[4],
1356  int x, int y, int w, int h,
1357  AVFrame *frame)
1358 {
1360  uint8_t *p, *p0;
1361  int plane;
1362 
1363  x = FFMIN(x, test->w - 1);
1364  y = FFMIN(y, test->h - 1);
1365  w = FFMAX(FFMIN(w, test->w - x), 0);
1366  h = FFMAX(FFMIN(h, test->h - y), 0);
1367 
1368  av_assert0(x + w <= test->w);
1369  av_assert0(y + h <= test->h);
1370 
1371  for (plane = 0; frame->data[plane]; plane++) {
1372  const int c = color[plane];
1373  const int linesize = frame->linesize[plane];
1374  int i, px, py, pw, ph;
1375 
1376  if (plane == 1 || plane == 2) {
1377  px = x >> desc->log2_chroma_w;
1378  pw = AV_CEIL_RSHIFT(w, desc->log2_chroma_w);
1379  py = y >> desc->log2_chroma_h;
1380  ph = AV_CEIL_RSHIFT(h, desc->log2_chroma_h);
1381  } else {
1382  px = x;
1383  pw = w;
1384  py = y;
1385  ph = h;
1386  }
1387 
1388  p0 = p = frame->data[plane] + py * linesize + px;
1389  memset(p, c, pw);
1390  p += linesize;
1391  for (i = 1; i < ph; i++, p += linesize)
1392  memcpy(p, p0, pw);
1393  }
1394 }
1395 
1396 static const enum AVPixelFormat smptebars_pix_fmts[] = {
1401 };
1402 
1403 static const AVFilterPad smptebars_outputs[] = {
1404  {
1405  .name = "default",
1406  .type = AVMEDIA_TYPE_VIDEO,
1407  .config_props = config_props,
1408  },
1409 };
1410 
1411 AVFILTER_DEFINE_CLASS_EXT(palbars, "pal(75|100)bars", options);
1412 
1413 #if CONFIG_PAL75BARS_FILTER
1414 
1415 static void pal75bars_fill_picture(AVFilterContext *ctx, AVFrame *picref)
1416 {
1417  TestSourceContext *test = ctx->priv;
1418  int r_w, i, x = 0;
1419  const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(picref->format);
1420 
1421  picref->color_range = AVCOL_RANGE_MPEG;
1422  picref->colorspace = AVCOL_SPC_BT470BG;
1423 
1424  r_w = FFALIGN((test->w + 7) / 8, 1 << pixdesc->log2_chroma_w);
1425 
1426  draw_bar(test, white, x, 0, r_w, test->h, picref);
1427  x += r_w;
1428  for (i = 1; i < 7; i++) {
1429  draw_bar(test, rainbow[i], x, 0, r_w, test->h, picref);
1430  x += r_w;
1431  }
1432  draw_bar(test, black0, x, 0, r_w, test->h, picref);
1433 }
1434 
1435 static av_cold int pal75bars_init(AVFilterContext *ctx)
1436 {
1437  TestSourceContext *test = ctx->priv;
1438 
1439  test->fill_picture_fn = pal75bars_fill_picture;
1440  test->draw_once = 1;
1441  return init(ctx);
1442 }
1443 
1444 const AVFilter ff_vsrc_pal75bars = {
1445  .name = "pal75bars",
1446  .description = NULL_IF_CONFIG_SMALL("Generate PAL 75% color bars."),
1447  .priv_class = &palbars_class,
1448  .priv_size = sizeof(TestSourceContext),
1449  .init = pal75bars_init,
1450  .uninit = uninit,
1451  .activate = activate,
1452  .inputs = NULL,
1453  FILTER_OUTPUTS(smptebars_outputs),
1454  FILTER_PIXFMTS_ARRAY(smptebars_pix_fmts),
1455 };
1456 
1457 #endif /* CONFIG_PAL75BARS_FILTER */
1458 
1459 #if CONFIG_PAL100BARS_FILTER
1460 
1461 static void pal100bars_fill_picture(AVFilterContext *ctx, AVFrame *picref)
1462 {
1463  TestSourceContext *test = ctx->priv;
1464  int r_w, i, x = 0;
1465  const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(picref->format);
1466 
1467  picref->color_range = AVCOL_RANGE_MPEG;
1468  picref->colorspace = AVCOL_SPC_BT470BG;
1469 
1470  r_w = FFALIGN((test->w + 7) / 8, 1 << pixdesc->log2_chroma_w);
1471 
1472  for (i = 0; i < 7; i++) {
1473  draw_bar(test, rainbow100[i], x, 0, r_w, test->h, picref);
1474  x += r_w;
1475  }
1476  draw_bar(test, black0, x, 0, r_w, test->h, picref);
1477 }
1478 
1479 static av_cold int pal100bars_init(AVFilterContext *ctx)
1480 {
1481  TestSourceContext *test = ctx->priv;
1482 
1483  test->fill_picture_fn = pal100bars_fill_picture;
1484  test->draw_once = 1;
1485  return init(ctx);
1486 }
1487 
1488 const AVFilter ff_vsrc_pal100bars = {
1489  .name = "pal100bars",
1490  .description = NULL_IF_CONFIG_SMALL("Generate PAL 100% color bars."),
1491  .priv_class = &palbars_class,
1492  .priv_size = sizeof(TestSourceContext),
1493  .init = pal100bars_init,
1494  .uninit = uninit,
1495  .activate = activate,
1496  .inputs = NULL,
1497  FILTER_OUTPUTS(smptebars_outputs),
1498  FILTER_PIXFMTS_ARRAY(smptebars_pix_fmts),
1499 };
1500 
1501 #endif /* CONFIG_PAL100BARS_FILTER */
1502 
1503 AVFILTER_DEFINE_CLASS_EXT(smptebars, "smpte(hd)bars", options);
1504 
1505 #if CONFIG_SMPTEBARS_FILTER
1506 
1507 static void smptebars_fill_picture(AVFilterContext *ctx, AVFrame *picref)
1508 {
1509  TestSourceContext *test = ctx->priv;
1510  int r_w, r_h, w_h, p_w, p_h, i, tmp, x = 0;
1511  const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(picref->format);
1512 
1513  picref->colorspace = AVCOL_SPC_BT470BG;
1514 
1515  r_w = FFALIGN((test->w + 6) / 7, 1 << pixdesc->log2_chroma_w);
1516  r_h = FFALIGN(test->h * 2 / 3, 1 << pixdesc->log2_chroma_h);
1517  w_h = FFALIGN(test->h * 3 / 4 - r_h, 1 << pixdesc->log2_chroma_h);
1518  p_w = FFALIGN(r_w * 5 / 4, 1 << pixdesc->log2_chroma_w);
1519  p_h = test->h - w_h - r_h;
1520 
1521  for (i = 0; i < 7; i++) {
1522  draw_bar(test, rainbow[i], x, 0, r_w, r_h, picref);
1523  draw_bar(test, wobnair[i], x, r_h, r_w, w_h, picref);
1524  x += r_w;
1525  }
1526  x = 0;
1527  draw_bar(test, i_pixel, x, r_h + w_h, p_w, p_h, picref);
1528  x += p_w;
1529  draw_bar(test, white, x, r_h + w_h, p_w, p_h, picref);
1530  x += p_w;
1531  draw_bar(test, q_pixel, x, r_h + w_h, p_w, p_h, picref);
1532  x += p_w;
1533  tmp = FFALIGN(5 * r_w - x, 1 << pixdesc->log2_chroma_w);
1534  draw_bar(test, black0, x, r_h + w_h, tmp, p_h, picref);
1535  x += tmp;
1536  tmp = FFALIGN(r_w / 3, 1 << pixdesc->log2_chroma_w);
1537  draw_bar(test, neg4ire, x, r_h + w_h, tmp, p_h, picref);
1538  x += tmp;
1539  draw_bar(test, black0, x, r_h + w_h, tmp, p_h, picref);
1540  x += tmp;
1541  draw_bar(test, pos4ire, x, r_h + w_h, tmp, p_h, picref);
1542  x += tmp;
1543  draw_bar(test, black0, x, r_h + w_h, test->w - x, p_h, picref);
1544 }
1545 
1546 static av_cold int smptebars_init(AVFilterContext *ctx)
1547 {
1548  TestSourceContext *test = ctx->priv;
1549 
1550  test->fill_picture_fn = smptebars_fill_picture;
1551  test->draw_once = 1;
1552  return init(ctx);
1553 }
1554 
1555 const AVFilter ff_vsrc_smptebars = {
1556  .name = "smptebars",
1557  .description = NULL_IF_CONFIG_SMALL("Generate SMPTE color bars."),
1558  .priv_size = sizeof(TestSourceContext),
1559  .priv_class = &smptebars_class,
1560  .init = smptebars_init,
1561  .uninit = uninit,
1562  .activate = activate,
1563  .inputs = NULL,
1564  FILTER_OUTPUTS(smptebars_outputs),
1565  FILTER_PIXFMTS_ARRAY(smptebars_pix_fmts),
1566 };
1567 
1568 #endif /* CONFIG_SMPTEBARS_FILTER */
1569 
1570 #if CONFIG_SMPTEHDBARS_FILTER
1571 
1572 static void smptehdbars_fill_picture(AVFilterContext *ctx, AVFrame *picref)
1573 {
1574  TestSourceContext *test = ctx->priv;
1575  int d_w, r_w, r_h, l_w, i, tmp, x = 0, y = 0;
1576  const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(picref->format);
1577 
1578  picref->colorspace = AVCOL_SPC_BT709;
1579 
1580  d_w = FFALIGN(test->w / 8, 1 << pixdesc->log2_chroma_w);
1581  r_h = FFALIGN(test->h * 7 / 12, 1 << pixdesc->log2_chroma_h);
1582  draw_bar(test, gray40, x, 0, d_w, r_h, picref);
1583  x += d_w;
1584 
1585  r_w = FFALIGN((((test->w + 3) / 4) * 3) / 7, 1 << pixdesc->log2_chroma_w);
1586  for (i = 0; i < 7; i++) {
1587  draw_bar(test, rainbowhd[i], x, 0, r_w, r_h, picref);
1588  x += r_w;
1589  }
1590  draw_bar(test, gray40, x, 0, test->w - x, r_h, picref);
1591  y = r_h;
1592  r_h = FFALIGN(test->h / 12, 1 << pixdesc->log2_chroma_h);
1593  draw_bar(test, cyan, 0, y, d_w, r_h, picref);
1594  x = d_w;
1595  draw_bar(test, i_pixel, x, y, r_w, r_h, picref);
1596  x += r_w;
1597  tmp = r_w * 6;
1598  draw_bar(test, rainbowhd[0], x, y, tmp, r_h, picref);
1599  x += tmp;
1600  l_w = x;
1601  draw_bar(test, blue, x, y, test->w - x, r_h, picref);
1602  y += r_h;
1603  draw_bar(test, yellow, 0, y, d_w, r_h, picref);
1604  x = d_w;
1605  draw_bar(test, q_pixel, x, y, r_w, r_h, picref);
1606  x += r_w;
1607 
1608  for (i = 0; i < tmp; i += 1 << pixdesc->log2_chroma_w) {
1609  uint8_t yramp[4] = {0};
1610 
1611  yramp[0] = i * 255 / tmp;
1612  yramp[1] = 128;
1613  yramp[2] = 128;
1614  yramp[3] = 255;
1615 
1616  draw_bar(test, yramp, x, y, 1 << pixdesc->log2_chroma_w, r_h, picref);
1617  x += 1 << pixdesc->log2_chroma_w;
1618  }
1619  draw_bar(test, red, x, y, test->w - x, r_h, picref);
1620  y += r_h;
1621  draw_bar(test, gray15, 0, y, d_w, test->h - y, picref);
1622  x = d_w;
1623  tmp = FFALIGN(r_w * 3 / 2, 1 << pixdesc->log2_chroma_w);
1624  draw_bar(test, black0, x, y, tmp, test->h - y, picref);
1625  x += tmp;
1626  tmp = FFALIGN(r_w * 2, 1 << pixdesc->log2_chroma_w);
1627  draw_bar(test, white, x, y, tmp, test->h - y, picref);
1628  x += tmp;
1629  tmp = FFALIGN(r_w * 5 / 6, 1 << pixdesc->log2_chroma_w);
1630  draw_bar(test, black0, x, y, tmp, test->h - y, picref);
1631  x += tmp;
1632  tmp = FFALIGN(r_w / 3, 1 << pixdesc->log2_chroma_w);
1633  draw_bar(test, neg2, x, y, tmp, test->h - y, picref);
1634  x += tmp;
1635  draw_bar(test, black0, x, y, tmp, test->h - y, picref);
1636  x += tmp;
1637  draw_bar(test, black2, x, y, tmp, test->h - y, picref);
1638  x += tmp;
1639  draw_bar(test, black0, x, y, tmp, test->h - y, picref);
1640  x += tmp;
1641  draw_bar(test, black4, x, y, tmp, test->h - y, picref);
1642  x += tmp;
1643  r_w = l_w - x;
1644  draw_bar(test, black0, x, y, r_w, test->h - y, picref);
1645  x += r_w;
1646  draw_bar(test, gray15, x, y, test->w - x, test->h - y, picref);
1647 }
1648 
1649 static av_cold int smptehdbars_init(AVFilterContext *ctx)
1650 {
1651  TestSourceContext *test = ctx->priv;
1652 
1653  test->fill_picture_fn = smptehdbars_fill_picture;
1654  test->draw_once = 1;
1655  return init(ctx);
1656 }
1657 
1658 const AVFilter ff_vsrc_smptehdbars = {
1659  .name = "smptehdbars",
1660  .description = NULL_IF_CONFIG_SMALL("Generate SMPTE HD color bars."),
1661  .priv_class = &smptebars_class,
1662  .priv_size = sizeof(TestSourceContext),
1663  .init = smptehdbars_init,
1664  .uninit = uninit,
1665  .activate = activate,
1666  .inputs = NULL,
1667  FILTER_OUTPUTS(smptebars_outputs),
1668  FILTER_PIXFMTS_ARRAY(smptebars_pix_fmts),
1669 };
1670 
1671 #endif /* CONFIG_SMPTEHDBARS_FILTER */
1672 #endif /* CONFIG_SMPTEBARS_FILTER || CONFIG_SMPTEHDBARS_FILTER */
1673 
1674 AVFILTER_DEFINE_CLASS_EXT(allyuv_allrgb, "allyuv/allrgb",
1676 
1677 #if CONFIG_ALLYUV_FILTER
1678 
1679 static void allyuv_fill_picture(AVFilterContext *ctx, AVFrame *frame)
1680 {
1681  const int ys = frame->linesize[0];
1682  const int us = frame->linesize[1];
1683  const int vs = frame->linesize[2];
1684  int x, y, j;
1685 
1686  for (y = 0; y < 4096; y++) {
1687  for (x = 0; x < 2048; x++) {
1688  frame->data[0][y * ys + x] = ((x / 8) % 256);
1689  frame->data[0][y * ys + 4095 - x] = ((x / 8) % 256);
1690  }
1691 
1692  for (x = 0; x < 2048; x+=8) {
1693  for (j = 0; j < 8; j++) {
1694  frame->data[1][vs * y + x + j] = (y%16 + (j % 8) * 16);
1695  frame->data[1][vs * y + 4095 - x - j] = (128 + y%16 + (j % 8) * 16);
1696  }
1697  }
1698 
1699  for (x = 0; x < 4096; x++)
1700  frame->data[2][y * us + x] = 256 * y / 4096;
1701  }
1702 }
1703 
1704 static av_cold int allyuv_init(AVFilterContext *ctx)
1705 {
1706  TestSourceContext *test = ctx->priv;
1707 
1708  test->w = test->h = 4096;
1709  test->draw_once = 1;
1710  test->fill_picture_fn = allyuv_fill_picture;
1711  return init(ctx);
1712 }
1713 
1714 static const AVFilterPad avfilter_vsrc_allyuv_outputs[] = {
1715  {
1716  .name = "default",
1717  .type = AVMEDIA_TYPE_VIDEO,
1718  .config_props = config_props,
1719  },
1720 };
1721 
1722 const AVFilter ff_vsrc_allyuv = {
1723  .name = "allyuv",
1724  .description = NULL_IF_CONFIG_SMALL("Generate all yuv colors."),
1725  .priv_size = sizeof(TestSourceContext),
1726  .priv_class = &allyuv_allrgb_class,
1727  .init = allyuv_init,
1728  .uninit = uninit,
1729  .activate = activate,
1730  .inputs = NULL,
1731  FILTER_OUTPUTS(avfilter_vsrc_allyuv_outputs),
1733 };
1734 
1735 #endif /* CONFIG_ALLYUV_FILTER */
1736 
1737 #if CONFIG_ALLRGB_FILTER
1738 
1739 static void allrgb_fill_picture(AVFilterContext *ctx, AVFrame *frame)
1740 {
1741  unsigned x, y;
1742  const int linesize = frame->linesize[0];
1743  uint8_t *line = frame->data[0];
1744 
1745  for (y = 0; y < 4096; y++) {
1746  uint8_t *dst = line;
1747 
1748  for (x = 0; x < 4096; x++) {
1749  *dst++ = x;
1750  *dst++ = y;
1751  *dst++ = (x >> 8) | ((y >> 8) << 4);
1752  }
1753  line += linesize;
1754  }
1755 }
1756 
1757 static av_cold int allrgb_init(AVFilterContext *ctx)
1758 {
1759  TestSourceContext *test = ctx->priv;
1760 
1761  test->w = test->h = 4096;
1762  test->draw_once = 1;
1763  test->fill_picture_fn = allrgb_fill_picture;
1764  return init(ctx);
1765 }
1766 
1767 static int allrgb_config_props(AVFilterLink *outlink)
1768 {
1769  TestSourceContext *test = outlink->src->priv;
1770 
1771  ff_fill_rgba_map(test->rgba_map, outlink->format);
1772  return config_props(outlink);
1773 }
1774 
1775 static const AVFilterPad avfilter_vsrc_allrgb_outputs[] = {
1776  {
1777  .name = "default",
1778  .type = AVMEDIA_TYPE_VIDEO,
1779  .config_props = allrgb_config_props,
1780  },
1781 };
1782 
1783 const AVFilter ff_vsrc_allrgb = {
1784  .name = "allrgb",
1785  .description = NULL_IF_CONFIG_SMALL("Generate all RGB colors."),
1786  .priv_size = sizeof(TestSourceContext),
1787  .priv_class = &allyuv_allrgb_class,
1788  .init = allrgb_init,
1789  .uninit = uninit,
1790  .activate = activate,
1791  .inputs = NULL,
1792  FILTER_OUTPUTS(avfilter_vsrc_allrgb_outputs),
1794 };
1795 
1796 #endif /* CONFIG_ALLRGB_FILTER */
1797 
1798 #if CONFIG_COLORSPECTRUM_FILTER
1799 
1800 static const AVOption colorspectrum_options[] = {
1802  { "type", "set the color spectrum type", OFFSET(type), AV_OPT_TYPE_INT, {.i64=0}, 0, 2, FLAGS, "type" },
1803  { "black","fade to black", 0, AV_OPT_TYPE_CONST,{.i64=0},0, 0, FLAGS, "type" },
1804  { "white","fade to white", 0, AV_OPT_TYPE_CONST,{.i64=1},0, 0, FLAGS, "type" },
1805  { "all", "white to black", 0, AV_OPT_TYPE_CONST,{.i64=2},0, 0, FLAGS, "type" },
1806  { NULL }
1807 };
1808 
1809 AVFILTER_DEFINE_CLASS(colorspectrum);
1810 
1811 static inline float mix(float a, float b, float mix)
1812 {
1813  return a * mix + b * (1.f - mix);
1814 }
1815 
1816 static void hsb2rgb(const float *c, float *rgb)
1817 {
1818  rgb[0] = av_clipf(fabsf(fmodf(c[0] * 6.f + 0.f, 6.f) - 3.f) - 1.f, 0.f, 1.f);
1819  rgb[1] = av_clipf(fabsf(fmodf(c[0] * 6.f + 4.f, 6.f) - 3.f) - 1.f, 0.f, 1.f);
1820  rgb[2] = av_clipf(fabsf(fmodf(c[0] * 6.f + 2.f, 6.f) - 3.f) - 1.f, 0.f, 1.f);
1821  rgb[0] = mix(c[3], (rgb[0] * rgb[0] * (3.f - 2.f * rgb[0])), c[1]) * c[2];
1822  rgb[1] = mix(c[3], (rgb[1] * rgb[1] * (3.f - 2.f * rgb[1])), c[1]) * c[2];
1823  rgb[2] = mix(c[3], (rgb[2] * rgb[2] * (3.f - 2.f * rgb[2])), c[1]) * c[2];
1824 }
1825 
1826 static void colorspectrum_fill_picture(AVFilterContext *ctx, AVFrame *frame)
1827 {
1828  TestSourceContext *test = ctx->priv;
1829  const float w = frame->width - 1.f;
1830  const float h = frame->height - 1.f;
1831  float c[4];
1832 
1833  for (int y = 0; y < frame->height; y++) {
1834  float *r = (float *)(frame->data[2] + y * frame->linesize[2]);
1835  float *g = (float *)(frame->data[0] + y * frame->linesize[0]);
1836  float *b = (float *)(frame->data[1] + y * frame->linesize[1]);
1837  const float yh = y / h;
1838 
1839  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;
1840  c[2] = 1.f;
1841  c[3] = test->type == 1 ? 1.f : test->type == 2 ? (yh > 0.5f ? 0.f : 1.f): 0.f;
1842  for (int x = 0; x < frame->width; x++) {
1843  float rgb[3];
1844 
1845  c[0] = x / w;
1846  hsb2rgb(c, rgb);
1847 
1848  r[x] = rgb[0];
1849  g[x] = rgb[1];
1850  b[x] = rgb[2];
1851  }
1852  }
1853 }
1854 
1855 static av_cold int colorspectrum_init(AVFilterContext *ctx)
1856 {
1857  TestSourceContext *test = ctx->priv;
1858 
1859  test->draw_once = 1;
1860  test->fill_picture_fn = colorspectrum_fill_picture;
1861  return init(ctx);
1862 }
1863 
1864 static const AVFilterPad avfilter_vsrc_colorspectrum_outputs[] = {
1865  {
1866  .name = "default",
1867  .type = AVMEDIA_TYPE_VIDEO,
1868  .config_props = config_props,
1869  },
1870 };
1871 
1873  .name = "colorspectrum",
1874  .description = NULL_IF_CONFIG_SMALL("Generate colors spectrum."),
1875  .priv_size = sizeof(TestSourceContext),
1876  .priv_class = &colorspectrum_class,
1877  .init = colorspectrum_init,
1878  .uninit = uninit,
1879  .activate = activate,
1880  .inputs = NULL,
1881  FILTER_OUTPUTS(avfilter_vsrc_colorspectrum_outputs),
1883 };
1884 
1885 #endif /* CONFIG_COLORSPECTRUM_FILTER */
ff_get_video_buffer
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:98
AV_PIX_FMT_GBRAP16
#define AV_PIX_FMT_GBRAP16
Definition: pixfmt.h:426
AVFrame::color_range
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: frame.h:566
FFDrawColor
Definition: drawutils.h:48
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
ff_exp10
static av_always_inline double ff_exp10(double x)
Compute 10^x for floating point values.
Definition: ffmath.h:42
level
uint8_t level
Definition: svq3.c:204
mix
static int mix(int c0, int c1)
Definition: 4xm.c:716
r
const char * r
Definition: vf_curves.c:116
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
AV_WL32
#define AV_WL32(p, v)
Definition: intreadwrite.h:426
color
Definition: vf_paletteuse.c:599
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1018
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2660
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
FFERROR_NOT_READY
return FFERROR_NOT_READY
Definition: filter_design.txt:204
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: vsrc_testsrc.c:130
FILTER_PIXFMTS_ARRAY
#define FILTER_PIXFMTS_ARRAY(array)
Definition: internal.h:171
AV_TIME_BASE_Q
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:260
inlink
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
Definition: filter_design.txt:212
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:109
AVFrame::colorspace
enum AVColorSpace colorspace
YUV colorspace type.
Definition: frame.h:577
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:317
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:26
ff_vsrc_color
const AVFilter ff_vsrc_color
step
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But a word about which is also called distortion Distortion can be quantified by almost any quality measurement one chooses the sum of squared differences is used but more complex methods that consider psychovisual effects can be used as well It makes no difference in this discussion First step
Definition: rate_distortion.txt:58
index
fg index
Definition: ffmpeg_filter.c:167
w
uint8_t w
Definition: llviddspenc.c:38
R
#define R
Definition: huffyuvdsp.h:34
AVOption
AVOption.
Definition: opt.h:247
b
#define b
Definition: input.c:40
FILTER_QUERY_FUNC
#define FILTER_QUERY_FUNC(func)
Definition: internal.h:168
data
const char data[16]
Definition: mxf.c:143
ff_vsrc_pal75bars
const AVFilter ff_vsrc_pal75bars
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:196
float.h
AV_PIX_FMT_BGR24
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:69
AV_PIX_FMT_BGRA
@ AV_PIX_FMT_BGRA
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
Definition: pixfmt.h:95
AV_PIX_FMT_YUV440P
@ AV_PIX_FMT_YUV440P
planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
Definition: pixfmt.h:99
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
init
static av_cold int init(AVFilterContext *ctx)
Definition: vsrc_testsrc.c:115
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:169
video.h
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:338
formats.h
ff_vsrc_haldclutsrc
const AVFilter ff_vsrc_haldclutsrc
A
#define A(x)
Definition: vp56_arith.h:28
av_pix_fmt_count_planes
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2700
AVCOL_SPC_BT470BG
@ AVCOL_SPC_BT470BG
also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601
Definition: pixfmt.h:529
rgb
Definition: rpzaenc.c:59
ff_vsrc_yuvtestsrc
const AVFilter ff_vsrc_yuvtestsrc
AV_PIX_FMT_GBRP14
#define AV_PIX_FMT_GBRP14
Definition: pixfmt.h:422
AV_PIX_FMT_GBRAP
@ AV_PIX_FMT_GBRAP
planar GBRA 4:4:4:4 32bpp
Definition: pixfmt.h:205
AVFilterContext::priv
void * priv
private data for use by the filter
Definition: avfilter.h:417
U
#define U(x)
Definition: vp56_arith.h:37
AV_PIX_FMT_GBRP10
#define AV_PIX_FMT_GBRP10
Definition: pixfmt.h:420
draw_rectangle
static void draw_rectangle(AVFormatContext *s)
Definition: xcbgrab.c:647
val
static double val(void *priv, double ch)
Definition: aeval.c:76
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
scale
static av_always_inline float scale(float x, float s)
Definition: vf_v360.c:1388
us
#define us(width, name, range_min, range_max, subs,...)
Definition: cbs_h2645.c:278
ff_vsrc_allrgb
const AVFilter ff_vsrc_allrgb
ff_blend_mask
void ff_blend_mask(FFDrawContext *draw, FFDrawColor *color, uint8_t *dst[], int dst_linesize[], int dst_w, int dst_h, const uint8_t *mask, int mask_linesize, int mask_w, int mask_h, int l2depth, unsigned endianness, int x0, int y0)
Blend an alpha mask with an uniform color.
Definition: drawutils.c:517
fabsf
static __device__ float fabsf(float a)
Definition: cuda_runtime.h:181
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:50
TestSourceContext::rgba_map
uint8_t rgba_map[4]
Definition: vsrc_testsrc.c:82
AV_PIX_FMT_YUV444P10
#define AV_PIX_FMT_YUV444P10
Definition: pixfmt.h:407
avassert.h
ff_vsrc_pal100bars
const AVFilter ff_vsrc_pal100bars
TestSourceContext::duration
int64_t duration
duration expressed in microseconds
Definition: vsrc_testsrc.c:59
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
av_cold
#define av_cold
Definition: attributes.h:90
ff_set_common_formats
int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
A helper for query_formats() which sets all links to the same list of formats.
Definition: formats.c:699
mask
static const uint16_t mask[17]
Definition: lzw.c:38
TestSourceContext::type
int type
Definition: vsrc_testsrc.c:74
AV_PIX_FMT_GBRAP10
#define AV_PIX_FMT_GBRAP10
Definition: pixfmt.h:424
ff_outlink_set_status
static void ff_outlink_set_status(AVFilterLink *link, int status, int64_t pts)
Set the status field of a link from the source filter.
Definition: filters.h:189
width
#define width
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:257
AV_PIX_FMT_GBRAP12
#define AV_PIX_FMT_GBRAP12
Definition: pixfmt.h:425
AV_PIX_FMT_YUV444P16
#define AV_PIX_FMT_YUV444P16
Definition: pixfmt.h:417
AV_CEIL_RSHIFT
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:51
g
const char * g
Definition: vf_curves.c:117
av_q2d
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
TestSourceContext::time_base
AVRational time_base
Definition: vsrc_testsrc.c:57
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
filters.h
ctx
AVFormatContext * ctx
Definition: movenc.c:48
FLAGSR
#define FLAGSR
Definition: vsrc_testsrc.c:92
av_frame_clone
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
Definition: frame.c:422
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:141
TestSourceContext::color_rgba
uint8_t color_rgba[4]
Definition: vsrc_testsrc.c:79
ff_draw_init
int ff_draw_init(FFDrawContext *draw, enum AVPixelFormat format, unsigned flags)
Init a draw context.
Definition: drawutils.c:79
AVPixFmtDescriptor::log2_chroma_w
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:80
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
ff_vsrc_testsrc2
const AVFilter ff_vsrc_testsrc2
f
#define f(width, name)
Definition: cbs_vp9.c:255
AV_PIX_FMT_YUVJ444P
@ AV_PIX_FMT_YUVJ444P
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
Definition: pixfmt.h:80
AV_PIX_FMT_RGBA
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:93
planes
static const struct @321 planes[]
AV_PIX_FMT_GBRP16
#define AV_PIX_FMT_GBRP16
Definition: pixfmt.h:423
TestSourceContext::sar
AVRational sar
sample aspect ratio
Definition: vsrc_testsrc.c:60
AV_PIX_FMT_RGBA64
#define AV_PIX_FMT_RGBA64
Definition: pixfmt.h:394
FLAGS
#define FLAGS
Definition: vsrc_testsrc.c:91
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
AV_PIX_FMT_BGR48
#define AV_PIX_FMT_BGR48
Definition: pixfmt.h:395
NULL
#define NULL
Definition: coverity.c:32
ff_vsrc_colorspectrum
const AVFilter ff_vsrc_colorspectrum
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
TestSourceContext::color
FFDrawColor color
Definition: vsrc_testsrc.c:78
AV_OPT_TYPE_COLOR
@ AV_OPT_TYPE_COLOR
Definition: opt.h:239
av_clipf
#define av_clipf
Definition: common.h:144
AV_WL24
#define AV_WL24(p, d)
Definition: intreadwrite.h:464
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:274
parseutils.h
NOSIZE_OPTIONS_OFFSET
#define NOSIZE_OPTIONS_OFFSET
Definition: vsrc_testsrc.c:107
AV_PIX_FMT_BGR0
@ AV_PIX_FMT_BGR0
packed BGR 8:8:8, 32bpp, BGRXBGRX... X=unused/undefined
Definition: pixfmt.h:230
inputs
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several inputs
Definition: filter_design.txt:243
AV_PIX_FMT_GBRP9
#define AV_PIX_FMT_GBRP9
Definition: pixfmt.h:419
ff_vsrc_allyuv
const AVFilter ff_vsrc_allyuv
AV_PIX_FMT_ABGR
@ AV_PIX_FMT_ABGR
packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
Definition: pixfmt.h:94
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
TestSourceContext::picref
AVFrame * picref
cached reference containing the painted picture
Definition: vsrc_testsrc.c:63
for
for(j=16;j >0;--j)
Definition: h264pred_template.c:469
av_rescale_rnd
int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd)
Rescale a 64-bit integer with specified rounding.
Definition: mathematics.c:57
AV_PIX_FMT_RGB24
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:68
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
config_props
static int config_props(AVFilterLink *outlink)
Definition: vsrc_testsrc.c:137
ff_vsrc_smptehdbars
const AVFilter ff_vsrc_smptehdbars
av_get_padded_bits_per_pixel
int av_get_padded_bits_per_pixel(const AVPixFmtDescriptor *pixdesc)
Return the number of bits per pixel for the pixel format described by pixdesc, including any padding ...
Definition: pixdesc.c:2625
FILTER_PIXFMTS
#define FILTER_PIXFMTS(...)
Definition: internal.h:177
ff_blend_rectangle
void ff_blend_rectangle(FFDrawContext *draw, FFDrawColor *color, uint8_t *dst[], int dst_linesize[], int dst_w, int dst_h, int x0, int y0, int w, int h)
Blend a rectangle with an uniform color.
Definition: drawutils.c:336
AV_ROUND_ZERO
@ AV_ROUND_ZERO
Round toward zero.
Definition: mathematics.h:80
TestSourceContext::frame_rate
AVRational frame_rate
Definition: vsrc_testsrc.c:57
AV_PIX_FMT_GBRPF32
#define AV_PIX_FMT_GBRPF32
Definition: pixfmt.h:433
AV_PIX_FMT_RGB48
#define AV_PIX_FMT_RGB48
Definition: pixfmt.h:390
size
int size
Definition: twinvq_data.h:10344
color
static const uint32_t color[16+AV_CLASS_CATEGORY_NB]
Definition: log.c:92
COMMON_OPTIONS
#define COMMON_OPTIONS
Definition: vsrc_testsrc.c:105
av_make_q
static AVRational av_make_q(int num, int den)
Create an AVRational.
Definition: rational.h:71
draw_text
static void draw_text(FFDrawContext *draw, AVFrame *frame, FFDrawColor *color, int x0, int y0, const uint8_t *text, int vertical)
Definition: vf_datascope.c:85
AV_PIX_FMT_BGR555
#define AV_PIX_FMT_BGR555
Definition: pixfmt.h:397
ff_fill_rectangle
void ff_fill_rectangle(FFDrawContext *draw, FFDrawColor *color, uint8_t *dst[], int dst_linesize[], int dst_x, int dst_y, int w, int h)
Fill a rectangle with an uniform color.
Definition: drawutils.c:214
AV_PIX_FMT_YUV444P12
#define AV_PIX_FMT_YUV444P12
Definition: pixfmt.h:411
AVFrame::format
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition: frame.h:404
ff_filter_process_command
int ff_filter_process_command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
Generic processing of user supplied commands that are set in the same way as the filter options.
Definition: avfilter.c:882
height
#define height
TestSourceContext::level
int level
Definition: vsrc_testsrc.c:87
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
TestSourceContext::nb_decimals
int nb_decimals
Definition: vsrc_testsrc.c:68
line
Definition: graph2dot.c:48
AV_PIX_FMT_RGB0
@ AV_PIX_FMT_RGB0
packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined
Definition: pixfmt.h:228
xga_font_data.h
TestSourceContext
Definition: vsrc_testsrc.c:53
internal.h
AVFILTER_DEFINE_CLASS
#define AVFILTER_DEFINE_CLASS(fname)
Definition: internal.h:326
AV_PIX_FMT_ARGB
@ AV_PIX_FMT_ARGB
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition: pixfmt.h:92
TestSourceContext::nb_frame
unsigned int nb_frame
Definition: vsrc_testsrc.c:56
FILTER_SINGLE_PIXFMT
#define FILTER_SINGLE_PIXFMT(pix_fmt_)
Definition: internal.h:181
TestSourceContext::draw_once
int draw_once
draw only the first frame, always put out the same picture
Definition: vsrc_testsrc.c:61
AV_PIX_FMT_BGRA64
#define AV_PIX_FMT_BGRA64
Definition: pixfmt.h:399
TestSourceContext::h
int h
Definition: vsrc_testsrc.c:55
avpriv_vga16_font
const uint8_t avpriv_vga16_font[4096]
Definition: xga_font_data.c:160
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:271
ff_vsrc_nullsrc
const AVFilter ff_vsrc_nullsrc
TestSourceContext::complement
int complement
Definition: vsrc_testsrc.c:83
ff_draw_supported_pixel_formats
AVFilterFormats * ff_draw_supported_pixel_formats(unsigned flags)
Return the list of pixel formats supported by the draw functions.
Definition: drawutils.c:630
AV_PIX_FMT_GBRP12
#define AV_PIX_FMT_GBRP12
Definition: pixfmt.h:421
AV_PIX_FMT_BGR444
#define AV_PIX_FMT_BGR444
Definition: pixfmt.h:398
common.h
AV_PIX_FMT_RGB555
#define AV_PIX_FMT_RGB555
Definition: pixfmt.h:392
ff_draw_round_to_sub
int ff_draw_round_to_sub(FFDrawContext *draw, int sub_dir, int round_dir, int value)
Round a dimension according to subsampling.
Definition: drawutils.c:618
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
ff_vsrc_smptebars
const AVFilter ff_vsrc_smptebars
FFDrawContext
Definition: drawutils.h:35
av_inv_q
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
Definition: rational.h:159
AV_PIX_FMT_BGR565
#define AV_PIX_FMT_BGR565
Definition: pixfmt.h:396
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:56
av_rescale
int64_t av_rescale(int64_t a, int64_t b, int64_t c)
Rescale a 64-bit integer with rounding to nearest.
Definition: mathematics.c:128
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:580
AV_PIX_FMT_YUV444P9
#define AV_PIX_FMT_YUV444P9
Definition: pixfmt.h:403
OFFSET
#define OFFSET(x)
Definition: vsrc_testsrc.c:90
AV_PIX_FMT_RGB565
#define AV_PIX_FMT_RGB565
Definition: pixfmt.h:391
ff_draw_color
void ff_draw_color(FFDrawContext *draw, FFDrawColor *color, const uint8_t rgba[4])
Prepare a color.
Definition: drawutils.c:141
AVFilter
Filter definition.
Definition: avfilter.h:165
G
#define G
Definition: huffyuvdsp.h:33
ret
ret
Definition: filter_design.txt:187
AV_PIX_FMT_0BGR
@ AV_PIX_FMT_0BGR
packed BGR 8:8:8, 32bpp, XBGRXBGR... X=unused/undefined
Definition: pixfmt.h:229
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:264
pos
unsigned int pos
Definition: spdifenc.c:412
B
#define B
Definition: huffyuvdsp.h:32
ff_vsrc_rgbtestsrc
const AVFilter ff_vsrc_rgbtestsrc
test
static int test(void)
Definition: dnn-layer-dense.c:28
TestSourceContext::alpha
int alpha
Definition: vsrc_testsrc.c:71
activate
static int activate(AVFilterContext *ctx)
Definition: vsrc_testsrc.c:150
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:224
avfilter.h
AVFILTER_DEFINE_CLASS_EXT
AVFILTER_DEFINE_CLASS_EXT(nullsrc_yuvtestsrc, "nullsrc/yuvtestsrc", options)
AV_PIX_FMT_FLAG_PLANAR
#define AV_PIX_FMT_FLAG_PLANAR
At least one pixel component is not in the first data plane.
Definition: pixdesc.h:132
ffmath.h
AV_PIX_FMT_YUV444P
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:71
AVFilterContext
An instance of a filter.
Definition: avfilter.h:402
factor
static const int factor[16]
Definition: vf_pp7.c:76
TestSourceContext::pts
int64_t pts
Definition: vsrc_testsrc.c:58
AV_PIX_FMT_GBRP
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:158
desc
const char * desc
Definition: libsvtav1.c:79
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
AV_PIX_FMT_YUV422P
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:70
ff_vsrc_testsrc
const AVFilter ff_vsrc_testsrc
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
alpha
static const int16_t alpha[]
Definition: ilbcdata.h:55
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:241
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: internal.h:192
AV_PIX_FMT_YUV411P
@ AV_PIX_FMT_YUV411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
Definition: pixfmt.h:73
ff_fill_rgba_map
int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt)
Definition: drawutils.c:34
TestSourceContext::draw_once_reset
int draw_once_reset
draw only the first frame or in case of reset
Definition: vsrc_testsrc.c:62
imgutils.h
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:561
AVFrame::linesize
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
Definition: frame.h:362
AV_PIX_FMT_0RGB
@ AV_PIX_FMT_0RGB
packed RGB 8:8:8, 32bpp, XRGBXRGB... X=unused/undefined
Definition: pixfmt.h:227
AV_PIX_FMT_YUV410P
@ AV_PIX_FMT_YUV410P
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
Definition: pixfmt.h:72
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
TestSourceContext::w
int w
Definition: vsrc_testsrc.c:55
h
h
Definition: vp9dsp_template.c:2038
ff_outlink_frame_wanted
the definition of that something depends on the semantic of the filter The callback must examine the status of the filter s links and proceed accordingly The status of output links is stored in the status_in and status_out fields and tested by the ff_outlink_frame_wanted() function. If this function returns true
AV_PIX_FMT_YUV444P14
#define AV_PIX_FMT_YUV444P14
Definition: pixfmt.h:414
av_image_check_size
int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx)
Check if the given dimension of an image is valid, meaning that all bytes of the image can be address...
Definition: imgutils.c:318
TestSourceContext::draw
FFDrawContext draw
Definition: vsrc_testsrc.c:77
drawutils.h
planar
uint8_t pi<< 24) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_U8,(uint64_t)((*(const uint8_t *) pi - 0x80U))<< 56) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16,(*(const int16_t *) pi >>8)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S16, *(const int16_t *) pi *(1<< 16)) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S16,(uint64_t)(*(const int16_t *) pi)<< 48) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32,(*(const int32_t *) pi >>24)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S32,(uint64_t)(*(const int32_t *) pi)<< 32) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S64,(*(const int64_t *) pi >>56)+0x80) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S64, *(const int64_t *) pi *(1.0f/(UINT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S64, *(const int64_t *) pi *(1.0/(UINT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_FLT, llrintf(*(const float *) pi *(UINT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_DBL, llrint(*(const double *) pi *(UINT64_C(1)<< 63))) #define FMT_PAIR_FUNC(out, in) static conv_func_type *const fmt_pair_to_conv_functions[AV_SAMPLE_FMT_NB *AV_SAMPLE_FMT_NB]={ FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S64), };static void cpy1(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, len);} static void cpy2(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, 2 *len);} static void cpy4(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, 4 *len);} static void cpy8(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, 8 *len);} AudioConvert *swri_audio_convert_alloc(enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, const int *ch_map, int flags) { AudioConvert *ctx;conv_func_type *f=fmt_pair_to_conv_functions[av_get_packed_sample_fmt(out_fmt)+AV_SAMPLE_FMT_NB *av_get_packed_sample_fmt(in_fmt)];if(!f) return NULL;ctx=av_mallocz(sizeof(*ctx));if(!ctx) return NULL;if(channels==1){ in_fmt=av_get_planar_sample_fmt(in_fmt);out_fmt=av_get_planar_sample_fmt(out_fmt);} ctx->channels=channels;ctx->conv_f=f;ctx->ch_map=ch_map;if(in_fmt==AV_SAMPLE_FMT_U8||in_fmt==AV_SAMPLE_FMT_U8P) memset(ctx->silence, 0x80, sizeof(ctx->silence));if(out_fmt==in_fmt &&!ch_map) { switch(av_get_bytes_per_sample(in_fmt)){ case 1:ctx->simd_f=cpy1;break;case 2:ctx->simd_f=cpy2;break;case 4:ctx->simd_f=cpy4;break;case 8:ctx->simd_f=cpy8;break;} } if(HAVE_X86ASM &&1) swri_audio_convert_init_x86(ctx, out_fmt, in_fmt, channels);if(ARCH_ARM) swri_audio_convert_init_arm(ctx, out_fmt, in_fmt, channels);if(ARCH_AARCH64) swri_audio_convert_init_aarch64(ctx, out_fmt, in_fmt, channels);return ctx;} void swri_audio_convert_free(AudioConvert **ctx) { av_freep(ctx);} int swri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, int len) { int ch;int off=0;const int os=(out->planar ? 1 :out->ch_count) *out->bps;unsigned misaligned=0;av_assert0(ctx->channels==out->ch_count);if(ctx->in_simd_align_mask) { int planes=in->planar ? in->ch_count :1;unsigned m=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) in->ch[ch];misaligned|=m &ctx->in_simd_align_mask;} if(ctx->out_simd_align_mask) { int planes=out->planar ? out->ch_count :1;unsigned m=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) out->ch[ch];misaligned|=m &ctx->out_simd_align_mask;} if(ctx->simd_f &&!ctx->ch_map &&!misaligned){ off=len &~15;av_assert1(off >=0);av_assert1(off<=len);av_assert2(ctx->channels==SWR_CH_MAX||!in->ch[ctx->channels]);if(off >0){ if(out->planar==in->planar){ int planes=out->planar ? out->ch_count :1;for(ch=0;ch< planes;ch++){ ctx->simd_f(out->ch+ch,(const uint8_t **) in->ch+ch, off *(out-> planar
Definition: audioconvert.c:56
AVCOL_SPC_BT709
@ AVCOL_SPC_BT709
also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / derived in SMPTE RP 177 Annex B
Definition: pixfmt.h:525
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:233
snprintf
#define snprintf
Definition: snprintf.h:34
TestSourceContext::fill_picture_fn
void(* fill_picture_fn)(AVFilterContext *ctx, AVFrame *frame)
Definition: vsrc_testsrc.c:65
AVPixFmtDescriptor::log2_chroma_h
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:89
line
The official guide to swscale for confused that consecutive non overlapping rectangles of slice_bottom special converter These generally are unscaled converters of common like for each output line the vertical scaler pulls lines from a ring buffer When the ring buffer does not contain the wanted line
Definition: swscale.txt:40
TestSourceContext::depth
int depth
Definition: vsrc_testsrc.c:84
COMMON_OPTIONS_NOSIZE
#define COMMON_OPTIONS_NOSIZE
Definition: vsrc_testsrc.c:98
options
static const AVOption options[]
Definition: vsrc_testsrc.c:110
AV_PIX_FMT_RGB444
#define AV_PIX_FMT_RGB444
Definition: pixfmt.h:393