FFmpeg
vf_mix.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Paul B Mahol
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include "config_components.h"
22 
23 #include "libavutil/avstring.h"
24 #include "libavutil/imgutils.h"
25 #include "libavutil/mem.h"
26 #include "libavutil/opt.h"
27 #include "libavutil/pixdesc.h"
28 
29 #include "avfilter.h"
30 #include "filters.h"
31 #include "formats.h"
32 #include "framesync.h"
33 #include "video.h"
34 
35 typedef struct MixContext {
36  const AVClass *class;
38  char *weights_str;
39  int nb_inputs;
41  int duration;
42  float *weights;
43  float scale;
44  float wfactor;
45 
46  int fast;
47  int tmix;
48  int nb_frames;
50 
51  int depth;
52  int max;
53  int planes;
54  int nb_planes;
55  int linesizes[4];
56  int height[4];
57 
58  uint8_t *sum[4];
59 
60  uint8_t **data;
61  int *linesize;
62 
65 } MixContext;
66 
67 static int query_formats(const AVFilterContext *ctx,
68  AVFilterFormatsConfig **cfg_in,
69  AVFilterFormatsConfig **cfg_out)
70 {
71  unsigned reject_flags = AV_PIX_FMT_FLAG_BITSTREAM |
74  unsigned accept_flags = 0;
75 
76  if (!HAVE_BIGENDIAN)
77  reject_flags |= AV_PIX_FMT_FLAG_BE;
78  else
79  accept_flags |= AV_PIX_FMT_FLAG_BE;
80 
81  return ff_set_common_formats2(ctx, cfg_in, cfg_out,
82  ff_formats_pixdesc_filter(accept_flags, reject_flags));
83 }
84 
86 {
87  MixContext *s = ctx->priv;
88  char *p, *arg, *saveptr = NULL;
89  int i, last = 0;
90 
91  s->fast = 1;
92  s->wfactor = 0.f;
93  p = s->weights_str;
94  for (i = 0; i < s->nb_inputs; i++) {
95  if (!(arg = av_strtok(p, " |", &saveptr)))
96  break;
97 
98  p = NULL;
99  if (av_sscanf(arg, "%f", &s->weights[i]) != 1) {
100  av_log(ctx, AV_LOG_ERROR, "Invalid syntax for weights[%d].\n", i);
101  return AVERROR(EINVAL);
102  }
103  s->wfactor += s->weights[i];
104  if (i > 0)
105  s->fast &= s->weights[i] == s->weights[0];
106  last = i;
107  }
108 
109  for (; i < s->nb_inputs; i++) {
110  s->weights[i] = s->weights[last];
111  s->wfactor += s->weights[i];
112  }
113  if (s->scale == 0) {
114  s->wfactor = 1 / s->wfactor;
115  } else {
116  if (s->scale != 1.f / s->wfactor)
117  s->fast = 0;
118  s->wfactor = s->scale;
119  }
120 
121  return 0;
122 }
123 
125 {
126  MixContext *s = ctx->priv;
127  int ret;
128 
129  s->tmix = !strcmp(ctx->filter->name, "tmix");
130 
131  s->frames = av_calloc(s->nb_inputs, sizeof(*s->frames));
132  if (!s->frames)
133  return AVERROR(ENOMEM);
134 
135  s->weights = av_calloc(s->nb_inputs, sizeof(*s->weights));
136  if (!s->weights)
137  return AVERROR(ENOMEM);
138 
139  if (!s->tmix) {
140  for (int i = 0; i < s->nb_inputs; i++) {
141  AVFilterPad pad = { 0 };
142 
143  pad.type = AVMEDIA_TYPE_VIDEO;
144  pad.name = av_asprintf("input%d", i);
145  if (!pad.name)
146  return AVERROR(ENOMEM);
147 
148  if ((ret = ff_append_inpad_free_name(ctx, &pad)) < 0)
149  return ret;
150  }
151  }
152 
153  return parse_weights(ctx);
154 }
155 
156 typedef struct ThreadData {
157  AVFrame **in, *out;
158 } ThreadData;
159 
160 #define FAST_TMIX_SLICE(type, stype, round) \
161  for (int p = 0; p < s->nb_planes; p++) { \
162  const int slice_start = (s->height[p] * jobnr) / nb_jobs; \
163  const int slice_end = (s->height[p] * (jobnr+1)) / nb_jobs; \
164  const int width = s->linesizes[p] / sizeof(type); \
165  stype *sum = (stype *)(s->sum[p] + slice_start * s->linesizes[p] * 2); \
166  type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
167  const ptrdiff_t sum_linesize = (s->linesizes[p] * 2) / sizeof(stype); \
168  const ptrdiff_t dst_linesize = out->linesize[p] / sizeof(type); \
169  const int idx = FFMAX(0, nb_inputs - nb_unique); \
170  const ptrdiff_t src_linesize[2] = { in[idx]->linesize[p], \
171  in[nb_inputs-1]->linesize[p] }; \
172  const type *src[2]; \
173  \
174  if (!((1 << p) & s->planes)) { \
175  av_image_copy_plane((uint8_t *)dst, out->linesize[p], \
176  in[0]->data[p] + slice_start * in[0]->linesize[p], \
177  in[0]->linesize[p], \
178  s->linesizes[p], slice_end - slice_start); \
179  continue; \
180  } \
181  \
182  src[0] = (const type *)(in[idx]->data[p] + slice_start*src_linesize[0]); \
183  src[1] = (const type *)(in[nb_inputs-1]->data[p] + slice_start * src_linesize[1]); \
184  \
185  for (int y = slice_start; y < slice_end; y++) { \
186  for (int x = 0; x < width; x++) { \
187  sum[x] += src[1][x] * (1 + (nb_inputs - 1) * (idx == (nb_inputs - 1))); \
188  dst[x] = (sum[x] + (round)) / nb_inputs; \
189  sum[x] -= src[0][x]; \
190  } \
191  \
192  dst += dst_linesize; \
193  sum += sum_linesize; \
194  src[0] += src_linesize[0] / sizeof(type); \
195  src[1] += src_linesize[1] / sizeof(type); \
196  } \
197  }
198 
199 #define MIX_SLICE(type, fun, clip) \
200  for (int p = 0; p < s->nb_planes; p++) { \
201  const int slice_start = (s->height[p] * jobnr) / nb_jobs; \
202  const int slice_end = (s->height[p] * (jobnr+1)) / nb_jobs; \
203  const int width = s->linesizes[p] / sizeof(type); \
204  type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
205  const ptrdiff_t dst_linesize = out->linesize[p] / sizeof(type); \
206  \
207  if (!((1 << p) & s->planes)) { \
208  av_image_copy_plane((uint8_t *)dst, out->linesize[p], \
209  in[0]->data[p] + slice_start * in[0]->linesize[p], \
210  in[0]->linesize[p], \
211  s->linesizes[p], slice_end - slice_start); \
212  continue; \
213  } \
214  \
215  for (int i = 0; i < nb_inputs; i++) \
216  linesize[i] = in[i]->linesize[p]; \
217  \
218  for (int i = 0; i < nb_inputs; i++) \
219  srcf[i] = in[i]->data[p] + slice_start * linesize[i]; \
220  \
221  for (int y = slice_start; y < slice_end; y++) { \
222  for (int x = 0; x < width; x++) { \
223  float val = 0.f; \
224  \
225  for (int i = 0; i < nb_inputs; i++) { \
226  float src = *(type *)(srcf[i] + x * sizeof(type)); \
227  \
228  val += src * weights[i]; \
229  } \
230  \
231  dst[x] = clip(fun(val * wfactor), 0, max); \
232  } \
233  \
234  dst += dst_linesize; \
235  for (int i = 0; i < nb_inputs; i++) \
236  srcf[i] += linesize[i]; \
237  } \
238  }
239 
240 #define CLIP8(x, min, max) av_clip_uint8(x)
241 #define CLIP16(x, min, max) av_clip(x, min, max)
242 #define CLIPF(x, min, max) (x)
243 #define NOP(x) (x)
244 
245 static int mix_frames(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
246 {
247  MixContext *s = ctx->priv;
248  ThreadData *td = arg;
249  AVFrame **in = td->in;
250  AVFrame *out = td->out;
251  const float *weights = s->weights;
252  uint8_t **srcf = s->data + jobnr * s->nb_inputs;
253  int *linesize = s->linesize + jobnr * s->nb_inputs;
254  const int nb_unique = s->nb_unique_frames;
255  const int nb_inputs = s->nb_inputs;
256  const float wfactor = s->wfactor;
257  const int max = s->max;
258 
259  if (s->tmix && s->fast) {
260  if (s->depth <= 8) {
261  FAST_TMIX_SLICE(uint8_t, uint16_t, nb_inputs >> 1)
262  } else if (s->depth <= 16) {
263  FAST_TMIX_SLICE(uint16_t, uint32_t, nb_inputs >> 1)
264  } else {
265  FAST_TMIX_SLICE(float, float, 0.f)
266  }
267 
268  return 0;
269  }
270 
271  if (s->depth <= 8) {
272  MIX_SLICE(uint8_t, lrintf, CLIP8)
273  } else if (s->depth <= 16) {
274  MIX_SLICE(uint16_t, lrintf, CLIP16)
275  } else {
276  MIX_SLICE(float, NOP, CLIPF)
277  }
278 
279  return 0;
280 }
281 
283 {
284  AVFilterContext *ctx = fs->parent;
285  AVFilterLink *outlink = ctx->outputs[0];
286  MixContext *s = fs->opaque;
287  AVFrame **in = s->frames;
288  AVFrame *out;
289  ThreadData td;
290  int i, ret;
291 
292  for (i = 0; i < s->nb_inputs; i++) {
293  if ((ret = ff_framesync_get_frame(&s->fs, i, &in[i], 0)) < 0)
294  return ret;
295  }
296 
297  if (ctx->is_disabled) {
298  out = av_frame_clone(s->frames[0]);
299  if (!out)
300  return AVERROR(ENOMEM);
301  out->pts = av_rescale_q(s->fs.pts, s->fs.time_base, outlink->time_base);
302  return ff_filter_frame(outlink, out);
303  }
304 
305  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
306  if (!out)
307  return AVERROR(ENOMEM);
308  out->pts = av_rescale_q(s->fs.pts, s->fs.time_base, outlink->time_base);
309 
310  td.in = in;
311  td.out = out;
313  FFMIN(s->height[1], s->nb_threads));
314 
315  return ff_filter_frame(outlink, out);
316 }
317 
318 static int config_output(AVFilterLink *outlink)
319 {
320  AVFilterContext *ctx = outlink->src;
321  MixContext *s = ctx->priv;
322  FilterLink *il = ff_filter_link(ctx->inputs[0]);
323  FilterLink *ol = ff_filter_link(outlink);
324  AVRational sar = ctx->inputs[0]->sample_aspect_ratio;
325  AVFilterLink *inlink = ctx->inputs[0];
326  int height = ctx->inputs[0]->h;
327  int width = ctx->inputs[0]->w;
328  FFFrameSyncIn *in;
329  int i, ret;
330 
331  if (!s->tmix) {
332  for (i = 1; i < s->nb_inputs; i++) {
333  if (ctx->inputs[i]->h != height || ctx->inputs[i]->w != width) {
334  av_log(ctx, AV_LOG_ERROR, "Input %d size (%dx%d) does not match input %d size (%dx%d).\n", i, ctx->inputs[i]->w, ctx->inputs[i]->h, 0, width, height);
335  return AVERROR(EINVAL);
336  }
337  }
338  }
339 
340  s->nb_threads = ff_filter_get_nb_threads(ctx);
341  s->desc = av_pix_fmt_desc_get(outlink->format);
342  if (!s->desc)
343  return AVERROR_BUG;
344  s->nb_planes = av_pix_fmt_count_planes(outlink->format);
345  s->depth = s->desc->comp[0].depth;
346  s->max = (1 << s->depth) - 1;
347 
348  if ((ret = av_image_fill_linesizes(s->linesizes, inlink->format, inlink->w)) < 0)
349  return ret;
350 
351  s->height[1] = s->height[2] = AV_CEIL_RSHIFT(inlink->h, s->desc->log2_chroma_h);
352  s->height[0] = s->height[3] = inlink->h;
353 
354  s->data = av_calloc(s->nb_threads * s->nb_inputs, sizeof(*s->data));
355  if (!s->data)
356  return AVERROR(ENOMEM);
357 
358  s->linesize = av_calloc(s->nb_threads * s->nb_inputs, sizeof(*s->linesize));
359  if (!s->linesize)
360  return AVERROR(ENOMEM);
361 
362  if (s->tmix) {
363  for (int p = 0; p < s->nb_planes; p++) {
364  s->sum[p] = av_calloc(s->linesizes[p], s->height[p] * sizeof(*s->sum) * 2);
365  if (!s->sum[p])
366  return AVERROR(ENOMEM);
367  }
368  return 0;
369  }
370 
371  outlink->w = width;
372  outlink->h = height;
373  ol->frame_rate = il->frame_rate;
374  outlink->sample_aspect_ratio = sar;
375 
376  if ((ret = ff_framesync_init(&s->fs, ctx, s->nb_inputs)) < 0)
377  return ret;
378 
379  in = s->fs.in;
380  s->fs.opaque = s;
381  s->fs.on_event = process_frame;
382 
383  for (i = 0; i < s->nb_inputs; i++) {
384  AVFilterLink *inlink = ctx->inputs[i];
385 
386  in[i].time_base = inlink->time_base;
387  in[i].sync = 1;
388  in[i].before = EXT_STOP;
389  in[i].after = (s->duration == 1 || (s->duration == 2 && i == 0)) ? EXT_STOP : EXT_INFINITY;
390  }
391 
392  ret = ff_framesync_configure(&s->fs);
393  outlink->time_base = s->fs.time_base;
394 
395  return ret;
396 }
397 
399 {
400  MixContext *s = ctx->priv;
401  int i;
402 
403  ff_framesync_uninit(&s->fs);
404  av_freep(&s->weights);
405  av_freep(&s->data);
406  av_freep(&s->linesize);
407 
408  if (s->tmix) {
409  for (i = 0; i < 4; i++)
410  av_freep(&s->sum[i]);
411  for (i = 0; i < s->nb_frames && s->frames; i++)
412  av_frame_free(&s->frames[i]);
413  }
414  av_freep(&s->frames);
415 }
416 
417 static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
418  char *res, int res_len, int flags)
419 {
420  int ret;
421 
422  ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags);
423  if (ret < 0)
424  return ret;
425 
426  return parse_weights(ctx);
427 }
428 
430 {
431  MixContext *s = ctx->priv;
432  return ff_framesync_activate(&s->fs);
433 }
434 
435 #define OFFSET(x) offsetof(MixContext, x)
436 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM
437 #define TFLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_RUNTIME_PARAM
438 
439 static const AVOption mix_options[] = {
440  { "inputs", "set number of inputs", OFFSET(nb_inputs), AV_OPT_TYPE_INT, {.i64=2}, 2, INT16_MAX, .flags = FLAGS },
441  { "weights", "set weight for each input", OFFSET(weights_str), AV_OPT_TYPE_STRING, {.str="1 1"}, 0, 0, .flags = TFLAGS },
442  { "scale", "set scale", OFFSET(scale), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, INT16_MAX, .flags = TFLAGS },
443  { "planes", "set what planes to filter", OFFSET(planes), AV_OPT_TYPE_FLAGS, {.i64=15}, 0, 15, .flags = TFLAGS },
444  { "duration", "how to determine end of stream", OFFSET(duration), AV_OPT_TYPE_INT, {.i64=0}, 0, 2, .flags = FLAGS, .unit = "duration" },
445  { "longest", "Duration of longest input", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, .unit = "duration" },
446  { "shortest", "Duration of shortest input", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, .unit = "duration" },
447  { "first", "Duration of first input", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, .unit = "duration" },
448  { NULL },
449 };
450 
451 static const AVFilterPad outputs[] = {
452  {
453  .name = "default",
454  .type = AVMEDIA_TYPE_VIDEO,
455  .config_props = config_output,
456  },
457 };
458 
459 #if CONFIG_MIX_FILTER
461 
462 const AVFilter ff_vf_mix = {
463  .name = "mix",
464  .description = NULL_IF_CONFIG_SMALL("Mix video inputs."),
465  .priv_size = sizeof(MixContext),
466  .priv_class = &mix_class,
469  .init = init,
470  .uninit = uninit,
471  .activate = activate,
474  .process_command = process_command,
475 };
476 
477 #endif /* CONFIG_MIX_FILTER */
478 
479 #if CONFIG_TMIX_FILTER
480 static int tmix_filter_frame(AVFilterLink *inlink, AVFrame *in)
481 {
482  AVFilterContext *ctx = inlink->dst;
483  AVFilterLink *outlink = ctx->outputs[0];
484  MixContext *s = ctx->priv;
485  ThreadData td;
486  AVFrame *out;
487 
488  if (s->nb_inputs == 1)
489  return ff_filter_frame(outlink, in);
490 
491  if (s->nb_frames < s->nb_inputs) {
492  s->frames[s->nb_frames] = in;
493  s->nb_frames++;
494  s->nb_unique_frames++;
495  while (s->nb_frames < s->nb_inputs) {
496  s->frames[s->nb_frames] = av_frame_clone(s->frames[s->nb_frames - 1]);
497  if (!s->frames[s->nb_frames])
498  return AVERROR(ENOMEM);
499  s->nb_frames++;
500  }
501  } else {
502  s->nb_unique_frames = FFMIN(s->nb_unique_frames + 1, s->nb_inputs);
503  av_frame_free(&s->frames[0]);
504  memmove(&s->frames[0], &s->frames[1], sizeof(*s->frames) * (s->nb_inputs - 1));
505  s->frames[s->nb_inputs - 1] = in;
506  }
507 
508  if (ctx->is_disabled) {
509  out = av_frame_clone(s->frames[0]);
510  if (!out)
511  return AVERROR(ENOMEM);
512  return ff_filter_frame(outlink, out);
513  }
514 
515  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
516  if (!out)
517  return AVERROR(ENOMEM);
518  out->pts = s->frames[s->nb_frames - 1]->pts;
519 
520  td.out = out;
521  td.in = s->frames;
523  FFMIN(s->height[1], s->nb_threads));
524 
525  return ff_filter_frame(outlink, out);
526 }
527 
528 static const AVOption tmix_options[] = {
529  { "frames", "set number of successive frames to mix", OFFSET(nb_inputs), AV_OPT_TYPE_INT, {.i64=3}, 1, 1024, .flags = FLAGS },
530  { "weights", "set weight for each frame", OFFSET(weights_str), AV_OPT_TYPE_STRING, {.str="1 1 1"}, 0, 0, .flags = TFLAGS },
531  { "scale", "set scale", OFFSET(scale), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, INT16_MAX, .flags = TFLAGS },
532  { "planes", "set what planes to filter", OFFSET(planes), AV_OPT_TYPE_FLAGS, {.i64=15}, 0, 15, .flags = TFLAGS },
533  { NULL },
534 };
535 
536 static const AVFilterPad inputs[] = {
537  {
538  .name = "default",
539  .type = AVMEDIA_TYPE_VIDEO,
540  .filter_frame = tmix_filter_frame,
541  },
542 };
543 
545 
546 const AVFilter ff_vf_tmix = {
547  .name = "tmix",
548  .description = NULL_IF_CONFIG_SMALL("Mix successive video frames."),
549  .priv_size = sizeof(MixContext),
550  .priv_class = &tmix_class,
554  .init = init,
555  .uninit = uninit,
557  .process_command = process_command,
558 };
559 
560 #endif /* CONFIG_TMIX_FILTER */
ff_get_video_buffer
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:116
FFFrameSyncIn::time_base
AVRational time_base
Time base for the incoming frames.
Definition: framesync.h:117
ff_framesync_configure
int ff_framesync_configure(FFFrameSync *fs)
Configure a frame sync structure.
Definition: framesync.c:137
parse_weights
static int parse_weights(AVFilterContext *ctx)
Definition: vf_mix.c:85
mix
static int mix(int c0, int c1)
Definition: 4xm.c:716
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
ff_framesync_uninit
void ff_framesync_uninit(FFFrameSync *fs)
Free all memory currently allocated.
Definition: framesync.c:301
out
FILE * out
Definition: movenc.c:55
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1061
MixContext::nb_threads
int nb_threads
Definition: vf_mix.c:40
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3170
ff_vf_tmix
const AVFilter ff_vf_tmix
ff_framesync_get_frame
int ff_framesync_get_frame(FFFrameSync *fs, unsigned in, AVFrame **rframe, unsigned get)
Get the current frame in an input.
Definition: framesync.c:269
ff_set_common_formats2
int ff_set_common_formats2(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out, AVFilterFormats *formats)
Definition: formats.c:1007
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
av_asprintf
char * av_asprintf(const char *fmt,...)
Definition: avstring.c:115
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:162
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: filters.h:262
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:389
MixContext::depth
int depth
Definition: vf_mix.c:51
pixdesc.h
ff_vf_mix
const AVFilter ff_vf_mix
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: vf_mix.c:398
MixContext::scale
float scale
Definition: vf_mix.c:43
AVOption
AVOption.
Definition: opt.h:429
TFLAGS
#define TFLAGS
Definition: vf_mix.c:437
MixContext
Definition: af_amix.c:157
planes
static const struct @467 planes[]
FAST_TMIX_SLICE
#define FAST_TMIX_SLICE(type, stype, round)
Definition: vf_mix.c:160
max
#define max(a, b)
Definition: cuda_runtime.h:33
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:205
FFFrameSync
Frame sync structure.
Definition: framesync.h:168
EXT_INFINITY
@ EXT_INFINITY
Extend the frame to infinity.
Definition: framesync.h:75
ThreadData::out
AVFrame * out
Definition: af_adeclick.c:526
video.h
ThreadData::in
AVFrame * in
Definition: af_adecorrelate.c:155
mix_frames
static int mix_frames(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_mix.c:245
MixContext::nb_frames
int nb_frames
Definition: vf_mix.c:48
formats.h
FLAGS
#define FLAGS
Definition: vf_mix.c:436
av_pix_fmt_count_planes
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3210
EXT_STOP
@ EXT_STOP
Completely stop all streams with this one.
Definition: framesync.h:65
MixContext::duration
int duration
Definition: vf_mix.c:41
MixContext::sum
uint8_t * sum[4]
Definition: vf_mix.c:58
AV_PIX_FMT_FLAG_HWACCEL
#define AV_PIX_FMT_FLAG_HWACCEL
Pixel format is an HW accelerated format.
Definition: pixdesc.h:128
FFFrameSyncIn
Input stream structure.
Definition: framesync.h:102
MixContext::tmix
int tmix
Definition: vf_mix.c:47
activate
static int activate(AVFilterContext *ctx)
Definition: vf_mix.c:429
FFFrameSyncIn::sync
unsigned sync
Synchronization level: frames on input at the highest sync level will generate output frame events.
Definition: framesync.h:160
AVFILTER_FLAG_DYNAMIC_INPUTS
#define AVFILTER_FLAG_DYNAMIC_INPUTS
The number of the filter inputs is not determined just by AVFilter.inputs.
Definition: avfilter.h:141
AVFilterPad
A filter pad used for either input or output.
Definition: filters.h:38
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:209
av_cold
#define av_cold
Definition: attributes.h:90
duration
int64_t duration
Definition: movenc.c:65
config_output
static int config_output(AVFilterLink *outlink)
Definition: vf_mix.c:318
av_image_fill_linesizes
int av_image_fill_linesizes(int linesizes[4], enum AVPixelFormat pix_fmt, int width)
Fill plane linesizes for an image with pixel format pix_fmt and width width.
Definition: imgutils.c:89
s
#define s(width, name)
Definition: cbs_vp9.c:198
query_formats
static int query_formats(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
Definition: vf_mix.c:67
AV_CEIL_RSHIFT
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:60
MixContext::fast
int fast
Definition: vf_mix.c:46
av_strtok
char * av_strtok(char *s, const char *delim, char **saveptr)
Split the string into several tokens which can be accessed by successive calls to av_strtok().
Definition: avstring.c:178
filters.h
NOP
#define NOP(x)
Definition: vf_mix.c:243
ctx
AVFormatContext * ctx
Definition: movenc.c:49
MixContext::fs
FFFrameSync fs
Definition: vf_mix.c:64
av_frame_clone
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
Definition: frame.c:609
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: filters.h:263
arg
const char * arg
Definition: jacosubdec.c:67
MIX_SLICE
#define MIX_SLICE(type, fun, clip)
Definition: vf_mix.c:199
av_sscanf
int av_sscanf(const char *string, const char *format,...)
See libc sscanf manual for more information.
Definition: avsscanf.c:961
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:75
NULL
#define NULL
Definition: coverity.c:32
fs
#define fs(width, name, subs,...)
Definition: cbs_vp9.c:200
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
ff_append_inpad_free_name
int ff_append_inpad_free_name(AVFilterContext *f, AVFilterPad *p)
Definition: avfilter.c:132
MixContext::planes
int planes
Definition: vf_mix.c:53
process_frame
static int process_frame(FFFrameSync *fs)
Definition: vf_mix.c:282
inputs
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several inputs
Definition: filter_design.txt:243
AVFILTER_DEFINE_CLASS
#define AVFILTER_DEFINE_CLASS(fname)
Definition: filters.h:273
AVFilterFormatsConfig
Lists of formats / etc.
Definition: avfilter.h:111
ff_filter_link
static FilterLink * ff_filter_link(AVFilterLink *link)
Definition: filters.h:197
f
f
Definition: af_crystalizer.c:122
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:94
height
#define height
Definition: dsp.h:85
AV_PIX_FMT_FLAG_BITSTREAM
#define AV_PIX_FMT_FLAG_BITSTREAM
All values of a component are bit-wise packed end to end.
Definition: pixdesc.h:124
MixContext::weights_str
char * weights_str
string for custom weights for every input
Definition: af_amix.c:165
MixContext::linesizes
int linesizes[4]
Definition: vf_mix.c:55
ff_filter_process_command
int ff_filter_process_command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
Generic processing of user supplied commands that are set in the same way as the filter options.
Definition: avfilter.c:900
MixContext::height
int height[4]
Definition: vf_mix.c:56
MixContext::nb_unique_frames
int nb_unique_frames
Definition: vf_mix.c:49
CLIP16
#define CLIP16(x, min, max)
Definition: vf_mix.c:241
AV_OPT_TYPE_FLOAT
@ AV_OPT_TYPE_FLOAT
Underlying C type is float.
Definition: opt.h:271
CLIP8
#define CLIP8(x, min, max)
Definition: vf_mix.c:240
ff_formats_pixdesc_filter
AVFilterFormats * ff_formats_pixdesc_filter(unsigned want, unsigned rej)
Construct a formats list containing all pixel formats with certain properties.
Definition: formats.c:553
lrintf
#define lrintf(x)
Definition: libm_mips.h:72
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
CLIPF
#define CLIPF(x, min, max)
Definition: vf_mix.c:242
weights
static const int weights[]
Definition: hevc_pel.c:32
ff_filter_get_nb_threads
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition: avfilter.c:840
ThreadData
Used for passing data between threads.
Definition: dsddec.c:71
MixContext::max
int max
Definition: vf_mix.c:52
FILTER_QUERY_FUNC2
#define FILTER_QUERY_FUNC2(func)
Definition: filters.h:239
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
AV_PIX_FMT_FLAG_BE
#define AV_PIX_FMT_FLAG_BE
Pixel format is big-endian.
Definition: pixdesc.h:116
AVFilterPad::name
const char * name
Pad name.
Definition: filters.h:44
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
MixContext::wfactor
float wfactor
Definition: vf_mix.c:44
AVFilter
Filter definition.
Definition: avfilter.h:201
ret
ret
Definition: filter_design.txt:187
AVFilterPad::type
enum AVMediaType type
AVFilterPad type.
Definition: filters.h:49
MixContext::weights
float * weights
custom weights for every input
Definition: af_amix.c:174
ff_framesync_init
int ff_framesync_init(FFFrameSync *fs, AVFilterContext *parent, unsigned nb_in)
Initialize a frame sync structure.
Definition: framesync.c:86
OFFSET
#define OFFSET(x)
Definition: vf_mix.c:435
FFFrameSyncIn::before
enum FFFrameSyncExtMode before
Extrapolation mode for timestamps before the first frame.
Definition: framesync.h:107
init
static av_cold int init(AVFilterContext *ctx)
Definition: vf_mix.c:124
framesync.h
ff_filter_execute
int ff_filter_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg, int *ret, int nb_jobs)
Definition: avfilter.c:1666
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
avfilter.h
process_command
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
Definition: vf_mix.c:417
AVFilterContext
An instance of a filter.
Definition: avfilter.h:457
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:152
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
mem.h
MixContext::data
uint8_t ** data
Definition: vf_mix.c:60
mix_options
static const AVOption mix_options[]
Definition: vf_mix.c:439
MixContext::nb_planes
int nb_planes
Definition: vf_mix.c:54
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
scale
static void scale(int *out, const int *in, const int w, const int h, const int shift)
Definition: intra.c:291
MixContext::linesize
int * linesize
Definition: vf_mix.c:61
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
AV_OPT_TYPE_FLAGS
@ AV_OPT_TYPE_FLAGS
Underlying C type is unsigned int.
Definition: opt.h:255
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:190
imgutils.h
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:482
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:52
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
FFFrameSyncIn::after
enum FFFrameSyncExtMode after
Extrapolation mode for timestamps after the last frame.
Definition: framesync.h:112
ff_framesync_activate
int ff_framesync_activate(FFFrameSync *fs)
Examine the frames in the filter's input and try to produce output.
Definition: framesync.c:352
avstring.h
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
Definition: opt.h:276
width
#define width
Definition: dsp.h:85
AV_PIX_FMT_FLAG_PAL
#define AV_PIX_FMT_FLAG_PAL
Pixel format has a palette in data[1], values are indexes in this palette.
Definition: pixdesc.h:120
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:299
outputs
static const AVFilterPad outputs[]
Definition: vf_mix.c:451
MixContext::desc
const AVPixFmtDescriptor * desc
Definition: vf_mix.c:37
MixContext::frames
AVFrame ** frames
Definition: vf_mix.c:63
MixContext::nb_inputs
int nb_inputs
number of inputs
Definition: af_amix.c:161