FFmpeg
vf_stack.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 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/parseutils.h"
28 #include "libavutil/pixdesc.h"
29 
30 #include "avfilter.h"
31 #include "drawutils.h"
32 #include "filters.h"
33 #include "formats.h"
34 #include "framesync.h"
35 #include "video.h"
36 
37 typedef struct StackItem {
38  int x[4], y[4];
39  int linesize[4];
40  int height[4];
41 } StackItem;
42 
43 typedef struct StackContext {
44  const AVClass *class;
46  int nb_inputs;
47  char *layout;
48  int shortest;
51  int nb_planes;
54  uint8_t fillcolor[4];
57 
60 
64 } StackContext;
65 
66 static int query_formats(const AVFilterContext *ctx,
67  AVFilterFormatsConfig **cfg_in,
68  AVFilterFormatsConfig **cfg_out)
69 {
70  const StackContext *s = ctx->priv;
71  int reject_flags = AV_PIX_FMT_FLAG_BITSTREAM |
74 
75  if (s->fillcolor_enable) {
76  return ff_set_common_formats2(ctx, cfg_in, cfg_out,
78  }
79 
80  return ff_set_common_formats2(ctx, cfg_in, cfg_out,
81  ff_formats_pixdesc_filter(0, reject_flags));
82 }
83 
85 {
86  StackContext *s = ctx->priv;
87  int i, ret;
88 
89  if (!strcmp(ctx->filter->name, "vstack"))
90  s->is_vertical = 1;
91 
92  if (!strcmp(ctx->filter->name, "hstack"))
93  s->is_horizontal = 1;
94 
95  if (!strcmp(ctx->filter->name, "xstack")) {
96  int is_grid;
97  if (strcmp(s->fillcolor_str, "none") &&
98  av_parse_color(s->fillcolor, s->fillcolor_str, -1, ctx) >= 0) {
99  s->fillcolor_enable = 1;
100  } else {
101  s->fillcolor_enable = 0;
102  }
103  is_grid = s->nb_grid_rows && s->nb_grid_columns;
104  if (s->layout && is_grid) {
105  av_log(ctx, AV_LOG_ERROR, "Both layout and grid were specified. Only one is allowed.\n");
106  return AVERROR(EINVAL);
107  }
108  if (!s->layout && !is_grid) {
109  if (s->nb_inputs == 2) {
110  s->nb_grid_rows = 1;
111  s->nb_grid_columns = 2;
112  is_grid = 1;
113  } else {
114  av_log(ctx, AV_LOG_ERROR, "No layout or grid specified.\n");
115  return AVERROR(EINVAL);
116  }
117  }
118 
119  if (is_grid)
120  s->nb_inputs = s->nb_grid_rows * s->nb_grid_columns;
121  }
122 
123  s->frames = av_calloc(s->nb_inputs, sizeof(*s->frames));
124  if (!s->frames)
125  return AVERROR(ENOMEM);
126 
127  s->items = av_calloc(s->nb_inputs, sizeof(*s->items));
128  if (!s->items)
129  return AVERROR(ENOMEM);
130 
131  for (i = 0; i < s->nb_inputs; i++) {
132  AVFilterPad pad = { 0 };
133 
134  pad.type = AVMEDIA_TYPE_VIDEO;
135  pad.name = av_asprintf("input%d", i);
136  if (!pad.name)
137  return AVERROR(ENOMEM);
138 
139  if ((ret = ff_append_inpad_free_name(ctx, &pad)) < 0)
140  return ret;
141  }
142 
143  return 0;
144 }
145 
146 static int process_slice(AVFilterContext *ctx, void *arg, int job, int nb_jobs)
147 {
148  StackContext *s = ctx->priv;
149  AVFrame *out = arg;
150  AVFrame **in = s->frames;
151  const int start = (s->nb_inputs * job ) / nb_jobs;
152  const int end = (s->nb_inputs * (job+1)) / nb_jobs;
153 
154  for (int i = start; i < end; i++) {
155  StackItem *item = &s->items[i];
156 
157  for (int p = 0; p < s->nb_planes; p++) {
158  av_image_copy_plane(out->data[p] + out->linesize[p] * item->y[p] + item->x[p],
159  out->linesize[p],
160  in[i]->data[p],
161  in[i]->linesize[p],
162  item->linesize[p], item->height[p]);
163  }
164  }
165 
166  return 0;
167 }
168 
170 {
171  AVFilterContext *ctx = fs->parent;
172  AVFilterLink *outlink = ctx->outputs[0];
173  StackContext *s = fs->opaque;
174  AVFrame **in = s->frames;
175  AVFrame *out;
176  int i, ret;
177 
178  for (i = 0; i < s->nb_inputs; i++) {
179  if ((ret = ff_framesync_get_frame(&s->fs, i, &in[i], 0)) < 0)
180  return ret;
181  }
182 
183  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
184  if (!out)
185  return AVERROR(ENOMEM);
186  out->pts = av_rescale_q(s->fs.pts, s->fs.time_base, outlink->time_base);
187  out->sample_aspect_ratio = outlink->sample_aspect_ratio;
188 
189  if (s->fillcolor_enable)
190  ff_fill_rectangle(&s->draw, &s->color, out->data, out->linesize,
191  0, 0, outlink->w, outlink->h);
192 
194  FFMIN(s->nb_inputs, ff_filter_get_nb_threads(ctx)));
195 
196  return ff_filter_frame(outlink, out);
197 }
198 
199 static int config_output(AVFilterLink *outlink)
200 {
201  AVFilterContext *ctx = outlink->src;
202  StackContext *s = ctx->priv;
203  FilterLink *il = ff_filter_link(ctx->inputs[0]);
204  FilterLink *ol = ff_filter_link(outlink);
205  AVRational frame_rate = il->frame_rate;
206  AVRational sar = ctx->inputs[0]->sample_aspect_ratio;
207  int height = ctx->inputs[0]->h;
208  int width = ctx->inputs[0]->w;
209  FFFrameSyncIn *in;
210  int i, ret;
211 
212  s->desc = av_pix_fmt_desc_get(outlink->format);
213  if (!s->desc)
214  return AVERROR_BUG;
215 
216  if (s->is_vertical) {
217  for (i = 0; i < s->nb_inputs; i++) {
218  AVFilterLink *inlink = ctx->inputs[i];
219  StackItem *item = &s->items[i];
220 
221  if (ctx->inputs[i]->w != width) {
222  av_log(ctx, AV_LOG_ERROR, "Input %d width %d does not match input %d width %d.\n", i, ctx->inputs[i]->w, 0, width);
223  return AVERROR(EINVAL);
224  }
225 
226  if ((ret = av_image_fill_linesizes(item->linesize, inlink->format, inlink->w)) < 0) {
227  return ret;
228  }
229 
230  item->height[1] = item->height[2] = AV_CEIL_RSHIFT(inlink->h, s->desc->log2_chroma_h);
231  item->height[0] = item->height[3] = inlink->h;
232 
233  if (i) {
234  item->y[1] = item->y[2] = AV_CEIL_RSHIFT(height, s->desc->log2_chroma_h);
235  item->y[0] = item->y[3] = height;
236 
237  if (height > INT_MAX - ctx->inputs[i]->h)
238  return AVERROR(EINVAL);
239  height += ctx->inputs[i]->h;
240  }
241  }
242  } else if (s->is_horizontal) {
243  for (i = 0; i < s->nb_inputs; i++) {
244  AVFilterLink *inlink = ctx->inputs[i];
245  StackItem *item = &s->items[i];
246 
247  if (ctx->inputs[i]->h != height) {
248  av_log(ctx, AV_LOG_ERROR, "Input %d height %d does not match input %d height %d.\n", i, ctx->inputs[i]->h, 0, height);
249  return AVERROR(EINVAL);
250  }
251 
252  if ((ret = av_image_fill_linesizes(item->linesize, inlink->format, inlink->w)) < 0) {
253  return ret;
254  }
255 
256  item->height[1] = item->height[2] = AV_CEIL_RSHIFT(inlink->h, s->desc->log2_chroma_h);
257  item->height[0] = item->height[3] = inlink->h;
258 
259  if (i) {
260  if ((ret = av_image_fill_linesizes(item->x, inlink->format, width)) < 0) {
261  return ret;
262  }
263 
264  if (width > INT_MAX - ctx->inputs[i]->w)
265  return AVERROR(EINVAL);
266  width += ctx->inputs[i]->w;
267  }
268  }
269  } else if (s->nb_grid_rows && s->nb_grid_columns) {
270  int inw = 0, inh = 0;
271  int k = 0;
272  int row_height;
273  height = 0;
274  width = 0;
275  for (i = 0; i < s->nb_grid_rows; i++, inh += row_height) {
276  row_height = ctx->inputs[i * s->nb_grid_columns]->h;
277  inw = 0;
278  for (int j = 0; j < s->nb_grid_columns; j++, k++) {
279  AVFilterLink *inlink = ctx->inputs[k];
280  StackItem *item = &s->items[k];
281 
282  if (ctx->inputs[k]->h != row_height) {
283  av_log(ctx, AV_LOG_ERROR, "Input %d height %d does not match current row's height %d.\n",
284  k, ctx->inputs[k]->h, row_height);
285  return AVERROR(EINVAL);
286  }
287 
288  if ((ret = av_image_fill_linesizes(item->linesize, inlink->format, inlink->w)) < 0) {
289  return ret;
290  }
291 
292  item->height[1] = item->height[2] = AV_CEIL_RSHIFT(inlink->h, s->desc->log2_chroma_h);
293  item->height[0] = item->height[3] = inlink->h;
294 
295  if ((ret = av_image_fill_linesizes(item->x, inlink->format, inw)) < 0) {
296  return ret;
297  }
298 
299  item->y[1] = item->y[2] = AV_CEIL_RSHIFT(inh, s->desc->log2_chroma_h);
300  item->y[0] = item->y[3] = inh;
301 
302  if (inw > INT_MAX - ctx->inputs[k]->w)
303  return AVERROR(EINVAL);
304  inw += ctx->inputs[k]->w;
305  }
306  if (height > INT_MAX - row_height)
307  return AVERROR(EINVAL);
308  height += row_height;
309  if (!i)
310  width = inw;
311  if (i && width != inw) {
312  av_log(ctx, AV_LOG_ERROR, "Row %d width %d does not match previous row width %d.\n", i, inw, width);
313  return AVERROR(EINVAL);
314  }
315  }
316  } else {
317  char *arg, *p = s->layout, *saveptr = NULL;
318  char *arg2, *p2, *saveptr2 = NULL;
319  char *arg3, *p3, *saveptr3 = NULL;
320  int inw, inh, size;
321 
322  if (s->fillcolor_enable) {
323  const AVFilterLink *inlink = ctx->inputs[0];
324  ret = ff_draw_init_from_link(&s->draw, inlink, 0);
325  if (ret < 0) {
326  av_log(ctx, AV_LOG_ERROR, "Failed to initialize FFDrawContext\n");
327  return ret;
328  }
329  ff_draw_color(&s->draw, &s->color, s->fillcolor);
330  }
331 
332  for (i = 0; i < s->nb_inputs; i++) {
333  AVFilterLink *inlink = ctx->inputs[i];
334  StackItem *item = &s->items[i];
335 
336  if (!(arg = av_strtok(p, "|", &saveptr)))
337  return AVERROR(EINVAL);
338 
339  p = NULL;
340 
341  if ((ret = av_image_fill_linesizes(item->linesize, inlink->format, inlink->w)) < 0) {
342  return ret;
343  }
344 
345  item->height[1] = item->height[2] = AV_CEIL_RSHIFT(inlink->h, s->desc->log2_chroma_h);
346  item->height[0] = item->height[3] = inlink->h;
347 
348  p2 = arg;
349  inw = inh = 0;
350 
351  for (int j = 0; j < 2; j++) {
352  if (!(arg2 = av_strtok(p2, "_", &saveptr2)))
353  return AVERROR(EINVAL);
354 
355  p2 = NULL;
356  p3 = arg2;
357  while ((arg3 = av_strtok(p3, "+", &saveptr3))) {
358  p3 = NULL;
359  if (sscanf(arg3, "w%d", &size) == 1) {
360  if (size == i || size < 0 || size >= s->nb_inputs)
361  return AVERROR(EINVAL);
362 
363  if (!j) {
364  if (inw > INT_MAX - ctx->inputs[size]->w)
365  return AVERROR(EINVAL);
366  inw += ctx->inputs[size]->w;
367  } else {
368  if (inh > INT_MAX - ctx->inputs[size]->w)
369  return AVERROR(EINVAL);
370  inh += ctx->inputs[size]->w;
371  }
372  } else if (sscanf(arg3, "h%d", &size) == 1) {
373  if (size == i || size < 0 || size >= s->nb_inputs)
374  return AVERROR(EINVAL);
375 
376  if (!j) {
377  if (inw > INT_MAX - ctx->inputs[size]->h)
378  return AVERROR(EINVAL);
379  inw += ctx->inputs[size]->h;
380  } else {
381  if (inh > INT_MAX - ctx->inputs[size]->h)
382  return AVERROR(EINVAL);
383  inh += ctx->inputs[size]->h;
384  }
385  } else if (sscanf(arg3, "%d", &size) == 1) {
386  if (size < 0)
387  return AVERROR(EINVAL);
388 
389  if (!j) {
390  if (inw > INT_MAX - size)
391  return AVERROR(EINVAL);
392  inw += size;
393  } else {
394  if (inh > INT_MAX - size)
395  return AVERROR(EINVAL);
396  inh += size;
397  }
398  } else {
399  return AVERROR(EINVAL);
400  }
401  }
402  }
403 
404  if ((ret = av_image_fill_linesizes(item->x, inlink->format, inw)) < 0) {
405  return ret;
406  }
407 
408  item->y[1] = item->y[2] = AV_CEIL_RSHIFT(inh, s->desc->log2_chroma_h);
409  item->y[0] = item->y[3] = inh;
410 
411  if (inlink->w > INT_MAX - inw || inlink->h > INT_MAX - inh)
412  return AVERROR(EINVAL);
413  width = FFMAX(width, inlink->w + inw);
414  height = FFMAX(height, inlink->h + inh);
415  }
416  }
417 
418  s->nb_planes = av_pix_fmt_count_planes(outlink->format);
419 
420  outlink->w = width;
421  outlink->h = height;
422  ol->frame_rate = frame_rate;
423  outlink->sample_aspect_ratio = sar;
424 
425  for (i = 1; i < s->nb_inputs; i++) {
426  il = ff_filter_link(ctx->inputs[i]);
427  if (ol->frame_rate.num != il->frame_rate.num ||
428  ol->frame_rate.den != il->frame_rate.den) {
430  "Video inputs have different frame rates, output will be VFR\n");
431  ol->frame_rate = av_make_q(1, 0);
432  break;
433  }
434  }
435 
436  if ((ret = ff_framesync_init(&s->fs, ctx, s->nb_inputs)) < 0)
437  return ret;
438 
439  in = s->fs.in;
440  s->fs.opaque = s;
441  s->fs.on_event = process_frame;
442 
443  for (i = 0; i < s->nb_inputs; i++) {
444  AVFilterLink *inlink = ctx->inputs[i];
445 
446  in[i].time_base = inlink->time_base;
447  in[i].sync = 1;
448  in[i].before = EXT_STOP;
449  in[i].after = s->shortest ? EXT_STOP : EXT_INFINITY;
450  }
451 
452  ret = ff_framesync_configure(&s->fs);
453  outlink->time_base = s->fs.time_base;
454 
455  return ret;
456 }
457 
459 {
460  StackContext *s = ctx->priv;
461 
462  ff_framesync_uninit(&s->fs);
463  av_freep(&s->frames);
464  av_freep(&s->items);
465 }
466 
468 {
469  StackContext *s = ctx->priv;
470  return ff_framesync_activate(&s->fs);
471 }
472 
473 #define OFFSET(x) offsetof(StackContext, x)
474 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM
475 static const AVOption stack_options[] = {
476  { "inputs", "set number of inputs", OFFSET(nb_inputs), AV_OPT_TYPE_INT, {.i64=2}, 2, INT_MAX, .flags = FLAGS },
477  { "shortest", "force termination when the shortest input terminates", OFFSET(shortest), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, .flags = FLAGS },
478  { NULL },
479 };
480 
481 AVFILTER_DEFINE_CLASS_EXT(stack, "(h|v)stack", stack_options);
482 
483 static const AVFilterPad outputs[] = {
484  {
485  .name = "default",
486  .type = AVMEDIA_TYPE_VIDEO,
487  .config_props = config_output,
488  },
489 };
490 
491 #if CONFIG_HSTACK_FILTER
492 
493 const FFFilter ff_vf_hstack = {
494  .p.name = "hstack",
495  .p.description = NULL_IF_CONFIG_SMALL("Stack video inputs horizontally."),
496  .p.priv_class = &stack_class,
498  .priv_size = sizeof(StackContext),
501  .init = init,
502  .uninit = uninit,
503  .activate = activate,
504 };
505 
506 #endif /* CONFIG_HSTACK_FILTER */
507 
508 #if CONFIG_VSTACK_FILTER
509 
510 const FFFilter ff_vf_vstack = {
511  .p.name = "vstack",
512  .p.description = NULL_IF_CONFIG_SMALL("Stack video inputs vertically."),
513  .p.priv_class = &stack_class,
515  .priv_size = sizeof(StackContext),
518  .init = init,
519  .uninit = uninit,
520  .activate = activate,
521 };
522 
523 #endif /* CONFIG_VSTACK_FILTER */
524 
525 #if CONFIG_XSTACK_FILTER
526 
527 static const AVOption xstack_options[] = {
528  { "inputs", "set number of inputs", OFFSET(nb_inputs), AV_OPT_TYPE_INT, {.i64=2}, 2, INT_MAX, .flags = FLAGS },
529  { "layout", "set custom layout", OFFSET(layout), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, .flags = FLAGS },
530  { "grid", "set fixed size grid layout", OFFSET(nb_grid_columns), AV_OPT_TYPE_IMAGE_SIZE, {.str=NULL}, 0, 0, .flags = FLAGS },
531  { "shortest", "force termination when the shortest input terminates", OFFSET(shortest), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, .flags = FLAGS },
532  { "fill", "set the color for unused pixels", OFFSET(fillcolor_str), AV_OPT_TYPE_STRING, {.str = "none"}, .flags = FLAGS },
533  { NULL },
534 };
535 
536 AVFILTER_DEFINE_CLASS(xstack);
537 
538 const FFFilter ff_vf_xstack = {
539  .p.name = "xstack",
540  .p.description = NULL_IF_CONFIG_SMALL("Stack video inputs into custom layout."),
541  .p.priv_class = &xstack_class,
543  .priv_size = sizeof(StackContext),
546  .init = init,
547  .uninit = uninit,
548  .activate = activate,
549 };
550 
551 #endif /* CONFIG_XSTACK_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:117
StackItem::x
int x[4]
Definition: vf_stack.c:38
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
StackContext::fillcolor
uint8_t fillcolor[4]
Definition: vf_stack.c:54
FFDrawColor
Definition: drawutils.h:52
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
StackContext::fillcolor_str
char * fillcolor_str
Definition: vf_stack.c:55
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:1067
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3456
av_parse_color
int av_parse_color(uint8_t *rgba_color, const char *color_string, int slen, void *log_ctx)
Put the RGBA values that correspond to color_string in rgba_color.
Definition: parseutils.c:359
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
StackContext::fs
FFFrameSync fs
Definition: vf_stack.c:63
ff_vf_vstack
const FFFilter ff_vf_vstack
ff_set_common_formats2
int ff_set_common_formats2(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out, AVFilterFormats *formats)
Definition: formats.c:1124
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
AVFILTER_DEFINE_CLASS_EXT
AVFILTER_DEFINE_CLASS_EXT(stack, "(h|v)stack", stack_options)
StackContext::color
FFDrawColor color
Definition: vf_stack.c:59
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:427
pixdesc.h
AVOption
AVOption.
Definition: opt.h:429
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:226
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:220
FFFrameSync
Frame sync structure.
Definition: framesync.h:168
EXT_INFINITY
@ EXT_INFINITY
Extend the frame to infinity.
Definition: framesync.h:75
video.h
StackContext::shortest
int shortest
Definition: vf_stack.c:48
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:448
av_image_copy_plane
void av_image_copy_plane(uint8_t *dst, int dst_linesize, const uint8_t *src, int src_linesize, int bytewidth, int height)
Copy image plane from src to dst.
Definition: imgutils.c:374
OFFSET
#define OFFSET(x)
Definition: vf_stack.c:473
formats.h
av_pix_fmt_count_planes
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3496
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: vf_stack.c:458
EXT_STOP
@ EXT_STOP
Completely stop all streams with this one.
Definition: framesync.h:65
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
outputs
static const AVFilterPad outputs[]
Definition: vf_stack.c:483
activate
static int activate(AVFilterContext *ctx)
Definition: vf_stack.c:467
StackContext::nb_planes
int nb_planes
Definition: vf_stack.c:51
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:156
AVRational::num
int num
Numerator.
Definition: rational.h:59
ff_vf_hstack
const FFFilter ff_vf_hstack
AVFilterPad
A filter pad used for either input or output.
Definition: filters.h:39
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
init
static av_cold int init(AVFilterContext *ctx)
Definition: vf_stack.c:84
av_cold
#define av_cold
Definition: attributes.h:106
FFFilter
Definition: filters.h:266
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
AV_CEIL_RSHIFT
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:60
StackItem::height
int height[4]
Definition: vf_stack.c:40
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:179
filters.h
StackContext::is_vertical
int is_vertical
Definition: vf_stack.c:49
ctx
AVFormatContext * ctx
Definition: movenc.c:49
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
process_frame
static int process_frame(FFFrameSync *fs)
Definition: vf_stack.c:169
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: filters.h:264
arg
const char * arg
Definition: jacosubdec.c:65
config_output
static int config_output(AVFilterLink *outlink)
Definition: vf_stack.c:199
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:76
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
AV_OPT_TYPE_IMAGE_SIZE
@ AV_OPT_TYPE_IMAGE_SIZE
Underlying C type is two consecutive integers.
Definition: opt.h:303
parseutils.h
AVFILTER_DEFINE_CLASS
#define AVFILTER_DEFINE_CLASS(fname)
Definition: filters.h:477
AVFilterFormatsConfig
Lists of formats / etc.
Definition: avfilter.h:121
ff_filter_link
static FilterLink * ff_filter_link(AVFilterLink *link)
Definition: filters.h:198
query_formats
static int query_formats(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
Definition: vf_stack.c:66
StackContext::items
StackItem * items
Definition: vf_stack.c:61
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:89
size
int size
Definition: twinvq_data.h:10344
av_make_q
static AVRational av_make_q(int num, int den)
Create an AVRational.
Definition: rational.h:71
ff_fill_rectangle
void ff_fill_rectangle(FFDrawContext *draw, FFDrawColor *color, uint8_t *dst[], int dst_linesize[], int dst_x, int dst_y, int w, int h)
Fill a rectangle with an uniform color.
Definition: drawutils.c:258
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
StackContext::is_horizontal
int is_horizontal
Definition: vf_stack.c:50
StackContext::draw
FFDrawContext draw
Definition: vf_stack.c:58
StackContext::desc
const AVPixFmtDescriptor * desc
Definition: vf_stack.c:45
layout
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 layout
Definition: filter_design.txt:18
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:617
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
StackContext::nb_grid_columns
int nb_grid_columns
Definition: vf_stack.c:52
FLAGS
#define FLAGS
Definition: vf_stack.c:474
ff_draw_supported_pixel_formats
AVFilterFormats * ff_draw_supported_pixel_formats(unsigned flags)
Return the list of pixel formats supported by the draw functions.
Definition: drawutils.c:670
ff_filter_get_nb_threads
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition: avfilter.c:845
FILTER_QUERY_FUNC2
#define FILTER_QUERY_FUNC2(func)
Definition: filters.h:240
ff_vf_xstack
const FFFilter ff_vf_xstack
StackContext::layout
char * layout
Definition: vf_stack.c:47
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
FFDrawContext
Definition: drawutils.h:36
AVFilterPad::name
const char * name
Pad name.
Definition: filters.h:45
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
ff_draw_color
void ff_draw_color(FFDrawContext *draw, FFDrawColor *color, const uint8_t rgba[4])
Prepare a color.
Definition: drawutils.c:179
ret
ret
Definition: filter_design.txt:187
AVFilterPad::type
enum AVMediaType type
AVFilterPad type.
Definition: filters.h:50
ff_framesync_init
int ff_framesync_init(FFFrameSync *fs, AVFilterContext *parent, unsigned nb_in)
Initialize a frame sync structure.
Definition: framesync.c:86
FFFrameSyncIn::before
enum FFFrameSyncExtMode before
Extrapolation mode for timestamps before the first frame.
Definition: framesync.h:107
StackItem::y
int y[4]
Definition: vf_stack.c:38
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:1693
AVRational::den
int den
Denominator.
Definition: rational.h:60
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
avfilter.h
StackItem::linesize
int linesize[4]
Definition: vf_stack.c:39
Windows::Graphics::DirectX::Direct3D11::p
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
Definition: vsrc_gfxcapture_winrt.hpp:53
ff_draw_init_from_link
int ff_draw_init_from_link(FFDrawContext *draw, const AVFilterLink *link, unsigned flags)
Init a draw context, taking the format, colorspace and range from the given filter link.
Definition: drawutils.c:168
AVFilterContext
An instance of a filter.
Definition: avfilter.h:274
StackContext::nb_grid_rows
int nb_grid_rows
Definition: vf_stack.c:53
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:167
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:200
FFFilter::p
AVFilter p
The public AVFilter.
Definition: filters.h:270
mem.h
StackContext::fillcolor_enable
int fillcolor_enable
Definition: vf_stack.c:56
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
StackItem
Definition: vf_stack.c:37
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition: opt.h:327
process_slice
static int process_slice(AVFilterContext *ctx, void *arg, int job, int nb_jobs)
Definition: vf_stack.c:146
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
StackContext
Definition: vf_stack.c:43
imgutils.h
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:52
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:472
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:89
drawutils.h
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
stack_options
static const AVOption stack_options[]
Definition: vf_stack.c:475
StackContext::nb_inputs
int nb_inputs
Definition: vf_stack.c:46
StackContext::frames
AVFrame ** frames
Definition: vf_stack.c:62