FFmpeg  4.3.7
avf_concat.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012 Nicolas George
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.
14  * See the GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with FFmpeg; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 /**
22  * @file
23  * concat audio-video filter
24  */
25 
26 #include "libavutil/avassert.h"
27 #include "libavutil/avstring.h"
29 #include "libavutil/opt.h"
30 #include "avfilter.h"
31 #include "filters.h"
32 #include "internal.h"
33 #include "video.h"
34 #include "audio.h"
35 
36 #define TYPE_ALL 2
37 
38 typedef struct ConcatContext {
39  const AVClass *class;
40  unsigned nb_streams[TYPE_ALL]; /**< number of out streams of each type */
41  unsigned nb_segments;
42  unsigned cur_idx; /**< index of the first input of current segment */
43  int64_t delta_ts; /**< timestamp to add to produce output timestamps */
44  unsigned nb_in_active; /**< number of active inputs in current segment */
45  unsigned unsafe;
46  struct concat_in {
47  int64_t pts;
48  int64_t nb_frames;
49  unsigned eof;
50  } *in;
52 
53 #define OFFSET(x) offsetof(ConcatContext, x)
54 #define A AV_OPT_FLAG_AUDIO_PARAM
55 #define F AV_OPT_FLAG_FILTERING_PARAM
56 #define V AV_OPT_FLAG_VIDEO_PARAM
57 
58 static const AVOption concat_options[] = {
59  { "n", "specify the number of segments", OFFSET(nb_segments),
60  AV_OPT_TYPE_INT, { .i64 = 2 }, 1, INT_MAX, V|A|F},
61  { "v", "specify the number of video streams",
63  AV_OPT_TYPE_INT, { .i64 = 1 }, 0, INT_MAX, V|F },
64  { "a", "specify the number of audio streams",
66  AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, A|F},
67  { "unsafe", "enable unsafe mode",
68  OFFSET(unsafe),
69  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, V|A|F},
70  { NULL }
71 };
72 
73 AVFILTER_DEFINE_CLASS(concat);
74 
76 {
77  ConcatContext *cat = ctx->priv;
78  unsigned type, nb_str, idx0 = 0, idx, str, seg;
81  int ret;
82 
83  for (type = 0; type < TYPE_ALL; type++) {
84  nb_str = cat->nb_streams[type];
85  for (str = 0; str < nb_str; str++) {
86  idx = idx0;
87 
88  /* Set the output formats */
89  formats = ff_all_formats(type);
90  if ((ret = ff_formats_ref(formats, &ctx->outputs[idx]->in_formats)) < 0)
91  return ret;
92 
93  if (type == AVMEDIA_TYPE_AUDIO) {
94  rates = ff_all_samplerates();
95  if ((ret = ff_formats_ref(rates, &ctx->outputs[idx]->in_samplerates)) < 0)
96  return ret;
97  layouts = ff_all_channel_layouts();
98  if ((ret = ff_channel_layouts_ref(layouts, &ctx->outputs[idx]->in_channel_layouts)) < 0)
99  return ret;
100  }
101 
102  /* Set the same formats for each corresponding input */
103  for (seg = 0; seg < cat->nb_segments; seg++) {
104  if ((ret = ff_formats_ref(formats, &ctx->inputs[idx]->out_formats)) < 0)
105  return ret;
106  if (type == AVMEDIA_TYPE_AUDIO) {
107  if ((ret = ff_formats_ref(rates, &ctx->inputs[idx]->out_samplerates)) < 0 ||
108  (ret = ff_channel_layouts_ref(layouts, &ctx->inputs[idx]->out_channel_layouts)) < 0)
109  return ret;
110  }
111  idx += ctx->nb_outputs;
112  }
113 
114  idx0++;
115  }
116  }
117  return 0;
118 }
119 
120 static int config_output(AVFilterLink *outlink)
121 {
122  AVFilterContext *ctx = outlink->src;
123  ConcatContext *cat = ctx->priv;
124  unsigned out_no = FF_OUTLINK_IDX(outlink);
125  unsigned in_no = out_no, seg;
126  AVFilterLink *inlink = ctx->inputs[in_no];
127 
128  /* enhancement: find a common one */
129  outlink->time_base = AV_TIME_BASE_Q;
130  outlink->w = inlink->w;
131  outlink->h = inlink->h;
132  outlink->sample_aspect_ratio = inlink->sample_aspect_ratio;
133  outlink->format = inlink->format;
134  outlink->frame_rate = inlink->frame_rate;
135 
136  for (seg = 1; seg < cat->nb_segments; seg++) {
137  inlink = ctx->inputs[in_no + seg * ctx->nb_outputs];
138  if (outlink->frame_rate.num != inlink->frame_rate.num ||
139  outlink->frame_rate.den != inlink->frame_rate.den) {
140  av_log(ctx, AV_LOG_VERBOSE,
141  "Video inputs have different frame rates, output will be VFR\n");
142  outlink->frame_rate = av_make_q(1, 0);
143  break;
144  }
145  }
146 
147  for (seg = 1; seg < cat->nb_segments; seg++) {
148  inlink = ctx->inputs[in_no + seg * ctx->nb_outputs];
149  if (!outlink->sample_aspect_ratio.num)
150  outlink->sample_aspect_ratio = inlink->sample_aspect_ratio;
151  /* possible enhancement: unsafe mode, do not check */
152  if (outlink->w != inlink->w ||
153  outlink->h != inlink->h ||
154  outlink->sample_aspect_ratio.num != inlink->sample_aspect_ratio.num &&
155  inlink->sample_aspect_ratio.num ||
156  outlink->sample_aspect_ratio.den != inlink->sample_aspect_ratio.den) {
157  av_log(ctx, AV_LOG_ERROR, "Input link %s parameters "
158  "(size %dx%d, SAR %d:%d) do not match the corresponding "
159  "output link %s parameters (%dx%d, SAR %d:%d)\n",
160  ctx->input_pads[in_no].name, inlink->w, inlink->h,
161  inlink->sample_aspect_ratio.num,
162  inlink->sample_aspect_ratio.den,
163  ctx->input_pads[out_no].name, outlink->w, outlink->h,
164  outlink->sample_aspect_ratio.num,
165  outlink->sample_aspect_ratio.den);
166  if (!cat->unsafe)
167  return AVERROR(EINVAL);
168  }
169  }
170 
171  return 0;
172 }
173 
174 static int push_frame(AVFilterContext *ctx, unsigned in_no, AVFrame *buf)
175 {
176  ConcatContext *cat = ctx->priv;
177  unsigned out_no = in_no % ctx->nb_outputs;
178  AVFilterLink * inlink = ctx-> inputs[ in_no];
179  AVFilterLink *outlink = ctx->outputs[out_no];
180  struct concat_in *in = &cat->in[in_no];
181 
182  buf->pts = av_rescale_q(buf->pts, inlink->time_base, outlink->time_base);
183  in->pts = buf->pts;
184  in->nb_frames++;
185  /* add duration to input PTS */
186  if (inlink->sample_rate)
187  /* use number of audio samples */
188  in->pts += av_rescale_q(buf->nb_samples,
189  av_make_q(1, inlink->sample_rate),
190  outlink->time_base);
191  else if (in->nb_frames >= 2)
192  /* use mean duration */
193  in->pts = av_rescale(in->pts, in->nb_frames, in->nb_frames - 1);
194 
195  buf->pts += cat->delta_ts;
196  return ff_filter_frame(outlink, buf);
197 }
198 
199 static AVFrame *get_video_buffer(AVFilterLink *inlink, int w, int h)
200 {
201  AVFilterContext *ctx = inlink->dst;
202  unsigned in_no = FF_INLINK_IDX(inlink);
203  AVFilterLink *outlink = ctx->outputs[in_no % ctx->nb_outputs];
204 
205  return ff_get_video_buffer(outlink, w, h);
206 }
207 
208 static AVFrame *get_audio_buffer(AVFilterLink *inlink, int nb_samples)
209 {
210  AVFilterContext *ctx = inlink->dst;
211  unsigned in_no = FF_INLINK_IDX(inlink);
212  AVFilterLink *outlink = ctx->outputs[in_no % ctx->nb_outputs];
213 
214  return ff_get_audio_buffer(outlink, nb_samples);
215 }
216 
217 static void close_input(AVFilterContext *ctx, unsigned in_no)
218 {
219  ConcatContext *cat = ctx->priv;
220 
221  cat->in[in_no].eof = 1;
222  cat->nb_in_active--;
223  av_log(ctx, AV_LOG_VERBOSE, "EOF on %s, %d streams left in segment.\n",
224  ctx->input_pads[in_no].name, cat->nb_in_active);
225 }
226 
227 static void find_next_delta_ts(AVFilterContext *ctx, int64_t *seg_delta)
228 {
229  ConcatContext *cat = ctx->priv;
230  unsigned i = cat->cur_idx;
231  unsigned imax = i + ctx->nb_outputs;
232  int64_t pts;
233 
234  pts = cat->in[i++].pts;
235  for (; i < imax; i++)
236  pts = FFMAX(pts, cat->in[i].pts);
237  cat->delta_ts += pts;
238  *seg_delta = pts;
239 }
240 
241 static int send_silence(AVFilterContext *ctx, unsigned in_no, unsigned out_no,
242  int64_t seg_delta)
243 {
244  ConcatContext *cat = ctx->priv;
245  AVFilterLink *outlink = ctx->outputs[out_no];
246  int64_t base_pts = cat->in[in_no].pts + cat->delta_ts - seg_delta;
247  int64_t nb_samples, sent = 0;
248  int frame_nb_samples, ret;
249  AVRational rate_tb = { 1, ctx->inputs[in_no]->sample_rate };
250  AVFrame *buf;
251 
252  if (!rate_tb.den)
253  return AVERROR_BUG;
254  nb_samples = av_rescale_q(seg_delta - cat->in[in_no].pts,
255  outlink->time_base, rate_tb);
256  frame_nb_samples = FFMAX(9600, rate_tb.den / 5); /* arbitrary */
257  while (nb_samples) {
258  frame_nb_samples = FFMIN(frame_nb_samples, nb_samples);
259  buf = ff_get_audio_buffer(outlink, frame_nb_samples);
260  if (!buf)
261  return AVERROR(ENOMEM);
262  av_samples_set_silence(buf->extended_data, 0, frame_nb_samples,
263  outlink->channels, outlink->format);
264  buf->pts = base_pts + av_rescale_q(sent, rate_tb, outlink->time_base);
265  ret = ff_filter_frame(outlink, buf);
266  if (ret < 0)
267  return ret;
268  sent += frame_nb_samples;
269  nb_samples -= frame_nb_samples;
270  }
271  return 0;
272 }
273 
275 {
276  int ret;
277  ConcatContext *cat = ctx->priv;
278  unsigned str, str_max;
279  int64_t seg_delta;
280 
281  find_next_delta_ts(ctx, &seg_delta);
282  cat->cur_idx += ctx->nb_outputs;
283  cat->nb_in_active = ctx->nb_outputs;
284  av_log(ctx, AV_LOG_VERBOSE, "Segment finished at pts=%"PRId64"\n",
285  cat->delta_ts);
286 
287  if (cat->cur_idx < ctx->nb_inputs) {
288  /* pad audio streams with silence */
289  str = cat->nb_streams[AVMEDIA_TYPE_VIDEO];
290  str_max = str + cat->nb_streams[AVMEDIA_TYPE_AUDIO];
291  for (; str < str_max; str++) {
292  ret = send_silence(ctx, cat->cur_idx - ctx->nb_outputs + str, str,
293  seg_delta);
294  if (ret < 0)
295  return ret;
296  }
297  }
298  return 0;
299 }
300 
302 {
303  ConcatContext *cat = ctx->priv;
304  unsigned seg, type, str;
305  int ret;
306 
307  /* create input pads */
308  for (seg = 0; seg < cat->nb_segments; seg++) {
309  for (type = 0; type < TYPE_ALL; type++) {
310  for (str = 0; str < cat->nb_streams[type]; str++) {
311  AVFilterPad pad = {
312  .type = type,
313  .get_video_buffer = get_video_buffer,
314  .get_audio_buffer = get_audio_buffer,
315  };
316  pad.name = av_asprintf("in%d:%c%d", seg, "va"[type], str);
317  if ((ret = ff_insert_inpad(ctx, ctx->nb_inputs, &pad)) < 0) {
318  av_freep(&pad.name);
319  return ret;
320  }
321  }
322  }
323  }
324  /* create output pads */
325  for (type = 0; type < TYPE_ALL; type++) {
326  for (str = 0; str < cat->nb_streams[type]; str++) {
327  AVFilterPad pad = {
328  .type = type,
329  .config_props = config_output,
330  };
331  pad.name = av_asprintf("out:%c%d", "va"[type], str);
332  if ((ret = ff_insert_outpad(ctx, ctx->nb_outputs, &pad)) < 0) {
333  av_freep(&pad.name);
334  return ret;
335  }
336  }
337  }
338 
339  cat->in = av_calloc(ctx->nb_inputs, sizeof(*cat->in));
340  if (!cat->in)
341  return AVERROR(ENOMEM);
342  cat->nb_in_active = ctx->nb_outputs;
343  return 0;
344 }
345 
347 {
348  ConcatContext *cat = ctx->priv;
349  unsigned i;
350 
351  for (i = 0; i < ctx->nb_inputs; i++)
352  av_freep(&ctx->input_pads[i].name);
353  for (i = 0; i < ctx->nb_outputs; i++)
354  av_freep(&ctx->output_pads[i].name);
355  av_freep(&cat->in);
356 }
357 
359 {
360  ConcatContext *cat = ctx->priv;
361  AVFrame *frame;
362  unsigned i, j;
363  int ret, status;
364  int64_t pts;
365 
366  /* Forward status back */
367  for (i = 0; i < ctx->nb_outputs; i++) {
368  status = ff_outlink_get_status(ctx->outputs[i]);
369  if (!status)
370  continue;
371  for (j = i; j < ctx->nb_inputs; j += ctx->nb_outputs) {
372  if (!cat->in[j].eof) {
373  cat->in[j].eof = 1;
374  ff_inlink_set_status(ctx->inputs[j], status);
375  return 0;
376  }
377  }
378 
379  }
380 
381  /* Forward available frames */
382  if (cat->cur_idx < ctx->nb_inputs) {
383  for (i = 0; i < ctx->nb_outputs; i++) {
384  ret = ff_inlink_consume_frame(ctx->inputs[cat->cur_idx + i], &frame);
385  if (ret < 0)
386  return ret;
387  if (ret) {
388  ff_filter_set_ready(ctx, 10);
389  return push_frame(ctx, cat->cur_idx + i, frame);
390  }
391  }
392  }
393 
394  /* Forward status change */
395  if (cat->cur_idx < ctx->nb_inputs) {
396  for (i = 0; i < ctx->nb_outputs; i++) {
397  ret = ff_inlink_acknowledge_status(ctx->inputs[cat->cur_idx + i], &status, &pts);
398  /* TODO use pts */
399  if (ret > 0) {
400  close_input(ctx, cat->cur_idx + i);
401  if (cat->cur_idx + ctx->nb_outputs >= ctx->nb_inputs) {
402  ff_outlink_set_status(ctx->outputs[i], status, pts);
403  }
404  if (!cat->nb_in_active) {
405  ret = flush_segment(ctx);
406  if (ret < 0)
407  return ret;
408  }
409  ff_filter_set_ready(ctx, 10);
410  return 0;
411  }
412  }
413  }
414 
415  ret = FFERROR_NOT_READY;
416  for (i = 0; i < ctx->nb_outputs; i++) {
417  if (ff_outlink_frame_wanted(ctx->outputs[i])) {
418  if (cat->in[cat->cur_idx + i].eof) {
419  for (j = 0; j < ctx->nb_outputs; j++)
420  if (!cat->in[cat->cur_idx + j].eof)
421  ff_inlink_request_frame(ctx->inputs[cat->cur_idx + j]);
422  return 0;
423  } else {
424  ff_inlink_request_frame(ctx->inputs[cat->cur_idx + i]);
425  ret = 0;
426  }
427  }
428  }
429 
430  return ret;
431 }
432 
433 static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
434  char *res, int res_len, int flags)
435 {
436  int ret = AVERROR(ENOSYS);
437 
438  if (!strcmp(cmd, "next")) {
439  av_log(ctx, AV_LOG_VERBOSE, "Command received: next\n");
440  return flush_segment(ctx);
441  }
442 
443  return ret;
444 }
445 
447  .name = "concat",
448  .description = NULL_IF_CONFIG_SMALL("Concatenate audio and video streams."),
449  .init = init,
450  .uninit = uninit,
451  .query_formats = query_formats,
452  .activate = activate,
453  .priv_size = sizeof(ConcatContext),
454  .inputs = NULL,
455  .outputs = NULL,
456  .priv_class = &concat_class,
459 };
int ff_inlink_consume_frame(AVFilterLink *link, AVFrame **rframe)
Take a frame from the link&#39;s FIFO and update the link&#39;s stats.
Definition: avfilter.c:1476
#define NULL
Definition: coverity.c:32
static AVFrame * get_audio_buffer(AVFilterLink *inlink, int nb_samples)
Definition: avf_concat.c:208
static int flush_segment(AVFilterContext *ctx)
Definition: avf_concat.c:274
static int send_silence(AVFilterContext *ctx, unsigned in_no, unsigned out_no, int64_t seg_delta)
Definition: avf_concat.c:241
This structure describes decoded (raw) audio or video data.
Definition: frame.h:300
static av_cold int init(AVFilterContext *ctx)
Definition: avf_concat.c:301
AVOption.
Definition: opt.h:246
unsigned nb_streams[TYPE_ALL]
number of out streams of each type
Definition: avf_concat.c:40
Main libavfilter public API header.
#define AVFILTER_FLAG_DYNAMIC_INPUTS
The number of the filter inputs is not determined just by AVFilter.inputs.
Definition: avfilter.h:105
int num
Numerator.
Definition: rational.h:59
#define FFERROR_NOT_READY
Filters implementation helper functions.
Definition: filters.h:34
enum AVMediaType type
AVFilterPad type.
Definition: internal.h:65
#define FF_OUTLINK_IDX(link)
Definition: internal.h:329
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:104
static void ff_outlink_set_status(AVFilterLink *link, int status, int64_t pts)
Set the status field of a link from the source filter.
Definition: filters.h:189
void ff_inlink_request_frame(AVFilterLink *link)
Mark that a frame is wanted on the link.
Definition: avfilter.c:1602
static int ff_outlink_frame_wanted(AVFilterLink *link)
Test if a frame is wanted on an output link.
Definition: filters.h:172
AVFilter ff_avf_concat
Definition: avf_concat.c:446
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
Definition: mem.c:245
#define V
Definition: avf_concat.c:56
static av_cold void uninit(AVFilterContext *ctx)
Definition: avf_concat.c:346
const char * name
Pad name.
Definition: internal.h:60
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:346
int ff_channel_layouts_ref(AVFilterChannelLayouts *f, AVFilterChannelLayouts **ref)
Add *ref as a new reference to f.
Definition: formats.c:479
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1075
AVFilterPad * output_pads
array of output pads
Definition: avfilter.h:349
#define av_cold
Definition: attributes.h:88
AVOptions.
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:393
static AVFrame * get_video_buffer(AVFilterLink *inlink, int w, int h)
Definition: avf_concat.c:199
static AVFrame * frame
static int push_frame(AVFilterContext *ctx, unsigned in_no, AVFrame *buf)
Definition: avf_concat.c:174
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:192
#define AVFILTER_FLAG_DYNAMIC_OUTPUTS
The number of the filter outputs is not determined just by AVFilter.outputs.
Definition: avfilter.h:111
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
Definition: avf_concat.c:433
#define av_log(a,...)
AVFilterFormats * ff_all_formats(enum AVMediaType type)
Return a list of all formats supported by FFmpeg for the given media type.
Definition: formats.c:363
A filter pad used for either input or output.
Definition: internal.h:54
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
int ff_inlink_acknowledge_status(AVFilterLink *link, int *rstatus, int64_t *rpts)
Test and acknowledge the change of status on the link.
Definition: avfilter.c:1431
static int activate(AVFilterContext *ctx)
Definition: avf_concat.c:358
AVFilterPad * input_pads
array of input pads
Definition: avfilter.h:345
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
int av_samples_set_silence(uint8_t **audio_data, int offset, int nb_samples, int nb_channels, enum AVSampleFormat sample_fmt)
Fill an audio buffer with silence.
Definition: samplefmt.c:237
AVFrame * ff_get_audio_buffer(AVFilterLink *link, int nb_samples)
Request an audio samples buffer with a specific set of permissions.
Definition: audio.c:86
#define AVERROR(e)
Definition: error.h:43
unsigned nb_outputs
number of output pads
Definition: avfilter.h:351
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:188
void * priv
private data for use by the filter
Definition: avfilter.h:353
#define A
Definition: avf_concat.c:54
simple assert() macros that are a bit more flexible than ISO C assert().
#define FFMAX(a, b)
Definition: common.h:94
char * av_asprintf(const char *fmt,...)
Definition: avstring.c:113
int64_t delta_ts
timestamp to add to produce output timestamps
Definition: avf_concat.c:43
audio channel layout utility functions
unsigned nb_inputs
number of input pads
Definition: avfilter.h:347
int64_t av_rescale(int64_t a, int64_t b, int64_t c)
Rescale a 64-bit integer with rounding to nearest.
Definition: mathematics.c:129
#define FFMIN(a, b)
Definition: common.h:96
int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
Add *ref as a new reference to formats.
Definition: formats.c:484
static void close_input(AVFilterContext *ctx, unsigned in_no)
Definition: avf_concat.c:217
uint8_t w
Definition: llviddspenc.c:38
static void find_next_delta_ts(AVFilterContext *ctx, int64_t *seg_delta)
Definition: avf_concat.c:227
unsigned nb_segments
Definition: avf_concat.c:41
static const AVClass concat_class
Definition: concatdec.c:774
AVFormatContext * ctx
Definition: movenc.c:48
static const AVFilterPad inputs[]
Definition: af_acontrast.c:193
AVFilterChannelLayouts * ff_all_channel_layouts(void)
Construct an empty AVFilterChannelLayouts/AVFilterFormats struct – representing any channel layout (...
Definition: formats.c:445
#define cat(a, bpp, b)
Definition: vp9dsp_init.h:29
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
A list of supported channel layouts.
Definition: formats.h:85
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:260
static AVRational av_make_q(int num, int den)
Create an AVRational.
Definition: rational.h:71
unsigned cur_idx
index of the first input of current segment
Definition: avf_concat.c:42
#define OFFSET(x)
Definition: avf_concat.c:53
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:50
Describe the class of an AVClass context structure.
Definition: log.h:67
Filter definition.
Definition: avfilter.h:144
int ff_outlink_get_status(AVFilterLink *link)
Get the status on an output link.
Definition: avfilter.c:1625
Rational number (pair of numerator and denominator).
Definition: rational.h:58
cl_device_type type
unsigned nb_in_active
number of active inputs in current segment
Definition: avf_concat.c:44
void ff_inlink_set_status(AVFilterLink *link, int status)
Set the status on an input link.
Definition: avfilter.c:1610
const char * name
Filter name.
Definition: avfilter.h:148
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:350
enum MovChannelLayoutTag * layouts
Definition: mov_chan.c:434
AVFilterFormats * ff_all_samplerates(void)
Definition: formats.c:439
#define flags(name, subs,...)
Definition: cbs_av1.c:565
#define FF_INLINK_IDX(link)
Find the index of a link.
Definition: internal.h:328
static int query_formats(AVFilterContext *ctx)
Definition: avf_concat.c:75
#define TYPE_ALL
Definition: avf_concat.c:36
void ff_filter_set_ready(AVFilterContext *filter, unsigned priority)
Mark a filter ready and schedule it for activation.
Definition: avfilter.c:193
#define F
Definition: avf_concat.c:55
unsigned unsafe
Definition: avf_concat.c:45
int den
Denominator.
Definition: rational.h:60
static int config_output(AVFilterLink *outlink)
Definition: avf_concat.c:120
struct ConcatContext::concat_in * in
A list of supported formats for one end of a filter link.
Definition: formats.h:64
An instance of a filter.
Definition: avfilter.h:338
AVFILTER_DEFINE_CLASS(concat)
#define av_freep(p)
static const AVOption concat_options[]
Definition: avf_concat.c:58
formats
Definition: signature.h:48
internal API functions
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: frame.h:347
static const int rates[]
Definition: avresample.c:176
static int ff_insert_outpad(AVFilterContext *f, unsigned index, AVFilterPad *p)
Insert a new output pad for the filter.
Definition: internal.h:274
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:366
static int ff_insert_inpad(AVFilterContext *f, unsigned index, AVFilterPad *p)
Insert a new input pad for the filter.
Definition: internal.h:266