2 * Copyright (c) 2011 Stefano Sabatini
4 * This file is part of FFmpeg.
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.
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.
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
26 #include "libavutil/audio_fifo.h"
27 #include "libavutil/avassert.h"
28 #include "libavutil/channel_layout.h"
29 #include "libavutil/common.h"
30 #include "libavutil/internal.h"
31 #include "libavutil/mathematics.h"
32 #include "libavutil/opt.h"
36 #include "buffersink.h"
39 typedef struct BufferSinkContext
{
41 AVFifoBuffer
*fifo
; ///< FIFO buffer of video frame references
42 unsigned warning_limit
;
44 /* only used for video */
45 enum AVPixelFormat
*pixel_fmts
; ///< list of accepted pixel formats, must be terminated with -1
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
52 int channel_layouts_size
;
53 int *channel_counts
; ///< list of accepted channel counts, terminated by -1
54 int channel_counts_size
;
55 int all_channel_counts
;
56 int *sample_rates
; ///< list of accepted sample rates, terminated by -1
57 int sample_rates_size
;
59 /* only used for compat API */
60 AVAudioFifo
*audio_fifo
; ///< FIFO for audio samples
61 int64_t next_pts
; ///< interpolating audio pts
64 #define NB_ITEMS(list) (list ## _size / sizeof(*list))
66 static av_cold
void uninit(AVFilterContext
*ctx
)
68 BufferSinkContext
*sink
= ctx
->priv
;
72 av_audio_fifo_free(sink
->audio_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
);
79 av_fifo_freep(&sink
->fifo
);
83 static int add_buffer_ref(AVFilterContext
*ctx
, AVFrame
*ref
)
85 BufferSinkContext
*buf
= ctx
->priv
;
87 if (av_fifo_space(buf
->fifo
) < sizeof(AVFilterBufferRef
*)) {
88 /* realloc fifo size */
89 if (av_fifo_realloc2(buf
->fifo
, av_fifo_size(buf
->fifo
) * 2) < 0) {
90 av_log(ctx
, AV_LOG_ERROR
,
91 "Cannot buffer more frames. Consume some available frames "
92 "before adding new ones.\n");
93 return AVERROR(ENOMEM
);
98 av_fifo_generic_write(buf
->fifo
, &ref
, sizeof(AVFilterBufferRef
*), NULL
);
102 static int filter_frame(AVFilterLink
*link
, AVFrame
*frame
)
104 AVFilterContext
*ctx
= link
->dst
;
105 BufferSinkContext
*buf
= link
->dst
->priv
;
108 if ((ret
= add_buffer_ref(ctx
, frame
)) < 0)
110 if (buf
->warning_limit
&&
111 av_fifo_size(buf
->fifo
) / sizeof(AVFilterBufferRef
*) >= buf
->warning_limit
) {
112 av_log(ctx
, AV_LOG_WARNING
,
113 "%d buffers queued in %s, something may be wrong.\n",
115 (char *)av_x_if_null(ctx
->name
, ctx
->filter
->name
));
116 buf
->warning_limit
*= 10;
121 int attribute_align_arg
av_buffersink_get_frame(AVFilterContext
*ctx
, AVFrame
*frame
)
123 return av_buffersink_get_frame_flags(ctx
, frame
, 0);
126 int attribute_align_arg
av_buffersink_get_frame_flags(AVFilterContext
*ctx
, AVFrame
*frame
, int flags
)
128 BufferSinkContext
*buf
= ctx
->priv
;
129 AVFilterLink
*inlink
= ctx
->inputs
[0];
133 /* no picref available, fetch it from the filterchain */
134 if (!av_fifo_size(buf
->fifo
)) {
135 if (flags
& AV_BUFFERSINK_FLAG_NO_REQUEST
)
136 return AVERROR(EAGAIN
);
137 if ((ret
= ff_request_frame(inlink
)) < 0)
141 if (!av_fifo_size(buf
->fifo
))
142 return AVERROR(EINVAL
);
144 if (flags
& AV_BUFFERSINK_FLAG_PEEK
) {
145 cur_frame
= *((AVFrame
**)av_fifo_peek2(buf
->fifo
, 0));
146 if ((ret
= av_frame_ref(frame
, cur_frame
)) < 0)
149 av_fifo_generic_read(buf
->fifo
, &cur_frame
, sizeof(cur_frame
), NULL
);
150 av_frame_move_ref(frame
, cur_frame
);
151 av_frame_free(&cur_frame
);
157 static int read_from_fifo(AVFilterContext
*ctx
, AVFrame
*frame
,
160 BufferSinkContext
*s
= ctx
->priv
;
161 AVFilterLink
*link
= ctx
->inputs
[0];
164 if (!(tmp
= ff_get_audio_buffer(link
, nb_samples
)))
165 return AVERROR(ENOMEM
);
166 av_audio_fifo_read(s
->audio_fifo
, (void**)tmp
->extended_data
, nb_samples
);
168 tmp
->pts
= s
->next_pts
;
169 if (s
->next_pts
!= AV_NOPTS_VALUE
)
170 s
->next_pts
+= av_rescale_q(nb_samples
, (AVRational
){1, link
->sample_rate
},
173 av_frame_move_ref(frame
, tmp
);
179 int attribute_align_arg
av_buffersink_get_samples(AVFilterContext
*ctx
,
180 AVFrame
*frame
, int nb_samples
)
182 BufferSinkContext
*s
= ctx
->priv
;
183 AVFilterLink
*link
= ctx
->inputs
[0];
187 if (!s
->audio_fifo
) {
188 int nb_channels
= link
->channels
;
189 if (!(s
->audio_fifo
= av_audio_fifo_alloc(link
->format
, nb_channels
, nb_samples
)))
190 return AVERROR(ENOMEM
);
194 if (av_audio_fifo_size(s
->audio_fifo
) >= nb_samples
)
195 return read_from_fifo(ctx
, frame
, nb_samples
);
197 if (!(cur_frame
= av_frame_alloc()))
198 return AVERROR(ENOMEM
);
199 ret
= av_buffersink_get_frame_flags(ctx
, cur_frame
, 0);
200 if (ret
== AVERROR_EOF
&& av_audio_fifo_size(s
->audio_fifo
)) {
201 av_frame_free(&cur_frame
);
202 return read_from_fifo(ctx
, frame
, av_audio_fifo_size(s
->audio_fifo
));
203 } else if (ret
< 0) {
204 av_frame_free(&cur_frame
);
208 if (cur_frame
->pts
!= AV_NOPTS_VALUE
) {
209 s
->next_pts
= cur_frame
->pts
-
210 av_rescale_q(av_audio_fifo_size(s
->audio_fifo
),
211 (AVRational
){ 1, link
->sample_rate
},
215 ret
= av_audio_fifo_write(s
->audio_fifo
, (void**)cur_frame
->extended_data
,
216 cur_frame
->nb_samples
);
217 av_frame_free(&cur_frame
);
223 AVBufferSinkParams
*av_buffersink_params_alloc(void)
225 static const int pixel_fmts
[] = { AV_PIX_FMT_NONE
};
226 AVBufferSinkParams
*params
= av_malloc(sizeof(AVBufferSinkParams
));
230 params
->pixel_fmts
= pixel_fmts
;
234 AVABufferSinkParams
*av_abuffersink_params_alloc(void)
236 AVABufferSinkParams
*params
= av_mallocz(sizeof(AVABufferSinkParams
));
243 #define FIFO_INIT_SIZE 8
245 static av_cold
int common_init(AVFilterContext
*ctx
)
247 BufferSinkContext
*buf
= ctx
->priv
;
249 buf
->fifo
= av_fifo_alloc_array(FIFO_INIT_SIZE
, sizeof(AVFilterBufferRef
*));
251 av_log(ctx
, AV_LOG_ERROR
, "Failed to allocate fifo\n");
252 return AVERROR(ENOMEM
);
254 buf
->warning_limit
= 100;
255 buf
->next_pts
= AV_NOPTS_VALUE
;
259 void av_buffersink_set_frame_size(AVFilterContext
*ctx
, unsigned frame_size
)
261 AVFilterLink
*inlink
= ctx
->inputs
[0];
263 inlink
->min_samples
= inlink
->max_samples
=
264 inlink
->partial_buf_size
= frame_size
;
267 #if FF_API_AVFILTERBUFFER
268 FF_DISABLE_DEPRECATION_WARNINGS
269 static void compat_free_buffer(AVFilterBuffer
*buf
)
271 AVFrame
*frame
= buf
->priv
;
272 av_frame_free(&frame
);
276 static int compat_read(AVFilterContext
*ctx
,
277 AVFilterBufferRef
**pbuf
, int nb_samples
, int flags
)
279 AVFilterBufferRef
*buf
;
284 return ff_poll_frame(ctx
->inputs
[0]);
286 frame
= av_frame_alloc();
288 return AVERROR(ENOMEM
);
291 ret
= av_buffersink_get_frame_flags(ctx
, frame
, flags
);
293 ret
= av_buffersink_get_samples(ctx
, frame
, nb_samples
);
298 AV_NOWARN_DEPRECATED(
299 if (ctx
->inputs
[0]->type
== AVMEDIA_TYPE_VIDEO
) {
300 buf
= avfilter_get_video_buffer_ref_from_arrays(frame
->data
, frame
->linesize
,
302 frame
->width
, frame
->height
,
305 buf
= avfilter_get_audio_buffer_ref_from_arrays(frame
->extended_data
,
306 frame
->linesize
[0], AV_PERM_READ
,
309 frame
->channel_layout
);
312 ret
= AVERROR(ENOMEM
);
316 avfilter_copy_frame_props(buf
, frame
);
319 buf
->buf
->priv
= frame
;
320 buf
->buf
->free
= compat_free_buffer
;
326 av_frame_free(&frame
);
330 int attribute_align_arg
av_buffersink_read(AVFilterContext
*ctx
, AVFilterBufferRef
**buf
)
332 return compat_read(ctx
, buf
, 0, 0);
335 int attribute_align_arg
av_buffersink_read_samples(AVFilterContext
*ctx
, AVFilterBufferRef
**buf
,
338 return compat_read(ctx
, buf
, nb_samples
, 0);
341 int attribute_align_arg
av_buffersink_get_buffer_ref(AVFilterContext
*ctx
,
342 AVFilterBufferRef
**bufref
, int flags
)
346 av_assert0( !strcmp(ctx
->filter
->name
, "buffersink")
347 || !strcmp(ctx
->filter
->name
, "abuffersink")
348 || !strcmp(ctx
->filter
->name
, "ffbuffersink")
349 || !strcmp(ctx
->filter
->name
, "ffabuffersink"));
351 return compat_read(ctx
, bufref
, 0, flags
);
353 FF_ENABLE_DEPRECATION_WARNINGS
356 AVRational
av_buffersink_get_frame_rate(AVFilterContext
*ctx
)
358 av_assert0( !strcmp(ctx
->filter
->name
, "buffersink")
359 || !strcmp(ctx
->filter
->name
, "ffbuffersink"));
361 return ctx
->inputs
[0]->frame_rate
;
364 int attribute_align_arg
av_buffersink_poll_frame(AVFilterContext
*ctx
)
366 BufferSinkContext
*buf
= ctx
->priv
;
367 AVFilterLink
*inlink
= ctx
->inputs
[0];
369 av_assert0( !strcmp(ctx
->filter
->name
, "buffersink")
370 || !strcmp(ctx
->filter
->name
, "abuffersink")
371 || !strcmp(ctx
->filter
->name
, "ffbuffersink")
372 || !strcmp(ctx
->filter
->name
, "ffabuffersink"));
374 return av_fifo_size(buf
->fifo
)/sizeof(AVFilterBufferRef
*) + ff_poll_frame(inlink
);
377 static av_cold
int vsink_init(AVFilterContext
*ctx
, void *opaque
)
379 BufferSinkContext
*buf
= ctx
->priv
;
380 AVBufferSinkParams
*params
= opaque
;
384 if ((ret
= av_opt_set_int_list(buf
, "pix_fmts", params
->pixel_fmts
, AV_PIX_FMT_NONE
, 0)) < 0)
388 return common_init(ctx
);
391 #define CHECK_LIST_SIZE(field) \
392 if (buf->field ## _size % sizeof(*buf->field)) { \
393 av_log(ctx, AV_LOG_ERROR, "Invalid size for " #field ": %d, " \
394 "should be multiple of %d\n", \
395 buf->field ## _size, (int)sizeof(*buf->field)); \
396 return AVERROR(EINVAL); \
398 static int vsink_query_formats(AVFilterContext
*ctx
)
400 BufferSinkContext
*buf
= ctx
->priv
;
401 AVFilterFormats
*formats
= NULL
;
405 CHECK_LIST_SIZE(pixel_fmts
)
406 if (buf
->pixel_fmts_size
) {
407 for (i
= 0; i
< NB_ITEMS(buf
->pixel_fmts
); i
++)
408 if ((ret
= ff_add_format(&formats
, buf
->pixel_fmts
[i
])) < 0) {
409 ff_formats_unref(&formats
);
412 ff_set_common_formats(ctx
, formats
);
414 ff_default_query_formats(ctx
);
420 static av_cold
int asink_init(AVFilterContext
*ctx
, void *opaque
)
422 BufferSinkContext
*buf
= ctx
->priv
;
423 AVABufferSinkParams
*params
= opaque
;
427 if ((ret
= av_opt_set_int_list(buf
, "sample_fmts", params
->sample_fmts
, AV_SAMPLE_FMT_NONE
, 0)) < 0 ||
428 (ret
= av_opt_set_int_list(buf
, "sample_rates", params
->sample_rates
, -1, 0)) < 0 ||
429 (ret
= av_opt_set_int_list(buf
, "channel_layouts", params
->channel_layouts
, -1, 0)) < 0 ||
430 (ret
= av_opt_set_int_list(buf
, "channel_counts", params
->channel_counts
, -1, 0)) < 0 ||
431 (ret
= av_opt_set_int(buf
, "all_channel_counts", params
->all_channel_counts
, 0)) < 0)
434 return common_init(ctx
);
437 static int asink_query_formats(AVFilterContext
*ctx
)
439 BufferSinkContext
*buf
= ctx
->priv
;
440 AVFilterFormats
*formats
= NULL
;
441 AVFilterChannelLayouts
*layouts
= NULL
;
445 CHECK_LIST_SIZE(sample_fmts
)
446 CHECK_LIST_SIZE(sample_rates
)
447 CHECK_LIST_SIZE(channel_layouts
)
448 CHECK_LIST_SIZE(channel_counts
)
450 if (buf
->sample_fmts_size
) {
451 for (i
= 0; i
< NB_ITEMS(buf
->sample_fmts
); i
++)
452 if ((ret
= ff_add_format(&formats
, buf
->sample_fmts
[i
])) < 0) {
453 ff_formats_unref(&formats
);
456 ff_set_common_formats(ctx
, formats
);
459 if (buf
->channel_layouts_size
|| buf
->channel_counts_size
||
460 buf
->all_channel_counts
) {
461 for (i
= 0; i
< NB_ITEMS(buf
->channel_layouts
); i
++)
462 if ((ret
= ff_add_channel_layout(&layouts
, buf
->channel_layouts
[i
])) < 0) {
463 ff_channel_layouts_unref(&layouts
);
466 for (i
= 0; i
< NB_ITEMS(buf
->channel_counts
); i
++)
467 if ((ret
= ff_add_channel_layout(&layouts
, FF_COUNT2LAYOUT(buf
->channel_counts
[i
]))) < 0) {
468 ff_channel_layouts_unref(&layouts
);
471 if (buf
->all_channel_counts
) {
473 av_log(ctx
, AV_LOG_WARNING
,
474 "Conflicting all_channel_counts and list in options\n");
475 else if (!(layouts
= ff_all_channel_counts()))
476 return AVERROR(ENOMEM
);
478 ff_set_common_channel_layouts(ctx
, layouts
);
481 if (buf
->sample_rates_size
) {
483 for (i
= 0; i
< NB_ITEMS(buf
->sample_rates
); i
++)
484 if ((ret
= ff_add_format(&formats
, buf
->sample_rates
[i
])) < 0) {
485 ff_formats_unref(&formats
);
488 ff_set_common_samplerates(ctx
, formats
);
494 #define OFFSET(x) offsetof(BufferSinkContext, x)
495 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
496 static const AVOption buffersink_options
[] = {
497 { "pix_fmts", "set the supported pixel formats", OFFSET(pixel_fmts
), AV_OPT_TYPE_BINARY
, .flags
= FLAGS
},
501 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
502 static const AVOption abuffersink_options
[] = {
503 { "sample_fmts", "set the supported sample formats", OFFSET(sample_fmts
), AV_OPT_TYPE_BINARY
, .flags
= FLAGS
},
504 { "sample_rates", "set the supported sample rates", OFFSET(sample_rates
), AV_OPT_TYPE_BINARY
, .flags
= FLAGS
},
505 { "channel_layouts", "set the supported channel layouts", OFFSET(channel_layouts
), AV_OPT_TYPE_BINARY
, .flags
= FLAGS
},
506 { "channel_counts", "set the supported channel counts", OFFSET(channel_counts
), AV_OPT_TYPE_BINARY
, .flags
= FLAGS
},
507 { "all_channel_counts", "accept all channel counts", OFFSET(all_channel_counts
), AV_OPT_TYPE_INT
, {.i64
= 0}, 0, 1, FLAGS
},
512 AVFILTER_DEFINE_CLASS(buffersink
);
513 AVFILTER_DEFINE_CLASS(abuffersink
);
515 #if FF_API_AVFILTERBUFFER
517 #define ffbuffersink_options buffersink_options
518 #define ffabuffersink_options abuffersink_options
519 AVFILTER_DEFINE_CLASS(ffbuffersink
);
520 AVFILTER_DEFINE_CLASS(ffabuffersink
);
522 static const AVFilterPad ffbuffersink_inputs
[] = {
525 .type
= AVMEDIA_TYPE_VIDEO
,
526 .filter_frame
= filter_frame
,
531 AVFilter ff_vsink_ffbuffersink
= {
532 .name
= "ffbuffersink",
533 .description
= NULL_IF_CONFIG_SMALL("Buffer video frames, and make them available to the end of the filter graph."),
534 .priv_size
= sizeof(BufferSinkContext
),
535 .priv_class
= &ffbuffersink_class
,
536 .init_opaque
= vsink_init
,
539 .query_formats
= vsink_query_formats
,
540 .inputs
= ffbuffersink_inputs
,
544 static const AVFilterPad ffabuffersink_inputs
[] = {
547 .type
= AVMEDIA_TYPE_AUDIO
,
548 .filter_frame
= filter_frame
,
553 AVFilter ff_asink_ffabuffersink
= {
554 .name
= "ffabuffersink",
555 .description
= NULL_IF_CONFIG_SMALL("Buffer audio frames, and make them available to the end of the filter graph."),
556 .init_opaque
= asink_init
,
558 .priv_size
= sizeof(BufferSinkContext
),
559 .priv_class
= &ffabuffersink_class
,
560 .query_formats
= asink_query_formats
,
561 .inputs
= ffabuffersink_inputs
,
564 #endif /* FF_API_AVFILTERBUFFER */
566 static const AVFilterPad avfilter_vsink_buffer_inputs
[] = {
569 .type
= AVMEDIA_TYPE_VIDEO
,
570 .filter_frame
= filter_frame
,
575 AVFilter ff_vsink_buffer
= {
576 .name
= "buffersink",
577 .description
= NULL_IF_CONFIG_SMALL("Buffer video frames, and make them available to the end of the filter graph."),
578 .priv_size
= sizeof(BufferSinkContext
),
579 .priv_class
= &buffersink_class
,
580 .init_opaque
= vsink_init
,
583 .query_formats
= vsink_query_formats
,
584 .inputs
= avfilter_vsink_buffer_inputs
,
588 static const AVFilterPad avfilter_asink_abuffer_inputs
[] = {
591 .type
= AVMEDIA_TYPE_AUDIO
,
592 .filter_frame
= filter_frame
,
597 AVFilter ff_asink_abuffer
= {
598 .name
= "abuffersink",
599 .description
= NULL_IF_CONFIG_SMALL("Buffer audio frames, and make them available to the end of the filter graph."),
600 .priv_class
= &abuffersink_class
,
601 .priv_size
= sizeof(BufferSinkContext
),
602 .init_opaque
= asink_init
,
605 .query_formats
= asink_query_formats
,
606 .inputs
= avfilter_asink_abuffer_inputs
,