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  "t", ///< timestamp expressed in seconds
59  NULL
60 };
61 
62 #define MAIN 0
63 #define OVERLAY 1
64 
65 #define R 0
66 #define G 1
67 #define B 2
68 #define A 3
69 
70 #define Y 0
71 #define U 1
72 #define V 2
73 
74 enum EvalMode {
78 };
79 
81 {
82  OverlayContext *s = ctx->priv;
83 
84  ff_framesync_uninit(&s->fs);
85  av_expr_free(s->x_pexpr); s->x_pexpr = NULL;
86  av_expr_free(s->y_pexpr); s->y_pexpr = NULL;
87 }
88 
89 static inline int normalize_xy(double d, int chroma_sub)
90 {
91  if (isnan(d))
92  return INT_MAX;
93  return (int)d & ~((1 << chroma_sub) - 1);
94 }
95 
97 {
98  OverlayContext *s = ctx->priv;
99 
100  s->var_values[VAR_X] = av_expr_eval(s->x_pexpr, s->var_values, NULL);
101  s->var_values[VAR_Y] = av_expr_eval(s->y_pexpr, s->var_values, NULL);
102  /* It is necessary if x is expressed from y */
103  s->var_values[VAR_X] = av_expr_eval(s->x_pexpr, s->var_values, NULL);
104  s->x = normalize_xy(s->var_values[VAR_X], s->hsub);
105  s->y = normalize_xy(s->var_values[VAR_Y], s->vsub);
106 }
107 
108 static int set_expr(AVExpr **pexpr, const char *expr, const char *option, void *log_ctx)
109 {
110  int ret;
111  AVExpr *old = NULL;
112 
113  if (*pexpr)
114  old = *pexpr;
115  ret = av_expr_parse(pexpr, expr, var_names,
116  NULL, NULL, NULL, NULL, 0, log_ctx);
117  if (ret < 0) {
118  av_log(log_ctx, AV_LOG_ERROR,
119  "Error when evaluating the expression '%s' for %s\n",
120  expr, option);
121  *pexpr = old;
122  return ret;
123  }
124 
125  av_expr_free(old);
126  return 0;
127 }
128 
129 static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
130  char *res, int res_len, int flags)
131 {
132  OverlayContext *s = ctx->priv;
133  int ret;
134 
135  if (!strcmp(cmd, "x"))
136  ret = set_expr(&s->x_pexpr, args, cmd, ctx);
137  else if (!strcmp(cmd, "y"))
138  ret = set_expr(&s->y_pexpr, args, cmd, ctx);
139  else
140  ret = AVERROR(ENOSYS);
141 
142  if (ret < 0)
143  return ret;
144 
145  if (s->eval_mode == EVAL_MODE_INIT) {
146  eval_expr(ctx);
147  av_log(ctx, AV_LOG_VERBOSE, "x:%f xi:%d y:%f yi:%d\n",
148  s->var_values[VAR_X], s->x,
149  s->var_values[VAR_Y], s->y);
150  }
151  return ret;
152 }
153 
154 static const enum AVPixelFormat alpha_pix_fmts[] = {
159 };
160 
162  AVFilterFormatsConfig **cfg_in,
163  AVFilterFormatsConfig **cfg_out)
164 {
165  const OverlayContext *s = ctx->priv;
166 
167  /* overlay formats contains alpha, for avoiding conversion with alpha information loss */
168  static const enum AVPixelFormat main_pix_fmts_yuv420[] = {
172  };
173  static const enum AVPixelFormat overlay_pix_fmts_yuv420[] = {
175  };
176 
177  static const enum AVPixelFormat main_pix_fmts_yuv420p10[] = {
180  };
181  static const enum AVPixelFormat overlay_pix_fmts_yuv420p10[] = {
183  };
184 
185  static const enum AVPixelFormat main_pix_fmts_yuv422[] = {
187  };
188  static const enum AVPixelFormat overlay_pix_fmts_yuv422[] = {
190  };
191 
192  static const enum AVPixelFormat main_pix_fmts_yuv422p10[] = {
194  };
195  static const enum AVPixelFormat overlay_pix_fmts_yuv422p10[] = {
197  };
198 
199  static const enum AVPixelFormat main_pix_fmts_yuv444[] = {
201  };
202  static const enum AVPixelFormat overlay_pix_fmts_yuv444[] = {
204  };
205 
206  static const enum AVPixelFormat main_pix_fmts_yuv444p10[] = {
208  };
209  static const enum AVPixelFormat overlay_pix_fmts_yuv444p10[] = {
211  };
212 
213  static const enum AVPixelFormat main_pix_fmts_gbrp[] = {
215  };
216  static const enum AVPixelFormat overlay_pix_fmts_gbrp[] = {
218  };
219 
220  static const enum AVPixelFormat main_pix_fmts_rgb[] = {
225  };
226  static const enum AVPixelFormat overlay_pix_fmts_rgb[] = {
230  };
231 
232  const enum AVPixelFormat *main_formats, *overlay_formats;
234  int ret;
235 
236  if (s->alpha_mode != AVALPHA_MODE_UNSPECIFIED) {
238  ret = ff_formats_ref(formats, &cfg_in[OVERLAY]->alpha_modes);
239  if (ret < 0)
240  return ret;
241  }
242 
243  switch (s->format) {
245  main_formats = main_pix_fmts_yuv420;
246  overlay_formats = overlay_pix_fmts_yuv420;
247  break;
249  main_formats = main_pix_fmts_yuv420p10;
250  overlay_formats = overlay_pix_fmts_yuv420p10;
251  break;
253  main_formats = main_pix_fmts_yuv422;
254  overlay_formats = overlay_pix_fmts_yuv422;
255  break;
257  main_formats = main_pix_fmts_yuv422p10;
258  overlay_formats = overlay_pix_fmts_yuv422p10;
259  break;
261  main_formats = main_pix_fmts_yuv444;
262  overlay_formats = overlay_pix_fmts_yuv444;
263  break;
265  main_formats = main_pix_fmts_yuv444p10;
266  overlay_formats = overlay_pix_fmts_yuv444p10;
267  break;
268  case OVERLAY_FORMAT_RGB:
269  main_formats = main_pix_fmts_rgb;
270  overlay_formats = overlay_pix_fmts_rgb;
271  break;
272  case OVERLAY_FORMAT_GBRP:
273  main_formats = main_pix_fmts_gbrp;
274  overlay_formats = overlay_pix_fmts_gbrp;
275  break;
276  case OVERLAY_FORMAT_AUTO:
277  return ff_set_common_formats_from_list2(ctx, cfg_in, cfg_out, alpha_pix_fmts);
278  default:
279  av_assert0(0);
280  }
281 
282  formats = ff_make_format_list(main_formats);
283  if ((ret = ff_formats_ref(formats, &cfg_in[MAIN]->formats)) < 0 ||
284  (ret = ff_formats_ref(formats, &cfg_out[MAIN]->formats)) < 0)
285  return ret;
286 
287  return ff_formats_ref(ff_make_format_list(overlay_formats),
288  &cfg_in[OVERLAY]->formats);
289 }
290 
292 {
293  AVFilterContext *ctx = inlink->dst;
294  OverlayContext *s = inlink->dst->priv;
295  int ret;
296  const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format);
297 
298  av_image_fill_max_pixsteps(s->overlay_pix_step, NULL, pix_desc);
299 
300  /* Finish the configuration by evaluating the expressions
301  now when both inputs are configured. */
302  s->var_values[VAR_MAIN_W ] = s->var_values[VAR_MW] = ctx->inputs[MAIN ]->w;
303  s->var_values[VAR_MAIN_H ] = s->var_values[VAR_MH] = ctx->inputs[MAIN ]->h;
304  s->var_values[VAR_OVERLAY_W] = s->var_values[VAR_OW] = ctx->inputs[OVERLAY]->w;
305  s->var_values[VAR_OVERLAY_H] = s->var_values[VAR_OH] = ctx->inputs[OVERLAY]->h;
306  s->var_values[VAR_HSUB] = 1<<pix_desc->log2_chroma_w;
307  s->var_values[VAR_VSUB] = 1<<pix_desc->log2_chroma_h;
308  s->var_values[VAR_X] = NAN;
309  s->var_values[VAR_Y] = NAN;
310  s->var_values[VAR_N] = 0;
311  s->var_values[VAR_T] = NAN;
312 
313  if ((ret = set_expr(&s->x_pexpr, s->x_expr, "x", ctx)) < 0 ||
314  (ret = set_expr(&s->y_pexpr, s->y_expr, "y", ctx)) < 0)
315  return ret;
316 
317  s->overlay_is_packed_rgb =
318  ff_fill_rgba_map(s->overlay_rgba_map, inlink->format) >= 0;
319  s->overlay_has_alpha = ff_fmt_is_in(inlink->format, alpha_pix_fmts);
320 
321  if (s->eval_mode == EVAL_MODE_INIT) {
322  eval_expr(ctx);
323  av_log(ctx, AV_LOG_VERBOSE, "x:%f xi:%d y:%f yi:%d\n",
324  s->var_values[VAR_X], s->x,
325  s->var_values[VAR_Y], s->y);
326  }
327 
329  "main w:%d h:%d fmt:%s overlay w:%d h:%d fmt:%s\n",
330  ctx->inputs[MAIN]->w, ctx->inputs[MAIN]->h,
331  av_get_pix_fmt_name(ctx->inputs[MAIN]->format),
332  ctx->inputs[OVERLAY]->w, ctx->inputs[OVERLAY]->h,
333  av_get_pix_fmt_name(ctx->inputs[OVERLAY]->format));
334  return 0;
335 }
336 
337 static int config_output(AVFilterLink *outlink)
338 {
339  AVFilterContext *ctx = outlink->src;
340  OverlayContext *s = ctx->priv;
341  int ret;
342 
343  if ((ret = ff_framesync_init_dualinput(&s->fs, ctx)) < 0)
344  return ret;
345 
346  outlink->w = ctx->inputs[MAIN]->w;
347  outlink->h = ctx->inputs[MAIN]->h;
348  outlink->time_base = ctx->inputs[MAIN]->time_base;
349 
350  return ff_framesync_configure(&s->fs);
351 }
352 
353 // divide by 255 and round to nearest
354 // apply a fast variant: (X+127)/255 = ((X+127)*257+257)>>16 = ((X+128)*257)>>16
355 #define FAST_DIV255(x) ((((x) + 128) * 257) >> 16)
356 
357 // calculate the unpremultiplied alpha, applying the general equation:
358 // alpha = alpha_overlay / ( (alpha_main + alpha_overlay) - (alpha_main * alpha_overlay) )
359 // (((x) << 16) - ((x) << 9) + (x)) is a faster version of: 255 * 255 * x
360 // ((((x) + (y)) << 8) - ((x) + (y)) - (y) * (x)) is a faster version of: 255 * (x + y)
361 // this is only needed when blending onto straight alpha main images
362 #define UNPREMULTIPLY_ALPHA(x, y) ((((x) << 16) - ((x) << 9) + (x)) / ((((x) + (y)) << 8) - ((x) + (y)) - (y) * (x)))
363 
364 #define PTR_ADD(TYPE, ptr, byte_addend) ((TYPE*)((uint8_t*)ptr + (byte_addend)))
365 #define CPTR_ADD(TYPE, ptr, byte_addend) ((const TYPE*)((const uint8_t*)ptr + (byte_addend)))
366 
367 /**
368  * Blend image in src to destination buffer dst at position (x, y).
369  */
370 
372  AVFrame *dst, const AVFrame *src,
373  int main_has_alpha, int x, int y,
374  int overlay_straight, int main_straight,
375  int jobnr, int nb_jobs)
376 {
377  OverlayContext *s = ctx->priv;
378  int i, imax, j, jmax;
379  const int src_w = src->width;
380  const int src_h = src->height;
381  const int dst_w = dst->width;
382  const int dst_h = dst->height;
383  uint8_t alpha; ///< the amount of overlay to blend on to main
384  const int dr = s->main_rgba_map[R];
385  const int dg = s->main_rgba_map[G];
386  const int db = s->main_rgba_map[B];
387  const int da = s->main_rgba_map[A];
388  const int dstep = s->main_pix_step[0];
389  const int sr = s->overlay_rgba_map[R];
390  const int sg = s->overlay_rgba_map[G];
391  const int sb = s->overlay_rgba_map[B];
392  const int sa = s->overlay_rgba_map[A];
393  const int sstep = s->overlay_pix_step[0];
394  int slice_start, slice_end;
395  uint8_t *S, *sp, *d, *dp;
396 
397  i = FFMAX(-y, 0);
398  imax = FFMIN3(-y + dst_h, FFMIN(src_h, dst_h), y + src_h);
399 
400  slice_start = i + (imax * jobnr) / nb_jobs;
401  slice_end = i + (imax * (jobnr+1)) / nb_jobs;
402 
403  sp = src->data[0] + (slice_start) * src->linesize[0];
404  dp = dst->data[0] + (y + slice_start) * dst->linesize[0];
405 
406  for (i = slice_start; i < slice_end; i++) {
407  j = FFMAX(-x, 0);
408  S = sp + j * sstep;
409  d = dp + (x+j) * dstep;
410 
411  for (jmax = FFMIN(-x + dst_w, src_w); j < jmax; j++) {
412  alpha = S[sa];
413 
414  // if the main channel has an alpha channel, alpha has to be calculated
415  // to create an un-premultiplied (straight) alpha value
416  if (main_straight && alpha != 0 && alpha != 255) {
417  uint8_t alpha_d = d[da];
418  alpha = UNPREMULTIPLY_ALPHA(alpha, alpha_d);
419  }
420 
421  switch (alpha) {
422  case 0:
423  break;
424  case 255:
425  d[dr] = S[sr];
426  d[dg] = S[sg];
427  d[db] = S[sb];
428  break;
429  default:
430  // main_value = main_value * (1 - alpha) + overlay_value * alpha
431  // since alpha is in the range 0-255, the result must divided by 255
432  d[dr] = overlay_straight ? FAST_DIV255(d[dr] * (255 - alpha) + S[sr] * alpha) :
433  FFMIN(FAST_DIV255(d[dr] * (255 - alpha)) + S[sr], 255);
434  d[dg] = overlay_straight ? FAST_DIV255(d[dg] * (255 - alpha) + S[sg] * alpha) :
435  FFMIN(FAST_DIV255(d[dg] * (255 - alpha)) + S[sg], 255);
436  d[db] = overlay_straight ? FAST_DIV255(d[db] * (255 - alpha) + S[sb] * alpha) :
437  FFMIN(FAST_DIV255(d[db] * (255 - alpha)) + S[sb], 255);
438  }
439  if (main_has_alpha) {
440  switch (alpha) {
441  case 0:
442  break;
443  case 255:
444  d[da] = S[sa];
445  break;
446  default:
447  // apply alpha compositing: main_alpha += (1-main_alpha) * overlay_alpha
448  d[da] += FAST_DIV255((255 - d[da]) * S[sa]);
449  }
450  }
451  d += dstep;
452  S += sstep;
453  }
454  dp += dst->linesize[0];
455  sp += src->linesize[0];
456  }
457 }
458 
459 #define DEFINE_BLEND_PLANE(depth, T, nbits) \
460 static av_always_inline void blend_plane_##depth##_##nbits##bits(AVFilterContext *ctx, \
461  AVFrame *dst, const AVFrame *src, \
462  int src_w, int src_h, \
463  int dst_w, int dst_h, \
464  int i, int hsub, int vsub, \
465  int x, int y, \
466  int main_straight, \
467  int dst_plane, \
468  int dst_offset, \
469  int dst_step, \
470  int overlay_straight, \
471  int yuv, \
472  int jobnr, \
473  int nb_jobs) \
474 { \
475  OverlayContext *octx = ctx->priv; \
476  int src_wp = AV_CEIL_RSHIFT(src_w, hsub); \
477  int src_hp = AV_CEIL_RSHIFT(src_h, vsub); \
478  int dst_wp = AV_CEIL_RSHIFT(dst_w, hsub); \
479  int dst_hp = AV_CEIL_RSHIFT(dst_h, vsub); \
480  int yp = y>>vsub; \
481  int xp = x>>hsub; \
482  const T max = (1 << nbits) - 1; \
483  const T mid = (1 << (nbits - 1)); \
484  \
485  const int jmin = FFMAX(-yp, 0), jmax = FFMIN3(-yp + dst_hp, FFMIN(src_hp, dst_hp), yp + src_hp); \
486  const int kmin = FFMAX(-xp, 0), kmax = FFMIN(-xp + dst_wp, src_wp); \
487  const int slice_start = jmin + (jmax * jobnr) / nb_jobs; \
488  const int slice_end = jmin + (jmax * (jobnr + 1)) / nb_jobs; \
489  \
490  const uint8_t *sp = src->data[i] + (slice_start) * src->linesize[i]; \
491  uint8_t *dp = dst->data[dst_plane] \
492  + (yp + slice_start) * dst->linesize[dst_plane] \
493  + dst_offset; \
494  const uint8_t *ap = src->data[3] + (slice_start << vsub) * src->linesize[3]; \
495  const uint8_t *dap = main_straight ? dst->data[3] + ((yp + slice_start) << vsub) * dst->linesize[3] : NULL; \
496  \
497  for (int j = slice_start; j < slice_end; ++j) { \
498  int k = kmin; \
499  const T *s = (const T *)sp + k; \
500  const T *a = (const T *)ap + (k << hsub); \
501  const T *da = main_straight ? (T *)dap + ((xp + k) << hsub) : NULL; \
502  T *d = (T *)(dp + (xp + k) * dst_step); \
503  \
504  if (nbits == 8 && ((vsub && j+1 < src_hp) || !vsub) && octx->blend_row[i]) { \
505  int c = octx->blend_row[i]((uint8_t*)d, (uint8_t*)da, (uint8_t*)s, \
506  (uint8_t*)a, kmax - k, src->linesize[3]); \
507  \
508  s += c; \
509  d = PTR_ADD(T, d, dst_step * c); \
510  if (main_straight) \
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  const T *next_line = CPTR_ADD(T, a, src->linesize[3]); \
521  alpha = (a[0] + next_line[0] + \
522  a[1] + next_line[1]) >> 2; \
523  } else if (hsub || vsub) { \
524  alpha_h = hsub && k+1 < src_wp ? \
525  (a[0] + a[1]) >> 1 : a[0]; \
526  alpha_v = vsub && j+1 < src_hp ? \
527  (a[0] + *CPTR_ADD(T, a, src->linesize[3])) >> 1 : a[0]; \
528  alpha = (alpha_v + alpha_h) >> 1; \
529  } else \
530  alpha = a[0]; \
531  /* if the main channel has an alpha channel, alpha has to be calculated */ \
532  /* to create an un-premultiplied (straight) alpha value */ \
533  if (main_straight && alpha != 0 && alpha != max) { \
534  /* average alpha for color components, improve quality */ \
535  uint8_t alpha_d; \
536  if (hsub && vsub && j+1 < src_hp && k+1 < src_wp) { \
537  const T *next_line = CPTR_ADD(T, da, dst->linesize[3]); \
538  alpha_d = (da[0] + next_line[0] + \
539  da[1] + next_line[1]) >> 2; \
540  } else if (hsub || vsub) { \
541  alpha_h = hsub && k+1 < src_wp ? \
542  (da[0] + da[1]) >> 1 : da[0]; \
543  alpha_v = vsub && j+1 < src_hp ? \
544  (da[0] + *CPTR_ADD(T, da, dst->linesize[3])) >> 1 : da[0]; \
545  alpha_d = (alpha_v + alpha_h) >> 1; \
546  } else \
547  alpha_d = da[0]; \
548  alpha = UNPREMULTIPLY_ALPHA(alpha, alpha_d); \
549  } \
550  if (overlay_straight) { \
551  if (nbits > 8) \
552  *d = (*d * (max - alpha) + *s * alpha) / max; \
553  else \
554  *d = FAST_DIV255(*d * (255 - alpha) + *s * alpha); \
555  } else { \
556  if (nbits > 8) { \
557  if (i && yuv) \
558  *d = av_clip((*d * (max - alpha) + *s * alpha) / max + *s - mid, -mid, mid) + mid; \
559  else \
560  *d = av_clip_uintp2((*d * (max - alpha) + *s * alpha) / max + *s - (16<<(nbits-8)),\
561  nbits);\
562  } else { \
563  if (i && yuv) \
564  *d = av_clip(FAST_DIV255((*d - mid) * (max - alpha)) + *s - mid, -mid, mid) + mid; \
565  else \
566  *d = av_clip_uint8(FAST_DIV255(*d * (255 - alpha)) + *s - 16); \
567  } \
568  } \
569  s++; \
570  d = PTR_ADD(T, d, dst_step); \
571  if (main_straight) \
572  da += 1 << hsub; \
573  a += 1 << hsub; \
574  } \
575  dp += dst->linesize[dst_plane]; \
576  sp += src->linesize[i]; \
577  ap += (1 << vsub) * src->linesize[3]; \
578  if (main_straight) \
579  dap += (1 << vsub) * dst->linesize[3]; \
580  } \
581 }
582 DEFINE_BLEND_PLANE(8, uint8_t, 8)
583 DEFINE_BLEND_PLANE(16, uint16_t, 10)
584 
585 #define DEFINE_ALPHA_COMPOSITE(depth, T, nbits) \
586 static inline void alpha_composite_##depth##_##nbits##bits(const AVFrame *src, const AVFrame *dst, \
587  int src_w, int src_h, \
588  int dst_w, int dst_h, \
589  int x, int y, int main_straight, \
590  int jobnr, int nb_jobs) \
591 { \
592  T alpha; /* the amount of overlay to blend on to main */ \
593  const T max = (1 << nbits) - 1; \
594  \
595  const int imin = FFMAX(-y, 0), imax = FFMIN3(-y + dst_h, FFMIN(src_h, dst_h), y + src_h); \
596  const int jmin = FFMAX(-x, 0), jmax = FFMIN(-x + dst_w, src_w); \
597  const int slice_start = imin + ( imax * jobnr) / nb_jobs; \
598  const int slice_end = imin + ((imax * (jobnr + 1)) / nb_jobs); \
599  \
600  const uint8_t *sa = src->data[3] + (slice_start) * src->linesize[3]; \
601  uint8_t *da = dst->data[3] + (y + slice_start) * dst->linesize[3]; \
602  \
603  for (int i = slice_start; i < slice_end; ++i) { \
604  const T *s = (const T *)sa + jmin; \
605  T *d = (T *)da + x + jmin; \
606  \
607  for (int j = jmin; j < jmax; ++j) { \
608  alpha = *s; \
609  if (main_straight && alpha != 0 && alpha != max) { \
610  uint8_t alpha_d = *d; \
611  alpha = UNPREMULTIPLY_ALPHA(alpha, alpha_d); \
612  } \
613  if (alpha == max) \
614  *d = *s; \
615  else if (alpha > 0) { \
616  /* apply alpha compositing: main_alpha += (1-main_alpha) * overlay_alpha */ \
617  if (nbits > 8) \
618  *d += (max - *d) * *s / max; \
619  else \
620  *d += FAST_DIV255((max - *d) * *s); \
621  } \
622  d += 1; \
623  s += 1; \
624  } \
625  da += dst->linesize[3]; \
626  sa += src->linesize[3]; \
627  } \
628 }
629 DEFINE_ALPHA_COMPOSITE(8, uint8_t, 8)
630 DEFINE_ALPHA_COMPOSITE(16, uint16_t, 10)
631 
632 #define DEFINE_BLEND_SLICE_YUV(depth, nbits) \
633 static av_always_inline void blend_slice_yuv_##depth##_##nbits##bits(AVFilterContext *ctx, \
634  AVFrame *dst, const AVFrame *src, \
635  int hsub, int vsub, \
636  int main_straight, \
637  int x, int y, \
638  int overlay_straight, \
639  int jobnr, int nb_jobs) \
640 { \
641  OverlayContext *s = ctx->priv; \
642  const int src_w = src->width; \
643  const int src_h = src->height; \
644  const int dst_w = dst->width; \
645  const int dst_h = dst->height; \
646  \
647  blend_plane_##depth##_##nbits##bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 0, 0, 0, \
648  x, y, main_straight, s->main_desc->comp[0].plane, s->main_desc->comp[0].offset, \
649  s->main_desc->comp[0].step, overlay_straight, 1, jobnr, nb_jobs); \
650  blend_plane_##depth##_##nbits##bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 1, hsub, vsub, \
651  x, y, main_straight, s->main_desc->comp[1].plane, s->main_desc->comp[1].offset, \
652  s->main_desc->comp[1].step, overlay_straight, 1, jobnr, nb_jobs); \
653  blend_plane_##depth##_##nbits##bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 2, hsub, vsub, \
654  x, y, main_straight, s->main_desc->comp[2].plane, s->main_desc->comp[2].offset, \
655  s->main_desc->comp[2].step, overlay_straight, 1, jobnr, nb_jobs); \
656  \
657  if (s->main_has_alpha) \
658  alpha_composite_##depth##_##nbits##bits(src, dst, src_w, src_h, dst_w, dst_h, x, y, main_straight, \
659  jobnr, nb_jobs); \
660 }
663 
665  AVFrame *dst, const AVFrame *src,
666  int hsub, int vsub,
667  int main_straight,
668  int x, int y,
669  int overlay_straight,
670  int jobnr,
671  int nb_jobs)
672 {
673  OverlayContext *s = ctx->priv;
674  const int src_w = src->width;
675  const int src_h = src->height;
676  const int dst_w = dst->width;
677  const int dst_h = dst->height;
678 
679  blend_plane_8_8bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 0, 0, 0, x, y, main_straight,
680  s->main_desc->comp[1].plane, s->main_desc->comp[1].offset, s->main_desc->comp[1].step, overlay_straight, 0,
681  jobnr, nb_jobs);
682  blend_plane_8_8bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 1, hsub, vsub, x, y, main_straight,
683  s->main_desc->comp[2].plane, s->main_desc->comp[2].offset, s->main_desc->comp[2].step, overlay_straight, 0,
684  jobnr, nb_jobs);
685  blend_plane_8_8bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 2, hsub, vsub, x, y, main_straight,
686  s->main_desc->comp[0].plane, s->main_desc->comp[0].offset, s->main_desc->comp[0].step, overlay_straight, 0,
687  jobnr, nb_jobs);
688 
689  if (s->main_has_alpha)
690  alpha_composite_8_8bits(src, dst, src_w, src_h, dst_w, dst_h, x, y, main_straight, jobnr, nb_jobs);
691 }
692 
693 #define DEFINE_BLEND_SLICE_PLANAR_FMT_(format_, blend_slice_fn_suffix_, hsub_, vsub_, main_straight_, overlay_straight_) \
694 static int blend_slice_##format_(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) \
695 { \
696  OverlayContext *s = ctx->priv; \
697  ThreadData *td = arg; \
698  blend_slice_##blend_slice_fn_suffix_(ctx, td->dst, td->src, \
699  hsub_, vsub_, main_straight_, \
700  s->x, s->y, overlay_straight_, \
701  jobnr, nb_jobs); \
702  return 0; \
703 }
704 
705 #define DEFINE_BLEND_SLICE_PLANAR_FMT(format_, blend_slice_fn_suffix_, hsub_, vsub_) \
706 DEFINE_BLEND_SLICE_PLANAR_FMT_(format_ ## _ss, blend_slice_fn_suffix_, hsub_, vsub_, 1, 1) \
707 DEFINE_BLEND_SLICE_PLANAR_FMT_(format_ ## _sp, blend_slice_fn_suffix_, hsub_, vsub_, 1, 0) \
708 DEFINE_BLEND_SLICE_PLANAR_FMT_(format_ ## _ps, blend_slice_fn_suffix_, hsub_, vsub_, 0, 1) \
709 DEFINE_BLEND_SLICE_PLANAR_FMT_(format_ ## _pp, blend_slice_fn_suffix_, hsub_, vsub_, 0, 0)
710 
711 // FMT FN H V
712 DEFINE_BLEND_SLICE_PLANAR_FMT(yuv420, yuv_8_8bits, 1, 1)
713 DEFINE_BLEND_SLICE_PLANAR_FMT(yuv420p10, yuv_16_10bits, 1, 1)
714 DEFINE_BLEND_SLICE_PLANAR_FMT(yuv422p10, yuv_16_10bits, 1, 0)
715 DEFINE_BLEND_SLICE_PLANAR_FMT(yuv422, yuv_8_8bits, 1, 0)
716 DEFINE_BLEND_SLICE_PLANAR_FMT(yuv444, yuv_8_8bits, 0, 0)
717 DEFINE_BLEND_SLICE_PLANAR_FMT(yuv444p10, yuv_16_10bits, 0, 0)
718 DEFINE_BLEND_SLICE_PLANAR_FMT(gbrp, planar_rgb, 0, 0)
719 
720 #define DEFINE_BLEND_SLICE_PACKED_FMT(format_, blend_slice_fn_suffix_, main_has_alpha_, main_straight_, overlay_straight_) \
721 static int blend_slice_##format_(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) \
722 { \
723  OverlayContext *s = ctx->priv; \
724  ThreadData *td = arg; \
725  blend_slice_packed_##blend_slice_fn_suffix_(ctx, td->dst, td->src, \
726  main_has_alpha_, \
727  s->x, s->y, \
728  overlay_straight_, \
729  main_straight_, \
730  jobnr, nb_jobs); \
731  return 0; \
732 }
733 
734 // FMT FN A MS OS
736 DEFINE_BLEND_SLICE_PACKED_FMT(rgb_pm, rgb, 0, 0, 0)
737 DEFINE_BLEND_SLICE_PACKED_FMT(rgba_ss, rgb, 1, 1, 1)
738 DEFINE_BLEND_SLICE_PACKED_FMT(rgba_sp, rgb, 1, 1, 0)
739 DEFINE_BLEND_SLICE_PACKED_FMT(rgba_ps, rgb, 1, 0, 1)
740 DEFINE_BLEND_SLICE_PACKED_FMT(rgba_pp, rgb, 1, 0, 0)
741 
743 {
744  OverlayContext *s = inlink->dst->priv;
745  const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format);
746 
747  av_image_fill_max_pixsteps(s->main_pix_step, NULL, pix_desc);
748 
749  s->hsub = pix_desc->log2_chroma_w;
750  s->vsub = pix_desc->log2_chroma_h;
751 
752  s->main_desc = pix_desc;
753 
754  s->main_is_packed_rgb =
755  ff_fill_rgba_map(s->main_rgba_map, inlink->format) >= 0;
756  s->main_has_alpha = ff_fmt_is_in(inlink->format, alpha_pix_fmts);
757  return 0;
758 }
759 
761 {
762  OverlayContext *s = ctx->priv;
763  const AVFilterLink *main = ctx->inputs[MAIN];
764  const AVFilterLink *overlay = ctx->inputs[OVERLAY];
765  const int main_straight = s->main_has_alpha && main->alpha_mode != AVALPHA_MODE_PREMULTIPLIED;
766  const int overlay_straight = overlay->alpha_mode != AVALPHA_MODE_PREMULTIPLIED;
767 
768  #define ASSIGN_BLEND_SLICE(format_) \
769  do { \
770  s->blend_slice = main_straight ? (overlay_straight ? format_##_ss : format_##_sp) \
771  : (overlay_straight ? format_##_ps : format_##_pp); \
772  } while (0)
773 
774  switch (s->format) {
776  ASSIGN_BLEND_SLICE(blend_slice_yuv420);
777  break;
779  ASSIGN_BLEND_SLICE(blend_slice_yuv420p10);
780  break;
782  ASSIGN_BLEND_SLICE(blend_slice_yuv422);
783  break;
785  ASSIGN_BLEND_SLICE(blend_slice_yuv422p10);
786  break;
788  ASSIGN_BLEND_SLICE(blend_slice_yuv444);
789  break;
791  ASSIGN_BLEND_SLICE(blend_slice_yuv444p10);
792  break;
793  case OVERLAY_FORMAT_RGB:
794  if (s->main_has_alpha)
795  ASSIGN_BLEND_SLICE(blend_slice_rgba);
796  else
797  s->blend_slice = overlay_straight ? blend_slice_rgb : blend_slice_rgb_pm;
798  break;
799  case OVERLAY_FORMAT_GBRP:
800  ASSIGN_BLEND_SLICE(blend_slice_gbrp);
801  break;
802  case OVERLAY_FORMAT_AUTO:
803  switch (main->format) {
804  case AV_PIX_FMT_YUVA420P:
805  ASSIGN_BLEND_SLICE(blend_slice_yuv420);
806  break;
808  ASSIGN_BLEND_SLICE(blend_slice_yuv420p10);
809  break;
810  case AV_PIX_FMT_YUVA422P:
811  ASSIGN_BLEND_SLICE(blend_slice_yuv422);
812  break;
814  ASSIGN_BLEND_SLICE(blend_slice_yuv422p10);
815  break;
816  case AV_PIX_FMT_YUVA444P:
817  ASSIGN_BLEND_SLICE(blend_slice_yuv444);
818  break;
820  ASSIGN_BLEND_SLICE(blend_slice_yuv444p10);
821  break;
822  case AV_PIX_FMT_ARGB:
823  case AV_PIX_FMT_RGBA:
824  case AV_PIX_FMT_BGRA:
825  case AV_PIX_FMT_ABGR:
826  ASSIGN_BLEND_SLICE(blend_slice_rgba);
827  break;
828  case AV_PIX_FMT_GBRAP:
829  ASSIGN_BLEND_SLICE(blend_slice_gbrp);
830  break;
831  default:
832  av_unreachable("Invalid pixel format for overlay");
833  break;
834  }
835  break;
836  }
837 
838 #if ARCH_X86
840 #endif
841 
842  return 0;
843 }
844 
845 static int do_blend(FFFrameSync *fs)
846 {
847  AVFilterContext *ctx = fs->parent;
848  AVFrame *mainpic, *second;
849  OverlayContext *s = ctx->priv;
850  AVFilterLink *inlink = ctx->inputs[0];
852  int ret;
853 
854  ret = ff_framesync_dualinput_get_writable(fs, &mainpic, &second);
855  if (ret < 0)
856  return ret;
857  if (!second)
858  return ff_filter_frame(ctx->outputs[0], mainpic);
859 
860  if (s->eval_mode == EVAL_MODE_FRAME) {
861 
862  s->var_values[VAR_N] = inl->frame_count_out;
863  s->var_values[VAR_T] = mainpic->pts == AV_NOPTS_VALUE ?
864  NAN : mainpic->pts * av_q2d(inlink->time_base);
865 
866  s->var_values[VAR_OVERLAY_W] = s->var_values[VAR_OW] = second->width;
867  s->var_values[VAR_OVERLAY_H] = s->var_values[VAR_OH] = second->height;
868  s->var_values[VAR_MAIN_W ] = s->var_values[VAR_MW] = mainpic->width;
869  s->var_values[VAR_MAIN_H ] = s->var_values[VAR_MH] = mainpic->height;
870 
871  eval_expr(ctx);
872  av_log(ctx, AV_LOG_DEBUG, "n:%f t:%f x:%f xi:%d y:%f yi:%d\n",
873  s->var_values[VAR_N], s->var_values[VAR_T],
874  s->var_values[VAR_X], s->x,
875  s->var_values[VAR_Y], s->y);
876  }
877 
878  if (s->x < mainpic->width && s->x + second->width >= 0 &&
879  s->y < mainpic->height && s->y + second->height >= 0) {
880  ThreadData td;
881 
883 
884  td.dst = mainpic;
885  td.src = second;
886  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)),
888  }
889  return ff_filter_frame(ctx->outputs[0], mainpic);
890 }
891 
893 {
894  OverlayContext *s = ctx->priv;
895 
896  s->fs.on_event = do_blend;
897  return 0;
898 }
899 
901 {
902  OverlayContext *s = ctx->priv;
903  return ff_framesync_activate(&s->fs);
904 }
905 
906 #define OFFSET(x) offsetof(OverlayContext, x)
907 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
908 #define TFLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
909 
910 static const AVOption overlay_options[] = {
911  { "x", "set the x expression", OFFSET(x_expr), AV_OPT_TYPE_STRING, {.str = "0"}, 0, 0, TFLAGS },
912  { "y", "set the y expression", OFFSET(y_expr), AV_OPT_TYPE_STRING, {.str = "0"}, 0, 0, TFLAGS },
913  { "eof_action", "Action to take when encountering EOF from secondary input ",
914  OFFSET(fs.opt_eof_action), AV_OPT_TYPE_INT, { .i64 = EOF_ACTION_REPEAT },
915  EOF_ACTION_REPEAT, EOF_ACTION_PASS, .flags = FLAGS, .unit = "eof_action" },
916  { "repeat", "Repeat the previous frame.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_REPEAT }, .flags = FLAGS, .unit = "eof_action" },
917  { "endall", "End both streams.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_ENDALL }, .flags = FLAGS, .unit = "eof_action" },
918  { "pass", "Pass through the main input.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_PASS }, .flags = FLAGS, .unit = "eof_action" },
919  { "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" },
920  { "init", "eval expressions once during initialization", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_INIT}, .flags = FLAGS, .unit = "eval" },
921  { "frame", "eval expressions per-frame", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_FRAME}, .flags = FLAGS, .unit = "eval" },
922  { "shortest", "force termination when the shortest input terminates", OFFSET(fs.opt_shortest), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS },
923  { "format", "set output format", OFFSET(format), AV_OPT_TYPE_INT, {.i64=OVERLAY_FORMAT_YUV420}, 0, OVERLAY_FORMAT_NB-1, FLAGS, .unit = "format" },
924  { "yuv420", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV420}, .flags = FLAGS, .unit = "format" },
925  { "yuv420p10", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV420P10}, .flags = FLAGS, .unit = "format" },
926  { "yuv422", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV422}, .flags = FLAGS, .unit = "format" },
927  { "yuv422p10", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV422P10}, .flags = FLAGS, .unit = "format" },
928  { "yuv444", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV444}, .flags = FLAGS, .unit = "format" },
929  { "yuv444p10", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV444P10}, .flags = FLAGS, .unit = "format" },
930  { "rgb", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_RGB}, .flags = FLAGS, .unit = "format" },
931  { "gbrp", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_GBRP}, .flags = FLAGS, .unit = "format" },
932  { "auto", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_AUTO}, .flags = FLAGS, .unit = "format" },
933  { "repeatlast", "repeat overlay of the last overlay frame", OFFSET(fs.opt_repeatlast), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGS },
934  { "alpha", "alpha format", OFFSET(alpha_mode), AV_OPT_TYPE_INT, {.i64=AVALPHA_MODE_UNSPECIFIED}, 0, AVALPHA_MODE_NB-1, FLAGS, .unit = "alpha_mode" },
935  { "auto", "", 0, AV_OPT_TYPE_CONST, {.i64=AVALPHA_MODE_UNSPECIFIED}, .flags = FLAGS, .unit = "alpha_mode" },
936  { "unknown", "", 0, AV_OPT_TYPE_CONST, {.i64=AVALPHA_MODE_UNSPECIFIED}, .flags = FLAGS, .unit = "alpha_mode" },
937  { "straight", "", 0, AV_OPT_TYPE_CONST, {.i64=AVALPHA_MODE_STRAIGHT}, .flags = FLAGS, .unit = "alpha_mode" },
938  { "premultiplied", "", 0, AV_OPT_TYPE_CONST, {.i64=AVALPHA_MODE_PREMULTIPLIED}, .flags = FLAGS, .unit = "alpha_mode" },
939  { NULL }
940 };
941 
943 
945  {
946  .name = "main",
947  .type = AVMEDIA_TYPE_VIDEO,
948  .config_props = config_input_main,
949  },
950  {
951  .name = "overlay",
952  .type = AVMEDIA_TYPE_VIDEO,
953  .config_props = config_input_overlay,
954  },
955 };
956 
958  {
959  .name = "default",
960  .type = AVMEDIA_TYPE_VIDEO,
961  .config_props = config_output,
962  },
963 };
964 
966  .p.name = "overlay",
967  .p.description = NULL_IF_CONFIG_SMALL("Overlay a video source on top of the input."),
968  .p.priv_class = &overlay_class,
971  .preinit = overlay_framesync_preinit,
972  .init = init,
973  .uninit = uninit,
974  .priv_size = sizeof(OverlayContext),
975  .activate = activate,
980 };
flags
const SwsFlags flags[]
Definition: swscale.c:61
formats
formats
Definition: signature.h:47
VAR_MAIN_H
@ VAR_MAIN_H
Definition: vf_drawtext.c:129
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
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
AVALPHA_MODE_STRAIGHT
@ AVALPHA_MODE_STRAIGHT
Alpha channel is independent of color values.
Definition: pixfmt.h:803
AVALPHA_MODE_PREMULTIPLIED
@ AVALPHA_MODE_PREMULTIPLIED
Alpha channel is multiplied into color values.
Definition: pixfmt.h:802
set_expr
static int set_expr(AVExpr **pexpr, const char *expr, const char *option, void *log_ctx)
Definition: vf_overlay.c:108
OVERLAY
#define OVERLAY
Definition: vf_overlay.c:63
ff_make_format_list
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:451
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:1067
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3447
avfilter_vf_overlay_outputs
static const AVFilterPad avfilter_vf_overlay_outputs[]
Definition: vf_overlay.c:957
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:263
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:427
pixdesc.h
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:529
AVFrame::width
int width
Definition: frame.h:499
do_blend
static int do_blend(FFFrameSync *fs)
Definition: vf_overlay.c:845
ASSIGN_BLEND_SLICE
#define ASSIGN_BLEND_SLICE(format_)
AV_PIX_FMT_YUVA420P10
#define AV_PIX_FMT_YUVA420P10
Definition: pixfmt.h:590
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:161
AV_PIX_FMT_YUV420P10
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:539
VAR_HSUB
@ VAR_HSUB
Definition: boxblur.c:41
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:226
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:220
FFFrameSync
Frame sync structure.
Definition: framesync.h:168
video.h
VAR_MAIN_W
@ VAR_MAIN_W
Definition: vf_drawtext.c:130
AV_PIX_FMT_YUVA422P10
#define AV_PIX_FMT_YUVA422P10
Definition: pixfmt.h:591
ff_make_formats_list_singleton
AVFilterFormats * ff_make_formats_list_singleton(int fmt)
Equivalent to ff_make_format_list({const int[]}{ fmt, -1 })
Definition: formats.c:545
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:48
slice_end
static int slice_end(AVCodecContext *avctx, AVFrame *pict, int *got_output)
Handle slice ends.
Definition: mpeg12dec.c:1688
AV_PIX_FMT_GBRAP
@ AV_PIX_FMT_GBRAP
planar GBRA 4:4:4:4 32bpp
Definition: pixfmt.h:212
DEFINE_ALPHA_COMPOSITE
#define DEFINE_ALPHA_COMPOSITE(depth, T, nbits)
Definition: vf_overlay.c:585
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 overlay_straight, int main_straight, int jobnr, int nb_jobs)
Blend image in src to destination buffer dst at position (x, y).
Definition: vf_overlay.c:371
FAST_DIV255
#define FAST_DIV255(x)
Definition: vf_overlay.c:355
OVERLAY_FORMAT_YUV422P10
@ OVERLAY_FORMAT_YUV422P10
Definition: vf_overlay.h:45
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:65
AVFilterPad
A filter pad used for either input or output.
Definition: filters.h:39
AV_PIX_FMT_YUV444P10
#define AV_PIX_FMT_YUV444P10
Definition: pixfmt.h:542
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
config_input_main
static int config_input_main(AVFilterLink *inlink)
Definition: vf_overlay.c:742
av_cold
#define av_cold
Definition: attributes.h:90
main
int main
Definition: dovi_rpuenc.c:38
FFFilter
Definition: filters.h:266
EVAL_MODE_FRAME
@ EVAL_MODE_FRAME
Definition: vf_overlay.c:76
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:44
ff_formats_ref
int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
Add *ref as a new reference to formats.
Definition: formats.c:705
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:41
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:231
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:362
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:422
vf_overlay.h
B
#define B
Definition: vf_overlay.c:67
VAR_N
@ VAR_N
Definition: noise.c:47
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:96
EOF_ACTION_PASS
@ EOF_ACTION_PASS
Definition: framesync.h:29
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: filters.h:264
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:314
ThreadData::dst
AVFrame * dst
Definition: vf_blend.c:58
config_input_overlay
static int config_input_overlay(AVFilterLink *inlink)
Definition: vf_overlay.c:291
NULL
#define NULL
Definition: coverity.c:32
format
New swscale design to change SwsGraph is what coordinates multiple passes These can include cascaded scaling error diffusion and so on Or we could have separate passes for the vertical and horizontal scaling In between each SwsPass lies a fully allocated image buffer Graph passes may have different levels of e g we can have a single threaded error diffusion pass following a multi threaded scaling pass SwsGraph is internally recreated whenever the image format
Definition: swscale-v2.txt:14
EVAL_MODE_NB
@ EVAL_MODE_NB
Definition: vf_overlay.c:77
fs
#define fs(width, name, subs,...)
Definition: cbs_vp9.c:200
ThreadData::src
const uint8_t * src
Definition: vf_bm3d.c:54
av_unreachable
#define av_unreachable(msg)
Asserts that are used as compiler optimization hints depending upon ASSERT_LEVEL and NBDEBUG.
Definition: avassert.h:108
isnan
#define isnan(x)
Definition: libm.h:342
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: vf_overlay.c:80
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
DEFINE_BLEND_PLANE
#define DEFINE_BLEND_PLANE(depth, T, nbits)
Definition: vf_overlay.c:459
OverlayContext
Definition: vf_overlay.h:54
VAR_Y
@ VAR_Y
Definition: vf_blend.c:54
AV_PIX_FMT_YUV422P10
#define AV_PIX_FMT_YUV422P10
Definition: pixfmt.h:540
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:121
avfilter_vf_overlay_inputs
static const AVFilterPad avfilter_vf_overlay_inputs[]
Definition: vf_overlay.c:944
ff_filter_link
static FilterLink * ff_filter_link(AVFilterLink *link)
Definition: filters.h:198
TFLAGS
#define TFLAGS
Definition: vf_overlay.c:908
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:68
overlay_options
static const AVOption overlay_options[]
Definition: vf_overlay.c:910
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:51
OVERLAY_FORMAT_YUV420P10
@ OVERLAY_FORMAT_YUV420P10
Definition: vf_overlay.h:43
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
OVERLAY_FORMAT_YUV420
@ OVERLAY_FORMAT_YUV420
Definition: vf_overlay.h:42
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:247
VAR_MH
@ VAR_MH
Definition: vf_overlay.h:29
AVALPHA_MODE_NB
@ AVALPHA_MODE_NB
Not part of ABI.
Definition: pixfmt.h:804
config_output
static int config_output(AVFilterLink *outlink)
Definition: vf_overlay.c:337
ff_vf_overlay
const FFFilter ff_vf_overlay
Definition: vf_overlay.c:965
OVERLAY_FORMAT_YUV444P10
@ OVERLAY_FORMAT_YUV444P10
Definition: vf_overlay.h:47
DEFINE_BLEND_SLICE_PLANAR_FMT
#define DEFINE_BLEND_SLICE_PLANAR_FMT(format_, blend_slice_fn_suffix_, hsub_, vsub_)
Definition: vf_overlay.c:705
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:592
OVERLAY_FORMAT_AUTO
@ OVERLAY_FORMAT_AUTO
Definition: vf_overlay.h:50
AV_PIX_FMT_ARGB
@ AV_PIX_FMT_ARGB
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition: pixfmt.h:99
FLAGS
#define FLAGS
Definition: vf_overlay.c:907
VAR_X
@ VAR_X
Definition: vf_blend.c:54
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
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:845
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:240
av_always_inline
#define av_always_inline
Definition: attributes.h:49
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
DEFINE_BLEND_SLICE_PACKED_FMT
#define DEFINE_BLEND_SLICE_PACKED_FMT(format_, blend_slice_fn_suffix_, main_has_alpha_, main_straight_, overlay_straight_)
Definition: vf_overlay.c:720
init_slice_fn
static int init_slice_fn(AVFilterContext *ctx)
Definition: vf_overlay.c:760
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:45
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:89
slice_start
static int slice_start(SliceContext *sc, VVCContext *s, VVCFrameContext *fc, const CodedBitstreamUnit *unit, const int is_first_slice)
Definition: dec.c:845
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:129
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
AVALPHA_MODE_UNSPECIFIED
@ AVALPHA_MODE_UNSPECIFIED
Unknown alpha handling, or no alpha channel.
Definition: pixfmt.h:801
MAIN
#define MAIN
Definition: vf_overlay.c:62
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_straight, int x, int y, int overlay_straight, int jobnr, int nb_jobs)
Definition: vf_overlay.c:664
EOF_ACTION_REPEAT
@ EOF_ACTION_REPEAT
Definition: framesync.h:27
AVFrame::height
int height
Definition: frame.h:499
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:1085
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:1693
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:900
G
#define G
Definition: vf_overlay.c:66
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:274
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:49
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:167
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:200
FFFilter::p
AVFilter p
The public AVFilter.
Definition: filters.h:270
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:46
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:75
ff_fill_rgba_map
int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt)
Definition: drawutils.c:80
DEFINE_BLEND_SLICE_YUV
#define DEFINE_BLEND_SLICE_YUV(depth, nbits)
Definition: vf_overlay.c:632
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:205
imgutils.h
timestamp.h
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
ff_overlay_init_x86
void ff_overlay_init_x86(AVFilterContext *ctx)
Definition: vf_overlay_init.c:35
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:154
OFFSET
#define OFFSET(x)
Definition: vf_overlay.c:906
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:3367
init
static av_cold int init(AVFilterContext *ctx)
Definition: vf_overlay.c:892