FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
buffersink.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  * buffer sink
24  */
25 
26 #include "libavutil/audio_fifo.h"
27 #include "libavutil/avassert.h"
29 #include "libavutil/common.h"
30 #include "libavutil/internal.h"
31 #include "libavutil/mathematics.h"
32 #include "libavutil/opt.h"
33 
34 #include "audio.h"
35 #include "avfilter.h"
36 #include "buffersink.h"
37 #include "internal.h"
38 
39 typedef struct {
40  const AVClass *class;
41  AVFifoBuffer *fifo; ///< FIFO buffer of video frame references
42  unsigned warning_limit;
43 
44  /* only used for video */
45  enum AVPixelFormat *pixel_fmts; ///< list of accepted pixel formats, must be terminated with -1
47 
48  /* only used for audio */
49  enum AVSampleFormat *sample_fmts; ///< list of accepted sample formats, terminated by AV_SAMPLE_FMT_NONE
51  int64_t *channel_layouts; ///< list of accepted channel layouts, terminated by -1
53  int *channel_counts; ///< list of accepted channel counts, terminated by -1
56  int *sample_rates; ///< list of accepted sample rates, terminated by -1
58 
59  /* only used for compat API */
60  AVAudioFifo *audio_fifo; ///< FIFO for audio samples
61  int64_t next_pts; ///< interpolating audio pts
63 
64 #define NB_ITEMS(list) (list ## _size / sizeof(*list))
65 
66 static av_cold void uninit(AVFilterContext *ctx)
67 {
68  BufferSinkContext *sink = ctx->priv;
69  AVFrame *frame;
70 
71  if (sink->audio_fifo)
73 
74  if (sink->fifo) {
75  while (av_fifo_size(sink->fifo) >= sizeof(AVFilterBufferRef *)) {
76  av_fifo_generic_read(sink->fifo, &frame, sizeof(frame), NULL);
77  av_frame_free(&frame);
78  }
79  av_fifo_free(sink->fifo);
80  sink->fifo = NULL;
81  }
82 }
83 
84 static int add_buffer_ref(AVFilterContext *ctx, AVFrame *ref)
85 {
86  BufferSinkContext *buf = ctx->priv;
87 
88  if (av_fifo_space(buf->fifo) < sizeof(AVFilterBufferRef *)) {
89  /* realloc fifo size */
90  if (av_fifo_realloc2(buf->fifo, av_fifo_size(buf->fifo) * 2) < 0) {
91  av_log(ctx, AV_LOG_ERROR,
92  "Cannot buffer more frames. Consume some available frames "
93  "before adding new ones.\n");
94  return AVERROR(ENOMEM);
95  }
96  }
97 
98  /* cache frame */
99  av_fifo_generic_write(buf->fifo, &ref, sizeof(AVFilterBufferRef *), NULL);
100  return 0;
101 }
102 
104 {
105  AVFilterContext *ctx = link->dst;
106  BufferSinkContext *buf = link->dst->priv;
107  int ret;
108 
109  if ((ret = add_buffer_ref(ctx, frame)) < 0)
110  return ret;
111  if (buf->warning_limit &&
112  av_fifo_size(buf->fifo) / sizeof(AVFilterBufferRef *) >= buf->warning_limit) {
113  av_log(ctx, AV_LOG_WARNING,
114  "%d buffers queued in %s, something may be wrong.\n",
115  buf->warning_limit,
116  (char *)av_x_if_null(ctx->name, ctx->filter->name));
117  buf->warning_limit *= 10;
118  }
119  return 0;
120 }
121 
123 {
124  return av_buffersink_get_frame_flags(ctx, frame, 0);
125 }
126 
128 {
129  BufferSinkContext *buf = ctx->priv;
130  AVFilterLink *inlink = ctx->inputs[0];
131  int ret;
132  AVFrame *cur_frame;
133 
134  /* no picref available, fetch it from the filterchain */
135  if (!av_fifo_size(buf->fifo)) {
136  if (flags & AV_BUFFERSINK_FLAG_NO_REQUEST)
137  return AVERROR(EAGAIN);
138  if ((ret = ff_request_frame(inlink)) < 0)
139  return ret;
140  }
141 
142  if (!av_fifo_size(buf->fifo))
143  return AVERROR(EINVAL);
144 
145  if (flags & AV_BUFFERSINK_FLAG_PEEK) {
146  cur_frame = *((AVFrame **)av_fifo_peek2(buf->fifo, 0));
147  if ((ret = av_frame_ref(frame, cur_frame)) < 0)
148  return ret;
149  } else {
150  av_fifo_generic_read(buf->fifo, &cur_frame, sizeof(cur_frame), NULL);
151  av_frame_move_ref(frame, cur_frame);
152  av_frame_free(&cur_frame);
153  }
154 
155  return 0;
156 }
157 
159  int nb_samples)
160 {
161  BufferSinkContext *s = ctx->priv;
162  AVFilterLink *link = ctx->inputs[0];
163  AVFrame *tmp;
164 
165  if (!(tmp = ff_get_audio_buffer(link, nb_samples)))
166  return AVERROR(ENOMEM);
167  av_audio_fifo_read(s->audio_fifo, (void**)tmp->extended_data, nb_samples);
168 
169  tmp->pts = s->next_pts;
170  if (s->next_pts != AV_NOPTS_VALUE)
171  s->next_pts += av_rescale_q(nb_samples, (AVRational){1, link->sample_rate},
172  link->time_base);
173 
174  av_frame_move_ref(frame, tmp);
175  av_frame_free(&tmp);
176 
177  return 0;
178 }
179 
181  AVFrame *frame, int nb_samples)
182 {
183  BufferSinkContext *s = ctx->priv;
184  AVFilterLink *link = ctx->inputs[0];
185  AVFrame *cur_frame;
186  int ret = 0;
187 
188  if (!s->audio_fifo) {
189  int nb_channels = link->channels;
190  if (!(s->audio_fifo = av_audio_fifo_alloc(link->format, nb_channels, nb_samples)))
191  return AVERROR(ENOMEM);
192  }
193 
194  while (ret >= 0) {
195  if (av_audio_fifo_size(s->audio_fifo) >= nb_samples)
196  return read_from_fifo(ctx, frame, nb_samples);
197 
198  if (!(cur_frame = av_frame_alloc()))
199  return AVERROR(ENOMEM);
200  ret = av_buffersink_get_frame_flags(ctx, cur_frame, 0);
201  if (ret == AVERROR_EOF && av_audio_fifo_size(s->audio_fifo)) {
202  av_frame_free(&cur_frame);
203  return read_from_fifo(ctx, frame, av_audio_fifo_size(s->audio_fifo));
204  } else if (ret < 0) {
205  av_frame_free(&cur_frame);
206  return ret;
207  }
208 
209  if (cur_frame->pts != AV_NOPTS_VALUE) {
210  s->next_pts = cur_frame->pts -
212  (AVRational){ 1, link->sample_rate },
213  link->time_base);
214  }
215 
216  ret = av_audio_fifo_write(s->audio_fifo, (void**)cur_frame->extended_data,
217  cur_frame->nb_samples);
218  av_frame_free(&cur_frame);
219  }
220 
221  return ret;
222 }
223 
225 {
226  static const int pixel_fmts[] = { AV_PIX_FMT_NONE };
228  if (!params)
229  return NULL;
230 
231  params->pixel_fmts = pixel_fmts;
232  return params;
233 }
234 
236 {
238 
239  if (!params)
240  return NULL;
241  return params;
242 }
243 
244 #define FIFO_INIT_SIZE 8
245 
247 {
248  BufferSinkContext *buf = ctx->priv;
249 
250  buf->fifo = av_fifo_alloc(FIFO_INIT_SIZE*sizeof(AVFilterBufferRef *));
251  if (!buf->fifo) {
252  av_log(ctx, AV_LOG_ERROR, "Failed to allocate fifo\n");
253  return AVERROR(ENOMEM);
254  }
255  buf->warning_limit = 100;
256  buf->next_pts = AV_NOPTS_VALUE;
257  return 0;
258 }
259 
261 {
262  AVFilterLink *inlink = ctx->inputs[0];
263 
264  inlink->min_samples = inlink->max_samples =
265  inlink->partial_buf_size = frame_size;
266 }
267 
268 #if FF_API_AVFILTERBUFFER
270 static void compat_free_buffer(AVFilterBuffer *buf)
271 {
272  AVFrame *frame = buf->priv;
273  av_frame_free(&frame);
274  av_free(buf);
275 }
276 
277 static int compat_read(AVFilterContext *ctx,
278  AVFilterBufferRef **pbuf, int nb_samples, int flags)
279 {
280  AVFilterBufferRef *buf;
281  AVFrame *frame;
282  int ret;
283 
284  if (!pbuf)
285  return ff_poll_frame(ctx->inputs[0]);
286 
287  frame = av_frame_alloc();
288  if (!frame)
289  return AVERROR(ENOMEM);
290 
291  if (!nb_samples)
292  ret = av_buffersink_get_frame_flags(ctx, frame, flags);
293  else
294  ret = av_buffersink_get_samples(ctx, frame, nb_samples);
295 
296  if (ret < 0)
297  goto fail;
298 
300  if (ctx->inputs[0]->type == AVMEDIA_TYPE_VIDEO) {
302  AV_PERM_READ,
303  frame->width, frame->height,
304  frame->format);
305  } else {
306  buf = avfilter_get_audio_buffer_ref_from_arrays(frame->extended_data,
307  frame->linesize[0], AV_PERM_READ,
308  frame->nb_samples,
309  frame->format,
310  frame->channel_layout);
311  }
312  if (!buf) {
313  ret = AVERROR(ENOMEM);
314  goto fail;
315  }
316 
317  avfilter_copy_frame_props(buf, frame);
318  )
319 
320  buf->buf->priv = frame;
321  buf->buf->free = compat_free_buffer;
322 
323  *pbuf = buf;
324 
325  return 0;
326 fail:
327  av_frame_free(&frame);
328  return ret;
329 }
330 
331 int attribute_align_arg av_buffersink_read(AVFilterContext *ctx, AVFilterBufferRef **buf)
332 {
333  return compat_read(ctx, buf, 0, 0);
334 }
335 
336 int attribute_align_arg av_buffersink_read_samples(AVFilterContext *ctx, AVFilterBufferRef **buf,
337  int nb_samples)
338 {
339  return compat_read(ctx, buf, nb_samples, 0);
340 }
341 
342 int attribute_align_arg av_buffersink_get_buffer_ref(AVFilterContext *ctx,
343  AVFilterBufferRef **bufref, int flags)
344 {
345  *bufref = NULL;
346 
347  av_assert0( !strcmp(ctx->filter->name, "buffersink")
348  || !strcmp(ctx->filter->name, "abuffersink")
349  || !strcmp(ctx->filter->name, "ffbuffersink")
350  || !strcmp(ctx->filter->name, "ffabuffersink"));
351 
352  return compat_read(ctx, bufref, 0, flags);
353 }
355 #endif
356 
358 {
359  av_assert0( !strcmp(ctx->filter->name, "buffersink")
360  || !strcmp(ctx->filter->name, "ffbuffersink"));
361 
362  return ctx->inputs[0]->frame_rate;
363 }
364 
366 {
367  BufferSinkContext *buf = ctx->priv;
368  AVFilterLink *inlink = ctx->inputs[0];
369 
370  av_assert0( !strcmp(ctx->filter->name, "buffersink")
371  || !strcmp(ctx->filter->name, "abuffersink")
372  || !strcmp(ctx->filter->name, "ffbuffersink")
373  || !strcmp(ctx->filter->name, "ffabuffersink"));
374 
375  return av_fifo_size(buf->fifo)/sizeof(AVFilterBufferRef *) + ff_poll_frame(inlink);
376 }
377 
378 static av_cold int vsink_init(AVFilterContext *ctx, void *opaque)
379 {
380  BufferSinkContext *buf = ctx->priv;
381  AVBufferSinkParams *params = opaque;
382  int ret;
383 
384  if (params) {
385  if ((ret = av_opt_set_int_list(buf, "pix_fmts", params->pixel_fmts, AV_PIX_FMT_NONE, 0)) < 0)
386  return ret;
387  }
388 
389  return common_init(ctx);
390 }
391 
392 #define CHECK_LIST_SIZE(field) \
393  if (buf->field ## _size % sizeof(*buf->field)) { \
394  av_log(ctx, AV_LOG_ERROR, "Invalid size for " #field ": %d, " \
395  "should be multiple of %d\n", \
396  buf->field ## _size, (int)sizeof(*buf->field)); \
397  return AVERROR(EINVAL); \
398  }
400 {
401  BufferSinkContext *buf = ctx->priv;
402  AVFilterFormats *formats = NULL;
403  unsigned i;
404  int ret;
405 
406  CHECK_LIST_SIZE(pixel_fmts)
407  if (buf->pixel_fmts_size) {
408  for (i = 0; i < NB_ITEMS(buf->pixel_fmts); i++)
409  if ((ret = ff_add_format(&formats, buf->pixel_fmts[i])) < 0) {
410  ff_formats_unref(&formats);
411  return ret;
412  }
413  ff_set_common_formats(ctx, formats);
414  } else {
416  }
417 
418  return 0;
419 }
420 
421 static av_cold int asink_init(AVFilterContext *ctx, void *opaque)
422 {
423  BufferSinkContext *buf = ctx->priv;
424  AVABufferSinkParams *params = opaque;
425  int ret;
426 
427  if (params) {
428  if ((ret = av_opt_set_int_list(buf, "sample_fmts", params->sample_fmts, AV_SAMPLE_FMT_NONE, 0)) < 0 ||
429  (ret = av_opt_set_int_list(buf, "sample_rates", params->sample_rates, -1, 0)) < 0 ||
430  (ret = av_opt_set_int_list(buf, "channel_layouts", params->channel_layouts, -1, 0)) < 0 ||
431  (ret = av_opt_set_int_list(buf, "channel_counts", params->channel_counts, -1, 0)) < 0 ||
432  (ret = av_opt_set_int(buf, "all_channel_counts", params->all_channel_counts, 0)) < 0)
433  return ret;
434  }
435  return common_init(ctx);
436 }
437 
439 {
440  BufferSinkContext *buf = ctx->priv;
441  AVFilterFormats *formats = NULL;
443  unsigned i;
444  int ret;
445 
448  CHECK_LIST_SIZE(channel_layouts)
449  CHECK_LIST_SIZE(channel_counts)
450 
451  if (buf->sample_fmts_size) {
452  for (i = 0; i < NB_ITEMS(buf->sample_fmts); i++)
453  if ((ret = ff_add_format(&formats, buf->sample_fmts[i])) < 0) {
454  ff_formats_unref(&formats);
455  return ret;
456  }
457  ff_set_common_formats(ctx, formats);
458  }
459 
460  if (buf->channel_layouts_size || buf->channel_counts_size ||
461  buf->all_channel_counts) {
462  for (i = 0; i < NB_ITEMS(buf->channel_layouts); i++)
463  if ((ret = ff_add_channel_layout(&layouts, buf->channel_layouts[i])) < 0) {
464  ff_channel_layouts_unref(&layouts);
465  return ret;
466  }
467  for (i = 0; i < NB_ITEMS(buf->channel_counts); i++)
468  if ((ret = ff_add_channel_layout(&layouts, FF_COUNT2LAYOUT(buf->channel_counts[i]))) < 0) {
469  ff_channel_layouts_unref(&layouts);
470  return ret;
471  }
472  if (buf->all_channel_counts) {
473  if (layouts)
474  av_log(ctx, AV_LOG_WARNING,
475  "Conflicting all_channel_counts and list in options\n");
476  else if (!(layouts = ff_all_channel_counts()))
477  return AVERROR(ENOMEM);
478  }
479  ff_set_common_channel_layouts(ctx, layouts);
480  }
481 
482  if (buf->sample_rates_size) {
483  formats = NULL;
484  for (i = 0; i < NB_ITEMS(buf->sample_rates); i++)
485  if ((ret = ff_add_format(&formats, buf->sample_rates[i])) < 0) {
486  ff_formats_unref(&formats);
487  return ret;
488  }
489  ff_set_common_samplerates(ctx, formats);
490  }
491 
492  return 0;
493 }
494 
495 #define OFFSET(x) offsetof(BufferSinkContext, x)
496 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
497 static const AVOption buffersink_options[] = {
498  { "pix_fmts", "set the supported pixel formats", OFFSET(pixel_fmts), AV_OPT_TYPE_BINARY, .flags = FLAGS },
499  { NULL },
500 };
501 #undef FLAGS
502 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
503 static const AVOption abuffersink_options[] = {
504  { "sample_fmts", "set the supported sample formats", OFFSET(sample_fmts), AV_OPT_TYPE_BINARY, .flags = FLAGS },
505  { "sample_rates", "set the supported sample rates", OFFSET(sample_rates), AV_OPT_TYPE_BINARY, .flags = FLAGS },
506  { "channel_layouts", "set the supported channel layouts", OFFSET(channel_layouts), AV_OPT_TYPE_BINARY, .flags = FLAGS },
507  { "channel_counts", "set the supported channel counts", OFFSET(channel_counts), AV_OPT_TYPE_BINARY, .flags = FLAGS },
508  { "all_channel_counts", "accept all channel counts", OFFSET(all_channel_counts), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, FLAGS },
509  { NULL },
510 };
511 #undef FLAGS
512 
513 AVFILTER_DEFINE_CLASS(buffersink);
514 AVFILTER_DEFINE_CLASS(abuffersink);
515 
516 #if FF_API_AVFILTERBUFFER
517 
518 #define ffbuffersink_options buffersink_options
519 #define ffabuffersink_options abuffersink_options
520 AVFILTER_DEFINE_CLASS(ffbuffersink);
521 AVFILTER_DEFINE_CLASS(ffabuffersink);
522 
523 static const AVFilterPad ffbuffersink_inputs[] = {
524  {
525  .name = "default",
526  .type = AVMEDIA_TYPE_VIDEO,
527  .filter_frame = filter_frame,
528  },
529  { NULL },
530 };
531 
532 AVFilter avfilter_vsink_ffbuffersink = {
533  .name = "ffbuffersink",
534  .description = NULL_IF_CONFIG_SMALL("Buffer video frames, and make them available to the end of the filter graph."),
535  .priv_size = sizeof(BufferSinkContext),
536  .priv_class = &ffbuffersink_class,
537  .init_opaque = vsink_init,
538  .uninit = uninit,
539 
541  .inputs = ffbuffersink_inputs,
542  .outputs = NULL,
543 };
544 
545 static const AVFilterPad ffabuffersink_inputs[] = {
546  {
547  .name = "default",
548  .type = AVMEDIA_TYPE_AUDIO,
549  .filter_frame = filter_frame,
550  },
551  { NULL },
552 };
553 
554 AVFilter avfilter_asink_ffabuffersink = {
555  .name = "ffabuffersink",
556  .description = NULL_IF_CONFIG_SMALL("Buffer audio frames, and make them available to the end of the filter graph."),
557  .init_opaque = asink_init,
558  .uninit = uninit,
559  .priv_size = sizeof(BufferSinkContext),
560  .priv_class = &ffabuffersink_class,
562  .inputs = ffabuffersink_inputs,
563  .outputs = NULL,
564 };
565 #endif /* FF_API_AVFILTERBUFFER */
566 
568  {
569  .name = "default",
570  .type = AVMEDIA_TYPE_VIDEO,
571  .filter_frame = filter_frame,
572  },
573  { NULL }
574 };
575 
577  .name = "buffersink",
578  .description = NULL_IF_CONFIG_SMALL("Buffer video frames, and make them available to the end of the filter graph."),
579  .priv_size = sizeof(BufferSinkContext),
580  .priv_class = &buffersink_class,
581  .init_opaque = vsink_init,
582  .uninit = uninit,
583 
585  .inputs = avfilter_vsink_buffer_inputs,
586  .outputs = NULL,
587 };
588 
590  {
591  .name = "default",
592  .type = AVMEDIA_TYPE_AUDIO,
593  .filter_frame = filter_frame,
594  },
595  { NULL }
596 };
597 
599  .name = "abuffersink",
600  .description = NULL_IF_CONFIG_SMALL("Buffer audio frames, and make them available to the end of the filter graph."),
601  .priv_class = &abuffersink_class,
602  .priv_size = sizeof(BufferSinkContext),
603  .init_opaque = asink_init,
604  .uninit = uninit,
605 
607  .inputs = avfilter_asink_abuffer_inputs,
608  .outputs = NULL,
609 };