MobileFFmpeg Android API  4.4
fftools_ffmpeg_filter.c
Go to the documentation of this file.
1 /*
2  * ffmpeg filter configuration
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 /*
22  * CHANGES 08.2018
23  * --------------------------------------------------------
24  * - fftools_ prefix added to file name and parent header
25  *
26  * CHANGES 07.2018
27  * --------------------------------------------------------
28  * - Unused headers removed
29  */
30 
31 #include <stdint.h>
32 
33 #include "fftools_ffmpeg.h"
34 
35 #include "libavfilter/avfilter.h"
36 #include "libavfilter/buffersink.h"
37 #include "libavfilter/buffersrc.h"
38 
39 #include "libavutil/avassert.h"
40 #include "libavutil/avstring.h"
41 #include "libavutil/bprint.h"
42 #include "libavutil/channel_layout.h"
43 #include "libavutil/display.h"
44 #include "libavutil/opt.h"
45 #include "libavutil/pixdesc.h"
46 #include "libavutil/pixfmt.h"
47 #include "libavutil/imgutils.h"
48 #include "libavutil/samplefmt.h"
49 
50 static const enum AVPixelFormat *get_compliance_unofficial_pix_fmts(enum AVCodecID codec_id, const enum AVPixelFormat default_formats[])
51 {
52  static const enum AVPixelFormat mjpeg_formats[] =
53  { AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P,
54  AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P,
55  AV_PIX_FMT_NONE };
56  static const enum AVPixelFormat ljpeg_formats[] =
57  { AV_PIX_FMT_BGR24 , AV_PIX_FMT_BGRA , AV_PIX_FMT_BGR0,
58  AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ422P,
59  AV_PIX_FMT_YUV420P , AV_PIX_FMT_YUV444P , AV_PIX_FMT_YUV422P,
60  AV_PIX_FMT_NONE};
61 
62  if (codec_id == AV_CODEC_ID_MJPEG) {
63  return mjpeg_formats;
64  } else if (codec_id == AV_CODEC_ID_LJPEG) {
65  return ljpeg_formats;
66  } else {
67  return default_formats;
68  }
69 }
70 
71 enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodecContext *enc_ctx, AVCodec *codec, enum AVPixelFormat target)
72 {
73  if (codec && codec->pix_fmts) {
74  const enum AVPixelFormat *p = codec->pix_fmts;
75  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(target);
76  //FIXME: This should check for AV_PIX_FMT_FLAG_ALPHA after PAL8 pixel format without alpha is implemented
77  int has_alpha = desc ? desc->nb_components % 2 == 0 : 0;
78  enum AVPixelFormat best= AV_PIX_FMT_NONE;
79 
80  if (enc_ctx->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
81  p = get_compliance_unofficial_pix_fmts(enc_ctx->codec_id, p);
82  }
83  for (; *p != AV_PIX_FMT_NONE; p++) {
84  best= avcodec_find_best_pix_fmt_of_2(best, *p, target, has_alpha, NULL);
85  if (*p == target)
86  break;
87  }
88  if (*p == AV_PIX_FMT_NONE) {
89  if (target != AV_PIX_FMT_NONE)
90  av_log(NULL, AV_LOG_WARNING,
91  "Incompatible pixel format '%s' for codec '%s', auto-selecting format '%s'\n",
92  av_get_pix_fmt_name(target),
93  codec->name,
94  av_get_pix_fmt_name(best));
95  return best;
96  }
97  }
98  return target;
99 }
100 
101 void choose_sample_fmt(AVStream *st, AVCodec *codec)
102 {
103  if (codec && codec->sample_fmts) {
104  const enum AVSampleFormat *p = codec->sample_fmts;
105  for (; *p != -1; p++) {
106  if (*p == st->codecpar->format)
107  break;
108  }
109  if (*p == -1) {
110  if((codec->capabilities & AV_CODEC_CAP_LOSSLESS) && av_get_sample_fmt_name(st->codecpar->format) > av_get_sample_fmt_name(codec->sample_fmts[0]))
111  av_log(NULL, AV_LOG_ERROR, "Conversion will not be lossless.\n");
112  if(av_get_sample_fmt_name(st->codecpar->format))
113  av_log(NULL, AV_LOG_WARNING,
114  "Incompatible sample format '%s' for codec '%s', auto-selecting format '%s'\n",
115  av_get_sample_fmt_name(st->codecpar->format),
116  codec->name,
117  av_get_sample_fmt_name(codec->sample_fmts[0]));
118  st->codecpar->format = codec->sample_fmts[0];
119  }
120  }
121 }
122 
123 static char *choose_pix_fmts(OutputFilter *ofilter)
124 {
125  OutputStream *ost = ofilter->ost;
126  AVDictionaryEntry *strict_dict = av_dict_get(ost->encoder_opts, "strict", NULL, 0);
127  if (strict_dict)
128  // used by choose_pixel_fmt() and below
129  av_opt_set(ost->enc_ctx, "strict", strict_dict->value, 0);
130 
131  if (ost->keep_pix_fmt) {
132  avfilter_graph_set_auto_convert(ofilter->graph->graph,
133  AVFILTER_AUTO_CONVERT_NONE);
134  if (ost->enc_ctx->pix_fmt == AV_PIX_FMT_NONE)
135  return NULL;
136  return av_strdup(av_get_pix_fmt_name(ost->enc_ctx->pix_fmt));
137  }
138  if (ost->enc_ctx->pix_fmt != AV_PIX_FMT_NONE) {
139  return av_strdup(av_get_pix_fmt_name(choose_pixel_fmt(ost->st, ost->enc_ctx, ost->enc, ost->enc_ctx->pix_fmt)));
140  } else if (ost->enc && ost->enc->pix_fmts) {
141  const enum AVPixelFormat *p;
142  AVIOContext *s = NULL;
143  uint8_t *ret;
144  int len;
145 
146  if (avio_open_dyn_buf(&s) < 0)
147  exit_program(1);
148 
149  p = ost->enc->pix_fmts;
150  if (ost->enc_ctx->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
151  p = get_compliance_unofficial_pix_fmts(ost->enc_ctx->codec_id, p);
152  }
153 
154  for (; *p != AV_PIX_FMT_NONE; p++) {
155  const char *name = av_get_pix_fmt_name(*p);
156  avio_printf(s, "%s|", name);
157  }
158  len = avio_close_dyn_buf(s, &ret);
159  ret[len - 1] = 0;
160  return ret;
161  } else
162  return NULL;
163 }
164 
165 /* Define a function for building a string containing a list of
166  * allowed formats. */
167 #define DEF_CHOOSE_FORMAT(suffix, type, var, supported_list, none, get_name) \
168 static char *choose_ ## suffix (OutputFilter *ofilter) \
169 { \
170  if (ofilter->var != none) { \
171  get_name(ofilter->var); \
172  return av_strdup(name); \
173  } else if (ofilter->supported_list) { \
174  const type *p; \
175  AVIOContext *s = NULL; \
176  uint8_t *ret; \
177  int len; \
178  \
179  if (avio_open_dyn_buf(&s) < 0) \
180  exit_program(1); \
181  \
182  for (p = ofilter->supported_list; *p != none; p++) { \
183  get_name(*p); \
184  avio_printf(s, "%s|", name); \
185  } \
186  len = avio_close_dyn_buf(s, &ret); \
187  ret[len - 1] = 0; \
188  return ret; \
189  } else \
190  return NULL; \
191 }
192 
193 //DEF_CHOOSE_FORMAT(pix_fmts, enum AVPixelFormat, format, formats, AV_PIX_FMT_NONE,
194 // GET_PIX_FMT_NAME)
195 
196 DEF_CHOOSE_FORMAT(sample_fmts, enum AVSampleFormat, format, formats,
197  AV_SAMPLE_FMT_NONE, GET_SAMPLE_FMT_NAME)
198 
201 
202 DEF_CHOOSE_FORMAT(channel_layouts, uint64_t, channel_layout, channel_layouts, 0,
204 
206 {
207  FilterGraph *fg = av_mallocz(sizeof(*fg));
208 
209  if (!fg)
210  exit_program(1);
211  fg->index = nb_filtergraphs;
212 
213  GROW_ARRAY(fg->outputs, fg->nb_outputs);
214  if (!(fg->outputs[0] = av_mallocz(sizeof(*fg->outputs[0]))))
215  exit_program(1);
216  fg->outputs[0]->ost = ost;
217  fg->outputs[0]->graph = fg;
218  fg->outputs[0]->format = -1;
219 
220  ost->filter = fg->outputs[0];
221 
222  GROW_ARRAY(fg->inputs, fg->nb_inputs);
223  if (!(fg->inputs[0] = av_mallocz(sizeof(*fg->inputs[0]))))
224  exit_program(1);
225  fg->inputs[0]->ist = ist;
226  fg->inputs[0]->graph = fg;
227  fg->inputs[0]->format = -1;
228 
229  fg->inputs[0]->frame_queue = av_fifo_alloc(8 * sizeof(AVFrame*));
230  if (!fg->inputs[0]->frame_queue)
231  exit_program(1);
232 
233  GROW_ARRAY(ist->filters, ist->nb_filters);
234  ist->filters[ist->nb_filters - 1] = fg->inputs[0];
235 
237  filtergraphs[nb_filtergraphs - 1] = fg;
238 
239  return 0;
240 }
241 
242 static char *describe_filter_link(FilterGraph *fg, AVFilterInOut *inout, int in)
243 {
244  AVFilterContext *ctx = inout->filter_ctx;
245  AVFilterPad *pads = in ? ctx->input_pads : ctx->output_pads;
246  int nb_pads = in ? ctx->nb_inputs : ctx->nb_outputs;
247  AVIOContext *pb;
248  uint8_t *res = NULL;
249 
250  if (avio_open_dyn_buf(&pb) < 0)
251  exit_program(1);
252 
253  avio_printf(pb, "%s", ctx->filter->name);
254  if (nb_pads > 1)
255  avio_printf(pb, ":%s", avfilter_pad_get_name(pads, inout->pad_idx));
256  avio_w8(pb, 0);
257  avio_close_dyn_buf(pb, &res);
258  return res;
259 }
260 
261 static void init_input_filter(FilterGraph *fg, AVFilterInOut *in)
262 {
263  InputStream *ist = NULL;
264  enum AVMediaType type = avfilter_pad_get_type(in->filter_ctx->input_pads, in->pad_idx);
265  int i;
266 
267  // TODO: support other filter types
268  if (type != AVMEDIA_TYPE_VIDEO && type != AVMEDIA_TYPE_AUDIO) {
269  av_log(NULL, AV_LOG_FATAL, "Only video and audio filters supported "
270  "currently.\n");
271  exit_program(1);
272  }
273 
274  if (in->name) {
275  AVFormatContext *s;
276  AVStream *st = NULL;
277  char *p;
278  int file_idx = strtol(in->name, &p, 0);
279 
280  if (file_idx < 0 || file_idx >= nb_input_files) {
281  av_log(NULL, AV_LOG_FATAL, "Invalid file index %d in filtergraph description %s.\n",
282  file_idx, fg->graph_desc);
283  exit_program(1);
284  }
285  s = input_files[file_idx]->ctx;
286 
287  for (i = 0; i < s->nb_streams; i++) {
288  enum AVMediaType stream_type = s->streams[i]->codecpar->codec_type;
289  if (stream_type != type &&
290  !(stream_type == AVMEDIA_TYPE_SUBTITLE &&
291  type == AVMEDIA_TYPE_VIDEO /* sub2video hack */))
292  continue;
293  if (check_stream_specifier(s, s->streams[i], *p == ':' ? p + 1 : p) == 1) {
294  st = s->streams[i];
295  break;
296  }
297  }
298  if (!st) {
299  av_log(NULL, AV_LOG_FATAL, "Stream specifier '%s' in filtergraph description %s "
300  "matches no streams.\n", p, fg->graph_desc);
301  exit_program(1);
302  }
303  ist = input_streams[input_files[file_idx]->ist_index + st->index];
304  if (ist->user_set_discard == AVDISCARD_ALL) {
305  av_log(NULL, AV_LOG_FATAL, "Stream specifier '%s' in filtergraph description %s "
306  "matches a disabled input stream.\n", p, fg->graph_desc);
307  exit_program(1);
308  }
309  } else {
310  /* find the first unused stream of corresponding type */
311  for (i = 0; i < nb_input_streams; i++) {
312  ist = input_streams[i];
313  if (ist->user_set_discard == AVDISCARD_ALL)
314  continue;
315  if (ist->dec_ctx->codec_type == type && ist->discard)
316  break;
317  }
318  if (i == nb_input_streams) {
319  av_log(NULL, AV_LOG_FATAL, "Cannot find a matching stream for "
320  "unlabeled input pad %d on filter %s\n", in->pad_idx,
321  in->filter_ctx->name);
322  exit_program(1);
323  }
324  }
325  av_assert0(ist);
326 
327  ist->discard = 0;
329  ist->st->discard = AVDISCARD_NONE;
330 
331  GROW_ARRAY(fg->inputs, fg->nb_inputs);
332  if (!(fg->inputs[fg->nb_inputs - 1] = av_mallocz(sizeof(*fg->inputs[0]))))
333  exit_program(1);
334  fg->inputs[fg->nb_inputs - 1]->ist = ist;
335  fg->inputs[fg->nb_inputs - 1]->graph = fg;
336  fg->inputs[fg->nb_inputs - 1]->format = -1;
337  fg->inputs[fg->nb_inputs - 1]->type = ist->st->codecpar->codec_type;
338  fg->inputs[fg->nb_inputs - 1]->name = describe_filter_link(fg, in, 1);
339 
340  fg->inputs[fg->nb_inputs - 1]->frame_queue = av_fifo_alloc(8 * sizeof(AVFrame*));
341  if (!fg->inputs[fg->nb_inputs - 1]->frame_queue)
342  exit_program(1);
343 
344  GROW_ARRAY(ist->filters, ist->nb_filters);
345  ist->filters[ist->nb_filters - 1] = fg->inputs[fg->nb_inputs - 1];
346 }
347 
349 {
350  AVFilterInOut *inputs, *outputs, *cur;
351  AVFilterGraph *graph;
352  int ret = 0;
353 
354  /* this graph is only used for determining the kinds of inputs
355  * and outputs we have, and is discarded on exit from this function */
356  graph = avfilter_graph_alloc();
357  if (!graph)
358  return AVERROR(ENOMEM);
359  graph->nb_threads = 1;
360 
361  ret = avfilter_graph_parse2(graph, fg->graph_desc, &inputs, &outputs);
362  if (ret < 0)
363  goto fail;
364 
365  for (cur = inputs; cur; cur = cur->next)
366  init_input_filter(fg, cur);
367 
368  for (cur = outputs; cur;) {
369  GROW_ARRAY(fg->outputs, fg->nb_outputs);
370  fg->outputs[fg->nb_outputs - 1] = av_mallocz(sizeof(*fg->outputs[0]));
371  if (!fg->outputs[fg->nb_outputs - 1])
372  exit_program(1);
373 
374  fg->outputs[fg->nb_outputs - 1]->graph = fg;
375  fg->outputs[fg->nb_outputs - 1]->out_tmp = cur;
376  fg->outputs[fg->nb_outputs - 1]->type = avfilter_pad_get_type(cur->filter_ctx->output_pads,
377  cur->pad_idx);
378  fg->outputs[fg->nb_outputs - 1]->name = describe_filter_link(fg, cur, 0);
379  cur = cur->next;
380  fg->outputs[fg->nb_outputs - 1]->out_tmp->next = NULL;
381  }
382 
383 fail:
384  avfilter_inout_free(&inputs);
385  avfilter_graph_free(&graph);
386  return ret;
387 }
388 
389 static int insert_trim(int64_t start_time, int64_t duration,
390  AVFilterContext **last_filter, int *pad_idx,
391  const char *filter_name)
392 {
393  AVFilterGraph *graph = (*last_filter)->graph;
394  AVFilterContext *ctx;
395  const AVFilter *trim;
396  enum AVMediaType type = avfilter_pad_get_type((*last_filter)->output_pads, *pad_idx);
397  const char *name = (type == AVMEDIA_TYPE_VIDEO) ? "trim" : "atrim";
398  int ret = 0;
399 
400  if (duration == INT64_MAX && start_time == AV_NOPTS_VALUE)
401  return 0;
402 
403  trim = avfilter_get_by_name(name);
404  if (!trim) {
405  av_log(NULL, AV_LOG_ERROR, "%s filter not present, cannot limit "
406  "recording time.\n", name);
407  return AVERROR_FILTER_NOT_FOUND;
408  }
409 
410  ctx = avfilter_graph_alloc_filter(graph, trim, filter_name);
411  if (!ctx)
412  return AVERROR(ENOMEM);
413 
414  if (duration != INT64_MAX) {
415  ret = av_opt_set_int(ctx, "durationi", duration,
416  AV_OPT_SEARCH_CHILDREN);
417  }
418  if (ret >= 0 && start_time != AV_NOPTS_VALUE) {
419  ret = av_opt_set_int(ctx, "starti", start_time,
420  AV_OPT_SEARCH_CHILDREN);
421  }
422  if (ret < 0) {
423  av_log(ctx, AV_LOG_ERROR, "Error configuring the %s filter", name);
424  return ret;
425  }
426 
427  ret = avfilter_init_str(ctx, NULL);
428  if (ret < 0)
429  return ret;
430 
431  ret = avfilter_link(*last_filter, *pad_idx, ctx, 0);
432  if (ret < 0)
433  return ret;
434 
435  *last_filter = ctx;
436  *pad_idx = 0;
437  return 0;
438 }
439 
440 static int insert_filter(AVFilterContext **last_filter, int *pad_idx,
441  const char *filter_name, const char *args)
442 {
443  AVFilterGraph *graph = (*last_filter)->graph;
444  AVFilterContext *ctx;
445  int ret;
446 
447  ret = avfilter_graph_create_filter(&ctx,
448  avfilter_get_by_name(filter_name),
449  filter_name, args, NULL, graph);
450  if (ret < 0)
451  return ret;
452 
453  ret = avfilter_link(*last_filter, *pad_idx, ctx, 0);
454  if (ret < 0)
455  return ret;
456 
457  *last_filter = ctx;
458  *pad_idx = 0;
459  return 0;
460 }
461 
462 static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out)
463 {
464  char *pix_fmts;
465  OutputStream *ost = ofilter->ost;
466  OutputFile *of = output_files[ost->file_index];
467  AVFilterContext *last_filter = out->filter_ctx;
468  int pad_idx = out->pad_idx;
469  int ret;
470  char name[255];
471 
472  snprintf(name, sizeof(name), "out_%d_%d", ost->file_index, ost->index);
473  ret = avfilter_graph_create_filter(&ofilter->filter,
474  avfilter_get_by_name("buffersink"),
475  name, NULL, NULL, fg->graph);
476 
477  if (ret < 0)
478  return ret;
479 
480  if (ofilter->width || ofilter->height) {
481  char args[255];
482  AVFilterContext *filter;
483  AVDictionaryEntry *e = NULL;
484 
485  snprintf(args, sizeof(args), "%d:%d",
486  ofilter->width, ofilter->height);
487 
488  while ((e = av_dict_get(ost->sws_dict, "", e,
489  AV_DICT_IGNORE_SUFFIX))) {
490  av_strlcatf(args, sizeof(args), ":%s=%s", e->key, e->value);
491  }
492 
493  snprintf(name, sizeof(name), "scaler_out_%d_%d",
494  ost->file_index, ost->index);
495  if ((ret = avfilter_graph_create_filter(&filter, avfilter_get_by_name("scale"),
496  name, args, NULL, fg->graph)) < 0)
497  return ret;
498  if ((ret = avfilter_link(last_filter, pad_idx, filter, 0)) < 0)
499  return ret;
500 
501  last_filter = filter;
502  pad_idx = 0;
503  }
504 
505  if ((pix_fmts = choose_pix_fmts(ofilter))) {
506  AVFilterContext *filter;
507  snprintf(name, sizeof(name), "format_out_%d_%d",
508  ost->file_index, ost->index);
509  ret = avfilter_graph_create_filter(&filter,
510  avfilter_get_by_name("format"),
511  "format", pix_fmts, NULL, fg->graph);
512  av_freep(&pix_fmts);
513  if (ret < 0)
514  return ret;
515  if ((ret = avfilter_link(last_filter, pad_idx, filter, 0)) < 0)
516  return ret;
517 
518  last_filter = filter;
519  pad_idx = 0;
520  }
521 
522  if (ost->frame_rate.num && 0) {
523  AVFilterContext *fps;
524  char args[255];
525 
526  snprintf(args, sizeof(args), "fps=%d/%d", ost->frame_rate.num,
527  ost->frame_rate.den);
528  snprintf(name, sizeof(name), "fps_out_%d_%d",
529  ost->file_index, ost->index);
530  ret = avfilter_graph_create_filter(&fps, avfilter_get_by_name("fps"),
531  name, args, NULL, fg->graph);
532  if (ret < 0)
533  return ret;
534 
535  ret = avfilter_link(last_filter, pad_idx, fps, 0);
536  if (ret < 0)
537  return ret;
538  last_filter = fps;
539  pad_idx = 0;
540  }
541 
542  snprintf(name, sizeof(name), "trim_out_%d_%d",
543  ost->file_index, ost->index);
544  ret = insert_trim(of->start_time, of->recording_time,
545  &last_filter, &pad_idx, name);
546  if (ret < 0)
547  return ret;
548 
549 
550  if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0)
551  return ret;
552 
553  return 0;
554 }
555 
556 static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out)
557 {
558  OutputStream *ost = ofilter->ost;
559  OutputFile *of = output_files[ost->file_index];
560  AVCodecContext *codec = ost->enc_ctx;
561  AVFilterContext *last_filter = out->filter_ctx;
562  int pad_idx = out->pad_idx;
563  char *sample_fmts, *sample_rates, *channel_layouts;
564  char name[255];
565  int ret;
566 
567  snprintf(name, sizeof(name), "out_%d_%d", ost->file_index, ost->index);
568  ret = avfilter_graph_create_filter(&ofilter->filter,
569  avfilter_get_by_name("abuffersink"),
570  name, NULL, NULL, fg->graph);
571  if (ret < 0)
572  return ret;
573  if ((ret = av_opt_set_int(ofilter->filter, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
574  return ret;
575 
576 #define AUTO_INSERT_FILTER(opt_name, filter_name, arg) do { \
577  AVFilterContext *filt_ctx; \
578  \
579  av_log(NULL, AV_LOG_INFO, opt_name " is forwarded to lavfi " \
580  "similarly to -af " filter_name "=%s.\n", arg); \
581  \
582  ret = avfilter_graph_create_filter(&filt_ctx, \
583  avfilter_get_by_name(filter_name), \
584  filter_name, arg, NULL, fg->graph); \
585  if (ret < 0) \
586  return ret; \
587  \
588  ret = avfilter_link(last_filter, pad_idx, filt_ctx, 0); \
589  if (ret < 0) \
590  return ret; \
591  \
592  last_filter = filt_ctx; \
593  pad_idx = 0; \
594 } while (0)
595  if (ost->audio_channels_mapped) {
596  int i;
597  AVBPrint pan_buf;
598  av_bprint_init(&pan_buf, 256, 8192);
599  av_bprintf(&pan_buf, "0x%"PRIx64,
600  av_get_default_channel_layout(ost->audio_channels_mapped));
601  for (i = 0; i < ost->audio_channels_mapped; i++)
602  if (ost->audio_channels_map[i] != -1)
603  av_bprintf(&pan_buf, "|c%d=c%d", i, ost->audio_channels_map[i]);
604 
605  AUTO_INSERT_FILTER("-map_channel", "pan", pan_buf.str);
606  av_bprint_finalize(&pan_buf, NULL);
607  }
608 
609  if (codec->channels && !codec->channel_layout)
610  codec->channel_layout = av_get_default_channel_layout(codec->channels);
611 
612  sample_fmts = choose_sample_fmts(ofilter);
613  sample_rates = choose_sample_rates(ofilter);
614  channel_layouts = choose_channel_layouts(ofilter);
615  if (sample_fmts || sample_rates || channel_layouts) {
616  AVFilterContext *format;
617  char args[256];
618  args[0] = 0;
619 
620  if (sample_fmts)
621  av_strlcatf(args, sizeof(args), "sample_fmts=%s:",
622  sample_fmts);
623  if (sample_rates)
624  av_strlcatf(args, sizeof(args), "sample_rates=%s:",
625  sample_rates);
626  if (channel_layouts)
627  av_strlcatf(args, sizeof(args), "channel_layouts=%s:",
628  channel_layouts);
629 
630  av_freep(&sample_fmts);
631  av_freep(&sample_rates);
632  av_freep(&channel_layouts);
633 
634  snprintf(name, sizeof(name), "format_out_%d_%d",
635  ost->file_index, ost->index);
636  ret = avfilter_graph_create_filter(&format,
637  avfilter_get_by_name("aformat"),
638  name, args, NULL, fg->graph);
639  if (ret < 0)
640  return ret;
641 
642  ret = avfilter_link(last_filter, pad_idx, format, 0);
643  if (ret < 0)
644  return ret;
645 
646  last_filter = format;
647  pad_idx = 0;
648  }
649 
650  if (audio_volume != 256 && 0) {
651  char args[256];
652 
653  snprintf(args, sizeof(args), "%f", audio_volume / 256.);
654  AUTO_INSERT_FILTER("-vol", "volume", args);
655  }
656 
657  if (ost->apad && of->shortest) {
658  char args[256];
659  int i;
660 
661  for (i=0; i<of->ctx->nb_streams; i++)
662  if (of->ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
663  break;
664 
665  if (i<of->ctx->nb_streams) {
666  snprintf(args, sizeof(args), "%s", ost->apad);
667  AUTO_INSERT_FILTER("-apad", "apad", args);
668  }
669  }
670 
671  snprintf(name, sizeof(name), "trim for output stream %d:%d",
672  ost->file_index, ost->index);
673  ret = insert_trim(of->start_time, of->recording_time,
674  &last_filter, &pad_idx, name);
675  if (ret < 0)
676  return ret;
677 
678  if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0)
679  return ret;
680 
681  return 0;
682 }
683 
684 int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out)
685 {
686  if (!ofilter->ost) {
687  av_log(NULL, AV_LOG_FATAL, "Filter %s has an unconnected output\n", ofilter->name);
688  exit_program(1);
689  }
690 
691  switch (avfilter_pad_get_type(out->filter_ctx->output_pads, out->pad_idx)) {
692  case AVMEDIA_TYPE_VIDEO: return configure_output_video_filter(fg, ofilter, out);
693  case AVMEDIA_TYPE_AUDIO: return configure_output_audio_filter(fg, ofilter, out);
694  default: av_assert0(0);
695  }
696 }
697 
699 {
700  int i;
701  for (i = 0; i < nb_filtergraphs; i++) {
702  int n;
703  for (n = 0; n < filtergraphs[i]->nb_outputs; n++) {
704  OutputFilter *output = filtergraphs[i]->outputs[n];
705  if (!output->ost) {
706  av_log(NULL, AV_LOG_FATAL, "Filter %s has an unconnected output\n", output->name);
707  exit_program(1);
708  }
709  }
710  }
711 }
712 
713 static int sub2video_prepare(InputStream *ist, InputFilter *ifilter)
714 {
715  AVFormatContext *avf = input_files[ist->file_index]->ctx;
716  int i, w, h;
717 
718  /* Compute the size of the canvas for the subtitles stream.
719  If the subtitles codecpar has set a size, use it. Otherwise use the
720  maximum dimensions of the video streams in the same file. */
721  w = ifilter->width;
722  h = ifilter->height;
723  if (!(w && h)) {
724  for (i = 0; i < avf->nb_streams; i++) {
725  if (avf->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
726  w = FFMAX(w, avf->streams[i]->codecpar->width);
727  h = FFMAX(h, avf->streams[i]->codecpar->height);
728  }
729  }
730  if (!(w && h)) {
731  w = FFMAX(w, 720);
732  h = FFMAX(h, 576);
733  }
734  av_log(avf, AV_LOG_INFO, "sub2video: using %dx%d canvas\n", w, h);
735  }
736  ist->sub2video.w = ifilter->width = w;
737  ist->sub2video.h = ifilter->height = h;
738 
739  ifilter->width = ist->dec_ctx->width ? ist->dec_ctx->width : ist->sub2video.w;
740  ifilter->height = ist->dec_ctx->height ? ist->dec_ctx->height : ist->sub2video.h;
741 
742  /* rectangles are AV_PIX_FMT_PAL8, but we have no guarantee that the
743  palettes for all rectangles are identical or compatible */
744  ifilter->format = AV_PIX_FMT_RGB32;
745 
746  ist->sub2video.frame = av_frame_alloc();
747  if (!ist->sub2video.frame)
748  return AVERROR(ENOMEM);
749  ist->sub2video.last_pts = INT64_MIN;
750  ist->sub2video.end_pts = INT64_MIN;
751  return 0;
752 }
753 
755  AVFilterInOut *in)
756 {
757  AVFilterContext *last_filter;
758  const AVFilter *buffer_filt = avfilter_get_by_name("buffer");
759  InputStream *ist = ifilter->ist;
760  InputFile *f = input_files[ist->file_index];
761  AVRational tb = ist->framerate.num ? av_inv_q(ist->framerate) :
762  ist->st->time_base;
763  AVRational fr = ist->framerate;
764  AVRational sar;
765  AVBPrint args;
766  char name[255];
767  int ret, pad_idx = 0;
768  int64_t tsoffset = 0;
769  AVBufferSrcParameters *par = av_buffersrc_parameters_alloc();
770 
771  if (!par)
772  return AVERROR(ENOMEM);
773  memset(par, 0, sizeof(*par));
774  par->format = AV_PIX_FMT_NONE;
775 
776  if (ist->dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
777  av_log(NULL, AV_LOG_ERROR, "Cannot connect video filter to audio input\n");
778  ret = AVERROR(EINVAL);
779  goto fail;
780  }
781 
782  if (!fr.num)
783  fr = av_guess_frame_rate(input_files[ist->file_index]->ctx, ist->st, NULL);
784 
785  if (ist->dec_ctx->codec_type == AVMEDIA_TYPE_SUBTITLE) {
786  ret = sub2video_prepare(ist, ifilter);
787  if (ret < 0)
788  goto fail;
789  }
790 
791  sar = ifilter->sample_aspect_ratio;
792  if(!sar.den)
793  sar = (AVRational){0,1};
794  av_bprint_init(&args, 0, AV_BPRINT_SIZE_AUTOMATIC);
795  av_bprintf(&args,
796  "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:"
797  "pixel_aspect=%d/%d:sws_param=flags=%d",
798  ifilter->width, ifilter->height, ifilter->format,
799  tb.num, tb.den, sar.num, sar.den,
800  SWS_BILINEAR + ((ist->dec_ctx->flags&AV_CODEC_FLAG_BITEXACT) ? SWS_BITEXACT:0));
801  if (fr.num && fr.den)
802  av_bprintf(&args, ":frame_rate=%d/%d", fr.num, fr.den);
803  snprintf(name, sizeof(name), "graph %d input from stream %d:%d", fg->index,
804  ist->file_index, ist->st->index);
805 
806 
807  if ((ret = avfilter_graph_create_filter(&ifilter->filter, buffer_filt, name,
808  args.str, NULL, fg->graph)) < 0)
809  goto fail;
810  par->hw_frames_ctx = ifilter->hw_frames_ctx;
811  ret = av_buffersrc_parameters_set(ifilter->filter, par);
812  if (ret < 0)
813  goto fail;
814  av_freep(&par);
815  last_filter = ifilter->filter;
816 
817  if (ist->autorotate) {
818  double theta = get_rotation(ist->st);
819 
820  if (fabs(theta - 90) < 1.0) {
821  ret = insert_filter(&last_filter, &pad_idx, "transpose", "clock");
822  } else if (fabs(theta - 180) < 1.0) {
823  ret = insert_filter(&last_filter, &pad_idx, "hflip", NULL);
824  if (ret < 0)
825  return ret;
826  ret = insert_filter(&last_filter, &pad_idx, "vflip", NULL);
827  } else if (fabs(theta - 270) < 1.0) {
828  ret = insert_filter(&last_filter, &pad_idx, "transpose", "cclock");
829  } else if (fabs(theta) > 1.0) {
830  char rotate_buf[64];
831  snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
832  ret = insert_filter(&last_filter, &pad_idx, "rotate", rotate_buf);
833  }
834  if (ret < 0)
835  return ret;
836  }
837 
838  if (do_deinterlace) {
839  AVFilterContext *yadif;
840 
841  snprintf(name, sizeof(name), "deinterlace_in_%d_%d",
842  ist->file_index, ist->st->index);
843  if ((ret = avfilter_graph_create_filter(&yadif,
844  avfilter_get_by_name("yadif"),
845  name, "", NULL,
846  fg->graph)) < 0)
847  return ret;
848 
849  if ((ret = avfilter_link(last_filter, 0, yadif, 0)) < 0)
850  return ret;
851 
852  last_filter = yadif;
853  }
854 
855  snprintf(name, sizeof(name), "trim_in_%d_%d",
856  ist->file_index, ist->st->index);
857  if (copy_ts) {
858  tsoffset = f->start_time == AV_NOPTS_VALUE ? 0 : f->start_time;
859  if (!start_at_zero && f->ctx->start_time != AV_NOPTS_VALUE)
860  tsoffset += f->ctx->start_time;
861  }
862  ret = insert_trim(((f->start_time == AV_NOPTS_VALUE) || !f->accurate_seek) ?
863  AV_NOPTS_VALUE : tsoffset, f->recording_time,
864  &last_filter, &pad_idx, name);
865  if (ret < 0)
866  return ret;
867 
868  if ((ret = avfilter_link(last_filter, 0, in->filter_ctx, in->pad_idx)) < 0)
869  return ret;
870  return 0;
871 fail:
872  av_freep(&par);
873 
874  return ret;
875 }
876 
878  AVFilterInOut *in)
879 {
880  AVFilterContext *last_filter;
881  const AVFilter *abuffer_filt = avfilter_get_by_name("abuffer");
882  InputStream *ist = ifilter->ist;
883  InputFile *f = input_files[ist->file_index];
884  AVBPrint args;
885  char name[255];
886  int ret, pad_idx = 0;
887  int64_t tsoffset = 0;
888 
889  if (ist->dec_ctx->codec_type != AVMEDIA_TYPE_AUDIO) {
890  av_log(NULL, AV_LOG_ERROR, "Cannot connect audio filter to non audio input\n");
891  return AVERROR(EINVAL);
892  }
893 
894  av_bprint_init(&args, 0, AV_BPRINT_SIZE_AUTOMATIC);
895  av_bprintf(&args, "time_base=%d/%d:sample_rate=%d:sample_fmt=%s",
896  1, ifilter->sample_rate,
897  ifilter->sample_rate,
898  av_get_sample_fmt_name(ifilter->format));
899  if (ifilter->channel_layout)
900  av_bprintf(&args, ":channel_layout=0x%"PRIx64,
901  ifilter->channel_layout);
902  else
903  av_bprintf(&args, ":channels=%d", ifilter->channels);
904  snprintf(name, sizeof(name), "graph_%d_in_%d_%d", fg->index,
905  ist->file_index, ist->st->index);
906 
907  if ((ret = avfilter_graph_create_filter(&ifilter->filter, abuffer_filt,
908  name, args.str, NULL,
909  fg->graph)) < 0)
910  return ret;
911  last_filter = ifilter->filter;
912 
913 #define AUTO_INSERT_FILTER_INPUT(opt_name, filter_name, arg) do { \
914  AVFilterContext *filt_ctx; \
915  \
916  av_log(NULL, AV_LOG_INFO, opt_name " is forwarded to lavfi " \
917  "similarly to -af " filter_name "=%s.\n", arg); \
918  \
919  snprintf(name, sizeof(name), "graph_%d_%s_in_%d_%d", \
920  fg->index, filter_name, ist->file_index, ist->st->index); \
921  ret = avfilter_graph_create_filter(&filt_ctx, \
922  avfilter_get_by_name(filter_name), \
923  name, arg, NULL, fg->graph); \
924  if (ret < 0) \
925  return ret; \
926  \
927  ret = avfilter_link(last_filter, 0, filt_ctx, 0); \
928  if (ret < 0) \
929  return ret; \
930  \
931  last_filter = filt_ctx; \
932 } while (0)
933 
934  if (audio_sync_method > 0) {
935  char args[256] = {0};
936 
937  av_strlcatf(args, sizeof(args), "async=%d", audio_sync_method);
938  if (audio_drift_threshold != 0.1)
939  av_strlcatf(args, sizeof(args), ":min_hard_comp=%f", audio_drift_threshold);
940  if (!fg->reconfiguration)
941  av_strlcatf(args, sizeof(args), ":first_pts=0");
942  AUTO_INSERT_FILTER_INPUT("-async", "aresample", args);
943  }
944 
945 // if (ost->audio_channels_mapped) {
946 // int i;
947 // AVBPrint pan_buf;
948 // av_bprint_init(&pan_buf, 256, 8192);
949 // av_bprintf(&pan_buf, "0x%"PRIx64,
950 // av_get_default_channel_layout(ost->audio_channels_mapped));
951 // for (i = 0; i < ost->audio_channels_mapped; i++)
952 // if (ost->audio_channels_map[i] != -1)
953 // av_bprintf(&pan_buf, ":c%d=c%d", i, ost->audio_channels_map[i]);
954 // AUTO_INSERT_FILTER_INPUT("-map_channel", "pan", pan_buf.str);
955 // av_bprint_finalize(&pan_buf, NULL);
956 // }
957 
958  if (audio_volume != 256) {
959  char args[256];
960 
961  av_log(NULL, AV_LOG_WARNING, "-vol has been deprecated. Use the volume "
962  "audio filter instead.\n");
963 
964  snprintf(args, sizeof(args), "%f", audio_volume / 256.);
965  AUTO_INSERT_FILTER_INPUT("-vol", "volume", args);
966  }
967 
968  snprintf(name, sizeof(name), "trim for input stream %d:%d",
969  ist->file_index, ist->st->index);
970  if (copy_ts) {
971  tsoffset = f->start_time == AV_NOPTS_VALUE ? 0 : f->start_time;
972  if (!start_at_zero && f->ctx->start_time != AV_NOPTS_VALUE)
973  tsoffset += f->ctx->start_time;
974  }
975  ret = insert_trim(((f->start_time == AV_NOPTS_VALUE) || !f->accurate_seek) ?
976  AV_NOPTS_VALUE : tsoffset, f->recording_time,
977  &last_filter, &pad_idx, name);
978  if (ret < 0)
979  return ret;
980 
981  if ((ret = avfilter_link(last_filter, 0, in->filter_ctx, in->pad_idx)) < 0)
982  return ret;
983 
984  return 0;
985 }
986 
988  AVFilterInOut *in)
989 {
990  if (!ifilter->ist->dec) {
991  av_log(NULL, AV_LOG_ERROR,
992  "No decoder for stream #%d:%d, filtering impossible\n",
993  ifilter->ist->file_index, ifilter->ist->st->index);
994  return AVERROR_DECODER_NOT_FOUND;
995  }
996  switch (avfilter_pad_get_type(in->filter_ctx->input_pads, in->pad_idx)) {
997  case AVMEDIA_TYPE_VIDEO: return configure_input_video_filter(fg, ifilter, in);
998  case AVMEDIA_TYPE_AUDIO: return configure_input_audio_filter(fg, ifilter, in);
999  default: av_assert0(0);
1000  }
1001 }
1002 
1004 {
1005  int i;
1006  for (i = 0; i < fg->nb_outputs; i++)
1007  fg->outputs[i]->filter = (AVFilterContext *)NULL;
1008  for (i = 0; i < fg->nb_inputs; i++)
1009  fg->inputs[i]->filter = (AVFilterContext *)NULL;
1010  avfilter_graph_free(&fg->graph);
1011 }
1012 
1014 {
1015  AVFilterInOut *inputs, *outputs, *cur;
1016  int ret, i, simple = filtergraph_is_simple(fg);
1017  const char *graph_desc = simple ? fg->outputs[0]->ost->avfilter :
1018  fg->graph_desc;
1019 
1020  cleanup_filtergraph(fg);
1021  if (!(fg->graph = avfilter_graph_alloc()))
1022  return AVERROR(ENOMEM);
1023 
1024  if (simple) {
1025  OutputStream *ost = fg->outputs[0]->ost;
1026  char args[512];
1027  AVDictionaryEntry *e = NULL;
1028 
1029  fg->graph->nb_threads = filter_nbthreads;
1030 
1031  args[0] = 0;
1032  while ((e = av_dict_get(ost->sws_dict, "", e,
1033  AV_DICT_IGNORE_SUFFIX))) {
1034  av_strlcatf(args, sizeof(args), "%s=%s:", e->key, e->value);
1035  }
1036  if (strlen(args))
1037  args[strlen(args)-1] = 0;
1038  fg->graph->scale_sws_opts = av_strdup(args);
1039 
1040  args[0] = 0;
1041  while ((e = av_dict_get(ost->swr_opts, "", e,
1042  AV_DICT_IGNORE_SUFFIX))) {
1043  av_strlcatf(args, sizeof(args), "%s=%s:", e->key, e->value);
1044  }
1045  if (strlen(args))
1046  args[strlen(args)-1] = 0;
1047  av_opt_set(fg->graph, "aresample_swr_opts", args, 0);
1048 
1049  args[0] = '\0';
1050  while ((e = av_dict_get(fg->outputs[0]->ost->resample_opts, "", e,
1051  AV_DICT_IGNORE_SUFFIX))) {
1052  av_strlcatf(args, sizeof(args), "%s=%s:", e->key, e->value);
1053  }
1054  if (strlen(args))
1055  args[strlen(args) - 1] = '\0';
1056 
1057  e = av_dict_get(ost->encoder_opts, "threads", NULL, 0);
1058  if (e)
1059  av_opt_set(fg->graph, "threads", e->value, 0);
1060  } else {
1061  fg->graph->nb_threads = filter_complex_nbthreads;
1062  }
1063 
1064  if ((ret = avfilter_graph_parse2(fg->graph, graph_desc, &inputs, &outputs)) < 0)
1065  goto fail;
1066 
1068  AVBufferRef *device = filter_hw_device ? filter_hw_device->device_ref
1069  : hw_device_ctx;
1070  for (i = 0; i < fg->graph->nb_filters; i++) {
1071  fg->graph->filters[i]->hw_device_ctx = av_buffer_ref(device);
1072  if (!fg->graph->filters[i]->hw_device_ctx) {
1073  ret = AVERROR(ENOMEM);
1074  goto fail;
1075  }
1076  }
1077  }
1078 
1079  if (simple && (!inputs || inputs->next || !outputs || outputs->next)) {
1080  const char *num_inputs;
1081  const char *num_outputs;
1082  if (!outputs) {
1083  num_outputs = "0";
1084  } else if (outputs->next) {
1085  num_outputs = ">1";
1086  } else {
1087  num_outputs = "1";
1088  }
1089  if (!inputs) {
1090  num_inputs = "0";
1091  } else if (inputs->next) {
1092  num_inputs = ">1";
1093  } else {
1094  num_inputs = "1";
1095  }
1096  av_log(NULL, AV_LOG_ERROR, "Simple filtergraph '%s' was expected "
1097  "to have exactly 1 input and 1 output."
1098  " However, it had %s input(s) and %s output(s)."
1099  " Please adjust, or use a complex filtergraph (-filter_complex) instead.\n",
1100  graph_desc, num_inputs, num_outputs);
1101  ret = AVERROR(EINVAL);
1102  goto fail;
1103  }
1104 
1105  for (cur = inputs, i = 0; cur; cur = cur->next, i++)
1106  if ((ret = configure_input_filter(fg, fg->inputs[i], cur)) < 0) {
1107  avfilter_inout_free(&inputs);
1108  avfilter_inout_free(&outputs);
1109  goto fail;
1110  }
1111  avfilter_inout_free(&inputs);
1112 
1113  for (cur = outputs, i = 0; cur; cur = cur->next, i++)
1114  configure_output_filter(fg, fg->outputs[i], cur);
1115  avfilter_inout_free(&outputs);
1116 
1117  if ((ret = avfilter_graph_config(fg->graph, NULL)) < 0)
1118  goto fail;
1119 
1120  /* limit the lists of allowed formats to the ones selected, to
1121  * make sure they stay the same if the filtergraph is reconfigured later */
1122  for (i = 0; i < fg->nb_outputs; i++) {
1123  OutputFilter *ofilter = fg->outputs[i];
1124  AVFilterContext *sink = ofilter->filter;
1125 
1126  ofilter->format = av_buffersink_get_format(sink);
1127 
1128  ofilter->width = av_buffersink_get_w(sink);
1129  ofilter->height = av_buffersink_get_h(sink);
1130 
1131  ofilter->sample_rate = av_buffersink_get_sample_rate(sink);
1132  ofilter->channel_layout = av_buffersink_get_channel_layout(sink);
1133  }
1134 
1135  fg->reconfiguration = 1;
1136 
1137  for (i = 0; i < fg->nb_outputs; i++) {
1138  OutputStream *ost = fg->outputs[i]->ost;
1139  if (!ost->enc) {
1140  /* identical to the same check in ffmpeg.c, needed because
1141  complex filter graphs are initialized earlier */
1142  av_log(NULL, AV_LOG_ERROR, "Encoder (codec %s) not found for output stream #%d:%d\n",
1143  avcodec_get_name(ost->st->codecpar->codec_id), ost->file_index, ost->index);
1144  ret = AVERROR(EINVAL);
1145  goto fail;
1146  }
1147  if (ost->enc->type == AVMEDIA_TYPE_AUDIO &&
1148  !(ost->enc->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE))
1149  av_buffersink_set_frame_size(ost->filter->filter,
1150  ost->enc_ctx->frame_size);
1151  }
1152 
1153  for (i = 0; i < fg->nb_inputs; i++) {
1154  while (av_fifo_size(fg->inputs[i]->frame_queue)) {
1155  AVFrame *tmp;
1156  av_fifo_generic_read(fg->inputs[i]->frame_queue, &tmp, sizeof(tmp), NULL);
1157  ret = av_buffersrc_add_frame(fg->inputs[i]->filter, tmp);
1158  av_frame_free(&tmp);
1159  if (ret < 0)
1160  goto fail;
1161  }
1162  }
1163 
1164  /* send the EOFs for the finished inputs */
1165  for (i = 0; i < fg->nb_inputs; i++) {
1166  if (fg->inputs[i]->eof) {
1167  ret = av_buffersrc_add_frame(fg->inputs[i]->filter, NULL);
1168  if (ret < 0)
1169  goto fail;
1170  }
1171  }
1172 
1173  /* process queued up subtitle packets */
1174  for (i = 0; i < fg->nb_inputs; i++) {
1175  InputStream *ist = fg->inputs[i]->ist;
1176  if (ist->sub2video.sub_queue && ist->sub2video.frame) {
1177  while (av_fifo_size(ist->sub2video.sub_queue)) {
1178  AVSubtitle tmp;
1179  av_fifo_generic_read(ist->sub2video.sub_queue, &tmp, sizeof(tmp), NULL);
1180  sub2video_update(ist, &tmp);
1181  avsubtitle_free(&tmp);
1182  }
1183  }
1184  }
1185 
1186  return 0;
1187 
1188 fail:
1189  cleanup_filtergraph(fg);
1190  return ret;
1191 }
1192 
1193 int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame)
1194 {
1195  av_buffer_unref(&ifilter->hw_frames_ctx);
1196 
1197  ifilter->format = frame->format;
1198 
1199  ifilter->width = frame->width;
1200  ifilter->height = frame->height;
1201  ifilter->sample_aspect_ratio = frame->sample_aspect_ratio;
1202 
1203  ifilter->sample_rate = frame->sample_rate;
1204  ifilter->channels = frame->channels;
1205  ifilter->channel_layout = frame->channel_layout;
1206 
1207  if (frame->hw_frames_ctx) {
1208  ifilter->hw_frames_ctx = av_buffer_ref(frame->hw_frames_ctx);
1209  if (!ifilter->hw_frames_ctx)
1210  return AVERROR(ENOMEM);
1211  }
1212 
1213  return 0;
1214 }
1215 
1217 {
1218  int i;
1219  for (i = 0; i < fg->nb_inputs; i++)
1220  if (fg->inputs[i]->ist == ist)
1221  return 1;
1222  return 0;
1223 }
1224 
1226 {
1227  return !fg->graph_desc;
1228 }
check_stream_specifier
int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec)
Definition: fftools_cmdutils.c:2123
AUTO_INSERT_FILTER
#define AUTO_INSERT_FILTER(opt_name, filter_name, arg)
OutputStream::avfilter
char * avfilter
Definition: fftools_ffmpeg.h:526
init_input_filter
static void init_input_filter(FilterGraph *fg, AVFilterInOut *in)
Definition: fftools_ffmpeg_filter.c:261
ifilter_parameters_from_frame
int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame)
Definition: fftools_ffmpeg_filter.c:1193
InputFilter::name
uint8_t * name
Definition: fftools_ffmpeg.h:262
InputStream::sub2video::h
int h
Definition: fftools_ffmpeg.h:374
AUTO_INSERT_FILTER_INPUT
#define AUTO_INSERT_FILTER_INPUT(opt_name, filter_name, arg)
InputStream::discard
int discard
Definition: fftools_ffmpeg.h:321
filter_hw_device
__thread HWDevice * filter_hw_device
Definition: fftools_ffmpeg_opt.c:97
OutputFile::ctx
AVFormatContext * ctx
Definition: fftools_ffmpeg.h:578
configure_output_filter
int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out)
Definition: fftools_ffmpeg_filter.c:684
fftools_ffmpeg.h
FilterGraph::index
int index
Definition: fftools_ffmpeg.h:306
exit_program
void exit_program(int ret)
Definition: fftools_cmdutils.c:166
output_files
__thread OutputFile ** output_files
Definition: fftools_ffmpeg.c:182
nb_input_streams
__thread int nb_input_streams
Definition: fftools_ffmpeg.c:176
InputStream
Definition: fftools_ffmpeg.h:318
DEF_CHOOSE_FORMAT
#define DEF_CHOOSE_FORMAT(suffix, type, var, supported_list, none, get_name)
Definition: fftools_ffmpeg_filter.c:167
GET_SAMPLE_FMT_NAME
#define GET_SAMPLE_FMT_NAME(sample_fmt)
Definition: fftools_cmdutils.h:616
audio_drift_threshold
__thread float audio_drift_threshold
Definition: fftools_ffmpeg_opt.c:102
OutputFilter::channel_layout
uint64_t channel_layout
Definition: fftools_ffmpeg.h:297
filtergraph_is_simple
int filtergraph_is_simple(FilterGraph *fg)
Definition: fftools_ffmpeg_filter.c:1225
OutputStream::audio_channels_mapped
int audio_channels_mapped
Definition: fftools_ffmpeg.h:520
OutputStream::file_index
int file_index
Definition: fftools_ffmpeg.h:466
InputFilter
Definition: fftools_ffmpeg.h:258
do_deinterlace
__thread int do_deinterlace
Definition: fftools_ffmpeg_opt.c:110
InputStream::nb_filters
int nb_filters
Definition: fftools_ffmpeg.h:382
InputStream::sub2video::end_pts
int64_t end_pts
Definition: fftools_ffmpeg.h:371
OutputFilter
Definition: fftools_ffmpeg.h:282
InputFilter::channel_layout
uint64_t channel_layout
Definition: fftools_ffmpeg.h:275
OutputStream::sws_dict
AVDictionary * sws_dict
Definition: fftools_ffmpeg.h:531
init_simple_filtergraph
int init_simple_filtergraph(InputStream *ist, OutputStream *ost)
InputStream::autorotate
int autorotate
Definition: fftools_ffmpeg.h:360
OutputFilter::graph
struct FilterGraph * graph
Definition: fftools_ffmpeg.h:285
InputStream::sub2video::sub_queue
AVFifoBuffer * sub_queue
queue of AVSubtitle* before filter init
Definition: fftools_ffmpeg.h:372
FilterGraph::nb_inputs
int nb_inputs
Definition: fftools_ffmpeg.h:313
InputFilter::ist
struct InputStream * ist
Definition: fftools_ffmpeg.h:260
InputFilter::type
enum AVMediaType type
Definition: fftools_ffmpeg.h:263
InputFilter::frame_queue
AVFifoBuffer * frame_queue
Definition: fftools_ffmpeg.h:265
InputFile
Definition: fftools_ffmpeg.h:416
OutputFilter::name
uint8_t * name
Definition: fftools_ffmpeg.h:286
init_complex_filtergraph
int init_complex_filtergraph(FilterGraph *fg)
Definition: fftools_ffmpeg_filter.c:348
InputFile::accurate_seek
int accurate_seek
Definition: fftools_ffmpeg.h:436
FilterGraph::graph_desc
const char * graph_desc
Definition: fftools_ffmpeg.h:307
insert_filter
static int insert_filter(AVFilterContext **last_filter, int *pad_idx, const char *filter_name, const char *args)
Definition: fftools_ffmpeg_filter.c:440
OutputFile::shortest
int shortest
Definition: fftools_ffmpeg.h:585
nb_input_files
__thread int nb_input_files
Definition: fftools_ffmpeg.c:178
OutputFile::recording_time
int64_t recording_time
desired length of the resulting file in microseconds == AV_TIME_BASE units
Definition: fftools_ffmpeg.h:581
filter_nbthreads
__thread int filter_nbthreads
Definition: fftools_ffmpeg_opt.c:126
InputStream::sub2video::last_pts
int64_t last_pts
Definition: fftools_ffmpeg.h:370
InputFile::ctx
AVFormatContext * ctx
Definition: fftools_ffmpeg.h:417
audio_sync_method
__thread int audio_sync_method
Definition: fftools_ffmpeg_opt.c:107
FilterGraph::nb_outputs
int nb_outputs
Definition: fftools_ffmpeg.h:315
InputFilter::sample_aspect_ratio
AVRational sample_aspect_ratio
Definition: fftools_ffmpeg.h:271
InputFilter::graph
struct FilterGraph * graph
Definition: fftools_ffmpeg.h:261
configure_output_audio_filter
static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out)
Definition: fftools_ffmpeg_filter.c:556
OutputStream::resample_opts
AVDictionary * resample_opts
Definition: fftools_ffmpeg.h:533
InputFilter::height
int height
Definition: fftools_ffmpeg.h:270
OutputStream::filter
OutputFilter * filter
Definition: fftools_ffmpeg.h:525
GROW_ARRAY
#define GROW_ARRAY(array, nb_elems)
Definition: fftools_cmdutils.h:607
InputStream::sub2video::w
int w
Definition: fftools_ffmpeg.h:374
get_compliance_unofficial_pix_fmts
static enum AVPixelFormat * get_compliance_unofficial_pix_fmts(enum AVCodecID codec_id, const enum AVPixelFormat default_formats[])
Definition: fftools_ffmpeg_filter.c:50
sample_rate
sample_rate
Definition: fftools_ffmpeg_filter.c:199
FilterGraph::graph
AVFilterGraph * graph
Definition: fftools_ffmpeg.h:309
InputStream::user_set_discard
int user_set_discard
Definition: fftools_ffmpeg.h:322
describe_filter_link
static char * describe_filter_link(FilterGraph *fg, AVFilterInOut *inout, int in)
Definition: fftools_ffmpeg_filter.c:242
InputFilter::filter
AVFilterContext * filter
Definition: fftools_ffmpeg.h:259
InputStream::framerate
AVRational framerate
Definition: fftools_ffmpeg.h:356
FilterGraph::outputs
OutputFilter ** outputs
Definition: fftools_ffmpeg.h:314
FilterGraph::inputs
InputFilter ** inputs
Definition: fftools_ffmpeg.h:312
hw_device_ctx
__thread AVBufferRef * hw_device_ctx
Definition: fftools_ffmpeg_opt.c:96
OutputFilter::format
int format
Definition: fftools_ffmpeg.h:295
OutputStream::index
int index
Definition: fftools_ffmpeg.h:467
InputStream::st
AVStream * st
Definition: fftools_ffmpeg.h:320
InputFilter::eof
int eof
Definition: fftools_ffmpeg.h:279
OutputStream::keep_pix_fmt
int keep_pix_fmt
Definition: fftools_ffmpeg.h:551
InputStream::dec_ctx
AVCodecContext * dec_ctx
Definition: fftools_ffmpeg.h:327
configure_filtergraph
int configure_filtergraph(FilterGraph *fg)
Definition: fftools_ffmpeg_filter.c:1013
configure_input_video_filter
static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter, AVFilterInOut *in)
Definition: fftools_ffmpeg_filter.c:754
InputFile::ist_index
int ist_index
Definition: fftools_ffmpeg.h:420
sub2video_prepare
static int sub2video_prepare(InputStream *ist, InputFilter *ifilter)
Definition: fftools_ffmpeg_filter.c:713
GET_CH_LAYOUT_NAME
#define GET_CH_LAYOUT_NAME(ch_layout)
Definition: fftools_cmdutils.h:623
InputStream::decoding_needed
int decoding_needed
Definition: fftools_ffmpeg.h:323
InputFilter::format
int format
Definition: fftools_ffmpeg.h:268
OutputStream::frame_rate
AVRational frame_rate
Definition: fftools_ffmpeg.h:500
OutputFilter::sample_rate
int sample_rate
Definition: fftools_ffmpeg.h:296
OutputFilter::width
int width
Definition: fftools_ffmpeg.h:293
input_files
__thread InputFile ** input_files
Definition: fftools_ffmpeg.c:177
insert_trim
static int insert_trim(int64_t start_time, int64_t duration, AVFilterContext **last_filter, int *pad_idx, const char *filter_name)
Definition: fftools_ffmpeg_filter.c:389
configure_output_video_filter
static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out)
Definition: fftools_ffmpeg_filter.c:462
choose_pix_fmts
static char * choose_pix_fmts(OutputFilter *ofilter)
Definition: fftools_ffmpeg_filter.c:123
InputFilter::sample_rate
int sample_rate
Definition: fftools_ffmpeg.h:273
filtergraphs
__thread FilterGraph ** filtergraphs
Definition: fftools_ffmpeg.c:185
configure_input_audio_filter
static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter, AVFilterInOut *in)
Definition: fftools_ffmpeg_filter.c:877
sample_rates
sample_rates
Definition: fftools_ffmpeg_filter.c:199
DECODING_FOR_FILTER
#define DECODING_FOR_FILTER
Definition: fftools_ffmpeg.h:325
InputFile::start_time
int64_t start_time
Definition: fftools_ffmpeg.h:429
OutputStream::enc
AVCodec * enc
Definition: fftools_ffmpeg.h:490
OutputFilter::filter
AVFilterContext * filter
Definition: fftools_ffmpeg.h:283
OutputStream::st
AVStream * st
Definition: fftools_ffmpeg.h:469
check_filter_outputs
void check_filter_outputs(void)
Definition: fftools_ffmpeg_filter.c:698
InputStream::sub2video::frame
AVFrame * frame
Definition: fftools_ffmpeg.h:373
OutputFile
Definition: fftools_ffmpeg.h:577
nb_filtergraphs
__thread int nb_filtergraphs
Definition: fftools_ffmpeg.c:186
FilterGraph::reconfiguration
int reconfiguration
Definition: fftools_ffmpeg.h:310
choose_pixel_fmt
enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodecContext *enc_ctx, AVCodec *codec, enum AVPixelFormat target)
Definition: fftools_ffmpeg_filter.c:71
OutputStream::apad
char * apad
Definition: fftools_ffmpeg.h:534
ist_in_filtergraph
int ist_in_filtergraph(FilterGraph *fg, InputStream *ist)
Definition: fftools_ffmpeg_filter.c:1216
configure_input_filter
static int configure_input_filter(FilterGraph *fg, InputFilter *ifilter, AVFilterInOut *in)
Definition: fftools_ffmpeg_filter.c:987
get_rotation
double get_rotation(AVStream *st)
Definition: fftools_cmdutils.c:2227
InputFilter::channels
int channels
Definition: fftools_ffmpeg.h:274
OutputFilter::type
enum AVMediaType type
Definition: fftools_ffmpeg.h:290
input_streams
__thread InputStream ** input_streams
Definition: fftools_ffmpeg.c:175
InputStream::dec
AVCodec * dec
Definition: fftools_ffmpeg.h:328
OutputFilter::out_tmp
AVFilterInOut * out_tmp
Definition: fftools_ffmpeg.h:289
InputStream::filters
InputFilter ** filters
Definition: fftools_ffmpeg.h:381
audio_volume
__thread int audio_volume
Definition: fftools_ffmpeg_opt.c:106
choose_sample_fmt
void choose_sample_fmt(AVStream *st, AVCodec *codec)
Definition: fftools_ffmpeg_filter.c:101
OutputStream::enc_ctx
AVCodecContext * enc_ctx
Definition: fftools_ffmpeg.h:488
HWDevice::device_ref
AVBufferRef * device_ref
Definition: fftools_ffmpeg.h:100
InputStream::sub2video
struct InputStream::sub2video sub2video
start_at_zero
__thread int start_at_zero
Definition: fftools_ffmpeg_opt.c:116
InputStream::file_index
int file_index
Definition: fftools_ffmpeg.h:319
OutputFile::start_time
int64_t start_time
start time in microseconds == AV_TIME_BASE units
Definition: fftools_ffmpeg.h:582
OutputStream::audio_channels_map
int * audio_channels_map
Definition: fftools_ffmpeg.h:519
FilterGraph
Definition: fftools_ffmpeg.h:305
OutputStream
Definition: fftools_ffmpeg.h:465
InputFilter::width
int width
Definition: fftools_ffmpeg.h:270
OutputFilter::height
int height
Definition: fftools_ffmpeg.h:293
InputFilter::hw_frames_ctx
AVBufferRef * hw_frames_ctx
Definition: fftools_ffmpeg.h:277
cleanup_filtergraph
static void cleanup_filtergraph(FilterGraph *fg)
Definition: fftools_ffmpeg_filter.c:1003
GET_SAMPLE_RATE_NAME
#define GET_SAMPLE_RATE_NAME(rate)
Definition: fftools_cmdutils.h:619
filter_complex_nbthreads
__thread int filter_complex_nbthreads
Definition: fftools_ffmpeg_opt.c:127
OutputStream::encoder_opts
AVDictionary * encoder_opts
Definition: fftools_ffmpeg.h:530
OutputStream::swr_opts
AVDictionary * swr_opts
Definition: fftools_ffmpeg.h:532
OutputFilter::ost
struct OutputStream * ost
Definition: fftools_ffmpeg.h:284
InputFile::recording_time
int64_t recording_time
Definition: fftools_ffmpeg.h:431
sub2video_update
void sub2video_update(InputStream *ist, AVSubtitle *sub)
Definition: fftools_ffmpeg.c:326
copy_ts
__thread int copy_ts
Definition: fftools_ffmpeg_opt.c:115