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
63
64 /* only used for audio */
67
70
73
76
81
83{
85 buf->peeked_frame = in;
86 return out ? av_frame_ref(out, in) : 0;
87 } else {
89 buf->peeked_frame = NULL;
91 av_frame_free(&in);
92 return 0;
93 }
94}
95
96static int get_frame_internal(AVFilterContext *ctx, AVFrame *frame, int flags, int samples)
97{
98 BufferSinkContext *buf = ctx->priv;
99 AVFilterLink *inlink = ctx->inputs[0];
101 int status, ret;
102 AVFrame *cur_frame;
103 int64_t pts;
104 int buffersrc_empty = 0;
105
106 if (buf->peeked_frame)
107 return return_or_keep_frame(buf, frame, buf->peeked_frame, flags);
108
109 while (1) {
110 ret = samples ? ff_inlink_consume_samples(inlink, samples, samples, &cur_frame) :
111 ff_inlink_consume_frame(inlink, &cur_frame);
112 if (ret < 0) {
113 return ret;
114 } else if (ret) {
115 /* TODO return the frame instead of copying it */
116 return return_or_keep_frame(buf, frame, cur_frame, flags);
117 } else if (ff_inlink_acknowledge_status(inlink, &status, &pts)) {
118 return status;
119 } else if ((flags & AV_BUFFERSINK_FLAG_NO_REQUEST)) {
120 return AVERROR(EAGAIN);
121 } else if (li->frame_wanted_out) {
122 ret = ff_filter_graph_run_once(ctx->graph);
123 if (ret == FFERROR_BUFFERSRC_EMPTY) {
124 buffersrc_empty = 1;
125 } else if (ret == AVERROR(EAGAIN)) {
126 if (buffersrc_empty)
127 return ret;
129 } else if (ret < 0) {
130 return ret;
131 }
132 } else {
134 }
135 }
136}
137
143
145 AVFrame *frame, int nb_samples)
146{
147 return get_frame_internal(ctx, frame, 0, nb_samples);
148}
149
151{
152 BufferSinkContext *buf = ctx->priv;
153
154 buf->warning_limit = 100;
155 return 0;
156}
157
158#define TERMINATE_ARRAY(arr, val) \
159 if (s->arr) { \
160 void *tmp = av_realloc_array(s->arr, s->nb_ ## arr + 1, sizeof(*s->arr)); \
161 if (!tmp) \
162 return AVERROR(ENOMEM); \
163 s->arr = tmp; \
164 s->arr[s->nb_ ## arr] = val; \
165 }
166
168{
169 BufferSinkContext *s = ctx->priv;
170
172 TERMINATE_ARRAY(colorranges, -1);
173 TERMINATE_ARRAY(colorspaces, -1);
174 TERMINATE_ARRAY(alphamodes, -1);
175 TERMINATE_ARRAY(chromalocations, -1);
176
177 return common_init(ctx);
178}
179
181{
182 BufferSinkContext *s = ctx->priv;
183
185 TERMINATE_ARRAY(samplerates, -1);
186 TERMINATE_ARRAY(channel_layouts, (AVChannelLayout){ .nb_channels = 0 });
187
188 return common_init(ctx);
189}
190
191#undef TERMINATE_ARRAY
192
194{
195 BufferSinkContext *buf = ctx->priv;
196
198}
199
201{
202 BufferSinkContext *buf = ctx->priv;
203 FilterLinkInternal * const li = ff_link_internal(ctx->inputs[0]);
204
205 if (buf->warning_limit &&
208 "%d buffers queued in %s, something may be wrong.\n",
209 buf->warning_limit,
210 (char *)av_x_if_null(ctx->name, ctx->filter->name));
211 buf->warning_limit *= 10;
212 }
213
214 /* The frame is queued, the rest is up to get_frame_internal */
215 return 0;
216}
217
219{
220 BufferSinkContext *buf = inlink->dst->priv;
221 FilterLink *l = ff_filter_link(inlink);
222
223 l->min_samples = l->max_samples = buf->frame_size;
224
225 return 0;
226}
227
229{
230 BufferSinkContext *buf = ctx->priv;
231 buf->frame_size = frame_size;
232
233 if (ctx->inputs && ctx->inputs[0]) {
234 FilterLink *l = ff_filter_link(ctx->inputs[0]);
235 l->min_samples = l->max_samples = buf->frame_size;
236 }
237}
238
239#define MAKE_AVFILTERLINK_ACCESSOR(type, field) \
240type av_buffersink_get_##field(const AVFilterContext *ctx) { \
241 av_assert0(fffilter(ctx->filter)->activate == activate); \
242 return ctx->inputs[0]->field; \
243}
244
248
251MAKE_AVFILTERLINK_ACCESSOR(AVRational , sample_aspect_ratio)
255MAKE_AVFILTERLINK_ACCESSOR(enum AVChromaLocation, chroma_location)
256
257MAKE_AVFILTERLINK_ACCESSOR(int , sample_rate )
258
265
272
274{
276 return ctx->inputs[0]->ch_layout.nb_channels;
277}
278
280{
281 AVChannelLayout ch_layout = { 0 };
282 int ret;
283
285 ret = av_channel_layout_copy(&ch_layout, &ctx->inputs[0]->ch_layout);
286 if (ret < 0)
287 return ret;
288 *out = ch_layout;
289 return 0;
290}
291
293 int *nb_side_data)
294{
296 *nb_side_data = ctx->inputs[0]->nb_side_data;
297 return (const AVFrameSideData *const *)ctx->inputs[0]->side_data;
298}
299
301 AVFilterFormatsConfig **cfg_in,
302 AVFilterFormatsConfig **cfg_out)
303{
304 const BufferSinkContext *buf = ctx->priv;
305 int ret;
306
307 if (buf->nb_pixel_formats) {
308 ret = ff_set_pixel_formats_from_list2(ctx, cfg_in, cfg_out, buf->pixel_formats);
309 if (ret < 0)
310 return ret;
311 }
312 if (buf->nb_colorspaces) {
313 ret = ff_set_common_color_spaces_from_list2(ctx, cfg_in, cfg_out, buf->colorspaces);
314 if (ret < 0)
315 return ret;
316 }
317 if (buf->nb_colorranges) {
318 ret = ff_set_common_color_ranges_from_list2(ctx, cfg_in, cfg_out, buf->colorranges);
319 if (ret < 0)
320 return ret;
321 }
322 if (buf->nb_chromalocations) {
324 if (ret < 0)
325 return ret;
326 }
327 if (buf->nb_alphamodes) {
328 ret = ff_set_common_alpha_modes_from_list2(ctx, cfg_in, cfg_out, buf->alphamodes);
329 if (ret < 0)
330 return ret;
331 }
332
333 return 0;
334}
335
337 AVFilterFormatsConfig **cfg_in,
338 AVFilterFormatsConfig **cfg_out)
339{
340 const BufferSinkContext *buf = ctx->priv;
341 int ret;
342
343 if (buf->nb_sample_formats) {
344 ret = ff_set_sample_formats_from_list2(ctx, cfg_in, cfg_out, buf->sample_formats);
345 if (ret < 0)
346 return ret;
347 }
348 if (buf->nb_samplerates) {
349 ret = ff_set_common_samplerates_from_list2(ctx, cfg_in, cfg_out, buf->samplerates);
350 if (ret < 0)
351 return ret;
352 }
353 if (buf->nb_channel_layouts) {
355 if (ret < 0)
356 return ret;
357 }
358
359 return 0;
360}
361
362#define OFFSET(x) offsetof(BufferSinkContext, x)
363#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
364static const AVOption buffersink_options[] = {
365 { "pixel_formats", "array of supported pixel formats", OFFSET(pixel_formats),
366 AV_OPT_TYPE_PIXEL_FMT | AV_OPT_TYPE_FLAG_ARRAY, .max = INT_MAX, .flags = FLAGS },
367 { "colorspaces", "array of supported color spaces", OFFSET(colorspaces),
368 AV_OPT_TYPE_INT | AV_OPT_TYPE_FLAG_ARRAY, .max = INT_MAX, .flags = FLAGS },
369 { "colorranges", "array of supported color ranges", OFFSET(colorranges),
370 AV_OPT_TYPE_INT | AV_OPT_TYPE_FLAG_ARRAY, .max = INT_MAX, .flags = FLAGS },
371 { "chromalocations", "array of supported chroma locations", OFFSET(chromalocations),
372 AV_OPT_TYPE_INT | AV_OPT_TYPE_FLAG_ARRAY, .max = INT_MAX, .flags = FLAGS },
373 { "alphamodes", "array of supported color ranges", OFFSET(alphamodes),
374 AV_OPT_TYPE_INT | AV_OPT_TYPE_FLAG_ARRAY, .max = INT_MAX, .flags = FLAGS },
375
376 { NULL },
377};
378#undef FLAGS
379#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_AUDIO_PARAM
381 { "sample_formats", "array of supported sample formats", OFFSET(sample_formats),
382 AV_OPT_TYPE_SAMPLE_FMT | AV_OPT_TYPE_FLAG_ARRAY, .max = INT_MAX, .flags = FLAGS },
383 { "samplerates", "array of supported sample formats", OFFSET(samplerates),
384 AV_OPT_TYPE_INT | AV_OPT_TYPE_FLAG_ARRAY, .max = INT_MAX, .flags = FLAGS },
385 { "channel_layouts", "array of supported channel layouts", OFFSET(channel_layouts),
387 { NULL },
388};
389#undef FLAGS
390
393
395 .p.name = "buffersink",
396 .p.description = NULL_IF_CONFIG_SMALL("Buffer video frames, and make them available to the end of the filter graph."),
397 .p.priv_class = &buffersink_class,
398 .p.outputs = NULL,
399 .priv_size = sizeof(BufferSinkContext),
400 .init = init_video,
401 .uninit = uninit,
405};
406
407static const AVFilterPad inputs_audio[] = {
408 {
409 .name = "default",
410 .type = AVMEDIA_TYPE_AUDIO,
411 .config_props = config_input_audio,
412 },
413};
414
416 .p.name = "abuffersink",
417 .p.description = NULL_IF_CONFIG_SMALL("Buffer audio frames, and make them available to the end of the filter graph."),
418 .p.priv_class = &abuffersink_class,
419 .p.outputs = NULL,
420 .priv_size = sizeof(BufferSinkContext),
421 .init = init_audio,
422 .uninit = uninit,
426};
static const char *const format[]
Definition af_aiir.c:445
const FFFilter ff_vsink_buffer
Definition buffersink.c:394
const FFFilter ff_asink_abuffer
Definition buffersink.c:415
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:1472
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:1545
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:1525
void ff_inlink_request_frame(AVFilterLink *link)
Mark that a frame is wanted on the link.
Definition avfilter.c:1628
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:380
static const AVOption buffersink_options[]
Definition buffersink.c:364
static const AVFilterPad inputs_audio[]
Definition buffersink.c:407
#define TERMINATE_ARRAY(arr, val)
Definition buffersink.c:158
#define MAKE_AVFILTERLINK_ACCESSOR(type, field)
Definition buffersink.c:239
static av_cold int common_init(AVFilterContext *ctx)
Definition buffersink.c:150
static int get_frame_internal(AVFilterContext *ctx, AVFrame *frame, int flags, int samples)
Definition buffersink.c:96
static int asink_query_formats(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
Definition buffersink.c:336
static int return_or_keep_frame(BufferSinkContext *buf, AVFrame *out, AVFrame *in, int flags)
Definition buffersink.c:82
static void uninit(AVFilterContext *ctx)
Definition buffersink.c:193
static int vsink_query_formats(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
Definition buffersink.c:300
static int config_input_audio(AVFilterLink *inlink)
Definition buffersink.c:218
static int init_audio(AVFilterContext *ctx)
Definition buffersink.c:180
static int activate(AVFilterContext *ctx)
Definition buffersink.c:200
static int init_video(AVFilterContext *ctx)
Definition buffersink.c:167
#define OFFSET(x)
Definition buffersink.c:362
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:596
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:1160
int ff_set_common_color_ranges_from_list2(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out, const int *color_ranges)
Definition formats.c:1136
int ff_set_common_samplerates_from_list2(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out, const int *samplerates)
Definition formats.c:1088
int ff_set_common_chroma_locations_from_list2(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out, const int *chroma_locations)
Definition formats.c:1184
int ff_set_common_color_spaces_from_list2(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out, const int *color_spaces)
Definition formats.c:1112
int ff_set_common_channel_layouts_from_list2(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out, const AVChannelLayout *fmts)
Definition formats.c:1064
int ff_set_pixel_formats_from_list2(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out, const enum AVPixelFormat *fmts)
Definition formats.c:1225
int ff_set_sample_formats_from_list2(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out, const enum AVSampleFormat *fmts)
Definition formats.c:1217
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:266
AVRational av_buffersink_get_frame_rate(const AVFilterContext *ctx)
Definition buffersink.c:259
const AVFrameSideData *const * av_buffersink_get_side_data(const AVFilterContext *ctx, int *nb_side_data)
Definition buffersink.c:292
int av_buffersink_get_ch_layout(const AVFilterContext *ctx, AVChannelLayout *out)
Definition buffersink.c:279
int av_buffersink_get_channels(const AVFilterContext *ctx)
Definition buffersink.c:273
void av_buffersink_set_frame_size(AVFilterContext *ctx, unsigned frame_size)
Set the frame size for an audio buffer sink.
Definition buffersink.c:228
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:77
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:138
#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:86
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:144
#define AV_BUFFERSINK_FLAG_NO_REQUEST
Tell av_buffersink_get_buffer_ref() not to request a frame from its input.
Definition buffersink.h:93
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
uint32_t type
Definition jpegmpfenc.c:80
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:97
#define attribute_align_arg
Definition internal.h:51
uint8_t w
Definition llvidencdsp.c:39
static const struct @161106304217160064156176027033213377304043230355 sample_formats[]
Memory handling functions.
AVOptions.
AVChromaLocation
Location of chroma samples.
Definition pixfmt.h:802
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:279
void * priv
private data for use by the filter
Definition avfilter.h:294
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:334
This structure describes decoded (raw) audio or video data.
Definition frame.h:479
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:66
AVFrame * peeked_frame
Definition buffersink.c:74
AVChannelLayout * channel_layouts
Definition buffersink.c:71
unsigned nb_colorranges
Definition buffersink.c:56
unsigned nb_pixel_formats
Definition buffersink.c:50
unsigned nb_channel_layouts
Definition buffersink.c:72
enum AVSampleFormat * sample_formats
Definition buffersink.c:65
unsigned nb_colorspaces
Definition buffersink.c:53
unsigned nb_chromalocations
Definition buffersink.c:62
unsigned warning_limit
Definition sink.c:34
unsigned nb_samplerates
Definition buffersink.c:69
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