FFmpeg  4.4
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 
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 */
90  if ((ret = ff_formats_ref(formats, &ctx->outputs[idx]->incfg.formats)) < 0)
91  return ret;
92 
93  if (type == AVMEDIA_TYPE_AUDIO) {
95  if ((ret = ff_formats_ref(rates, &ctx->outputs[idx]->incfg.samplerates)) < 0)
96  return ret;
98  if ((ret = ff_channel_layouts_ref(layouts, &ctx->outputs[idx]->incfg.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]->outcfg.formats)) < 0)
105  return ret;
106  if (type == AVMEDIA_TYPE_AUDIO) {
107  if ((ret = ff_formats_ref(rates, &ctx->inputs[idx]->outcfg.samplerates)) < 0 ||
108  (ret = ff_channel_layouts_ref(layouts, &ctx->inputs[idx]->outcfg.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) {
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  if (cat->in[in_no].pts < INT64_MIN + seg_delta)
255  return AVERROR_INVALIDDATA;
256  if (seg_delta < cat->in[in_no].pts)
257  return AVERROR_INVALIDDATA;
258  nb_samples = av_rescale_q(seg_delta - cat->in[in_no].pts,
259  outlink->time_base, rate_tb);
260  frame_nb_samples = FFMAX(9600, rate_tb.den / 5); /* arbitrary */
261  while (nb_samples) {
262  frame_nb_samples = FFMIN(frame_nb_samples, nb_samples);
263  buf = ff_get_audio_buffer(outlink, frame_nb_samples);
264  if (!buf)
265  return AVERROR(ENOMEM);
266  av_samples_set_silence(buf->extended_data, 0, frame_nb_samples,
267  outlink->channels, outlink->format);
268  buf->pts = base_pts + av_rescale_q(sent, rate_tb, outlink->time_base);
269  ret = ff_filter_frame(outlink, buf);
270  if (ret < 0)
271  return ret;
272  sent += frame_nb_samples;
273  nb_samples -= frame_nb_samples;
274  }
275  return 0;
276 }
277 
279 {
280  int ret;
281  ConcatContext *cat = ctx->priv;
282  unsigned str, str_max;
283  int64_t seg_delta;
284 
285  find_next_delta_ts(ctx, &seg_delta);
286  cat->cur_idx += ctx->nb_outputs;
287  cat->nb_in_active = ctx->nb_outputs;
288  av_log(ctx, AV_LOG_VERBOSE, "Segment finished at pts=%"PRId64"\n",
289  cat->delta_ts);
290 
291  if (cat->cur_idx < ctx->nb_inputs) {
292  /* pad audio streams with silence */
293  str = cat->nb_streams[AVMEDIA_TYPE_VIDEO];
294  str_max = str + cat->nb_streams[AVMEDIA_TYPE_AUDIO];
295  for (; str < str_max; str++) {
296  ret = send_silence(ctx, cat->cur_idx - ctx->nb_outputs + str, str,
297  seg_delta);
298  if (ret < 0)
299  return ret;
300  }
301  }
302  return 0;
303 }
304 
306 {
307  ConcatContext *cat = ctx->priv;
308  unsigned seg, type, str;
309  int ret;
310 
311  /* create input pads */
312  for (seg = 0; seg < cat->nb_segments; seg++) {
313  for (type = 0; type < TYPE_ALL; type++) {
314  for (str = 0; str < cat->nb_streams[type]; str++) {
315  AVFilterPad pad = {
316  .type = type,
317  .get_video_buffer = get_video_buffer,
318  .get_audio_buffer = get_audio_buffer,
319  };
320  pad.name = av_asprintf("in%d:%c%d", seg, "va"[type], str);
321  if ((ret = ff_insert_inpad(ctx, ctx->nb_inputs, &pad)) < 0) {
322  av_freep(&pad.name);
323  return ret;
324  }
325  }
326  }
327  }
328  /* create output pads */
329  for (type = 0; type < TYPE_ALL; type++) {
330  for (str = 0; str < cat->nb_streams[type]; str++) {
331  AVFilterPad pad = {
332  .type = type,
333  .config_props = config_output,
334  };
335  pad.name = av_asprintf("out:%c%d", "va"[type], str);
336  if ((ret = ff_insert_outpad(ctx, ctx->nb_outputs, &pad)) < 0) {
337  av_freep(&pad.name);
338  return ret;
339  }
340  }
341  }
342 
343  cat->in = av_calloc(ctx->nb_inputs, sizeof(*cat->in));
344  if (!cat->in)
345  return AVERROR(ENOMEM);
346  cat->nb_in_active = ctx->nb_outputs;
347  return 0;
348 }
349 
351 {
352  ConcatContext *cat = ctx->priv;
353  unsigned i;
354 
355  for (i = 0; i < ctx->nb_inputs; i++)
356  av_freep(&ctx->input_pads[i].name);
357  for (i = 0; i < ctx->nb_outputs; i++)
358  av_freep(&ctx->output_pads[i].name);
359  av_freep(&cat->in);
360 }
361 
363 {
364  ConcatContext *cat = ctx->priv;
365  AVFrame *frame;
366  unsigned i, j;
367  int ret, status;
368  int64_t pts;
369 
370  /* Forward status back */
371  for (i = 0; i < ctx->nb_outputs; i++) {
372  status = ff_outlink_get_status(ctx->outputs[i]);
373  if (!status)
374  continue;
375  for (j = i; j < ctx->nb_inputs; j += ctx->nb_outputs) {
376  if (!cat->in[j].eof) {
377  cat->in[j].eof = 1;
378  ff_inlink_set_status(ctx->inputs[j], status);
379  return 0;
380  }
381  }
382 
383  }
384 
385  /* Forward available frames */
386  if (cat->cur_idx < ctx->nb_inputs) {
387  for (i = 0; i < ctx->nb_outputs; i++) {
388  ret = ff_inlink_consume_frame(ctx->inputs[cat->cur_idx + i], &frame);
389  if (ret < 0)
390  return ret;
391  if (ret) {
393  return push_frame(ctx, cat->cur_idx + i, frame);
394  }
395  }
396  }
397 
398  /* Forward status change */
399  if (cat->cur_idx < ctx->nb_inputs) {
400  for (i = 0; i < ctx->nb_outputs; i++) {
401  ret = ff_inlink_acknowledge_status(ctx->inputs[cat->cur_idx + i], &status, &pts);
402  /* TODO use pts */
403  if (ret > 0) {
404  close_input(ctx, cat->cur_idx + i);
405  if (cat->cur_idx + ctx->nb_outputs >= ctx->nb_inputs) {
406  ff_outlink_set_status(ctx->outputs[i], status, pts);
407  }
408  if (!cat->nb_in_active) {
409  ret = flush_segment(ctx);
410  if (ret < 0)
411  return ret;
412  }
414  return 0;
415  }
416  }
417  }
418 
419  ret = FFERROR_NOT_READY;
420  for (i = 0; i < ctx->nb_outputs; i++) {
421  if (ff_outlink_frame_wanted(ctx->outputs[i])) {
422  if (cat->in[cat->cur_idx + i].eof) {
423  for (j = 0; j < ctx->nb_outputs; j++)
424  if (!cat->in[cat->cur_idx + j].eof)
425  ff_inlink_request_frame(ctx->inputs[cat->cur_idx + j]);
426  return 0;
427  } else {
428  ff_inlink_request_frame(ctx->inputs[cat->cur_idx + i]);
429  ret = 0;
430  }
431  }
432  }
433 
434  return ret;
435 }
436 
437 static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
438  char *res, int res_len, int flags)
439 {
440  int ret = AVERROR(ENOSYS);
441 
442  if (!strcmp(cmd, "next")) {
443  av_log(ctx, AV_LOG_VERBOSE, "Command received: next\n");
444  return flush_segment(ctx);
445  }
446 
447  return ret;
448 }
449 
451  .name = "concat",
452  .description = NULL_IF_CONFIG_SMALL("Concatenate audio and video streams."),
453  .init = init,
454  .uninit = uninit,
455  .query_formats = query_formats,
456  .activate = activate,
457  .priv_size = sizeof(ConcatContext),
458  .inputs = NULL,
459  .outputs = NULL,
460  .priv_class = &concat_class,
463 };
static const AVFilterPad inputs[]
Definition: af_acontrast.c:193
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
#define av_cold
Definition: attributes.h:88
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
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) #define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac) { } void ff_audio_convert_free(AudioConvert **ac) { if(! *ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);} AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map) { AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method !=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2) { ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc) { av_free(ac);return NULL;} return ac;} in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar) { ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar ? ac->channels :1;} else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;} int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in) { int use_generic=1;int len=in->nb_samples;int p;if(ac->dc) { av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
simple assert() macros that are a bit more flexible than ISO C assert().
static void close_input(AVFilterContext *ctx, unsigned in_no)
Definition: avf_concat.c:217
#define F
Definition: avf_concat.c:55
static int send_silence(AVFilterContext *ctx, unsigned in_no, unsigned out_no, int64_t seg_delta)
Definition: avf_concat.c:241
static int query_formats(AVFilterContext *ctx)
Definition: avf_concat.c:75
static int push_frame(AVFilterContext *ctx, unsigned in_no, AVFrame *buf)
Definition: avf_concat.c:174
static void find_next_delta_ts(AVFilterContext *ctx, int64_t *seg_delta)
Definition: avf_concat.c:227
AVFilter ff_avf_concat
Definition: avf_concat.c:450
static AVFrame * get_audio_buffer(AVFilterLink *inlink, int nb_samples)
Definition: avf_concat.c:208
#define A
Definition: avf_concat.c:54
AVFILTER_DEFINE_CLASS(concat)
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
Definition: avf_concat.c:437
static int activate(AVFilterContext *ctx)
Definition: avf_concat.c:362
#define TYPE_ALL
Definition: avf_concat.c:36
static AVFrame * get_video_buffer(AVFilterLink *inlink, int w, int h)
Definition: avf_concat.c:199
static av_cold int init(AVFilterContext *ctx)
Definition: avf_concat.c:305
static av_cold void uninit(AVFilterContext *ctx)
Definition: avf_concat.c:350
#define OFFSET(x)
Definition: avf_concat.c:53
static int config_output(AVFilterLink *outlink)
Definition: avf_concat.c:120
static int flush_segment(AVFilterContext *ctx)
Definition: avf_concat.c:278
static const AVOption concat_options[]
Definition: avf_concat.c:58
#define V
Definition: avf_concat.c:56
void ff_inlink_set_status(AVFilterLink *link, int status)
Set the status on an input link.
Definition: avfilter.c:1626
int ff_outlink_get_status(AVFilterLink *link)
Get the status on an output link.
Definition: avfilter.c:1641
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:1447
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1094
void ff_filter_set_ready(AVFilterContext *filter, unsigned priority)
Mark a filter ready and schedule it for activation.
Definition: avfilter.c:193
int ff_inlink_consume_frame(AVFilterLink *link, AVFrame **rframe)
Take a frame from the link's FIFO and update the link's stats.
Definition: avfilter.c:1492
void ff_inlink_request_frame(AVFilterLink *link)
Mark that a frame is wanted on the link.
Definition: avfilter.c:1618
Main libavfilter public API header.
static const int rates[]
Definition: avresample.c:176
char * av_asprintf(const char *fmt,...)
Definition: avstring.c:113
#define flags(name, subs,...)
Definition: cbs_av1.c:561
audio channel layout utility functions
#define FFMIN(a, b)
Definition: common.h:105
#define FFMAX(a, b)
Definition: common.h:103
static const AVClass concat_class
Definition: concatdec.c:770
#define NULL
Definition: coverity.c:32
static AVFrame * frame
static int nb_streams
Definition: ffprobe.c:283
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
#define FFERROR_NOT_READY
Filters implementation helper functions.
Definition: filters.h:34
static int ff_outlink_frame_wanted(AVFilterLink *link)
Test if a frame is wanted on an output link.
Definition: filters.h:172
int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
Add ref as a new reference to formats.
Definition: formats.c:466
AVFilterFormats * ff_all_formats(enum AVMediaType type)
Return a list of all formats supported by FFmpeg for the given media type.
Definition: formats.c:345
AVFilterChannelLayouts * ff_all_channel_layouts(void)
Construct an empty AVFilterChannelLayouts/AVFilterFormats struct – representing any channel layout (w...
Definition: formats.c:427
int ff_channel_layouts_ref(AVFilterChannelLayouts *f, AVFilterChannelLayouts **ref)
Add *ref as a new reference to f.
Definition: formats.c:461
AVFilterFormats * ff_all_samplerates(void)
Definition: formats.c:421
@ AV_OPT_TYPE_INT
Definition: opt.h:225
@ AV_OPT_TYPE_BOOL
Definition: opt.h:242
#define AVFILTER_FLAG_DYNAMIC_OUTPUTS
The number of the filter outputs is not determined just by AVFilter.outputs.
Definition: avfilter.h:112
#define AVFILTER_FLAG_DYNAMIC_INPUTS
The number of the filter inputs is not determined just by AVFilter.inputs.
Definition: avfilter.h:106
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:50
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
#define AVERROR(e)
Definition: error.h:43
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:210
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
static AVRational av_make_q(int num, int den)
Create an AVRational.
Definition: rational.h:71
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
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
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
Definition: mem.c:245
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
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
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:260
cl_device_type type
int i
Definition: input.c:407
static int ff_insert_inpad(AVFilterContext *f, unsigned index, AVFilterPad *p)
Insert a new input pad for the filter.
Definition: internal.h:240
static int ff_insert_outpad(AVFilterContext *f, unsigned index, AVFilterPad *p)
Insert a new output pad for the filter.
Definition: internal.h:248
#define FF_INLINK_IDX(link)
Find the index of a link.
Definition: internal.h:302
#define FF_OUTLINK_IDX(link)
Definition: internal.h:303
common internal API header
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
uint8_t w
Definition: llviddspenc.c:39
enum MovChannelLayoutTag * layouts
Definition: mov_chan.c:434
AVOptions.
formats
Definition: signature.h:48
Describe the class of an AVClass context structure.
Definition: log.h:67
A list of supported channel layouts.
Definition: formats.h:86
An instance of a filter.
Definition: avfilter.h:341
A list of supported formats for one end of a filter link.
Definition: formats.h:65
A filter pad used for either input or output.
Definition: internal.h:54
enum AVMediaType type
AVFilterPad type.
Definition: internal.h:65
const char * name
Pad name.
Definition: internal.h:60
Filter definition.
Definition: avfilter.h:145
const char * name
Filter name.
Definition: avfilter.h:149
This structure describes decoded (raw) audio or video data.
Definition: frame.h:318
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:384
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:411
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: frame.h:365
AVOption.
Definition: opt.h:248
Rational number (pair of numerator and denominator).
Definition: rational.h:58
int num
Numerator.
Definition: rational.h:59
int den
Denominator.
Definition: rational.h:60
int64_t delta_ts
timestamp to add to produce output timestamps
Definition: avf_concat.c:43
struct ConcatContext::concat_in * in
unsigned nb_streams[TYPE_ALL]
number of out streams of each type
Definition: avf_concat.c:40
unsigned unsafe
Definition: avf_concat.c:45
unsigned cur_idx
index of the first input of current segment
Definition: avf_concat.c:42
unsigned nb_segments
Definition: avf_concat.c:41
unsigned nb_in_active
number of active inputs in current segment
Definition: avf_concat.c:44
#define av_freep(p)
#define av_log(a,...)
AVFormatContext * ctx
Definition: movenc.c:48
static int64_t pts
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:99
#define cat(a, bpp, b)
Definition: vp9dsp_init.h:31