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 
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 
103  /* It is necessary if x is expressed from y */
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[] = {
160 };
161 
163 {
164  OverlayContext *s = ctx->priv;
165 
166  /* overlay formats contains alpha, for avoiding conversion with alpha information loss */
167  static const enum AVPixelFormat main_pix_fmts_yuv420[] = {
171  };
172  static const enum AVPixelFormat overlay_pix_fmts_yuv420[] = {
173  AV_PIX_FMT_YUVA420P, AV_PIX_FMT_NONE
174  };
175 
176  static const enum AVPixelFormat main_pix_fmts_yuv420p10[] = {
178  AV_PIX_FMT_NONE
179  };
180  static const enum AVPixelFormat overlay_pix_fmts_yuv420p10[] = {
181  AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_NONE
182  };
183 
184  static const enum AVPixelFormat main_pix_fmts_yuv422[] = {
186  };
187  static const enum AVPixelFormat overlay_pix_fmts_yuv422[] = {
188  AV_PIX_FMT_YUVA422P, AV_PIX_FMT_NONE
189  };
190 
191  static const enum AVPixelFormat main_pix_fmts_yuv422p10[] = {
193  };
194  static const enum AVPixelFormat overlay_pix_fmts_yuv422p10[] = {
195  AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_NONE
196  };
197 
198  static const enum AVPixelFormat main_pix_fmts_yuv444[] = {
200  };
201  static const enum AVPixelFormat overlay_pix_fmts_yuv444[] = {
202  AV_PIX_FMT_YUVA444P, AV_PIX_FMT_NONE
203  };
204 
205  static const enum AVPixelFormat main_pix_fmts_gbrp[] = {
206  AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP, AV_PIX_FMT_NONE
207  };
208  static const enum AVPixelFormat overlay_pix_fmts_gbrp[] = {
209  AV_PIX_FMT_GBRAP, AV_PIX_FMT_NONE
210  };
211 
212  static const enum AVPixelFormat main_pix_fmts_rgb[] = {
216  AV_PIX_FMT_NONE
217  };
218  static const enum AVPixelFormat overlay_pix_fmts_rgb[] = {
221  AV_PIX_FMT_NONE
222  };
223 
224  const enum AVPixelFormat *main_formats, *overlay_formats;
226  int ret;
227 
228  switch (s->format) {
230  main_formats = main_pix_fmts_yuv420;
231  overlay_formats = overlay_pix_fmts_yuv420;
232  break;
234  main_formats = main_pix_fmts_yuv420p10;
235  overlay_formats = overlay_pix_fmts_yuv420p10;
236  break;
238  main_formats = main_pix_fmts_yuv422;
239  overlay_formats = overlay_pix_fmts_yuv422;
240  break;
242  main_formats = main_pix_fmts_yuv422p10;
243  overlay_formats = overlay_pix_fmts_yuv422p10;
244  break;
246  main_formats = main_pix_fmts_yuv444;
247  overlay_formats = overlay_pix_fmts_yuv444;
248  break;
249  case OVERLAY_FORMAT_RGB:
250  main_formats = main_pix_fmts_rgb;
251  overlay_formats = overlay_pix_fmts_rgb;
252  break;
253  case OVERLAY_FORMAT_GBRP:
254  main_formats = main_pix_fmts_gbrp;
255  overlay_formats = overlay_pix_fmts_gbrp;
256  break;
257  case OVERLAY_FORMAT_AUTO:
259  default:
260  av_assert0(0);
261  }
262 
263  formats = ff_make_format_list(main_formats);
264  if ((ret = ff_formats_ref(formats, &ctx->inputs[MAIN]->outcfg.formats)) < 0 ||
265  (ret = ff_formats_ref(formats, &ctx->outputs[MAIN]->incfg.formats)) < 0)
266  return ret;
267 
268  return ff_formats_ref(ff_make_format_list(overlay_formats),
269  &ctx->inputs[OVERLAY]->outcfg.formats);
270 }
271 
273 {
274  AVFilterContext *ctx = inlink->dst;
275  OverlayContext *s = inlink->dst->priv;
276  int ret;
277  const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format);
278 
280 
281  /* Finish the configuration by evaluating the expressions
282  now when both inputs are configured. */
283  s->var_values[VAR_MAIN_W ] = s->var_values[VAR_MW] = ctx->inputs[MAIN ]->w;
284  s->var_values[VAR_MAIN_H ] = s->var_values[VAR_MH] = ctx->inputs[MAIN ]->h;
287  s->var_values[VAR_HSUB] = 1<<pix_desc->log2_chroma_w;
288  s->var_values[VAR_VSUB] = 1<<pix_desc->log2_chroma_h;
289  s->var_values[VAR_X] = NAN;
290  s->var_values[VAR_Y] = NAN;
291  s->var_values[VAR_N] = 0;
292  s->var_values[VAR_T] = NAN;
293  s->var_values[VAR_POS] = NAN;
294 
295  if ((ret = set_expr(&s->x_pexpr, s->x_expr, "x", ctx)) < 0 ||
296  (ret = set_expr(&s->y_pexpr, s->y_expr, "y", ctx)) < 0)
297  return ret;
298 
300  ff_fill_rgba_map(s->overlay_rgba_map, inlink->format) >= 0;
302 
303  if (s->eval_mode == EVAL_MODE_INIT) {
304  eval_expr(ctx);
305  av_log(ctx, AV_LOG_VERBOSE, "x:%f xi:%d y:%f yi:%d\n",
306  s->var_values[VAR_X], s->x,
307  s->var_values[VAR_Y], s->y);
308  }
309 
310  av_log(ctx, AV_LOG_VERBOSE,
311  "main w:%d h:%d fmt:%s overlay w:%d h:%d fmt:%s\n",
312  ctx->inputs[MAIN]->w, ctx->inputs[MAIN]->h,
314  ctx->inputs[OVERLAY]->w, ctx->inputs[OVERLAY]->h,
316  return 0;
317 }
318 
319 static int config_output(AVFilterLink *outlink)
320 {
321  AVFilterContext *ctx = outlink->src;
322  OverlayContext *s = ctx->priv;
323  int ret;
324 
325  if ((ret = ff_framesync_init_dualinput(&s->fs, ctx)) < 0)
326  return ret;
327 
328  outlink->w = ctx->inputs[MAIN]->w;
329  outlink->h = ctx->inputs[MAIN]->h;
330  outlink->time_base = ctx->inputs[MAIN]->time_base;
331 
332  return ff_framesync_configure(&s->fs);
333 }
334 
335 // divide by 255 and round to nearest
336 // apply a fast variant: (X+127)/255 = ((X+127)*257+257)>>16 = ((X+128)*257)>>16
337 #define FAST_DIV255(x) ((((x) + 128) * 257) >> 16)
338 
339 // calculate the unpremultiplied alpha, applying the general equation:
340 // alpha = alpha_overlay / ( (alpha_main + alpha_overlay) - (alpha_main * alpha_overlay) )
341 // (((x) << 16) - ((x) << 9) + (x)) is a faster version of: 255 * 255 * x
342 // ((((x) + (y)) << 8) - ((x) + (y)) - (y) * (x)) is a faster version of: 255 * (x + y)
343 #define UNPREMULTIPLY_ALPHA(x, y) ((((x) << 16) - ((x) << 9) + (x)) / ((((x) + (y)) << 8) - ((x) + (y)) - (y) * (x)))
344 
345 /**
346  * Blend image in src to destination buffer dst at position (x, y).
347  */
348 
350  AVFrame *dst, const AVFrame *src,
351  int main_has_alpha, int x, int y,
352  int is_straight, int jobnr, int nb_jobs)
353 {
354  OverlayContext *s = ctx->priv;
355  int i, imax, j, jmax;
356  const int src_w = src->width;
357  const int src_h = src->height;
358  const int dst_w = dst->width;
359  const int dst_h = dst->height;
360  uint8_t alpha; ///< the amount of overlay to blend on to main
361  const int dr = s->main_rgba_map[R];
362  const int dg = s->main_rgba_map[G];
363  const int db = s->main_rgba_map[B];
364  const int da = s->main_rgba_map[A];
365  const int dstep = s->main_pix_step[0];
366  const int sr = s->overlay_rgba_map[R];
367  const int sg = s->overlay_rgba_map[G];
368  const int sb = s->overlay_rgba_map[B];
369  const int sa = s->overlay_rgba_map[A];
370  const int sstep = s->overlay_pix_step[0];
371  int slice_start, slice_end;
372  uint8_t *S, *sp, *d, *dp;
373 
374  i = FFMAX(-y, 0);
375  imax = FFMIN3(-y + dst_h, FFMIN(src_h, dst_h), y + src_h);
376 
377  slice_start = i + (imax * jobnr) / nb_jobs;
378  slice_end = i + (imax * (jobnr+1)) / nb_jobs;
379 
380  sp = src->data[0] + (slice_start) * src->linesize[0];
381  dp = dst->data[0] + (y + slice_start) * dst->linesize[0];
382 
383  for (i = slice_start; i < slice_end; i++) {
384  j = FFMAX(-x, 0);
385  S = sp + j * sstep;
386  d = dp + (x+j) * dstep;
387 
388  for (jmax = FFMIN(-x + dst_w, src_w); j < jmax; j++) {
389  alpha = S[sa];
390 
391  // if the main channel has an alpha channel, alpha has to be calculated
392  // to create an un-premultiplied (straight) alpha value
393  if (main_has_alpha && alpha != 0 && alpha != 255) {
394  uint8_t alpha_d = d[da];
395  alpha = UNPREMULTIPLY_ALPHA(alpha, alpha_d);
396  }
397 
398  switch (alpha) {
399  case 0:
400  break;
401  case 255:
402  d[dr] = S[sr];
403  d[dg] = S[sg];
404  d[db] = S[sb];
405  break;
406  default:
407  // main_value = main_value * (1 - alpha) + overlay_value * alpha
408  // since alpha is in the range 0-255, the result must divided by 255
409  d[dr] = is_straight ? FAST_DIV255(d[dr] * (255 - alpha) + S[sr] * alpha) :
410  FFMIN(FAST_DIV255(d[dr] * (255 - alpha)) + S[sr], 255);
411  d[dg] = is_straight ? FAST_DIV255(d[dg] * (255 - alpha) + S[sg] * alpha) :
412  FFMIN(FAST_DIV255(d[dg] * (255 - alpha)) + S[sg], 255);
413  d[db] = is_straight ? FAST_DIV255(d[db] * (255 - alpha) + S[sb] * alpha) :
414  FFMIN(FAST_DIV255(d[db] * (255 - alpha)) + S[sb], 255);
415  }
416  if (main_has_alpha) {
417  switch (alpha) {
418  case 0:
419  break;
420  case 255:
421  d[da] = S[sa];
422  break;
423  default:
424  // apply alpha compositing: main_alpha += (1-main_alpha) * overlay_alpha
425  d[da] += FAST_DIV255((255 - d[da]) * S[sa]);
426  }
427  }
428  d += dstep;
429  S += sstep;
430  }
431  dp += dst->linesize[0];
432  sp += src->linesize[0];
433  }
434 }
435 
436 #define DEFINE_BLEND_PLANE(depth, nbits) \
437 static av_always_inline void blend_plane_##depth##_##nbits##bits(AVFilterContext *ctx, \
438  AVFrame *dst, const AVFrame *src, \
439  int src_w, int src_h, \
440  int dst_w, int dst_h, \
441  int i, int hsub, int vsub, \
442  int x, int y, \
443  int main_has_alpha, \
444  int dst_plane, \
445  int dst_offset, \
446  int dst_step, \
447  int straight, \
448  int yuv, \
449  int jobnr, \
450  int nb_jobs) \
451 { \
452  OverlayContext *octx = ctx->priv; \
453  int src_wp = AV_CEIL_RSHIFT(src_w, hsub); \
454  int src_hp = AV_CEIL_RSHIFT(src_h, vsub); \
455  int dst_wp = AV_CEIL_RSHIFT(dst_w, hsub); \
456  int dst_hp = AV_CEIL_RSHIFT(dst_h, vsub); \
457  int yp = y>>vsub; \
458  int xp = x>>hsub; \
459  uint##depth##_t *s, *sp, *d, *dp, *dap, *a, *da, *ap; \
460  int jmax, j, k, kmax; \
461  int slice_start, slice_end; \
462  const uint##depth##_t max = (1 << nbits) - 1; \
463  const uint##depth##_t mid = (1 << (nbits -1)) ; \
464  int bytes = depth / 8; \
465  \
466  dst_step /= bytes; \
467  j = FFMAX(-yp, 0); \
468  jmax = FFMIN3(-yp + dst_hp, FFMIN(src_hp, dst_hp), yp + src_hp); \
469  \
470  slice_start = j + (jmax * jobnr) / nb_jobs; \
471  slice_end = j + (jmax * (jobnr+1)) / nb_jobs; \
472  \
473  sp = (uint##depth##_t *)(src->data[i] + (slice_start) * src->linesize[i]); \
474  dp = (uint##depth##_t *)(dst->data[dst_plane] \
475  + (yp + slice_start) * dst->linesize[dst_plane] \
476  + dst_offset); \
477  ap = (uint##depth##_t *)(src->data[3] + (slice_start << vsub) * src->linesize[3]); \
478  dap = (uint##depth##_t *)(dst->data[3] + ((yp + slice_start) << vsub) * dst->linesize[3]); \
479  \
480  for (j = slice_start; j < slice_end; j++) { \
481  k = FFMAX(-xp, 0); \
482  d = dp + (xp+k) * dst_step; \
483  s = sp + k; \
484  a = ap + (k<<hsub); \
485  da = dap + ((xp+k) << hsub); \
486  kmax = FFMIN(-xp + dst_wp, src_wp); \
487  \
488  if (nbits == 8 && ((vsub && j+1 < src_hp) || !vsub) && octx->blend_row[i]) { \
489  int c = octx->blend_row[i]((uint8_t*)d, (uint8_t*)da, (uint8_t*)s, \
490  (uint8_t*)a, kmax - k, src->linesize[3]); \
491  \
492  s += c; \
493  d += dst_step * c; \
494  da += (1 << hsub) * c; \
495  a += (1 << hsub) * c; \
496  k += c; \
497  } \
498  for (; k < kmax; k++) { \
499  int alpha_v, alpha_h, alpha; \
500  \
501  /* average alpha for color components, improve quality */ \
502  if (hsub && vsub && j+1 < src_hp && k+1 < src_wp) { \
503  alpha = (a[0] + a[src->linesize[3]] + \
504  a[1] + a[src->linesize[3]+1]) >> 2; \
505  } else if (hsub || vsub) { \
506  alpha_h = hsub && k+1 < src_wp ? \
507  (a[0] + a[1]) >> 1 : a[0]; \
508  alpha_v = vsub && j+1 < src_hp ? \
509  (a[0] + a[src->linesize[3]]) >> 1 : a[0]; \
510  alpha = (alpha_v + alpha_h) >> 1; \
511  } else \
512  alpha = a[0]; \
513  /* if the main channel has an alpha channel, alpha has to be calculated */ \
514  /* to create an un-premultiplied (straight) alpha value */ \
515  if (main_has_alpha && alpha != 0 && alpha != max) { \
516  /* average alpha for color components, improve quality */ \
517  uint8_t alpha_d; \
518  if (hsub && vsub && j+1 < src_hp && k+1 < src_wp) { \
519  alpha_d = (da[0] + da[dst->linesize[3]] + \
520  da[1] + da[dst->linesize[3]+1]) >> 2; \
521  } else if (hsub || vsub) { \
522  alpha_h = hsub && k+1 < src_wp ? \
523  (da[0] + da[1]) >> 1 : da[0]; \
524  alpha_v = vsub && j+1 < src_hp ? \
525  (da[0] + da[dst->linesize[3]]) >> 1 : da[0]; \
526  alpha_d = (alpha_v + alpha_h) >> 1; \
527  } else \
528  alpha_d = da[0]; \
529  alpha = UNPREMULTIPLY_ALPHA(alpha, alpha_d); \
530  } \
531  if (straight) { \
532  if (nbits > 8) \
533  *d = (*d * (max - alpha) + *s * alpha) / max; \
534  else \
535  *d = FAST_DIV255(*d * (255 - alpha) + *s * alpha); \
536  } else { \
537  if (nbits > 8) { \
538  if (i && yuv) \
539  *d = av_clip((*d * (max - alpha) + *s * alpha) / max + *s - mid, -mid, mid) + mid; \
540  else \
541  *d = FFMIN((*d * (max - alpha) + *s * alpha) / max + *s, max); \
542  } else { \
543  if (i && yuv) \
544  *d = av_clip(FAST_DIV255((*d - mid) * (max - alpha)) + *s - mid, -mid, mid) + mid; \
545  else \
546  *d = FFMIN(FAST_DIV255(*d * (max - alpha)) + *s, max); \
547  } \
548  } \
549  s++; \
550  d += dst_step; \
551  da += 1 << hsub; \
552  a += 1 << hsub; \
553  } \
554  dp += dst->linesize[dst_plane] / bytes; \
555  sp += src->linesize[i] / bytes; \
556  ap += (1 << vsub) * src->linesize[3] / bytes; \
557  dap += (1 << vsub) * dst->linesize[3] / bytes; \
558  } \
559 }
560 DEFINE_BLEND_PLANE(8, 8)
561 DEFINE_BLEND_PLANE(16, 10)
562 
563 #define DEFINE_ALPHA_COMPOSITE(depth, nbits) \
564 static inline void alpha_composite_##depth##_##nbits##bits(const AVFrame *src, const AVFrame *dst, \
565  int src_w, int src_h, \
566  int dst_w, int dst_h, \
567  int x, int y, \
568  int jobnr, int nb_jobs) \
569 { \
570  uint##depth##_t alpha; /* the amount of overlay to blend on to main */ \
571  uint##depth##_t *s, *sa, *d, *da; \
572  int i, imax, j, jmax; \
573  int slice_start, slice_end; \
574  const uint##depth##_t max = (1 << nbits) - 1; \
575  int bytes = depth / 8; \
576  \
577  imax = FFMIN(-y + dst_h, src_h); \
578  slice_start = (imax * jobnr) / nb_jobs; \
579  slice_end = ((imax * (jobnr+1)) / nb_jobs); \
580  \
581  i = FFMAX(-y, 0); \
582  sa = (uint##depth##_t *)(src->data[3] + (i + slice_start) * src->linesize[3]); \
583  da = (uint##depth##_t *)(dst->data[3] + (y + i + slice_start) * dst->linesize[3]); \
584  \
585  for (i = i + slice_start; i < slice_end; i++) { \
586  j = FFMAX(-x, 0); \
587  s = sa + j; \
588  d = da + x+j; \
589  \
590  for (jmax = FFMIN(-x + dst_w, src_w); j < jmax; j++) { \
591  alpha = *s; \
592  if (alpha != 0 && alpha != max) { \
593  uint8_t alpha_d = *d; \
594  alpha = UNPREMULTIPLY_ALPHA(alpha, alpha_d); \
595  } \
596  if (alpha == max) \
597  *d = *s; \
598  else if (alpha > 0) { \
599  /* apply alpha compositing: main_alpha += (1-main_alpha) * overlay_alpha */ \
600  if (nbits > 8) \
601  *d += (max - *d) * *s / max; \
602  else \
603  *d += FAST_DIV255((max - *d) * *s); \
604  } \
605  d += 1; \
606  s += 1; \
607  } \
608  da += dst->linesize[3] / bytes; \
609  sa += src->linesize[3] / bytes; \
610  } \
611 }
614 
615 #define DEFINE_BLEND_SLICE_YUV(depth, nbits) \
616 static av_always_inline void blend_slice_yuv_##depth##_##nbits##bits(AVFilterContext *ctx, \
617  AVFrame *dst, const AVFrame *src, \
618  int hsub, int vsub, \
619  int main_has_alpha, \
620  int x, int y, \
621  int is_straight, \
622  int jobnr, int nb_jobs) \
623 { \
624  OverlayContext *s = ctx->priv; \
625  const int src_w = src->width; \
626  const int src_h = src->height; \
627  const int dst_w = dst->width; \
628  const int dst_h = dst->height; \
629  \
630  blend_plane_##depth##_##nbits##bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 0, 0, 0, \
631  x, y, main_has_alpha, s->main_desc->comp[0].plane, s->main_desc->comp[0].offset, \
632  s->main_desc->comp[0].step, is_straight, 1, jobnr, nb_jobs); \
633  blend_plane_##depth##_##nbits##bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 1, hsub, vsub, \
634  x, y, main_has_alpha, s->main_desc->comp[1].plane, s->main_desc->comp[1].offset, \
635  s->main_desc->comp[1].step, is_straight, 1, jobnr, nb_jobs); \
636  blend_plane_##depth##_##nbits##bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 2, hsub, vsub, \
637  x, y, main_has_alpha, s->main_desc->comp[2].plane, s->main_desc->comp[2].offset, \
638  s->main_desc->comp[2].step, is_straight, 1, jobnr, nb_jobs); \
639  \
640  if (main_has_alpha) \
641  alpha_composite_##depth##_##nbits##bits(src, dst, src_w, src_h, dst_w, dst_h, x, y, \
642  jobnr, nb_jobs); \
643 }
646 
648  AVFrame *dst, const AVFrame *src,
649  int hsub, int vsub,
650  int main_has_alpha,
651  int x, int y,
652  int is_straight,
653  int jobnr,
654  int nb_jobs)
655 {
656  OverlayContext *s = ctx->priv;
657  const int src_w = src->width;
658  const int src_h = src->height;
659  const int dst_w = dst->width;
660  const int dst_h = dst->height;
661 
662  blend_plane_8_8bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 0, 0, 0, x, y, main_has_alpha,
663  s->main_desc->comp[1].plane, s->main_desc->comp[1].offset, s->main_desc->comp[1].step, is_straight, 0,
664  jobnr, nb_jobs);
665  blend_plane_8_8bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 1, hsub, vsub, x, y, main_has_alpha,
666  s->main_desc->comp[2].plane, s->main_desc->comp[2].offset, s->main_desc->comp[2].step, is_straight, 0,
667  jobnr, nb_jobs);
668  blend_plane_8_8bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 2, hsub, vsub, x, y, main_has_alpha,
669  s->main_desc->comp[0].plane, s->main_desc->comp[0].offset, s->main_desc->comp[0].step, is_straight, 0,
670  jobnr, nb_jobs);
671 
672  if (main_has_alpha)
673  alpha_composite_8_8bits(src, dst, src_w, src_h, dst_w, dst_h, x, y, jobnr, nb_jobs);
674 }
675 
676 static int blend_slice_yuv420(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
677 {
678  OverlayContext *s = ctx->priv;
679  ThreadData *td = arg;
680  blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 1, 0, s->x, s->y, 1, jobnr, nb_jobs);
681  return 0;
682 }
683 
684 static int blend_slice_yuva420(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
685 {
686  OverlayContext *s = ctx->priv;
687  ThreadData *td = arg;
688  blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 1, 1, s->x, s->y, 1, jobnr, nb_jobs);
689  return 0;
690 }
691 
692 static int blend_slice_yuv420p10(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
693 {
694  OverlayContext *s = ctx->priv;
695  ThreadData *td = arg;
696  blend_slice_yuv_16_10bits(ctx, td->dst, td->src, 1, 1, 0, s->x, s->y, 1, jobnr, nb_jobs);
697  return 0;
698 }
699 
700 static int blend_slice_yuva420p10(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
701 {
702  OverlayContext *s = ctx->priv;
703  ThreadData *td = arg;
704  blend_slice_yuv_16_10bits(ctx, td->dst, td->src, 1, 1, 1, s->x, s->y, 1, jobnr, nb_jobs);
705  return 0;
706 }
707 
708 static int blend_slice_yuv422p10(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
709 {
710  OverlayContext *s = ctx->priv;
711  ThreadData *td = arg;
712  blend_slice_yuv_16_10bits(ctx, td->dst, td->src, 1, 0, 0, s->x, s->y, 1, jobnr, nb_jobs);
713  return 0;
714 }
715 
716 static int blend_slice_yuva422p10(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
717 {
718  OverlayContext *s = ctx->priv;
719  ThreadData *td = arg;
720  blend_slice_yuv_16_10bits(ctx, td->dst, td->src, 1, 0, 1, s->x, s->y, 1, jobnr, nb_jobs);
721  return 0;
722 }
723 
724 static int blend_slice_yuv422(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
725 {
726  OverlayContext *s = ctx->priv;
727  ThreadData *td = arg;
728  blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 0, 0, s->x, s->y, 1, jobnr, nb_jobs);
729  return 0;
730 }
731 
732 static int blend_slice_yuva422(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
733 {
734  OverlayContext *s = ctx->priv;
735  ThreadData *td = arg;
736  blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 0, 1, s->x, s->y, 1, jobnr, nb_jobs);
737  return 0;
738 }
739 
740 static int blend_slice_yuv444(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
741 {
742  OverlayContext *s = ctx->priv;
743  ThreadData *td = arg;
744  blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 0, 0, 0, s->x, s->y, 1, jobnr, nb_jobs);
745  return 0;
746 }
747 
748 static int blend_slice_yuva444(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
749 {
750  OverlayContext *s = ctx->priv;
751  ThreadData *td = arg;
752  blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 0, 0, 1, s->x, s->y, 1, jobnr, nb_jobs);
753  return 0;
754 }
755 
756 static int blend_slice_gbrp(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
757 {
758  OverlayContext *s = ctx->priv;
759  ThreadData *td = arg;
760  blend_slice_planar_rgb(ctx, td->dst, td->src, 0, 0, 0, s->x, s->y, 1, jobnr, nb_jobs);
761  return 0;
762 }
763 
764 static int blend_slice_gbrap(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
765 {
766  OverlayContext *s = ctx->priv;
767  ThreadData *td = arg;
768  blend_slice_planar_rgb(ctx, td->dst, td->src, 0, 0, 1, s->x, s->y, 1, jobnr, nb_jobs);
769  return 0;
770 }
771 
772 static int blend_slice_yuv420_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
773 {
774  OverlayContext *s = ctx->priv;
775  ThreadData *td = arg;
776  blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 1, 0, s->x, s->y, 0, jobnr, nb_jobs);
777  return 0;
778 }
779 
780 static int blend_slice_yuva420_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
781 {
782  OverlayContext *s = ctx->priv;
783  ThreadData *td = arg;
784  blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 1, 1, s->x, s->y, 0, jobnr, nb_jobs);
785  return 0;
786 }
787 
788 static int blend_slice_yuv422_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
789 {
790  OverlayContext *s = ctx->priv;
791  ThreadData *td = arg;
792  blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 0, 0, s->x, s->y, 0, jobnr, nb_jobs);
793  return 0;
794 }
795 
796 static int blend_slice_yuva422_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
797 {
798  OverlayContext *s = ctx->priv;
799  ThreadData *td = arg;
800  blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 0, 1, s->x, s->y, 0, jobnr, nb_jobs);
801  return 0;
802 }
803 
804 static int blend_slice_yuv444_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
805 {
806  OverlayContext *s = ctx->priv;
807  ThreadData *td = arg;
808  blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 0, 0, 0, s->x, s->y, 0, jobnr, nb_jobs);
809  return 0;
810 }
811 
812 static int blend_slice_yuva444_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
813 {
814  OverlayContext *s = ctx->priv;
815  ThreadData *td = arg;
816  blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 0, 0, 1, s->x, s->y, 0, jobnr, nb_jobs);
817  return 0;
818 }
819 
820 static int blend_slice_gbrp_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
821 {
822  OverlayContext *s = ctx->priv;
823  ThreadData *td = arg;
824  blend_slice_planar_rgb(ctx, td->dst, td->src, 0, 0, 0, s->x, s->y, 0, jobnr, nb_jobs);
825  return 0;
826 }
827 
828 static int blend_slice_gbrap_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
829 {
830  OverlayContext *s = ctx->priv;
831  ThreadData *td = arg;
832  blend_slice_planar_rgb(ctx, td->dst, td->src, 0, 0, 1, s->x, s->y, 0, jobnr, nb_jobs);
833  return 0;
834 }
835 
836 static int blend_slice_rgb(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
837 {
838  OverlayContext *s = ctx->priv;
839  ThreadData *td = arg;
840  blend_slice_packed_rgb(ctx, td->dst, td->src, 0, s->x, s->y, 1, jobnr, nb_jobs);
841  return 0;
842 }
843 
844 static int blend_slice_rgba(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
845 {
846  OverlayContext *s = ctx->priv;
847  ThreadData *td = arg;
848  blend_slice_packed_rgb(ctx, td->dst, td->src, 1, s->x, s->y, 1, jobnr, nb_jobs);
849  return 0;
850 }
851 
852 static int blend_slice_rgb_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
853 {
854  OverlayContext *s = ctx->priv;
855  ThreadData *td = arg;
856  blend_slice_packed_rgb(ctx, td->dst, td->src, 0, s->x, s->y, 0, jobnr, nb_jobs);
857  return 0;
858 }
859 
860 static int blend_slice_rgba_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
861 {
862  OverlayContext *s = ctx->priv;
863  ThreadData *td = arg;
864  blend_slice_packed_rgb(ctx, td->dst, td->src, 1, s->x, s->y, 0, jobnr, nb_jobs);
865  return 0;
866 }
867 
869 {
870  OverlayContext *s = inlink->dst->priv;
871  const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format);
872 
874 
875  s->hsub = pix_desc->log2_chroma_w;
876  s->vsub = pix_desc->log2_chroma_h;
877 
878  s->main_desc = pix_desc;
879 
880  s->main_is_packed_rgb =
881  ff_fill_rgba_map(s->main_rgba_map, inlink->format) >= 0;
883  switch (s->format) {
886  break;
889  break;
892  break;
895  break;
898  break;
899  case OVERLAY_FORMAT_RGB:
901  break;
902  case OVERLAY_FORMAT_GBRP:
904  break;
905  case OVERLAY_FORMAT_AUTO:
906  switch (inlink->format) {
907  case AV_PIX_FMT_YUVA420P:
909  break;
912  break;
913  case AV_PIX_FMT_YUVA422P:
915  break;
918  break;
919  case AV_PIX_FMT_YUVA444P:
921  break;
922  case AV_PIX_FMT_ARGB:
923  case AV_PIX_FMT_RGBA:
924  case AV_PIX_FMT_BGRA:
925  case AV_PIX_FMT_ABGR:
927  break;
928  case AV_PIX_FMT_GBRAP:
930  break;
931  default:
932  av_assert0(0);
933  break;
934  }
935  break;
936  }
937 
938  if (!s->alpha_format)
939  goto end;
940 
941  switch (s->format) {
944  break;
947  break;
950  break;
951  case OVERLAY_FORMAT_RGB:
953  break;
954  case OVERLAY_FORMAT_GBRP:
956  break;
957  case OVERLAY_FORMAT_AUTO:
958  switch (inlink->format) {
959  case AV_PIX_FMT_YUVA420P:
961  break;
962  case AV_PIX_FMT_YUVA422P:
964  break;
965  case AV_PIX_FMT_YUVA444P:
967  break;
968  case AV_PIX_FMT_ARGB:
969  case AV_PIX_FMT_RGBA:
970  case AV_PIX_FMT_BGRA:
971  case AV_PIX_FMT_ABGR:
973  break;
974  case AV_PIX_FMT_GBRAP:
976  break;
977  default:
978  av_assert0(0);
979  break;
980  }
981  break;
982  }
983 
984 end:
985  if (ARCH_X86)
986  ff_overlay_init_x86(s, s->format, inlink->format,
988 
989  return 0;
990 }
991 
992 static int do_blend(FFFrameSync *fs)
993 {
994  AVFilterContext *ctx = fs->parent;
995  AVFrame *mainpic, *second;
996  OverlayContext *s = ctx->priv;
997  AVFilterLink *inlink = ctx->inputs[0];
998  int ret;
999 
1000  ret = ff_framesync_dualinput_get_writable(fs, &mainpic, &second);
1001  if (ret < 0)
1002  return ret;
1003  if (!second)
1004  return ff_filter_frame(ctx->outputs[0], mainpic);
1005 
1006  if (s->eval_mode == EVAL_MODE_FRAME) {
1007  int64_t pos = mainpic->pkt_pos;
1008 
1009  s->var_values[VAR_N] = inlink->frame_count_out;
1010  s->var_values[VAR_T] = mainpic->pts == AV_NOPTS_VALUE ?
1011  NAN : mainpic->pts * av_q2d(inlink->time_base);
1012  s->var_values[VAR_POS] = pos == -1 ? NAN : pos;
1013 
1014  s->var_values[VAR_OVERLAY_W] = s->var_values[VAR_OW] = second->width;
1015  s->var_values[VAR_OVERLAY_H] = s->var_values[VAR_OH] = second->height;
1016  s->var_values[VAR_MAIN_W ] = s->var_values[VAR_MW] = mainpic->width;
1017  s->var_values[VAR_MAIN_H ] = s->var_values[VAR_MH] = mainpic->height;
1018 
1019  eval_expr(ctx);
1020  av_log(ctx, AV_LOG_DEBUG, "n:%f t:%f pos:%f x:%f xi:%d y:%f yi:%d\n",
1022  s->var_values[VAR_X], s->x,
1023  s->var_values[VAR_Y], s->y);
1024  }
1025 
1026  if (s->x < mainpic->width && s->x + second->width >= 0 &&
1027  s->y < mainpic->height && s->y + second->height >= 0) {
1028  ThreadData td;
1029 
1030  td.dst = mainpic;
1031  td.src = second;
1032  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)),
1033  ff_filter_get_nb_threads(ctx)));
1034  }
1035  return ff_filter_frame(ctx->outputs[0], mainpic);
1036 }
1037 
1039 {
1040  OverlayContext *s = ctx->priv;
1041 
1042  s->fs.on_event = do_blend;
1043  return 0;
1044 }
1045 
1047 {
1048  OverlayContext *s = ctx->priv;
1049  return ff_framesync_activate(&s->fs);
1050 }
1051 
1052 #define OFFSET(x) offsetof(OverlayContext, x)
1053 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
1054 
1055 static const AVOption overlay_options[] = {
1056  { "x", "set the x expression", OFFSET(x_expr), AV_OPT_TYPE_STRING, {.str = "0"}, 0, 0, FLAGS },
1057  { "y", "set the y expression", OFFSET(y_expr), AV_OPT_TYPE_STRING, {.str = "0"}, 0, 0, FLAGS },
1058  { "eof_action", "Action to take when encountering EOF from secondary input ",
1059  OFFSET(fs.opt_eof_action), AV_OPT_TYPE_INT, { .i64 = EOF_ACTION_REPEAT },
1060  EOF_ACTION_REPEAT, EOF_ACTION_PASS, .flags = FLAGS, "eof_action" },
1061  { "repeat", "Repeat the previous frame.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_REPEAT }, .flags = FLAGS, "eof_action" },
1062  { "endall", "End both streams.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_ENDALL }, .flags = FLAGS, "eof_action" },
1063  { "pass", "Pass through the main input.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_PASS }, .flags = FLAGS, "eof_action" },
1064  { "eval", "specify when to evaluate expressions", OFFSET(eval_mode), AV_OPT_TYPE_INT, {.i64 = EVAL_MODE_FRAME}, 0, EVAL_MODE_NB-1, FLAGS, "eval" },
1065  { "init", "eval expressions once during initialization", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_INIT}, .flags = FLAGS, .unit = "eval" },
1066  { "frame", "eval expressions per-frame", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_FRAME}, .flags = FLAGS, .unit = "eval" },
1067  { "shortest", "force termination when the shortest input terminates", OFFSET(fs.opt_shortest), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS },
1068  { "format", "set output format", OFFSET(format), AV_OPT_TYPE_INT, {.i64=OVERLAY_FORMAT_YUV420}, 0, OVERLAY_FORMAT_NB-1, FLAGS, "format" },
1069  { "yuv420", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV420}, .flags = FLAGS, .unit = "format" },
1070  { "yuv420p10", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV420P10}, .flags = FLAGS, .unit = "format" },
1071  { "yuv422", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV422}, .flags = FLAGS, .unit = "format" },
1072  { "yuv422p10", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV422P10}, .flags = FLAGS, .unit = "format" },
1073  { "yuv444", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV444}, .flags = FLAGS, .unit = "format" },
1074  { "rgb", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_RGB}, .flags = FLAGS, .unit = "format" },
1075  { "gbrp", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_GBRP}, .flags = FLAGS, .unit = "format" },
1076  { "auto", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_AUTO}, .flags = FLAGS, .unit = "format" },
1077  { "repeatlast", "repeat overlay of the last overlay frame", OFFSET(fs.opt_repeatlast), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGS },
1078  { "alpha", "alpha format", OFFSET(alpha_format), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "alpha_format" },
1079  { "straight", "", 0, AV_OPT_TYPE_CONST, {.i64=0}, .flags = FLAGS, .unit = "alpha_format" },
1080  { "premultiplied", "", 0, AV_OPT_TYPE_CONST, {.i64=1}, .flags = FLAGS, .unit = "alpha_format" },
1081  { NULL }
1082 };
1083 
1085 
1087  {
1088  .name = "main",
1089  .type = AVMEDIA_TYPE_VIDEO,
1090  .config_props = config_input_main,
1091  },
1092  {
1093  .name = "overlay",
1094  .type = AVMEDIA_TYPE_VIDEO,
1095  .config_props = config_input_overlay,
1096  },
1097  { NULL }
1098 };
1099 
1101  {
1102  .name = "default",
1103  .type = AVMEDIA_TYPE_VIDEO,
1104  .config_props = config_output,
1105  },
1106  { NULL }
1107 };
1108 
1110  .name = "overlay",
1111  .description = NULL_IF_CONFIG_SMALL("Overlay a video source on top of the input."),
1112  .preinit = overlay_framesync_preinit,
1113  .init = init,
1114  .uninit = uninit,
1115  .priv_size = sizeof(OverlayContext),
1116  .priv_class = &overlay_class,
1118  .activate = activate,
1120  .inputs = avfilter_vf_overlay_inputs,
1121  .outputs = avfilter_vf_overlay_outputs,
1124 };
static int activate(AVFilterContext *ctx)
Definition: vf_overlay.c:1046
int plane
Which of the 4 planes contains the component.
Definition: pixdesc.h:35
#define NULL
Definition: coverity.c:32
static int blend_slice_yuv420p10(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:692
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2573
static int blend_slice_rgb_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:852
This structure describes decoded (raw) audio or video data.
Definition: frame.h:308
AVOption.
Definition: opt.h:248
#define AV_PIX_FMT_YUVA420P10
Definition: pixfmt.h:436
int64_t pkt_pos
reordered pos from the last AVPacket that has been input into the decoder
Definition: frame.h:579
#define AV_PIX_FMT_YUVA422P10
Definition: pixfmt.h:437
Definition: aeval.c:48
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:71
misc image utilities
Main libavfilter public API header.
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:68
AVFrame * old
Definition: vf_lagfun.c:77
const AVPixFmtDescriptor * main_desc
format descriptor for main input
Definition: vf_overlay.h:73
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:168
static int blend_slice_yuv444_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:804
static const AVFilterPad avfilter_vf_overlay_inputs[]
Definition: vf_overlay.c:1086
Definition: vf_blend.c:52
void ff_overlay_init_x86(OverlayContext *s, int format, int pix_format, int alpha_format, int main_has_alpha)
int ff_framesync_configure(FFFrameSync *fs)
Configure a frame sync structure.
Definition: framesync.c:124
static int blend_slice_rgba_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:860
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
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
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:92
static int blend_slice_yuva420_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:780
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:287
static int blend_slice_gbrp(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:756
static int blend_slice_yuv420(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:676
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
const char * name
Pad name.
Definition: internal.h:60
AVFilterContext * parent
Parent filter context.
Definition: framesync.h:152
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:347
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1091
static int blend_slice_yuv422(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:724
char * x_expr
Definition: vf_overlay.h:76
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
Definition: pixfmt.h:101
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:117
uint8_t
#define av_cold
Definition: attributes.h:88
#define fs(width, name, subs,...)
Definition: cbs_vp9.c:259
AVOptions.
timestamp utils, mostly useful for debugging/logging purposes
static const char *const var_names[]
Definition: vf_overlay.c:48
int ff_framesync_init_dualinput(FFFrameSync *fs, AVFilterContext *parent)
Initialize a frame sync structure for dualinput.
Definition: framesync.c:358
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:92
#define G
Definition: vf_overlay.c:67
double var_values[VAR_VARS_NB]
Definition: vf_overlay.h:75
static int blend_slice_yuva444(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:748
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:396
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:401
Definition: eval.c:157
#define R
Definition: vf_overlay.c:66
packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
Definition: pixfmt.h:94
#define FAST_DIV255(x)
Definition: vf_overlay.c:337
uint8_t overlay_rgba_map[4]
Definition: vf_overlay.h:62
AVFrame * dst
Definition: vf_blend.c:56
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
#define FFMIN3(a, b, c)
Definition: common.h:97
planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting col...
Definition: pixfmt.h:79
AVExpr * y_pexpr
Definition: vf_overlay.h:78
#define sp
Definition: regdef.h:63
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:210
#define OVERLAY
Definition: vf_overlay.c:64
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:258
#define av_log(a,...)
static int blend_slice_yuva422p10(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:716
static int blend_slice_yuv444(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:740
A filter pad used for either input or output.
Definition: internal.h:54
int eval_mode
EvalMode.
Definition: vf_overlay.h:66
int format
OverlayFormat.
Definition: vf_overlay.h:64
planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
Definition: pixfmt.h:176
int width
Definition: frame.h:366
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
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:588
#define td
Definition: regdef.h:70
#define UNPREMULTIPLY_ALPHA(x, y)
Definition: vf_overlay.c:343
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:101
void ff_framesync_uninit(FFFrameSync *fs)
Free all memory currently allocated.
Definition: framesync.c:290
static int blend_slice_gbrap_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:828
static int blend_slice_yuva422_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:796
#define S(s, c, i)
Frame sync structure.
Definition: framesync.h:146
uint8_t main_has_alpha
Definition: vf_overlay.h:60
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:153
const uint8_t * src
Definition: vf_bm3d.c:56
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
Definition: pixfmt.h:95
void * priv
private data for use by the filter
Definition: avfilter.h:354
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
Definition: avfilter.h:117
unsigned int pos
Definition: spdifenc.c:410
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:215
AVFilterFormats * formats
List of supported formats (pixel or sample).
Definition: avfilter.h:443
const char * arg
Definition: jacosubdec.c:66
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
static int config_input_overlay(AVFilterLink *inlink)
Definition: vf_overlay.c:272
static int blend_slice_yuva444_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:812
int ff_framesync_activate(FFFrameSync *fs)
Examine the frames in the filter&#39;s input and try to produce output.
Definition: framesync.c:341
int(* on_event)(struct FFFrameSync *fs)
Callback called when a frame event is ready.
Definition: framesync.h:172
#define FFMAX(a, b)
Definition: common.h:94
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition: pixfmt.h:92
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:93
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:70
as above, but U and V bytes are swapped
Definition: pixfmt.h:90
static const AVFilterPad avfilter_vf_overlay_outputs[]
Definition: vf_overlay.c:1100
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition: avfilter.c:800
#define NAN
Definition: mathematics.h:64
#define FFMIN(a, b)
Definition: common.h:96
static int blend_slice_yuva422(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:732
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting col...
Definition: pixfmt.h:78
uint8_t main_rgba_map[4]
Definition: vf_overlay.h:59
int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
Add *ref as a new reference to formats.
Definition: formats.c:467
AVFormatContext * ctx
Definition: movenc.c:48
Definition: aeval.c:51
#define B
Definition: vf_overlay.c:68
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:69
static av_cold int init(AVFilterContext *ctx)
Definition: vf_overlay.c:1038
int(* blend_slice)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.h:82
int main_pix_step[4]
steps per pixel for each plane of the main output
Definition: vf_overlay.h:70
EvalMode
Definition: af_volume.h:39
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
static int blend_slice_yuv422_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:788
int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt)
Definition: drawutils.c:35
char * y_expr
Definition: vf_overlay.h:76
static const AVOption overlay_options[]
Definition: vf_overlay.c:1055
Definition: vf_blend.c:52
static int blend_slice_rgba(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:844
static int blend_slice_rgb(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:836
static int blend_slice_gbrp_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:820
misc drawing utilities
#define DEFINE_BLEND_SLICE_YUV(depth, nbits)
Definition: vf_overlay.c:615
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:349
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
Definition: eval.c:336
static int blend_slice_yuv422p10(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:708
static av_cold void uninit(AVFilterContext *ctx)
Definition: vf_overlay.c:81
Used for passing data between threads.
Definition: dsddec.c:67
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:339
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
Definition: pixfmt.h:177
static int set_expr(AVExpr **pexpr, const char *expr, const char *option, void *log_ctx)
Definition: vf_overlay.c:109
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
static const int16_t alpha[]
Definition: ilbcdata.h:55
static int blend_slice_yuv420_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:772
AVExpr * x_pexpr
Definition: vf_overlay.h:78
#define OFFSET(x)
Definition: vf_overlay.c:1052
int y
position of overlaid picture
Definition: vf_overlay.h:56
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
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:399
static int blend_slice_yuva420(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:684
Filter definition.
Definition: avfilter.h:145
uint8_t overlay_has_alpha
Definition: vf_overlay.h:63
#define FLAGS
Definition: vf_overlay.c:1053
option
Definition: libkvazaar.c:316
#define isnan(x)
Definition: libm.h:340
uint8_t overlay_is_packed_rgb
Definition: vf_overlay.h:61
#define A
Definition: vf_overlay.c:69
const char * name
Filter name.
Definition: avfilter.h:149
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:647
static int query_formats(AVFilterContext *ctx)
Definition: vf_overlay.c:162
#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:134
int overlay_pix_step[4]
steps per pixel for each plane of the overlay
Definition: vf_overlay.h:71
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:351
AVFrame * overlay
int offset
Number of elements before the component of the first pixel.
Definition: pixdesc.h:47
#define flags(name, subs,...)
Definition: cbs_av1.c:560
AVFilterInternal * internal
An opaque struct for libavfilter internal use.
Definition: avfilter.h:379
#define AV_PIX_FMT_YUV422P10
Definition: pixfmt.h:400
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:322
#define DEFINE_BLEND_PLANE(depth, nbits)
Definition: vf_overlay.c:436
static int normalize_xy(double d, int chroma_sub)
Definition: vf_overlay.c:90
static int config_input_main(AVFilterLink *inlink)
Definition: vf_overlay.c:868
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
#define DEFINE_ALPHA_COMPOSITE(depth, nbits)
Definition: vf_overlay.c:563
common internal and external API header
static int blend_slice_gbrap(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:764
planar GBRA 4:4:4:4 32bpp
Definition: pixfmt.h:215
static int blend_slice_yuva420p10(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:700
int vsub
chroma subsampling values
Definition: vf_overlay.h:72
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
Definition: pixfmt.h:80
AVFilter ff_vf_overlay
Definition: vf_overlay.c:1109
avfilter_execute_func * execute
Definition: internal.h:136
static int slice_end(AVCodecContext *avctx, AVFrame *pict)
Handle slice ends.
Definition: mpeg12dec.c:2039
double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
Evaluate a previously parsed expression.
Definition: eval.c:766
static int config_output(AVFilterLink *outlink)
Definition: vf_overlay.c:319
A list of supported formats for one end of a filter link.
Definition: formats.h:65
uint8_t main_is_packed_rgb
Definition: vf_overlay.h:58
An instance of a filter.
Definition: avfilter.h:339
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
Definition: vf_overlay.c:130
FFFrameSync fs
Definition: vf_overlay.h:68
int height
Definition: frame.h:366
FRAMESYNC_DEFINE_CLASS(overlay, OverlayContext, fs)
#define MAIN
Definition: vf_overlay.c:63
const void ** s
#define av_always_inline
Definition: attributes.h:45
static void eval_expr(AVFilterContext *ctx)
Definition: vf_overlay.c:97
formats
Definition: signature.h:48
static int do_blend(FFFrameSync *fs)
Definition: vf_overlay.c:992
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:2489
AVFilterLink * inlink
Definition: vf_blend.c:57
internal API functions
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Frame references ownership and permissions
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
int i
Definition: input.c:407
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
static enum AVPixelFormat alpha_pix_fmts[]
Definition: vf_overlay.c:155
int step
Number of elements between 2 horizontally consecutive pixels.
Definition: pixdesc.h:41
simple arithmetic expression evaluator