0b9d5d082957e0c926abc6aacf4c20ea2d226b52
[ffmpeg.git] / libavfilter / buffersrc.c
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
21 /**
22  * @file
23  * memory buffer source filter
24  */
25
26 #include "audio.h"
27 #include "avfilter.h"
28 #include "buffersrc.h"
29 #include "formats.h"
30 #include "internal.h"
31 #include "video.h"
32
33 #include "libavutil/audioconvert.h"
34 #include "libavutil/fifo.h"
35 #include "libavutil/imgutils.h"
36 #include "libavutil/opt.h"
37 #include "libavutil/samplefmt.h"
38
39 typedef struct {
40     const AVClass    *class;
41     AVFifoBuffer     *fifo;
42     AVRational        time_base;     ///< time_base to set in the output link
43
44     /* video only */
45     int               h, w;
46     enum PixelFormat  pix_fmt;
47     AVRational        pixel_aspect;
48
49     /* audio only */
50     int sample_rate;
51     enum AVSampleFormat sample_fmt;
52     char               *sample_fmt_str;
53     uint64_t channel_layout;
54     char    *channel_layout_str;
55
56     int eof;
57 } BufferSourceContext;
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, 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         av_image_copy(buf->data, buf->linesize, frame->data, frame->linesize,
96                       c->pix_fmt, c->w, c->h);
97         break;
98     case AVMEDIA_TYPE_AUDIO:
99         CHECK_AUDIO_PARAM_CHANGE(buffer_filter, c, frame->sample_rate, frame->channel_layout,
100                                  frame->format);
101         buf = ff_get_audio_buffer(buffer_filter->outputs[0], AV_PERM_WRITE,
102                                   frame->nb_samples);
103         av_samples_copy(buf->extended_data, frame->extended_data,
104                         0, 0, frame->nb_samples,
105                         av_get_channel_layout_nb_channels(frame->channel_layout),
106                         frame->format);
107         break;
108     default:
109         return AVERROR(EINVAL);
110     }
111
112     avfilter_copy_frame_props(buf, frame);
113
114     if ((ret = av_fifo_generic_write(c->fifo, &buf, sizeof(buf), NULL)) < 0) {
115         avfilter_unref_buffer(buf);
116         return ret;
117     }
118
119     return 0;
120 }
121
122 int av_buffersrc_buffer(AVFilterContext *s, AVFilterBufferRef *buf)
123 {
124     BufferSourceContext *c = s->priv;
125     int ret;
126
127     if (!buf) {
128         c->eof = 1;
129         return 0;
130     } else if (c->eof)
131         return AVERROR(EINVAL);
132
133     if (!av_fifo_space(c->fifo) &&
134         (ret = av_fifo_realloc2(c->fifo, av_fifo_size(c->fifo) +
135                                          sizeof(buf))) < 0)
136         return ret;
137
138     switch (s->outputs[0]->type) {
139     case AVMEDIA_TYPE_VIDEO:
140         CHECK_VIDEO_PARAM_CHANGE(s, c, buf->video->w, buf->video->h, buf->format);
141         break;
142     case AVMEDIA_TYPE_AUDIO:
143         CHECK_AUDIO_PARAM_CHANGE(s, c, buf->audio->sample_rate, buf->audio->channel_layout,
144                                  buf->format);
145         break;
146     default:
147         return AVERROR(EINVAL);
148     }
149
150     if ((ret = av_fifo_generic_write(c->fifo, &buf, sizeof(buf), NULL)) < 0)
151         return ret;
152
153     return 0;
154 }
155
156 static av_cold int init_video(AVFilterContext *ctx, const char *args)
157 {
158     BufferSourceContext *c = ctx->priv;
159     char pix_fmt_str[128];
160     int n = 0;
161
162     if (!args ||
163         (n = sscanf(args, "%d:%d:%127[^:]:%d:%d:%d:%d", &c->w, &c->h, pix_fmt_str,
164                     &c->time_base.num, &c->time_base.den,
165                     &c->pixel_aspect.num, &c->pixel_aspect.den)) != 7) {
166         av_log(ctx, AV_LOG_ERROR, "Expected 7 arguments, but %d found in '%s'\n", n, args);
167         return AVERROR(EINVAL);
168     }
169     if ((c->pix_fmt = av_get_pix_fmt(pix_fmt_str)) == PIX_FMT_NONE) {
170         char *tail;
171         c->pix_fmt = strtol(pix_fmt_str, &tail, 10);
172         if (*tail || c->pix_fmt < 0 || c->pix_fmt >= PIX_FMT_NB) {
173             av_log(ctx, AV_LOG_ERROR, "Invalid pixel format string '%s'\n", pix_fmt_str);
174             return AVERROR(EINVAL);
175         }
176     }
177
178     if (!(c->fifo = av_fifo_alloc(sizeof(AVFilterBufferRef*))))
179         return AVERROR(ENOMEM);
180
181     av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d pixfmt:%s\n", c->w, c->h, av_pix_fmt_descriptors[c->pix_fmt].name);
182     return 0;
183 }
184
185 #define OFFSET(x) offsetof(BufferSourceContext, x)
186 #define A AV_OPT_FLAG_AUDIO_PARAM
187 static const AVOption audio_options[] = {
188     { "time_base",      NULL, OFFSET(time_base),           AV_OPT_TYPE_RATIONAL, { 0 }, 0, INT_MAX, A },
189     { "sample_rate",    NULL, OFFSET(sample_rate),         AV_OPT_TYPE_INT,      { 0 }, 0, INT_MAX, A },
190     { "sample_fmt",     NULL, OFFSET(sample_fmt_str),      AV_OPT_TYPE_STRING,             .flags = A },
191     { "channel_layout", NULL, OFFSET(channel_layout_str),  AV_OPT_TYPE_STRING,             .flags = A },
192     { NULL },
193 };
194
195 static const AVClass abuffer_class = {
196     .class_name = "abuffer source",
197     .item_name  = av_default_item_name,
198     .option     = audio_options,
199     .version    = LIBAVUTIL_VERSION_INT,
200 };
201
202 static av_cold int init_audio(AVFilterContext *ctx, const char *args)
203 {
204     BufferSourceContext *s = ctx->priv;
205     int ret = 0;
206
207     s->class = &abuffer_class;
208     av_opt_set_defaults(s);
209
210     if ((ret = av_set_options_string(s, args, "=", ":")) < 0) {
211         av_log(ctx, AV_LOG_ERROR, "Error parsing options string: %s.\n", args);
212         goto fail;
213     }
214
215     s->sample_fmt = av_get_sample_fmt(s->sample_fmt_str);
216     if (s->sample_fmt == AV_SAMPLE_FMT_NONE) {
217         av_log(ctx, AV_LOG_ERROR, "Invalid sample format %s.\n",
218                s->sample_fmt_str);
219         ret = AVERROR(EINVAL);
220         goto fail;
221     }
222
223     s->channel_layout = av_get_channel_layout(s->channel_layout_str);
224     if (!s->channel_layout) {
225         av_log(ctx, AV_LOG_ERROR, "Invalid channel layout %s.\n",
226                s->channel_layout_str);
227         ret = AVERROR(EINVAL);
228         goto fail;
229     }
230
231     if (!(s->fifo = av_fifo_alloc(sizeof(AVFilterBufferRef*)))) {
232         ret = AVERROR(ENOMEM);
233         goto fail;
234     }
235
236     if (!s->time_base.num)
237         s->time_base = (AVRational){1, s->sample_rate};
238
239     av_log(ctx, AV_LOG_VERBOSE, "tb:%d/%d samplefmt:%s samplerate: %d "
240            "ch layout:%s\n", s->time_base.num, s->time_base.den, s->sample_fmt_str,
241            s->sample_rate, s->channel_layout_str);
242
243 fail:
244     av_opt_free(s);
245     return ret;
246 }
247
248 static av_cold void uninit(AVFilterContext *ctx)
249 {
250     BufferSourceContext *s = ctx->priv;
251     while (s->fifo && av_fifo_size(s->fifo)) {
252         AVFilterBufferRef *buf;
253         av_fifo_generic_read(s->fifo, &buf, sizeof(buf), NULL);
254         avfilter_unref_buffer(buf);
255     }
256     av_fifo_free(s->fifo);
257     s->fifo = NULL;
258 }
259
260 static int query_formats(AVFilterContext *ctx)
261 {
262     BufferSourceContext *c = ctx->priv;
263     AVFilterChannelLayouts *channel_layouts = NULL;
264     AVFilterFormats *formats = NULL;
265     AVFilterFormats *samplerates = NULL;
266
267     switch (ctx->outputs[0]->type) {
268     case AVMEDIA_TYPE_VIDEO:
269         ff_add_format(&formats, c->pix_fmt);
270         ff_set_common_formats(ctx, formats);
271         break;
272     case AVMEDIA_TYPE_AUDIO:
273         ff_add_format(&formats,           c->sample_fmt);
274         ff_set_common_formats(ctx, formats);
275
276         ff_add_format(&samplerates,       c->sample_rate);
277         ff_set_common_samplerates(ctx, samplerates);
278
279         ff_add_channel_layout(&channel_layouts, c->channel_layout);
280         ff_set_common_channel_layouts(ctx, channel_layouts);
281         break;
282     default:
283         return AVERROR(EINVAL);
284     }
285
286     return 0;
287 }
288
289 static int config_props(AVFilterLink *link)
290 {
291     BufferSourceContext *c = link->src->priv;
292
293     switch (link->type) {
294     case AVMEDIA_TYPE_VIDEO:
295         link->w = c->w;
296         link->h = c->h;
297         link->sample_aspect_ratio = c->pixel_aspect;
298         break;
299     case AVMEDIA_TYPE_AUDIO:
300         link->channel_layout = c->channel_layout;
301         link->sample_rate    = c->sample_rate;
302         break;
303     default:
304         return AVERROR(EINVAL);
305     }
306
307     link->time_base = c->time_base;
308     return 0;
309 }
310
311 static int request_frame(AVFilterLink *link)
312 {
313     BufferSourceContext *c = link->src->priv;
314     AVFilterBufferRef *buf;
315
316     if (!av_fifo_size(c->fifo)) {
317         if (c->eof)
318             return AVERROR_EOF;
319         return AVERROR(EAGAIN);
320     }
321     av_fifo_generic_read(c->fifo, &buf, sizeof(buf), NULL);
322
323     switch (link->type) {
324     case AVMEDIA_TYPE_VIDEO:
325         ff_start_frame(link, avfilter_ref_buffer(buf, ~0));
326         ff_draw_slice(link, 0, link->h, 1);
327         ff_end_frame(link);
328         break;
329     case AVMEDIA_TYPE_AUDIO:
330         ff_filter_samples(link, avfilter_ref_buffer(buf, ~0));
331         break;
332     default:
333         return AVERROR(EINVAL);
334     }
335
336     avfilter_unref_buffer(buf);
337
338     return 0;
339 }
340
341 static int poll_frame(AVFilterLink *link)
342 {
343     BufferSourceContext *c = link->src->priv;
344     int size = av_fifo_size(c->fifo);
345     if (!size && c->eof)
346         return AVERROR_EOF;
347     return size/sizeof(AVFilterBufferRef*);
348 }
349
350 AVFilter avfilter_vsrc_buffer = {
351     .name      = "buffer",
352     .description = NULL_IF_CONFIG_SMALL("Buffer video frames, and make them accessible to the filterchain."),
353     .priv_size = sizeof(BufferSourceContext),
354     .query_formats = query_formats,
355
356     .init      = init_video,
357     .uninit    = uninit,
358
359     .inputs    = (AVFilterPad[]) {{ .name = NULL }},
360     .outputs   = (AVFilterPad[]) {{ .name            = "default",
361                                     .type            = AVMEDIA_TYPE_VIDEO,
362                                     .request_frame   = request_frame,
363                                     .poll_frame      = poll_frame,
364                                     .config_props    = config_props, },
365                                   { .name = NULL}},
366 };
367
368 AVFilter avfilter_asrc_abuffer = {
369     .name          = "abuffer",
370     .description   = NULL_IF_CONFIG_SMALL("Buffer audio frames, and make them accessible to the filterchain."),
371     .priv_size     = sizeof(BufferSourceContext),
372     .query_formats = query_formats,
373
374     .init      = init_audio,
375     .uninit    = uninit,
376
377     .inputs    = (AVFilterPad[]) {{ .name = NULL }},
378     .outputs   = (AVFilterPad[]) {{ .name            = "default",
379                                     .type            = AVMEDIA_TYPE_AUDIO,
380                                     .request_frame   = request_frame,
381                                     .poll_frame      = poll_frame,
382                                     .config_props    = config_props, },
383                                   { .name = NULL}},
384 };