]> git.sesse.net Git - ffmpeg/blob - libavfilter/buffersrc.c
avfilter/buffersrc: remove redundant flag
[ffmpeg] / libavfilter / buffersrc.c
1 /*
2  * Copyright (c) 2008 Vitor Sessak
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  * memory buffer source filter
24  */
25
26 #include <float.h>
27
28 #include "libavutil/avassert.h"
29 #include "libavutil/channel_layout.h"
30 #include "libavutil/common.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 "libavutil/timestamp.h"
37 #include "audio.h"
38 #include "avfilter.h"
39 #include "buffersrc.h"
40 #include "formats.h"
41 #include "internal.h"
42 #include "video.h"
43
44 typedef struct BufferSourceContext {
45     const AVClass    *class;
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     unsigned          nb_failed_requests;
49
50     /* video only */
51     int               w, h;
52     enum AVPixelFormat  pix_fmt;
53     AVRational        pixel_aspect;
54     char              *sws_param;
55
56     AVBufferRef *hw_frames_ctx;
57
58     /* audio only */
59     int sample_rate;
60     enum AVSampleFormat sample_fmt;
61     int channels;
62     uint64_t channel_layout;
63     char    *channel_layout_str;
64
65     int eof;
66 } BufferSourceContext;
67
68 #define CHECK_VIDEO_PARAM_CHANGE(s, c, width, height, format, pts)\
69     if (c->w != width || c->h != height || c->pix_fmt != format) {\
70         av_log(s, AV_LOG_INFO, "filter context - w: %d h: %d fmt: %d, incoming frame - w: %d h: %d fmt: %d pts_time: %s\n",\
71                c->w, c->h, c->pix_fmt, width, height, format, av_ts2timestr(pts, &s->outputs[0]->time_base));\
72         av_log(s, AV_LOG_WARNING, "Changing video frame properties on the fly is not supported by all filters.\n");\
73     }
74
75 #define CHECK_AUDIO_PARAM_CHANGE(s, c, srate, ch_layout, ch_count, format, pts)\
76     if (c->sample_fmt != format || c->sample_rate != srate ||\
77         c->channel_layout != ch_layout || c->channels != ch_count) {\
78         av_log(s, AV_LOG_INFO, "filter context - fmt: %s r: %d layout: %"PRIX64" ch: %d, incoming frame - fmt: %s r: %d layout: %"PRIX64" ch: %d pts_time: %s\n",\
79                av_get_sample_fmt_name(c->sample_fmt), c->sample_rate, c->channel_layout, c->channels,\
80                av_get_sample_fmt_name(format), srate, ch_layout, ch_count, av_ts2timestr(pts, &s->outputs[0]->time_base));\
81         av_log(s, AV_LOG_ERROR, "Changing audio frame properties on the fly is not supported.\n");\
82         return AVERROR(EINVAL);\
83     }
84
85 AVBufferSrcParameters *av_buffersrc_parameters_alloc(void)
86 {
87     AVBufferSrcParameters *par = av_mallocz(sizeof(*par));
88     if (!par)
89         return NULL;
90
91     par->format = -1;
92
93     return par;
94 }
95
96 int av_buffersrc_parameters_set(AVFilterContext *ctx, AVBufferSrcParameters *param)
97 {
98     BufferSourceContext *s = ctx->priv;
99
100     if (param->time_base.num > 0 && param->time_base.den > 0)
101         s->time_base = param->time_base;
102
103     switch (ctx->filter->outputs[0].type) {
104     case AVMEDIA_TYPE_VIDEO:
105         if (param->format != AV_PIX_FMT_NONE) {
106             s->pix_fmt = param->format;
107         }
108         if (param->width > 0)
109             s->w = param->width;
110         if (param->height > 0)
111             s->h = param->height;
112         if (param->sample_aspect_ratio.num > 0 && param->sample_aspect_ratio.den > 0)
113             s->pixel_aspect = param->sample_aspect_ratio;
114         if (param->frame_rate.num > 0 && param->frame_rate.den > 0)
115             s->frame_rate = param->frame_rate;
116         if (param->hw_frames_ctx) {
117             av_buffer_unref(&s->hw_frames_ctx);
118             s->hw_frames_ctx = av_buffer_ref(param->hw_frames_ctx);
119             if (!s->hw_frames_ctx)
120                 return AVERROR(ENOMEM);
121         }
122         break;
123     case AVMEDIA_TYPE_AUDIO:
124         if (param->format != AV_SAMPLE_FMT_NONE) {
125             s->sample_fmt = param->format;
126         }
127         if (param->sample_rate > 0)
128             s->sample_rate = param->sample_rate;
129         if (param->channel_layout)
130             s->channel_layout = param->channel_layout;
131         break;
132     default:
133         return AVERROR_BUG;
134     }
135
136     return 0;
137 }
138
139 int attribute_align_arg av_buffersrc_write_frame(AVFilterContext *ctx, const AVFrame *frame)
140 {
141     return av_buffersrc_add_frame_flags(ctx, (AVFrame *)frame,
142                                         AV_BUFFERSRC_FLAG_KEEP_REF);
143 }
144
145 int attribute_align_arg av_buffersrc_add_frame(AVFilterContext *ctx, AVFrame *frame)
146 {
147     return av_buffersrc_add_frame_flags(ctx, frame, 0);
148 }
149
150 static int av_buffersrc_add_frame_internal(AVFilterContext *ctx,
151                                            AVFrame *frame, int flags);
152
153 int attribute_align_arg av_buffersrc_add_frame_flags(AVFilterContext *ctx, AVFrame *frame, int flags)
154 {
155     AVFrame *copy = NULL;
156     int ret = 0;
157
158     if (frame && frame->channel_layout &&
159         av_get_channel_layout_nb_channels(frame->channel_layout) != frame->channels) {
160         av_log(ctx, AV_LOG_ERROR, "Layout indicates a different number of channels than actually present\n");
161         return AVERROR(EINVAL);
162     }
163
164     if (!(flags & AV_BUFFERSRC_FLAG_KEEP_REF) || !frame)
165         return av_buffersrc_add_frame_internal(ctx, frame, flags);
166
167     if (!(copy = av_frame_alloc()))
168         return AVERROR(ENOMEM);
169     ret = av_frame_ref(copy, frame);
170     if (ret >= 0)
171         ret = av_buffersrc_add_frame_internal(ctx, copy, flags);
172
173     av_frame_free(&copy);
174     return ret;
175 }
176
177 static int push_frame(AVFilterGraph *graph)
178 {
179     int ret;
180
181     while (1) {
182         ret = ff_filter_graph_run_once(graph);
183         if (ret == AVERROR(EAGAIN))
184             break;
185         if (ret < 0)
186             return ret;
187     }
188     return 0;
189 }
190
191 static int av_buffersrc_add_frame_internal(AVFilterContext *ctx,
192                                            AVFrame *frame, int flags)
193 {
194     BufferSourceContext *s = ctx->priv;
195     AVFrame *copy;
196     int refcounted, ret;
197
198     s->nb_failed_requests = 0;
199
200     if (!frame)
201         return av_buffersrc_close(ctx, AV_NOPTS_VALUE, flags);
202     if (s->eof)
203         return AVERROR(EINVAL);
204
205     refcounted = !!frame->buf[0];
206
207     if (!(flags & AV_BUFFERSRC_FLAG_NO_CHECK_FORMAT)) {
208
209         switch (ctx->outputs[0]->type) {
210         case AVMEDIA_TYPE_VIDEO:
211             CHECK_VIDEO_PARAM_CHANGE(ctx, s, frame->width, frame->height,
212                                      frame->format, frame->pts);
213             break;
214         case AVMEDIA_TYPE_AUDIO:
215             /* For layouts unknown on input but known on link after negotiation. */
216             if (!frame->channel_layout)
217                 frame->channel_layout = s->channel_layout;
218             CHECK_AUDIO_PARAM_CHANGE(ctx, s, frame->sample_rate, frame->channel_layout,
219                                      frame->channels, frame->format, frame->pts);
220             break;
221         default:
222             return AVERROR(EINVAL);
223         }
224
225     }
226
227     if (!(copy = av_frame_alloc()))
228         return AVERROR(ENOMEM);
229
230     if (refcounted) {
231         av_frame_move_ref(copy, frame);
232     } else {
233         ret = av_frame_ref(copy, frame);
234         if (ret < 0) {
235             av_frame_free(&copy);
236             return ret;
237         }
238     }
239
240     ret = ff_filter_frame(ctx->outputs[0], copy);
241     if (ret < 0) {
242         av_frame_free(&copy);
243         return ret;
244     }
245
246     if ((flags & AV_BUFFERSRC_FLAG_PUSH)) {
247         ret = push_frame(ctx->graph);
248         if (ret < 0)
249             return ret;
250     }
251
252     return 0;
253 }
254
255 int av_buffersrc_close(AVFilterContext *ctx, int64_t pts, unsigned flags)
256 {
257     BufferSourceContext *s = ctx->priv;
258
259     s->eof = 1;
260     ff_avfilter_link_set_in_status(ctx->outputs[0], AVERROR_EOF, pts);
261     return (flags & AV_BUFFERSRC_FLAG_PUSH) ? push_frame(ctx->graph) : 0;
262 }
263
264 static av_cold int init_video(AVFilterContext *ctx)
265 {
266     BufferSourceContext *c = ctx->priv;
267
268     if (c->pix_fmt == AV_PIX_FMT_NONE || !c->w || !c->h ||
269         av_q2d(c->time_base) <= 0) {
270         av_log(ctx, AV_LOG_ERROR, "Invalid parameters provided.\n");
271         return AVERROR(EINVAL);
272     }
273
274     av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d pixfmt:%s tb:%d/%d fr:%d/%d sar:%d/%d sws_param:%s\n",
275            c->w, c->h, av_get_pix_fmt_name(c->pix_fmt),
276            c->time_base.num, c->time_base.den, c->frame_rate.num, c->frame_rate.den,
277            c->pixel_aspect.num, c->pixel_aspect.den, (char *)av_x_if_null(c->sws_param, ""));
278     return 0;
279 }
280
281 unsigned av_buffersrc_get_nb_failed_requests(AVFilterContext *buffer_src)
282 {
283     return ((BufferSourceContext *)buffer_src->priv)->nb_failed_requests;
284 }
285
286 #define OFFSET(x) offsetof(BufferSourceContext, x)
287 #define A AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_AUDIO_PARAM
288 #define V AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
289
290 static const AVOption buffer_options[] = {
291     { "width",         NULL,                     OFFSET(w),                AV_OPT_TYPE_INT,      { .i64 = 0 }, 0, INT_MAX, V },
292     { "video_size",    NULL,                     OFFSET(w),                AV_OPT_TYPE_IMAGE_SIZE,                .flags = V },
293     { "height",        NULL,                     OFFSET(h),                AV_OPT_TYPE_INT,      { .i64 = 0 }, 0, INT_MAX, V },
294     { "pix_fmt",       NULL,                     OFFSET(pix_fmt),          AV_OPT_TYPE_PIXEL_FMT, { .i64 = AV_PIX_FMT_NONE }, .min = AV_PIX_FMT_NONE, .max = INT_MAX, .flags = V },
295     { "sar",           "sample aspect ratio",    OFFSET(pixel_aspect),     AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, DBL_MAX, V },
296     { "pixel_aspect",  "sample aspect ratio",    OFFSET(pixel_aspect),     AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, DBL_MAX, V },
297     { "time_base",     NULL,                     OFFSET(time_base),        AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, DBL_MAX, V },
298     { "frame_rate",    NULL,                     OFFSET(frame_rate),       AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, DBL_MAX, V },
299     { "sws_param",     NULL,                     OFFSET(sws_param),        AV_OPT_TYPE_STRING,                    .flags = V },
300     { NULL },
301 };
302
303 AVFILTER_DEFINE_CLASS(buffer);
304
305 static const AVOption abuffer_options[] = {
306     { "time_base",      NULL, OFFSET(time_base),           AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, INT_MAX, A },
307     { "sample_rate",    NULL, OFFSET(sample_rate),         AV_OPT_TYPE_INT,      { .i64 = 0 }, 0, INT_MAX, A },
308     { "sample_fmt",     NULL, OFFSET(sample_fmt),          AV_OPT_TYPE_SAMPLE_FMT, { .i64 = AV_SAMPLE_FMT_NONE }, .min = AV_SAMPLE_FMT_NONE, .max = INT_MAX, .flags = A },
309     { "channel_layout", NULL, OFFSET(channel_layout_str),  AV_OPT_TYPE_STRING,             .flags = A },
310     { "channels",       NULL, OFFSET(channels),            AV_OPT_TYPE_INT,      { .i64 = 0 }, 0, INT_MAX, A },
311     { NULL },
312 };
313
314 AVFILTER_DEFINE_CLASS(abuffer);
315
316 static av_cold int init_audio(AVFilterContext *ctx)
317 {
318     BufferSourceContext *s = ctx->priv;
319     int ret = 0;
320
321     if (s->sample_fmt == AV_SAMPLE_FMT_NONE) {
322         av_log(ctx, AV_LOG_ERROR, "Sample format was not set or was invalid\n");
323         return AVERROR(EINVAL);
324     }
325
326     if (s->channel_layout_str || s->channel_layout) {
327         int n;
328
329         if (!s->channel_layout) {
330             s->channel_layout = av_get_channel_layout(s->channel_layout_str);
331             if (!s->channel_layout) {
332                 av_log(ctx, AV_LOG_ERROR, "Invalid channel layout %s.\n",
333                        s->channel_layout_str);
334                 return AVERROR(EINVAL);
335             }
336         }
337         n = av_get_channel_layout_nb_channels(s->channel_layout);
338         if (s->channels) {
339             if (n != s->channels) {
340                 av_log(ctx, AV_LOG_ERROR,
341                        "Mismatching channel count %d and layout '%s' "
342                        "(%d channels)\n",
343                        s->channels, s->channel_layout_str, n);
344                 return AVERROR(EINVAL);
345             }
346         }
347         s->channels = n;
348     } else if (!s->channels) {
349         av_log(ctx, AV_LOG_ERROR, "Neither number of channels nor "
350                                   "channel layout specified\n");
351         return AVERROR(EINVAL);
352     }
353
354     if (!s->time_base.num)
355         s->time_base = (AVRational){1, s->sample_rate};
356
357     av_log(ctx, AV_LOG_VERBOSE,
358            "tb:%d/%d samplefmt:%s samplerate:%d chlayout:%s\n",
359            s->time_base.num, s->time_base.den, av_get_sample_fmt_name(s->sample_fmt),
360            s->sample_rate, s->channel_layout_str);
361
362     return ret;
363 }
364
365 static av_cold void uninit(AVFilterContext *ctx)
366 {
367     BufferSourceContext *s = ctx->priv;
368     av_buffer_unref(&s->hw_frames_ctx);
369 }
370
371 static int query_formats(AVFilterContext *ctx)
372 {
373     BufferSourceContext *c = ctx->priv;
374     AVFilterChannelLayouts *channel_layouts = NULL;
375     AVFilterFormats *formats = NULL;
376     AVFilterFormats *samplerates = NULL;
377     int ret;
378
379     switch (ctx->outputs[0]->type) {
380     case AVMEDIA_TYPE_VIDEO:
381         if ((ret = ff_add_format         (&formats, c->pix_fmt)) < 0 ||
382             (ret = ff_set_common_formats (ctx     , formats   )) < 0)
383             return ret;
384         break;
385     case AVMEDIA_TYPE_AUDIO:
386         if ((ret = ff_add_format             (&formats    , c->sample_fmt )) < 0 ||
387             (ret = ff_set_common_formats     (ctx         , formats       )) < 0 ||
388             (ret = ff_add_format             (&samplerates, c->sample_rate)) < 0 ||
389             (ret = ff_set_common_samplerates (ctx         , samplerates   )) < 0)
390             return ret;
391
392         if ((ret = ff_add_channel_layout(&channel_layouts,
393                               c->channel_layout ? c->channel_layout :
394                               FF_COUNT2LAYOUT(c->channels))) < 0)
395             return ret;
396         if ((ret = ff_set_common_channel_layouts(ctx, channel_layouts)) < 0)
397             return ret;
398         break;
399     default:
400         return AVERROR(EINVAL);
401     }
402
403     return 0;
404 }
405
406 static int config_props(AVFilterLink *link)
407 {
408     BufferSourceContext *c = link->src->priv;
409
410     switch (link->type) {
411     case AVMEDIA_TYPE_VIDEO:
412         link->w = c->w;
413         link->h = c->h;
414         link->sample_aspect_ratio = c->pixel_aspect;
415
416         if (c->hw_frames_ctx) {
417             link->hw_frames_ctx = av_buffer_ref(c->hw_frames_ctx);
418             if (!link->hw_frames_ctx)
419                 return AVERROR(ENOMEM);
420         }
421         break;
422     case AVMEDIA_TYPE_AUDIO:
423         if (!c->channel_layout)
424             c->channel_layout = link->channel_layout;
425         break;
426     default:
427         return AVERROR(EINVAL);
428     }
429
430     link->time_base = c->time_base;
431     link->frame_rate = c->frame_rate;
432     return 0;
433 }
434
435 static int request_frame(AVFilterLink *link)
436 {
437     BufferSourceContext *c = link->src->priv;
438     AVFrame *frame;
439     int ret;
440
441     if (c->eof)
442         return AVERROR_EOF;
443     c->nb_failed_requests++;
444     return AVERROR(EAGAIN);
445 }
446
447 static const AVFilterPad avfilter_vsrc_buffer_outputs[] = {
448     {
449         .name          = "default",
450         .type          = AVMEDIA_TYPE_VIDEO,
451         .request_frame = request_frame,
452         .config_props  = config_props,
453     },
454     { NULL }
455 };
456
457 AVFilter ff_vsrc_buffer = {
458     .name      = "buffer",
459     .description = NULL_IF_CONFIG_SMALL("Buffer video frames, and make them accessible to the filterchain."),
460     .priv_size = sizeof(BufferSourceContext),
461     .query_formats = query_formats,
462
463     .init      = init_video,
464     .uninit    = uninit,
465
466     .inputs    = NULL,
467     .outputs   = avfilter_vsrc_buffer_outputs,
468     .priv_class = &buffer_class,
469 };
470
471 static const AVFilterPad avfilter_asrc_abuffer_outputs[] = {
472     {
473         .name          = "default",
474         .type          = AVMEDIA_TYPE_AUDIO,
475         .request_frame = request_frame,
476         .config_props  = config_props,
477     },
478     { NULL }
479 };
480
481 AVFilter ff_asrc_abuffer = {
482     .name          = "abuffer",
483     .description   = NULL_IF_CONFIG_SMALL("Buffer audio frames, and make them accessible to the filterchain."),
484     .priv_size     = sizeof(BufferSourceContext),
485     .query_formats = query_formats,
486
487     .init      = init_audio,
488     .uninit    = uninit,
489
490     .inputs    = NULL,
491     .outputs   = avfilter_asrc_abuffer_outputs,
492     .priv_class = &abuffer_class,
493 };