buffersrc.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2008 Vitor Sessak
3  *
4  * This file is part of Libav.
5  *
6  * Libav 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  * Libav 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 Libav; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
27 #include "libavutil/common.h"
28 #include "libavutil/fifo.h"
29 #include "libavutil/imgutils.h"
30 #include "libavutil/opt.h"
31 #include "libavutil/samplefmt.h"
32 #include "audio.h"
33 #include "avfilter.h"
34 #include "buffersrc.h"
35 #include "formats.h"
36 #include "internal.h"
37 #include "video.h"
38 
39 typedef struct {
40  const AVClass *class;
43 
44  /* video only */
45  int h, w;
48 
49  /* audio only */
53  uint64_t channel_layout;
55 
56  int eof;
58 
59 #define CHECK_VIDEO_PARAM_CHANGE(s, c, width, height, format)\
60  if (c->w != width || c->h != height || c->pix_fmt != format) {\
61  av_log(s, AV_LOG_ERROR, "Changing frame properties on the fly is not supported.\n");\
62  return AVERROR(EINVAL);\
63  }
64 
65 #define CHECK_AUDIO_PARAM_CHANGE(s, c, srate, ch_layout, format)\
66  if (c->sample_fmt != format || c->sample_rate != srate ||\
67  c->channel_layout != ch_layout) {\
68  av_log(s, AV_LOG_ERROR, "Changing frame properties on the fly is not supported.\n");\
69  return AVERROR(EINVAL);\
70  }
71 
72 int av_buffersrc_write_frame(AVFilterContext *buffer_filter, const AVFrame *frame)
73 {
74  BufferSourceContext *c = buffer_filter->priv;
75  AVFilterBufferRef *buf;
76  int ret;
77 
78  if (!frame) {
79  c->eof = 1;
80  return 0;
81  } else if (c->eof)
82  return AVERROR(EINVAL);
83 
84  if (!av_fifo_space(c->fifo) &&
85  (ret = av_fifo_realloc2(c->fifo, av_fifo_size(c->fifo) +
86  sizeof(buf))) < 0)
87  return ret;
88 
89  switch (buffer_filter->outputs[0]->type) {
90  case AVMEDIA_TYPE_VIDEO:
91  CHECK_VIDEO_PARAM_CHANGE(buffer_filter, c, frame->width, frame->height,
92  frame->format);
93  buf = ff_get_video_buffer(buffer_filter->outputs[0], AV_PERM_WRITE,
94  c->w, c->h);
95  if (!buf)
96  return AVERROR(ENOMEM);
97 
98  av_image_copy(buf->data, buf->linesize, frame->data, frame->linesize,
99  c->pix_fmt, c->w, c->h);
100  break;
101  case AVMEDIA_TYPE_AUDIO:
102  CHECK_AUDIO_PARAM_CHANGE(buffer_filter, c, frame->sample_rate, frame->channel_layout,
103  frame->format);
104  buf = ff_get_audio_buffer(buffer_filter->outputs[0], AV_PERM_WRITE,
105  frame->nb_samples);
106  if (!buf)
107  return AVERROR(ENOMEM);
108 
110  0, 0, frame->nb_samples,
112  frame->format);
113  break;
114  default:
115  return AVERROR(EINVAL);
116  }
117 
118  avfilter_copy_frame_props(buf, frame);
119 
120  if ((ret = av_fifo_generic_write(c->fifo, &buf, sizeof(buf), NULL)) < 0) {
122  return ret;
123  }
124 
125  return 0;
126 }
127 
129 {
130  BufferSourceContext *c = s->priv;
131  int ret;
132 
133  if (!buf) {
134  c->eof = 1;
135  return 0;
136  } else if (c->eof)
137  return AVERROR(EINVAL);
138 
139  if (!av_fifo_space(c->fifo) &&
140  (ret = av_fifo_realloc2(c->fifo, av_fifo_size(c->fifo) +
141  sizeof(buf))) < 0)
142  return ret;
143 
144  switch (s->outputs[0]->type) {
145  case AVMEDIA_TYPE_VIDEO:
146  CHECK_VIDEO_PARAM_CHANGE(s, c, buf->video->w, buf->video->h, buf->format);
147  break;
148  case AVMEDIA_TYPE_AUDIO:
150  buf->format);
151  break;
152  default:
153  return AVERROR(EINVAL);
154  }
155 
156  if ((ret = av_fifo_generic_write(c->fifo, &buf, sizeof(buf), NULL)) < 0)
157  return ret;
158 
159  return 0;
160 }
161 
162 static av_cold int init_video(AVFilterContext *ctx, const char *args)
163 {
164  BufferSourceContext *c = ctx->priv;
165  char pix_fmt_str[128];
166  int n = 0;
167 
168  if (!args ||
169  (n = sscanf(args, "%d:%d:%127[^:]:%d:%d:%d:%d", &c->w, &c->h, pix_fmt_str,
170  &c->time_base.num, &c->time_base.den,
171  &c->pixel_aspect.num, &c->pixel_aspect.den)) != 7) {
172  av_log(ctx, AV_LOG_ERROR, "Expected 7 arguments, but %d found in '%s'\n", n, args);
173  return AVERROR(EINVAL);
174  }
175  if ((c->pix_fmt = av_get_pix_fmt(pix_fmt_str)) == AV_PIX_FMT_NONE) {
176  char *tail;
177  c->pix_fmt = strtol(pix_fmt_str, &tail, 10);
178  if (*tail || c->pix_fmt < 0 || c->pix_fmt >= AV_PIX_FMT_NB) {
179  av_log(ctx, AV_LOG_ERROR, "Invalid pixel format string '%s'\n", pix_fmt_str);
180  return AVERROR(EINVAL);
181  }
182  }
183 
184  if (!(c->fifo = av_fifo_alloc(sizeof(AVFilterBufferRef*))))
185  return AVERROR(ENOMEM);
186 
187  av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d pixfmt:%s\n", c->w, c->h, av_get_pix_fmt_name(c->pix_fmt));
188  return 0;
189 }
190 
191 #define OFFSET(x) offsetof(BufferSourceContext, x)
192 #define A AV_OPT_FLAG_AUDIO_PARAM
193 static const AVOption audio_options[] = {
194  { "time_base", NULL, OFFSET(time_base), AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, INT_MAX, A },
195  { "sample_rate", NULL, OFFSET(sample_rate), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, A },
196  { "sample_fmt", NULL, OFFSET(sample_fmt_str), AV_OPT_TYPE_STRING, .flags = A },
197  { "channel_layout", NULL, OFFSET(channel_layout_str), AV_OPT_TYPE_STRING, .flags = A },
198  { NULL },
199 };
200 
201 static const AVClass abuffer_class = {
202  .class_name = "abuffer source",
203  .item_name = av_default_item_name,
204  .option = audio_options,
205  .version = LIBAVUTIL_VERSION_INT,
206 };
207 
208 static av_cold int init_audio(AVFilterContext *ctx, const char *args)
209 {
210  BufferSourceContext *s = ctx->priv;
211  int ret = 0;
212 
213  s->class = &abuffer_class;
215 
216  if ((ret = av_set_options_string(s, args, "=", ":")) < 0) {
217  av_log(ctx, AV_LOG_ERROR, "Error parsing options string: %s.\n", args);
218  goto fail;
219  }
220 
222  if (s->sample_fmt == AV_SAMPLE_FMT_NONE) {
223  av_log(ctx, AV_LOG_ERROR, "Invalid sample format %s.\n",
224  s->sample_fmt_str);
225  ret = AVERROR(EINVAL);
226  goto fail;
227  }
228 
230  if (!s->channel_layout) {
231  av_log(ctx, AV_LOG_ERROR, "Invalid channel layout %s.\n",
232  s->channel_layout_str);
233  ret = AVERROR(EINVAL);
234  goto fail;
235  }
236 
237  if (!(s->fifo = av_fifo_alloc(sizeof(AVFilterBufferRef*)))) {
238  ret = AVERROR(ENOMEM);
239  goto fail;
240  }
241 
242  if (!s->time_base.num)
243  s->time_base = (AVRational){1, s->sample_rate};
244 
245  av_log(ctx, AV_LOG_VERBOSE, "tb:%d/%d samplefmt:%s samplerate: %d "
246  "ch layout:%s\n", s->time_base.num, s->time_base.den, s->sample_fmt_str,
248 
249 fail:
250  av_opt_free(s);
251  return ret;
252 }
253 
254 static av_cold void uninit(AVFilterContext *ctx)
255 {
256  BufferSourceContext *s = ctx->priv;
257  while (s->fifo && av_fifo_size(s->fifo)) {
258  AVFilterBufferRef *buf;
259  av_fifo_generic_read(s->fifo, &buf, sizeof(buf), NULL);
261  }
262  av_fifo_free(s->fifo);
263  s->fifo = NULL;
264 }
265 
267 {
268  BufferSourceContext *c = ctx->priv;
269  AVFilterChannelLayouts *channel_layouts = NULL;
271  AVFilterFormats *samplerates = NULL;
272 
273  switch (ctx->outputs[0]->type) {
274  case AVMEDIA_TYPE_VIDEO:
275  ff_add_format(&formats, c->pix_fmt);
276  ff_set_common_formats(ctx, formats);
277  break;
278  case AVMEDIA_TYPE_AUDIO:
279  ff_add_format(&formats, c->sample_fmt);
280  ff_set_common_formats(ctx, formats);
281 
282  ff_add_format(&samplerates, c->sample_rate);
283  ff_set_common_samplerates(ctx, samplerates);
284 
285  ff_add_channel_layout(&channel_layouts, c->channel_layout);
286  ff_set_common_channel_layouts(ctx, channel_layouts);
287  break;
288  default:
289  return AVERROR(EINVAL);
290  }
291 
292  return 0;
293 }
294 
295 static int config_props(AVFilterLink *link)
296 {
297  BufferSourceContext *c = link->src->priv;
298 
299  switch (link->type) {
300  case AVMEDIA_TYPE_VIDEO:
301  link->w = c->w;
302  link->h = c->h;
304  break;
305  case AVMEDIA_TYPE_AUDIO:
306  link->channel_layout = c->channel_layout;
307  link->sample_rate = c->sample_rate;
308  break;
309  default:
310  return AVERROR(EINVAL);
311  }
312 
313  link->time_base = c->time_base;
314  return 0;
315 }
316 
317 static int request_frame(AVFilterLink *link)
318 {
319  BufferSourceContext *c = link->src->priv;
320  AVFilterBufferRef *buf;
321  int ret = 0;
322 
323  if (!av_fifo_size(c->fifo)) {
324  if (c->eof)
325  return AVERROR_EOF;
326  return AVERROR(EAGAIN);
327  }
328  av_fifo_generic_read(c->fifo, &buf, sizeof(buf), NULL);
329 
330  ff_filter_frame(link, buf);
331 
332  return ret;
333 }
334 
335 static int poll_frame(AVFilterLink *link)
336 {
337  BufferSourceContext *c = link->src->priv;
338  int size = av_fifo_size(c->fifo);
339  if (!size && c->eof)
340  return AVERROR_EOF;
341  return size/sizeof(AVFilterBufferRef*);
342 }
343 
345  {
346  .name = "default",
347  .type = AVMEDIA_TYPE_VIDEO,
348  .request_frame = request_frame,
349  .poll_frame = poll_frame,
350  .config_props = config_props,
351  },
352  { NULL }
353 };
354 
356  .name = "buffer",
357  .description = NULL_IF_CONFIG_SMALL("Buffer video frames, and make them accessible to the filterchain."),
358  .priv_size = sizeof(BufferSourceContext),
360 
361  .init = init_video,
362  .uninit = uninit,
363 
364  .inputs = NULL,
365  .outputs = avfilter_vsrc_buffer_outputs,
366 };
367 
369  {
370  .name = "default",
371  .type = AVMEDIA_TYPE_AUDIO,
372  .request_frame = request_frame,
373  .poll_frame = poll_frame,
374  .config_props = config_props,
375  },
376  { NULL }
377 };
378 
380  .name = "abuffer",
381  .description = NULL_IF_CONFIG_SMALL("Buffer audio frames, and make them accessible to the filterchain."),
382  .priv_size = sizeof(BufferSourceContext),
384 
385  .init = init_audio,
386  .uninit = uninit,
387 
388  .inputs = NULL,
389  .outputs = avfilter_asrc_abuffer_outputs,
390 };
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: avfilter.h:156
static av_cold int init_audio(AVFilterContext *ctx, const char *args)
Definition: buffersrc.c:208
AVFilterBufferRef * ff_get_audio_buffer(AVFilterLink *link, int perms, int nb_samples)
Request an audio samples buffer with a specific set of permissions.
Definition: audio.c:63
int size
This structure describes decoded (raw) audio or video data.
Definition: avcodec.h:989
int av_buffersrc_write_frame(AVFilterContext *buffer_filter, const AVFrame *frame)
Add a frame to the buffer source.
Definition: buffersrc.c:72
AVOption.
Definition: opt.h:233
AVRational pixel_aspect
Definition: buffersrc.c:47
AVFilterBufferRefAudioProps * audio
audio buffer specific properties
Definition: avfilter.h:160
AVFilterBufferRefVideoProps * video
video buffer specific properties
Definition: avfilter.h:159
int linesize[8]
number of bytes per line
Definition: avfilter.h:157
misc image utilities
static const AVFilterPad outputs[]
Definition: af_ashowinfo.c:122
Memory buffer source API.
void av_opt_set_defaults(void *s)
Set the values of all AVOption fields to their default values.
Definition: opt.c:505
int ff_filter_frame(AVFilterLink *link, AVFilterBufferRef *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:459
int num
numerator
Definition: rational.h:44
int av_set_options_string(void *ctx, const char *opts, const char *key_val_sep, const char *pairs_sep)
Parse the key/value pairs list in opts.
Definition: opt.c:587
static const AVFilterPad avfilter_vsrc_buffer_outputs[]
Definition: buffersrc.c:344
static enum AVSampleFormat formats[]
enum AVPixelFormat pix_fmt
Definition: buffersrc.c:46
static av_cold int init_video(AVFilterContext *ctx, const char *args)
Definition: buffersrc.c:162
static av_cold void uninit(AVFilterContext *ctx)
Definition: buffersrc.c:254
static const AVClass abuffer_class
Definition: buffersrc.c:201
#define OFFSET(x)
Definition: buffersrc.c:191
int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, int(*func)(void *, void *, int))
Feed data from a user-supplied callback to an AVFifoBuffer.
Definition: fifo.c:82
void avfilter_unref_buffer(AVFilterBufferRef *ref)
Remove a reference to a buffer.
Definition: buffer.c:75
const char * name
Pad name.
Definition: internal.h:39
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:38
#define CHECK_AUDIO_PARAM_CHANGE(s, c, srate, ch_layout, format)
Definition: buffersrc.c:65
AVOptions.
static int poll_frame(AVFilterLink *link)
Definition: buffersrc.c:335
AVFilter avfilter_asrc_abuffer
Definition: buffersrc.c:379
void av_fifo_free(AVFifoBuffer *f)
Free an AVFifoBuffer.
Definition: fifo.c:38
static const AVFilterPad avfilter_asrc_abuffer_outputs[]
Definition: buffersrc.c:368
void ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
A helper for query_formats() which sets all links to the same list of formats.
Definition: formats.c:375
static int init(AVCodecParserContext *s)
Definition: h264_parser.c:335
const AVClass * class
Definition: buffersrc.c:40
A filter pad used for either input or output.
Definition: internal.h:33
AVFilterBufferRef * ff_get_video_buffer(AVFilterLink *link, int perms, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:145
int width
width and height of the video frame
Definition: avcodec.h:1035
int h
image height
Definition: avfilter.h:123
int ff_add_channel_layout(AVFilterChannelLayouts **l, uint64_t channel_layout)
Definition: formats.c:204
static int request_frame(AVFilterLink *link)
Definition: buffersrc.c:317
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:88
void * priv
private data for use by the filter
Definition: avfilter.h:439
int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size, void(*func)(void *, void *, int))
Feed data from an AVFifoBuffer to a user-supplied callback.
Definition: fifo.c:105
int av_get_channel_layout_nb_channels(uint64_t channel_layout)
Return the number of channels in the channel layout.
#define A
Definition: buffersrc.c:192
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:146
AVRational time_base
time_base to set in the output link
Definition: buffersrc.c:42
void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4], const uint8_t *src_data[4], const int src_linesizes[4], enum AVPixelFormat pix_fmt, int width, int height)
Copy image in src_data to dst_data.
Definition: imgutils.c:244
uint64_t channel_layout
Channel layout of the audio data.
Definition: avcodec.h:1318
struct AVRational AVRational
rational number numerator/denominator
audio channel layout utility functions
enum AVPixelFormat pix_fmt
Definition: movenc.c:801
int avfilter_copy_frame_props(AVFilterBufferRef *dst, const AVFrame *src)
Copy the frame properties of src to dst, without copying the actual image data.
Definition: buffer.c:94
LIBAVUTIL_VERSION_INT
Definition: eval.c:52
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
Definition: avcodec.h:1051
A reference to an AVFilterBuffer.
Definition: avfilter.h:139
NULL
Definition: eval.c:52
int av_fifo_space(AVFifoBuffer *f)
Return the amount of space in bytes in the AVFifoBuffer, that is the amount of data you can write int...
Definition: fifo.c:57
sample_fmt
Definition: avconv_filter.c:63
AV_SAMPLE_FMT_NONE
Definition: avconv_filter.c:63
int linesize[AV_NUM_DATA_POINTERS]
Size, in bytes, of the data for each picture/channel plane.
Definition: avcodec.h:1008
int av_fifo_realloc2(AVFifoBuffer *f, unsigned int new_size)
Resize an AVFifoBuffer.
Definition: fifo.c:62
int sample_rate
audio buffer sample rate
Definition: avfilter.h:112
av_default_item_name
Definition: dnxhdenc.c:43
int av_samples_copy(uint8_t **dst, uint8_t *const *src, int dst_offset, int src_offset, int nb_samples, int nb_channels, enum AVSampleFormat sample_fmt)
Copy samples from src to dst.
Definition: samplefmt.c:187
a very simple circular buffer FIFO implementation
Describe the class of an AVClass context structure.
Definition: log.h:33
int sample_rate
Sample rate of the audio data.
Definition: avcodec.h:1310
Filter definition.
Definition: avfilter.h:371
static const AVFilterPad inputs[]
Definition: af_ashowinfo.c:110
rational number numerator/denominator
Definition: rational.h:43
static int config_props(AVFilterLink *link)
Definition: buffersrc.c:295
char * sample_fmt_str
Definition: buffersrc.c:52
const char * name
filter name
Definition: avfilter.h:372
AVFifoBuffer * fifo
Definition: buffersrc.c:41
uint64_t channel_layout
channel layout of audio buffer
Definition: avfilter.h:110
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:433
uint64_t channel_layout
Definition: buffersrc.c:53
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: avcodec.h:997
static const AVOption audio_options[]
Definition: buffersrc.c:193
AVFilter avfilter_vsrc_buffer
Definition: buffersrc.c:355
void ff_set_common_samplerates(AVFilterContext *ctx, AVFilterFormats *samplerates)
Definition: formats.c:363
int av_fifo_size(AVFifoBuffer *f)
Return the amount of data in bytes in the AVFifoBuffer, that is the amount of data you can read from ...
Definition: fifo.c:52
int av_buffersrc_buffer(AVFilterContext *s, AVFilterBufferRef *buf)
Add a buffer to the filtergraph s.
Definition: buffersrc.c:128
void av_opt_free(void *obj)
Free all string and binary options in obj.
Definition: opt.c:607
common internal and external API header
AVSampleFormat
Audio Sample Formats.
Definition: samplefmt.h:49
int den
denominator
Definition: rational.h:45
#define AV_PERM_WRITE
can write to the buffer
Definition: avfilter.h:98
int ff_add_format(AVFilterFormats **avff, int fmt)
Add fmt to the list of media formats contained in *avff.
Definition: formats.c:199
AVFifoBuffer * av_fifo_alloc(unsigned int size)
Initialize an AVFifoBuffer.
Definition: fifo.c:25
enum AVSampleFormat sample_fmt
Definition: buffersrc.c:51
static int query_formats(AVFilterContext *ctx)
Definition: buffersrc.c:266
uint8_t * data[8]
picture/audio data for each plane
Definition: avfilter.h:141
int format
media format
Definition: avfilter.h:170
uint64_t av_get_channel_layout(const char *name)
Return a channel layout id that matches name, or 0 if no match is found.
A list of supported formats for one end of a filter link.
Definition: formats.h:64
An instance of a filter.
Definition: avfilter.h:418
number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of...
Definition: pixfmt.h:181
int height
Definition: avcodec.h:1035
void ff_set_common_channel_layouts(AVFilterContext *ctx, AVFilterChannelLayouts *layouts)
A helper for query_formats() which sets all links to the same list of channel layouts/sample rates...
Definition: formats.c:356
enum AVPixelFormat av_get_pix_fmt(const char *name)
Return the pixel format corresponding to name.
Definition: pixdesc.c:1389
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
Definition: pixdesc.c:1377
internal API functions
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: avcodec.h:1028
AVPixelFormat
Pixel format.
Definition: pixfmt.h:63
int nb_samples
number of audio samples (per channel) described by this frame
Definition: avcodec.h:1042
enum AVSampleFormat av_get_sample_fmt(const char *name)
Return a sample format corresponding to name, or AV_SAMPLE_FMT_NONE on error.
Definition: samplefmt.c:54
#define CHECK_VIDEO_PARAM_CHANGE(s, c, width, height, format)
Definition: buffersrc.c:59
char * channel_layout_str
Definition: buffersrc.c:54