FFmpeg
vf_overlay.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010 Stefano Sabatini
3  * Copyright (c) 2010 Baptiste Coudurier
4  * Copyright (c) 2007 Bobby Bingham
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 /**
24  * @file
25  * overlay one video on top of another
26  */
27 
28 #include "avfilter.h"
29 #include "formats.h"
30 #include "libavutil/common.h"
31 #include "libavutil/eval.h"
32 #include "libavutil/avstring.h"
33 #include "libavutil/pixdesc.h"
34 #include "libavutil/imgutils.h"
35 #include "libavutil/mathematics.h"
36 #include "libavutil/opt.h"
37 #include "libavutil/timestamp.h"
38 #include "internal.h"
39 #include "drawutils.h"
40 #include "framesync.h"
41 #include "video.h"
42 #include "vf_overlay.h"
43 
44 typedef struct ThreadData {
45  AVFrame *dst, *src;
46 } ThreadData;
47 
48 static const char *const var_names[] = {
49  "main_w", "W", ///< width of the main video
50  "main_h", "H", ///< height of the main video
51  "overlay_w", "w", ///< width of the overlay video
52  "overlay_h", "h", ///< height of the overlay video
53  "hsub",
54  "vsub",
55  "x",
56  "y",
57  "n", ///< number of frame
58  "pos", ///< position in the file
59  "t", ///< timestamp expressed in seconds
60  NULL
61 };
62 
63 #define MAIN 0
64 #define OVERLAY 1
65 
66 #define R 0
67 #define G 1
68 #define B 2
69 #define A 3
70 
71 #define Y 0
72 #define U 1
73 #define V 2
74 
75 enum EvalMode {
79 };
80 
82 {
83  OverlayContext *s = ctx->priv;
84 
85  ff_framesync_uninit(&s->fs);
86  av_expr_free(s->x_pexpr); s->x_pexpr = NULL;
87  av_expr_free(s->y_pexpr); s->y_pexpr = NULL;
88 }
89 
90 static inline int normalize_xy(double d, int chroma_sub)
91 {
92  if (isnan(d))
93  return INT_MAX;
94  return (int)d & ~((1 << chroma_sub) - 1);
95 }
96 
98 {
99  OverlayContext *s = ctx->priv;
100 
101  s->var_values[VAR_X] = av_expr_eval(s->x_pexpr, s->var_values, NULL);
102  s->var_values[VAR_Y] = av_expr_eval(s->y_pexpr, s->var_values, NULL);
103  /* It is necessary if x is expressed from y */
104  s->var_values[VAR_X] = av_expr_eval(s->x_pexpr, s->var_values, NULL);
105  s->x = normalize_xy(s->var_values[VAR_X], s->hsub);
106  s->y = normalize_xy(s->var_values[VAR_Y], s->vsub);
107 }
108 
109 static int set_expr(AVExpr **pexpr, const char *expr, const char *option, void *log_ctx)
110 {
111  int ret;
112  AVExpr *old = NULL;
113 
114  if (*pexpr)
115  old = *pexpr;
116  ret = av_expr_parse(pexpr, expr, var_names,
117  NULL, NULL, NULL, NULL, 0, log_ctx);
118  if (ret < 0) {
119  av_log(log_ctx, AV_LOG_ERROR,
120  "Error when evaluating the expression '%s' for %s\n",
121  expr, option);
122  *pexpr = old;
123  return ret;
124  }
125 
126  av_expr_free(old);
127  return 0;
128 }
129 
130 static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
131  char *res, int res_len, int flags)
132 {
133  OverlayContext *s = ctx->priv;
134  int ret;
135 
136  if (!strcmp(cmd, "x"))
137  ret = set_expr(&s->x_pexpr, args, cmd, ctx);
138  else if (!strcmp(cmd, "y"))
139  ret = set_expr(&s->y_pexpr, args, cmd, ctx);
140  else
141  ret = AVERROR(ENOSYS);
142 
143  if (ret < 0)
144  return ret;
145 
146  if (s->eval_mode == EVAL_MODE_INIT) {
147  eval_expr(ctx);
148  av_log(ctx, AV_LOG_VERBOSE, "x:%f xi:%d y:%f yi:%d\n",
149  s->var_values[VAR_X], s->x,
150  s->var_values[VAR_Y], s->y);
151  }
152  return ret;
153 }
154 
155 static const enum AVPixelFormat alpha_pix_fmts[] = {
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[] = {
174  };
175 
176  static const enum AVPixelFormat main_pix_fmts_yuv420p10[] = {
179  };
180  static const enum AVPixelFormat overlay_pix_fmts_yuv420p10[] = {
182  };
183 
184  static const enum AVPixelFormat main_pix_fmts_yuv422[] = {
186  };
187  static const enum AVPixelFormat overlay_pix_fmts_yuv422[] = {
189  };
190 
191  static const enum AVPixelFormat main_pix_fmts_yuv422p10[] = {
193  };
194  static const enum AVPixelFormat overlay_pix_fmts_yuv422p10[] = {
196  };
197 
198  static const enum AVPixelFormat main_pix_fmts_yuv444[] = {
200  };
201  static const enum AVPixelFormat overlay_pix_fmts_yuv444[] = {
203  };
204 
205  static const enum AVPixelFormat main_pix_fmts_gbrp[] = {
207  };
208  static const enum AVPixelFormat overlay_pix_fmts_gbrp[] = {
210  };
211 
212  static const enum AVPixelFormat main_pix_fmts_rgb[] = {
217  };
218  static const enum AVPixelFormat overlay_pix_fmts_rgb[] = {
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 
279  av_image_fill_max_pixsteps(s->overlay_pix_step, NULL, pix_desc);
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;
285  s->var_values[VAR_OVERLAY_W] = s->var_values[VAR_OW] = ctx->inputs[OVERLAY]->w;
286  s->var_values[VAR_OVERLAY_H] = s->var_values[VAR_OH] = ctx->inputs[OVERLAY]->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 
299  s->overlay_is_packed_rgb =
300  ff_fill_rgba_map(s->overlay_rgba_map, inlink->format) >= 0;
301  s->overlay_has_alpha = ff_fmt_is_in(inlink->format, alpha_pix_fmts);
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 
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,
313  av_get_pix_fmt_name(ctx->inputs[MAIN]->format),
314  ctx->inputs[OVERLAY]->w, ctx->inputs[OVERLAY]->h,
315  av_get_pix_fmt_name(ctx->inputs[OVERLAY]->format));
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 = av_clip_uintp2((*d * (max - alpha) + *s * alpha) / max + *s - (16<<(nbits-8)),\
542  nbits);\
543  } else { \
544  if (i && yuv) \
545  *d = av_clip(FAST_DIV255((*d - mid) * (max - alpha)) + *s - mid, -mid, mid) + mid; \
546  else \
547  *d = av_clip_uint8(FAST_DIV255(*d * (255 - alpha)) + *s - 16); \
548  } \
549  } \
550  s++; \
551  d += dst_step; \
552  da += 1 << hsub; \
553  a += 1 << hsub; \
554  } \
555  dp += dst->linesize[dst_plane] / bytes; \
556  sp += src->linesize[i] / bytes; \
557  ap += (1 << vsub) * src->linesize[3] / bytes; \
558  dap += (1 << vsub) * dst->linesize[3] / bytes; \
559  } \
560 }
561 DEFINE_BLEND_PLANE(8, 8)
562 DEFINE_BLEND_PLANE(16, 10)
563 
564 #define DEFINE_ALPHA_COMPOSITE(depth, nbits) \
565 static inline void alpha_composite_##depth##_##nbits##bits(const AVFrame *src, const AVFrame *dst, \
566  int src_w, int src_h, \
567  int dst_w, int dst_h, \
568  int x, int y, \
569  int jobnr, int nb_jobs) \
570 { \
571  uint##depth##_t alpha; /* the amount of overlay to blend on to main */ \
572  uint##depth##_t *s, *sa, *d, *da; \
573  int i, imax, j, jmax; \
574  int slice_start, slice_end; \
575  const uint##depth##_t max = (1 << nbits) - 1; \
576  int bytes = depth / 8; \
577  \
578  imax = FFMIN3(-y + dst_h, FFMIN(src_h, dst_h), y + src_h); \
579  i = FFMAX(-y, 0); \
580  \
581  slice_start = i + (imax * jobnr) / nb_jobs; \
582  slice_end = i + ((imax * (jobnr+1)) / nb_jobs); \
583  \
584  sa = (uint##depth##_t *)(src->data[3] + (slice_start) * src->linesize[3]); \
585  da = (uint##depth##_t *)(dst->data[3] + (y + slice_start) * dst->linesize[3]); \
586  \
587  for (i = slice_start; i < slice_end; i++) { \
588  j = FFMAX(-x, 0); \
589  s = sa + j; \
590  d = da + x+j; \
591  \
592  for (jmax = FFMIN(-x + dst_w, src_w); j < jmax; j++) { \
593  alpha = *s; \
594  if (alpha != 0 && alpha != max) { \
595  uint8_t alpha_d = *d; \
596  alpha = UNPREMULTIPLY_ALPHA(alpha, alpha_d); \
597  } \
598  if (alpha == max) \
599  *d = *s; \
600  else if (alpha > 0) { \
601  /* apply alpha compositing: main_alpha += (1-main_alpha) * overlay_alpha */ \
602  if (nbits > 8) \
603  *d += (max - *d) * *s / max; \
604  else \
605  *d += FAST_DIV255((max - *d) * *s); \
606  } \
607  d += 1; \
608  s += 1; \
609  } \
610  da += dst->linesize[3] / bytes; \
611  sa += src->linesize[3] / bytes; \
612  } \
613 }
616 
617 #define DEFINE_BLEND_SLICE_YUV(depth, nbits) \
618 static av_always_inline void blend_slice_yuv_##depth##_##nbits##bits(AVFilterContext *ctx, \
619  AVFrame *dst, const AVFrame *src, \
620  int hsub, int vsub, \
621  int main_has_alpha, \
622  int x, int y, \
623  int is_straight, \
624  int jobnr, int nb_jobs) \
625 { \
626  OverlayContext *s = ctx->priv; \
627  const int src_w = src->width; \
628  const int src_h = src->height; \
629  const int dst_w = dst->width; \
630  const int dst_h = dst->height; \
631  \
632  blend_plane_##depth##_##nbits##bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 0, 0, 0, \
633  x, y, main_has_alpha, s->main_desc->comp[0].plane, s->main_desc->comp[0].offset, \
634  s->main_desc->comp[0].step, is_straight, 1, jobnr, nb_jobs); \
635  blend_plane_##depth##_##nbits##bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 1, hsub, vsub, \
636  x, y, main_has_alpha, s->main_desc->comp[1].plane, s->main_desc->comp[1].offset, \
637  s->main_desc->comp[1].step, is_straight, 1, jobnr, nb_jobs); \
638  blend_plane_##depth##_##nbits##bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 2, hsub, vsub, \
639  x, y, main_has_alpha, s->main_desc->comp[2].plane, s->main_desc->comp[2].offset, \
640  s->main_desc->comp[2].step, is_straight, 1, jobnr, nb_jobs); \
641  \
642  if (main_has_alpha) \
643  alpha_composite_##depth##_##nbits##bits(src, dst, src_w, src_h, dst_w, dst_h, x, y, \
644  jobnr, nb_jobs); \
645 }
648 
650  AVFrame *dst, const AVFrame *src,
651  int hsub, int vsub,
652  int main_has_alpha,
653  int x, int y,
654  int is_straight,
655  int jobnr,
656  int nb_jobs)
657 {
658  OverlayContext *s = ctx->priv;
659  const int src_w = src->width;
660  const int src_h = src->height;
661  const int dst_w = dst->width;
662  const int dst_h = dst->height;
663 
664  blend_plane_8_8bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 0, 0, 0, x, y, main_has_alpha,
665  s->main_desc->comp[1].plane, s->main_desc->comp[1].offset, s->main_desc->comp[1].step, is_straight, 0,
666  jobnr, nb_jobs);
667  blend_plane_8_8bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 1, hsub, vsub, x, y, main_has_alpha,
668  s->main_desc->comp[2].plane, s->main_desc->comp[2].offset, s->main_desc->comp[2].step, is_straight, 0,
669  jobnr, nb_jobs);
670  blend_plane_8_8bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 2, hsub, vsub, x, y, main_has_alpha,
671  s->main_desc->comp[0].plane, s->main_desc->comp[0].offset, s->main_desc->comp[0].step, is_straight, 0,
672  jobnr, nb_jobs);
673 
674  if (main_has_alpha)
675  alpha_composite_8_8bits(src, dst, src_w, src_h, dst_w, dst_h, x, y, jobnr, nb_jobs);
676 }
677 
678 static int blend_slice_yuv420(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
679 {
680  OverlayContext *s = ctx->priv;
681  ThreadData *td = arg;
682  blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 1, 0, s->x, s->y, 1, jobnr, nb_jobs);
683  return 0;
684 }
685 
686 static int blend_slice_yuva420(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
687 {
688  OverlayContext *s = ctx->priv;
689  ThreadData *td = arg;
690  blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 1, 1, s->x, s->y, 1, jobnr, nb_jobs);
691  return 0;
692 }
693 
694 static int blend_slice_yuv420p10(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
695 {
696  OverlayContext *s = ctx->priv;
697  ThreadData *td = arg;
698  blend_slice_yuv_16_10bits(ctx, td->dst, td->src, 1, 1, 0, s->x, s->y, 1, jobnr, nb_jobs);
699  return 0;
700 }
701 
702 static int blend_slice_yuva420p10(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
703 {
704  OverlayContext *s = ctx->priv;
705  ThreadData *td = arg;
706  blend_slice_yuv_16_10bits(ctx, td->dst, td->src, 1, 1, 1, s->x, s->y, 1, jobnr, nb_jobs);
707  return 0;
708 }
709 
710 static int blend_slice_yuv422p10(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
711 {
712  OverlayContext *s = ctx->priv;
713  ThreadData *td = arg;
714  blend_slice_yuv_16_10bits(ctx, td->dst, td->src, 1, 0, 0, s->x, s->y, 1, jobnr, nb_jobs);
715  return 0;
716 }
717 
718 static int blend_slice_yuva422p10(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
719 {
720  OverlayContext *s = ctx->priv;
721  ThreadData *td = arg;
722  blend_slice_yuv_16_10bits(ctx, td->dst, td->src, 1, 0, 1, s->x, s->y, 1, jobnr, nb_jobs);
723  return 0;
724 }
725 
726 static int blend_slice_yuv422(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
727 {
728  OverlayContext *s = ctx->priv;
729  ThreadData *td = arg;
730  blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 0, 0, s->x, s->y, 1, jobnr, nb_jobs);
731  return 0;
732 }
733 
734 static int blend_slice_yuva422(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
735 {
736  OverlayContext *s = ctx->priv;
737  ThreadData *td = arg;
738  blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 0, 1, s->x, s->y, 1, jobnr, nb_jobs);
739  return 0;
740 }
741 
742 static int blend_slice_yuv444(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
743 {
744  OverlayContext *s = ctx->priv;
745  ThreadData *td = arg;
746  blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 0, 0, 0, s->x, s->y, 1, jobnr, nb_jobs);
747  return 0;
748 }
749 
750 static int blend_slice_yuva444(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
751 {
752  OverlayContext *s = ctx->priv;
753  ThreadData *td = arg;
754  blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 0, 0, 1, s->x, s->y, 1, jobnr, nb_jobs);
755  return 0;
756 }
757 
758 static int blend_slice_gbrp(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
759 {
760  OverlayContext *s = ctx->priv;
761  ThreadData *td = arg;
762  blend_slice_planar_rgb(ctx, td->dst, td->src, 0, 0, 0, s->x, s->y, 1, jobnr, nb_jobs);
763  return 0;
764 }
765 
766 static int blend_slice_gbrap(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
767 {
768  OverlayContext *s = ctx->priv;
769  ThreadData *td = arg;
770  blend_slice_planar_rgb(ctx, td->dst, td->src, 0, 0, 1, s->x, s->y, 1, jobnr, nb_jobs);
771  return 0;
772 }
773 
774 static int blend_slice_yuv420_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
775 {
776  OverlayContext *s = ctx->priv;
777  ThreadData *td = arg;
778  blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 1, 0, s->x, s->y, 0, jobnr, nb_jobs);
779  return 0;
780 }
781 
782 static int blend_slice_yuva420_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
783 {
784  OverlayContext *s = ctx->priv;
785  ThreadData *td = arg;
786  blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 1, 1, s->x, s->y, 0, jobnr, nb_jobs);
787  return 0;
788 }
789 
790 static int blend_slice_yuv422_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
791 {
792  OverlayContext *s = ctx->priv;
793  ThreadData *td = arg;
794  blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 0, 0, s->x, s->y, 0, jobnr, nb_jobs);
795  return 0;
796 }
797 
798 static int blend_slice_yuva422_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
799 {
800  OverlayContext *s = ctx->priv;
801  ThreadData *td = arg;
802  blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 0, 1, s->x, s->y, 0, jobnr, nb_jobs);
803  return 0;
804 }
805 
806 static int blend_slice_yuv444_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
807 {
808  OverlayContext *s = ctx->priv;
809  ThreadData *td = arg;
810  blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 0, 0, 0, s->x, s->y, 0, jobnr, nb_jobs);
811  return 0;
812 }
813 
814 static int blend_slice_yuva444_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
815 {
816  OverlayContext *s = ctx->priv;
817  ThreadData *td = arg;
818  blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 0, 0, 1, s->x, s->y, 0, jobnr, nb_jobs);
819  return 0;
820 }
821 
822 static int blend_slice_gbrp_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
823 {
824  OverlayContext *s = ctx->priv;
825  ThreadData *td = arg;
826  blend_slice_planar_rgb(ctx, td->dst, td->src, 0, 0, 0, s->x, s->y, 0, jobnr, nb_jobs);
827  return 0;
828 }
829 
830 static int blend_slice_gbrap_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
831 {
832  OverlayContext *s = ctx->priv;
833  ThreadData *td = arg;
834  blend_slice_planar_rgb(ctx, td->dst, td->src, 0, 0, 1, s->x, s->y, 0, jobnr, nb_jobs);
835  return 0;
836 }
837 
838 static int blend_slice_rgb(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
839 {
840  OverlayContext *s = ctx->priv;
841  ThreadData *td = arg;
842  blend_slice_packed_rgb(ctx, td->dst, td->src, 0, s->x, s->y, 1, jobnr, nb_jobs);
843  return 0;
844 }
845 
846 static int blend_slice_rgba(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
847 {
848  OverlayContext *s = ctx->priv;
849  ThreadData *td = arg;
850  blend_slice_packed_rgb(ctx, td->dst, td->src, 1, s->x, s->y, 1, jobnr, nb_jobs);
851  return 0;
852 }
853 
854 static int blend_slice_rgb_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
855 {
856  OverlayContext *s = ctx->priv;
857  ThreadData *td = arg;
858  blend_slice_packed_rgb(ctx, td->dst, td->src, 0, s->x, s->y, 0, jobnr, nb_jobs);
859  return 0;
860 }
861 
862 static int blend_slice_rgba_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
863 {
864  OverlayContext *s = ctx->priv;
865  ThreadData *td = arg;
866  blend_slice_packed_rgb(ctx, td->dst, td->src, 1, s->x, s->y, 0, jobnr, nb_jobs);
867  return 0;
868 }
869 
871 {
872  OverlayContext *s = inlink->dst->priv;
873  const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format);
874 
875  av_image_fill_max_pixsteps(s->main_pix_step, NULL, pix_desc);
876 
877  s->hsub = pix_desc->log2_chroma_w;
878  s->vsub = pix_desc->log2_chroma_h;
879 
880  s->main_desc = pix_desc;
881 
882  s->main_is_packed_rgb =
883  ff_fill_rgba_map(s->main_rgba_map, inlink->format) >= 0;
884  s->main_has_alpha = ff_fmt_is_in(inlink->format, alpha_pix_fmts);
885  switch (s->format) {
887  s->blend_slice = s->main_has_alpha ? blend_slice_yuva420 : blend_slice_yuv420;
888  break;
890  s->blend_slice = s->main_has_alpha ? blend_slice_yuva420p10 : blend_slice_yuv420p10;
891  break;
893  s->blend_slice = s->main_has_alpha ? blend_slice_yuva422 : blend_slice_yuv422;
894  break;
896  s->blend_slice = s->main_has_alpha ? blend_slice_yuva422p10 : blend_slice_yuv422p10;
897  break;
899  s->blend_slice = s->main_has_alpha ? blend_slice_yuva444 : blend_slice_yuv444;
900  break;
901  case OVERLAY_FORMAT_RGB:
902  s->blend_slice = s->main_has_alpha ? blend_slice_rgba : blend_slice_rgb;
903  break;
904  case OVERLAY_FORMAT_GBRP:
905  s->blend_slice = s->main_has_alpha ? blend_slice_gbrap : blend_slice_gbrp;
906  break;
907  case OVERLAY_FORMAT_AUTO:
908  switch (inlink->format) {
909  case AV_PIX_FMT_YUVA420P:
910  s->blend_slice = blend_slice_yuva420;
911  break;
913  s->blend_slice = blend_slice_yuva420p10;
914  break;
915  case AV_PIX_FMT_YUVA422P:
916  s->blend_slice = blend_slice_yuva422;
917  break;
919  s->blend_slice = blend_slice_yuva422p10;
920  break;
921  case AV_PIX_FMT_YUVA444P:
922  s->blend_slice = blend_slice_yuva444;
923  break;
924  case AV_PIX_FMT_ARGB:
925  case AV_PIX_FMT_RGBA:
926  case AV_PIX_FMT_BGRA:
927  case AV_PIX_FMT_ABGR:
928  s->blend_slice = blend_slice_rgba;
929  break;
930  case AV_PIX_FMT_GBRAP:
931  s->blend_slice = blend_slice_gbrap;
932  break;
933  default:
934  av_assert0(0);
935  break;
936  }
937  break;
938  }
939 
940  if (!s->alpha_format)
941  goto end;
942 
943  switch (s->format) {
945  s->blend_slice = s->main_has_alpha ? blend_slice_yuva420_pm : blend_slice_yuv420_pm;
946  break;
948  s->blend_slice = s->main_has_alpha ? blend_slice_yuva422_pm : blend_slice_yuv422_pm;
949  break;
951  s->blend_slice = s->main_has_alpha ? blend_slice_yuva444_pm : blend_slice_yuv444_pm;
952  break;
953  case OVERLAY_FORMAT_RGB:
954  s->blend_slice = s->main_has_alpha ? blend_slice_rgba_pm : blend_slice_rgb_pm;
955  break;
956  case OVERLAY_FORMAT_GBRP:
957  s->blend_slice = s->main_has_alpha ? blend_slice_gbrap_pm : blend_slice_gbrp_pm;
958  break;
959  case OVERLAY_FORMAT_AUTO:
960  switch (inlink->format) {
961  case AV_PIX_FMT_YUVA420P:
962  s->blend_slice = blend_slice_yuva420_pm;
963  break;
964  case AV_PIX_FMT_YUVA422P:
965  s->blend_slice = blend_slice_yuva422_pm;
966  break;
967  case AV_PIX_FMT_YUVA444P:
968  s->blend_slice = blend_slice_yuva444_pm;
969  break;
970  case AV_PIX_FMT_ARGB:
971  case AV_PIX_FMT_RGBA:
972  case AV_PIX_FMT_BGRA:
973  case AV_PIX_FMT_ABGR:
974  s->blend_slice = blend_slice_rgba_pm;
975  break;
976  case AV_PIX_FMT_GBRAP:
977  s->blend_slice = blend_slice_gbrap_pm;
978  break;
979  default:
980  av_assert0(0);
981  break;
982  }
983  break;
984  }
985 
986 end:
987 #if ARCH_X86
988  ff_overlay_init_x86(s, s->format, inlink->format,
989  s->alpha_format, s->main_has_alpha);
990 #endif
991 
992  return 0;
993 }
994 
995 static int do_blend(FFFrameSync *fs)
996 {
997  AVFilterContext *ctx = fs->parent;
998  AVFrame *mainpic, *second;
999  OverlayContext *s = ctx->priv;
1000  AVFilterLink *inlink = ctx->inputs[0];
1001  int ret;
1002 
1003  ret = ff_framesync_dualinput_get_writable(fs, &mainpic, &second);
1004  if (ret < 0)
1005  return ret;
1006  if (!second)
1007  return ff_filter_frame(ctx->outputs[0], mainpic);
1008 
1009  if (s->eval_mode == EVAL_MODE_FRAME) {
1010  int64_t pos = mainpic->pkt_pos;
1011 
1012  s->var_values[VAR_N] = inlink->frame_count_out;
1013  s->var_values[VAR_T] = mainpic->pts == AV_NOPTS_VALUE ?
1014  NAN : mainpic->pts * av_q2d(inlink->time_base);
1015  s->var_values[VAR_POS] = pos == -1 ? NAN : pos;
1016 
1017  s->var_values[VAR_OVERLAY_W] = s->var_values[VAR_OW] = second->width;
1018  s->var_values[VAR_OVERLAY_H] = s->var_values[VAR_OH] = second->height;
1019  s->var_values[VAR_MAIN_W ] = s->var_values[VAR_MW] = mainpic->width;
1020  s->var_values[VAR_MAIN_H ] = s->var_values[VAR_MH] = mainpic->height;
1021 
1022  eval_expr(ctx);
1023  av_log(ctx, AV_LOG_DEBUG, "n:%f t:%f pos:%f x:%f xi:%d y:%f yi:%d\n",
1024  s->var_values[VAR_N], s->var_values[VAR_T], s->var_values[VAR_POS],
1025  s->var_values[VAR_X], s->x,
1026  s->var_values[VAR_Y], s->y);
1027  }
1028 
1029  if (s->x < mainpic->width && s->x + second->width >= 0 &&
1030  s->y < mainpic->height && s->y + second->height >= 0) {
1031  ThreadData td;
1032 
1033  td.dst = mainpic;
1034  td.src = second;
1035  ff_filter_execute(ctx, s->blend_slice, &td, NULL, FFMIN(FFMAX(1, FFMIN3(s->y + second->height, FFMIN(second->height, mainpic->height), mainpic->height - s->y)),
1037  }
1038  return ff_filter_frame(ctx->outputs[0], mainpic);
1039 }
1040 
1042 {
1043  OverlayContext *s = ctx->priv;
1044 
1045  s->fs.on_event = do_blend;
1046  return 0;
1047 }
1048 
1050 {
1051  OverlayContext *s = ctx->priv;
1052  return ff_framesync_activate(&s->fs);
1053 }
1054 
1055 #define OFFSET(x) offsetof(OverlayContext, x)
1056 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
1057 
1058 static const AVOption overlay_options[] = {
1059  { "x", "set the x expression", OFFSET(x_expr), AV_OPT_TYPE_STRING, {.str = "0"}, 0, 0, FLAGS },
1060  { "y", "set the y expression", OFFSET(y_expr), AV_OPT_TYPE_STRING, {.str = "0"}, 0, 0, FLAGS },
1061  { "eof_action", "Action to take when encountering EOF from secondary input ",
1062  OFFSET(fs.opt_eof_action), AV_OPT_TYPE_INT, { .i64 = EOF_ACTION_REPEAT },
1063  EOF_ACTION_REPEAT, EOF_ACTION_PASS, .flags = FLAGS, "eof_action" },
1064  { "repeat", "Repeat the previous frame.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_REPEAT }, .flags = FLAGS, "eof_action" },
1065  { "endall", "End both streams.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_ENDALL }, .flags = FLAGS, "eof_action" },
1066  { "pass", "Pass through the main input.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_PASS }, .flags = FLAGS, "eof_action" },
1067  { "eval", "specify when to evaluate expressions", OFFSET(eval_mode), AV_OPT_TYPE_INT, {.i64 = EVAL_MODE_FRAME}, 0, EVAL_MODE_NB-1, FLAGS, "eval" },
1068  { "init", "eval expressions once during initialization", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_INIT}, .flags = FLAGS, .unit = "eval" },
1069  { "frame", "eval expressions per-frame", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_FRAME}, .flags = FLAGS, .unit = "eval" },
1070  { "shortest", "force termination when the shortest input terminates", OFFSET(fs.opt_shortest), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS },
1071  { "format", "set output format", OFFSET(format), AV_OPT_TYPE_INT, {.i64=OVERLAY_FORMAT_YUV420}, 0, OVERLAY_FORMAT_NB-1, FLAGS, "format" },
1072  { "yuv420", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV420}, .flags = FLAGS, .unit = "format" },
1073  { "yuv420p10", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV420P10}, .flags = FLAGS, .unit = "format" },
1074  { "yuv422", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV422}, .flags = FLAGS, .unit = "format" },
1075  { "yuv422p10", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV422P10}, .flags = FLAGS, .unit = "format" },
1076  { "yuv444", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV444}, .flags = FLAGS, .unit = "format" },
1077  { "rgb", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_RGB}, .flags = FLAGS, .unit = "format" },
1078  { "gbrp", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_GBRP}, .flags = FLAGS, .unit = "format" },
1079  { "auto", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_AUTO}, .flags = FLAGS, .unit = "format" },
1080  { "repeatlast", "repeat overlay of the last overlay frame", OFFSET(fs.opt_repeatlast), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGS },
1081  { "alpha", "alpha format", OFFSET(alpha_format), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "alpha_format" },
1082  { "straight", "", 0, AV_OPT_TYPE_CONST, {.i64=0}, .flags = FLAGS, .unit = "alpha_format" },
1083  { "premultiplied", "", 0, AV_OPT_TYPE_CONST, {.i64=1}, .flags = FLAGS, .unit = "alpha_format" },
1084  { NULL }
1085 };
1086 
1088 
1090  {
1091  .name = "main",
1092  .type = AVMEDIA_TYPE_VIDEO,
1093  .config_props = config_input_main,
1094  },
1095  {
1096  .name = "overlay",
1097  .type = AVMEDIA_TYPE_VIDEO,
1098  .config_props = config_input_overlay,
1099  },
1100 };
1101 
1103  {
1104  .name = "default",
1105  .type = AVMEDIA_TYPE_VIDEO,
1106  .config_props = config_output,
1107  },
1108 };
1109 
1111  .name = "overlay",
1112  .description = NULL_IF_CONFIG_SMALL("Overlay a video source on top of the input."),
1113  .preinit = overlay_framesync_preinit,
1114  .init = init,
1115  .uninit = uninit,
1116  .priv_size = sizeof(OverlayContext),
1117  .priv_class = &overlay_class,
1118  .activate = activate,
1125 };
formats
formats
Definition: signature.h:48
VAR_MAIN_H
@ VAR_MAIN_H
Definition: vf_drawtext.c:122
ff_framesync_configure
int ff_framesync_configure(FFFrameSync *fs)
Configure a frame sync structure.
Definition: framesync.c:119
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:349
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
VAR_OH
@ VAR_OH
Definition: scale_eval.c:46
blend_slice_rgb
static int blend_slice_rgb(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:838
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:380
ff_framesync_uninit
void ff_framesync_uninit(FFFrameSync *fs)
Free all memory currently allocated.
Definition: framesync.c:285
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:999
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2675
blend_slice_yuv422
static int blend_slice_yuv422(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:726
avfilter_vf_overlay_outputs
static const AVFilterPad avfilter_vf_overlay_outputs[]
Definition: vf_overlay.c:1102
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
blend_slice_yuv422p10
static int blend_slice_yuv422p10(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:710
blend_slice_yuva422_pm
static int blend_slice_yuva422_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:798
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:325
pixdesc.h
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:432
AVFrame::width
int width
Definition: frame.h:397
do_blend
static int do_blend(FFFrameSync *fs)
Definition: vf_overlay.c:995
AV_PIX_FMT_YUVA420P10
#define AV_PIX_FMT_YUVA420P10
Definition: pixfmt.h:445
AVOption
AVOption.
Definition: opt.h:251
EOF_ACTION_ENDALL
@ EOF_ACTION_ENDALL
Definition: framesync.h:28
FILTER_QUERY_FUNC
#define FILTER_QUERY_FUNC(func)
Definition: internal.h:167
AV_PIX_FMT_YUV420P10
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:408
VAR_HSUB
@ VAR_HSUB
Definition: boxblur.c:40
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:196
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
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
blend_slice_yuv420
static int blend_slice_yuv420(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:678
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:175
FFFrameSync
Frame sync structure.
Definition: framesync.h:146
blend_slice_yuva422p10
static int blend_slice_yuva422p10(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:718
video.h
VAR_MAIN_W
@ VAR_MAIN_W
Definition: vf_drawtext.c:123
AV_PIX_FMT_YUVA422P10
#define AV_PIX_FMT_YUVA422P10
Definition: pixfmt.h:446
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:346
hsub
static void hsub(htype *dst, const htype *src, int bins)
Definition: vf_median.c:74
AVFilterFormats
A list of supported formats for one end of a filter link.
Definition: formats.h:64
blend_slice_gbrap
static int blend_slice_gbrap(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:766
formats.h
av_expr_parse
int av_expr_parse(AVExpr **expr, const char *s, const char *const *const_names, const char *const *func1_names, double(*const *funcs1)(void *, double), const char *const *func2_names, double(*const *funcs2)(void *, double, double), int log_offset, void *log_ctx)
Parse an expression.
Definition: eval.c:685
var_names
static const char *const var_names[]
Definition: vf_overlay.c:48
S
#define S(s, c, i)
Definition: flacdsp_template.c:46
VAR_T
@ VAR_T
Definition: aeval.c:53
VAR_VSUB
@ VAR_VSUB
Definition: boxblur.c:41
OVERLAY_FORMAT_RGB
@ OVERLAY_FORMAT_RGB
Definition: vf_overlay.h:48
blend_slice_gbrp_pm
static int blend_slice_gbrp_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:822
AV_PIX_FMT_GBRAP
@ AV_PIX_FMT_GBRAP
planar GBRA 4:4:4:4 32bpp
Definition: pixfmt.h:205
FAST_DIV255
#define FAST_DIV255(x)
Definition: vf_overlay.c:337
OVERLAY_FORMAT_YUV422P10
@ OVERLAY_FORMAT_YUV422P10
Definition: vf_overlay.h:46
av_expr_free
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
Definition: eval.c:336
VAR_X
@ VAR_X
Definition: vf_blend.c:52
R
#define R
Definition: vf_overlay.c:66
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:49
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:180
config_input_main
static int config_input_main(AVFilterLink *inlink)
Definition: vf_overlay.c:870
query_formats
static int query_formats(AVFilterContext *ctx)
Definition: vf_overlay.c:162
av_cold
#define av_cold
Definition: attributes.h:90
blend_slice_rgb_pm
static int blend_slice_rgb_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:854
EVAL_MODE_FRAME
@ EVAL_MODE_FRAME
Definition: vf_overlay.c:77
AV_PIX_FMT_YUVJ422P
@ AV_PIX_FMT_YUVJ422P
planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting col...
Definition: pixfmt.h:79
s
#define s(width, name)
Definition: cbs_vp9.c:256
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:45
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:605
ff_formats_ref
int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
Add *ref as a new reference to formats.
Definition: formats.c:596
slice_end
static int slice_end(AVCodecContext *avctx, AVFrame *pict)
Handle slice ends.
Definition: mpeg12dec.c:2013
av_q2d
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
ff_set_common_formats_from_list
int ff_set_common_formats_from_list(AVFilterContext *ctx, const int *fmts)
Equivalent to ff_set_common_formats(ctx, ff_make_format_list(fmts))
Definition: formats.c:755
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
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:201
ctx
AVFormatContext * ctx
Definition: movenc.c:48
av_expr_eval
double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
Evaluate a previously parsed expression.
Definition: eval.c:766
UNPREMULTIPLY_ALPHA
#define UNPREMULTIPLY_ALPHA(x, y)
Definition: vf_overlay.c:343
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:80
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
blend_slice_yuva420p10
static int blend_slice_yuva420p10(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:702
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
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: internal.h:190
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:67
ff_vf_overlay
const AVFilter ff_vf_overlay
Definition: vf_overlay.c:1110
option
option
Definition: libkvazaar.c:312
ThreadData::dst
AVFrame * dst
Definition: vf_blend.c:56
config_input_overlay
static int config_input_overlay(AVFilterLink *inlink)
Definition: vf_overlay.c:272
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:258
ThreadData::src
const uint8_t * src
Definition: vf_bm3d.c:55
blend_slice_yuva444_pm
static int blend_slice_yuva444_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:814
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:54
VAR_POS
@ VAR_POS
Definition: noise_bsf.c:55
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:351
AV_PIX_FMT_YUV422P10
#define AV_PIX_FMT_YUV422P10
Definition: pixfmt.h:409
blend_slice_yuv420_pm
static int blend_slice_yuv420_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:774
AV_PIX_FMT_ABGR
@ AV_PIX_FMT_ABGR
packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
Definition: pixfmt.h:94
avfilter_vf_overlay_inputs
static const AVFilterPad avfilter_vf_overlay_inputs[]
Definition: vf_overlay.c:1089
eval.h
blend_slice_yuv420p10
static int blend_slice_yuv420p10(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:694
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:1058
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:117
ff_framesync_init_dualinput
int ff_framesync_init_dualinput(FFFrameSync *fs, AVFilterContext *parent)
Initialize a frame sync structure for dualinput.
Definition: framesync.c:353
VAR_N
@ VAR_N
Definition: noise_bsf.c:47
OVERLAY_FORMAT_NB
@ OVERLAY_FORMAT_NB
Definition: vf_overlay.h:51
OVERLAY_FORMAT_YUV420P10
@ OVERLAY_FORMAT_YUV420P10
Definition: vf_overlay.h:44
sp
#define sp
Definition: regdef.h:63
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:319
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:167
OVERLAY_FORMAT_AUTO
@ OVERLAY_FORMAT_AUTO
Definition: vf_overlay.h:50
DEFINE_ALPHA_COMPOSITE
#define DEFINE_ALPHA_COMPOSITE(depth, nbits)
Definition: vf_overlay.c:564
blend_slice_rgba
static int blend_slice_rgba(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:846
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:782
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:1056
blend_slice_gbrap_pm
static int blend_slice_gbrap_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:830
blend_slice_yuva444
static int blend_slice_yuva444(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:750
blend_slice_rgba_pm
static int blend_slice_rgba_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:862
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
blend_slice_planar_rgb
static av_always_inline void blend_slice_planar_rgb(AVFilterContext *ctx, AVFrame *dst, const AVFrame *src, int hsub, int vsub, int main_has_alpha, int x, int y, int is_straight, int jobnr, int nb_jobs)
Definition: vf_overlay.c:649
FFMIN3
#define FFMIN3(a, b, c)
Definition: macros.h:50
common.h
ff_filter_get_nb_threads
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition: avfilter.c:783
VAR_Y
@ VAR_Y
Definition: vf_blend.c:52
ThreadData
Used for passing data between threads.
Definition: dsddec.c:68
EvalMode
EvalMode
Definition: af_volume.h:39
av_always_inline
#define av_always_inline
Definition: attributes.h:49
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
AV_PIX_FMT_NV21
@ AV_PIX_FMT_NV21
as above, but U and V bytes are swapped
Definition: pixfmt.h:90
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:55
blend_slice_gbrp
static int blend_slice_gbrp(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:758
VAR_OVERLAY_H
@ VAR_OVERLAY_H
Definition: vf_overlay.h:31
VAR_OW
@ VAR_OW
Definition: scale_eval.c:45
normalize_xy
static int normalize_xy(double d, int chroma_sub)
Definition: vf_overlay.c:90
blend_slice_yuv444
static int blend_slice_yuv444(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:742
AVFilter
Filter definition.
Definition: avfilter.h:171
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
DEFINE_BLEND_PLANE
#define DEFINE_BLEND_PLANE(depth, nbits)
Definition: vf_overlay.c:436
MAIN
#define MAIN
Definition: vf_overlay.c:63
pos
unsigned int pos
Definition: spdifenc.c:412
EOF_ACTION_REPEAT
@ EOF_ACTION_REPEAT
Definition: framesync.h:27
blend_slice_yuva422
static int blend_slice_yuva422(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:734
AVFrame::height
int height
Definition: frame.h:397
framesync.h
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:225
avfilter.h
activate
static int activate(AVFilterContext *ctx)
Definition: vf_overlay.c:1049
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:806
AVFilterContext
An instance of a filter.
Definition: avfilter.h:408
AV_PIX_FMT_GBRP
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:158
OVERLAY_FORMAT_GBRP
@ OVERLAY_FORMAT_GBRP
Definition: vf_overlay.h:49
AVFILTER_FLAG_SLICE_THREADS
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
Definition: avfilter.h:127
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:47
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
FRAMESYNC_DEFINE_CLASS
FRAMESYNC_DEFINE_CLASS(overlay, OverlayContext, fs)
alpha
static const int16_t alpha[]
Definition: ilbcdata.h:55
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:244
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: internal.h:191
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
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
DEFINE_BLEND_SLICE_YUV
#define DEFINE_BLEND_SLICE_YUV(depth, nbits)
Definition: vf_overlay.c:617
d
d
Definition: ffmpeg_filter.c:155
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:160
imgutils.h
timestamp.h
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:561
AVFrame::linesize
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
Definition: frame.h:370
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
ff_framesync_activate
int ff_framesync_activate(FFFrameSync *fs)
Examine the frames in the filter's input and try to produce output.
Definition: framesync.c:336
avstring.h
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:229
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:391
drawutils.h
alpha_pix_fmts
static enum AVPixelFormat alpha_pix_fmts[]
Definition: vf_overlay.c:155
OFFSET
#define OFFSET(x)
Definition: vf_overlay.c:1055
ff_filter_execute
static av_always_inline int ff_filter_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg, int *ret, int nb_jobs)
Definition: internal.h:142
VAR_OVERLAY_W
@ VAR_OVERLAY_W
Definition: vf_overlay.h:30
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:234
blend_slice_yuva420
static int blend_slice_yuva420(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:686
AVPixFmtDescriptor::log2_chroma_h
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:89
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:166
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:2595
blend_slice_yuv422_pm
static int blend_slice_yuv422_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_overlay.c:790
init
static av_cold int init(AVFilterContext *ctx)
Definition: vf_overlay.c:1041