FFmpeg
vf_overlay.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010 Stefano Sabatini
3  * Copyright (c) 2010 Baptiste Coudurier
4  * Copyright (c) 2007 Bobby Bingham
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  * overlay one video on top of another
26  */
27 
28 #include "avfilter.h"
29 #include "formats.h"
30 #include "libavutil/common.h"
31 #include "libavutil/eval.h"
32 #include "libavutil/avstring.h"
33 #include "libavutil/pixdesc.h"
34 #include "libavutil/imgutils.h"
35 #include "libavutil/mathematics.h"
36 #include "libavutil/opt.h"
37 #include "libavutil/timestamp.h"
38 #include "filters.h"
39 #include "drawutils.h"
40 #include "framesync.h"
41 #include "video.h"
42 #include "vf_overlay.h"
43 
44 typedef struct ThreadData {
45  AVFrame *dst, *src;
46 } ThreadData;
47 
48 static const char *const var_names[] = {
49  "main_w", "W", ///< width of the main video
50  "main_h", "H", ///< height of the main video
51  "overlay_w", "w", ///< width of the overlay video
52  "overlay_h", "h", ///< height of the overlay video
53  "hsub",
54  "vsub",
55  "x",
56  "y",
57  "n", ///< number of frame
58 #if FF_API_FRAME_PKT
59  "pos", ///< position in the file
60 #endif
61  "t", ///< timestamp expressed in seconds
62  NULL
63 };
64 
65 #define MAIN 0
66 #define OVERLAY 1
67 
68 #define R 0
69 #define G 1
70 #define B 2
71 #define A 3
72 
73 #define Y 0
74 #define U 1
75 #define V 2
76 
77 enum EvalMode {
81 };
82 
84 {
85  OverlayContext *s = ctx->priv;
86 
87  ff_framesync_uninit(&s->fs);
88  av_expr_free(s->x_pexpr); s->x_pexpr = NULL;
89  av_expr_free(s->y_pexpr); s->y_pexpr = NULL;
90 }
91 
92 static inline int normalize_xy(double d, int chroma_sub)
93 {
94  if (isnan(d))
95  return INT_MAX;
96  return (int)d & ~((1 << chroma_sub) - 1);
97 }
98 
100 {
101  OverlayContext *s = ctx->priv;
102 
103  s->var_values[VAR_X] = av_expr_eval(s->x_pexpr, s->var_values, NULL);
104  s->var_values[VAR_Y] = av_expr_eval(s->y_pexpr, s->var_values, NULL);
105  /* It is necessary if x is expressed from y */
106  s->var_values[VAR_X] = av_expr_eval(s->x_pexpr, s->var_values, NULL);
107  s->x = normalize_xy(s->var_values[VAR_X], s->hsub);
108  s->y = normalize_xy(s->var_values[VAR_Y], s->vsub);
109 }
110 
111 static int set_expr(AVExpr **pexpr, const char *expr, const char *option, void *log_ctx)
112 {
113  int ret;
114  AVExpr *old = NULL;
115 
116  if (*pexpr)
117  old = *pexpr;
118  ret = av_expr_parse(pexpr, expr, var_names,
119  NULL, NULL, NULL, NULL, 0, log_ctx);
120  if (ret < 0) {
121  av_log(log_ctx, AV_LOG_ERROR,
122  "Error when evaluating the expression '%s' for %s\n",
123  expr, option);
124  *pexpr = old;
125  return ret;
126  }
127 
128  av_expr_free(old);
129  return 0;
130 }
131 
132 static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
133  char *res, int res_len, int flags)
134 {
135  OverlayContext *s = ctx->priv;
136  int ret;
137 
138  if (!strcmp(cmd, "x"))
139  ret = set_expr(&s->x_pexpr, args, cmd, ctx);
140  else if (!strcmp(cmd, "y"))
141  ret = set_expr(&s->y_pexpr, args, cmd, ctx);
142  else
143  ret = AVERROR(ENOSYS);
144 
145  if (ret < 0)
146  return ret;
147 
148  if (s->eval_mode == EVAL_MODE_INIT) {
149  eval_expr(ctx);
150  av_log(ctx, AV_LOG_VERBOSE, "x:%f xi:%d y:%f yi:%d\n",
151  s->var_values[VAR_X], s->x,
152  s->var_values[VAR_Y], s->y);
153  }
154  return ret;
155 }
156 
157 static const enum AVPixelFormat alpha_pix_fmts[] = {
162 };
163 
165  AVFilterFormatsConfig **cfg_in,
166  AVFilterFormatsConfig **cfg_out)
167 {
168  const OverlayContext *s = ctx->priv;
169 
170  /* overlay formats contains alpha, for avoiding conversion with alpha information loss */
171  static const enum AVPixelFormat main_pix_fmts_yuv420[] = {
175  };
176  static const enum AVPixelFormat overlay_pix_fmts_yuv420[] = {
178  };
179 
180  static const enum AVPixelFormat main_pix_fmts_yuv420p10[] = {
183  };
184  static const enum AVPixelFormat overlay_pix_fmts_yuv420p10[] = {
186  };
187 
188  static const enum AVPixelFormat main_pix_fmts_yuv422[] = {
190  };
191  static const enum AVPixelFormat overlay_pix_fmts_yuv422[] = {
193  };
194 
195  static const enum AVPixelFormat main_pix_fmts_yuv422p10[] = {
197  };
198  static const enum AVPixelFormat overlay_pix_fmts_yuv422p10[] = {
200  };
201 
202  static const enum AVPixelFormat main_pix_fmts_yuv444[] = {
204  };
205  static const enum AVPixelFormat overlay_pix_fmts_yuv444[] = {
207  };
208 
209  static const enum AVPixelFormat main_pix_fmts_yuv444p10[] = {
211  };
212  static const enum AVPixelFormat overlay_pix_fmts_yuv444p10[] = {
214  };
215 
216  static const enum AVPixelFormat main_pix_fmts_gbrp[] = {
218  };
219  static const enum AVPixelFormat overlay_pix_fmts_gbrp[] = {
221  };
222 
223  static const enum AVPixelFormat main_pix_fmts_rgb[] = {
228  };
229  static const enum AVPixelFormat overlay_pix_fmts_rgb[] = {
233  };
234 
235  const enum AVPixelFormat *main_formats, *overlay_formats;
237  int ret;
238 
239  switch (s->format) {
241  main_formats = main_pix_fmts_yuv420;
242  overlay_formats = overlay_pix_fmts_yuv420;
243  break;
245  main_formats = main_pix_fmts_yuv420p10;
246  overlay_formats = overlay_pix_fmts_yuv420p10;
247  break;
249  main_formats = main_pix_fmts_yuv422;
250  overlay_formats = overlay_pix_fmts_yuv422;
251  break;
253  main_formats = main_pix_fmts_yuv422p10;
254  overlay_formats = overlay_pix_fmts_yuv422p10;
255  break;
257  main_formats = main_pix_fmts_yuv444;
258  overlay_formats = overlay_pix_fmts_yuv444;
259  break;
261  main_formats = main_pix_fmts_yuv444p10;
262  overlay_formats = overlay_pix_fmts_yuv444p10;
263  break;
264  case OVERLAY_FORMAT_RGB:
265  main_formats = main_pix_fmts_rgb;
266  overlay_formats = overlay_pix_fmts_rgb;
267  break;
268  case OVERLAY_FORMAT_GBRP:
269  main_formats = main_pix_fmts_gbrp;
270  overlay_formats = overlay_pix_fmts_gbrp;
271  break;
272  case OVERLAY_FORMAT_AUTO:
273  return ff_set_common_formats_from_list2(ctx, cfg_in, cfg_out, alpha_pix_fmts);
274  default:
275  av_assert0(0);
276  }
277 
278  formats = ff_make_format_list(main_formats);
279  if ((ret = ff_formats_ref(formats, &cfg_in[MAIN]->formats)) < 0 ||
280  (ret = ff_formats_ref(formats, &cfg_out[MAIN]->formats)) < 0)
281  return ret;
282 
283  return ff_formats_ref(ff_make_format_list(overlay_formats),
284  &cfg_in[OVERLAY]->formats);
285 }
286 
288 {
289  AVFilterContext *ctx = inlink->dst;
290  OverlayContext *s = inlink->dst->priv;
291  int ret;
292  const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format);
293 
294  av_image_fill_max_pixsteps(s->overlay_pix_step, NULL, pix_desc);
295 
296  /* Finish the configuration by evaluating the expressions
297  now when both inputs are configured. */
298  s->var_values[VAR_MAIN_W ] = s->var_values[VAR_MW] = ctx->inputs[MAIN ]->w;
299  s->var_values[VAR_MAIN_H ] = s->var_values[VAR_MH] = ctx->inputs[MAIN ]->h;
300  s->var_values[VAR_OVERLAY_W] = s->var_values[VAR_OW] = ctx->inputs[OVERLAY]->w;
301  s->var_values[VAR_OVERLAY_H] = s->var_values[VAR_OH] = ctx->inputs[OVERLAY]->h;
302  s->var_values[VAR_HSUB] = 1<<pix_desc->log2_chroma_w;
303  s->var_values[VAR_VSUB] = 1<<pix_desc->log2_chroma_h;
304  s->var_values[VAR_X] = NAN;
305  s->var_values[VAR_Y] = NAN;
306  s->var_values[VAR_N] = 0;
307  s->var_values[VAR_T] = NAN;
308 #if FF_API_FRAME_PKT
309  s->var_values[VAR_POS] = NAN;
310 #endif
311 
312  if ((ret = set_expr(&s->x_pexpr, s->x_expr, "x", ctx)) < 0 ||
313  (ret = set_expr(&s->y_pexpr, s->y_expr, "y", ctx)) < 0)
314  return ret;
315 
316  s->overlay_is_packed_rgb =
317  ff_fill_rgba_map(s->overlay_rgba_map, inlink->format) >= 0;
318  s->overlay_has_alpha = ff_fmt_is_in(inlink->format, alpha_pix_fmts);
319 
320  if (s->eval_mode == EVAL_MODE_INIT) {
321  eval_expr(ctx);
322  av_log(ctx, AV_LOG_VERBOSE, "x:%f xi:%d y:%f yi:%d\n",
323  s->var_values[VAR_X], s->x,
324  s->var_values[VAR_Y], s->y);
325  }
326 
328  "main w:%d h:%d fmt:%s overlay w:%d h:%d fmt:%s\n",
329  ctx->inputs[MAIN]->w, ctx->inputs[MAIN]->h,
330  av_get_pix_fmt_name(ctx->inputs[MAIN]->format),
331  ctx->inputs[OVERLAY]->w, ctx->inputs[OVERLAY]->h,
332  av_get_pix_fmt_name(ctx->inputs[OVERLAY]->format));
333  return 0;
334 }
335 
336 static int config_output(AVFilterLink *outlink)
337 {
338  AVFilterContext *ctx = outlink->src;
339  OverlayContext *s = ctx->priv;
340  int ret;
341 
342  if ((ret = ff_framesync_init_dualinput(&s->fs, ctx)) < 0)
343  return ret;
344 
345  outlink->w = ctx->inputs[MAIN]->w;
346  outlink->h = ctx->inputs[MAIN]->h;
347  outlink->time_base = ctx->inputs[MAIN]->time_base;
348 
349  return ff_framesync_configure(&s->fs);
350 }
351 
352 // divide by 255 and round to nearest
353 // apply a fast variant: (X+127)/255 = ((X+127)*257+257)>>16 = ((X+128)*257)>>16
354 #define FAST_DIV255(x) ((((x) + 128) * 257) >> 16)
355 
356 // calculate the unpremultiplied alpha, applying the general equation:
357 // alpha = alpha_overlay / ( (alpha_main + alpha_overlay) - (alpha_main * alpha_overlay) )
358 // (((x) << 16) - ((x) << 9) + (x)) is a faster version of: 255 * 255 * x
359 // ((((x) + (y)) << 8) - ((x) + (y)) - (y) * (x)) is a faster version of: 255 * (x + y)
360 #define UNPREMULTIPLY_ALPHA(x, y) ((((x) << 16) - ((x) << 9) + (x)) / ((((x) + (y)) << 8) - ((x) + (y)) - (y) * (x)))
361 
362 /**
363  * Blend image in src to destination buffer dst at position (x, y).
364  */
365 
367  AVFrame *dst, const AVFrame *src,
368  int main_has_alpha, int x, int y,
369  int is_straight, int jobnr, int nb_jobs)
370 {
371  OverlayContext *s = ctx->priv;
372  int i, imax, j, jmax;
373  const int src_w = src->width;
374  const int src_h = src->height;
375  const int dst_w = dst->width;
376  const int dst_h = dst->height;
377  uint8_t alpha; ///< the amount of overlay to blend on to main
378  const int dr = s->main_rgba_map[R];
379  const int dg = s->main_rgba_map[G];
380  const int db = s->main_rgba_map[B];
381  const int da = s->main_rgba_map[A];
382  const int dstep = s->main_pix_step[0];
383  const int sr = s->overlay_rgba_map[R];
384  const int sg = s->overlay_rgba_map[G];
385  const int sb = s->overlay_rgba_map[B];
386  const int sa = s->overlay_rgba_map[A];
387  const int sstep = s->overlay_pix_step[0];
388  int slice_start, slice_end;
389  uint8_t *S, *sp, *d, *dp;
390 
391  i = FFMAX(-y, 0);
392  imax = FFMIN3(-y + dst_h, FFMIN(src_h, dst_h), y + src_h);
393 
394  slice_start = i + (imax * jobnr) / nb_jobs;
395  slice_end = i + (imax * (jobnr+1)) / nb_jobs;
396 
397  sp = src->data[0] + (slice_start) * src->linesize[0];
398  dp = dst->data[0] + (y + slice_start) * dst->linesize[0];
399 
400  for (i = slice_start; i < slice_end; i++) {
401  j = FFMAX(-x, 0);
402  S = sp + j * sstep;
403  d = dp + (x+j) * dstep;
404 
405  for (jmax = FFMIN(-x + dst_w, src_w); j < jmax; j++) {
406  alpha = S[sa];
407 
408  // if the main channel has an alpha channel, alpha has to be calculated
409  // to create an un-premultiplied (straight) alpha value
410  if (main_has_alpha && alpha != 0 && alpha != 255) {
411  uint8_t alpha_d = d[da];
412  alpha = UNPREMULTIPLY_ALPHA(alpha, alpha_d);
413  }
414 
415  switch (alpha) {
416  case 0:
417  break;
418  case 255:
419  d[dr] = S[sr];
420  d[dg] = S[sg];
421  d[db] = S[sb];
422  break;
423  default:
424  // main_value = main_value * (1 - alpha) + overlay_value * alpha
425  // since alpha is in the range 0-255, the result must divided by 255
426  d[dr] = is_straight ? FAST_DIV255(d[dr] * (255 - alpha) + S[sr] * alpha) :
427  FFMIN(FAST_DIV255(d[dr] * (255 - alpha)) + S[sr], 255);
428  d[dg] = is_straight ? FAST_DIV255(d[dg] * (255 - alpha) + S[sg] * alpha) :
429  FFMIN(FAST_DIV255(d[dg] * (255 - alpha)) + S[sg], 255);
430  d[db] = is_straight ? FAST_DIV255(d[db] * (255 - alpha) + S[sb] * alpha) :
431  FFMIN(FAST_DIV255(d[db] * (255 - alpha)) + S[sb], 255);
432  }
433  if (main_has_alpha) {
434  switch (alpha) {
435  case 0:
436  break;
437  case 255:
438  d[da] = S[sa];
439  break;
440  default:
441  // apply alpha compositing: main_alpha += (1-main_alpha) * overlay_alpha
442  d[da] += FAST_DIV255((255 - d[da]) * S[sa]);
443  }
444  }
445  d += dstep;
446  S += sstep;
447  }
448  dp += dst->linesize[0];
449  sp += src->linesize[0];
450  }
451 }
452 
453 #define DEFINE_BLEND_PLANE(depth, nbits) \
454 static av_always_inline void blend_plane_##depth##_##nbits##bits(AVFilterContext *ctx, \
455  AVFrame *dst, const AVFrame *src, \
456  int src_w, int src_h, \
457  int dst_w, int dst_h, \
458  int i, int hsub, int vsub, \
459  int x, int y, \
460  int main_has_alpha, \
461  int dst_plane, \
462  int dst_offset, \
463  int dst_step, \
464  int straight, \
465  int yuv, \
466  int jobnr, \
467  int nb_jobs) \
468 { \
469  OverlayContext *octx = ctx->priv; \
470  int src_wp = AV_CEIL_RSHIFT(src_w, hsub); \
471  int src_hp = AV_CEIL_RSHIFT(src_h, vsub); \
472  int dst_wp = AV_CEIL_RSHIFT(dst_w, hsub); \
473  int dst_hp = AV_CEIL_RSHIFT(dst_h, vsub); \
474  int yp = y>>vsub; \
475  int xp = x>>hsub; \
476  uint##depth##_t *s, *sp, *d, *dp, *dap, *a, *da, *ap; \
477  int jmax, j, k, kmax; \
478  int slice_start, slice_end; \
479  const uint##depth##_t max = (1 << nbits) - 1; \
480  const uint##depth##_t mid = (1 << (nbits -1)) ; \
481  int bytes = depth / 8; \
482  \
483  dst_step /= bytes; \
484  j = FFMAX(-yp, 0); \
485  jmax = FFMIN3(-yp + dst_hp, FFMIN(src_hp, dst_hp), yp + src_hp); \
486  \
487  slice_start = j + (jmax * jobnr) / nb_jobs; \
488  slice_end = j + (jmax * (jobnr+1)) / nb_jobs; \
489  \
490  sp = (uint##depth##_t *)(src->data[i] + (slice_start) * src->linesize[i]); \
491  dp = (uint##depth##_t *)(dst->data[dst_plane] \
492  + (yp + slice_start) * dst->linesize[dst_plane] \
493  + dst_offset); \
494  ap = (uint##depth##_t *)(src->data[3] + (slice_start << vsub) * src->linesize[3]); \
495  dap = (uint##depth##_t *)(dst->data[3] + ((yp + slice_start) << vsub) * dst->linesize[3]); \
496  \
497  for (j = slice_start; j < slice_end; j++) { \
498  k = FFMAX(-xp, 0); \
499  d = dp + (xp+k) * dst_step; \
500  s = sp + k; \
501  a = ap + (k<<hsub); \
502  da = dap + ((xp+k) << hsub); \
503  kmax = FFMIN(-xp + dst_wp, src_wp); \
504  \
505  if (nbits == 8 && ((vsub && j+1 < src_hp) || !vsub) && octx->blend_row[i]) { \
506  int c = octx->blend_row[i]((uint8_t*)d, (uint8_t*)da, (uint8_t*)s, \
507  (uint8_t*)a, kmax - k, src->linesize[3]); \
508  \
509  s += c; \
510  d += dst_step * c; \
511  da += (1 << hsub) * c; \
512  a += (1 << hsub) * c; \
513  k += c; \
514  } \
515  for (; k < kmax; k++) { \
516  int alpha_v, alpha_h, alpha; \
517  \
518  /* average alpha for color components, improve quality */ \
519  if (hsub && vsub && j+1 < src_hp && k+1 < src_wp) { \
520  alpha = (a[0] + a[src->linesize[3]] + \
521  a[1] + a[src->linesize[3]+1]) >> 2; \
522  } else if (hsub || vsub) { \
523  alpha_h = hsub && k+1 < src_wp ? \
524  (a[0] + a[1]) >> 1 : a[0]; \
525  alpha_v = vsub && j+1 < src_hp ? \
526  (a[0] + a[src->linesize[3]]) >> 1 : a[0]; \
527  alpha = (alpha_v + alpha_h) >> 1; \
528  } else \
529  alpha = a[0]; \
530  /* if the main channel has an alpha channel, alpha has to be calculated */ \
531  /* to create an un-premultiplied (straight) alpha value */ \
532  if (main_has_alpha && alpha != 0 && alpha != max) { \
533  /* average alpha for color components, improve quality */ \
534  uint8_t alpha_d; \
535  if (hsub && vsub && j+1 < src_hp && k+1 < src_wp) { \
536  alpha_d = (da[0] + da[dst->linesize[3]] + \
537  da[1] + da[dst->linesize[3]+1]) >> 2; \
538  } else if (hsub || vsub) { \
539  alpha_h = hsub && k+1 < src_wp ? \
540  (da[0] + da[1]) >> 1 : da[0]; \
541  alpha_v = vsub && j+1 < src_hp ? \
542  (da[0] + da[dst->linesize[3]]) >> 1 : da[0]; \
543  alpha_d = (alpha_v + alpha_h) >> 1; \
544  } else \
545  alpha_d = da[0]; \
546  alpha = UNPREMULTIPLY_ALPHA(alpha, alpha_d); \
547  } \
548  if (straight) { \
549  if (nbits > 8) \
550  *d = (*d * (max - alpha) + *s * alpha) / max; \
551  else \
552  *d = FAST_DIV255(*d * (255 - alpha) + *s * alpha); \
553  } else { \
554  if (nbits > 8) { \
555  if (i && yuv) \
556  *d = av_clip((*d * (max - alpha) + *s * alpha) / max + *s - mid, -mid, mid) + mid; \
557  else \
558  *d = av_clip_uintp2((*d * (max - alpha) + *s * alpha) / max + *s - (16<<(nbits-8)),\
559  nbits);\
560  } else { \
561  if (i && yuv) \
562  *d = av_clip(FAST_DIV255((*d - mid) * (max - alpha)) + *s - mid, -mid, mid) + mid; \
563  else \
564  *d = av_clip_uint8(FAST_DIV255(*d * (255 - alpha)) + *s - 16); \
565  } \
566  } \
567  s++; \
568  d += dst_step; \
569  da += 1 << hsub; \
570  a += 1 << hsub; \
571  } \
572  dp += dst->linesize[dst_plane] / bytes; \
573  sp += src->linesize[i] / bytes; \
574  ap += (1 << vsub) * src->linesize[3] / bytes; \
575  dap += (1 << vsub) * dst->linesize[3] / bytes; \
576  } \
577 }
578 DEFINE_BLEND_PLANE(8, 8)
579 DEFINE_BLEND_PLANE(16, 10)
580 
581 #define DEFINE_ALPHA_COMPOSITE(depth, nbits) \
582 static inline void alpha_composite_##depth##_##nbits##bits(const AVFrame *src, const AVFrame *dst, \
583  int src_w, int src_h, \
584  int dst_w, int dst_h, \
585  int x, int y, \
586  int jobnr, int nb_jobs) \
587 { \
588  uint##depth##_t alpha; /* the amount of overlay to blend on to main */ \
589  uint##depth##_t *s, *sa, *d, *da; \
590  int i, imax, j, jmax; \
591  int slice_start, slice_end; \
592  const uint##depth##_t max = (1 << nbits) - 1; \
593  int bytes = depth / 8; \
594  \
595  imax = FFMIN3(-y + dst_h, FFMIN(src_h, dst_h), y + src_h); \
596  i = FFMAX(-y, 0); \
597  \
598  slice_start = i + (imax * jobnr) / nb_jobs; \
599  slice_end = i + ((imax * (jobnr+1)) / nb_jobs); \
600  \
601  sa = (uint##depth##_t *)(src->data[3] + (slice_start) * src->linesize[3]); \
602  da = (uint##depth##_t *)(dst->data[3] + (y + slice_start) * dst->linesize[3]); \
603  \
604  for (i = slice_start; i < slice_end; i++) { \
605  j = FFMAX(-x, 0); \
606  s = sa + j; \
607  d = da + x+j; \
608  \
609  for (jmax = FFMIN(-x + dst_w, src_w); j < jmax; j++) { \
610  alpha = *s; \
611  if (alpha != 0 && alpha != max) { \
612  uint8_t alpha_d = *d; \
613  alpha = UNPREMULTIPLY_ALPHA(alpha, alpha_d); \
614  } \
615  if (alpha == max) \
616  *d = *s; \
617  else if (alpha > 0) { \
618  /* apply alpha compositing: main_alpha += (1-main_alpha) * overlay_alpha */ \
619  if (nbits > 8) \
620  *d += (max - *d) * *s / max; \
621  else \
622  *d += FAST_DIV255((max - *d) * *s); \
623  } \
624  d += 1; \
625  s += 1; \
626  } \
627  da += dst->linesize[3] / bytes; \
628  sa += src->linesize[3] / bytes; \
629  } \
630 }
633 
634 #define DEFINE_BLEND_SLICE_YUV(depth, nbits) \
635 static av_always_inline void blend_slice_yuv_##depth##_##nbits##bits(AVFilterContext *ctx, \
636  AVFrame *dst, const AVFrame *src, \
637  int hsub, int vsub, \
638  int main_has_alpha, \
639  int x, int y, \
640  int is_straight, \
641  int jobnr, int nb_jobs) \
642 { \
643  OverlayContext *s = ctx->priv; \
644  const int src_w = src->width; \
645  const int src_h = src->height; \
646  const int dst_w = dst->width; \
647  const int dst_h = dst->height; \
648  \
649  blend_plane_##depth##_##nbits##bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 0, 0, 0, \
650  x, y, main_has_alpha, s->main_desc->comp[0].plane, s->main_desc->comp[0].offset, \
651  s->main_desc->comp[0].step, is_straight, 1, jobnr, nb_jobs); \
652  blend_plane_##depth##_##nbits##bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 1, hsub, vsub, \
653  x, y, main_has_alpha, s->main_desc->comp[1].plane, s->main_desc->comp[1].offset, \
654  s->main_desc->comp[1].step, is_straight, 1, jobnr, nb_jobs); \
655  blend_plane_##depth##_##nbits##bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 2, hsub, vsub, \
656  x, y, main_has_alpha, s->main_desc->comp[2].plane, s->main_desc->comp[2].offset, \
657  s->main_desc->comp[2].step, is_straight, 1, jobnr, nb_jobs); \
658  \
659  if (main_has_alpha) \
660  alpha_composite_##depth##_##nbits##bits(src, dst, src_w, src_h, dst_w, dst_h, x, y, \
661  jobnr, nb_jobs); \
662 }
665 
667  AVFrame *dst, const AVFrame *src,
668  int hsub, int vsub,
669  int main_has_alpha,
670  int x, int y,
671  int is_straight,
672  int jobnr,
673  int nb_jobs)
674 {
675  OverlayContext *s = ctx->priv;
676  const int src_w = src->width;
677  const int src_h = src->height;
678  const int dst_w = dst->width;
679  const int dst_h = dst->height;
680 
681  blend_plane_8_8bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 0, 0, 0, x, y, main_has_alpha,
682  s->main_desc->comp[1].plane, s->main_desc->comp[1].offset, s->main_desc->comp[1].step, is_straight, 0,
683  jobnr, nb_jobs);
684  blend_plane_8_8bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 1, hsub, vsub, x, y, main_has_alpha,
685  s->main_desc->comp[2].plane, s->main_desc->comp[2].offset, s->main_desc->comp[2].step, is_straight, 0,
686  jobnr, nb_jobs);
687  blend_plane_8_8bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 2, hsub, vsub, x, y, main_has_alpha,
688  s->main_desc->comp[0].plane, s->main_desc->comp[0].offset, s->main_desc->comp[0].step, is_straight, 0,
689  jobnr, nb_jobs);
690 
691  if (main_has_alpha)
692  alpha_composite_8_8bits(src, dst, src_w, src_h, dst_w, dst_h, x, y, jobnr, nb_jobs);
693 }
694 
695 #define DEFINE_BLEND_SLICE_PLANAR_FMT(format_, blend_slice_fn_suffix_, hsub_, vsub_, main_has_alpha_, direct_) \
696 static int blend_slice_##format_(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) \
697 { \
698  OverlayContext *s = ctx->priv; \
699  ThreadData *td = arg; \
700  blend_slice_##blend_slice_fn_suffix_(ctx, td->dst, td->src, \
701  hsub_, vsub_, main_has_alpha_, \
702  s->x, s->y, direct_, \
703  jobnr, nb_jobs); \
704  return 0; \
705 }
706 
707 // FMT FN H V A D
708 DEFINE_BLEND_SLICE_PLANAR_FMT(yuv420, yuv_8_8bits, 1, 1, 0, 1)
709 DEFINE_BLEND_SLICE_PLANAR_FMT(yuva420, yuv_8_8bits, 1, 1, 1, 1)
710 DEFINE_BLEND_SLICE_PLANAR_FMT(yuv420p10, yuv_16_10bits, 1, 1, 0, 1)
711 DEFINE_BLEND_SLICE_PLANAR_FMT(yuva420p10, yuv_16_10bits, 1, 1, 1, 1)
712 DEFINE_BLEND_SLICE_PLANAR_FMT(yuv422p10, yuv_16_10bits, 1, 0, 0, 1)
713 DEFINE_BLEND_SLICE_PLANAR_FMT(yuva422p10, yuv_16_10bits, 1, 0, 1, 1)
714 DEFINE_BLEND_SLICE_PLANAR_FMT(yuv422, yuv_8_8bits, 1, 0, 0, 1)
715 DEFINE_BLEND_SLICE_PLANAR_FMT(yuva422, yuv_8_8bits, 1, 0, 1, 1)
716 DEFINE_BLEND_SLICE_PLANAR_FMT(yuv444, yuv_8_8bits, 0, 0, 0, 1)
717 DEFINE_BLEND_SLICE_PLANAR_FMT(yuva444, yuv_8_8bits, 0, 0, 1, 1)
718 DEFINE_BLEND_SLICE_PLANAR_FMT(yuv444p10, yuv_16_10bits, 0, 0, 0, 1)
719 DEFINE_BLEND_SLICE_PLANAR_FMT(yuva444p10, yuv_16_10bits, 0, 0, 1, 1)
720 DEFINE_BLEND_SLICE_PLANAR_FMT(gbrp, planar_rgb, 0, 0, 0, 1)
721 DEFINE_BLEND_SLICE_PLANAR_FMT(gbrap, planar_rgb, 0, 0, 1, 1)
722 DEFINE_BLEND_SLICE_PLANAR_FMT(yuv420_pm, yuv_8_8bits, 1, 1, 0, 0)
723 DEFINE_BLEND_SLICE_PLANAR_FMT(yuva420_pm, yuv_8_8bits, 1, 1, 1, 0)
724 DEFINE_BLEND_SLICE_PLANAR_FMT(yuv422_pm, yuv_8_8bits, 1, 0, 0, 0)
725 DEFINE_BLEND_SLICE_PLANAR_FMT(yuva422_pm, yuv_8_8bits, 1, 0, 1, 0)
726 DEFINE_BLEND_SLICE_PLANAR_FMT(yuv444_pm, yuv_8_8bits, 0, 0, 0, 0)
727 DEFINE_BLEND_SLICE_PLANAR_FMT(yuva444_pm, yuv_8_8bits, 0, 0, 1, 0)
728 DEFINE_BLEND_SLICE_PLANAR_FMT(gbrp_pm, planar_rgb, 0, 0, 0, 0)
729 DEFINE_BLEND_SLICE_PLANAR_FMT(gbrap_pm, planar_rgb, 0, 0, 1, 0)
730 
731 #define DEFINE_BLEND_SLICE_PACKED_FMT(format_, blend_slice_fn_suffix_, main_has_alpha_, direct_) \
732 static int blend_slice_##format_(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) \
733 { \
734  OverlayContext *s = ctx->priv; \
735  ThreadData *td = arg; \
736  blend_slice_packed_##blend_slice_fn_suffix_(ctx, td->dst, td->src, \
737  main_has_alpha_, \
738  s->x, s->y, direct_, \
739  jobnr, nb_jobs); \
740  return 0; \
741 }
742 
743 // FMT FN A D
746 DEFINE_BLEND_SLICE_PACKED_FMT(rgb_pm, rgb, 0, 0)
747 DEFINE_BLEND_SLICE_PACKED_FMT(rgba_pm, rgb, 1, 0)
748 
750 {
751  OverlayContext *s = inlink->dst->priv;
752  const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format);
753 
754  av_image_fill_max_pixsteps(s->main_pix_step, NULL, pix_desc);
755 
756  s->hsub = pix_desc->log2_chroma_w;
757  s->vsub = pix_desc->log2_chroma_h;
758 
759  s->main_desc = pix_desc;
760 
761  s->main_is_packed_rgb =
762  ff_fill_rgba_map(s->main_rgba_map, inlink->format) >= 0;
763  s->main_has_alpha = ff_fmt_is_in(inlink->format, alpha_pix_fmts);
764  switch (s->format) {
766  s->blend_slice = s->main_has_alpha ? blend_slice_yuva420 : blend_slice_yuv420;
767  break;
769  s->blend_slice = s->main_has_alpha ? blend_slice_yuva420p10 : blend_slice_yuv420p10;
770  break;
772  s->blend_slice = s->main_has_alpha ? blend_slice_yuva422 : blend_slice_yuv422;
773  break;
775  s->blend_slice = s->main_has_alpha ? blend_slice_yuva422p10 : blend_slice_yuv422p10;
776  break;
778  s->blend_slice = s->main_has_alpha ? blend_slice_yuva444 : blend_slice_yuv444;
779  break;
781  s->blend_slice = s->main_has_alpha ? blend_slice_yuva444p10 : blend_slice_yuv444p10;
782  break;
783  case OVERLAY_FORMAT_RGB:
784  s->blend_slice = s->main_has_alpha ? blend_slice_rgba : blend_slice_rgb;
785  break;
786  case OVERLAY_FORMAT_GBRP:
787  s->blend_slice = s->main_has_alpha ? blend_slice_gbrap : blend_slice_gbrp;
788  break;
789  case OVERLAY_FORMAT_AUTO:
790  switch (inlink->format) {
791  case AV_PIX_FMT_YUVA420P:
792  s->blend_slice = blend_slice_yuva420;
793  break;
795  s->blend_slice = blend_slice_yuva420p10;
796  break;
797  case AV_PIX_FMT_YUVA422P:
798  s->blend_slice = blend_slice_yuva422;
799  break;
801  s->blend_slice = blend_slice_yuva422p10;
802  break;
803  case AV_PIX_FMT_YUVA444P:
804  s->blend_slice = blend_slice_yuva444;
805  break;
807  s->blend_slice = blend_slice_yuva444p10;
808  break;
809  case AV_PIX_FMT_ARGB:
810  case AV_PIX_FMT_RGBA:
811  case AV_PIX_FMT_BGRA:
812  case AV_PIX_FMT_ABGR:
813  s->blend_slice = blend_slice_rgba;
814  break;
815  case AV_PIX_FMT_GBRAP:
816  s->blend_slice = blend_slice_gbrap;
817  break;
818  default:
819  av_assert0(0);
820  break;
821  }
822  break;
823  }
824 
825  if (!s->alpha_format)
826  goto end;
827 
828  switch (s->format) {
830  s->blend_slice = s->main_has_alpha ? blend_slice_yuva420_pm : blend_slice_yuv420_pm;
831  break;
833  s->blend_slice = s->main_has_alpha ? blend_slice_yuva422_pm : blend_slice_yuv422_pm;
834  break;
836  s->blend_slice = s->main_has_alpha ? blend_slice_yuva444_pm : blend_slice_yuv444_pm;
837  break;
838  case OVERLAY_FORMAT_RGB:
839  s->blend_slice = s->main_has_alpha ? blend_slice_rgba_pm : blend_slice_rgb_pm;
840  break;
841  case OVERLAY_FORMAT_GBRP:
842  s->blend_slice = s->main_has_alpha ? blend_slice_gbrap_pm : blend_slice_gbrp_pm;
843  break;
844  case OVERLAY_FORMAT_AUTO:
845  switch (inlink->format) {
846  case AV_PIX_FMT_YUVA420P:
847  s->blend_slice = blend_slice_yuva420_pm;
848  break;
849  case AV_PIX_FMT_YUVA422P:
850  s->blend_slice = blend_slice_yuva422_pm;
851  break;
852  case AV_PIX_FMT_YUVA444P:
853  s->blend_slice = blend_slice_yuva444_pm;
854  break;
855  case AV_PIX_FMT_ARGB:
856  case AV_PIX_FMT_RGBA:
857  case AV_PIX_FMT_BGRA:
858  case AV_PIX_FMT_ABGR:
859  s->blend_slice = blend_slice_rgba_pm;
860  break;
861  case AV_PIX_FMT_GBRAP:
862  s->blend_slice = blend_slice_gbrap_pm;
863  break;
864  default:
865  av_assert0(0);
866  break;
867  }
868  break;
869  }
870 
871 end:
872 #if ARCH_X86
873  ff_overlay_init_x86(s, s->format, inlink->format,
874  s->alpha_format, s->main_has_alpha);
875 #endif
876 
877  return 0;
878 }
879 
880 static int do_blend(FFFrameSync *fs)
881 {
882  AVFilterContext *ctx = fs->parent;
883  AVFrame *mainpic, *second;
884  OverlayContext *s = ctx->priv;
885  AVFilterLink *inlink = ctx->inputs[0];
887  int ret;
888 
889  ret = ff_framesync_dualinput_get_writable(fs, &mainpic, &second);
890  if (ret < 0)
891  return ret;
892  if (!second)
893  return ff_filter_frame(ctx->outputs[0], mainpic);
894 
895  if (s->eval_mode == EVAL_MODE_FRAME) {
896 
897  s->var_values[VAR_N] = inl->frame_count_out;
898  s->var_values[VAR_T] = mainpic->pts == AV_NOPTS_VALUE ?
899  NAN : mainpic->pts * av_q2d(inlink->time_base);
900 #if FF_API_FRAME_PKT
902  {
903  int64_t pos = mainpic->pkt_pos;
904  s->var_values[VAR_POS] = pos == -1 ? NAN : pos;
905  }
907 #endif
908 
909  s->var_values[VAR_OVERLAY_W] = s->var_values[VAR_OW] = second->width;
910  s->var_values[VAR_OVERLAY_H] = s->var_values[VAR_OH] = second->height;
911  s->var_values[VAR_MAIN_W ] = s->var_values[VAR_MW] = mainpic->width;
912  s->var_values[VAR_MAIN_H ] = s->var_values[VAR_MH] = mainpic->height;
913 
914  eval_expr(ctx);
915  av_log(ctx, AV_LOG_DEBUG, "n:%f t:%f x:%f xi:%d y:%f yi:%d\n",
916  s->var_values[VAR_N], s->var_values[VAR_T],
917  s->var_values[VAR_X], s->x,
918  s->var_values[VAR_Y], s->y);
919  }
920 
921  if (s->x < mainpic->width && s->x + second->width >= 0 &&
922  s->y < mainpic->height && s->y + second->height >= 0) {
923  ThreadData td;
924 
925  td.dst = mainpic;
926  td.src = second;
927  ff_filter_execute(ctx, s->blend_slice, &td, NULL, FFMIN(FFMAX(1, FFMIN3(s->y + second->height, FFMIN(second->height, mainpic->height), mainpic->height - s->y)),
929  }
930  return ff_filter_frame(ctx->outputs[0], mainpic);
931 }
932 
934 {
935  OverlayContext *s = ctx->priv;
936 
937  s->fs.on_event = do_blend;
938  return 0;
939 }
940 
942 {
943  OverlayContext *s = ctx->priv;
944  return ff_framesync_activate(&s->fs);
945 }
946 
947 #define OFFSET(x) offsetof(OverlayContext, x)
948 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
949 #define TFLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
950 
951 static const AVOption overlay_options[] = {
952  { "x", "set the x expression", OFFSET(x_expr), AV_OPT_TYPE_STRING, {.str = "0"}, 0, 0, TFLAGS },
953  { "y", "set the y expression", OFFSET(y_expr), AV_OPT_TYPE_STRING, {.str = "0"}, 0, 0, TFLAGS },
954  { "eof_action", "Action to take when encountering EOF from secondary input ",
955  OFFSET(fs.opt_eof_action), AV_OPT_TYPE_INT, { .i64 = EOF_ACTION_REPEAT },
956  EOF_ACTION_REPEAT, EOF_ACTION_PASS, .flags = FLAGS, .unit = "eof_action" },
957  { "repeat", "Repeat the previous frame.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_REPEAT }, .flags = FLAGS, .unit = "eof_action" },
958  { "endall", "End both streams.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_ENDALL }, .flags = FLAGS, .unit = "eof_action" },
959  { "pass", "Pass through the main input.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_PASS }, .flags = FLAGS, .unit = "eof_action" },
960  { "eval", "specify when to evaluate expressions", OFFSET(eval_mode), AV_OPT_TYPE_INT, {.i64 = EVAL_MODE_FRAME}, 0, EVAL_MODE_NB-1, FLAGS, .unit = "eval" },
961  { "init", "eval expressions once during initialization", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_INIT}, .flags = FLAGS, .unit = "eval" },
962  { "frame", "eval expressions per-frame", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_FRAME}, .flags = FLAGS, .unit = "eval" },
963  { "shortest", "force termination when the shortest input terminates", OFFSET(fs.opt_shortest), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS },
964  { "format", "set output format", OFFSET(format), AV_OPT_TYPE_INT, {.i64=OVERLAY_FORMAT_YUV420}, 0, OVERLAY_FORMAT_NB-1, FLAGS, .unit = "format" },
965  { "yuv420", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV420}, .flags = FLAGS, .unit = "format" },
966  { "yuv420p10", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV420P10}, .flags = FLAGS, .unit = "format" },
967  { "yuv422", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV422}, .flags = FLAGS, .unit = "format" },
968  { "yuv422p10", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV422P10}, .flags = FLAGS, .unit = "format" },
969  { "yuv444", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV444}, .flags = FLAGS, .unit = "format" },
970  { "yuv444p10", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV444P10}, .flags = FLAGS, .unit = "format" },
971  { "rgb", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_RGB}, .flags = FLAGS, .unit = "format" },
972  { "gbrp", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_GBRP}, .flags = FLAGS, .unit = "format" },
973  { "auto", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_AUTO}, .flags = FLAGS, .unit = "format" },
974  { "repeatlast", "repeat overlay of the last overlay frame", OFFSET(fs.opt_repeatlast), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGS },
975  { "alpha", "alpha format", OFFSET(alpha_format), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, .unit = "alpha_format" },
976  { "straight", "", 0, AV_OPT_TYPE_CONST, {.i64=0}, .flags = FLAGS, .unit = "alpha_format" },
977  { "premultiplied", "", 0, AV_OPT_TYPE_CONST, {.i64=1}, .flags = FLAGS, .unit = "alpha_format" },
978  { NULL }
979 };
980 
982 
984  {
985  .name = "main",
986  .type = AVMEDIA_TYPE_VIDEO,
987  .config_props = config_input_main,
988  },
989  {
990  .name = "overlay",
991  .type = AVMEDIA_TYPE_VIDEO,
992  .config_props = config_input_overlay,
993  },
994 };
995 
997  {
998  .name = "default",
999  .type = AVMEDIA_TYPE_VIDEO,
1000  .config_props = config_output,
1001  },
1002 };
1003 
1005  .p.name = "overlay",
1006  .p.description = NULL_IF_CONFIG_SMALL("Overlay a video source on top of the input."),
1007  .p.priv_class = &overlay_class,
1010  .preinit = overlay_framesync_preinit,
1011  .init = init,
1012  .uninit = uninit,
1013  .priv_size = sizeof(OverlayContext),
1014  .activate = activate,
1019 };
formats
formats
Definition: signature.h:47
FF_ENABLE_DEPRECATION_WARNINGS
#define FF_ENABLE_DEPRECATION_WARNINGS
Definition: internal.h:73
VAR_MAIN_H
@ VAR_MAIN_H
Definition: vf_drawtext.c:135
ff_framesync_configure
int ff_framesync_configure(FFFrameSync *fs)
Configure a frame sync structure.
Definition: framesync.c:137
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
blend_slice_packed_rgb
static av_always_inline void blend_slice_packed_rgb(AVFilterContext *ctx, AVFrame *dst, const AVFrame *src, int main_has_alpha, int x, int y, int is_straight, int jobnr, int nb_jobs)
Blend image in src to destination buffer dst at position (x, y).
Definition: vf_overlay.c:366
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
VAR_OH
@ VAR_OH
Definition: scale_eval.c:46
set_expr
static int set_expr(AVExpr **pexpr, const char *expr, const char *option, void *log_ctx)
Definition: vf_overlay.c:111
OVERLAY
#define OVERLAY
Definition: vf_overlay.c:66
ff_make_format_list
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:435
ff_framesync_uninit
void ff_framesync_uninit(FFFrameSync *fs)
Free all memory currently allocated.
Definition: framesync.c:301
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1062
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3170
avfilter_vf_overlay_outputs
static const AVFilterPad avfilter_vf_overlay_outputs[]
Definition: vf_overlay.c:996
int64_t
long long int64_t
Definition: coverity.c:34
inlink
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
Definition: filter_design.txt:212
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: filters.h:262
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:403
pixdesc.h
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:515
AVFrame::width
int width
Definition: frame.h:475
do_blend
static int do_blend(FFFrameSync *fs)
Definition: vf_overlay.c:880
AV_PIX_FMT_YUVA420P10
#define AV_PIX_FMT_YUVA420P10
Definition: pixfmt.h:540
AVOption
AVOption.
Definition: opt.h:429
EOF_ACTION_ENDALL
@ EOF_ACTION_ENDALL
Definition: framesync.h:28
query_formats
static int query_formats(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
Definition: vf_overlay.c:164
AV_PIX_FMT_YUV420P10
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:502
VAR_HSUB
@ VAR_HSUB
Definition: boxblur.c:41
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:225
AV_PIX_FMT_BGR24
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:76
AV_PIX_FMT_BGRA
@ AV_PIX_FMT_BGRA
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
Definition: pixfmt.h:102
mathematics.h
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:203
FFFrameSync
Frame sync structure.
Definition: framesync.h:168
video.h
VAR_MAIN_W
@ VAR_MAIN_W
Definition: vf_drawtext.c:136
AV_PIX_FMT_YUVA422P10
#define AV_PIX_FMT_YUVA422P10
Definition: pixfmt.h:541
hsub
static void hsub(htype *dst, const htype *src, int bins)
Definition: vf_median.c:74
AVFilterFormats
A list of supported formats for one end of a filter link.
Definition: formats.h:64
formats.h
av_expr_parse
int av_expr_parse(AVExpr **expr, const char *s, const char *const *const_names, const char *const *func1_names, double(*const *funcs1)(void *, double), const char *const *func2_names, double(*const *funcs2)(void *, double, double), int log_offset, void *log_ctx)
Parse an expression.
Definition: eval.c:710
var_names
static const char *const var_names[]
Definition: vf_overlay.c:48
S
#define S(s, c, i)
Definition: flacdsp_template.c:46
VAR_T
@ VAR_T
Definition: aeval.c:53
rgb
Definition: rpzaenc.c:60
VAR_VSUB
@ VAR_VSUB
Definition: boxblur.c:42
OVERLAY_FORMAT_RGB
@ OVERLAY_FORMAT_RGB
Definition: vf_overlay.h:51
slice_end
static int slice_end(AVCodecContext *avctx, AVFrame *pict, int *got_output)
Handle slice ends.
Definition: mpeg12dec.c:1720
AV_PIX_FMT_GBRAP
@ AV_PIX_FMT_GBRAP
planar GBRA 4:4:4:4 32bpp
Definition: pixfmt.h:212
FAST_DIV255
#define FAST_DIV255(x)
Definition: vf_overlay.c:354
VAR_X
@ VAR_X
Definition: vf_blend.c:54
OVERLAY_FORMAT_YUV422P10
@ OVERLAY_FORMAT_YUV422P10
Definition: vf_overlay.h:48
av_expr_free
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
Definition: eval.c:358
R
#define R
Definition: vf_overlay.c:68
AVFilterPad
A filter pad used for either input or output.
Definition: filters.h:38
DEFINE_BLEND_SLICE_PACKED_FMT
#define DEFINE_BLEND_SLICE_PACKED_FMT(format_, blend_slice_fn_suffix_, main_has_alpha_, direct_)
Definition: vf_overlay.c:731
ff_overlay_init_x86
void ff_overlay_init_x86(OverlayContext *s, int format, int pix_format, int alpha_format, int main_has_alpha)
Definition: vf_overlay_init.c:35
AV_PIX_FMT_YUV444P10
#define AV_PIX_FMT_YUV444P10
Definition: pixfmt.h:505
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:209
config_input_main
static int config_input_main(AVFilterLink *inlink)
Definition: vf_overlay.c:749
av_cold
#define av_cold
Definition: attributes.h:90
FFFilter
Definition: filters.h:265
EVAL_MODE_FRAME
@ EVAL_MODE_FRAME
Definition: vf_overlay.c:79
AV_PIX_FMT_YUVJ422P
@ AV_PIX_FMT_YUVJ422P
planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting col...
Definition: pixfmt.h:86
s
#define s(width, name)
Definition: cbs_vp9.c:198
AV_PIX_FMT_YUVA420P
@ AV_PIX_FMT_YUVA420P
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
Definition: pixfmt.h:108
OVERLAY_FORMAT_YUV422
@ OVERLAY_FORMAT_YUV422
Definition: vf_overlay.h:47
format
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 format(the sample packing is implied by the sample format) and sample rate. The lists are not just lists
ff_formats_ref
int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
Add *ref as a new reference to formats.
Definition: formats.c:678
av_q2d
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
filters.h
VAR_MW
@ VAR_MW
Definition: vf_overlay.h:28
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:230
ctx
AVFormatContext * ctx
Definition: movenc.c:49
av_expr_eval
double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
Evaluate a previously parsed expression.
Definition: eval.c:792
UNPREMULTIPLY_ALPHA
#define UNPREMULTIPLY_ALPHA(x, y)
Definition: vf_overlay.c:360
AVExpr
Definition: eval.c:158
AVPixFmtDescriptor::log2_chroma_w
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:80
ff_fmt_is_in
int ff_fmt_is_in(int fmt, const int *fmts)
Tell if an integer is contained in the provided -1-terminated list of integers.
Definition: formats.c:406
vf_overlay.h
B
#define B
Definition: vf_overlay.c:70
VAR_N
@ VAR_N
Definition: noise.c:48
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:73
eval_expr
static void eval_expr(AVFilterContext *ctx)
Definition: vf_overlay.c:99
EOF_ACTION_PASS
@ EOF_ACTION_PASS
Definition: framesync.h:29
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: filters.h:263
NAN
#define NAN
Definition: mathematics.h:115
AV_PIX_FMT_YUVJ444P
@ AV_PIX_FMT_YUVJ444P
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
Definition: pixfmt.h:87
AV_PIX_FMT_RGBA
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:100
option
option
Definition: libkvazaar.c:320
ThreadData::dst
AVFrame * dst
Definition: vf_blend.c:58
config_input_overlay
static int config_input_overlay(AVFilterLink *inlink)
Definition: vf_overlay.c:287
NULL
#define NULL
Definition: coverity.c:32
VAR_POS
@ VAR_POS
Definition: noise.c:56
EVAL_MODE_NB
@ EVAL_MODE_NB
Definition: vf_overlay.c:80
fs
#define fs(width, name, subs,...)
Definition: cbs_vp9.c:200
ThreadData::src
const uint8_t * src
Definition: vf_bm3d.c:54
isnan
#define isnan(x)
Definition: libm.h:340
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: vf_overlay.c:83
AV_PIX_FMT_YUVJ420P
@ AV_PIX_FMT_YUVJ420P
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting col...
Definition: pixfmt.h:85
OverlayContext
Definition: vf_overlay.h:57
AV_PIX_FMT_YUV422P10
#define AV_PIX_FMT_YUV422P10
Definition: pixfmt.h:503
AV_PIX_FMT_ABGR
@ AV_PIX_FMT_ABGR
packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
Definition: pixfmt.h:101
AVFilterFormatsConfig
Lists of formats / etc.
Definition: avfilter.h:109
avfilter_vf_overlay_inputs
static const AVFilterPad avfilter_vf_overlay_inputs[]
Definition: vf_overlay.c:983
ff_filter_link
static FilterLink * ff_filter_link(AVFilterLink *link)
Definition: filters.h:197
TFLAGS
#define TFLAGS
Definition: vf_overlay.c:949
eval.h
AV_PIX_FMT_RGB24
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:75
A
#define A
Definition: vf_overlay.c:71
overlay_options
static const AVOption overlay_options[]
Definition: vf_overlay.c:951
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:94
ff_framesync_init_dualinput
int ff_framesync_init_dualinput(FFFrameSync *fs, AVFilterContext *parent)
Initialize a frame sync structure for dualinput.
Definition: framesync.c:372
OVERLAY_FORMAT_NB
@ OVERLAY_FORMAT_NB
Definition: vf_overlay.h:54
OVERLAY_FORMAT_YUV420P10
@ OVERLAY_FORMAT_YUV420P10
Definition: vf_overlay.h:46
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:83
OVERLAY_FORMAT_YUV420
@ OVERLAY_FORMAT_YUV420
Definition: vf_overlay.h:45
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
VAR_MH
@ VAR_MH
Definition: vf_overlay.h:29
AVFrame::pkt_pos
attribute_deprecated int64_t pkt_pos
reordered pos from the last AVPacket that has been input into the decoder
Definition: frame.h:721
config_output
static int config_output(AVFilterLink *outlink)
Definition: vf_overlay.c:336
ff_vf_overlay
const FFFilter ff_vf_overlay
Definition: vf_overlay.c:1004
OVERLAY_FORMAT_YUV444P10
@ OVERLAY_FORMAT_YUV444P10
Definition: vf_overlay.h:50
AV_PIX_FMT_YUVA444P
@ AV_PIX_FMT_YUVA444P
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
Definition: pixfmt.h:174
AV_PIX_FMT_YUVA444P10
#define AV_PIX_FMT_YUVA444P10
Definition: pixfmt.h:542
OVERLAY_FORMAT_AUTO
@ OVERLAY_FORMAT_AUTO
Definition: vf_overlay.h:53
DEFINE_ALPHA_COMPOSITE
#define DEFINE_ALPHA_COMPOSITE(depth, nbits)
Definition: vf_overlay.c:581
AV_PIX_FMT_ARGB
@ AV_PIX_FMT_ARGB
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition: pixfmt.h:99
DEFINE_BLEND_SLICE_PLANAR_FMT
#define DEFINE_BLEND_SLICE_PLANAR_FMT(format_, blend_slice_fn_suffix_, hsub_, vsub_, main_has_alpha_, direct_)
Definition: vf_overlay.c:695
FLAGS
#define FLAGS
Definition: vf_overlay.c:948
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
blend_slice_planar_rgb
static av_always_inline void blend_slice_planar_rgb(AVFilterContext *ctx, AVFrame *dst, const AVFrame *src, int hsub, int vsub, int main_has_alpha, int x, int y, int is_straight, int jobnr, int nb_jobs)
Definition: vf_overlay.c:666
FFMIN3
#define FFMIN3(a, b, c)
Definition: macros.h:50
common.h
ff_filter_get_nb_threads
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition: avfilter.c:841
ThreadData
Used for passing data between threads.
Definition: dsddec.c:71
EvalMode
EvalMode
Definition: af_volume.h:39
FILTER_QUERY_FUNC2
#define FILTER_QUERY_FUNC2(func)
Definition: filters.h:239
av_always_inline
#define av_always_inline
Definition: attributes.h:49
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
AV_PIX_FMT_NV21
@ AV_PIX_FMT_NV21
as above, but U and V bytes are swapped
Definition: pixfmt.h:97
AVFilterPad::name
const char * name
Pad name.
Definition: filters.h:44
VAR_OVERLAY_H
@ VAR_OVERLAY_H
Definition: vf_overlay.h:31
VAR_OW
@ VAR_OW
Definition: scale_eval.c:45
normalize_xy
static int normalize_xy(double d, int chroma_sub)
Definition: vf_overlay.c:92
slice_start
static int slice_start(SliceContext *sc, VVCContext *s, VVCFrameContext *fc, const CodedBitstreamUnit *unit, const int is_first_slice)
Definition: dec.c:736
process_command
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
Definition: vf_overlay.c:132
ret
ret
Definition: filter_design.txt:187
AV_PIX_FMT_NV12
@ AV_PIX_FMT_NV12
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
Definition: pixfmt.h:96
DEFINE_BLEND_PLANE
#define DEFINE_BLEND_PLANE(depth, nbits)
Definition: vf_overlay.c:453
MAIN
#define MAIN
Definition: vf_overlay.c:65
pos
unsigned int pos
Definition: spdifenc.c:414
EOF_ACTION_REPEAT
@ EOF_ACTION_REPEAT
Definition: framesync.h:27
VAR_Y
@ VAR_Y
Definition: vf_blend.c:54
AVFrame::height
int height
Definition: frame.h:475
ff_set_common_formats_from_list2
int ff_set_common_formats_from_list2(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out, const int *fmts)
Definition: formats.c:1016
framesync.h
ff_filter_execute
int ff_filter_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg, int *ret, int nb_jobs)
Definition: avfilter.c:1667
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
avfilter.h
activate
static int activate(AVFilterContext *ctx)
Definition: vf_overlay.c:941
G
#define G
Definition: vf_overlay.c:69
av_image_fill_max_pixsteps
void av_image_fill_max_pixsteps(int max_pixsteps[4], int max_pixstep_comps[4], const AVPixFmtDescriptor *pixdesc)
Compute the max pixel step for each plane of an image with a format described by pixdesc.
Definition: imgutils.c:35
AV_PIX_FMT_YUV444P
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:78
AVFilterContext
An instance of a filter.
Definition: avfilter.h:257
FF_DISABLE_DEPRECATION_WARNINGS
#define FF_DISABLE_DEPRECATION_WARNINGS
Definition: internal.h:72
AV_PIX_FMT_GBRP
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:165
OVERLAY_FORMAT_GBRP
@ OVERLAY_FORMAT_GBRP
Definition: vf_overlay.h:52
AVFILTER_FLAG_SLICE_THREADS
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
Definition: avfilter.h:150
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
FFFilter::p
AVFilter p
The public AVFilter.
Definition: filters.h:269
AV_PIX_FMT_YUV422P
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:77
OVERLAY_FORMAT_YUV444
@ OVERLAY_FORMAT_YUV444
Definition: vf_overlay.h:49
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
FRAMESYNC_DEFINE_CLASS
FRAMESYNC_DEFINE_CLASS(overlay, OverlayContext, fs)
alpha
static const int16_t alpha[]
Definition: ilbcdata.h:55
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition: opt.h:327
EVAL_MODE_INIT
@ EVAL_MODE_INIT
Definition: vf_overlay.c:78
ff_fill_rgba_map
int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt)
Definition: drawutils.c:79
DEFINE_BLEND_SLICE_YUV
#define DEFINE_BLEND_SLICE_YUV(depth, nbits)
Definition: vf_overlay.c:634
AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL
#define AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL
Same as AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, except that the filter will have its filter_frame() c...
Definition: avfilter.h:188
imgutils.h
timestamp.h
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:482
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
ff_framesync_activate
int ff_framesync_activate(FFFrameSync *fs)
Examine the frames in the filter's input and try to produce output.
Definition: framesync.c:352
avstring.h
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
Definition: opt.h:276
ff_framesync_dualinput_get_writable
int ff_framesync_dualinput_get_writable(FFFrameSync *fs, AVFrame **f0, AVFrame **f1)
Same as ff_framesync_dualinput_get(), but make sure that f0 is writable.
Definition: framesync.c:410
drawutils.h
alpha_pix_fmts
static enum AVPixelFormat alpha_pix_fmts[]
Definition: vf_overlay.c:157
OFFSET
#define OFFSET(x)
Definition: vf_overlay.c:947
VAR_OVERLAY_W
@ VAR_OVERLAY_W
Definition: vf_overlay.h:30
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:299
AVPixFmtDescriptor::log2_chroma_h
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:89
src
#define src
Definition: vp8dsp.c:248
AV_PIX_FMT_YUVA422P
@ AV_PIX_FMT_YUVA422P
planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
Definition: pixfmt.h:173
av_get_pix_fmt_name
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
Definition: pixdesc.c:3090
init
static av_cold int init(AVFilterContext *ctx)
Definition: vf_overlay.c:933