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 "formats.h"
49 #include "internal.h"
50 #include "video.h"
51 
52 typedef struct TestSourceContext {
53  const AVClass *class;
54  int w, h;
55  unsigned int nb_frame;
57  int64_t pts;
58  int64_t duration; ///< duration expressed in microseconds
59  AVRational sar; ///< sample aspect ratio
60  int draw_once; ///< draw only the first frame, always put out the same picture
61  int draw_once_reset; ///< draw only the first frame or in case of reset
62  AVFrame *picref; ///< cached reference containing the painted picture
63 
65 
66  /* only used by testsrc */
68 
69  /* only used by testsrc2 */
70  int alpha;
71 
72  /* only used by color */
76 
77  /* only used by rgbtest */
79 
80  /* only used by haldclut */
81  int level;
83 
84 #define OFFSET(x) offsetof(TestSourceContext, x)
85 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
86 
87 #define SIZE_OPTIONS \
88  { "size", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "320x240"}, 0, 0, FLAGS },\
89  { "s", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "320x240"}, 0, 0, FLAGS },\
90 
91 #define COMMON_OPTIONS_NOSIZE \
92  { "rate", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, INT_MAX, FLAGS },\
93  { "r", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, INT_MAX, FLAGS },\
94  { "duration", "set video duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = -1}, -1, INT64_MAX, FLAGS },\
95  { "d", "set video duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = -1}, -1, INT64_MAX, FLAGS },\
96  { "sar", "set video sample aspect ratio", OFFSET(sar), AV_OPT_TYPE_RATIONAL, {.dbl= 1}, 0, INT_MAX, FLAGS },
97 
98 #define COMMON_OPTIONS SIZE_OPTIONS COMMON_OPTIONS_NOSIZE
99 
100 static const AVOption options[] = {
102  { NULL }
103 };
104 
106 {
107  TestSourceContext *test = ctx->priv;
108 
109  test->time_base = av_inv_q(test->frame_rate);
110  test->nb_frame = 0;
111  test->pts = 0;
112 
113  av_log(ctx, AV_LOG_VERBOSE, "size:%dx%d rate:%d/%d duration:%f sar:%d/%d\n",
114  test->w, test->h, test->frame_rate.num, test->frame_rate.den,
115  test->duration < 0 ? -1 : (double)test->duration/1000000,
116  test->sar.num, test->sar.den);
117  return 0;
118 }
119 
121 {
122  TestSourceContext *test = ctx->priv;
123 
124  av_frame_free(&test->picref);
125 }
126 
127 static int config_props(AVFilterLink *outlink)
128 {
129  TestSourceContext *test = outlink->src->priv;
130 
131  outlink->w = test->w;
132  outlink->h = test->h;
133  outlink->sample_aspect_ratio = test->sar;
134  outlink->frame_rate = test->frame_rate;
135  outlink->time_base = test->time_base;
136 
137  return 0;
138 }
139 
140 static int request_frame(AVFilterLink *outlink)
141 {
142  TestSourceContext *test = outlink->src->priv;
143  AVFrame *frame;
144 
145  if (test->duration >= 0 &&
146  av_rescale_q(test->pts, test->time_base, AV_TIME_BASE_Q) >= test->duration)
147  return AVERROR_EOF;
148 
149  if (test->draw_once) {
150  if (test->draw_once_reset) {
151  av_frame_free(&test->picref);
152  test->draw_once_reset = 0;
153  }
154  if (!test->picref) {
155  test->picref =
156  ff_get_video_buffer(outlink, test->w, test->h);
157  if (!test->picref)
158  return AVERROR(ENOMEM);
159  test->fill_picture_fn(outlink->src, test->picref);
160  }
161  frame = av_frame_clone(test->picref);
162  } else
163  frame = ff_get_video_buffer(outlink, test->w, test->h);
164 
165  if (!frame)
166  return AVERROR(ENOMEM);
167  frame->pts = test->pts;
168  frame->key_frame = 1;
169  frame->interlaced_frame = 0;
170  frame->pict_type = AV_PICTURE_TYPE_I;
171  frame->sample_aspect_ratio = test->sar;
172  if (!test->draw_once)
173  test->fill_picture_fn(outlink->src, frame);
174 
175  test->pts++;
176  test->nb_frame++;
177 
178  return ff_filter_frame(outlink, frame);
179 }
180 
181 #if CONFIG_COLOR_FILTER
182 
183 static const AVOption color_options[] = {
184  { "color", "set color", OFFSET(color_rgba), AV_OPT_TYPE_COLOR, {.str = "black"}, CHAR_MIN, CHAR_MAX, FLAGS },
185  { "c", "set color", OFFSET(color_rgba), AV_OPT_TYPE_COLOR, {.str = "black"}, CHAR_MIN, CHAR_MAX, FLAGS },
187  { NULL }
188 };
189 
191 
192 static void color_fill_picture(AVFilterContext *ctx, AVFrame *picref)
193 {
194  TestSourceContext *test = ctx->priv;
195  ff_fill_rectangle(&test->draw, &test->color,
196  picref->data, picref->linesize,
197  0, 0, test->w, test->h);
198 }
199 
200 static av_cold int color_init(AVFilterContext *ctx)
201 {
202  TestSourceContext *test = ctx->priv;
203  test->fill_picture_fn = color_fill_picture;
204  test->draw_once = 1;
205  return init(ctx);
206 }
207 
208 static int color_query_formats(AVFilterContext *ctx)
209 {
211 }
212 
213 static int color_config_props(AVFilterLink *inlink)
214 {
215  AVFilterContext *ctx = inlink->src;
216  TestSourceContext *test = ctx->priv;
217  int ret;
218 
219  ff_draw_init(&test->draw, inlink->format, 0);
220  ff_draw_color(&test->draw, &test->color, test->color_rgba);
221 
222  test->w = ff_draw_round_to_sub(&test->draw, 0, -1, test->w);
223  test->h = ff_draw_round_to_sub(&test->draw, 1, -1, test->h);
224  if (av_image_check_size(test->w, test->h, 0, ctx) < 0)
225  return AVERROR(EINVAL);
226 
227  if ((ret = config_props(inlink)) < 0)
228  return ret;
229 
230  return 0;
231 }
232 
233 static int color_process_command(AVFilterContext *ctx, const char *cmd, const char *args,
234  char *res, int res_len, int flags)
235 {
236  TestSourceContext *test = ctx->priv;
237  int ret;
238 
239  if (!strcmp(cmd, "color") || !strcmp(cmd, "c")) {
240  uint8_t color_rgba[4];
241 
242  ret = av_parse_color(color_rgba, args, -1, ctx);
243  if (ret < 0)
244  return ret;
245 
246  memcpy(test->color_rgba, color_rgba, sizeof(color_rgba));
247  ff_draw_color(&test->draw, &test->color, test->color_rgba);
248  test->draw_once_reset = 1;
249  return 0;
250  }
251 
252  return AVERROR(ENOSYS);
253 }
254 
255 static const AVFilterPad color_outputs[] = {
256  {
257  .name = "default",
258  .type = AVMEDIA_TYPE_VIDEO,
259  .request_frame = request_frame,
260  .config_props = color_config_props,
261  },
262  { NULL }
263 };
264 
266  .name = "color",
267  .description = NULL_IF_CONFIG_SMALL("Provide an uniformly colored input."),
268  .priv_class = &color_class,
269  .priv_size = sizeof(TestSourceContext),
270  .init = color_init,
271  .uninit = uninit,
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, 8, 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  .request_frame = request_frame,
394  .config_props = haldclutsrc_config_props,
395  },
396  { NULL }
397 };
398 
400  .name = "haldclutsrc",
401  .description = NULL_IF_CONFIG_SMALL("Provide an identity Hald CLUT."),
402  .priv_class = &haldclutsrc_class,
403  .priv_size = sizeof(TestSourceContext),
404  .init = haldclutsrc_init,
405  .uninit = uninit,
406  .query_formats = haldclutsrc_query_formats,
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  .request_frame = request_frame,
432  .config_props = config_props,
433  },
434  { NULL },
435 };
436 
438  .name = "nullsrc",
439  .description = NULL_IF_CONFIG_SMALL("Null video source, return unprocessed video frames."),
440  .init = nullsrc_init,
441  .uninit = uninit,
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  .request_frame = request_frame,
668  .config_props = config_props,
669  },
670  { NULL }
671 };
672 
674  .name = "testsrc",
675  .description = NULL_IF_CONFIG_SMALL("Generate test pattern."),
676  .priv_size = sizeof(TestSourceContext),
677  .priv_class = &testsrc_class,
678  .init = test_init,
679  .uninit = uninit,
680  .query_formats = test_query_formats,
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  .request_frame = request_frame,
941  .config_props = test2_config_props,
942  },
943  { NULL }
944 };
945 
947  .name = "testsrc2",
948  .description = NULL_IF_CONFIG_SMALL("Generate another test pattern."),
949  .priv_size = sizeof(TestSourceContext),
950  .priv_class = &testsrc2_class,
951  .init = test2_init,
952  .uninit = uninit,
953  .query_formats = test2_query_formats,
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, int r, int g, int b, enum AVPixelFormat fmt,
972  uint8_t rgba_map[4])
973 {
974  int32_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)) + (255 << (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  .request_frame = request_frame,
1060  .config_props = rgbtest_config_props,
1061  },
1062  { NULL }
1063 };
1064 
1066  .name = "rgbtestsrc",
1067  .description = NULL_IF_CONFIG_SMALL("Generate RGB test pattern."),
1068  .priv_size = sizeof(TestSourceContext),
1069  .priv_class = &rgbtestsrc_class,
1070  .init = rgbtest_init,
1071  .uninit = uninit,
1072  .query_formats = rgbtest_query_formats,
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  .request_frame = request_frame,
1236  .config_props = yuvtest_config_props,
1237  },
1238  { NULL }
1239 };
1240 
1242  .name = "yuvtestsrc",
1243  .description = NULL_IF_CONFIG_SMALL("Generate YUV test pattern."),
1244  .priv_size = sizeof(TestSourceContext),
1245  .priv_class = &yuvtestsrc_class,
1246  .init = yuvtest_init,
1247  .uninit = uninit,
1248  .query_formats = yuvtest_query_formats,
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  .request_frame = request_frame,
1379  .config_props = config_props,
1380  },
1381  { NULL }
1382 };
1383 
1384 #if CONFIG_PAL75BARS_FILTER
1385 
1386 #define pal75bars_options options
1387 AVFILTER_DEFINE_CLASS(pal75bars);
1388 
1389 static void pal75bars_fill_picture(AVFilterContext *ctx, AVFrame *picref)
1390 {
1391  TestSourceContext *test = ctx->priv;
1392  int r_w, i, x = 0;
1393  const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(picref->format);
1394 
1395  picref->color_range = AVCOL_RANGE_MPEG;
1396  picref->colorspace = AVCOL_SPC_BT470BG;
1397 
1398  r_w = FFALIGN((test->w + 7) / 8, 1 << pixdesc->log2_chroma_w);
1399 
1400  draw_bar(test, white, x, 0, r_w, test->h, picref);
1401  x += r_w;
1402  for (i = 1; i < 7; i++) {
1403  draw_bar(test, rainbow[i], x, 0, r_w, test->h, picref);
1404  x += r_w;
1405  }
1406  draw_bar(test, black0, x, 0, r_w, test->h, picref);
1407 }
1408 
1409 static av_cold int pal75bars_init(AVFilterContext *ctx)
1410 {
1411  TestSourceContext *test = ctx->priv;
1412 
1413  test->fill_picture_fn = pal75bars_fill_picture;
1414  test->draw_once = 1;
1415  return init(ctx);
1416 }
1417 
1419  .name = "pal75bars",
1420  .description = NULL_IF_CONFIG_SMALL("Generate PAL 75% color bars."),
1421  .priv_size = sizeof(TestSourceContext),
1422  .priv_class = &pal75bars_class,
1423  .init = pal75bars_init,
1424  .uninit = uninit,
1425  .query_formats = smptebars_query_formats,
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  .inputs = NULL,
1473  .outputs = smptebars_outputs,
1474 };
1475 
1476 #endif /* CONFIG_PAL100BARS_FILTER */
1477 
1478 #if CONFIG_SMPTEBARS_FILTER
1479 
1480 #define smptebars_options options
1481 AVFILTER_DEFINE_CLASS(smptebars);
1482 
1483 static void smptebars_fill_picture(AVFilterContext *ctx, AVFrame *picref)
1484 {
1485  TestSourceContext *test = ctx->priv;
1486  int r_w, r_h, w_h, p_w, p_h, i, tmp, x = 0;
1487  const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(picref->format);
1488 
1489  picref->colorspace = AVCOL_SPC_BT470BG;
1490 
1491  r_w = FFALIGN((test->w + 6) / 7, 1 << pixdesc->log2_chroma_w);
1492  r_h = FFALIGN(test->h * 2 / 3, 1 << pixdesc->log2_chroma_h);
1493  w_h = FFALIGN(test->h * 3 / 4 - r_h, 1 << pixdesc->log2_chroma_h);
1494  p_w = FFALIGN(r_w * 5 / 4, 1 << pixdesc->log2_chroma_w);
1495  p_h = test->h - w_h - r_h;
1496 
1497  for (i = 0; i < 7; i++) {
1498  draw_bar(test, rainbow[i], x, 0, r_w, r_h, picref);
1499  draw_bar(test, wobnair[i], x, r_h, r_w, w_h, picref);
1500  x += r_w;
1501  }
1502  x = 0;
1503  draw_bar(test, i_pixel, x, r_h + w_h, p_w, p_h, picref);
1504  x += p_w;
1505  draw_bar(test, white, x, r_h + w_h, p_w, p_h, picref);
1506  x += p_w;
1507  draw_bar(test, q_pixel, x, r_h + w_h, p_w, p_h, picref);
1508  x += p_w;
1509  tmp = FFALIGN(5 * r_w - x, 1 << pixdesc->log2_chroma_w);
1510  draw_bar(test, black0, x, r_h + w_h, tmp, p_h, picref);
1511  x += tmp;
1512  tmp = FFALIGN(r_w / 3, 1 << pixdesc->log2_chroma_w);
1513  draw_bar(test, neg4ire, x, r_h + w_h, tmp, p_h, picref);
1514  x += tmp;
1515  draw_bar(test, black0, x, r_h + w_h, tmp, p_h, picref);
1516  x += tmp;
1517  draw_bar(test, pos4ire, x, r_h + w_h, tmp, p_h, picref);
1518  x += tmp;
1519  draw_bar(test, black0, x, r_h + w_h, test->w - x, p_h, picref);
1520 }
1521 
1522 static av_cold int smptebars_init(AVFilterContext *ctx)
1523 {
1524  TestSourceContext *test = ctx->priv;
1525 
1526  test->fill_picture_fn = smptebars_fill_picture;
1527  test->draw_once = 1;
1528  return init(ctx);
1529 }
1530 
1532  .name = "smptebars",
1533  .description = NULL_IF_CONFIG_SMALL("Generate SMPTE color bars."),
1534  .priv_size = sizeof(TestSourceContext),
1535  .priv_class = &smptebars_class,
1536  .init = smptebars_init,
1537  .uninit = uninit,
1538  .query_formats = smptebars_query_formats,
1539  .inputs = NULL,
1540  .outputs = smptebars_outputs,
1541 };
1542 
1543 #endif /* CONFIG_SMPTEBARS_FILTER */
1544 
1545 #if CONFIG_SMPTEHDBARS_FILTER
1546 
1547 #define smptehdbars_options options
1548 AVFILTER_DEFINE_CLASS(smptehdbars);
1549 
1550 static void smptehdbars_fill_picture(AVFilterContext *ctx, AVFrame *picref)
1551 {
1552  TestSourceContext *test = ctx->priv;
1553  int d_w, r_w, r_h, l_w, i, tmp, x = 0, y = 0;
1554  const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(picref->format);
1555 
1556  picref->colorspace = AVCOL_SPC_BT709;
1557 
1558  d_w = FFALIGN(test->w / 8, 1 << pixdesc->log2_chroma_w);
1559  r_h = FFALIGN(test->h * 7 / 12, 1 << pixdesc->log2_chroma_h);
1560  draw_bar(test, gray40, x, 0, d_w, r_h, picref);
1561  x += d_w;
1562 
1563  r_w = FFALIGN((((test->w + 3) / 4) * 3) / 7, 1 << pixdesc->log2_chroma_w);
1564  for (i = 0; i < 7; i++) {
1565  draw_bar(test, rainbowhd[i], x, 0, r_w, r_h, picref);
1566  x += r_w;
1567  }
1568  draw_bar(test, gray40, x, 0, test->w - x, r_h, picref);
1569  y = r_h;
1570  r_h = FFALIGN(test->h / 12, 1 << pixdesc->log2_chroma_h);
1571  draw_bar(test, cyan, 0, y, d_w, r_h, picref);
1572  x = d_w;
1573  draw_bar(test, i_pixel, x, y, r_w, r_h, picref);
1574  x += r_w;
1575  tmp = r_w * 6;
1576  draw_bar(test, rainbowhd[0], x, y, tmp, r_h, picref);
1577  x += tmp;
1578  l_w = x;
1579  draw_bar(test, blue, x, y, test->w - x, r_h, picref);
1580  y += r_h;
1581  draw_bar(test, yellow, 0, y, d_w, r_h, picref);
1582  x = d_w;
1583  draw_bar(test, q_pixel, x, y, r_w, r_h, picref);
1584  x += r_w;
1585 
1586  for (i = 0; i < tmp; i += 1 << pixdesc->log2_chroma_w) {
1587  uint8_t yramp[4] = {0};
1588 
1589  yramp[0] = i * 255 / tmp;
1590  yramp[1] = 128;
1591  yramp[2] = 128;
1592  yramp[3] = 255;
1593 
1594  draw_bar(test, yramp, x, y, 1 << pixdesc->log2_chroma_w, r_h, picref);
1595  x += 1 << pixdesc->log2_chroma_w;
1596  }
1597  draw_bar(test, red, x, y, test->w - x, r_h, picref);
1598  y += r_h;
1599  draw_bar(test, gray15, 0, y, d_w, test->h - y, picref);
1600  x = d_w;
1601  tmp = FFALIGN(r_w * 3 / 2, 1 << pixdesc->log2_chroma_w);
1602  draw_bar(test, black0, x, y, tmp, test->h - y, picref);
1603  x += tmp;
1604  tmp = FFALIGN(r_w * 2, 1 << pixdesc->log2_chroma_w);
1605  draw_bar(test, white, x, y, tmp, test->h - y, picref);
1606  x += tmp;
1607  tmp = FFALIGN(r_w * 5 / 6, 1 << pixdesc->log2_chroma_w);
1608  draw_bar(test, black0, x, y, tmp, test->h - y, picref);
1609  x += tmp;
1610  tmp = FFALIGN(r_w / 3, 1 << pixdesc->log2_chroma_w);
1611  draw_bar(test, neg2, x, y, tmp, test->h - y, picref);
1612  x += tmp;
1613  draw_bar(test, black0, x, y, tmp, test->h - y, picref);
1614  x += tmp;
1615  draw_bar(test, black2, x, y, tmp, test->h - y, picref);
1616  x += tmp;
1617  draw_bar(test, black0, x, y, tmp, test->h - y, picref);
1618  x += tmp;
1619  draw_bar(test, black4, x, y, tmp, test->h - y, picref);
1620  x += tmp;
1621  r_w = l_w - x;
1622  draw_bar(test, black0, x, y, r_w, test->h - y, picref);
1623  x += r_w;
1624  draw_bar(test, gray15, x, y, test->w - x, test->h - y, picref);
1625 }
1626 
1627 static av_cold int smptehdbars_init(AVFilterContext *ctx)
1628 {
1629  TestSourceContext *test = ctx->priv;
1630 
1631  test->fill_picture_fn = smptehdbars_fill_picture;
1632  test->draw_once = 1;
1633  return init(ctx);
1634 }
1635 
1637  .name = "smptehdbars",
1638  .description = NULL_IF_CONFIG_SMALL("Generate SMPTE HD color bars."),
1639  .priv_size = sizeof(TestSourceContext),
1640  .priv_class = &smptehdbars_class,
1641  .init = smptehdbars_init,
1642  .uninit = uninit,
1643  .query_formats = smptebars_query_formats,
1644  .inputs = NULL,
1645  .outputs = smptebars_outputs,
1646 };
1647 
1648 #endif /* CONFIG_SMPTEHDBARS_FILTER */
1649 #endif /* CONFIG_SMPTEBARS_FILTER || CONFIG_SMPTEHDBARS_FILTER */
1650 
1651 #if CONFIG_ALLYUV_FILTER
1652 
1653 static const AVOption allyuv_options[] = {
1655  { NULL }
1656 };
1657 
1658 AVFILTER_DEFINE_CLASS(allyuv);
1659 
1660 static void allyuv_fill_picture(AVFilterContext *ctx, AVFrame *frame)
1661 {
1662  const int ys = frame->linesize[0];
1663  const int us = frame->linesize[1];
1664  const int vs = frame->linesize[2];
1665  int x, y, j;
1666 
1667  for (y = 0; y < 4096; y++) {
1668  for (x = 0; x < 2048; x++) {
1669  frame->data[0][y * ys + x] = ((x / 8) % 256);
1670  frame->data[0][y * ys + 4095 - x] = ((x / 8) % 256);
1671  }
1672 
1673  for (x = 0; x < 2048; x+=8) {
1674  for (j = 0; j < 8; j++) {
1675  frame->data[1][vs * y + x + j] = (y%16 + (j % 8) * 16);
1676  frame->data[1][vs * y + 4095 - x - j] = (128 + y%16 + (j % 8) * 16);
1677  }
1678  }
1679 
1680  for (x = 0; x < 4096; x++)
1681  frame->data[2][y * us + x] = 256 * y / 4096;
1682  }
1683 }
1684 
1685 static av_cold int allyuv_init(AVFilterContext *ctx)
1686 {
1687  TestSourceContext *test = ctx->priv;
1688 
1689  test->w = test->h = 4096;
1690  test->draw_once = 1;
1691  test->fill_picture_fn = allyuv_fill_picture;
1692  return init(ctx);
1693 }
1694 
1695 static int allyuv_query_formats(AVFilterContext *ctx)
1696 {
1697  static const enum AVPixelFormat pix_fmts[] = {
1700  };
1701 
1702  AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts);
1703  if (!fmts_list)
1704  return AVERROR(ENOMEM);
1705  return ff_set_common_formats(ctx, fmts_list);
1706 }
1707 
1708 static const AVFilterPad avfilter_vsrc_allyuv_outputs[] = {
1709  {
1710  .name = "default",
1711  .type = AVMEDIA_TYPE_VIDEO,
1712  .request_frame = request_frame,
1713  .config_props = config_props,
1714  },
1715  { NULL }
1716 };
1717 
1719  .name = "allyuv",
1720  .description = NULL_IF_CONFIG_SMALL("Generate all yuv colors."),
1721  .priv_size = sizeof(TestSourceContext),
1722  .priv_class = &allyuv_class,
1723  .init = allyuv_init,
1724  .uninit = uninit,
1725  .query_formats = allyuv_query_formats,
1726  .inputs = NULL,
1727  .outputs = avfilter_vsrc_allyuv_outputs,
1728 };
1729 
1730 #endif /* CONFIG_ALLYUV_FILTER */
1731 
1732 #if CONFIG_ALLRGB_FILTER
1733 
1734 static const AVOption allrgb_options[] = {
1736  { NULL }
1737 };
1738 
1739 AVFILTER_DEFINE_CLASS(allrgb);
1740 
1741 static void allrgb_fill_picture(AVFilterContext *ctx, AVFrame *frame)
1742 {
1743  unsigned x, y;
1744  const int linesize = frame->linesize[0];
1745  uint8_t *line = frame->data[0];
1746 
1747  for (y = 0; y < 4096; y++) {
1748  uint8_t *dst = line;
1749 
1750  for (x = 0; x < 4096; x++) {
1751  *dst++ = x;
1752  *dst++ = y;
1753  *dst++ = (x >> 8) | ((y >> 8) << 4);
1754  }
1755  line += linesize;
1756  }
1757 }
1758 
1759 static av_cold int allrgb_init(AVFilterContext *ctx)
1760 {
1761  TestSourceContext *test = ctx->priv;
1762 
1763  test->w = test->h = 4096;
1764  test->draw_once = 1;
1765  test->fill_picture_fn = allrgb_fill_picture;
1766  return init(ctx);
1767 }
1768 
1769 static int allrgb_config_props(AVFilterLink *outlink)
1770 {
1771  TestSourceContext *test = outlink->src->priv;
1772 
1773  ff_fill_rgba_map(test->rgba_map, outlink->format);
1774  return config_props(outlink);
1775 }
1776 
1777 static int allrgb_query_formats(AVFilterContext *ctx)
1778 {
1779  static const enum AVPixelFormat pix_fmts[] = {
1781  };
1782 
1783  AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts);
1784  if (!fmts_list)
1785  return AVERROR(ENOMEM);
1786  return ff_set_common_formats(ctx, fmts_list);
1787 }
1788 
1789 static const AVFilterPad avfilter_vsrc_allrgb_outputs[] = {
1790  {
1791  .name = "default",
1792  .type = AVMEDIA_TYPE_VIDEO,
1793  .request_frame = request_frame,
1794  .config_props = allrgb_config_props,
1795  },
1796  { NULL }
1797 };
1798 
1800  .name = "allrgb",
1801  .description = NULL_IF_CONFIG_SMALL("Generate all RGB colors."),
1802  .priv_size = sizeof(TestSourceContext),
1803  .priv_class = &allrgb_class,
1804  .init = allrgb_init,
1805  .uninit = uninit,
1806  .query_formats = allrgb_query_formats,
1807  .inputs = NULL,
1808  .outputs = avfilter_vsrc_allrgb_outputs,
1809 };
1810 
1811 #endif /* CONFIG_ALLRGB_FILTER */
also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B
Definition: pixfmt.h:498
int plane
Definition: avisynth_c.h:384
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 char const char void * val
Definition: avisynth_c.h:863
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2522
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
AVFilter ff_vsrc_smptehdbars
AVOption.
Definition: opt.h:246
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:100
AVFilter ff_vsrc_allyuv
#define AV_PIX_FMT_YUV444P14
Definition: pixfmt.h:397
const char * fmt
Definition: avisynth_c.h:861
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
const char * desc
Definition: nvenc.c:68
#define AV_PIX_FMT_RGBA64
Definition: pixfmt.h:377
also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601 ...
Definition: pixfmt.h:502
static void draw_rectangle(AVFormatContext *s)
Definition: xcbgrab.c:568
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:266
static av_cold void uninit(AVFilterContext *ctx)
Definition: vsrc_testsrc.c:120
#define AV_PIX_FMT_BGRA64
Definition: pixfmt.h:382
#define COMMON_OPTIONS_NOSIZE
Definition: vsrc_testsrc.c:91
const uint8_t avpriv_vga16_font[4096]
packed BGR 8:8:8, 32bpp, XBGRXBGR... X=unused/undefined
Definition: pixfmt.h:239
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:60
#define AV_PIX_FMT_RGB444
Definition: pixfmt.h:376
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:92
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:283
static av_cold int init(AVFilterContext *ctx)
Definition: vsrc_testsrc.c:105
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:61
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:1080
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:117
uint8_t
#define av_cold
Definition: attributes.h:82
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:388
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
static int request_frame(AVFilterLink *outlink)
Definition: vsrc_testsrc.c:140
#define AVERROR_EOF
End of file.
Definition: error.h:55
#define AV_PIX_FMT_BGR48
Definition: pixfmt.h:378
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:192
#define AV_PIX_FMT_YUV444P16
Definition: pixfmt.h:400
int interlaced_frame
The content of the picture is interlaced.
Definition: frame.h:442
ptrdiff_t size
Definition: opengl_enc.c:100
#define A(x)
Definition: vp56_arith.h:28
#define FFALIGN(x, a)
Definition: macros.h:48
#define av_log(a,...)
int av_parse_color(uint8_t *rgba_color, const char *color_string, int slen, void *log_ctx)
Put the RGBA values that correspond to color_string in rgba_color.
Definition: parseutils.c:354
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 i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
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:353
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:568
#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:202
#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:186
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
Definition: pixfmt.h:95
const char * r
Definition: vf_curves.c:114
void * priv
private data for use by the filter
Definition: avfilter.h:353
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:2487
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: frame.h:539
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:550
Definition: graph2dot.c:48
#define AV_PIX_FMT_RGB48
Definition: pixfmt.h:373
simple assert() macros that are a bit more flexible than ISO C assert().
#define AV_PIX_FMT_YUV444P10
Definition: pixfmt.h:390
#define COMMON_OPTIONS
Definition: vsrc_testsrc.c:98
#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:59
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:282
#define b
Definition: input.c:41
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:378
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:58
typedef void(APIENTRY *FF_PFNGLACTIVETEXTUREPROC)(GLenum texture)
static int config_props(AVFilterLink *outlink)
Definition: vsrc_testsrc.c:127
int32_t
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:85
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:386
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
Definition: frame.c:540
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:368
#define AV_PIX_FMT_BGR555
Definition: pixfmt.h:380
void(* fill_picture_fn)(AVFilterContext *ctx, AVFrame *frame)
Definition: vsrc_testsrc.c:64
uint8_t color_rgba[4]
Definition: vsrc_testsrc.c:75
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:326
static void draw_text(FFDrawContext *draw, AVFrame *frame, FFDrawColor *color, int x0, int y0, const uint8_t *text, int vertical)
Definition: vf_datascope.c:79
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:78
AVFilter ff_vsrc_haldclutsrc
AVRational sample_aspect_ratio
Sample aspect ratio for the video frame, 0/1 if unknown/unspecified.
Definition: frame.h:383
void * buf
Definition: avisynth_c.h:766
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:56
Describe the class of an AVClass context structure.
Definition: log.h:67
Filter definition.
Definition: avfilter.h:144
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:148
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:350
FFDrawColor color
Definition: vsrc_testsrc.c:74
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:275
#define AV_PIX_FMT_BGR565
Definition: pixfmt.h:379
#define flags(name, subs,...)
Definition: cbs_av1.c:561
AVFilter ff_vsrc_yuvtestsrc
#define AV_PIX_FMT_YUV444P12
Definition: pixfmt.h:394
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:309
AVRational time_base
Definition: vsrc_testsrc.c:56
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
the normal 219*2^(n-8) "MPEG" YUV ranges
Definition: pixfmt.h:521
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:55
#define G
Definition: huffyuvdsp.h:33
#define AV_PIX_FMT_BGR444
Definition: pixfmt.h:381
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:100
#define AV_PIX_FMT_RGB555
Definition: pixfmt.h:375
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:334
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:373
A list of supported formats for one end of a filter link.
Definition: formats.h:64
AVFilter ff_vsrc_color
#define OFFSET(x)
Definition: vsrc_testsrc.c:84
#define AV_PIX_FMT_RGB565
Definition: pixfmt.h:374
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:338
int height
Definition: frame.h:353
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
Definition: af_afftdn.c:1373
planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
Definition: pixfmt.h:99
FFDrawContext draw
Definition: vsrc_testsrc.c:73
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:62
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
AVFilter ff_vsrc_rgbtestsrc
for(j=16;j >0;--j)
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