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 {
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  AVFilterFormats *main_formats = NULL;
209  AVFilterFormats *overlay_formats = NULL;
210  int ret;
211 
212  switch (s->format) {
214  if (!(main_formats = ff_make_format_list(main_pix_fmts_yuv420)) ||
215  !(overlay_formats = ff_make_format_list(overlay_pix_fmts_yuv420))) {
216  ret = AVERROR(ENOMEM);
217  goto fail;
218  }
219  break;
221  if (!(main_formats = ff_make_format_list(main_pix_fmts_yuv422)) ||
222  !(overlay_formats = ff_make_format_list(overlay_pix_fmts_yuv422))) {
223  ret = AVERROR(ENOMEM);
224  goto fail;
225  }
226  break;
228  if (!(main_formats = ff_make_format_list(main_pix_fmts_yuv444)) ||
229  !(overlay_formats = ff_make_format_list(overlay_pix_fmts_yuv444))) {
230  ret = AVERROR(ENOMEM);
231  goto fail;
232  }
233  break;
234  case OVERLAY_FORMAT_RGB:
235  if (!(main_formats = ff_make_format_list(main_pix_fmts_rgb)) ||
236  !(overlay_formats = ff_make_format_list(overlay_pix_fmts_rgb))) {
237  ret = AVERROR(ENOMEM);
238  goto fail;
239  }
240  break;
241  case OVERLAY_FORMAT_GBRP:
242  if (!(main_formats = ff_make_format_list(main_pix_fmts_gbrp)) ||
243  !(overlay_formats = ff_make_format_list(overlay_pix_fmts_gbrp))) {
244  ret = AVERROR(ENOMEM);
245  goto fail;
246  }
247  break;
248  case OVERLAY_FORMAT_AUTO:
249  if (!(main_formats = ff_make_format_list(alpha_pix_fmts))) {
250  ret = AVERROR(ENOMEM);
251  goto fail;
252  }
253  break;
254  default:
255  av_assert0(0);
256  }
257 
258  if (s->format == OVERLAY_FORMAT_AUTO) {
259  ret = ff_set_common_formats(ctx, main_formats);
260  if (ret < 0)
261  goto fail;
262  } else {
263  if ((ret = ff_formats_ref(main_formats , &ctx->inputs[MAIN]->out_formats )) < 0 ||
264  (ret = ff_formats_ref(overlay_formats, &ctx->inputs[OVERLAY]->out_formats)) < 0 ||
265  (ret = ff_formats_ref(main_formats , &ctx->outputs[MAIN]->in_formats )) < 0)
266  goto fail;
267  }
268 
269  return 0;
270 fail:
271  if (main_formats)
272  av_freep(&main_formats->formats);
273  av_freep(&main_formats);
274  if (overlay_formats)
275  av_freep(&overlay_formats->formats);
276  av_freep(&overlay_formats);
277  return ret;
278 }
279 
281 {
282  AVFilterContext *ctx = inlink->dst;
283  OverlayContext *s = inlink->dst->priv;
284  int ret;
285  const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format);
286 
287  av_image_fill_max_pixsteps(s->overlay_pix_step, NULL, pix_desc);
288 
289  /* Finish the configuration by evaluating the expressions
290  now when both inputs are configured. */
291  s->var_values[VAR_MAIN_W ] = s->var_values[VAR_MW] = ctx->inputs[MAIN ]->w;
292  s->var_values[VAR_MAIN_H ] = s->var_values[VAR_MH] = ctx->inputs[MAIN ]->h;
293  s->var_values[VAR_OVERLAY_W] = s->var_values[VAR_OW] = ctx->inputs[OVERLAY]->w;
294  s->var_values[VAR_OVERLAY_H] = s->var_values[VAR_OH] = ctx->inputs[OVERLAY]->h;
295  s->var_values[VAR_HSUB] = 1<<pix_desc->log2_chroma_w;
296  s->var_values[VAR_VSUB] = 1<<pix_desc->log2_chroma_h;
297  s->var_values[VAR_X] = NAN;
298  s->var_values[VAR_Y] = NAN;
299  s->var_values[VAR_N] = 0;
300  s->var_values[VAR_T] = NAN;
301  s->var_values[VAR_POS] = NAN;
302 
303  if ((ret = set_expr(&s->x_pexpr, s->x_expr, "x", ctx)) < 0 ||
304  (ret = set_expr(&s->y_pexpr, s->y_expr, "y", ctx)) < 0)
305  return ret;
306 
307  s->overlay_is_packed_rgb =
308  ff_fill_rgba_map(s->overlay_rgba_map, inlink->format) >= 0;
309  s->overlay_has_alpha = ff_fmt_is_in(inlink->format, alpha_pix_fmts);
310 
311  if (s->eval_mode == EVAL_MODE_INIT) {
312  eval_expr(ctx);
313  av_log(ctx, AV_LOG_VERBOSE, "x:%f xi:%d y:%f yi:%d\n",
314  s->var_values[VAR_X], s->x,
315  s->var_values[VAR_Y], s->y);
316  }
317 
319  "main w:%d h:%d fmt:%s overlay w:%d h:%d fmt:%s\n",
320  ctx->inputs[MAIN]->w, ctx->inputs[MAIN]->h,
321  av_get_pix_fmt_name(ctx->inputs[MAIN]->format),
322  ctx->inputs[OVERLAY]->w, ctx->inputs[OVERLAY]->h,
323  av_get_pix_fmt_name(ctx->inputs[OVERLAY]->format));
324  return 0;
325 }
326 
327 static int config_output(AVFilterLink *outlink)
328 {
329  AVFilterContext *ctx = outlink->src;
330  OverlayContext *s = ctx->priv;
331  int ret;
332 
333  if ((ret = ff_framesync_init_dualinput(&s->fs, ctx)) < 0)
334  return ret;
335 
336  outlink->w = ctx->inputs[MAIN]->w;
337  outlink->h = ctx->inputs[MAIN]->h;
338  outlink->time_base = ctx->inputs[MAIN]->time_base;
339 
340  return ff_framesync_configure(&s->fs);
341 }
342 
343 // divide by 255 and round to nearest
344 // apply a fast variant: (X+127)/255 = ((X+127)*257+257)>>16 = ((X+128)*257)>>16
345 #define FAST_DIV255(x) ((((x) + 128) * 257) >> 16)
346 
347 // calculate the unpremultiplied alpha, applying the general equation:
348 // alpha = alpha_overlay / ( (alpha_main + alpha_overlay) - (alpha_main * alpha_overlay) )
349 // (((x) << 16) - ((x) << 9) + (x)) is a faster version of: 255 * 255 * x
350 // ((((x) + (y)) << 8) - ((x) + (y)) - (y) * (x)) is a faster version of: 255 * (x + y)
351 #define UNPREMULTIPLY_ALPHA(x, y) ((((x) << 16) - ((x) << 9) + (x)) / ((((x) + (y)) << 8) - ((x) + (y)) - (y) * (x)))
352 
353 /**
354  * Blend image in src to destination buffer dst at position (x, y).
355  */
356 
358  AVFrame *dst, const AVFrame *src,
359  int main_has_alpha, int x, int y,
360  int is_straight, int jobnr, int nb_jobs)
361 {
362  OverlayContext *s = ctx->priv;
363  int i, imax, j, jmax;
364  const int src_w = src->width;
365  const int src_h = src->height;
366  const int dst_w = dst->width;
367  const int dst_h = dst->height;
368  uint8_t alpha; ///< the amount of overlay to blend on to main
369  const int dr = s->main_rgba_map[R];
370  const int dg = s->main_rgba_map[G];
371  const int db = s->main_rgba_map[B];
372  const int da = s->main_rgba_map[A];
373  const int dstep = s->main_pix_step[0];
374  const int sr = s->overlay_rgba_map[R];
375  const int sg = s->overlay_rgba_map[G];
376  const int sb = s->overlay_rgba_map[B];
377  const int sa = s->overlay_rgba_map[A];
378  const int sstep = s->overlay_pix_step[0];
379  int slice_start, slice_end;
380  uint8_t *S, *sp, *d, *dp;
381 
382  i = FFMAX(-y, 0);
383  imax = FFMIN3(-y + dst_h, FFMIN(src_h, dst_h), y + src_h);
384 
385  slice_start = i + (imax * jobnr) / nb_jobs;
386  slice_end = i + (imax * (jobnr+1)) / nb_jobs;
387 
388  sp = src->data[0] + (slice_start) * src->linesize[0];
389  dp = dst->data[0] + (y + slice_start) * dst->linesize[0];
390 
391  for (i = slice_start; i < slice_end; i++) {
392  j = FFMAX(-x, 0);
393  S = sp + j * sstep;
394  d = dp + (x+j) * dstep;
395 
396  for (jmax = FFMIN(-x + dst_w, src_w); j < jmax; j++) {
397  alpha = S[sa];
398 
399  // if the main channel has an alpha channel, alpha has to be calculated
400  // to create an un-premultiplied (straight) alpha value
401  if (main_has_alpha && alpha != 0 && alpha != 255) {
402  uint8_t alpha_d = d[da];
403  alpha = UNPREMULTIPLY_ALPHA(alpha, alpha_d);
404  }
405 
406  switch (alpha) {
407  case 0:
408  break;
409  case 255:
410  d[dr] = S[sr];
411  d[dg] = S[sg];
412  d[db] = S[sb];
413  break;
414  default:
415  // main_value = main_value * (1 - alpha) + overlay_value * alpha
416  // since alpha is in the range 0-255, the result must divided by 255
417  d[dr] = is_straight ? FAST_DIV255(d[dr] * (255 - alpha) + S[sr] * alpha) :
418  FFMIN(FAST_DIV255(d[dr] * (255 - alpha)) + S[sr], 255);
419  d[dg] = is_straight ? FAST_DIV255(d[dg] * (255 - alpha) + S[sg] * alpha) :
420  FFMIN(FAST_DIV255(d[dg] * (255 - alpha)) + S[sg], 255);
421  d[db] = is_straight ? FAST_DIV255(d[db] * (255 - alpha) + S[sb] * alpha) :
422  FFMIN(FAST_DIV255(d[db] * (255 - alpha)) + S[sb], 255);
423  }
424  if (main_has_alpha) {
425  switch (alpha) {
426  case 0:
427  break;
428  case 255:
429  d[da] = S[sa];
430  break;
431  default:
432  // apply alpha compositing: main_alpha += (1-main_alpha) * overlay_alpha
433  d[da] += FAST_DIV255((255 - d[da]) * S[sa]);
434  }
435  }
436  d += dstep;
437  S += sstep;
438  }
439  dp += dst->linesize[0];
440  sp += src->linesize[0];
441  }
442 }
443 
445  AVFrame *dst, const AVFrame *src,
446  int src_w, int src_h,
447  int dst_w, int dst_h,
448  int i, int hsub, int vsub,
449  int x, int y,
450  int main_has_alpha,
451  int dst_plane,
452  int dst_offset,
453  int dst_step,
454  int straight,
455  int yuv,
456  int jobnr,
457  int nb_jobs)
458 {
459  OverlayContext *octx = ctx->priv;
460  int src_wp = AV_CEIL_RSHIFT(src_w, hsub);
461  int src_hp = AV_CEIL_RSHIFT(src_h, vsub);
462  int dst_wp = AV_CEIL_RSHIFT(dst_w, hsub);
463  int dst_hp = AV_CEIL_RSHIFT(dst_h, vsub);
464  int yp = y>>vsub;
465  int xp = x>>hsub;
466  uint8_t *s, *sp, *d, *dp, *dap, *a, *da, *ap;
467  int jmax, j, k, kmax;
468  int slice_start, slice_end;
469 
470  j = FFMAX(-yp, 0);
471  jmax = FFMIN3(-yp + dst_hp, FFMIN(src_hp, dst_hp), yp + src_hp);
472 
473  slice_start = j + (jmax * jobnr) / nb_jobs;
474  slice_end = j + (jmax * (jobnr+1)) / nb_jobs;
475 
476  sp = src->data[i] + (slice_start) * src->linesize[i];
477  dp = dst->data[dst_plane]
478  + (yp + slice_start) * dst->linesize[dst_plane]
479  + dst_offset;
480  ap = src->data[3] + (slice_start << vsub) * src->linesize[3];
481  dap = dst->data[3] + ((yp + slice_start) << vsub) * dst->linesize[3];
482 
483  for (j = slice_start; j < slice_end; j++) {
484  k = FFMAX(-xp, 0);
485  d = dp + (xp+k) * dst_step;
486  s = sp + k;
487  a = ap + (k<<hsub);
488  da = dap + ((xp+k) << hsub);
489  kmax = FFMIN(-xp + dst_wp, src_wp);
490 
491  if (((vsub && j+1 < src_hp) || !vsub) && octx->blend_row[i]) {
492  int c = octx->blend_row[i](d, da, s, a, kmax - k, src->linesize[3]);
493 
494  s += c;
495  d += dst_step * c;
496  da += (1 << hsub) * c;
497  a += (1 << hsub) * c;
498  k += c;
499  }
500  for (; k < kmax; k++) {
501  int alpha_v, alpha_h, alpha;
502 
503  // average alpha for color components, improve quality
504  if (hsub && vsub && j+1 < src_hp && k+1 < src_wp) {
505  alpha = (a[0] + a[src->linesize[3]] +
506  a[1] + a[src->linesize[3]+1]) >> 2;
507  } else if (hsub || vsub) {
508  alpha_h = hsub && k+1 < src_wp ?
509  (a[0] + a[1]) >> 1 : a[0];
510  alpha_v = vsub && j+1 < src_hp ?
511  (a[0] + a[src->linesize[3]]) >> 1 : a[0];
512  alpha = (alpha_v + alpha_h) >> 1;
513  } else
514  alpha = a[0];
515  // if the main channel has an alpha channel, alpha has to be calculated
516  // to create an un-premultiplied (straight) alpha value
517  if (main_has_alpha && alpha != 0 && alpha != 255) {
518  // average alpha for color components, improve quality
519  uint8_t alpha_d;
520  if (hsub && vsub && j+1 < src_hp && k+1 < src_wp) {
521  alpha_d = (da[0] + da[dst->linesize[3]] +
522  da[1] + da[dst->linesize[3]+1]) >> 2;
523  } else if (hsub || vsub) {
524  alpha_h = hsub && k+1 < src_wp ?
525  (da[0] + da[1]) >> 1 : da[0];
526  alpha_v = vsub && j+1 < src_hp ?
527  (da[0] + da[dst->linesize[3]]) >> 1 : da[0];
528  alpha_d = (alpha_v + alpha_h) >> 1;
529  } else
530  alpha_d = da[0];
531  alpha = UNPREMULTIPLY_ALPHA(alpha, alpha_d);
532  }
533  if (straight) {
534  *d = FAST_DIV255(*d * (255 - alpha) + *s * alpha);
535  } else {
536  if (i && yuv)
537  *d = av_clip(FAST_DIV255((*d - 128) * (255 - alpha)) + *s - 128, -128, 128) + 128;
538  else
539  *d = FFMIN(FAST_DIV255(*d * (255 - alpha)) + *s, 255);
540  }
541  s++;
542  d += dst_step;
543  da += 1 << hsub;
544  a += 1 << hsub;
545  }
546  dp += dst->linesize[dst_plane];
547  sp += src->linesize[i];
548  ap += (1 << vsub) * src->linesize[3];
549  dap += (1 << vsub) * dst->linesize[3];
550  }
551 }
552 
553 static inline void alpha_composite(const AVFrame *src, const AVFrame *dst,
554  int src_w, int src_h,
555  int dst_w, int dst_h,
556  int x, int y,
557  int jobnr, int nb_jobs)
558 {
559  uint8_t alpha; ///< the amount of overlay to blend on to main
560  uint8_t *s, *sa, *d, *da;
561  int i, imax, j, jmax;
562  int slice_start, slice_end;
563 
564  imax = FFMIN(-y + dst_h, src_h);
565  slice_start = (imax * jobnr) / nb_jobs;
566  slice_end = ((imax * (jobnr+1)) / nb_jobs);
567 
568  i = FFMAX(-y, 0);
569  sa = src->data[3] + (i + slice_start) * src->linesize[3];
570  da = dst->data[3] + (y + i + slice_start) * dst->linesize[3];
571 
572  for (i = i + slice_start; i < slice_end; i++) {
573  j = FFMAX(-x, 0);
574  s = sa + j;
575  d = da + x+j;
576 
577  for (jmax = FFMIN(-x + dst_w, src_w); j < jmax; j++) {
578  alpha = *s;
579  if (alpha != 0 && alpha != 255) {
580  uint8_t alpha_d = *d;
581  alpha = UNPREMULTIPLY_ALPHA(alpha, alpha_d);
582  }
583  switch (alpha) {
584  case 0:
585  break;
586  case 255:
587  *d = *s;
588  break;
589  default:
590  // apply alpha compositing: main_alpha += (1-main_alpha) * overlay_alpha
591  *d += FAST_DIV255((255 - *d) * *s);
592  }
593  d += 1;
594  s += 1;
595  }
596  da += dst->linesize[3];
597  sa += src->linesize[3];
598  }
599 }
600 
602  AVFrame *dst, const AVFrame *src,
603  int hsub, int vsub,
604  int main_has_alpha,
605  int x, int y,
606  int is_straight,
607  int jobnr, int nb_jobs)
608 {
609  OverlayContext *s = ctx->priv;
610  const int src_w = src->width;
611  const int src_h = src->height;
612  const int dst_w = dst->width;
613  const int dst_h = dst->height;
614 
615  blend_plane(ctx, dst, src, src_w, src_h, dst_w, dst_h, 0, 0, 0, x, y, main_has_alpha,
616  s->main_desc->comp[0].plane, s->main_desc->comp[0].offset, s->main_desc->comp[0].step, is_straight, 1,
617  jobnr, nb_jobs);
618  blend_plane(ctx, dst, src, src_w, src_h, dst_w, dst_h, 1, hsub, vsub, x, y, main_has_alpha,
619  s->main_desc->comp[1].plane, s->main_desc->comp[1].offset, s->main_desc->comp[1].step, is_straight, 1,
620  jobnr, nb_jobs);
621  blend_plane(ctx, dst, src, src_w, src_h, dst_w, dst_h, 2, hsub, vsub, x, y, main_has_alpha,
622  s->main_desc->comp[2].plane, s->main_desc->comp[2].offset, s->main_desc->comp[2].step, is_straight, 1,
623  jobnr, nb_jobs);
624 
625  if (main_has_alpha)
626  alpha_composite(src, dst, src_w, src_h, dst_w, dst_h, x, y, jobnr, nb_jobs);
627 }
628 
630  AVFrame *dst, const AVFrame *src,
631  int hsub, int vsub,
632  int main_has_alpha,
633  int x, int y,
634  int is_straight,
635  int jobnr,
636  int nb_jobs)
637 {
638  OverlayContext *s = ctx->priv;
639  const int src_w = src->width;
640  const int src_h = src->height;
641  const int dst_w = dst->width;
642  const int dst_h = dst->height;
643 
644  blend_plane(ctx, dst, src, src_w, src_h, dst_w, dst_h, 0, 0, 0, x, y, main_has_alpha,
645  s->main_desc->comp[1].plane, s->main_desc->comp[1].offset, s->main_desc->comp[1].step, is_straight, 0,
646  jobnr, nb_jobs);
647  blend_plane(ctx, dst, src, src_w, src_h, dst_w, dst_h, 1, hsub, vsub, x, y, main_has_alpha,
648  s->main_desc->comp[2].plane, s->main_desc->comp[2].offset, s->main_desc->comp[2].step, is_straight, 0,
649  jobnr, nb_jobs);
650  blend_plane(ctx, dst, src, src_w, src_h, dst_w, dst_h, 2, hsub, vsub, x, y, main_has_alpha,
651  s->main_desc->comp[0].plane, s->main_desc->comp[0].offset, s->main_desc->comp[0].step, is_straight, 0,
652  jobnr, nb_jobs);
653 
654  if (main_has_alpha)
655  alpha_composite(src, dst, src_w, src_h, dst_w, dst_h, x, y, jobnr, nb_jobs);
656 }
657 
658 static int blend_slice_yuv420(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, 1, 1, 0, s->x, s->y, 1, jobnr, nb_jobs);
663  return 0;
664 }
665 
666 static int blend_slice_yuva420(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, 1, 1, 1, s->x, s->y, 1, jobnr, nb_jobs);
671  return 0;
672 }
673 
674 static int blend_slice_yuv422(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
675 {
676  OverlayContext *s = ctx->priv;
677  ThreadData *td = arg;
678  blend_slice_yuv(ctx, td->dst, td->src, 1, 0, 0, s->x, s->y, 1, jobnr, nb_jobs);
679  return 0;
680 }
681 
682 static int blend_slice_yuva422(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
683 {
684  OverlayContext *s = ctx->priv;
685  ThreadData *td = arg;
686  blend_slice_yuv(ctx, td->dst, td->src, 1, 0, 1, s->x, s->y, 1, jobnr, nb_jobs);
687  return 0;
688 }
689 
690 static int blend_slice_yuv444(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, 0, 0, 0, s->x, s->y, 1, jobnr, nb_jobs);
695  return 0;
696 }
697 
698 static int blend_slice_yuva444(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, 0, 0, 1, s->x, s->y, 1, jobnr, nb_jobs);
703  return 0;
704 }
705 
706 static int blend_slice_gbrp(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
707 {
708  OverlayContext *s = ctx->priv;
709  ThreadData *td = arg;
710  blend_slice_planar_rgb(ctx, td->dst, td->src, 0, 0, 0, s->x, s->y, 1, jobnr, nb_jobs);
711  return 0;
712 }
713 
714 static int blend_slice_gbrap(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
715 {
716  OverlayContext *s = ctx->priv;
717  ThreadData *td = arg;
718  blend_slice_planar_rgb(ctx, td->dst, td->src, 0, 0, 1, s->x, s->y, 1, jobnr, nb_jobs);
719  return 0;
720 }
721 
722 static int blend_slice_yuv420_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, 1, 1, 0, s->x, s->y, 0, jobnr, nb_jobs);
727  return 0;
728 }
729 
730 static int blend_slice_yuva420_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, 1, 1, 1, s->x, s->y, 0, jobnr, nb_jobs);
735  return 0;
736 }
737 
738 static int blend_slice_yuv422_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
739 {
740  OverlayContext *s = ctx->priv;
741  ThreadData *td = arg;
742  blend_slice_yuv(ctx, td->dst, td->src, 1, 0, 0, s->x, s->y, 0, jobnr, nb_jobs);
743  return 0;
744 }
745 
746 static int blend_slice_yuva422_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
747 {
748  OverlayContext *s = ctx->priv;
749  ThreadData *td = arg;
750  blend_slice_yuv(ctx, td->dst, td->src, 1, 0, 1, s->x, s->y, 0, jobnr, nb_jobs);
751  return 0;
752 }
753 
754 static int blend_slice_yuv444_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
755 {
756  OverlayContext *s = ctx->priv;
757  ThreadData *td = arg;
758  blend_slice_yuv(ctx, td->dst, td->src, 0, 0, 0, s->x, s->y, 0, jobnr, nb_jobs);
759  return 0;
760 }
761 
762 static int blend_slice_yuva444_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
763 {
764  OverlayContext *s = ctx->priv;
765  ThreadData *td = arg;
766  blend_slice_yuv(ctx, td->dst, td->src, 0, 0, 1, s->x, s->y, 0, jobnr, nb_jobs);
767  return 0;
768 }
769 
770 static int blend_slice_gbrp_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
771 {
772  OverlayContext *s = ctx->priv;
773  ThreadData *td = arg;
774  blend_slice_planar_rgb(ctx, td->dst, td->src, 0, 0, 0, s->x, s->y, 0, jobnr, nb_jobs);
775  return 0;
776 }
777 
778 static int blend_slice_gbrap_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
779 {
780  OverlayContext *s = ctx->priv;
781  ThreadData *td = arg;
782  blend_slice_planar_rgb(ctx, td->dst, td->src, 0, 0, 1, s->x, s->y, 0, jobnr, nb_jobs);
783  return 0;
784 }
785 
786 static int blend_slice_rgb(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
787 {
788  OverlayContext *s = ctx->priv;
789  ThreadData *td = arg;
790  blend_slice_packed_rgb(ctx, td->dst, td->src, 0, s->x, s->y, 1, jobnr, nb_jobs);
791  return 0;
792 }
793 
794 static int blend_slice_rgba(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
795 {
796  OverlayContext *s = ctx->priv;
797  ThreadData *td = arg;
798  blend_slice_packed_rgb(ctx, td->dst, td->src, 1, s->x, s->y, 1, jobnr, nb_jobs);
799  return 0;
800 }
801 
802 static int blend_slice_rgb_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
803 {
804  OverlayContext *s = ctx->priv;
805  ThreadData *td = arg;
806  blend_slice_packed_rgb(ctx, td->dst, td->src, 0, s->x, s->y, 0, jobnr, nb_jobs);
807  return 0;
808 }
809 
810 static int blend_slice_rgba_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
811 {
812  OverlayContext *s = ctx->priv;
813  ThreadData *td = arg;
814  blend_slice_packed_rgb(ctx, td->dst, td->src, 1, s->x, s->y, 0, jobnr, nb_jobs);
815  return 0;
816 }
817 
819 {
820  OverlayContext *s = inlink->dst->priv;
821  const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format);
822 
823  av_image_fill_max_pixsteps(s->main_pix_step, NULL, pix_desc);
824 
825  s->hsub = pix_desc->log2_chroma_w;
826  s->vsub = pix_desc->log2_chroma_h;
827 
828  s->main_desc = pix_desc;
829 
830  s->main_is_packed_rgb =
831  ff_fill_rgba_map(s->main_rgba_map, inlink->format) >= 0;
832  s->main_has_alpha = ff_fmt_is_in(inlink->format, alpha_pix_fmts);
833  switch (s->format) {
835  s->blend_slice = s->main_has_alpha ? blend_slice_yuva420 : blend_slice_yuv420;
836  break;
838  s->blend_slice = s->main_has_alpha ? blend_slice_yuva422 : blend_slice_yuv422;
839  break;
841  s->blend_slice = s->main_has_alpha ? blend_slice_yuva444 : blend_slice_yuv444;
842  break;
843  case OVERLAY_FORMAT_RGB:
844  s->blend_slice = s->main_has_alpha ? blend_slice_rgba : blend_slice_rgb;
845  break;
846  case OVERLAY_FORMAT_GBRP:
847  s->blend_slice = s->main_has_alpha ? blend_slice_gbrap : blend_slice_gbrp;
848  break;
849  case OVERLAY_FORMAT_AUTO:
850  switch (inlink->format) {
851  case AV_PIX_FMT_YUVA420P:
852  s->blend_slice = blend_slice_yuva420;
853  break;
854  case AV_PIX_FMT_YUVA422P:
855  s->blend_slice = blend_slice_yuva422;
856  break;
857  case AV_PIX_FMT_YUVA444P:
858  s->blend_slice = blend_slice_yuva444;
859  break;
860  case AV_PIX_FMT_ARGB:
861  case AV_PIX_FMT_RGBA:
862  case AV_PIX_FMT_BGRA:
863  case AV_PIX_FMT_ABGR:
864  s->blend_slice = blend_slice_rgba;
865  break;
866  case AV_PIX_FMT_GBRAP:
867  s->blend_slice = blend_slice_gbrap;
868  break;
869  default:
870  av_assert0(0);
871  break;
872  }
873  break;
874  }
875 
876  if (!s->alpha_format)
877  goto end;
878 
879  switch (s->format) {
881  s->blend_slice = s->main_has_alpha ? blend_slice_yuva420_pm : blend_slice_yuv420_pm;
882  break;
884  s->blend_slice = s->main_has_alpha ? blend_slice_yuva422_pm : blend_slice_yuv422_pm;
885  break;
887  s->blend_slice = s->main_has_alpha ? blend_slice_yuva444_pm : blend_slice_yuv444_pm;
888  break;
889  case OVERLAY_FORMAT_RGB:
890  s->blend_slice = s->main_has_alpha ? blend_slice_rgba_pm : blend_slice_rgb_pm;
891  break;
892  case OVERLAY_FORMAT_GBRP:
893  s->blend_slice = s->main_has_alpha ? blend_slice_gbrap_pm : blend_slice_gbrp_pm;
894  break;
895  case OVERLAY_FORMAT_AUTO:
896  switch (inlink->format) {
897  case AV_PIX_FMT_YUVA420P:
898  s->blend_slice = blend_slice_yuva420_pm;
899  break;
900  case AV_PIX_FMT_YUVA422P:
901  s->blend_slice = blend_slice_yuva422_pm;
902  break;
903  case AV_PIX_FMT_YUVA444P:
904  s->blend_slice = blend_slice_yuva444_pm;
905  break;
906  case AV_PIX_FMT_ARGB:
907  case AV_PIX_FMT_RGBA:
908  case AV_PIX_FMT_BGRA:
909  case AV_PIX_FMT_ABGR:
910  s->blend_slice = blend_slice_rgba_pm;
911  break;
912  case AV_PIX_FMT_GBRAP:
913  s->blend_slice = blend_slice_gbrap_pm;
914  break;
915  default:
916  av_assert0(0);
917  break;
918  }
919  break;
920  }
921 
922 end:
923  if (ARCH_X86)
924  ff_overlay_init_x86(s, s->format, inlink->format,
925  s->alpha_format, s->main_has_alpha);
926 
927  return 0;
928 }
929 
930 static int do_blend(FFFrameSync *fs)
931 {
932  AVFilterContext *ctx = fs->parent;
933  AVFrame *mainpic, *second;
934  OverlayContext *s = ctx->priv;
935  AVFilterLink *inlink = ctx->inputs[0];
936  int ret;
937 
938  ret = ff_framesync_dualinput_get_writable(fs, &mainpic, &second);
939  if (ret < 0)
940  return ret;
941  if (!second)
942  return ff_filter_frame(ctx->outputs[0], mainpic);
943 
944  if (s->eval_mode == EVAL_MODE_FRAME) {
945  int64_t pos = mainpic->pkt_pos;
946 
947  s->var_values[VAR_N] = inlink->frame_count_out;
948  s->var_values[VAR_T] = mainpic->pts == AV_NOPTS_VALUE ?
949  NAN : mainpic->pts * av_q2d(inlink->time_base);
950  s->var_values[VAR_POS] = pos == -1 ? NAN : pos;
951 
952  s->var_values[VAR_OVERLAY_W] = s->var_values[VAR_OW] = second->width;
953  s->var_values[VAR_OVERLAY_H] = s->var_values[VAR_OH] = second->height;
954  s->var_values[VAR_MAIN_W ] = s->var_values[VAR_MW] = mainpic->width;
955  s->var_values[VAR_MAIN_H ] = s->var_values[VAR_MH] = mainpic->height;
956 
957  eval_expr(ctx);
958  av_log(ctx, AV_LOG_DEBUG, "n:%f t:%f pos:%f x:%f xi:%d y:%f yi:%d\n",
959  s->var_values[VAR_N], s->var_values[VAR_T], s->var_values[VAR_POS],
960  s->var_values[VAR_X], s->x,
961  s->var_values[VAR_Y], s->y);
962  }
963 
964  if (s->x < mainpic->width && s->x + second->width >= 0 &&
965  s->y < mainpic->height && s->y + second->height >= 0) {
966  ThreadData td;
967 
968  td.dst = mainpic;
969  td.src = second;
970  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)),
972  }
973  return ff_filter_frame(ctx->outputs[0], mainpic);
974 }
975 
977 {
978  OverlayContext *s = ctx->priv;
979 
980  s->fs.on_event = do_blend;
981  return 0;
982 }
983 
985 {
986  OverlayContext *s = ctx->priv;
987  return ff_framesync_activate(&s->fs);
988 }
989 
990 #define OFFSET(x) offsetof(OverlayContext, x)
991 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
992 
993 static const AVOption overlay_options[] = {
994  { "x", "set the x expression", OFFSET(x_expr), AV_OPT_TYPE_STRING, {.str = "0"}, CHAR_MIN, CHAR_MAX, FLAGS },
995  { "y", "set the y expression", OFFSET(y_expr), AV_OPT_TYPE_STRING, {.str = "0"}, CHAR_MIN, CHAR_MAX, FLAGS },
996  { "eof_action", "Action to take when encountering EOF from secondary input ",
997  OFFSET(fs.opt_eof_action), AV_OPT_TYPE_INT, { .i64 = EOF_ACTION_REPEAT },
998  EOF_ACTION_REPEAT, EOF_ACTION_PASS, .flags = FLAGS, "eof_action" },
999  { "repeat", "Repeat the previous frame.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_REPEAT }, .flags = FLAGS, "eof_action" },
1000  { "endall", "End both streams.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_ENDALL }, .flags = FLAGS, "eof_action" },
1001  { "pass", "Pass through the main input.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_PASS }, .flags = FLAGS, "eof_action" },
1002  { "eval", "specify when to evaluate expressions", OFFSET(eval_mode), AV_OPT_TYPE_INT, {.i64 = EVAL_MODE_FRAME}, 0, EVAL_MODE_NB-1, FLAGS, "eval" },
1003  { "init", "eval expressions once during initialization", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_INIT}, .flags = FLAGS, .unit = "eval" },
1004  { "frame", "eval expressions per-frame", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_FRAME}, .flags = FLAGS, .unit = "eval" },
1005  { "shortest", "force termination when the shortest input terminates", OFFSET(fs.opt_shortest), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS },
1006  { "format", "set output format", OFFSET(format), AV_OPT_TYPE_INT, {.i64=OVERLAY_FORMAT_YUV420}, 0, OVERLAY_FORMAT_NB-1, FLAGS, "format" },
1007  { "yuv420", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV420}, .flags = FLAGS, .unit = "format" },
1008  { "yuv422", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV422}, .flags = FLAGS, .unit = "format" },
1009  { "yuv444", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV444}, .flags = FLAGS, .unit = "format" },
1010  { "rgb", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_RGB}, .flags = FLAGS, .unit = "format" },
1011  { "gbrp", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_GBRP}, .flags = FLAGS, .unit = "format" },
1012  { "auto", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_AUTO}, .flags = FLAGS, .unit = "format" },
1013  { "repeatlast", "repeat overlay of the last overlay frame", OFFSET(fs.opt_repeatlast), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGS },
1014  { "alpha", "alpha format", OFFSET(alpha_format), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "alpha_format" },
1015  { "straight", "", 0, AV_OPT_TYPE_CONST, {.i64=0}, .flags = FLAGS, .unit = "alpha_format" },
1016  { "premultiplied", "", 0, AV_OPT_TYPE_CONST, {.i64=1}, .flags = FLAGS, .unit = "alpha_format" },
1017  { NULL }
1018 };
1019 
1021 
1023  {
1024  .name = "main",
1025  .type = AVMEDIA_TYPE_VIDEO,
1026  .config_props = config_input_main,
1027  },
1028  {
1029  .name = "overlay",
1030  .type = AVMEDIA_TYPE_VIDEO,
1031  .config_props = config_input_overlay,
1032  },
1033  { NULL }
1034 };
1035 
1037  {
1038  .name = "default",
1039  .type = AVMEDIA_TYPE_VIDEO,
1040  .config_props = config_output,
1041  },
1042  { NULL }
1043 };
1044 
1046  .name = "overlay",
1047  .description = NULL_IF_CONFIG_SMALL("Overlay a video source on top of the input."),
1048  .preinit = overlay_framesync_preinit,
1049  .init = init,
1050  .uninit = uninit,
1051  .priv_size = sizeof(OverlayContext),
1052  .priv_class = &overlay_class,
1054  .activate = activate,
1060 };
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:357
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
blend_slice_rgb
static int blend_slice_rgb(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:786
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:283
ff_framesync_uninit
void ff_framesync_uninit(FFFrameSync *fs)
Free all memory currently allocated.
Definition: framesync.c:293
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1080
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2522
blend_slice_yuv422
static int blend_slice_yuv422(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:674
avfilter_vf_overlay_outputs
static const AVFilterPad avfilter_vf_overlay_outputs[]
Definition: vf_overlay.c:1036
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:90
blend_slice_yuva422_pm
static int blend_slice_yuva422_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:746
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
pixdesc.h
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:388
VAR_Y
@ VAR_Y
Definition: vf_blend.c:51
AVFrame::width
int width
Definition: frame.h:353
do_blend
static int do_blend(FFFrameSync *fs)
Definition: vf_overlay.c:930
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
AVFilterFormats::formats
int * formats
list of media formats
Definition: formats.h:66
blend_slice_yuv420
static int blend_slice_yuv420(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:658
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:1795
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:309
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:714
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:679
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:1045
blend_slice_gbrp_pm
static int blend_slice_gbrp_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:770
AV_PIX_FMT_GBRAP
@ AV_PIX_FMT_GBRAP
planar GBRA 4:4:4:4 32bpp
Definition: pixfmt.h:215
fail
#define fail()
Definition: checkasm.h:120
FAST_DIV255
#define FAST_DIV255(x)
Definition: vf_overlay.c:345
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:334
src
#define src
Definition: vp8dsp.c:254
VAR_X
@ VAR_X
Definition: vf_blend.c:51
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:818
query_formats
static int query_formats(AVFilterContext *ctx)
Definition: vf_overlay.c:161
av_cold
#define av_cold
Definition: attributes.h:84
blend_slice_rgb_pm
static int blend_slice_rgb_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:802
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:568
EVAL_MODE_FRAME
@ EVAL_MODE_FRAME
Definition: vf_overlay.c:77
ThreadData::src
AVFrame * src
Definition: vf_overlay.c:45
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:566
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:601
ff_formats_ref
int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
Add *ref as a new reference to formats.
Definition: formats.c:440
slice_end
static int slice_end(AVCodecContext *avctx, AVFrame *pict)
Handle slice ends.
Definition: mpeg12dec.c:2026
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:734
UNPREMULTIPLY_ALPHA
#define UNPREMULTIPLY_ALPHA(x, y)
Definition: vf_overlay.c:351
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
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
VAR_OW
@ VAR_OW
Definition: scale.c:51
config_input_overlay
static int config_input_overlay(AVFilterLink *inlink)
Definition: vf_overlay.c:280
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
blend_slice_yuva444_pm
static int blend_slice_yuva444_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:762
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
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:254
blend_slice_yuv420_pm
static int blend_slice_yuv420_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:722
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:1022
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:993
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:361
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:327
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:794
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:730
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:991
blend_slice_gbrap_pm
static int blend_slice_gbrap_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:778
blend_slice_yuva444
static int blend_slice_yuva444(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:698
blend_slice_rgba_pm
static int blend_slice_rgba_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:810
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
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:629
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:444
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:802
ThreadData
Used for passing data between threads.
Definition: af_adeclick.c:487
EvalMode
EvalMode
Definition: af_volume.h:39
av_always_inline
#define av_always_inline
Definition: attributes.h:43
args
const char AVS_Value args
Definition: avisynth_c.h:873
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:706
VAR_OVERLAY_H
@ VAR_OVERLAY_H
Definition: vf_overlay.h:31
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:690
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
ThreadData::dst
AVFrame * dst
Definition: vf_blend.c:55
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:682
AVFrame::height
int height
Definition: frame.h:353
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:984
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:754
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
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
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:326
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
VAR_OH
@ VAR_OH
Definition: scale.c:52
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:344
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:399
drawutils.h
alpha_pix_fmts
static enum AVPixelFormat alpha_pix_fmts[]
Definition: vf_overlay.c:155
OFFSET
#define OFFSET(x)
Definition: vf_overlay.c:990
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:553
blend_slice_yuva420
static int blend_slice_yuva420(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:666
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:2438
blend_slice_yuv422_pm
static int blend_slice_yuv422_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:738
init
static av_cold int init(AVFilterContext *ctx)
Definition: vf_overlay.c:976