FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
lavfi.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011 Stefano Sabatini
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  * @file
23  * libavfilter virtual input device
24  */
25 
26 /* #define DEBUG */
27 
28 #include <float.h> /* DBL_MIN, DBL_MAX */
29 
30 #include "libavutil/bprint.h"
32 #include "libavutil/file.h"
33 #include "libavutil/log.h"
34 #include "libavutil/mem.h"
35 #include "libavutil/opt.h"
36 #include "libavutil/parseutils.h"
37 #include "libavutil/pixdesc.h"
38 #include "libavfilter/avfilter.h"
40 #include "libavfilter/buffersink.h"
41 #include "libavformat/internal.h"
42 #include "avdevice.h"
43 
44 typedef struct {
45  AVClass *class; ///< class for private options
46  char *graph_str;
48  char *dump_graph;
52  int *sink_eof;
56  int nb_sinks;
58 } LavfiContext;
59 
60 static int *create_all_formats(int n)
61 {
62  int i, j, *fmts, count = 0;
63 
64  for (i = 0; i < n; i++) {
65  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(i);
66  if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL))
67  count++;
68  }
69 
70  if (!(fmts = av_malloc((count+1) * sizeof(int))))
71  return NULL;
72  for (j = 0, i = 0; i < n; i++) {
73  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(i);
74  if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL))
75  fmts[j++] = i;
76  }
77  fmts[j] = -1;
78  return fmts;
79 }
80 
82 {
83  LavfiContext *lavfi = avctx->priv_data;
84 
85  av_freep(&lavfi->sink_stream_map);
86  av_freep(&lavfi->sink_eof);
87  av_freep(&lavfi->stream_sink_map);
89  av_freep(&lavfi->sinks);
90  avfilter_graph_free(&lavfi->graph);
92 
93  return 0;
94 }
95 
97 {
98  LavfiContext *lavfi = avctx->priv_data;
99  AVStream *st;
100  int stream_idx, sink_idx;
101 
102  for (stream_idx = 0; stream_idx < lavfi->nb_sinks; stream_idx++) {
103  sink_idx = lavfi->stream_sink_map[stream_idx];
104  if (lavfi->sink_stream_subcc_map[sink_idx]) {
105  lavfi->sink_stream_subcc_map[sink_idx] = avctx->nb_streams;
106  if (!(st = avformat_new_stream(avctx, NULL)))
107  return AVERROR(ENOMEM);
110  } else {
111  lavfi->sink_stream_subcc_map[sink_idx] = -1;
112  }
113  }
114  return 0;
115 }
116 
118 {
119  LavfiContext *lavfi = avctx->priv_data;
120  AVFilterInOut *input_links = NULL, *output_links = NULL, *inout;
121  AVFilter *buffersink, *abuffersink;
122  int *pix_fmts = create_all_formats(AV_PIX_FMT_NB);
123  enum AVMediaType type;
124  int ret = 0, i, n;
125 
126 #define FAIL(ERR) { ret = ERR; goto end; }
127 
128  if (!pix_fmts)
129  FAIL(AVERROR(ENOMEM));
130 
132 
133  buffersink = avfilter_get_by_name("buffersink");
134  abuffersink = avfilter_get_by_name("abuffersink");
135 
136  if (lavfi->graph_filename && lavfi->graph_str) {
137  av_log(avctx, AV_LOG_ERROR,
138  "Only one of the graph or graph_file options must be specified\n");
139  FAIL(AVERROR(EINVAL));
140  }
141 
142  if (lavfi->graph_filename) {
143  AVBPrint graph_file_pb;
144  AVIOContext *avio = NULL;
145  ret = avio_open(&avio, lavfi->graph_filename, AVIO_FLAG_READ);
146  if (ret < 0)
147  goto end;
148  av_bprint_init(&graph_file_pb, 0, AV_BPRINT_SIZE_UNLIMITED);
149  ret = avio_read_to_bprint(avio, &graph_file_pb, INT_MAX);
150  avio_closep(&avio);
151  av_bprint_chars(&graph_file_pb, '\0', 1);
152  if (!ret && !av_bprint_is_complete(&graph_file_pb))
153  ret = AVERROR(ENOMEM);
154  if (ret) {
155  av_bprint_finalize(&graph_file_pb, NULL);
156  goto end;
157  }
158  if ((ret = av_bprint_finalize(&graph_file_pb, &lavfi->graph_str)))
159  goto end;
160  }
161 
162  if (!lavfi->graph_str)
163  lavfi->graph_str = av_strdup(avctx->filename);
164 
165  /* parse the graph, create a stream for each open output */
166  if (!(lavfi->graph = avfilter_graph_alloc()))
167  FAIL(AVERROR(ENOMEM));
168 
169  if ((ret = avfilter_graph_parse_ptr(lavfi->graph, lavfi->graph_str,
170  &input_links, &output_links, avctx)) < 0)
171  goto end;
172 
173  if (input_links) {
174  av_log(avctx, AV_LOG_ERROR,
175  "Open inputs in the filtergraph are not acceptable\n");
176  FAIL(AVERROR(EINVAL));
177  }
178 
179  /* count the outputs */
180  for (n = 0, inout = output_links; inout; n++, inout = inout->next);
181  lavfi->nb_sinks = n;
182 
183  if (!(lavfi->sink_stream_map = av_malloc(sizeof(int) * n)))
184  FAIL(AVERROR(ENOMEM));
185  if (!(lavfi->sink_eof = av_mallocz(sizeof(int) * n)))
186  FAIL(AVERROR(ENOMEM));
187  if (!(lavfi->stream_sink_map = av_malloc(sizeof(int) * n)))
188  FAIL(AVERROR(ENOMEM));
189  if (!(lavfi->sink_stream_subcc_map = av_malloc(sizeof(int) * n)))
190  FAIL(AVERROR(ENOMEM));
191 
192  for (i = 0; i < n; i++)
193  lavfi->stream_sink_map[i] = -1;
194 
195  /* parse the output link names - they need to be of the form out0, out1, ...
196  * create a mapping between them and the streams */
197  for (i = 0, inout = output_links; inout; i++, inout = inout->next) {
198  int stream_idx = 0, suffix = 0, use_subcc = 0;
199  sscanf(inout->name, "out%n%d%n", &suffix, &stream_idx, &suffix);
200  if (!suffix) {
201  av_log(avctx, AV_LOG_ERROR,
202  "Invalid outpad name '%s'\n", inout->name);
203  FAIL(AVERROR(EINVAL));
204  }
205  if (inout->name[suffix]) {
206  if (!strcmp(inout->name + suffix, "+subcc")) {
207  use_subcc = 1;
208  } else {
209  av_log(avctx, AV_LOG_ERROR,
210  "Invalid outpad suffix '%s'\n", inout->name);
211  FAIL(AVERROR(EINVAL));
212  }
213  }
214 
215  if ((unsigned)stream_idx >= n) {
216  av_log(avctx, AV_LOG_ERROR,
217  "Invalid index was specified in output '%s', "
218  "must be a non-negative value < %d\n",
219  inout->name, n);
220  FAIL(AVERROR(EINVAL));
221  }
222 
223  if (lavfi->stream_sink_map[stream_idx] != -1) {
224  av_log(avctx, AV_LOG_ERROR,
225  "An output with stream index %d was already specified\n",
226  stream_idx);
227  FAIL(AVERROR(EINVAL));
228  }
229  lavfi->sink_stream_map[i] = stream_idx;
230  lavfi->stream_sink_map[stream_idx] = i;
231  lavfi->sink_stream_subcc_map[i] = !!use_subcc;
232  }
233 
234  /* for each open output create a corresponding stream */
235  for (i = 0, inout = output_links; inout; i++, inout = inout->next) {
236  AVStream *st;
237  if (!(st = avformat_new_stream(avctx, NULL)))
238  FAIL(AVERROR(ENOMEM));
239  st->id = i;
240  }
241 
242  /* create a sink for each output and connect them to the graph */
243  lavfi->sinks = av_malloc_array(lavfi->nb_sinks, sizeof(AVFilterContext *));
244  if (!lavfi->sinks)
245  FAIL(AVERROR(ENOMEM));
246 
247  for (i = 0, inout = output_links; inout; i++, inout = inout->next) {
248  AVFilterContext *sink;
249 
250  type = inout->filter_ctx->output_pads[inout->pad_idx].type;
251 
252  if (type == AVMEDIA_TYPE_VIDEO && ! buffersink ||
253  type == AVMEDIA_TYPE_AUDIO && ! abuffersink) {
254  av_log(avctx, AV_LOG_ERROR, "Missing required buffersink filter, aborting.\n");
256  }
257 
258  if (type == AVMEDIA_TYPE_VIDEO) {
259  ret = avfilter_graph_create_filter(&sink, buffersink,
260  inout->name, NULL,
261  NULL, lavfi->graph);
262  if (ret >= 0)
263  ret = av_opt_set_int_list(sink, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN);
264  if (ret < 0)
265  goto end;
266  } else if (type == AVMEDIA_TYPE_AUDIO) {
271  AV_SAMPLE_FMT_DBL, -1 };
272 
273  ret = avfilter_graph_create_filter(&sink, abuffersink,
274  inout->name, NULL,
275  NULL, lavfi->graph);
276  if (ret >= 0)
277  ret = av_opt_set_int_list(sink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN);
278  if (ret < 0)
279  goto end;
280  ret = av_opt_set_int(sink, "all_channel_counts", 1,
282  if (ret < 0)
283  goto end;
284  } else {
285  av_log(avctx, AV_LOG_ERROR,
286  "Output '%s' is not a video or audio output, not yet supported\n", inout->name);
287  FAIL(AVERROR(EINVAL));
288  }
289 
290  lavfi->sinks[i] = sink;
291  if ((ret = avfilter_link(inout->filter_ctx, inout->pad_idx, sink, 0)) < 0)
292  goto end;
293  }
294 
295  /* configure the graph */
296  if ((ret = avfilter_graph_config(lavfi->graph, avctx)) < 0)
297  goto end;
298 
299  if (lavfi->dump_graph) {
300  char *dump = avfilter_graph_dump(lavfi->graph, lavfi->dump_graph);
301  fputs(dump, stderr);
302  fflush(stderr);
303  av_free(dump);
304  }
305 
306  /* fill each stream with the information in the corresponding sink */
307  for (i = 0; i < lavfi->nb_sinks; i++) {
308  AVFilterLink *link = lavfi->sinks[lavfi->stream_sink_map[i]]->inputs[0];
309  AVStream *st = avctx->streams[i];
310  st->codec->codec_type = link->type;
311  avpriv_set_pts_info(st, 64, link->time_base.num, link->time_base.den);
312  if (link->type == AVMEDIA_TYPE_VIDEO) {
314  st->codec->pix_fmt = link->format;
315  st->codec->time_base = link->time_base;
316  st->codec->width = link->w;
317  st->codec->height = link->h;
318  st ->sample_aspect_ratio =
320  avctx->probesize = FFMAX(avctx->probesize,
321  link->w * link->h *
323  30);
324  } else if (link->type == AVMEDIA_TYPE_AUDIO) {
325  st->codec->codec_id = av_get_pcm_codec(link->format, -1);
327  st->codec->sample_fmt = link->format;
328  st->codec->sample_rate = link->sample_rate;
329  st->codec->time_base = link->time_base;
330  st->codec->channel_layout = link->channel_layout;
331  if (st->codec->codec_id == AV_CODEC_ID_NONE)
332  av_log(avctx, AV_LOG_ERROR,
333  "Could not find PCM codec for sample format %s.\n",
335  }
336  }
337 
338  if ((ret = create_subcc_streams(avctx)) < 0)
339  FAIL(ret);
340 
341  if (!(lavfi->decoded_frame = av_frame_alloc()))
342  FAIL(AVERROR(ENOMEM));
343 
344 end:
345  av_free(pix_fmts);
346  avfilter_inout_free(&input_links);
347  avfilter_inout_free(&output_links);
348  if (ret < 0)
349  lavfi_read_close(avctx);
350  return ret;
351 }
352 
354  int sink_idx)
355 {
356  LavfiContext *lavfi = avctx->priv_data;
357  AVFrameSideData *sd;
358  int stream_idx, i, ret;
359 
360  if ((stream_idx = lavfi->sink_stream_subcc_map[sink_idx]) < 0)
361  return 0;
362  for (i = 0; i < frame->nb_side_data; i++)
363  if (frame->side_data[i]->type == AV_FRAME_DATA_A53_CC)
364  break;
365  if (i >= frame->nb_side_data)
366  return 0;
367  sd = frame->side_data[i];
368  if ((ret = av_new_packet(&lavfi->subcc_packet, sd->size)) < 0)
369  return ret;
370  memcpy(lavfi->subcc_packet.data, sd->data, sd->size);
371  lavfi->subcc_packet.stream_index = stream_idx;
372  lavfi->subcc_packet.pts = frame->pts;
373  lavfi->subcc_packet.pos = av_frame_get_pkt_pos(frame);
374  return 0;
375 }
376 
378 {
379  LavfiContext *lavfi = avctx->priv_data;
380  double min_pts = DBL_MAX;
381  int stream_idx, min_pts_sink_idx = 0;
382  AVFrame *frame = lavfi->decoded_frame;
383  AVPicture pict;
384  AVDictionary *frame_metadata;
385  int ret, i;
386  int size = 0;
387 
388  if (lavfi->subcc_packet.size) {
389  *pkt = lavfi->subcc_packet;
390  av_init_packet(&lavfi->subcc_packet);
391  lavfi->subcc_packet.size = 0;
392  lavfi->subcc_packet.data = NULL;
393  return pkt->size;
394  }
395 
396  /* iterate through all the graph sinks. Select the sink with the
397  * minimum PTS */
398  for (i = 0; i < lavfi->nb_sinks; i++) {
399  AVRational tb = lavfi->sinks[i]->inputs[0]->time_base;
400  double d;
401  int ret;
402 
403  if (lavfi->sink_eof[i])
404  continue;
405 
406  ret = av_buffersink_get_frame_flags(lavfi->sinks[i], frame,
408  if (ret == AVERROR_EOF) {
409  av_dlog(avctx, "EOF sink_idx:%d\n", i);
410  lavfi->sink_eof[i] = 1;
411  continue;
412  } else if (ret < 0)
413  return ret;
414  d = av_rescale_q(frame->pts, tb, AV_TIME_BASE_Q);
415  av_dlog(avctx, "sink_idx:%d time:%f\n", i, d);
416  av_frame_unref(frame);
417 
418  if (d < min_pts) {
419  min_pts = d;
420  min_pts_sink_idx = i;
421  }
422  }
423  if (min_pts == DBL_MAX)
424  return AVERROR_EOF;
425 
426  av_dlog(avctx, "min_pts_sink_idx:%i\n", min_pts_sink_idx);
427 
428  av_buffersink_get_frame_flags(lavfi->sinks[min_pts_sink_idx], frame, 0);
429  stream_idx = lavfi->sink_stream_map[min_pts_sink_idx];
430 
431  if (frame->width /* FIXME best way of testing a video */) {
432  size = avpicture_get_size(frame->format, frame->width, frame->height);
433  if ((ret = av_new_packet(pkt, size)) < 0)
434  return ret;
435 
436  memcpy(pict.data, frame->data, 4*sizeof(frame->data[0]));
437  memcpy(pict.linesize, frame->linesize, 4*sizeof(frame->linesize[0]));
438 
439  avpicture_layout(&pict, frame->format, frame->width, frame->height,
440  pkt->data, size);
441  } else if (av_frame_get_channels(frame) /* FIXME test audio */) {
442  size = frame->nb_samples * av_get_bytes_per_sample(frame->format) *
443  av_frame_get_channels(frame);
444  if ((ret = av_new_packet(pkt, size)) < 0)
445  return ret;
446  memcpy(pkt->data, frame->data[0], size);
447  }
448 
449  frame_metadata = av_frame_get_metadata(frame);
450  if (frame_metadata) {
451  uint8_t *metadata;
452  AVDictionaryEntry *e = NULL;
453  AVBPrint meta_buf;
454 
456  while ((e = av_dict_get(frame_metadata, "", e, AV_DICT_IGNORE_SUFFIX))) {
457  av_bprintf(&meta_buf, "%s", e->key);
458  av_bprint_chars(&meta_buf, '\0', 1);
459  av_bprintf(&meta_buf, "%s", e->value);
460  av_bprint_chars(&meta_buf, '\0', 1);
461  }
462  if (!av_bprint_is_complete(&meta_buf) ||
464  meta_buf.len))) {
465  av_bprint_finalize(&meta_buf, NULL);
466  return AVERROR(ENOMEM);
467  }
468  memcpy(metadata, meta_buf.str, meta_buf.len);
469  av_bprint_finalize(&meta_buf, NULL);
470  }
471 
472  if ((ret = create_subcc_packet(avctx, frame, min_pts_sink_idx)) < 0) {
473  av_frame_unref(frame);
474  av_packet_unref(pkt);
475  return ret;
476  }
477 
478  pkt->stream_index = stream_idx;
479  pkt->pts = frame->pts;
480  pkt->pos = av_frame_get_pkt_pos(frame);
481  pkt->size = size;
482  av_frame_unref(frame);
483  return size;
484 }
485 
486 #define OFFSET(x) offsetof(LavfiContext, x)
487 
488 #define DEC AV_OPT_FLAG_DECODING_PARAM
489 
490 static const AVOption options[] = {
491  { "graph", "set libavfilter graph", OFFSET(graph_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
492  { "graph_file","set libavfilter graph filename", OFFSET(graph_filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC},
493  { "dumpgraph", "dump graph to stderr", OFFSET(dump_graph), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
494  { NULL },
495 };
496 
497 static const AVClass lavfi_class = {
498  .class_name = "lavfi indev",
499  .item_name = av_default_item_name,
500  .option = options,
501  .version = LIBAVUTIL_VERSION_INT,
502  .category = AV_CLASS_CATEGORY_DEVICE_INPUT,
503 };
504 
506  .name = "lavfi",
507  .long_name = NULL_IF_CONFIG_SMALL("Libavfilter virtual input device"),
508  .priv_data_size = sizeof(LavfiContext),
512  .flags = AVFMT_NOFILE,
513  .priv_class = &lavfi_class,
514 };