e68379612c3317c40a46b9ffd2b03311f6855d87
[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 <float.h>
27
28 #include "libavutil/channel_layout.h"
29 #include "libavutil/common.h"
30 #include "libavutil/fifo.h"
31 #include "libavutil/frame.h"
32 #include "libavutil/imgutils.h"
33 #include "libavutil/internal.h"
34 #include "libavutil/opt.h"
35 #include "libavutil/samplefmt.h"
36 #include "audio.h"
37 #include "avfilter.h"
38 #include "buffersrc.h"
39 #include "formats.h"
40 #include "internal.h"
41 #include "video.h"
42
43 typedef struct BufferSourceContext {
44     const AVClass    *class;
45     AVFifoBuffer     *fifo;
46     AVRational        time_base;     ///< time_base to set in the output link
47     AVRational        frame_rate;    ///< frame_rate to set in the output link
48
49     /* video only */
50     int               h, w;
51     enum AVPixelFormat  pix_fmt;
52     char               *pix_fmt_str;
53     AVRational        pixel_aspect;
54
55     /* audio only */
56     int sample_rate;
57     enum AVSampleFormat sample_fmt;
58     char               *sample_fmt_str;
59     uint64_t channel_layout;
60     char    *channel_layout_str;
61
62     int eof;
63 } BufferSourceContext;
64
65 #define CHECK_VIDEO_PARAM_CHANGE(s, c, width, height, format)\
66     if (c->w != width || c->h != height || c->pix_fmt != format) {\
67         av_log(s, AV_LOG_ERROR, "Changing frame properties on the fly is not supported.\n");\
68         return AVERROR(EINVAL);\
69     }
70
71 #define CHECK_AUDIO_PARAM_CHANGE(s, c, srate, ch_layout, format)\
72     if (c->sample_fmt != format || c->sample_rate != srate ||\
73         c->channel_layout != ch_layout) {\
74         av_log(s, AV_LOG_ERROR, "Changing frame properties on the fly is not supported.\n");\
75         return AVERROR(EINVAL);\
76     }
77
78 int attribute_align_arg av_buffersrc_write_frame(AVFilterContext *ctx, const AVFrame *frame)
79 {
80     AVFrame *copy;
81     int ret = 0;
82
83     if (!(copy = av_frame_alloc()))
84         return AVERROR(ENOMEM);
85     ret = av_frame_ref(copy, frame);
86     if (ret >= 0)
87         ret = av_buffersrc_add_frame(ctx, copy);
88
89     av_frame_free(&copy);
90     return ret;
91 }
92
93 int attribute_align_arg av_buffersrc_add_frame(AVFilterContext *ctx,
94                                                AVFrame *frame)
95 {
96     BufferSourceContext *s = ctx->priv;
97     AVFrame *copy;
98     int refcounted, ret;
99
100     if (!frame) {
101         s->eof = 1;
102         return 0;
103     } else if (s->eof)
104         return AVERROR(EINVAL);
105
106     refcounted = !!frame->buf[0];
107
108     switch (ctx->outputs[0]->type) {
109     case AVMEDIA_TYPE_VIDEO:
110         CHECK_VIDEO_PARAM_CHANGE(ctx, s, frame->width, frame->height,
111                                  frame->format);
112         break;
113     case AVMEDIA_TYPE_AUDIO:
114         CHECK_AUDIO_PARAM_CHANGE(ctx, s, frame->sample_rate, frame->channel_layout,
115                                  frame->format);
116         break;
117     default:
118         return AVERROR(EINVAL);
119     }
120
121     if (!av_fifo_space(s->fifo) &&
122         (ret = av_fifo_realloc2(s->fifo, av_fifo_size(s->fifo) +
123                                          sizeof(copy))) < 0)
124         return ret;
125
126     if (!(copy = av_frame_alloc()))
127         return AVERROR(ENOMEM);
128
129     if (refcounted) {
130         av_frame_move_ref(copy, frame);
131     } else {
132         ret = av_frame_ref(copy, frame);
133         if (ret < 0) {
134             av_frame_free(&copy);
135             return ret;
136         }
137     }
138
139     if ((ret = av_fifo_generic_write(s->fifo, &copy, sizeof(copy), NULL)) < 0) {
140         if (refcounted)
141             av_frame_move_ref(frame, copy);
142         av_frame_free(&copy);
143         return ret;
144     }
145
146     return 0;
147 }
148
149 static av_cold int init_video(AVFilterContext *ctx)
150 {
151     BufferSourceContext *c = ctx->priv;
152
153     if (!c->pix_fmt_str || !c->w || !c->h || av_q2d(c->time_base) <= 0) {
154         av_log(ctx, AV_LOG_ERROR, "Invalid parameters provided.\n");
155         return AVERROR(EINVAL);
156     }
157
158     if ((c->pix_fmt = av_get_pix_fmt(c->pix_fmt_str)) == AV_PIX_FMT_NONE) {
159         char *tail;
160         c->pix_fmt = strtol(c->pix_fmt_str, &tail, 10);
161         if (*tail || c->pix_fmt < 0 || !av_pix_fmt_desc_get(c->pix_fmt)) {
162             av_log(ctx, AV_LOG_ERROR, "Invalid pixel format string '%s'\n", c->pix_fmt_str);
163             return AVERROR(EINVAL);
164         }
165     }
166
167     if (!(c->fifo = av_fifo_alloc(sizeof(AVFrame*))))
168         return AVERROR(ENOMEM);
169
170     av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d pixfmt:%s tb:%d/%d sar:%d/%d\n",
171            c->w, c->h, av_get_pix_fmt_name(c->pix_fmt),
172            c->time_base.num, c->time_base.den,
173            c->pixel_aspect.num, c->pixel_aspect.den);
174     return 0;
175 }
176
177 #define OFFSET(x) offsetof(BufferSourceContext, x)
178 #define A AV_OPT_FLAG_AUDIO_PARAM
179 #define V AV_OPT_FLAG_VIDEO_PARAM
180
181 static const AVOption video_options[] = {
182     { "width",         NULL,                     OFFSET(w),                AV_OPT_TYPE_INT,      { .i64 = 0 }, 0, INT_MAX, V },
183     { "height",        NULL,                     OFFSET(h),                AV_OPT_TYPE_INT,      { .i64 = 0 }, 0, INT_MAX, V },
184     { "pix_fmt",       NULL,                     OFFSET(pix_fmt_str),      AV_OPT_TYPE_STRING,                    .flags = V },
185 #if FF_API_OLD_FILTER_OPTS
186     /* those 4 are for compatibility with the old option passing system where each filter
187      * did its own parsing */
188     { "time_base_num", "deprecated, do not use", OFFSET(time_base.num),    AV_OPT_TYPE_INT,      { .i64 = 0 }, 0, INT_MAX, V },
189     { "time_base_den", "deprecated, do not use", OFFSET(time_base.den),    AV_OPT_TYPE_INT,      { .i64 = 0 }, 0, INT_MAX, V },
190     { "sar_num",       "deprecated, do not use", OFFSET(pixel_aspect.num), AV_OPT_TYPE_INT,      { .i64 = 0 }, 0, INT_MAX, V },
191     { "sar_den",       "deprecated, do not use", OFFSET(pixel_aspect.den), AV_OPT_TYPE_INT,      { .i64 = 0 }, 0, INT_MAX, V },
192 #endif
193     { "sar",           "sample aspect ratio",    OFFSET(pixel_aspect),     AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, DBL_MAX, V },
194     { "time_base",     NULL,                     OFFSET(time_base),        AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, DBL_MAX, V },
195     { "frame_rate",    NULL,                     OFFSET(frame_rate),       AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, DBL_MAX, V },
196     { NULL },
197 };
198
199 static const AVClass buffer_class = {
200     .class_name = "buffer source",
201     .item_name  = av_default_item_name,
202     .option     = video_options,
203     .version    = LIBAVUTIL_VERSION_INT,
204 };
205
206 static const AVOption audio_options[] = {
207     { "time_base",      NULL, OFFSET(time_base),           AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, INT_MAX, A },
208     { "sample_rate",    NULL, OFFSET(sample_rate),         AV_OPT_TYPE_INT,      { .i64 = 0 }, 0, INT_MAX, A },
209     { "sample_fmt",     NULL, OFFSET(sample_fmt_str),      AV_OPT_TYPE_STRING,             .flags = A },
210     { "channel_layout", NULL, OFFSET(channel_layout_str),  AV_OPT_TYPE_STRING,             .flags = A },
211     { NULL },
212 };
213
214 static const AVClass abuffer_class = {
215     .class_name = "abuffer source",
216     .item_name  = av_default_item_name,
217     .option     = audio_options,
218     .version    = LIBAVUTIL_VERSION_INT,
219 };
220
221 static av_cold int init_audio(AVFilterContext *ctx)
222 {
223     BufferSourceContext *s = ctx->priv;
224     int ret = 0;
225
226     s->sample_fmt = av_get_sample_fmt(s->sample_fmt_str);
227     if (s->sample_fmt == AV_SAMPLE_FMT_NONE) {
228         av_log(ctx, AV_LOG_ERROR, "Invalid sample format %s.\n",
229                s->sample_fmt_str);
230         return AVERROR(EINVAL);
231     }
232
233     s->channel_layout = av_get_channel_layout(s->channel_layout_str);
234     if (!s->channel_layout) {
235         av_log(ctx, AV_LOG_ERROR, "Invalid channel layout %s.\n",
236                s->channel_layout_str);
237         return AVERROR(EINVAL);
238     }
239
240     if (!(s->fifo = av_fifo_alloc(sizeof(AVFrame*))))
241         return AVERROR(ENOMEM);
242
243     if (!s->time_base.num)
244         s->time_base = (AVRational){1, s->sample_rate};
245
246     av_log(ctx, AV_LOG_VERBOSE, "tb:%d/%d samplefmt:%s samplerate: %d "
247            "ch layout:%s\n", s->time_base.num, s->time_base.den, s->sample_fmt_str,
248            s->sample_rate, s->channel_layout_str);
249
250     return ret;
251 }
252
253 static av_cold void uninit(AVFilterContext *ctx)
254 {
255     BufferSourceContext *s = ctx->priv;
256     while (s->fifo && av_fifo_size(s->fifo)) {
257         AVFrame *frame;
258         av_fifo_generic_read(s->fifo, &frame, sizeof(frame), NULL);
259         av_frame_free(&frame);
260     }
261     av_fifo_free(s->fifo);
262     s->fifo = NULL;
263 }
264
265 static int query_formats(AVFilterContext *ctx)
266 {
267     BufferSourceContext *c = ctx->priv;
268     AVFilterChannelLayouts *channel_layouts = NULL;
269     AVFilterFormats *formats = NULL;
270     AVFilterFormats *samplerates = NULL;
271
272     switch (ctx->outputs[0]->type) {
273     case AVMEDIA_TYPE_VIDEO:
274         ff_add_format(&formats, c->pix_fmt);
275         ff_set_common_formats(ctx, formats);
276         break;
277     case AVMEDIA_TYPE_AUDIO:
278         ff_add_format(&formats,           c->sample_fmt);
279         ff_set_common_formats(ctx, formats);
280
281         ff_add_format(&samplerates,       c->sample_rate);
282         ff_set_common_samplerates(ctx, samplerates);
283
284         ff_add_channel_layout(&channel_layouts, c->channel_layout);
285         ff_set_common_channel_layouts(ctx, channel_layouts);
286         break;
287     default:
288         return AVERROR(EINVAL);
289     }
290
291     return 0;
292 }
293
294 static int config_props(AVFilterLink *link)
295 {
296     BufferSourceContext *c = link->src->priv;
297
298     switch (link->type) {
299     case AVMEDIA_TYPE_VIDEO:
300         link->w = c->w;
301         link->h = c->h;
302         link->sample_aspect_ratio = c->pixel_aspect;
303         break;
304     case AVMEDIA_TYPE_AUDIO:
305         link->channel_layout = c->channel_layout;
306         link->sample_rate    = c->sample_rate;
307         break;
308     default:
309         return AVERROR(EINVAL);
310     }
311
312     link->time_base = c->time_base;
313     link->frame_rate = c->frame_rate;
314     return 0;
315 }
316
317 static int request_frame(AVFilterLink *link)
318 {
319     BufferSourceContext *c = link->src->priv;
320     AVFrame *frame;
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, &frame, sizeof(frame), NULL);
329
330     ret = ff_filter_frame(link, frame);
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(AVFrame*);
342 }
343
344 static const AVFilterPad avfilter_vsrc_buffer_outputs[] = {
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
355 AVFilter ff_vsrc_buffer = {
356     .name      = "buffer",
357     .description = NULL_IF_CONFIG_SMALL("Buffer video frames, and make them accessible to the filterchain."),
358     .priv_size = sizeof(BufferSourceContext),
359     .priv_class = &buffer_class,
360     .query_formats = query_formats,
361
362     .init      = init_video,
363     .uninit    = uninit,
364
365     .inputs    = NULL,
366     .outputs   = avfilter_vsrc_buffer_outputs,
367 };
368
369 static const AVFilterPad avfilter_asrc_abuffer_outputs[] = {
370     {
371         .name          = "default",
372         .type          = AVMEDIA_TYPE_AUDIO,
373         .request_frame = request_frame,
374         .poll_frame    = poll_frame,
375         .config_props  = config_props,
376     },
377     { NULL }
378 };
379
380 AVFilter ff_asrc_abuffer = {
381     .name          = "abuffer",
382     .description   = NULL_IF_CONFIG_SMALL("Buffer audio frames, and make them accessible to the filterchain."),
383     .priv_size     = sizeof(BufferSourceContext),
384     .priv_class    = &abuffer_class,
385     .query_formats = query_formats,
386
387     .init      = init_audio,
388     .uninit    = uninit,
389
390     .inputs    = NULL,
391     .outputs   = avfilter_asrc_abuffer_outputs,
392 };