FFmpeg
Loading...
Searching...
No Matches
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/avassert.h"
27#include "libavutil/avstring.h"
29#include "libavutil/common.h"
30#include "libavutil/internal.h"
31#include "libavutil/mem.h"
32#include "libavutil/opt.h"
33
34#include "audio.h"
35#include "avfilter.h"
36#include "avfilter_internal.h"
37#include "buffersink.h"
38#include "filters.h"
39#include "formats.h"
40#include "framequeue.h"
41#include "video.h"
42
43typedef struct BufferSinkContext {
44 const AVClass *class;
45 unsigned warning_limit;
46 unsigned frame_size;
47
48 /* only used for video */
51
54
57
59 unsigned nb_alphamodes;
60
61 /* only used for audio */
64
67
70
73
78
80{
82 buf->peeked_frame = in;
83 return out ? av_frame_ref(out, in) : 0;
84 } else {
86 buf->peeked_frame = NULL;
88 av_frame_free(&in);
89 return 0;
90 }
91}
92
93static int get_frame_internal(AVFilterContext *ctx, AVFrame *frame, int flags, int samples)
94{
95 BufferSinkContext *buf = ctx->priv;
96 AVFilterLink *inlink = ctx->inputs[0];
98 int status, ret;
99 AVFrame *cur_frame;
100 int64_t pts;
101 int buffersrc_empty = 0;
102
103 if (buf->peeked_frame)
104 return return_or_keep_frame(buf, frame, buf->peeked_frame, flags);
105
106 while (1) {
107 ret = samples ? ff_inlink_consume_samples(inlink, samples, samples, &cur_frame) :
108 ff_inlink_consume_frame(inlink, &cur_frame);
109 if (ret < 0) {
110 return ret;
111 } else if (ret) {
112 /* TODO return the frame instead of copying it */
113 return return_or_keep_frame(buf, frame, cur_frame, flags);
114 } else if (ff_inlink_acknowledge_status(inlink, &status, &pts)) {
115 return status;
116 } else if ((flags & AV_BUFFERSINK_FLAG_NO_REQUEST)) {
117 return AVERROR(EAGAIN);
118 } else if (li->frame_wanted_out) {
119 ret = ff_filter_graph_run_once(ctx->graph);
120 if (ret == FFERROR_BUFFERSRC_EMPTY) {
121 buffersrc_empty = 1;
122 } else if (ret == AVERROR(EAGAIN)) {
123 if (buffersrc_empty)
124 return ret;
126 } else if (ret < 0) {
127 return ret;
128 }
129 } else {
131 }
132 }
133}
134
140
142 AVFrame *frame, int nb_samples)
143{
144 return get_frame_internal(ctx, frame, 0, nb_samples);
145}
146
148{
149 BufferSinkContext *buf = ctx->priv;
150
151 buf->warning_limit = 100;
152 return 0;
153}
154
155#define TERMINATE_ARRAY(arr, val) \
156 if (s->arr) { \
157 void *tmp = av_realloc_array(s->arr, s->nb_ ## arr + 1, sizeof(*s->arr)); \
158 if (!tmp) \
159 return AVERROR(ENOMEM); \
160 s->arr = tmp; \
161 s->arr[s->nb_ ## arr] = val; \
162 }
163
165{
166 BufferSinkContext *s = ctx->priv;
167
169 TERMINATE_ARRAY(colorranges, -1);
170 TERMINATE_ARRAY(colorspaces, -1);
171 TERMINATE_ARRAY(alphamodes, -1);
172
173 return common_init(ctx);
174}
175
177{
178 BufferSinkContext *s = ctx->priv;
179
181 TERMINATE_ARRAY(samplerates, -1);
182 TERMINATE_ARRAY(channel_layouts, (AVChannelLayout){ .nb_channels = 0 });
183
184 return common_init(ctx);
185}
186
187#undef TERMINATE_ARRAY
188
190{
191 BufferSinkContext *buf = ctx->priv;
192
194}
195
197{
198 BufferSinkContext *buf = ctx->priv;
199 FilterLinkInternal * const li = ff_link_internal(ctx->inputs[0]);
200
201 if (buf->warning_limit &&
204 "%d buffers queued in %s, something may be wrong.\n",
205 buf->warning_limit,
206 (char *)av_x_if_null(ctx->name, ctx->filter->name));
207 buf->warning_limit *= 10;
208 }
209
210 /* The frame is queued, the rest is up to get_frame_internal */
211 return 0;
212}
213
215{
216 BufferSinkContext *buf = inlink->dst->priv;
217 FilterLink *l = ff_filter_link(inlink);
218
219 l->min_samples = l->max_samples = buf->frame_size;
220
221 return 0;
222}
223
225{
226 BufferSinkContext *buf = ctx->priv;
227 buf->frame_size = frame_size;
228
229 if (ctx->inputs && ctx->inputs[0]) {
230 FilterLink *l = ff_filter_link(ctx->inputs[0]);
231 l->min_samples = l->max_samples = buf->frame_size;
232 }
233}
234
235#define MAKE_AVFILTERLINK_ACCESSOR(type, field) \
236type av_buffersink_get_##field(const AVFilterContext *ctx) { \
237 av_assert0(fffilter(ctx->filter)->activate == activate); \
238 return ctx->inputs[0]->field; \
239}
240
244
247MAKE_AVFILTERLINK_ACCESSOR(AVRational , sample_aspect_ratio)
251
252MAKE_AVFILTERLINK_ACCESSOR(int , sample_rate )
253
260
267
269{
271 return ctx->inputs[0]->ch_layout.nb_channels;
272}
273
275{
276 AVChannelLayout ch_layout = { 0 };
277 int ret;
278
280 ret = av_channel_layout_copy(&ch_layout, &ctx->inputs[0]->ch_layout);
281 if (ret < 0)
282 return ret;
283 *out = ch_layout;
284 return 0;
285}
286
288 int *nb_side_data)
289{
291 *nb_side_data = ctx->inputs[0]->nb_side_data;
292 return (const AVFrameSideData *const *)ctx->inputs[0]->side_data;
293}
294
296 AVFilterFormatsConfig **cfg_in,
297 AVFilterFormatsConfig **cfg_out)
298{
299 const BufferSinkContext *buf = ctx->priv;
300 int ret;
301
302 if (buf->nb_pixel_formats) {
303 ret = ff_set_pixel_formats_from_list2(ctx, cfg_in, cfg_out, buf->pixel_formats);
304 if (ret < 0)
305 return ret;
306 }
307 if (buf->nb_colorspaces) {
308 ret = ff_set_common_color_spaces_from_list2(ctx, cfg_in, cfg_out, buf->colorspaces);
309 if (ret < 0)
310 return ret;
311 }
312 if (buf->nb_colorranges) {
313 ret = ff_set_common_color_ranges_from_list2(ctx, cfg_in, cfg_out, buf->colorranges);
314 if (ret < 0)
315 return ret;
316 }
317 if (buf->nb_alphamodes) {
318 ret = ff_set_common_alpha_modes_from_list2(ctx, cfg_in, cfg_out, buf->alphamodes);
319 if (ret < 0)
320 return ret;
321 }
322
323 return 0;
324}
325
327 AVFilterFormatsConfig **cfg_in,
328 AVFilterFormatsConfig **cfg_out)
329{
330 const BufferSinkContext *buf = ctx->priv;
331 int ret;
332
333 if (buf->nb_sample_formats) {
334 ret = ff_set_sample_formats_from_list2(ctx, cfg_in, cfg_out, buf->sample_formats);
335 if (ret < 0)
336 return ret;
337 }
338 if (buf->nb_samplerates) {
339 ret = ff_set_common_samplerates_from_list2(ctx, cfg_in, cfg_out, buf->samplerates);
340 if (ret < 0)
341 return ret;
342 }
343 if (buf->nb_channel_layouts) {
345 if (ret < 0)
346 return ret;
347 }
348
349 return 0;
350}
351
352#define OFFSET(x) offsetof(BufferSinkContext, x)
353#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
354static const AVOption buffersink_options[] = {
355 { "pixel_formats", "array of supported pixel formats", OFFSET(pixel_formats),
356 AV_OPT_TYPE_PIXEL_FMT | AV_OPT_TYPE_FLAG_ARRAY, .max = INT_MAX, .flags = FLAGS },
357 { "colorspaces", "array of supported color spaces", OFFSET(colorspaces),
358 AV_OPT_TYPE_INT | AV_OPT_TYPE_FLAG_ARRAY, .max = INT_MAX, .flags = FLAGS },
359 { "colorranges", "array of supported color ranges", OFFSET(colorranges),
360 AV_OPT_TYPE_INT | AV_OPT_TYPE_FLAG_ARRAY, .max = INT_MAX, .flags = FLAGS },
361 { "alphamodes", "array of supported color ranges", OFFSET(alphamodes),
362 AV_OPT_TYPE_INT | AV_OPT_TYPE_FLAG_ARRAY, .max = INT_MAX, .flags = FLAGS },
363
364 { NULL },
365};
366#undef FLAGS
367#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_AUDIO_PARAM
369 { "sample_formats", "array of supported sample formats", OFFSET(sample_formats),
370 AV_OPT_TYPE_SAMPLE_FMT | AV_OPT_TYPE_FLAG_ARRAY, .max = INT_MAX, .flags = FLAGS },
371 { "samplerates", "array of supported sample formats", OFFSET(samplerates),
372 AV_OPT_TYPE_INT | AV_OPT_TYPE_FLAG_ARRAY, .max = INT_MAX, .flags = FLAGS },
373 { "channel_layouts", "array of supported channel layouts", OFFSET(channel_layouts),
375 { NULL },
376};
377#undef FLAGS
378
381
383 .p.name = "buffersink",
384 .p.description = NULL_IF_CONFIG_SMALL("Buffer video frames, and make them available to the end of the filter graph."),
385 .p.priv_class = &buffersink_class,
386 .p.outputs = NULL,
387 .priv_size = sizeof(BufferSinkContext),
388 .init = init_video,
389 .uninit = uninit,
393};
394
395static const AVFilterPad inputs_audio[] = {
396 {
397 .name = "default",
398 .type = AVMEDIA_TYPE_AUDIO,
399 .config_props = config_input_audio,
400 },
401};
402
404 .p.name = "abuffersink",
405 .p.description = NULL_IF_CONFIG_SMALL("Buffer audio frames, and make them available to the end of the filter graph."),
406 .p.priv_class = &abuffersink_class,
407 .p.outputs = NULL,
408 .priv_size = sizeof(BufferSinkContext),
409 .init = init_audio,
410 .uninit = uninit,
414};
static const char *const format[]
Definition af_aiir.c:444
const FFFilter ff_vsink_buffer
Definition buffersink.c:382
const FFFilter ff_asink_abuffer
Definition buffersink.c:403
static FILE * out
static AVFormatContext * ctx
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition avassert.h:58
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
int ff_inlink_acknowledge_status(AVFilterLink *link, int *rstatus, int64_t *rpts)
Test and acknowledge the change of status on the link.
Definition avfilter.c:1467
int ff_inlink_consume_samples(AVFilterLink *link, unsigned min, unsigned max, AVFrame **rframe)
Take samples from the link's FIFO and update the link's stats.
Definition avfilter.c:1540
int ff_inlink_consume_frame(AVFilterLink *link, AVFrame **rframe)
Take a frame from the link's FIFO and update the link's stats.
Definition avfilter.c:1520
void ff_inlink_request_frame(AVFilterLink *link)
Mark that a frame is wanted on the link.
Definition avfilter.c:1623
Main libavfilter public API header.
int ff_filter_graph_run_once(AVFilterGraph *graph)
Run one round of processing on a filter graph.
static BitStreamFilterLinkInternal * ff_link_internal(AVBitStreamFilterLink *link)
static const AVOption abuffersink_options[]
Definition buffersink.c:368
static const AVOption buffersink_options[]
Definition buffersink.c:354
static const AVFilterPad inputs_audio[]
Definition buffersink.c:395
#define TERMINATE_ARRAY(arr, val)
Definition buffersink.c:155
#define MAKE_AVFILTERLINK_ACCESSOR(type, field)
Definition buffersink.c:235
static av_cold int common_init(AVFilterContext *ctx)
Definition buffersink.c:147
static int get_frame_internal(AVFilterContext *ctx, AVFrame *frame, int flags, int samples)
Definition buffersink.c:93
static int asink_query_formats(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
Definition buffersink.c:326
static int return_or_keep_frame(BufferSinkContext *buf, AVFrame *out, AVFrame *in, int flags)
Definition buffersink.c:79
static void uninit(AVFilterContext *ctx)
Definition buffersink.c:189
static int vsink_query_formats(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
Definition buffersink.c:295
static int config_input_audio(AVFilterLink *inlink)
Definition buffersink.c:214
static int init_audio(AVFilterContext *ctx)
Definition buffersink.c:176
static int activate(AVFilterContext *ctx)
Definition buffersink.c:196
static int init_video(AVFilterContext *ctx)
Definition buffersink.c:164
#define OFFSET(x)
Definition buffersink.c:352
memory buffer sink API for audio and video
#define flags(name, subs,...)
Definition cbs_h264.c:74
#define s(width, name)
Definition cbs_vp9.c:198
Public libavutil channel layout APIs header.
#define FLAGS
Definition cmdutils.c:598
common internal and external API header
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
static const uint16_t channel_layouts[7]
Definition dca_lbr.c:112
static AVFrame * frame
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
int ff_set_common_alpha_modes_from_list2(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out, const int *alpha_modes)
Definition formats.c:1122
int ff_set_common_color_ranges_from_list2(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out, const int *color_ranges)
Definition formats.c:1098
int ff_set_common_samplerates_from_list2(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out, const int *samplerates)
Definition formats.c:1050
int ff_set_common_color_spaces_from_list2(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out, const int *color_spaces)
Definition formats.c:1074
int ff_set_common_channel_layouts_from_list2(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out, const AVChannelLayout *fmts)
Definition formats.c:1026
int ff_set_pixel_formats_from_list2(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out, const enum AVPixelFormat *fmts)
Definition formats.c:1162
int ff_set_sample_formats_from_list2(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out, const enum AVSampleFormat *fmts)
Definition formats.c:1154
static size_t ff_framequeue_queued_frames(const FFFrameQueue *fq)
Get the number of queued frames.
Definition framequeue.h:158
static const uint8_t frame_size[4]
Definition g723_1.h:222
@ AV_OPT_TYPE_PIXEL_FMT
Underlying C type is enum AVPixelFormat.
Definition opt.h:306
@ AV_OPT_TYPE_FLAG_ARRAY
May be combined with another regular option type to declare an array option.
Definition opt.h:345
@ AV_OPT_TYPE_SAMPLE_FMT
Underlying C type is enum AVSampleFormat.
Definition opt.h:310
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition opt.h:258
@ AV_OPT_TYPE_CHLAYOUT
Underlying C type is AVChannelLayout.
Definition opt.h:330
AVBufferRef * av_buffersink_get_hw_frames_ctx(const AVFilterContext *ctx)
Definition buffersink.c:261
AVRational av_buffersink_get_frame_rate(const AVFilterContext *ctx)
Definition buffersink.c:254
const AVFrameSideData *const * av_buffersink_get_side_data(const AVFilterContext *ctx, int *nb_side_data)
Definition buffersink.c:287
int av_buffersink_get_ch_layout(const AVFilterContext *ctx, AVChannelLayout *out)
Definition buffersink.c:274
int av_buffersink_get_channels(const AVFilterContext *ctx)
Definition buffersink.c:268
void av_buffersink_set_frame_size(AVFilterContext *ctx, unsigned frame_size)
Set the frame size for an audio buffer sink.
Definition buffersink.c:224
int attribute_align_arg av_buffersink_get_frame(AVFilterContext *ctx, AVFrame *frame)
Get a frame with filtered data from sink and put it in frame.
Definition buffersink.c:74
int attribute_align_arg av_buffersink_get_frame_flags(AVFilterContext *ctx, AVFrame *frame, int flags)
Get a frame with filtered data from sink and put it in frame.
Definition buffersink.c:135
#define AV_BUFFERSINK_FLAG_PEEK
Tell av_buffersink_get_buffer_ref() to read video/samples buffer reference, but not remove it from th...
Definition buffersink.h:85
int attribute_align_arg av_buffersink_get_samples(AVFilterContext *ctx, AVFrame *frame, int nb_samples)
Same as av_buffersink_get_frame(), but with the ability to specify the number of samples read.
Definition buffersink.c:141
#define AV_BUFFERSINK_FLAG_NO_REQUEST
Tell av_buffersink_get_buffer_ref() not to request a frame from its input.
Definition buffersink.h:92
int av_channel_layout_copy(AVChannelLayout *dst, const AVChannelLayout *src)
Make a copy of a channel layout.
#define AVERROR(e)
Definition error.h:45
void av_frame_move_ref(AVFrame *dst, AVFrame *src)
Move everything contained in src to dst and reset src.
Definition frame.c:523
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
Definition frame.c:278
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition frame.c:64
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
AVMediaType
Definition avutil.h:198
static void * av_x_if_null(const void *p, const void *x)
Return x default pointer in case p is NULL.
Definition avutil.h:311
@ AVMEDIA_TYPE_AUDIO
Definition avutil.h:201
AVSampleFormat
Audio sample formats.
Definition samplefmt.h:55
@ AV_SAMPLE_FMT_NONE
Definition samplefmt.h:56
cl_device_type type
static av_cold void uninit(AVBitStreamFilterContext *ctx)
static int activate(AVBitStreamFilterContext *ctx)
#define FILTER_INPUTS(array)
Definition filters.h:264
#define FFERROR_BUFFERSRC_EMPTY
Definition filters.h:35
static FilterLink * ff_filter_link(AVFilterLink *link)
Definition filters.h:199
#define AVFILTER_DEFINE_CLASS(fname)
Definition filters.h:478
#define FILTER_QUERY_FUNC2(func)
Definition filters.h:241
static const FFFilter * fffilter(const AVFilter *f)
Definition filters.h:464
#define av_cold
Definition attributes.h:117
common internal API header
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:88
#define attribute_align_arg
Definition internal.h:50
uint8_t w
Definition llvidencdsp.c:39
static const struct @161106304217160064156176027033213377304043230355 sample_formats[]
Memory handling functions.
AVOptions.
AVColorRange
Visual content value range.
Definition pixfmt.h:748
AVAlphaMode
Correlation between the alpha channel and color values.
Definition pixfmt.h:816
AVPixelFormat
Pixel format.
Definition pixfmt.h:71
@ AV_PIX_FMT_NONE
Definition pixfmt.h:72
AVColorSpace
YUV colorspace type.
Definition pixfmt.h:706
A reference to a data buffer.
Definition buffer.h:82
An AVChannelLayout holds information about the channel layout of audio data.
An instance of a filter.
Definition avfilter.h:273
void * priv
private data for use by the filter
Definition avfilter.h:288
Lists of formats / etc.
Definition avfilter.h:120
A filter pad used for either input or output.
Definition filters.h:40
Structure to hold side data for an AVFrame.
Definition frame.h:327
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
AVOption.
Definition opt.h:428
Rational number (pair of numerator and denominator).
Definition rational.h:58
unsigned frame_size
Definition buffersink.c:46
unsigned nb_alphamodes
Definition buffersink.c:59
unsigned nb_sample_formats
Definition buffersink.c:63
AVFrame * peeked_frame
Definition buffersink.c:71
AVChannelLayout * channel_layouts
Definition buffersink.c:68
unsigned nb_colorranges
Definition buffersink.c:56
unsigned nb_pixel_formats
Definition buffersink.c:50
unsigned nb_channel_layouts
Definition buffersink.c:69
enum AVSampleFormat * sample_formats
Definition buffersink.c:62
unsigned nb_colorspaces
Definition buffersink.c:53
unsigned warning_limit
Definition sink.c:34
unsigned nb_samplerates
Definition buffersink.c:66
enum AVPixelFormat * pixel_formats
Definition buffersink.c:49
int(* activate)(AVFilterContext *ctx)
Filter activation function.
Definition filters.h:461
int frame_wanted_out
True if a frame is currently wanted on the output of this filter.
FFFrameQueue fifo
Queue of frames waiting to be filtered.
#define av_log(a,...)
static int64_t pts
color_range
static enum AVPixelFormat pixel_formats[]
Definition vf_sr.c:64
const AVFilterPad ff_video_default_filterpad[1]
An AVFilterPad array whose only entry has name "default" and is of type AVMEDIA_TYPE_VIDEO.
Definition video.c:37