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