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 "internal.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  "pos", ///< position in the file
59  "t", ///< timestamp expressed in seconds
60  NULL
61 };
62 
63 #define MAIN 0
64 #define OVERLAY 1
65 
66 #define R 0
67 #define G 1
68 #define B 2
69 #define A 3
70 
71 #define Y 0
72 #define U 1
73 #define V 2
74 
75 enum EvalMode {
79 };
80 
82 {
83  OverlayContext *s = ctx->priv;
84 
85  ff_framesync_uninit(&s->fs);
86  av_expr_free(s->x_pexpr); s->x_pexpr = NULL;
87  av_expr_free(s->y_pexpr); s->y_pexpr = NULL;
88 }
89 
90 static inline int normalize_xy(double d, int chroma_sub)
91 {
92  if (isnan(d))
93  return INT_MAX;
94  return (int)d & ~((1 << chroma_sub) - 1);
95 }
96 
98 {
99  OverlayContext *s = ctx->priv;
100 
101  s->var_values[VAR_X] = av_expr_eval(s->x_pexpr, s->var_values, NULL);
102  s->var_values[VAR_Y] = av_expr_eval(s->y_pexpr, s->var_values, NULL);
103  /* It is necessary if x is expressed from y */
104  s->var_values[VAR_X] = av_expr_eval(s->x_pexpr, s->var_values, NULL);
105  s->x = normalize_xy(s->var_values[VAR_X], s->hsub);
106  s->y = normalize_xy(s->var_values[VAR_Y], s->vsub);
107 }
108 
109 static int set_expr(AVExpr **pexpr, const char *expr, const char *option, void *log_ctx)
110 {
111  int ret;
112  AVExpr *old = NULL;
113 
114  if (*pexpr)
115  old = *pexpr;
116  ret = av_expr_parse(pexpr, expr, var_names,
117  NULL, NULL, NULL, NULL, 0, log_ctx);
118  if (ret < 0) {
119  av_log(log_ctx, AV_LOG_ERROR,
120  "Error when evaluating the expression '%s' for %s\n",
121  expr, option);
122  *pexpr = old;
123  return ret;
124  }
125 
126  av_expr_free(old);
127  return 0;
128 }
129 
130 static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
131  char *res, int res_len, int flags)
132 {
133  OverlayContext *s = ctx->priv;
134  int ret;
135 
136  if (!strcmp(cmd, "x"))
137  ret = set_expr(&s->x_pexpr, args, cmd, ctx);
138  else if (!strcmp(cmd, "y"))
139  ret = set_expr(&s->y_pexpr, args, cmd, ctx);
140  else
141  ret = AVERROR(ENOSYS);
142 
143  if (ret < 0)
144  return ret;
145 
146  if (s->eval_mode == EVAL_MODE_INIT) {
147  eval_expr(ctx);
148  av_log(ctx, AV_LOG_VERBOSE, "x:%f xi:%d y:%f yi:%d\n",
149  s->var_values[VAR_X], s->x,
150  s->var_values[VAR_Y], s->y);
151  }
152  return ret;
153 }
154 
155 static const enum AVPixelFormat alpha_pix_fmts[] = {
159 };
160 
162 {
163  OverlayContext *s = ctx->priv;
164 
165  /* overlay formats contains alpha, for avoiding conversion with alpha information loss */
166  static const enum AVPixelFormat main_pix_fmts_yuv420[] = {
170  };
171  static const enum AVPixelFormat overlay_pix_fmts_yuv420[] = {
173  };
174 
175  static const enum AVPixelFormat main_pix_fmts_yuv422[] = {
177  };
178  static const enum AVPixelFormat overlay_pix_fmts_yuv422[] = {
180  };
181 
182  static const enum AVPixelFormat main_pix_fmts_yuv444[] = {
184  };
185  static const enum AVPixelFormat overlay_pix_fmts_yuv444[] = {
187  };
188 
189  static const enum AVPixelFormat main_pix_fmts_gbrp[] = {
191  };
192  static const enum AVPixelFormat overlay_pix_fmts_gbrp[] = {
194  };
195 
196  static const enum AVPixelFormat main_pix_fmts_rgb[] = {
201  };
202  static const enum AVPixelFormat overlay_pix_fmts_rgb[] = {
206  };
207 
208  const enum AVPixelFormat *main_formats, *overlay_formats;
210  int ret;
211 
212  switch (s->format) {
214  main_formats = main_pix_fmts_yuv420;
215  overlay_formats = overlay_pix_fmts_yuv420;
216  break;
218  main_formats = main_pix_fmts_yuv422;
219  overlay_formats = overlay_pix_fmts_yuv422;
220  break;
222  main_formats = main_pix_fmts_yuv444;
223  overlay_formats = overlay_pix_fmts_yuv444;
224  break;
225  case OVERLAY_FORMAT_RGB:
226  main_formats = main_pix_fmts_rgb;
227  overlay_formats = overlay_pix_fmts_rgb;
228  break;
229  case OVERLAY_FORMAT_GBRP:
230  main_formats = main_pix_fmts_gbrp;
231  overlay_formats = overlay_pix_fmts_gbrp;
232  break;
233  case OVERLAY_FORMAT_AUTO:
235  default:
236  av_assert0(0);
237  }
238 
239  formats = ff_make_format_list(main_formats);
240  if ((ret = ff_formats_ref(formats, &ctx->inputs[MAIN]->out_formats)) < 0 ||
241  (ret = ff_formats_ref(formats, &ctx->outputs[MAIN]->in_formats)) < 0)
242  return ret;
243 
244  return ff_formats_ref(ff_make_format_list(overlay_formats),
245  &ctx->inputs[OVERLAY]->out_formats);
246 }
247 
249 {
250  AVFilterContext *ctx = inlink->dst;
251  OverlayContext *s = inlink->dst->priv;
252  int ret;
253  const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format);
254 
255  av_image_fill_max_pixsteps(s->overlay_pix_step, NULL, pix_desc);
256 
257  /* Finish the configuration by evaluating the expressions
258  now when both inputs are configured. */
259  s->var_values[VAR_MAIN_W ] = s->var_values[VAR_MW] = ctx->inputs[MAIN ]->w;
260  s->var_values[VAR_MAIN_H ] = s->var_values[VAR_MH] = ctx->inputs[MAIN ]->h;
261  s->var_values[VAR_OVERLAY_W] = s->var_values[VAR_OW] = ctx->inputs[OVERLAY]->w;
262  s->var_values[VAR_OVERLAY_H] = s->var_values[VAR_OH] = ctx->inputs[OVERLAY]->h;
263  s->var_values[VAR_HSUB] = 1<<pix_desc->log2_chroma_w;
264  s->var_values[VAR_VSUB] = 1<<pix_desc->log2_chroma_h;
265  s->var_values[VAR_X] = NAN;
266  s->var_values[VAR_Y] = NAN;
267  s->var_values[VAR_N] = 0;
268  s->var_values[VAR_T] = NAN;
269  s->var_values[VAR_POS] = NAN;
270 
271  if ((ret = set_expr(&s->x_pexpr, s->x_expr, "x", ctx)) < 0 ||
272  (ret = set_expr(&s->y_pexpr, s->y_expr, "y", ctx)) < 0)
273  return ret;
274 
275  s->overlay_is_packed_rgb =
276  ff_fill_rgba_map(s->overlay_rgba_map, inlink->format) >= 0;
277  s->overlay_has_alpha = ff_fmt_is_in(inlink->format, alpha_pix_fmts);
278 
279  if (s->eval_mode == EVAL_MODE_INIT) {
280  eval_expr(ctx);
281  av_log(ctx, AV_LOG_VERBOSE, "x:%f xi:%d y:%f yi:%d\n",
282  s->var_values[VAR_X], s->x,
283  s->var_values[VAR_Y], s->y);
284  }
285 
287  "main w:%d h:%d fmt:%s overlay w:%d h:%d fmt:%s\n",
288  ctx->inputs[MAIN]->w, ctx->inputs[MAIN]->h,
289  av_get_pix_fmt_name(ctx->inputs[MAIN]->format),
290  ctx->inputs[OVERLAY]->w, ctx->inputs[OVERLAY]->h,
291  av_get_pix_fmt_name(ctx->inputs[OVERLAY]->format));
292  return 0;
293 }
294 
295 static int config_output(AVFilterLink *outlink)
296 {
297  AVFilterContext *ctx = outlink->src;
298  OverlayContext *s = ctx->priv;
299  int ret;
300 
301  if ((ret = ff_framesync_init_dualinput(&s->fs, ctx)) < 0)
302  return ret;
303 
304  outlink->w = ctx->inputs[MAIN]->w;
305  outlink->h = ctx->inputs[MAIN]->h;
306  outlink->time_base = ctx->inputs[MAIN]->time_base;
307 
308  return ff_framesync_configure(&s->fs);
309 }
310 
311 // divide by 255 and round to nearest
312 // apply a fast variant: (X+127)/255 = ((X+127)*257+257)>>16 = ((X+128)*257)>>16
313 #define FAST_DIV255(x) ((((x) + 128) * 257) >> 16)
314 
315 // calculate the unpremultiplied alpha, applying the general equation:
316 // alpha = alpha_overlay / ( (alpha_main + alpha_overlay) - (alpha_main * alpha_overlay) )
317 // (((x) << 16) - ((x) << 9) + (x)) is a faster version of: 255 * 255 * x
318 // ((((x) + (y)) << 8) - ((x) + (y)) - (y) * (x)) is a faster version of: 255 * (x + y)
319 #define UNPREMULTIPLY_ALPHA(x, y) ((((x) << 16) - ((x) << 9) + (x)) / ((((x) + (y)) << 8) - ((x) + (y)) - (y) * (x)))
320 
321 /**
322  * Blend image in src to destination buffer dst at position (x, y).
323  */
324 
326  AVFrame *dst, const AVFrame *src,
327  int main_has_alpha, int x, int y,
328  int is_straight, int jobnr, int nb_jobs)
329 {
330  OverlayContext *s = ctx->priv;
331  int i, imax, j, jmax;
332  const int src_w = src->width;
333  const int src_h = src->height;
334  const int dst_w = dst->width;
335  const int dst_h = dst->height;
336  uint8_t alpha; ///< the amount of overlay to blend on to main
337  const int dr = s->main_rgba_map[R];
338  const int dg = s->main_rgba_map[G];
339  const int db = s->main_rgba_map[B];
340  const int da = s->main_rgba_map[A];
341  const int dstep = s->main_pix_step[0];
342  const int sr = s->overlay_rgba_map[R];
343  const int sg = s->overlay_rgba_map[G];
344  const int sb = s->overlay_rgba_map[B];
345  const int sa = s->overlay_rgba_map[A];
346  const int sstep = s->overlay_pix_step[0];
347  int slice_start, slice_end;
348  uint8_t *S, *sp, *d, *dp;
349 
350  i = FFMAX(-y, 0);
351  imax = FFMIN3(-y + dst_h, FFMIN(src_h, dst_h), y + src_h);
352 
353  slice_start = i + (imax * jobnr) / nb_jobs;
354  slice_end = i + (imax * (jobnr+1)) / nb_jobs;
355 
356  sp = src->data[0] + (slice_start) * src->linesize[0];
357  dp = dst->data[0] + (y + slice_start) * dst->linesize[0];
358 
359  for (i = slice_start; i < slice_end; i++) {
360  j = FFMAX(-x, 0);
361  S = sp + j * sstep;
362  d = dp + (x+j) * dstep;
363 
364  for (jmax = FFMIN(-x + dst_w, src_w); j < jmax; j++) {
365  alpha = S[sa];
366 
367  // if the main channel has an alpha channel, alpha has to be calculated
368  // to create an un-premultiplied (straight) alpha value
369  if (main_has_alpha && alpha != 0 && alpha != 255) {
370  uint8_t alpha_d = d[da];
371  alpha = UNPREMULTIPLY_ALPHA(alpha, alpha_d);
372  }
373 
374  switch (alpha) {
375  case 0:
376  break;
377  case 255:
378  d[dr] = S[sr];
379  d[dg] = S[sg];
380  d[db] = S[sb];
381  break;
382  default:
383  // main_value = main_value * (1 - alpha) + overlay_value * alpha
384  // since alpha is in the range 0-255, the result must divided by 255
385  d[dr] = is_straight ? FAST_DIV255(d[dr] * (255 - alpha) + S[sr] * alpha) :
386  FFMIN(FAST_DIV255(d[dr] * (255 - alpha)) + S[sr], 255);
387  d[dg] = is_straight ? FAST_DIV255(d[dg] * (255 - alpha) + S[sg] * alpha) :
388  FFMIN(FAST_DIV255(d[dg] * (255 - alpha)) + S[sg], 255);
389  d[db] = is_straight ? FAST_DIV255(d[db] * (255 - alpha) + S[sb] * alpha) :
390  FFMIN(FAST_DIV255(d[db] * (255 - alpha)) + S[sb], 255);
391  }
392  if (main_has_alpha) {
393  switch (alpha) {
394  case 0:
395  break;
396  case 255:
397  d[da] = S[sa];
398  break;
399  default:
400  // apply alpha compositing: main_alpha += (1-main_alpha) * overlay_alpha
401  d[da] += FAST_DIV255((255 - d[da]) * S[sa]);
402  }
403  }
404  d += dstep;
405  S += sstep;
406  }
407  dp += dst->linesize[0];
408  sp += src->linesize[0];
409  }
410 }
411 
413  AVFrame *dst, const AVFrame *src,
414  int src_w, int src_h,
415  int dst_w, int dst_h,
416  int i, int hsub, int vsub,
417  int x, int y,
418  int main_has_alpha,
419  int dst_plane,
420  int dst_offset,
421  int dst_step,
422  int straight,
423  int yuv,
424  int jobnr,
425  int nb_jobs)
426 {
427  OverlayContext *octx = ctx->priv;
428  int src_wp = AV_CEIL_RSHIFT(src_w, hsub);
429  int src_hp = AV_CEIL_RSHIFT(src_h, vsub);
430  int dst_wp = AV_CEIL_RSHIFT(dst_w, hsub);
431  int dst_hp = AV_CEIL_RSHIFT(dst_h, vsub);
432  int yp = y>>vsub;
433  int xp = x>>hsub;
434  uint8_t *s, *sp, *d, *dp, *dap, *a, *da, *ap;
435  int jmax, j, k, kmax;
436  int slice_start, slice_end;
437 
438  j = FFMAX(-yp, 0);
439  jmax = FFMIN3(-yp + dst_hp, FFMIN(src_hp, dst_hp), yp + src_hp);
440 
441  slice_start = j + (jmax * jobnr) / nb_jobs;
442  slice_end = j + (jmax * (jobnr+1)) / nb_jobs;
443 
444  sp = src->data[i] + (slice_start) * src->linesize[i];
445  dp = dst->data[dst_plane]
446  + (yp + slice_start) * dst->linesize[dst_plane]
447  + dst_offset;
448  ap = src->data[3] + (slice_start << vsub) * src->linesize[3];
449  dap = dst->data[3] + ((yp + slice_start) << vsub) * dst->linesize[3];
450 
451  for (j = slice_start; j < slice_end; j++) {
452  k = FFMAX(-xp, 0);
453  d = dp + (xp+k) * dst_step;
454  s = sp + k;
455  a = ap + (k<<hsub);
456  da = dap + ((xp+k) << hsub);
457  kmax = FFMIN(-xp + dst_wp, src_wp);
458 
459  if (((vsub && j+1 < src_hp) || !vsub) && octx->blend_row[i]) {
460  int c = octx->blend_row[i](d, da, s, a, kmax - k, src->linesize[3]);
461 
462  s += c;
463  d += dst_step * c;
464  da += (1 << hsub) * c;
465  a += (1 << hsub) * c;
466  k += c;
467  }
468  for (; k < kmax; k++) {
469  int alpha_v, alpha_h, alpha;
470 
471  // average alpha for color components, improve quality
472  if (hsub && vsub && j+1 < src_hp && k+1 < src_wp) {
473  alpha = (a[0] + a[src->linesize[3]] +
474  a[1] + a[src->linesize[3]+1]) >> 2;
475  } else if (hsub || vsub) {
476  alpha_h = hsub && k+1 < src_wp ?
477  (a[0] + a[1]) >> 1 : a[0];
478  alpha_v = vsub && j+1 < src_hp ?
479  (a[0] + a[src->linesize[3]]) >> 1 : a[0];
480  alpha = (alpha_v + alpha_h) >> 1;
481  } else
482  alpha = a[0];
483  // if the main channel has an alpha channel, alpha has to be calculated
484  // to create an un-premultiplied (straight) alpha value
485  if (main_has_alpha && alpha != 0 && alpha != 255) {
486  // average alpha for color components, improve quality
487  uint8_t alpha_d;
488  if (hsub && vsub && j+1 < src_hp && k+1 < src_wp) {
489  alpha_d = (da[0] + da[dst->linesize[3]] +
490  da[1] + da[dst->linesize[3]+1]) >> 2;
491  } else if (hsub || vsub) {
492  alpha_h = hsub && k+1 < src_wp ?
493  (da[0] + da[1]) >> 1 : da[0];
494  alpha_v = vsub && j+1 < src_hp ?
495  (da[0] + da[dst->linesize[3]]) >> 1 : da[0];
496  alpha_d = (alpha_v + alpha_h) >> 1;
497  } else
498  alpha_d = da[0];
499  alpha = UNPREMULTIPLY_ALPHA(alpha, alpha_d);
500  }
501  if (straight) {
502  *d = FAST_DIV255(*d * (255 - alpha) + *s * alpha);
503  } else {
504  if (i && yuv)
505  *d = av_clip(FAST_DIV255((*d - 128) * (255 - alpha)) + *s - 128, -128, 128) + 128;
506  else
507  *d = FFMIN(FAST_DIV255(*d * (255 - alpha)) + *s, 255);
508  }
509  s++;
510  d += dst_step;
511  da += 1 << hsub;
512  a += 1 << hsub;
513  }
514  dp += dst->linesize[dst_plane];
515  sp += src->linesize[i];
516  ap += (1 << vsub) * src->linesize[3];
517  dap += (1 << vsub) * dst->linesize[3];
518  }
519 }
520 
521 static inline void alpha_composite(const AVFrame *src, const AVFrame *dst,
522  int src_w, int src_h,
523  int dst_w, int dst_h,
524  int x, int y,
525  int jobnr, int nb_jobs)
526 {
527  uint8_t alpha; ///< the amount of overlay to blend on to main
528  uint8_t *s, *sa, *d, *da;
529  int i, imax, j, jmax;
530  int slice_start, slice_end;
531 
532  imax = FFMIN(-y + dst_h, src_h);
533  slice_start = (imax * jobnr) / nb_jobs;
534  slice_end = ((imax * (jobnr+1)) / nb_jobs);
535 
536  i = FFMAX(-y, 0);
537  sa = src->data[3] + (i + slice_start) * src->linesize[3];
538  da = dst->data[3] + (y + i + slice_start) * dst->linesize[3];
539 
540  for (i = i + slice_start; i < slice_end; i++) {
541  j = FFMAX(-x, 0);
542  s = sa + j;
543  d = da + x+j;
544 
545  for (jmax = FFMIN(-x + dst_w, src_w); j < jmax; j++) {
546  alpha = *s;
547  if (alpha != 0 && alpha != 255) {
548  uint8_t alpha_d = *d;
549  alpha = UNPREMULTIPLY_ALPHA(alpha, alpha_d);
550  }
551  switch (alpha) {
552  case 0:
553  break;
554  case 255:
555  *d = *s;
556  break;
557  default:
558  // apply alpha compositing: main_alpha += (1-main_alpha) * overlay_alpha
559  *d += FAST_DIV255((255 - *d) * *s);
560  }
561  d += 1;
562  s += 1;
563  }
564  da += dst->linesize[3];
565  sa += src->linesize[3];
566  }
567 }
568 
570  AVFrame *dst, const AVFrame *src,
571  int hsub, int vsub,
572  int main_has_alpha,
573  int x, int y,
574  int is_straight,
575  int jobnr, int nb_jobs)
576 {
577  OverlayContext *s = ctx->priv;
578  const int src_w = src->width;
579  const int src_h = src->height;
580  const int dst_w = dst->width;
581  const int dst_h = dst->height;
582 
583  blend_plane(ctx, dst, src, src_w, src_h, dst_w, dst_h, 0, 0, 0, x, y, main_has_alpha,
584  s->main_desc->comp[0].plane, s->main_desc->comp[0].offset, s->main_desc->comp[0].step, is_straight, 1,
585  jobnr, nb_jobs);
586  blend_plane(ctx, dst, src, src_w, src_h, dst_w, dst_h, 1, hsub, vsub, x, y, main_has_alpha,
587  s->main_desc->comp[1].plane, s->main_desc->comp[1].offset, s->main_desc->comp[1].step, is_straight, 1,
588  jobnr, nb_jobs);
589  blend_plane(ctx, dst, src, src_w, src_h, dst_w, dst_h, 2, hsub, vsub, x, y, main_has_alpha,
590  s->main_desc->comp[2].plane, s->main_desc->comp[2].offset, s->main_desc->comp[2].step, is_straight, 1,
591  jobnr, nb_jobs);
592 
593  if (main_has_alpha)
594  alpha_composite(src, dst, src_w, src_h, dst_w, dst_h, x, y, jobnr, nb_jobs);
595 }
596 
598  AVFrame *dst, const AVFrame *src,
599  int hsub, int vsub,
600  int main_has_alpha,
601  int x, int y,
602  int is_straight,
603  int jobnr,
604  int nb_jobs)
605 {
606  OverlayContext *s = ctx->priv;
607  const int src_w = src->width;
608  const int src_h = src->height;
609  const int dst_w = dst->width;
610  const int dst_h = dst->height;
611 
612  blend_plane(ctx, dst, src, src_w, src_h, dst_w, dst_h, 0, 0, 0, x, y, main_has_alpha,
613  s->main_desc->comp[1].plane, s->main_desc->comp[1].offset, s->main_desc->comp[1].step, is_straight, 0,
614  jobnr, nb_jobs);
615  blend_plane(ctx, dst, src, src_w, src_h, dst_w, dst_h, 1, hsub, vsub, x, y, main_has_alpha,
616  s->main_desc->comp[2].plane, s->main_desc->comp[2].offset, s->main_desc->comp[2].step, is_straight, 0,
617  jobnr, nb_jobs);
618  blend_plane(ctx, dst, src, src_w, src_h, dst_w, dst_h, 2, hsub, vsub, x, y, main_has_alpha,
619  s->main_desc->comp[0].plane, s->main_desc->comp[0].offset, s->main_desc->comp[0].step, is_straight, 0,
620  jobnr, nb_jobs);
621 
622  if (main_has_alpha)
623  alpha_composite(src, dst, src_w, src_h, dst_w, dst_h, x, y, jobnr, nb_jobs);
624 }
625 
626 static int blend_slice_yuv420(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
627 {
628  OverlayContext *s = ctx->priv;
629  ThreadData *td = arg;
630  blend_slice_yuv(ctx, td->dst, td->src, 1, 1, 0, s->x, s->y, 1, jobnr, nb_jobs);
631  return 0;
632 }
633 
634 static int blend_slice_yuva420(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
635 {
636  OverlayContext *s = ctx->priv;
637  ThreadData *td = arg;
638  blend_slice_yuv(ctx, td->dst, td->src, 1, 1, 1, s->x, s->y, 1, jobnr, nb_jobs);
639  return 0;
640 }
641 
642 static int blend_slice_yuv422(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
643 {
644  OverlayContext *s = ctx->priv;
645  ThreadData *td = arg;
646  blend_slice_yuv(ctx, td->dst, td->src, 1, 0, 0, s->x, s->y, 1, jobnr, nb_jobs);
647  return 0;
648 }
649 
650 static int blend_slice_yuva422(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
651 {
652  OverlayContext *s = ctx->priv;
653  ThreadData *td = arg;
654  blend_slice_yuv(ctx, td->dst, td->src, 1, 0, 1, s->x, s->y, 1, jobnr, nb_jobs);
655  return 0;
656 }
657 
658 static int blend_slice_yuv444(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
659 {
660  OverlayContext *s = ctx->priv;
661  ThreadData *td = arg;
662  blend_slice_yuv(ctx, td->dst, td->src, 0, 0, 0, s->x, s->y, 1, jobnr, nb_jobs);
663  return 0;
664 }
665 
666 static int blend_slice_yuva444(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
667 {
668  OverlayContext *s = ctx->priv;
669  ThreadData *td = arg;
670  blend_slice_yuv(ctx, td->dst, td->src, 0, 0, 1, s->x, s->y, 1, jobnr, nb_jobs);
671  return 0;
672 }
673 
674 static int blend_slice_gbrp(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
675 {
676  OverlayContext *s = ctx->priv;
677  ThreadData *td = arg;
678  blend_slice_planar_rgb(ctx, td->dst, td->src, 0, 0, 0, s->x, s->y, 1, jobnr, nb_jobs);
679  return 0;
680 }
681 
682 static int blend_slice_gbrap(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
683 {
684  OverlayContext *s = ctx->priv;
685  ThreadData *td = arg;
686  blend_slice_planar_rgb(ctx, td->dst, td->src, 0, 0, 1, s->x, s->y, 1, jobnr, nb_jobs);
687  return 0;
688 }
689 
690 static int blend_slice_yuv420_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
691 {
692  OverlayContext *s = ctx->priv;
693  ThreadData *td = arg;
694  blend_slice_yuv(ctx, td->dst, td->src, 1, 1, 0, s->x, s->y, 0, jobnr, nb_jobs);
695  return 0;
696 }
697 
698 static int blend_slice_yuva420_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
699 {
700  OverlayContext *s = ctx->priv;
701  ThreadData *td = arg;
702  blend_slice_yuv(ctx, td->dst, td->src, 1, 1, 1, s->x, s->y, 0, jobnr, nb_jobs);
703  return 0;
704 }
705 
706 static int blend_slice_yuv422_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
707 {
708  OverlayContext *s = ctx->priv;
709  ThreadData *td = arg;
710  blend_slice_yuv(ctx, td->dst, td->src, 1, 0, 0, s->x, s->y, 0, jobnr, nb_jobs);
711  return 0;
712 }
713 
714 static int blend_slice_yuva422_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
715 {
716  OverlayContext *s = ctx->priv;
717  ThreadData *td = arg;
718  blend_slice_yuv(ctx, td->dst, td->src, 1, 0, 1, s->x, s->y, 0, jobnr, nb_jobs);
719  return 0;
720 }
721 
722 static int blend_slice_yuv444_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
723 {
724  OverlayContext *s = ctx->priv;
725  ThreadData *td = arg;
726  blend_slice_yuv(ctx, td->dst, td->src, 0, 0, 0, s->x, s->y, 0, jobnr, nb_jobs);
727  return 0;
728 }
729 
730 static int blend_slice_yuva444_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
731 {
732  OverlayContext *s = ctx->priv;
733  ThreadData *td = arg;
734  blend_slice_yuv(ctx, td->dst, td->src, 0, 0, 1, s->x, s->y, 0, jobnr, nb_jobs);
735  return 0;
736 }
737 
738 static int blend_slice_gbrp_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
739 {
740  OverlayContext *s = ctx->priv;
741  ThreadData *td = arg;
742  blend_slice_planar_rgb(ctx, td->dst, td->src, 0, 0, 0, s->x, s->y, 0, jobnr, nb_jobs);
743  return 0;
744 }
745 
746 static int blend_slice_gbrap_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
747 {
748  OverlayContext *s = ctx->priv;
749  ThreadData *td = arg;
750  blend_slice_planar_rgb(ctx, td->dst, td->src, 0, 0, 1, s->x, s->y, 0, jobnr, nb_jobs);
751  return 0;
752 }
753 
754 static int blend_slice_rgb(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
755 {
756  OverlayContext *s = ctx->priv;
757  ThreadData *td = arg;
758  blend_slice_packed_rgb(ctx, td->dst, td->src, 0, s->x, s->y, 1, jobnr, nb_jobs);
759  return 0;
760 }
761 
762 static int blend_slice_rgba(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
763 {
764  OverlayContext *s = ctx->priv;
765  ThreadData *td = arg;
766  blend_slice_packed_rgb(ctx, td->dst, td->src, 1, s->x, s->y, 1, jobnr, nb_jobs);
767  return 0;
768 }
769 
770 static int blend_slice_rgb_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
771 {
772  OverlayContext *s = ctx->priv;
773  ThreadData *td = arg;
774  blend_slice_packed_rgb(ctx, td->dst, td->src, 0, s->x, s->y, 0, jobnr, nb_jobs);
775  return 0;
776 }
777 
778 static int blend_slice_rgba_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
779 {
780  OverlayContext *s = ctx->priv;
781  ThreadData *td = arg;
782  blend_slice_packed_rgb(ctx, td->dst, td->src, 1, s->x, s->y, 0, jobnr, nb_jobs);
783  return 0;
784 }
785 
787 {
788  OverlayContext *s = inlink->dst->priv;
789  const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format);
790 
791  av_image_fill_max_pixsteps(s->main_pix_step, NULL, pix_desc);
792 
793  s->hsub = pix_desc->log2_chroma_w;
794  s->vsub = pix_desc->log2_chroma_h;
795 
796  s->main_desc = pix_desc;
797 
798  s->main_is_packed_rgb =
799  ff_fill_rgba_map(s->main_rgba_map, inlink->format) >= 0;
800  s->main_has_alpha = ff_fmt_is_in(inlink->format, alpha_pix_fmts);
801  switch (s->format) {
803  s->blend_slice = s->main_has_alpha ? blend_slice_yuva420 : blend_slice_yuv420;
804  break;
806  s->blend_slice = s->main_has_alpha ? blend_slice_yuva422 : blend_slice_yuv422;
807  break;
809  s->blend_slice = s->main_has_alpha ? blend_slice_yuva444 : blend_slice_yuv444;
810  break;
811  case OVERLAY_FORMAT_RGB:
812  s->blend_slice = s->main_has_alpha ? blend_slice_rgba : blend_slice_rgb;
813  break;
814  case OVERLAY_FORMAT_GBRP:
815  s->blend_slice = s->main_has_alpha ? blend_slice_gbrap : blend_slice_gbrp;
816  break;
817  case OVERLAY_FORMAT_AUTO:
818  switch (inlink->format) {
819  case AV_PIX_FMT_YUVA420P:
820  s->blend_slice = blend_slice_yuva420;
821  break;
822  case AV_PIX_FMT_YUVA422P:
823  s->blend_slice = blend_slice_yuva422;
824  break;
825  case AV_PIX_FMT_YUVA444P:
826  s->blend_slice = blend_slice_yuva444;
827  break;
828  case AV_PIX_FMT_ARGB:
829  case AV_PIX_FMT_RGBA:
830  case AV_PIX_FMT_BGRA:
831  case AV_PIX_FMT_ABGR:
832  s->blend_slice = blend_slice_rgba;
833  break;
834  case AV_PIX_FMT_GBRAP:
835  s->blend_slice = blend_slice_gbrap;
836  break;
837  default:
838  av_assert0(0);
839  break;
840  }
841  break;
842  }
843 
844  if (!s->alpha_format)
845  goto end;
846 
847  switch (s->format) {
849  s->blend_slice = s->main_has_alpha ? blend_slice_yuva420_pm : blend_slice_yuv420_pm;
850  break;
852  s->blend_slice = s->main_has_alpha ? blend_slice_yuva422_pm : blend_slice_yuv422_pm;
853  break;
855  s->blend_slice = s->main_has_alpha ? blend_slice_yuva444_pm : blend_slice_yuv444_pm;
856  break;
857  case OVERLAY_FORMAT_RGB:
858  s->blend_slice = s->main_has_alpha ? blend_slice_rgba_pm : blend_slice_rgb_pm;
859  break;
860  case OVERLAY_FORMAT_GBRP:
861  s->blend_slice = s->main_has_alpha ? blend_slice_gbrap_pm : blend_slice_gbrp_pm;
862  break;
863  case OVERLAY_FORMAT_AUTO:
864  switch (inlink->format) {
865  case AV_PIX_FMT_YUVA420P:
866  s->blend_slice = blend_slice_yuva420_pm;
867  break;
868  case AV_PIX_FMT_YUVA422P:
869  s->blend_slice = blend_slice_yuva422_pm;
870  break;
871  case AV_PIX_FMT_YUVA444P:
872  s->blend_slice = blend_slice_yuva444_pm;
873  break;
874  case AV_PIX_FMT_ARGB:
875  case AV_PIX_FMT_RGBA:
876  case AV_PIX_FMT_BGRA:
877  case AV_PIX_FMT_ABGR:
878  s->blend_slice = blend_slice_rgba_pm;
879  break;
880  case AV_PIX_FMT_GBRAP:
881  s->blend_slice = blend_slice_gbrap_pm;
882  break;
883  default:
884  av_assert0(0);
885  break;
886  }
887  break;
888  }
889 
890 end:
891  if (ARCH_X86)
892  ff_overlay_init_x86(s, s->format, inlink->format,
893  s->alpha_format, s->main_has_alpha);
894 
895  return 0;
896 }
897 
898 static int do_blend(FFFrameSync *fs)
899 {
900  AVFilterContext *ctx = fs->parent;
901  AVFrame *mainpic, *second;
902  OverlayContext *s = ctx->priv;
903  AVFilterLink *inlink = ctx->inputs[0];
904  int ret;
905 
906  ret = ff_framesync_dualinput_get_writable(fs, &mainpic, &second);
907  if (ret < 0)
908  return ret;
909  if (!second)
910  return ff_filter_frame(ctx->outputs[0], mainpic);
911 
912  if (s->eval_mode == EVAL_MODE_FRAME) {
913  int64_t pos = mainpic->pkt_pos;
914 
915  s->var_values[VAR_N] = inlink->frame_count_out;
916  s->var_values[VAR_T] = mainpic->pts == AV_NOPTS_VALUE ?
917  NAN : mainpic->pts * av_q2d(inlink->time_base);
918  s->var_values[VAR_POS] = pos == -1 ? NAN : pos;
919 
920  s->var_values[VAR_OVERLAY_W] = s->var_values[VAR_OW] = second->width;
921  s->var_values[VAR_OVERLAY_H] = s->var_values[VAR_OH] = second->height;
922  s->var_values[VAR_MAIN_W ] = s->var_values[VAR_MW] = mainpic->width;
923  s->var_values[VAR_MAIN_H ] = s->var_values[VAR_MH] = mainpic->height;
924 
925  eval_expr(ctx);
926  av_log(ctx, AV_LOG_DEBUG, "n:%f t:%f pos:%f x:%f xi:%d y:%f yi:%d\n",
927  s->var_values[VAR_N], s->var_values[VAR_T], s->var_values[VAR_POS],
928  s->var_values[VAR_X], s->x,
929  s->var_values[VAR_Y], s->y);
930  }
931 
932  if (s->x < mainpic->width && s->x + second->width >= 0 &&
933  s->y < mainpic->height && s->y + second->height >= 0) {
934  ThreadData td;
935 
936  td.dst = mainpic;
937  td.src = second;
938  ctx->internal->execute(ctx, s->blend_slice, &td, NULL, FFMIN(FFMAX(1, FFMIN3(s->y + second->height, FFMIN(second->height, mainpic->height), mainpic->height - s->y)),
940  }
941  return ff_filter_frame(ctx->outputs[0], mainpic);
942 }
943 
945 {
946  OverlayContext *s = ctx->priv;
947 
948  s->fs.on_event = do_blend;
949  return 0;
950 }
951 
953 {
954  OverlayContext *s = ctx->priv;
955  return ff_framesync_activate(&s->fs);
956 }
957 
958 #define OFFSET(x) offsetof(OverlayContext, x)
959 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
960 
961 static const AVOption overlay_options[] = {
962  { "x", "set the x expression", OFFSET(x_expr), AV_OPT_TYPE_STRING, {.str = "0"}, 0, 0, FLAGS },
963  { "y", "set the y expression", OFFSET(y_expr), AV_OPT_TYPE_STRING, {.str = "0"}, 0, 0, FLAGS },
964  { "eof_action", "Action to take when encountering EOF from secondary input ",
965  OFFSET(fs.opt_eof_action), AV_OPT_TYPE_INT, { .i64 = EOF_ACTION_REPEAT },
966  EOF_ACTION_REPEAT, EOF_ACTION_PASS, .flags = FLAGS, "eof_action" },
967  { "repeat", "Repeat the previous frame.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_REPEAT }, .flags = FLAGS, "eof_action" },
968  { "endall", "End both streams.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_ENDALL }, .flags = FLAGS, "eof_action" },
969  { "pass", "Pass through the main input.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_PASS }, .flags = FLAGS, "eof_action" },
970  { "eval", "specify when to evaluate expressions", OFFSET(eval_mode), AV_OPT_TYPE_INT, {.i64 = EVAL_MODE_FRAME}, 0, EVAL_MODE_NB-1, FLAGS, "eval" },
971  { "init", "eval expressions once during initialization", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_INIT}, .flags = FLAGS, .unit = "eval" },
972  { "frame", "eval expressions per-frame", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_FRAME}, .flags = FLAGS, .unit = "eval" },
973  { "shortest", "force termination when the shortest input terminates", OFFSET(fs.opt_shortest), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS },
974  { "format", "set output format", OFFSET(format), AV_OPT_TYPE_INT, {.i64=OVERLAY_FORMAT_YUV420}, 0, OVERLAY_FORMAT_NB-1, FLAGS, "format" },
975  { "yuv420", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV420}, .flags = FLAGS, .unit = "format" },
976  { "yuv422", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV422}, .flags = FLAGS, .unit = "format" },
977  { "yuv444", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV444}, .flags = FLAGS, .unit = "format" },
978  { "rgb", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_RGB}, .flags = FLAGS, .unit = "format" },
979  { "gbrp", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_GBRP}, .flags = FLAGS, .unit = "format" },
980  { "auto", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_AUTO}, .flags = FLAGS, .unit = "format" },
981  { "repeatlast", "repeat overlay of the last overlay frame", OFFSET(fs.opt_repeatlast), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGS },
982  { "alpha", "alpha format", OFFSET(alpha_format), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "alpha_format" },
983  { "straight", "", 0, AV_OPT_TYPE_CONST, {.i64=0}, .flags = FLAGS, .unit = "alpha_format" },
984  { "premultiplied", "", 0, AV_OPT_TYPE_CONST, {.i64=1}, .flags = FLAGS, .unit = "alpha_format" },
985  { NULL }
986 };
987 
989 
991  {
992  .name = "main",
993  .type = AVMEDIA_TYPE_VIDEO,
994  .config_props = config_input_main,
995  },
996  {
997  .name = "overlay",
998  .type = AVMEDIA_TYPE_VIDEO,
999  .config_props = config_input_overlay,
1000  },
1001  { NULL }
1002 };
1003 
1005  {
1006  .name = "default",
1007  .type = AVMEDIA_TYPE_VIDEO,
1008  .config_props = config_output,
1009  },
1010  { NULL }
1011 };
1012 
1014  .name = "overlay",
1015  .description = NULL_IF_CONFIG_SMALL("Overlay a video source on top of the input."),
1016  .preinit = overlay_framesync_preinit,
1017  .init = init,
1018  .uninit = uninit,
1019  .priv_size = sizeof(OverlayContext),
1020  .priv_class = &overlay_class,
1022  .activate = activate,
1028 };
formats
formats
Definition: signature.h:48
VAR_MAIN_H
@ VAR_MAIN_H
Definition: vf_drawtext.c:117
ff_framesync_configure
int ff_framesync_configure(FFFrameSync *fs)
Configure a frame sync structure.
Definition: framesync.c:117
td
#define td
Definition: regdef.h:70
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
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:325
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
blend_slice_rgb
static int blend_slice_rgb(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:754
set_expr
static int set_expr(AVExpr **pexpr, const char *expr, const char *option, void *log_ctx)
Definition: vf_overlay.c:109
OVERLAY
#define OVERLAY
Definition: vf_overlay.c:64
ff_make_format_list
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:300
ff_framesync_uninit
void ff_framesync_uninit(FFFrameSync *fs)
Free all memory currently allocated.
Definition: framesync.c:283
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1075
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2549
blend_slice_yuv422
static int blend_slice_yuv422(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:642
avfilter_vf_overlay_outputs
static const AVFilterPad avfilter_vf_overlay_outputs[]
Definition: vf_overlay.c:1004
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
end
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:92
blend_slice_yuva422_pm
static int blend_slice_yuva422_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:714
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:300
pixdesc.h
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:393
AVFrame::width
int width
Definition: frame.h:358
do_blend
static int do_blend(FFFrameSync *fs)
Definition: vf_overlay.c:898
AVOption
AVOption.
Definition: opt.h:246
EOF_ACTION_ENDALL
@ EOF_ACTION_ENDALL
Definition: framesync.h:28
VAR_HSUB
@ VAR_HSUB
Definition: boxblur.c:40
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:192
AV_PIX_FMT_BGR24
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:69
AV_PIX_FMT_BGRA
@ AV_PIX_FMT_BGRA
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
Definition: pixfmt.h:95
mathematics.h
blend_slice_yuv420
static int blend_slice_yuv420(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:626
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:148
VAR_POS
@ VAR_POS
Definition: af_volume.h:50
FFFrameSync
Frame sync structure.
Definition: framesync.h:146
video.h
AVFormatContext::internal
AVFormatInternal * internal
An opaque field for libavformat internal usage.
Definition: avformat.h:1788
VAR_MAIN_W
@ VAR_MAIN_W
Definition: vf_drawtext.c:118
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:314
hsub
static void hsub(htype *dst, const htype *src, int bins)
Definition: vf_median.c:75
AVFilterFormats
A list of supported formats for one end of a filter link.
Definition: formats.h:64
blend_slice_gbrap
static int blend_slice_gbrap(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:682
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:685
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:51
VAR_VSUB
@ VAR_VSUB
Definition: boxblur.c:41
OVERLAY_FORMAT_RGB
@ OVERLAY_FORMAT_RGB
Definition: vf_overlay.h:46
ff_vf_overlay
AVFilter ff_vf_overlay
Definition: vf_overlay.c:1013
blend_slice_gbrp_pm
static int blend_slice_gbrp_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:738
AV_PIX_FMT_GBRAP
@ AV_PIX_FMT_GBRAP
planar GBRA 4:4:4:4 32bpp
Definition: pixfmt.h:215
FAST_DIV255
#define FAST_DIV255(x)
Definition: vf_overlay.c:313
FFMIN3
#define FFMIN3(a, b, c)
Definition: common.h:97
av_expr_free
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
Definition: eval.c:336
R
#define R
Definition: vf_overlay.c:66
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:54
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_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
config_input_main
static int config_input_main(AVFilterLink *inlink)
Definition: vf_overlay.c:786
query_formats
static int query_formats(AVFilterContext *ctx)
Definition: vf_overlay.c:161
av_cold
#define av_cold
Definition: attributes.h:90
blend_slice_rgb_pm
static int blend_slice_rgb_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:770
ff_set_common_formats
int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
A helper for query_formats() which sets all links to the same list of formats.
Definition: formats.c:605
EVAL_MODE_FRAME
@ EVAL_MODE_FRAME
Definition: vf_overlay.c:77
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:79
s
#define s(width, name)
Definition: cbs_vp9.c:257
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:101
OVERLAY_FORMAT_YUV422
@ OVERLAY_FORMAT_YUV422
Definition: vf_overlay.h:44
AV_CEIL_RSHIFT
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:58
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
AVFrame::pkt_pos
int64_t pkt_pos
reordered pos from the last AVPacket that has been input into the decoder
Definition: frame.h:571
blend_slice_yuv
static av_always_inline void blend_slice_yuv(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:569
ff_formats_ref
int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
Add *ref as a new reference to formats.
Definition: formats.c:484
slice_end
static int slice_end(AVCodecContext *avctx, AVFrame *pict)
Handle slice ends.
Definition: mpeg12dec.c:2040
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:37
outputs
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
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:197
ctx
AVFormatContext * ctx
Definition: movenc.c:48
av_expr_eval
double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
Evaluate a previously parsed expression.
Definition: eval.c:766
UNPREMULTIPLY_ALPHA
#define UNPREMULTIPLY_ALPHA(x, y)
Definition: vf_overlay.c:319
AVExpr
Definition: eval.c:157
AVPixFmtDescriptor::log2_chroma_w
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:92
vf_overlay.h
B
#define B
Definition: vf_overlay.c:68
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
eval_expr
static void eval_expr(AVFilterContext *ctx)
Definition: vf_overlay.c:97
EOF_ACTION_PASS
@ EOF_ACTION_PASS
Definition: framesync.h:29
VAR_X
@ VAR_X
Definition: vf_blend.c:52
NAN
#define NAN
Definition: mathematics.h:64
AV_PIX_FMT_YUVJ444P
@ AV_PIX_FMT_YUVJ444P
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
Definition: pixfmt.h:80
AV_PIX_FMT_RGBA
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:93
arg
const char * arg
Definition: jacosubdec.c:66
option
option
Definition: libkvazaar.c:291
ThreadData::dst
AVFrame * dst
Definition: vf_blend.c:56
config_input_overlay
static int config_input_overlay(AVFilterLink *inlink)
Definition: vf_overlay.c:248
NULL
#define NULL
Definition: coverity.c:32
EVAL_MODE_NB
@ EVAL_MODE_NB
Definition: vf_overlay.c:78
fs
#define fs(width, name, subs,...)
Definition: cbs_vp9.c:259
ThreadData::src
const uint8_t * src
Definition: vf_bm3d.c:56
blend_slice_yuva444_pm
static int blend_slice_yuva444_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:730
isnan
#define isnan(x)
Definition: libm.h:340
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: vf_overlay.c:81
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:78
src
#define src
Definition: vp8dsp.c:254
OverlayContext
Definition: vf_overlay.h:52
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:271
VAR_Y
@ VAR_Y
Definition: vf_blend.c:52
blend_slice_yuv420_pm
static int blend_slice_yuv420_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:690
inputs
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several inputs
Definition: filter_design.txt:243
AV_PIX_FMT_ABGR
@ AV_PIX_FMT_ABGR
packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
Definition: pixfmt.h:94
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
avfilter_vf_overlay_inputs
static const AVFilterPad avfilter_vf_overlay_inputs[]
Definition: vf_overlay.c:990
for
for(j=16;j >0;--j)
Definition: h264pred_template.c:469
eval.h
AV_PIX_FMT_RGB24
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:68
A
#define A
Definition: vf_overlay.c:69
overlay_options
static const AVOption overlay_options[]
Definition: vf_overlay.c:961
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:188
ff_framesync_init_dualinput
int ff_framesync_init_dualinput(FFFrameSync *fs, AVFilterContext *parent)
Initialize a frame sync structure for dualinput.
Definition: framesync.c:351
OVERLAY_FORMAT_NB
@ OVERLAY_FORMAT_NB
Definition: vf_overlay.h:49
sp
#define sp
Definition: regdef.h:63
FFMAX
#define FFMAX(a, b)
Definition: common.h:94
OVERLAY_FORMAT_YUV420
@ OVERLAY_FORMAT_YUV420
Definition: vf_overlay.h:43
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
VAR_MH
@ VAR_MH
Definition: vf_overlay.h:29
config_output
static int config_output(AVFilterLink *outlink)
Definition: vf_overlay.c:295
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
FFMIN
#define FFMIN(a, b)
Definition: common.h:96
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:177
OVERLAY_FORMAT_AUTO
@ OVERLAY_FORMAT_AUTO
Definition: vf_overlay.h:48
blend_slice_rgba
static int blend_slice_rgba(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:762
internal.h
blend_slice_yuva420_pm
static int blend_slice_yuva420_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:698
AV_PIX_FMT_ARGB
@ AV_PIX_FMT_ARGB
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition: pixfmt.h:92
FLAGS
#define FLAGS
Definition: vf_overlay.c:959
blend_slice_gbrap_pm
static int blend_slice_gbrap_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:746
blend_slice_yuva444
static int blend_slice_yuva444(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:666
blend_slice_rgba_pm
static int blend_slice_rgba_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:778
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
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:597
blend_plane
static av_always_inline void blend_plane(AVFilterContext *ctx, AVFrame *dst, const AVFrame *src, int src_w, int src_h, int dst_w, int dst_h, int i, int hsub, int vsub, int x, int y, int main_has_alpha, int dst_plane, int dst_offset, int dst_step, int straight, int yuv, int jobnr, int nb_jobs)
Definition: vf_overlay.c:412
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:784
ThreadData
Used for passing data between threads.
Definition: dsddec.c:67
EvalMode
EvalMode
Definition: af_volume.h:39
av_always_inline
#define av_always_inline
Definition: attributes.h:49
uint8_t
uint8_t
Definition: audio_convert.c:194
AV_PIX_FMT_NV21
@ AV_PIX_FMT_NV21
as above, but U and V bytes are swapped
Definition: pixfmt.h:90
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:60
blend_slice_gbrp
static int blend_slice_gbrp(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:674
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:90
blend_slice_yuv444
static int blend_slice_yuv444(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:658
AVFilter
Filter definition.
Definition: avfilter.h:144
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:130
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:89
MAIN
#define MAIN
Definition: vf_overlay.c:63
pos
unsigned int pos
Definition: spdifenc.c:412
EOF_ACTION_REPEAT
@ EOF_ACTION_REPEAT
Definition: framesync.h:27
blend_slice_yuva422
static int blend_slice_yuva422(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:650
AVFrame::height
int height
Definition: frame.h:358
framesync.h
OverlayContext::blend_row
int(* blend_row[4])(uint8_t *d, uint8_t *da, uint8_t *s, uint8_t *a, int w, ptrdiff_t alinesize)
Definition: vf_overlay.h:78
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:223
avfilter.h
activate
static int activate(AVFilterContext *ctx)
Definition: vf_overlay.c:952
VAR_N
@ VAR_N
Definition: aeval.c:48
G
#define G
Definition: vf_overlay.c:67
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:71
blend_slice_yuv444_pm
static int blend_slice_yuv444_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:722
AVFilterContext
An instance of a filter.
Definition: avfilter.h:338
AV_PIX_FMT_GBRP
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:168
OVERLAY_FORMAT_GBRP
@ OVERLAY_FORMAT_GBRP
Definition: vf_overlay.h:47
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:116
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
AV_PIX_FMT_YUV422P
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:70
OVERLAY_FORMAT_YUV444
@ OVERLAY_FORMAT_YUV444
Definition: vf_overlay.h:45
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
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
Definition: opt.h:240
EVAL_MODE_INIT
@ EVAL_MODE_INIT
Definition: vf_overlay.c:76
ff_fill_rgba_map
int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt)
Definition: drawutils.c:35
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:133
imgutils.h
timestamp.h
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:565
AVFrame::linesize
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:331
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
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:334
avstring.h
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:227
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:389
drawutils.h
alpha_pix_fmts
static enum AVPixelFormat alpha_pix_fmts[]
Definition: vf_overlay.c:155
OFFSET
#define OFFSET(x)
Definition: vf_overlay.c:958
VAR_OVERLAY_W
@ VAR_OVERLAY_W
Definition: vf_overlay.h:30
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:232
alpha_composite
static void alpha_composite(const AVFrame *src, const AVFrame *dst, int src_w, int src_h, int dst_w, int dst_h, int x, int y, int jobnr, int nb_jobs)
Definition: vf_overlay.c:521
blend_slice_yuva420
static int blend_slice_yuva420(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:634
AVPixFmtDescriptor::log2_chroma_h
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:101
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:176
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:2465
blend_slice_yuv422_pm
static int blend_slice_yuv422_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:706
init
static av_cold int init(AVFilterContext *ctx)
Definition: vf_overlay.c:944