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 color */
77 
78  /* only used by rgbtest */
80 
81  /* only used by haldclut */
82  int level;
84 
85 #define OFFSET(x) offsetof(TestSourceContext, x)
86 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
87 #define FLAGSR AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
88 
89 #define SIZE_OPTIONS \
90  { "size", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "320x240"}, 0, 0, FLAGS },\
91  { "s", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "320x240"}, 0, 0, FLAGS },\
92 
93 #define COMMON_OPTIONS_NOSIZE \
94  { "rate", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, INT_MAX, FLAGS },\
95  { "r", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, INT_MAX, FLAGS },\
96  { "duration", "set video duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = -1}, -1, INT64_MAX, FLAGS },\
97  { "d", "set video duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = -1}, -1, INT64_MAX, FLAGS },\
98  { "sar", "set video sample aspect ratio", OFFSET(sar), AV_OPT_TYPE_RATIONAL, {.dbl= 1}, 0, INT_MAX, FLAGS },
99 
100 #define COMMON_OPTIONS SIZE_OPTIONS COMMON_OPTIONS_NOSIZE
101 
102 static const AVOption options[] = {
104  { NULL }
105 };
106 
108 {
109  TestSourceContext *test = ctx->priv;
110 
111  test->time_base = av_inv_q(test->frame_rate);
112  test->nb_frame = 0;
113  test->pts = 0;
114 
115  av_log(ctx, AV_LOG_VERBOSE, "size:%dx%d rate:%d/%d duration:%f sar:%d/%d\n",
116  test->w, test->h, test->frame_rate.num, test->frame_rate.den,
117  test->duration < 0 ? -1 : (double)test->duration/1000000,
118  test->sar.num, test->sar.den);
119  return 0;
120 }
121 
123 {
124  TestSourceContext *test = ctx->priv;
125 
126  av_frame_free(&test->picref);
127 }
128 
129 static int config_props(AVFilterLink *outlink)
130 {
131  TestSourceContext *test = outlink->src->priv;
132 
133  outlink->w = test->w;
134  outlink->h = test->h;
135  outlink->sample_aspect_ratio = test->sar;
136  outlink->frame_rate = test->frame_rate;
137  outlink->time_base = test->time_base;
138 
139  return 0;
140 }
141 
143 {
144  AVFilterLink *outlink = ctx->outputs[0];
145  TestSourceContext *test = ctx->priv;
146  AVFrame *frame;
147 
148  if (!ff_outlink_frame_wanted(outlink))
149  return FFERROR_NOT_READY;
150  if (test->duration >= 0 &&
151  av_rescale_q(test->pts, test->time_base, AV_TIME_BASE_Q) >= test->duration) {
152  ff_outlink_set_status(outlink, AVERROR_EOF, test->pts);
153  return 0;
154  }
155 
156  if (test->draw_once) {
157  if (test->draw_once_reset) {
158  av_frame_free(&test->picref);
159  test->draw_once_reset = 0;
160  }
161  if (!test->picref) {
162  test->picref =
163  ff_get_video_buffer(outlink, test->w, test->h);
164  if (!test->picref)
165  return AVERROR(ENOMEM);
166  test->fill_picture_fn(outlink->src, test->picref);
167  }
168  frame = av_frame_clone(test->picref);
169  } else
170  frame = ff_get_video_buffer(outlink, test->w, test->h);
171 
172  if (!frame)
173  return AVERROR(ENOMEM);
174  frame->pts = test->pts;
175  frame->key_frame = 1;
176  frame->interlaced_frame = 0;
177  frame->pict_type = AV_PICTURE_TYPE_I;
178  frame->sample_aspect_ratio = test->sar;
179  if (!test->draw_once)
180  test->fill_picture_fn(outlink->src, frame);
181 
182  test->pts++;
183  test->nb_frame++;
184 
185  return ff_filter_frame(outlink, frame);
186 }
187 
188 #if CONFIG_COLOR_FILTER
189 
190 static const AVOption color_options[] = {
191  { "color", "set color", OFFSET(color_rgba), AV_OPT_TYPE_COLOR, {.str = "black"}, 0, 0, FLAGSR },
192  { "c", "set color", OFFSET(color_rgba), AV_OPT_TYPE_COLOR, {.str = "black"}, 0, 0, FLAGSR },
194  { NULL }
195 };
196 
198 
199 static void color_fill_picture(AVFilterContext *ctx, AVFrame *picref)
200 {
201  TestSourceContext *test = ctx->priv;
202  ff_fill_rectangle(&test->draw, &test->color,
203  picref->data, picref->linesize,
204  0, 0, test->w, test->h);
205 }
206 
207 static av_cold int color_init(AVFilterContext *ctx)
208 {
209  TestSourceContext *test = ctx->priv;
210  test->fill_picture_fn = color_fill_picture;
211  test->draw_once = 1;
212  return init(ctx);
213 }
214 
215 static int color_query_formats(AVFilterContext *ctx)
216 {
218 }
219 
220 static int color_config_props(AVFilterLink *inlink)
221 {
222  AVFilterContext *ctx = inlink->src;
223  TestSourceContext *test = ctx->priv;
224  int ret;
225 
226  ff_draw_init(&test->draw, inlink->format, 0);
227  ff_draw_color(&test->draw, &test->color, test->color_rgba);
228 
229  test->w = ff_draw_round_to_sub(&test->draw, 0, -1, test->w);
230  test->h = ff_draw_round_to_sub(&test->draw, 1, -1, test->h);
231  if (av_image_check_size(test->w, test->h, 0, ctx) < 0)
232  return AVERROR(EINVAL);
233 
234  if ((ret = config_props(inlink)) < 0)
235  return ret;
236 
237  return 0;
238 }
239 
240 static int color_process_command(AVFilterContext *ctx, const char *cmd, const char *args,
241  char *res, int res_len, int flags)
242 {
243  TestSourceContext *test = ctx->priv;
244  int ret;
245 
246  ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags);
247  if (ret < 0)
248  return ret;
249 
250  ff_draw_color(&test->draw, &test->color, test->color_rgba);
251  test->draw_once_reset = 1;
252  return 0;
253 }
254 
255 static const AVFilterPad color_outputs[] = {
256  {
257  .name = "default",
258  .type = AVMEDIA_TYPE_VIDEO,
259  .config_props = color_config_props,
260  },
261  { NULL }
262 };
263 
265  .name = "color",
266  .description = NULL_IF_CONFIG_SMALL("Provide an uniformly colored input."),
267  .priv_class = &color_class,
268  .priv_size = sizeof(TestSourceContext),
269  .init = color_init,
270  .uninit = uninit,
271  .activate = activate,
272  .query_formats = color_query_formats,
273  .inputs = NULL,
274  .outputs = color_outputs,
275  .process_command = color_process_command,
276 };
277 
278 #endif /* CONFIG_COLOR_FILTER */
279 
280 #if CONFIG_HALDCLUTSRC_FILTER
281 
282 static const AVOption haldclutsrc_options[] = {
283  { "level", "set level", OFFSET(level), AV_OPT_TYPE_INT, {.i64 = 6}, 2, 16, FLAGS },
285  { NULL }
286 };
287 
288 AVFILTER_DEFINE_CLASS(haldclutsrc);
289 
290 static void haldclutsrc_fill_picture(AVFilterContext *ctx, AVFrame *frame)
291 {
292  int i, j, k, x = 0, y = 0, is16bit = 0, step;
293  uint32_t alpha = 0;
294  const TestSourceContext *hc = ctx->priv;
295  int level = hc->level;
296  float scale;
297  const int w = frame->width;
298  const int h = frame->height;
299  const uint8_t *data = frame->data[0];
300  const int linesize = frame->linesize[0];
302  uint8_t rgba_map[4];
303 
304  av_assert0(w == h && w == level*level*level);
305 
306  ff_fill_rgba_map(rgba_map, frame->format);
307 
308  switch (frame->format) {
309  case AV_PIX_FMT_RGB48:
310  case AV_PIX_FMT_BGR48:
311  case AV_PIX_FMT_RGBA64:
312  case AV_PIX_FMT_BGRA64:
313  is16bit = 1;
314  alpha = 0xffff;
315  break;
316  case AV_PIX_FMT_RGBA:
317  case AV_PIX_FMT_BGRA:
318  case AV_PIX_FMT_ARGB:
319  case AV_PIX_FMT_ABGR:
320  alpha = 0xff;
321  break;
322  }
323 
324  step = av_get_padded_bits_per_pixel(desc) >> (3 + is16bit);
325  scale = ((float)(1 << (8*(is16bit+1))) - 1) / (level*level - 1);
326 
327 #define LOAD_CLUT(nbits) do { \
328  uint##nbits##_t *dst = ((uint##nbits##_t *)(data + y*linesize)) + x*step; \
329  dst[rgba_map[0]] = av_clip_uint##nbits(i * scale); \
330  dst[rgba_map[1]] = av_clip_uint##nbits(j * scale); \
331  dst[rgba_map[2]] = av_clip_uint##nbits(k * scale); \
332  if (step == 4) \
333  dst[rgba_map[3]] = alpha; \
334 } while (0)
335 
336  level *= level;
337  for (k = 0; k < level; k++) {
338  for (j = 0; j < level; j++) {
339  for (i = 0; i < level; i++) {
340  if (!is16bit)
341  LOAD_CLUT(8);
342  else
343  LOAD_CLUT(16);
344  if (++x == w) {
345  x = 0;
346  y++;
347  }
348  }
349  }
350  }
351 }
352 
353 static av_cold int haldclutsrc_init(AVFilterContext *ctx)
354 {
355  TestSourceContext *hc = ctx->priv;
356  hc->fill_picture_fn = haldclutsrc_fill_picture;
357  hc->draw_once = 1;
358  return init(ctx);
359 }
360 
361 static int haldclutsrc_query_formats(AVFilterContext *ctx)
362 {
363  static const enum AVPixelFormat pix_fmts[] = {
372  };
373 
374  AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts);
375  if (!fmts_list)
376  return AVERROR(ENOMEM);
377  return ff_set_common_formats(ctx, fmts_list);
378 }
379 
380 static int haldclutsrc_config_props(AVFilterLink *outlink)
381 {
382  AVFilterContext *ctx = outlink->src;
383  TestSourceContext *hc = ctx->priv;
384 
385  hc->w = hc->h = hc->level * hc->level * hc->level;
386  return config_props(outlink);
387 }
388 
389 static const AVFilterPad haldclutsrc_outputs[] = {
390  {
391  .name = "default",
392  .type = AVMEDIA_TYPE_VIDEO,
393  .config_props = haldclutsrc_config_props,
394  },
395  { NULL }
396 };
397 
399  .name = "haldclutsrc",
400  .description = NULL_IF_CONFIG_SMALL("Provide an identity Hald CLUT."),
401  .priv_class = &haldclutsrc_class,
402  .priv_size = sizeof(TestSourceContext),
403  .init = haldclutsrc_init,
404  .uninit = uninit,
405  .query_formats = haldclutsrc_query_formats,
406  .activate = activate,
407  .inputs = NULL,
408  .outputs = haldclutsrc_outputs,
409 };
410 #endif /* CONFIG_HALDCLUTSRC_FILTER */
411 
412 #if CONFIG_NULLSRC_FILTER
413 
414 #define nullsrc_options options
415 AVFILTER_DEFINE_CLASS(nullsrc);
416 
417 static void nullsrc_fill_picture(AVFilterContext *ctx, AVFrame *picref) { }
418 
419 static av_cold int nullsrc_init(AVFilterContext *ctx)
420 {
421  TestSourceContext *test = ctx->priv;
422 
423  test->fill_picture_fn = nullsrc_fill_picture;
424  return init(ctx);
425 }
426 
427 static const AVFilterPad nullsrc_outputs[] = {
428  {
429  .name = "default",
430  .type = AVMEDIA_TYPE_VIDEO,
431  .config_props = config_props,
432  },
433  { NULL },
434 };
435 
437  .name = "nullsrc",
438  .description = NULL_IF_CONFIG_SMALL("Null video source, return unprocessed video frames."),
439  .init = nullsrc_init,
440  .uninit = uninit,
441  .activate = activate,
442  .priv_size = sizeof(TestSourceContext),
443  .priv_class = &nullsrc_class,
444  .inputs = NULL,
445  .outputs = nullsrc_outputs,
446 };
447 
448 #endif /* CONFIG_NULLSRC_FILTER */
449 
450 #if CONFIG_TESTSRC_FILTER
451 
452 static const AVOption testsrc_options[] = {
454  { "decimals", "set number of decimals to show", OFFSET(nb_decimals), AV_OPT_TYPE_INT, {.i64=0}, 0, 17, FLAGS },
455  { "n", "set number of decimals to show", OFFSET(nb_decimals), AV_OPT_TYPE_INT, {.i64=0}, 0, 17, FLAGS },
456  { NULL }
457 };
458 
459 AVFILTER_DEFINE_CLASS(testsrc);
460 
461 /**
462  * Fill a rectangle with value val.
463  *
464  * @param val the RGB value to set
465  * @param dst pointer to the destination buffer to fill
466  * @param dst_linesize linesize of destination
467  * @param segment_width width of the segment
468  * @param x horizontal coordinate where to draw the rectangle in the destination buffer
469  * @param y horizontal coordinate where to draw the rectangle in the destination buffer
470  * @param w width of the rectangle to draw, expressed as a number of segment_width units
471  * @param h height of the rectangle to draw, expressed as a number of segment_width units
472  */
473 static void draw_rectangle(unsigned val, uint8_t *dst, int dst_linesize, int segment_width,
474  int x, int y, int w, int h)
475 {
476  int i;
477  int step = 3;
478 
479  dst += segment_width * (step * x + y * dst_linesize);
480  w *= segment_width * step;
481  h *= segment_width;
482  for (i = 0; i < h; i++) {
483  memset(dst, val, w);
484  dst += dst_linesize;
485  }
486 }
487 
488 static void draw_digit(int digit, uint8_t *dst, int dst_linesize,
489  int segment_width)
490 {
491 #define TOP_HBAR 1
492 #define MID_HBAR 2
493 #define BOT_HBAR 4
494 #define LEFT_TOP_VBAR 8
495 #define LEFT_BOT_VBAR 16
496 #define RIGHT_TOP_VBAR 32
497 #define RIGHT_BOT_VBAR 64
498  struct segments {
499  int x, y, w, h;
500  } segments[] = {
501  { 1, 0, 5, 1 }, /* TOP_HBAR */
502  { 1, 6, 5, 1 }, /* MID_HBAR */
503  { 1, 12, 5, 1 }, /* BOT_HBAR */
504  { 0, 1, 1, 5 }, /* LEFT_TOP_VBAR */
505  { 0, 7, 1, 5 }, /* LEFT_BOT_VBAR */
506  { 6, 1, 1, 5 }, /* RIGHT_TOP_VBAR */
507  { 6, 7, 1, 5 } /* RIGHT_BOT_VBAR */
508  };
509  static const unsigned char masks[10] = {
510  /* 0 */ TOP_HBAR |BOT_HBAR|LEFT_TOP_VBAR|LEFT_BOT_VBAR|RIGHT_TOP_VBAR|RIGHT_BOT_VBAR,
511  /* 1 */ RIGHT_TOP_VBAR|RIGHT_BOT_VBAR,
512  /* 2 */ TOP_HBAR|MID_HBAR|BOT_HBAR|LEFT_BOT_VBAR |RIGHT_TOP_VBAR,
513  /* 3 */ TOP_HBAR|MID_HBAR|BOT_HBAR |RIGHT_TOP_VBAR|RIGHT_BOT_VBAR,
514  /* 4 */ MID_HBAR |LEFT_TOP_VBAR |RIGHT_TOP_VBAR|RIGHT_BOT_VBAR,
515  /* 5 */ TOP_HBAR|BOT_HBAR|MID_HBAR|LEFT_TOP_VBAR |RIGHT_BOT_VBAR,
516  /* 6 */ TOP_HBAR|BOT_HBAR|MID_HBAR|LEFT_TOP_VBAR|LEFT_BOT_VBAR |RIGHT_BOT_VBAR,
517  /* 7 */ TOP_HBAR |RIGHT_TOP_VBAR|RIGHT_BOT_VBAR,
518  /* 8 */ TOP_HBAR|BOT_HBAR|MID_HBAR|LEFT_TOP_VBAR|LEFT_BOT_VBAR|RIGHT_TOP_VBAR|RIGHT_BOT_VBAR,
519  /* 9 */ TOP_HBAR|BOT_HBAR|MID_HBAR|LEFT_TOP_VBAR |RIGHT_TOP_VBAR|RIGHT_BOT_VBAR,
520  };
521  unsigned mask = masks[digit];
522  int i;
523 
524  draw_rectangle(0, dst, dst_linesize, segment_width, 0, 0, 8, 13);
525  for (i = 0; i < FF_ARRAY_ELEMS(segments); i++)
526  if (mask & (1<<i))
527  draw_rectangle(255, dst, dst_linesize, segment_width,
528  segments[i].x, segments[i].y, segments[i].w, segments[i].h);
529 }
530 
531 #define GRADIENT_SIZE (6 * 256)
532 
533 static void test_fill_picture(AVFilterContext *ctx, AVFrame *frame)
534 {
535  TestSourceContext *test = ctx->priv;
536  uint8_t *p, *p0;
537  int x, y;
538  int color, color_rest;
539  int icolor;
540  int radius;
541  int quad0, quad;
542  int dquad_x, dquad_y;
543  int grad, dgrad, rgrad, drgrad;
544  int seg_size;
545  int second;
546  int i;
547  uint8_t *data = frame->data[0];
548  int width = frame->width;
549  int height = frame->height;
550 
551  /* draw colored bars and circle */
552  radius = (width + height) / 4;
553  quad0 = width * width / 4 + height * height / 4 - radius * radius;
554  dquad_y = 1 - height;
555  p0 = data;
556  for (y = 0; y < height; y++) {
557  p = p0;
558  color = 0;
559  color_rest = 0;
560  quad = quad0;
561  dquad_x = 1 - width;
562  for (x = 0; x < width; x++) {
563  icolor = color;
564  if (quad < 0)
565  icolor ^= 7;
566  quad += dquad_x;
567  dquad_x += 2;
568  *(p++) = icolor & 1 ? 255 : 0;
569  *(p++) = icolor & 2 ? 255 : 0;
570  *(p++) = icolor & 4 ? 255 : 0;
571  color_rest += 8;
572  if (color_rest >= width) {
573  color_rest -= width;
574  color++;
575  }
576  }
577  quad0 += dquad_y;
578  dquad_y += 2;
579  p0 += frame->linesize[0];
580  }
581 
582  /* draw sliding color line */
583  p0 = p = data + frame->linesize[0] * (height * 3/4);
584  grad = (256 * test->nb_frame * test->time_base.num / test->time_base.den) %
585  GRADIENT_SIZE;
586  rgrad = 0;
587  dgrad = GRADIENT_SIZE / width;
588  drgrad = GRADIENT_SIZE % width;
589  for (x = 0; x < width; x++) {
590  *(p++) =
591  grad < 256 || grad >= 5 * 256 ? 255 :
592  grad >= 2 * 256 && grad < 4 * 256 ? 0 :
593  grad < 2 * 256 ? 2 * 256 - 1 - grad : grad - 4 * 256;
594  *(p++) =
595  grad >= 4 * 256 ? 0 :
596  grad >= 1 * 256 && grad < 3 * 256 ? 255 :
597  grad < 1 * 256 ? grad : 4 * 256 - 1 - grad;
598  *(p++) =
599  grad < 2 * 256 ? 0 :
600  grad >= 3 * 256 && grad < 5 * 256 ? 255 :
601  grad < 3 * 256 ? grad - 2 * 256 : 6 * 256 - 1 - grad;
602  grad += dgrad;
603  rgrad += drgrad;
604  if (rgrad >= GRADIENT_SIZE) {
605  grad++;
606  rgrad -= GRADIENT_SIZE;
607  }
608  if (grad >= GRADIENT_SIZE)
609  grad -= GRADIENT_SIZE;
610  }
611  p = p0;
612  for (y = height / 8; y > 0; y--) {
613  memcpy(p+frame->linesize[0], p, 3 * width);
614  p += frame->linesize[0];
615  }
616 
617  /* draw digits */
618  seg_size = width / 80;
619  if (seg_size >= 1 && height >= 13 * seg_size) {
620  int64_t p10decimals = 1;
621  double time = av_q2d(test->time_base) * test->nb_frame *
622  ff_exp10(test->nb_decimals);
623  if (time >= INT_MAX)
624  return;
625 
626  for (x = 0; x < test->nb_decimals; x++)
627  p10decimals *= 10;
628 
629  second = av_rescale_rnd(test->nb_frame * test->time_base.num, p10decimals, test->time_base.den, AV_ROUND_ZERO);
630  x = width - (width - seg_size * 64) / 2;
631  y = (height - seg_size * 13) / 2;
632  p = data + (x*3 + y * frame->linesize[0]);
633  for (i = 0; i < 8; i++) {
634  p -= 3 * 8 * seg_size;
635  draw_digit(second % 10, p, frame->linesize[0], seg_size);
636  second /= 10;
637  if (second == 0)
638  break;
639  }
640  }
641 }
642 
643 static av_cold int test_init(AVFilterContext *ctx)
644 {
645  TestSourceContext *test = ctx->priv;
646 
647  test->fill_picture_fn = test_fill_picture;
648  return init(ctx);
649 }
650 
651 static int test_query_formats(AVFilterContext *ctx)
652 {
653  static const enum AVPixelFormat pix_fmts[] = {
655  };
656 
657  AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts);
658  if (!fmts_list)
659  return AVERROR(ENOMEM);
660  return ff_set_common_formats(ctx, fmts_list);
661 }
662 
663 static const AVFilterPad avfilter_vsrc_testsrc_outputs[] = {
664  {
665  .name = "default",
666  .type = AVMEDIA_TYPE_VIDEO,
667  .config_props = config_props,
668  },
669  { NULL }
670 };
671 
673  .name = "testsrc",
674  .description = NULL_IF_CONFIG_SMALL("Generate test pattern."),
675  .priv_size = sizeof(TestSourceContext),
676  .priv_class = &testsrc_class,
677  .init = test_init,
678  .uninit = uninit,
679  .query_formats = test_query_formats,
680  .activate = activate,
681  .inputs = NULL,
682  .outputs = avfilter_vsrc_testsrc_outputs,
683 };
684 
685 #endif /* CONFIG_TESTSRC_FILTER */
686 
687 #if CONFIG_TESTSRC2_FILTER
688 
689 static const AVOption testsrc2_options[] = {
691  { "alpha", "set global alpha (opacity)", OFFSET(alpha), AV_OPT_TYPE_INT, {.i64 = 255}, 0, 255, FLAGS },
692  { NULL }
693 };
694 
695 AVFILTER_DEFINE_CLASS(testsrc2);
696 
697 static void set_color(TestSourceContext *s, FFDrawColor *color, uint32_t argb)
698 {
699  uint8_t rgba[4] = { (argb >> 16) & 0xFF,
700  (argb >> 8) & 0xFF,
701  (argb >> 0) & 0xFF,
702  (argb >> 24) & 0xFF, };
703  ff_draw_color(&s->draw, color, rgba);
704 }
705 
706 static uint32_t color_gradient(unsigned index)
707 {
708  unsigned si = index & 0xFF, sd = 0xFF - si;
709  switch (index >> 8) {
710  case 0: return 0xFF0000 + (si << 8);
711  case 1: return 0x00FF00 + (sd << 16);
712  case 2: return 0x00FF00 + (si << 0);
713  case 3: return 0x0000FF + (sd << 8);
714  case 4: return 0x0000FF + (si << 16);
715  case 5: return 0xFF0000 + (sd << 0);
716  }
717  av_assert0(0);
718 }
719 
720 static void draw_text(TestSourceContext *s, AVFrame *frame, FFDrawColor *color,
721  int x0, int y0, const uint8_t *text)
722 {
723  int x = x0;
724 
725  for (; *text; text++) {
726  if (*text == '\n') {
727  x = x0;
728  y0 += 16;
729  continue;
730  }
731  ff_blend_mask(&s->draw, color, frame->data, frame->linesize,
732  frame->width, frame->height,
733  avpriv_vga16_font + *text * 16, 1, 8, 16, 0, 0, x, y0);
734  x += 8;
735  }
736 }
737 
738 static void test2_fill_picture(AVFilterContext *ctx, AVFrame *frame)
739 {
740  TestSourceContext *s = ctx->priv;
742  unsigned alpha = (uint32_t)s->alpha << 24;
743 
744  /* colored background */
745  {
746  unsigned i, x = 0, x2;
747 
748  x = 0;
749  for (i = 1; i < 7; i++) {
750  x2 = av_rescale(i, s->w, 6);
751  x2 = ff_draw_round_to_sub(&s->draw, 0, 0, x2);
752  set_color(s, &color, ((i & 1) ? 0xFF0000 : 0) |
753  ((i & 2) ? 0x00FF00 : 0) |
754  ((i & 4) ? 0x0000FF : 0) |
755  alpha);
756  ff_fill_rectangle(&s->draw, &color, frame->data, frame->linesize,
757  x, 0, x2 - x, frame->height);
758  x = x2;
759  }
760  }
761 
762  /* oblique gradient */
763  /* note: too slow if using blending */
764  if (s->h >= 64) {
765  unsigned x, dx, y0, y, g0, g;
766 
767  dx = ff_draw_round_to_sub(&s->draw, 0, +1, 1);
768  y0 = av_rescale_q(s->pts, s->time_base, av_make_q(2, s->h - 16));
769  g0 = av_rescale_q(s->pts, s->time_base, av_make_q(1, 128));
770  for (x = 0; x < s->w; x += dx) {
771  g = (av_rescale(x, 6 * 256, s->w) + g0) % (6 * 256);
772  set_color(s, &color, color_gradient(g) | alpha);
773  y = y0 + av_rescale(x, s->h / 2, s->w);
774  y %= 2 * (s->h - 16);
775  if (y > s->h - 16)
776  y = 2 * (s->h - 16) - y;
777  y = ff_draw_round_to_sub(&s->draw, 1, 0, y);
778  ff_fill_rectangle(&s->draw, &color, frame->data, frame->linesize,
779  x, y, dx, 16);
780  }
781  }
782 
783  /* top right: draw clock hands */
784  if (s->w >= 64 && s->h >= 64) {
785  int l = (FFMIN(s->w, s->h) - 32) >> 1;
786  int steps = FFMAX(4, l >> 5);
787  int xc = (s->w >> 2) + (s->w >> 1);
788  int yc = (s->h >> 2);
789  int cycle = l << 2;
790  int pos, xh, yh;
791  int c, i;
792 
793  for (c = 0; c < 3; c++) {
794  set_color(s, &color, (0xBBBBBB ^ (0xFF << (c << 3))) | alpha);
795  pos = av_rescale_q(s->pts, s->time_base, av_make_q(64 >> (c << 1), cycle)) % cycle;
796  xh = pos < 1 * l ? pos :
797  pos < 2 * l ? l :
798  pos < 3 * l ? 3 * l - pos : 0;
799  yh = pos < 1 * l ? 0 :
800  pos < 2 * l ? pos - l :
801  pos < 3 * l ? l :
802  cycle - pos;
803  xh -= l >> 1;
804  yh -= l >> 1;
805  for (i = 1; i <= steps; i++) {
806  int x = av_rescale(xh, i, steps) + xc;
807  int y = av_rescale(yh, i, steps) + yc;
808  x = ff_draw_round_to_sub(&s->draw, 0, -1, x);
809  y = ff_draw_round_to_sub(&s->draw, 1, -1, y);
810  ff_fill_rectangle(&s->draw, &color, frame->data, frame->linesize,
811  x, y, 8, 8);
812  }
813  }
814  }
815 
816  /* bottom left: beating rectangles */
817  if (s->w >= 64 && s->h >= 64) {
818  int l = (FFMIN(s->w, s->h) - 16) >> 2;
819  int cycle = l << 3;
820  int xc = (s->w >> 2);
821  int yc = (s->h >> 2) + (s->h >> 1);
822  int xm1 = ff_draw_round_to_sub(&s->draw, 0, -1, xc - 8);
823  int xm2 = ff_draw_round_to_sub(&s->draw, 0, +1, xc + 8);
824  int ym1 = ff_draw_round_to_sub(&s->draw, 1, -1, yc - 8);
825  int ym2 = ff_draw_round_to_sub(&s->draw, 1, +1, yc + 8);
826  int size, step, x1, x2, y1, y2;
827 
828  size = av_rescale_q(s->pts, s->time_base, av_make_q(4, cycle));
829  step = size / l;
830  size %= l;
831  if (step & 1)
832  size = l - size;
833  step = (step >> 1) & 3;
834  set_color(s, &color, 0xFF808080);
835  x1 = ff_draw_round_to_sub(&s->draw, 0, -1, xc - 4 - size);
836  x2 = ff_draw_round_to_sub(&s->draw, 0, +1, xc + 4 + size);
837  y1 = ff_draw_round_to_sub(&s->draw, 1, -1, yc - 4 - size);
838  y2 = ff_draw_round_to_sub(&s->draw, 1, +1, yc + 4 + size);
839  if (step == 0 || step == 2)
840  ff_fill_rectangle(&s->draw, &color, frame->data, frame->linesize,
841  x1, ym1, x2 - x1, ym2 - ym1);
842  if (step == 1 || step == 2)
843  ff_fill_rectangle(&s->draw, &color, frame->data, frame->linesize,
844  xm1, y1, xm2 - xm1, y2 - y1);
845  if (step == 3)
846  ff_fill_rectangle(&s->draw, &color, frame->data, frame->linesize,
847  x1, y1, x2 - x1, y2 - y1);
848  }
849 
850  /* bottom right: checker with random noise */
851  {
852  unsigned xmin = av_rescale(5, s->w, 8);
853  unsigned xmax = av_rescale(7, s->w, 8);
854  unsigned ymin = av_rescale(5, s->h, 8);
855  unsigned ymax = av_rescale(7, s->h, 8);
856  unsigned x, y, i, r;
857  uint8_t alpha[256];
858 
859  r = s->pts;
860  for (y = ymin; y + 15 < ymax; y += 16) {
861  for (x = xmin; x + 15 < xmax; x += 16) {
862  if ((x ^ y) & 16)
863  continue;
864  for (i = 0; i < 256; i++) {
865  r = r * 1664525 + 1013904223;
866  alpha[i] = r >> 24;
867  }
868  set_color(s, &color, 0xFF00FF80);
869  ff_blend_mask(&s->draw, &color, frame->data, frame->linesize,
870  frame->width, frame->height,
871  alpha, 16, 16, 16, 3, 0, x, y);
872  }
873  }
874  }
875 
876  /* bouncing square */
877  if (s->w >= 16 && s->h >= 16) {
878  unsigned w = s->w - 8;
879  unsigned h = s->h - 8;
880  unsigned x = av_rescale_q(s->pts, s->time_base, av_make_q(233, 55 * w)) % (w << 1);
881  unsigned y = av_rescale_q(s->pts, s->time_base, av_make_q(233, 89 * h)) % (h << 1);
882  if (x > w)
883  x = (w << 1) - x;
884  if (y > h)
885  y = (h << 1) - y;
886  x = ff_draw_round_to_sub(&s->draw, 0, -1, x);
887  y = ff_draw_round_to_sub(&s->draw, 1, -1, y);
888  set_color(s, &color, 0xFF8000FF);
889  ff_fill_rectangle(&s->draw, &color, frame->data, frame->linesize,
890  x, y, 8, 8);
891  }
892 
893  /* top right: draw frame time and frame number */
894  {
895  char buf[256];
896  unsigned time;
897 
898  time = av_rescale_q(s->pts, s->time_base, av_make_q(1, 1000)) % 86400000;
899  set_color(s, &color, 0xC0000000);
900  ff_blend_rectangle(&s->draw, &color, frame->data, frame->linesize,
901  frame->width, frame->height,
902  2, 2, 100, 36);
903  set_color(s, &color, 0xFFFF8000);
904  snprintf(buf, sizeof(buf), "%02d:%02d:%02d.%03d\n%12"PRIi64,
905  time / 3600000, (time / 60000) % 60, (time / 1000) % 60,
906  time % 1000, s->pts);
907  draw_text(s, frame, &color, 4, 4, buf);
908  }
909 }
910 static av_cold int test2_init(AVFilterContext *ctx)
911 {
912  TestSourceContext *s = ctx->priv;
913 
914  s->fill_picture_fn = test2_fill_picture;
915  return init(ctx);
916 }
917 
918 static int test2_query_formats(AVFilterContext *ctx)
919 {
921 }
922 
923 static int test2_config_props(AVFilterLink *inlink)
924 {
925  AVFilterContext *ctx = inlink->src;
926  TestSourceContext *s = ctx->priv;
927 
928  av_assert0(ff_draw_init(&s->draw, inlink->format, 0) >= 0);
929  s->w = ff_draw_round_to_sub(&s->draw, 0, -1, s->w);
930  s->h = ff_draw_round_to_sub(&s->draw, 1, -1, s->h);
931  if (av_image_check_size(s->w, s->h, 0, ctx) < 0)
932  return AVERROR(EINVAL);
933  return config_props(inlink);
934 }
935 
936 static const AVFilterPad avfilter_vsrc_testsrc2_outputs[] = {
937  {
938  .name = "default",
939  .type = AVMEDIA_TYPE_VIDEO,
940  .config_props = test2_config_props,
941  },
942  { NULL }
943 };
944 
946  .name = "testsrc2",
947  .description = NULL_IF_CONFIG_SMALL("Generate another test pattern."),
948  .priv_size = sizeof(TestSourceContext),
949  .priv_class = &testsrc2_class,
950  .init = test2_init,
951  .uninit = uninit,
952  .query_formats = test2_query_formats,
953  .activate = activate,
954  .inputs = NULL,
955  .outputs = avfilter_vsrc_testsrc2_outputs,
956 };
957 
958 #endif /* CONFIG_TESTSRC2_FILTER */
959 
960 #if CONFIG_RGBTESTSRC_FILTER
961 
962 #define rgbtestsrc_options options
963 AVFILTER_DEFINE_CLASS(rgbtestsrc);
964 
965 #define R 0
966 #define G 1
967 #define B 2
968 #define A 3
969 
970 static void rgbtest_put_pixel(uint8_t *dst, int dst_linesize,
971  int x, int y, unsigned r, unsigned g, unsigned b, enum AVPixelFormat fmt,
972  uint8_t rgba_map[4])
973 {
974  uint32_t v;
975  uint8_t *p;
976 
977  switch (fmt) {
978  case AV_PIX_FMT_BGR444: ((uint16_t*)(dst + y*dst_linesize))[x] = ((r >> 4) << 8) | ((g >> 4) << 4) | (b >> 4); break;
979  case AV_PIX_FMT_RGB444: ((uint16_t*)(dst + y*dst_linesize))[x] = ((b >> 4) << 8) | ((g >> 4) << 4) | (r >> 4); break;
980  case AV_PIX_FMT_BGR555: ((uint16_t*)(dst + y*dst_linesize))[x] = ((r>>3)<<10) | ((g>>3)<<5) | (b>>3); break;
981  case AV_PIX_FMT_RGB555: ((uint16_t*)(dst + y*dst_linesize))[x] = ((b>>3)<<10) | ((g>>3)<<5) | (r>>3); break;
982  case AV_PIX_FMT_BGR565: ((uint16_t*)(dst + y*dst_linesize))[x] = ((r>>3)<<11) | ((g>>2)<<5) | (b>>3); break;
983  case AV_PIX_FMT_RGB565: ((uint16_t*)(dst + y*dst_linesize))[x] = ((b>>3)<<11) | ((g>>2)<<5) | (r>>3); break;
984  case AV_PIX_FMT_RGB24:
985  case AV_PIX_FMT_BGR24:
986  v = (r << (rgba_map[R]*8)) + (g << (rgba_map[G]*8)) + (b << (rgba_map[B]*8));
987  p = dst + 3*x + y*dst_linesize;
988  AV_WL24(p, v);
989  break;
990  case AV_PIX_FMT_RGBA:
991  case AV_PIX_FMT_BGRA:
992  case AV_PIX_FMT_ARGB:
993  case AV_PIX_FMT_ABGR:
994  v = (r << (rgba_map[R]*8)) + (g << (rgba_map[G]*8)) + (b << (rgba_map[B]*8)) + (255U << (rgba_map[A]*8));
995  p = dst + 4*x + y*dst_linesize;
996  AV_WL32(p, v);
997  break;
998  }
999 }
1000 
1001 static void rgbtest_fill_picture(AVFilterContext *ctx, AVFrame *frame)
1002 {
1003  TestSourceContext *test = ctx->priv;
1004  int x, y, w = frame->width, h = frame->height;
1005 
1006  for (y = 0; y < h; y++) {
1007  for (x = 0; x < w; x++) {
1008  int c = 256*x/w;
1009  int r = 0, g = 0, b = 0;
1010 
1011  if (3*y < h ) r = c;
1012  else if (3*y < 2*h) g = c;
1013  else b = c;
1014 
1015  rgbtest_put_pixel(frame->data[0], frame->linesize[0], x, y, r, g, b,
1016  ctx->outputs[0]->format, test->rgba_map);
1017  }
1018  }
1019 }
1020 
1021 static av_cold int rgbtest_init(AVFilterContext *ctx)
1022 {
1023  TestSourceContext *test = ctx->priv;
1024 
1025  test->draw_once = 1;
1026  test->fill_picture_fn = rgbtest_fill_picture;
1027  return init(ctx);
1028 }
1029 
1030 static int rgbtest_query_formats(AVFilterContext *ctx)
1031 {
1032  static const enum AVPixelFormat pix_fmts[] = {
1039  };
1040 
1041  AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts);
1042  if (!fmts_list)
1043  return AVERROR(ENOMEM);
1044  return ff_set_common_formats(ctx, fmts_list);
1045 }
1046 
1047 static int rgbtest_config_props(AVFilterLink *outlink)
1048 {
1049  TestSourceContext *test = outlink->src->priv;
1050 
1051  ff_fill_rgba_map(test->rgba_map, outlink->format);
1052  return config_props(outlink);
1053 }
1054 
1055 static const AVFilterPad avfilter_vsrc_rgbtestsrc_outputs[] = {
1056  {
1057  .name = "default",
1058  .type = AVMEDIA_TYPE_VIDEO,
1059  .config_props = rgbtest_config_props,
1060  },
1061  { NULL }
1062 };
1063 
1065  .name = "rgbtestsrc",
1066  .description = NULL_IF_CONFIG_SMALL("Generate RGB test pattern."),
1067  .priv_size = sizeof(TestSourceContext),
1068  .priv_class = &rgbtestsrc_class,
1069  .init = rgbtest_init,
1070  .uninit = uninit,
1071  .query_formats = rgbtest_query_formats,
1072  .activate = activate,
1073  .inputs = NULL,
1074  .outputs = avfilter_vsrc_rgbtestsrc_outputs,
1075 };
1076 
1077 #endif /* CONFIG_RGBTESTSRC_FILTER */
1078 
1079 #if CONFIG_YUVTESTSRC_FILTER
1080 
1081 #define yuvtestsrc_options options
1082 AVFILTER_DEFINE_CLASS(yuvtestsrc);
1083 
1084 static void yuvtest_fill_picture8(AVFilterContext *ctx, AVFrame *frame)
1085 {
1086  int x, y, w = frame->width, h = frame->height / 3;
1088  const int factor = 1 << desc->comp[0].depth;
1089  const int mid = 1 << (desc->comp[0].depth - 1);
1090  uint8_t *ydst = frame->data[0];
1091  uint8_t *udst = frame->data[1];
1092  uint8_t *vdst = frame->data[2];
1093  int ylinesize = frame->linesize[0];
1094  int ulinesize = frame->linesize[1];
1095  int vlinesize = frame->linesize[2];
1096 
1097  for (y = 0; y < h; y++) {
1098  for (x = 0; x < w; x++) {
1099  int c = factor * x / w;
1100 
1101  ydst[x] = c;
1102  udst[x] = mid;
1103  vdst[x] = mid;
1104  }
1105 
1106  ydst += ylinesize;
1107  udst += ulinesize;
1108  vdst += vlinesize;
1109  }
1110 
1111  h += h;
1112  for (; y < h; y++) {
1113  for (x = 0; x < w; x++) {
1114  int c = factor * x / w;
1115 
1116  ydst[x] = mid;
1117  udst[x] = c;
1118  vdst[x] = mid;
1119  }
1120 
1121  ydst += ylinesize;
1122  udst += ulinesize;
1123  vdst += vlinesize;
1124  }
1125 
1126  for (; y < frame->height; y++) {
1127  for (x = 0; x < w; x++) {
1128  int c = factor * x / w;
1129 
1130  ydst[x] = mid;
1131  udst[x] = mid;
1132  vdst[x] = c;
1133  }
1134 
1135  ydst += ylinesize;
1136  udst += ulinesize;
1137  vdst += vlinesize;
1138  }
1139 }
1140 
1141 static void yuvtest_fill_picture16(AVFilterContext *ctx, AVFrame *frame)
1142 {
1143  int x, y, w = frame->width, h = frame->height / 3;
1145  const int factor = 1 << desc->comp[0].depth;
1146  const int mid = 1 << (desc->comp[0].depth - 1);
1147  uint16_t *ydst = (uint16_t *)frame->data[0];
1148  uint16_t *udst = (uint16_t *)frame->data[1];
1149  uint16_t *vdst = (uint16_t *)frame->data[2];
1150  int ylinesize = frame->linesize[0] / 2;
1151  int ulinesize = frame->linesize[1] / 2;
1152  int vlinesize = frame->linesize[2] / 2;
1153 
1154  for (y = 0; y < h; y++) {
1155  for (x = 0; x < w; x++) {
1156  int c = factor * x / w;
1157 
1158  ydst[x] = c;
1159  udst[x] = mid;
1160  vdst[x] = mid;
1161  }
1162 
1163  ydst += ylinesize;
1164  udst += ulinesize;
1165  vdst += vlinesize;
1166  }
1167 
1168  h += h;
1169  for (; y < h; y++) {
1170  for (x = 0; x < w; x++) {
1171  int c = factor * x / w;
1172 
1173  ydst[x] = mid;
1174  udst[x] = c;
1175  vdst[x] = mid;
1176  }
1177 
1178  ydst += ylinesize;
1179  udst += ulinesize;
1180  vdst += vlinesize;
1181  }
1182 
1183  for (; y < frame->height; y++) {
1184  for (x = 0; x < w; x++) {
1185  int c = factor * x / w;
1186 
1187  ydst[x] = mid;
1188  udst[x] = mid;
1189  vdst[x] = c;
1190  }
1191 
1192  ydst += ylinesize;
1193  udst += ulinesize;
1194  vdst += vlinesize;
1195  }
1196 }
1197 
1198 static av_cold int yuvtest_init(AVFilterContext *ctx)
1199 {
1200  TestSourceContext *test = ctx->priv;
1201 
1202  test->draw_once = 1;
1203  return init(ctx);
1204 }
1205 
1206 static int yuvtest_query_formats(AVFilterContext *ctx)
1207 {
1208  static const enum AVPixelFormat pix_fmts[] = {
1214  };
1215 
1216  AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts);
1217  if (!fmts_list)
1218  return AVERROR(ENOMEM);
1219  return ff_set_common_formats(ctx, fmts_list);
1220 }
1221 
1222 static int yuvtest_config_props(AVFilterLink *outlink)
1223 {
1224  TestSourceContext *test = outlink->src->priv;
1226 
1227  test->fill_picture_fn = desc->comp[0].depth > 8 ? yuvtest_fill_picture16 : yuvtest_fill_picture8;
1228  return config_props(outlink);
1229 }
1230 
1231 static const AVFilterPad avfilter_vsrc_yuvtestsrc_outputs[] = {
1232  {
1233  .name = "default",
1234  .type = AVMEDIA_TYPE_VIDEO,
1235  .config_props = yuvtest_config_props,
1236  },
1237  { NULL }
1238 };
1239 
1241  .name = "yuvtestsrc",
1242  .description = NULL_IF_CONFIG_SMALL("Generate YUV test pattern."),
1243  .priv_size = sizeof(TestSourceContext),
1244  .priv_class = &yuvtestsrc_class,
1245  .init = yuvtest_init,
1246  .uninit = uninit,
1247  .query_formats = yuvtest_query_formats,
1248  .activate = activate,
1249  .inputs = NULL,
1250  .outputs = avfilter_vsrc_yuvtestsrc_outputs,
1251 };
1252 
1253 #endif /* CONFIG_YUVTESTSRC_FILTER */
1254 
1255 #if CONFIG_PAL75BARS_FILTER || CONFIG_PAL100BARS_FILTER || CONFIG_SMPTEBARS_FILTER || CONFIG_SMPTEHDBARS_FILTER
1256 
1257 static const uint8_t rainbow[7][4] = {
1258  { 180, 128, 128, 255 }, /* 75% white */
1259  { 162, 44, 142, 255 }, /* 75% yellow */
1260  { 131, 156, 44, 255 }, /* 75% cyan */
1261  { 112, 72, 58, 255 }, /* 75% green */
1262  { 84, 184, 198, 255 }, /* 75% magenta */
1263  { 65, 100, 212, 255 }, /* 75% red */
1264  { 35, 212, 114, 255 }, /* 75% blue */
1265 };
1266 
1267 static const uint8_t rainbow100[7][4] = {
1268  { 235, 128, 128, 255 }, /* 100% white */
1269  { 210, 16, 146, 255 }, /* 100% yellow */
1270  { 170, 166, 16, 255 }, /* 100% cyan */
1271  { 145, 54, 34, 255 }, /* 100% green */
1272  { 106, 202, 222, 255 }, /* 100% magenta */
1273  { 81, 90, 240, 255 }, /* 100% red */
1274  { 41, 240, 110, 255 }, /* 100% blue */
1275 };
1276 
1277 static const uint8_t rainbowhd[7][4] = {
1278  { 180, 128, 128, 255 }, /* 75% white */
1279  { 168, 44, 136, 255 }, /* 75% yellow */
1280  { 145, 147, 44, 255 }, /* 75% cyan */
1281  { 133, 63, 52, 255 }, /* 75% green */
1282  { 63, 193, 204, 255 }, /* 75% magenta */
1283  { 51, 109, 212, 255 }, /* 75% red */
1284  { 28, 212, 120, 255 }, /* 75% blue */
1285 };
1286 
1287 static const uint8_t wobnair[7][4] = {
1288  { 35, 212, 114, 255 }, /* 75% blue */
1289  { 19, 128, 128, 255 }, /* 7.5% intensity black */
1290  { 84, 184, 198, 255 }, /* 75% magenta */
1291  { 19, 128, 128, 255 }, /* 7.5% intensity black */
1292  { 131, 156, 44, 255 }, /* 75% cyan */
1293  { 19, 128, 128, 255 }, /* 7.5% intensity black */
1294  { 180, 128, 128, 255 }, /* 75% white */
1295 };
1296 
1297 static const uint8_t white[4] = { 235, 128, 128, 255 };
1298 
1299 /* pluge pulses */
1300 static const uint8_t neg4ire[4] = { 7, 128, 128, 255 };
1301 static const uint8_t pos4ire[4] = { 24, 128, 128, 255 };
1302 
1303 /* fudged Q/-I */
1304 static const uint8_t i_pixel[4] = { 57, 156, 97, 255 };
1305 static const uint8_t q_pixel[4] = { 44, 171, 147, 255 };
1306 
1307 static const uint8_t gray40[4] = { 104, 128, 128, 255 };
1308 static const uint8_t gray15[4] = { 49, 128, 128, 255 };
1309 static const uint8_t cyan[4] = { 188, 154, 16, 255 };
1310 static const uint8_t yellow[4] = { 219, 16, 138, 255 };
1311 static const uint8_t blue[4] = { 32, 240, 118, 255 };
1312 static const uint8_t red[4] = { 63, 102, 240, 255 };
1313 static const uint8_t black0[4] = { 16, 128, 128, 255 };
1314 static const uint8_t black2[4] = { 20, 128, 128, 255 };
1315 static const uint8_t black4[4] = { 25, 128, 128, 255 };
1316 static const uint8_t neg2[4] = { 12, 128, 128, 255 };
1317 
1318 static void draw_bar(TestSourceContext *test, const uint8_t color[4],
1319  int x, int y, int w, int h,
1320  AVFrame *frame)
1321 {
1323  uint8_t *p, *p0;
1324  int plane;
1325 
1326  x = FFMIN(x, test->w - 1);
1327  y = FFMIN(y, test->h - 1);
1328  w = FFMAX(FFMIN(w, test->w - x), 0);
1329  h = FFMAX(FFMIN(h, test->h - y), 0);
1330 
1331  av_assert0(x + w <= test->w);
1332  av_assert0(y + h <= test->h);
1333 
1334  for (plane = 0; frame->data[plane]; plane++) {
1335  const int c = color[plane];
1336  const int linesize = frame->linesize[plane];
1337  int i, px, py, pw, ph;
1338 
1339  if (plane == 1 || plane == 2) {
1340  px = x >> desc->log2_chroma_w;
1341  pw = AV_CEIL_RSHIFT(w, desc->log2_chroma_w);
1342  py = y >> desc->log2_chroma_h;
1343  ph = AV_CEIL_RSHIFT(h, desc->log2_chroma_h);
1344  } else {
1345  px = x;
1346  pw = w;
1347  py = y;
1348  ph = h;
1349  }
1350 
1351  p0 = p = frame->data[plane] + py * linesize + px;
1352  memset(p, c, pw);
1353  p += linesize;
1354  for (i = 1; i < ph; i++, p += linesize)
1355  memcpy(p, p0, pw);
1356  }
1357 }
1358 
1359 static int smptebars_query_formats(AVFilterContext *ctx)
1360 {
1361  static const enum AVPixelFormat pix_fmts[] = {
1366  };
1367 
1368  AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts);
1369  if (!fmts_list)
1370  return AVERROR(ENOMEM);
1371  return ff_set_common_formats(ctx, fmts_list);
1372 }
1373 
1374 static const AVFilterPad smptebars_outputs[] = {
1375  {
1376  .name = "default",
1377  .type = AVMEDIA_TYPE_VIDEO,
1378  .config_props = config_props,
1379  },
1380  { NULL }
1381 };
1382 
1383 #if CONFIG_PAL75BARS_FILTER
1384 
1385 #define pal75bars_options options
1386 AVFILTER_DEFINE_CLASS(pal75bars);
1387 
1388 static void pal75bars_fill_picture(AVFilterContext *ctx, AVFrame *picref)
1389 {
1390  TestSourceContext *test = ctx->priv;
1391  int r_w, i, x = 0;
1392  const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(picref->format);
1393 
1394  picref->color_range = AVCOL_RANGE_MPEG;
1395  picref->colorspace = AVCOL_SPC_BT470BG;
1396 
1397  r_w = FFALIGN((test->w + 7) / 8, 1 << pixdesc->log2_chroma_w);
1398 
1399  draw_bar(test, white, x, 0, r_w, test->h, picref);
1400  x += r_w;
1401  for (i = 1; i < 7; i++) {
1402  draw_bar(test, rainbow[i], x, 0, r_w, test->h, picref);
1403  x += r_w;
1404  }
1405  draw_bar(test, black0, x, 0, r_w, test->h, picref);
1406 }
1407 
1408 static av_cold int pal75bars_init(AVFilterContext *ctx)
1409 {
1410  TestSourceContext *test = ctx->priv;
1411 
1412  test->fill_picture_fn = pal75bars_fill_picture;
1413  test->draw_once = 1;
1414  return init(ctx);
1415 }
1416 
1418  .name = "pal75bars",
1419  .description = NULL_IF_CONFIG_SMALL("Generate PAL 75% color bars."),
1420  .priv_size = sizeof(TestSourceContext),
1421  .priv_class = &pal75bars_class,
1422  .init = pal75bars_init,
1423  .uninit = uninit,
1424  .query_formats = smptebars_query_formats,
1425  .activate = activate,
1426  .inputs = NULL,
1427  .outputs = smptebars_outputs,
1428 };
1429 
1430 #endif /* CONFIG_PAL75BARS_FILTER */
1431 
1432 #if CONFIG_PAL100BARS_FILTER
1433 
1434 #define pal100bars_options options
1435 AVFILTER_DEFINE_CLASS(pal100bars);
1436 
1437 static void pal100bars_fill_picture(AVFilterContext *ctx, AVFrame *picref)
1438 {
1439  TestSourceContext *test = ctx->priv;
1440  int r_w, i, x = 0;
1441  const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(picref->format);
1442 
1443  picref->color_range = AVCOL_RANGE_MPEG;
1444  picref->colorspace = AVCOL_SPC_BT470BG;
1445 
1446  r_w = FFALIGN((test->w + 7) / 8, 1 << pixdesc->log2_chroma_w);
1447 
1448  for (i = 0; i < 7; i++) {
1449  draw_bar(test, rainbow100[i], x, 0, r_w, test->h, picref);
1450  x += r_w;
1451  }
1452  draw_bar(test, black0, x, 0, r_w, test->h, picref);
1453 }
1454 
1455 static av_cold int pal100bars_init(AVFilterContext *ctx)
1456 {
1457  TestSourceContext *test = ctx->priv;
1458 
1459  test->fill_picture_fn = pal100bars_fill_picture;
1460  test->draw_once = 1;
1461  return init(ctx);
1462 }
1463 
1465  .name = "pal100bars",
1466  .description = NULL_IF_CONFIG_SMALL("Generate PAL 100% color bars."),
1467  .priv_size = sizeof(TestSourceContext),
1468  .priv_class = &pal100bars_class,
1469  .init = pal100bars_init,
1470  .uninit = uninit,
1471  .query_formats = smptebars_query_formats,
1472  .activate = activate,
1473  .inputs = NULL,
1474  .outputs = smptebars_outputs,
1475 };
1476 
1477 #endif /* CONFIG_PAL100BARS_FILTER */
1478 
1479 #if CONFIG_SMPTEBARS_FILTER
1480 
1481 #define smptebars_options options
1482 AVFILTER_DEFINE_CLASS(smptebars);
1483 
1484 static void smptebars_fill_picture(AVFilterContext *ctx, AVFrame *picref)
1485 {
1486  TestSourceContext *test = ctx->priv;
1487  int r_w, r_h, w_h, p_w, p_h, i, tmp, x = 0;
1488  const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(picref->format);
1489 
1490  picref->colorspace = AVCOL_SPC_BT470BG;
1491 
1492  r_w = FFALIGN((test->w + 6) / 7, 1 << pixdesc->log2_chroma_w);
1493  r_h = FFALIGN(test->h * 2 / 3, 1 << pixdesc->log2_chroma_h);
1494  w_h = FFALIGN(test->h * 3 / 4 - r_h, 1 << pixdesc->log2_chroma_h);
1495  p_w = FFALIGN(r_w * 5 / 4, 1 << pixdesc->log2_chroma_w);
1496  p_h = test->h - w_h - r_h;
1497 
1498  for (i = 0; i < 7; i++) {
1499  draw_bar(test, rainbow[i], x, 0, r_w, r_h, picref);
1500  draw_bar(test, wobnair[i], x, r_h, r_w, w_h, picref);
1501  x += r_w;
1502  }
1503  x = 0;
1504  draw_bar(test, i_pixel, x, r_h + w_h, p_w, p_h, picref);
1505  x += p_w;
1506  draw_bar(test, white, x, r_h + w_h, p_w, p_h, picref);
1507  x += p_w;
1508  draw_bar(test, q_pixel, x, r_h + w_h, p_w, p_h, picref);
1509  x += p_w;
1510  tmp = FFALIGN(5 * r_w - x, 1 << pixdesc->log2_chroma_w);
1511  draw_bar(test, black0, x, r_h + w_h, tmp, p_h, picref);
1512  x += tmp;
1513  tmp = FFALIGN(r_w / 3, 1 << pixdesc->log2_chroma_w);
1514  draw_bar(test, neg4ire, x, r_h + w_h, tmp, p_h, picref);
1515  x += tmp;
1516  draw_bar(test, black0, x, r_h + w_h, tmp, p_h, picref);
1517  x += tmp;
1518  draw_bar(test, pos4ire, x, r_h + w_h, tmp, p_h, picref);
1519  x += tmp;
1520  draw_bar(test, black0, x, r_h + w_h, test->w - x, p_h, picref);
1521 }
1522 
1523 static av_cold int smptebars_init(AVFilterContext *ctx)
1524 {
1525  TestSourceContext *test = ctx->priv;
1526 
1527  test->fill_picture_fn = smptebars_fill_picture;
1528  test->draw_once = 1;
1529  return init(ctx);
1530 }
1531 
1533  .name = "smptebars",
1534  .description = NULL_IF_CONFIG_SMALL("Generate SMPTE color bars."),
1535  .priv_size = sizeof(TestSourceContext),
1536  .priv_class = &smptebars_class,
1537  .init = smptebars_init,
1538  .uninit = uninit,
1539  .query_formats = smptebars_query_formats,
1540  .activate = activate,
1541  .inputs = NULL,
1542  .outputs = smptebars_outputs,
1543 };
1544 
1545 #endif /* CONFIG_SMPTEBARS_FILTER */
1546 
1547 #if CONFIG_SMPTEHDBARS_FILTER
1548 
1549 #define smptehdbars_options options
1550 AVFILTER_DEFINE_CLASS(smptehdbars);
1551 
1552 static void smptehdbars_fill_picture(AVFilterContext *ctx, AVFrame *picref)
1553 {
1554  TestSourceContext *test = ctx->priv;
1555  int d_w, r_w, r_h, l_w, i, tmp, x = 0, y = 0;
1556  const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(picref->format);
1557 
1558  picref->colorspace = AVCOL_SPC_BT709;
1559 
1560  d_w = FFALIGN(test->w / 8, 1 << pixdesc->log2_chroma_w);
1561  r_h = FFALIGN(test->h * 7 / 12, 1 << pixdesc->log2_chroma_h);
1562  draw_bar(test, gray40, x, 0, d_w, r_h, picref);
1563  x += d_w;
1564 
1565  r_w = FFALIGN((((test->w + 3) / 4) * 3) / 7, 1 << pixdesc->log2_chroma_w);
1566  for (i = 0; i < 7; i++) {
1567  draw_bar(test, rainbowhd[i], x, 0, r_w, r_h, picref);
1568  x += r_w;
1569  }
1570  draw_bar(test, gray40, x, 0, test->w - x, r_h, picref);
1571  y = r_h;
1572  r_h = FFALIGN(test->h / 12, 1 << pixdesc->log2_chroma_h);
1573  draw_bar(test, cyan, 0, y, d_w, r_h, picref);
1574  x = d_w;
1575  draw_bar(test, i_pixel, x, y, r_w, r_h, picref);
1576  x += r_w;
1577  tmp = r_w * 6;
1578  draw_bar(test, rainbowhd[0], x, y, tmp, r_h, picref);
1579  x += tmp;
1580  l_w = x;
1581  draw_bar(test, blue, x, y, test->w - x, r_h, picref);
1582  y += r_h;
1583  draw_bar(test, yellow, 0, y, d_w, r_h, picref);
1584  x = d_w;
1585  draw_bar(test, q_pixel, x, y, r_w, r_h, picref);
1586  x += r_w;
1587 
1588  for (i = 0; i < tmp; i += 1 << pixdesc->log2_chroma_w) {
1589  uint8_t yramp[4] = {0};
1590 
1591  yramp[0] = i * 255 / tmp;
1592  yramp[1] = 128;
1593  yramp[2] = 128;
1594  yramp[3] = 255;
1595 
1596  draw_bar(test, yramp, x, y, 1 << pixdesc->log2_chroma_w, r_h, picref);
1597  x += 1 << pixdesc->log2_chroma_w;
1598  }
1599  draw_bar(test, red, x, y, test->w - x, r_h, picref);
1600  y += r_h;
1601  draw_bar(test, gray15, 0, y, d_w, test->h - y, picref);
1602  x = d_w;
1603  tmp = FFALIGN(r_w * 3 / 2, 1 << pixdesc->log2_chroma_w);
1604  draw_bar(test, black0, x, y, tmp, test->h - y, picref);
1605  x += tmp;
1606  tmp = FFALIGN(r_w * 2, 1 << pixdesc->log2_chroma_w);
1607  draw_bar(test, white, x, y, tmp, test->h - y, picref);
1608  x += tmp;
1609  tmp = FFALIGN(r_w * 5 / 6, 1 << pixdesc->log2_chroma_w);
1610  draw_bar(test, black0, x, y, tmp, test->h - y, picref);
1611  x += tmp;
1612  tmp = FFALIGN(r_w / 3, 1 << pixdesc->log2_chroma_w);
1613  draw_bar(test, neg2, x, y, tmp, test->h - y, picref);
1614  x += tmp;
1615  draw_bar(test, black0, x, y, tmp, test->h - y, picref);
1616  x += tmp;
1617  draw_bar(test, black2, x, y, tmp, test->h - y, picref);
1618  x += tmp;
1619  draw_bar(test, black0, x, y, tmp, test->h - y, picref);
1620  x += tmp;
1621  draw_bar(test, black4, x, y, tmp, test->h - y, picref);
1622  x += tmp;
1623  r_w = l_w - x;
1624  draw_bar(test, black0, x, y, r_w, test->h - y, picref);
1625  x += r_w;
1626  draw_bar(test, gray15, x, y, test->w - x, test->h - y, picref);
1627 }
1628 
1629 static av_cold int smptehdbars_init(AVFilterContext *ctx)
1630 {
1631  TestSourceContext *test = ctx->priv;
1632 
1633  test->fill_picture_fn = smptehdbars_fill_picture;
1634  test->draw_once = 1;
1635  return init(ctx);
1636 }
1637 
1639  .name = "smptehdbars",
1640  .description = NULL_IF_CONFIG_SMALL("Generate SMPTE HD color bars."),
1641  .priv_size = sizeof(TestSourceContext),
1642  .priv_class = &smptehdbars_class,
1643  .init = smptehdbars_init,
1644  .uninit = uninit,
1645  .query_formats = smptebars_query_formats,
1646  .activate = activate,
1647  .inputs = NULL,
1648  .outputs = smptebars_outputs,
1649 };
1650 
1651 #endif /* CONFIG_SMPTEHDBARS_FILTER */
1652 #endif /* CONFIG_SMPTEBARS_FILTER || CONFIG_SMPTEHDBARS_FILTER */
1653 
1654 #if CONFIG_ALLYUV_FILTER
1655 
1656 static const AVOption allyuv_options[] = {
1658  { NULL }
1659 };
1660 
1661 AVFILTER_DEFINE_CLASS(allyuv);
1662 
1663 static void allyuv_fill_picture(AVFilterContext *ctx, AVFrame *frame)
1664 {
1665  const int ys = frame->linesize[0];
1666  const int us = frame->linesize[1];
1667  const int vs = frame->linesize[2];
1668  int x, y, j;
1669 
1670  for (y = 0; y < 4096; y++) {
1671  for (x = 0; x < 2048; x++) {
1672  frame->data[0][y * ys + x] = ((x / 8) % 256);
1673  frame->data[0][y * ys + 4095 - x] = ((x / 8) % 256);
1674  }
1675 
1676  for (x = 0; x < 2048; x+=8) {
1677  for (j = 0; j < 8; j++) {
1678  frame->data[1][vs * y + x + j] = (y%16 + (j % 8) * 16);
1679  frame->data[1][vs * y + 4095 - x - j] = (128 + y%16 + (j % 8) * 16);
1680  }
1681  }
1682 
1683  for (x = 0; x < 4096; x++)
1684  frame->data[2][y * us + x] = 256 * y / 4096;
1685  }
1686 }
1687 
1688 static av_cold int allyuv_init(AVFilterContext *ctx)
1689 {
1690  TestSourceContext *test = ctx->priv;
1691 
1692  test->w = test->h = 4096;
1693  test->draw_once = 1;
1694  test->fill_picture_fn = allyuv_fill_picture;
1695  return init(ctx);
1696 }
1697 
1698 static int allyuv_query_formats(AVFilterContext *ctx)
1699 {
1700  static const enum AVPixelFormat pix_fmts[] = {
1703  };
1704 
1705  AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts);
1706  if (!fmts_list)
1707  return AVERROR(ENOMEM);
1708  return ff_set_common_formats(ctx, fmts_list);
1709 }
1710 
1711 static const AVFilterPad avfilter_vsrc_allyuv_outputs[] = {
1712  {
1713  .name = "default",
1714  .type = AVMEDIA_TYPE_VIDEO,
1715  .config_props = config_props,
1716  },
1717  { NULL }
1718 };
1719 
1721  .name = "allyuv",
1722  .description = NULL_IF_CONFIG_SMALL("Generate all yuv colors."),
1723  .priv_size = sizeof(TestSourceContext),
1724  .priv_class = &allyuv_class,
1725  .init = allyuv_init,
1726  .uninit = uninit,
1727  .query_formats = allyuv_query_formats,
1728  .activate = activate,
1729  .inputs = NULL,
1730  .outputs = avfilter_vsrc_allyuv_outputs,
1731 };
1732 
1733 #endif /* CONFIG_ALLYUV_FILTER */
1734 
1735 #if CONFIG_ALLRGB_FILTER
1736 
1737 static const AVOption allrgb_options[] = {
1739  { NULL }
1740 };
1741 
1742 AVFILTER_DEFINE_CLASS(allrgb);
1743 
1744 static void allrgb_fill_picture(AVFilterContext *ctx, AVFrame *frame)
1745 {
1746  unsigned x, y;
1747  const int linesize = frame->linesize[0];
1748  uint8_t *line = frame->data[0];
1749 
1750  for (y = 0; y < 4096; y++) {
1751  uint8_t *dst = line;
1752 
1753  for (x = 0; x < 4096; x++) {
1754  *dst++ = x;
1755  *dst++ = y;
1756  *dst++ = (x >> 8) | ((y >> 8) << 4);
1757  }
1758  line += linesize;
1759  }
1760 }
1761 
1762 static av_cold int allrgb_init(AVFilterContext *ctx)
1763 {
1764  TestSourceContext *test = ctx->priv;
1765 
1766  test->w = test->h = 4096;
1767  test->draw_once = 1;
1768  test->fill_picture_fn = allrgb_fill_picture;
1769  return init(ctx);
1770 }
1771 
1772 static int allrgb_config_props(AVFilterLink *outlink)
1773 {
1774  TestSourceContext *test = outlink->src->priv;
1775 
1776  ff_fill_rgba_map(test->rgba_map, outlink->format);
1777  return config_props(outlink);
1778 }
1779 
1780 static int allrgb_query_formats(AVFilterContext *ctx)
1781 {
1782  static const enum AVPixelFormat pix_fmts[] = {
1784  };
1785 
1786  AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts);
1787  if (!fmts_list)
1788  return AVERROR(ENOMEM);
1789  return ff_set_common_formats(ctx, fmts_list);
1790 }
1791 
1792 static const AVFilterPad avfilter_vsrc_allrgb_outputs[] = {
1793  {
1794  .name = "default",
1795  .type = AVMEDIA_TYPE_VIDEO,
1796  .config_props = allrgb_config_props,
1797  },
1798  { NULL }
1799 };
1800 
1802  .name = "allrgb",
1803  .description = NULL_IF_CONFIG_SMALL("Generate all RGB colors."),
1804  .priv_size = sizeof(TestSourceContext),
1805  .priv_class = &allrgb_class,
1806  .init = allrgb_init,
1807  .uninit = uninit,
1808  .query_formats = allrgb_query_formats,
1809  .activate = activate,
1810  .inputs = NULL,
1811  .outputs = avfilter_vsrc_allrgb_outputs,
1812 };
1813 
1814 #endif /* CONFIG_ALLRGB_FILTER */
also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B
Definition: pixfmt.h:514
AVFilterFormats * ff_draw_supported_pixel_formats(unsigned flags)
Return the list of pixel formats supported by the draw functions.
Definition: drawutils.c:731
#define NULL
Definition: coverity.c:32
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2573
This structure describes decoded (raw) audio or video data.
Definition: frame.h:308
AVFilter ff_vsrc_smptehdbars
AVOption.
Definition: opt.h:248
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:100
AVFilter ff_vsrc_allyuv
#define AV_PIX_FMT_YUV444P14
Definition: pixfmt.h:409
const char * desc
Definition: libsvtav1.c:79
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:71
misc image utilities
Main libavfilter public API header.
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:68
const char * g
Definition: vf_curves.c:115
#define AV_PIX_FMT_RGBA64
Definition: pixfmt.h:389
also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601 ...
Definition: pixfmt.h:518
static void draw_rectangle(AVFormatContext *s)
Definition: xcbgrab.c:621
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:168
int num
Numerator.
Definition: rational.h:59
AVFilter ff_vsrc_pal100bars
#define us(width, name, range_min, range_max, subs,...)
Definition: cbs_h2645.c:276
static av_cold void uninit(AVFilterContext *ctx)
Definition: vsrc_testsrc.c:122
#define AV_PIX_FMT_BGRA64
Definition: pixfmt.h:394
#define COMMON_OPTIONS_NOSIZE
Definition: vsrc_testsrc.c:93
const uint8_t avpriv_vga16_font[4096]
packed BGR 8:8:8, 32bpp, XBGRXBGR... X=unused/undefined
Definition: pixfmt.h:239
return FFERROR_NOT_READY
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:99
int draw_once
draw only the first frame, always put out the same picture
Definition: vsrc_testsrc.c:61
#define AV_PIX_FMT_RGB444
Definition: pixfmt.h:388
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:92
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
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:287
static av_cold int init(AVFilterContext *ctx)
Definition: vsrc_testsrc.c:107
AVFilter ff_vsrc_testsrc
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:719
const char * name
Pad name.
Definition: internal.h:60
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
int draw_once_reset
draw only the first frame or in case of reset
Definition: vsrc_testsrc.c:62
AVFilter ff_vsrc_nullsrc
#define AV_WL24(p, d)
Definition: intreadwrite.h:464
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1091
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:117
uint8_t
#define av_cold
Definition: attributes.h:88
packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined
Definition: pixfmt.h:238
AVOptions.
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
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:401
packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
Definition: pixfmt.h:94
#define height
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
#define AVERROR_EOF
End of file.
Definition: error.h:55
#define AV_PIX_FMT_BGR48
Definition: pixfmt.h:390
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:210
#define AV_PIX_FMT_YUV444P16
Definition: pixfmt.h:412
int interlaced_frame
The content of the picture is interlaced.
Definition: frame.h:455
ptrdiff_t size
Definition: opengl_enc.c:100
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
#define A(x)
Definition: vp56_arith.h:28
#define FFALIGN(x, a)
Definition: macros.h:48
#define av_log(a,...)
A filter pad used for either input or output.
Definition: internal.h:54
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
#define U(x)
Definition: vp56_arith.h:37
static av_always_inline double ff_exp10(double x)
Compute 10^x for floating point values.
Definition: ffmath.h:42
int width
Definition: frame.h:366
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:588
#define R
Definition: huffyuvdsp.h:34
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:101
AVFilter ff_vsrc_pal75bars
static const uint16_t mask[17]
Definition: lzw.c:38
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:203
#define B
Definition: huffyuvdsp.h:32
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:153
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
Definition: pixfmt.h:95
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:885
const char * r
Definition: vf_curves.c:114
void * priv
private data for use by the filter
Definition: avfilter.h:356
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:2538
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: frame.h:552
unsigned int pos
Definition: spdifenc.c:410
void ff_draw_color(FFDrawContext *draw, FFDrawColor *color, const uint8_t rgba[4])
Prepare a color.
Definition: drawutils.c:231
enum AVColorSpace colorspace
YUV colorspace type.
Definition: frame.h:563
Definition: graph2dot.c:48
#define AV_PIX_FMT_RGB48
Definition: pixfmt.h:385
simple assert() macros that are a bit more flexible than ISO C assert().
#define AV_PIX_FMT_YUV444P10
Definition: pixfmt.h:402
#define COMMON_OPTIONS
Definition: vsrc_testsrc.c:100
#define FFMAX(a, b)
Definition: common.h:94
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition: pixfmt.h:92
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:93
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:70
AVRational sar
sample aspect ratio
Definition: vsrc_testsrc.c:60
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:317
#define b
Definition: input.c:41
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:391
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:129
#define FFMIN(a, b)
Definition: common.h:96
Round toward zero.
Definition: mathematics.h:80
#define width
int64_t duration
duration expressed in microseconds
Definition: vsrc_testsrc.c:59
typedef void(APIENTRY *FF_PFNGLACTIVETEXTUREPROC)(GLenum texture)
#define FLAGSR
Definition: vsrc_testsrc.c:87
static int config_props(AVFilterLink *outlink)
Definition: vsrc_testsrc.c:129
AVFormatContext * ctx
Definition: movenc.c:48
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
#define s(width, name)
Definition: cbs_vp9.c:257
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:69
#define FLAGS
Definition: vsrc_testsrc.c:86
AVFilter ff_vsrc_testsrc2
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:58
#define AV_PIX_FMT_YUV444P9
Definition: pixfmt.h:398
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
Definition: frame.c:553
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
#define FF_ARRAY_ELEMS(a)
int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt)
Definition: drawutils.c:35
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:622
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
Definition: frame.h:381
#define AV_PIX_FMT_BGR555
Definition: pixfmt.h:392
void(* fill_picture_fn)(AVFilterContext *ctx, AVFrame *frame)
Definition: vsrc_testsrc.c:65
uint8_t color_rgba[4]
Definition: vsrc_testsrc.c:76
misc drawing utilities
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:260
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:339
static void draw_text(FFDrawContext *draw, AVFrame *frame, FFDrawColor *color, int x0, int y0, const uint8_t *text, int vertical)
Definition: vf_datascope.c:84
static void test(const char *pattern, const char *host)
Definition: noproxy.c:23
static AVRational av_make_q(int num, int den)
Create an AVRational.
Definition: rational.h:71
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
uint8_t rgba_map[4]
Definition: vsrc_testsrc.c:79
AVFilter ff_vsrc_haldclutsrc
AVRational sample_aspect_ratio
Sample aspect ratio for the video frame, 0/1 if unknown/unspecified.
Definition: frame.h:396
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
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
Definition: pixfmt.h:72
AVRational frame_rate
Definition: vsrc_testsrc.c:57
Describe the class of an AVClass context structure.
Definition: log.h:67
Filter definition.
Definition: avfilter.h:145
int index
Definition: gxfenc.c:89
Rational number (pair of numerator and denominator).
Definition: rational.h:58
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:445
packed BGR 8:8:8, 32bpp, BGRXBGRX... X=unused/undefined
Definition: pixfmt.h:240
static const int factor[16]
Definition: vf_pp7.c:75
const char * name
Filter name.
Definition: avfilter.h:149
int ff_draw_init(FFDrawContext *draw, enum AVPixelFormat format, unsigned flags)
Init a draw context.
Definition: drawutils.c:178
#define snprintf
Definition: snprintf.h:34
AVFilter ff_vsrc_smptebars
misc parsing utilities
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:353
FFDrawColor color
Definition: vsrc_testsrc.c:75
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:300
#define AV_PIX_FMT_BGR565
Definition: pixfmt.h:391
#define flags(name, subs,...)
Definition: cbs_av1.c:560
AVFilter ff_vsrc_yuvtestsrc
#define AV_PIX_FMT_YUV444P12
Definition: pixfmt.h:406
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:322
static int activate(AVFilterContext *ctx)
Definition: vsrc_testsrc.c:142
AVRational time_base
Definition: vsrc_testsrc.c:57
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
Narrow or limited range content.
Definition: pixfmt.h:569
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
Definition: rational.h:159
internal math functions header
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
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:33
static int query_formats(AVFilterContext *ctx)
Definition: aeval.c:244
common internal and external API header
unsigned int nb_frame
Definition: vsrc_testsrc.c:56
#define G
Definition: huffyuvdsp.h:33
#define AV_PIX_FMT_BGR444
Definition: pixfmt.h:393
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
Definition: pixfmt.h:80
static const AVOption options[]
Definition: vsrc_testsrc.c:102
#define AV_PIX_FMT_RGB555
Definition: pixfmt.h:387
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
Definition: pixfmt.h:73
int den
Denominator.
Definition: rational.h:60
AVFilter ff_vsrc_allrgb
#define AVFILTER_DEFINE_CLASS(fname)
Definition: internal.h:288
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:386
A list of supported formats for one end of a filter link.
Definition: formats.h:65
AVFilter ff_vsrc_color
#define OFFSET(x)
Definition: vsrc_testsrc.c:85
#define AV_PIX_FMT_RGB565
Definition: pixfmt.h:386
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:318
An instance of a filter.
Definition: avfilter.h:341
int height
Definition: frame.h:366
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
Definition: af_afftdn.c:1374
planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
Definition: pixfmt.h:99
FFDrawContext draw
Definition: vsrc_testsrc.c:74
internal API functions
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
int depth
Number of bits in the component.
Definition: pixdesc.h:58
packed RGB 8:8:8, 32bpp, XRGBXRGB... X=unused/undefined
Definition: pixfmt.h:237
AVFrame * picref
cached reference containing the painted picture
Definition: vsrc_testsrc.c:63
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
static double val(void *priv, double ch)
Definition: aeval.c:76
AVFilter ff_vsrc_rgbtestsrc
for(j=16;j >0;--j)
int i
Definition: input.c:407
CGA/EGA/VGA ROM font data.
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
#define AV_WL32(p, v)
Definition: intreadwrite.h:426
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:58
static uint8_t tmp[11]
Definition: aes_ctr.c:26