GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavdevice/lavfi.c Lines: 215 274 78.5 %
Date: 2020-08-14 10:39:37 Branches: 115 170 67.6 %

Line Branch Exec Source
1
/*
2
 * Copyright (c) 2011 Stefano Sabatini
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
 * libavfilter virtual input device
24
 */
25
26
/* #define DEBUG */
27
28
#include <float.h>              /* DBL_MIN, DBL_MAX */
29
30
#include "libavutil/bprint.h"
31
#include "libavutil/channel_layout.h"
32
#include "libavutil/file.h"
33
#include "libavutil/imgutils.h"
34
#include "libavutil/internal.h"
35
#include "libavutil/log.h"
36
#include "libavutil/mem.h"
37
#include "libavutil/opt.h"
38
#include "libavutil/parseutils.h"
39
#include "libavutil/pixdesc.h"
40
#include "libavfilter/avfilter.h"
41
#include "libavfilter/buffersink.h"
42
#include "libavformat/avio_internal.h"
43
#include "libavformat/internal.h"
44
#include "avdevice.h"
45
46
typedef struct {
47
    AVClass *class;          ///< class for private options
48
    char          *graph_str;
49
    char          *graph_filename;
50
    char          *dump_graph;
51
    AVFilterGraph *graph;
52
    AVFilterContext **sinks;
53
    int *sink_stream_map;
54
    int *sink_eof;
55
    int *stream_sink_map;
56
    int *sink_stream_subcc_map;
57
    AVFrame *decoded_frame;
58
    int nb_sinks;
59
    AVPacket subcc_packet;
60
} LavfiContext;
61
62
31
static int *create_all_formats(int n)
63
{
64
31
    int i, j, *fmts, count = 0;
65
66
6169
    for (i = 0; i < n; i++) {
67
6138
        const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(i);
68
6138
        if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL))
69
5642
            count++;
70
    }
71
72
31
    if (!(fmts = av_malloc((count+1) * sizeof(int))))
73
        return NULL;
74
6169
    for (j = 0, i = 0; i < n; i++) {
75
6138
        const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(i);
76
6138
        if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL))
77
5642
            fmts[j++] = i;
78
    }
79
31
    fmts[j] = -1;
80
31
    return fmts;
81
}
82
83
31
av_cold static int lavfi_read_close(AVFormatContext *avctx)
84
{
85
31
    LavfiContext *lavfi = avctx->priv_data;
86
87
31
    av_freep(&lavfi->sink_stream_map);
88
31
    av_freep(&lavfi->sink_eof);
89
31
    av_freep(&lavfi->stream_sink_map);
90
31
    av_freep(&lavfi->sink_stream_subcc_map);
91
31
    av_freep(&lavfi->sinks);
92
31
    avfilter_graph_free(&lavfi->graph);
93
31
    av_frame_free(&lavfi->decoded_frame);
94
95
31
    return 0;
96
}
97
98
31
static int create_subcc_streams(AVFormatContext *avctx)
99
{
100
31
    LavfiContext *lavfi = avctx->priv_data;
101
    AVStream *st;
102
    int stream_idx, sink_idx;
103
104
64
    for (stream_idx = 0; stream_idx < lavfi->nb_sinks; stream_idx++) {
105
33
        sink_idx = lavfi->stream_sink_map[stream_idx];
106
33
        if (lavfi->sink_stream_subcc_map[sink_idx]) {
107
3
            lavfi->sink_stream_subcc_map[sink_idx] = avctx->nb_streams;
108
3
            if (!(st = avformat_new_stream(avctx, NULL)))
109
                return AVERROR(ENOMEM);
110
3
            st->codecpar->codec_id = AV_CODEC_ID_EIA_608;
111
3
            st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
112
        } else {
113
30
            lavfi->sink_stream_subcc_map[sink_idx] = -1;
114
        }
115
    }
116
31
    return 0;
117
}
118
119
31
av_cold static int lavfi_read_header(AVFormatContext *avctx)
120
{
121
31
    LavfiContext *lavfi = avctx->priv_data;
122
31
    AVFilterInOut *input_links = NULL, *output_links = NULL, *inout;
123
    const AVFilter *buffersink, *abuffersink;
124
31
    int *pix_fmts = create_all_formats(AV_PIX_FMT_NB);
125
    enum AVMediaType type;
126
31
    int ret = 0, i, n;
127
128
#define FAIL(ERR) { ret = ERR; goto end; }
129
130
31
    if (!pix_fmts)
131
        FAIL(AVERROR(ENOMEM));
132
133
31
    buffersink = avfilter_get_by_name("buffersink");
134
31
    abuffersink = avfilter_get_by_name("abuffersink");
135
136

31
    if (lavfi->graph_filename && lavfi->graph_str) {
137
        av_log(avctx, AV_LOG_ERROR,
138
               "Only one of the graph or graph_file options must be specified\n");
139
        FAIL(AVERROR(EINVAL));
140
    }
141
142
31
    if (lavfi->graph_filename) {
143
        AVBPrint graph_file_pb;
144
1
        AVIOContext *avio = NULL;
145
1
        AVDictionary *options = NULL;
146

1
        if (avctx->protocol_whitelist && (ret = av_dict_set(&options, "protocol_whitelist", avctx->protocol_whitelist, 0)) < 0)
147
            goto end;
148
1
        ret = avio_open2(&avio, lavfi->graph_filename, AVIO_FLAG_READ, &avctx->interrupt_callback, &options);
149
1
        av_dict_set(&options, "protocol_whitelist", NULL, 0);
150
1
        if (ret < 0)
151
            goto end;
152
1
        av_bprint_init(&graph_file_pb, 0, AV_BPRINT_SIZE_UNLIMITED);
153
1
        ret = avio_read_to_bprint(avio, &graph_file_pb, INT_MAX);
154
1
        avio_closep(&avio);
155
1
        av_bprint_chars(&graph_file_pb, '\0', 1);
156

1
        if (!ret && !av_bprint_is_complete(&graph_file_pb))
157
            ret = AVERROR(ENOMEM);
158
1
        if (ret) {
159
            av_bprint_finalize(&graph_file_pb, NULL);
160
            goto end;
161
        }
162
1
        if ((ret = av_bprint_finalize(&graph_file_pb, &lavfi->graph_str)))
163
            goto end;
164
    }
165
166
31
    if (!lavfi->graph_str)
167
30
        lavfi->graph_str = av_strdup(avctx->url);
168
169
    /* parse the graph, create a stream for each open output */
170
31
    if (!(lavfi->graph = avfilter_graph_alloc()))
171
        FAIL(AVERROR(ENOMEM));
172
173
31
    if ((ret = avfilter_graph_parse_ptr(lavfi->graph, lavfi->graph_str,
174
                                    &input_links, &output_links, avctx)) < 0)
175
        goto end;
176
177
31
    if (input_links) {
178
        av_log(avctx, AV_LOG_ERROR,
179
               "Open inputs in the filtergraph are not acceptable\n");
180
        FAIL(AVERROR(EINVAL));
181
    }
182
183
    /* count the outputs */
184
64
    for (n = 0, inout = output_links; inout; n++, inout = inout->next);
185
31
    lavfi->nb_sinks = n;
186
187
31
    if (!(lavfi->sink_stream_map = av_malloc(sizeof(int) * n)))
188
        FAIL(AVERROR(ENOMEM));
189
31
    if (!(lavfi->sink_eof = av_mallocz(sizeof(int) * n)))
190
        FAIL(AVERROR(ENOMEM));
191
31
    if (!(lavfi->stream_sink_map = av_malloc(sizeof(int) * n)))
192
        FAIL(AVERROR(ENOMEM));
193
31
    if (!(lavfi->sink_stream_subcc_map = av_malloc(sizeof(int) * n)))
194
        FAIL(AVERROR(ENOMEM));
195
196
64
    for (i = 0; i < n; i++)
197
33
        lavfi->stream_sink_map[i] = -1;
198
199
    /* parse the output link names - they need to be of the form out0, out1, ...
200
     * create a mapping between them and the streams */
201
64
    for (i = 0, inout = output_links; inout; i++, inout = inout->next) {
202
33
        int stream_idx = 0, suffix = 0, use_subcc = 0;
203
33
        sscanf(inout->name, "out%n%d%n", &suffix, &stream_idx, &suffix);
204
33
        if (!suffix) {
205
            av_log(avctx,  AV_LOG_ERROR,
206
                   "Invalid outpad name '%s'\n", inout->name);
207
            FAIL(AVERROR(EINVAL));
208
        }
209
33
        if (inout->name[suffix]) {
210
3
            if (!strcmp(inout->name + suffix, "+subcc")) {
211
3
                use_subcc = 1;
212
            } else {
213
                av_log(avctx,  AV_LOG_ERROR,
214
                       "Invalid outpad suffix '%s'\n", inout->name);
215
                FAIL(AVERROR(EINVAL));
216
            }
217
        }
218
219
33
        if ((unsigned)stream_idx >= n) {
220
            av_log(avctx, AV_LOG_ERROR,
221
                   "Invalid index was specified in output '%s', "
222
                   "must be a non-negative value < %d\n",
223
                   inout->name, n);
224
            FAIL(AVERROR(EINVAL));
225
        }
226
227
33
        if (lavfi->stream_sink_map[stream_idx] != -1) {
228
            av_log(avctx,  AV_LOG_ERROR,
229
                   "An output with stream index %d was already specified\n",
230
                   stream_idx);
231
            FAIL(AVERROR(EINVAL));
232
        }
233
33
        lavfi->sink_stream_map[i] = stream_idx;
234
33
        lavfi->stream_sink_map[stream_idx] = i;
235
33
        lavfi->sink_stream_subcc_map[i] = !!use_subcc;
236
    }
237
238
    /* for each open output create a corresponding stream */
239
64
    for (i = 0, inout = output_links; inout; i++, inout = inout->next) {
240
        AVStream *st;
241
33
        if (!(st = avformat_new_stream(avctx, NULL)))
242
            FAIL(AVERROR(ENOMEM));
243
33
        st->id = i;
244
    }
245
246
    /* create a sink for each output and connect them to the graph */
247
31
    lavfi->sinks = av_malloc_array(lavfi->nb_sinks, sizeof(AVFilterContext *));
248
31
    if (!lavfi->sinks)
249
        FAIL(AVERROR(ENOMEM));
250
251
64
    for (i = 0, inout = output_links; inout; i++, inout = inout->next) {
252
        AVFilterContext *sink;
253
254
33
        type = avfilter_pad_get_type(inout->filter_ctx->output_pads, inout->pad_idx);
255
256

33
        if (type == AVMEDIA_TYPE_VIDEO && ! buffersink ||
257
16
            type == AVMEDIA_TYPE_AUDIO && ! abuffersink) {
258
                av_log(avctx, AV_LOG_ERROR, "Missing required buffersink filter, aborting.\n");
259
                FAIL(AVERROR_FILTER_NOT_FOUND);
260
        }
261
262
33
        if (type == AVMEDIA_TYPE_VIDEO) {
263
17
            ret = avfilter_graph_create_filter(&sink, buffersink,
264
17
                                               inout->name, NULL,
265
                                               NULL, lavfi->graph);
266
17
            if (ret >= 0)
267
17
                ret = av_opt_set_int_list(sink, "pix_fmts", pix_fmts,  AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN);
268
17
            if (ret < 0)
269
                goto end;
270
16
        } else if (type == AVMEDIA_TYPE_AUDIO) {
271
16
            enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_U8,
272
                                                  AV_SAMPLE_FMT_S16,
273
                                                  AV_SAMPLE_FMT_S32,
274
                                                  AV_SAMPLE_FMT_FLT,
275
                                                  AV_SAMPLE_FMT_DBL, -1 };
276
277
16
            ret = avfilter_graph_create_filter(&sink, abuffersink,
278
16
                                               inout->name, NULL,
279
                                               NULL, lavfi->graph);
280
16
            if (ret >= 0)
281
16
                ret = av_opt_set_int_list(sink, "sample_fmts", sample_fmts,  AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN);
282
16
            if (ret < 0)
283
                goto end;
284
16
            ret = av_opt_set_int(sink, "all_channel_counts", 1,
285
                                 AV_OPT_SEARCH_CHILDREN);
286
16
            if (ret < 0)
287
                goto end;
288
        } else {
289
            av_log(avctx,  AV_LOG_ERROR,
290
                   "Output '%s' is not a video or audio output, not yet supported\n", inout->name);
291
            FAIL(AVERROR(EINVAL));
292
        }
293
294
33
        lavfi->sinks[i] = sink;
295
33
        if ((ret = avfilter_link(inout->filter_ctx, inout->pad_idx, sink, 0)) < 0)
296
            goto end;
297
    }
298
299
    /* configure the graph */
300
31
    if ((ret = avfilter_graph_config(lavfi->graph, avctx)) < 0)
301
        goto end;
302
303
31
    if (lavfi->dump_graph) {
304
        char *dump = avfilter_graph_dump(lavfi->graph, lavfi->dump_graph);
305
        if (dump != NULL) {
306
            fputs(dump, stderr);
307
            fflush(stderr);
308
            av_free(dump);
309
        } else {
310
            FAIL(AVERROR(ENOMEM));
311
        }
312
    }
313
314
    /* fill each stream with the information in the corresponding sink */
315
64
    for (i = 0; i < lavfi->nb_sinks; i++) {
316
33
        AVFilterContext *sink = lavfi->sinks[lavfi->stream_sink_map[i]];
317
33
        AVRational time_base = av_buffersink_get_time_base(sink);
318
33
        AVStream *st = avctx->streams[i];
319
33
        st->codecpar->codec_type = av_buffersink_get_type(sink);
320
33
        avpriv_set_pts_info(st, 64, time_base.num, time_base.den);
321
33
        if (av_buffersink_get_type(sink) == AVMEDIA_TYPE_VIDEO) {
322
17
            st->codecpar->codec_id   = AV_CODEC_ID_RAWVIDEO;
323
17
            st->codecpar->format     = av_buffersink_get_format(sink);
324
17
            st->codecpar->width      = av_buffersink_get_w(sink);
325
17
            st->codecpar->height     = av_buffersink_get_h(sink);
326
17
            st       ->sample_aspect_ratio =
327
17
            st->codecpar->sample_aspect_ratio = av_buffersink_get_sample_aspect_ratio(sink);
328
17
            avctx->probesize = FFMAX(avctx->probesize,
329
                                     av_buffersink_get_w(sink) * av_buffersink_get_h(sink) *
330
                                     av_get_padded_bits_per_pixel(av_pix_fmt_desc_get(av_buffersink_get_format(sink))) *
331
                                     30);
332
16
        } else if (av_buffersink_get_type(sink) == AVMEDIA_TYPE_AUDIO) {
333
16
            st->codecpar->codec_id    = av_get_pcm_codec(av_buffersink_get_format(sink), -1);
334
16
            st->codecpar->channels    = av_buffersink_get_channels(sink);
335
16
            st->codecpar->format      = av_buffersink_get_format(sink);
336
16
            st->codecpar->sample_rate = av_buffersink_get_sample_rate(sink);
337
16
            st->codecpar->channel_layout = av_buffersink_get_channel_layout(sink);
338
16
            if (st->codecpar->codec_id == AV_CODEC_ID_NONE)
339
                av_log(avctx, AV_LOG_ERROR,
340
                       "Could not find PCM codec for sample format %s.\n",
341
                       av_get_sample_fmt_name(av_buffersink_get_format(sink)));
342
        }
343
    }
344
345
31
    if ((ret = create_subcc_streams(avctx)) < 0)
346
        goto end;
347
348
31
    if (!(lavfi->decoded_frame = av_frame_alloc()))
349
        FAIL(AVERROR(ENOMEM));
350
351
31
end:
352
31
    av_free(pix_fmts);
353
31
    avfilter_inout_free(&input_links);
354
31
    avfilter_inout_free(&output_links);
355
31
    if (ret < 0)
356
        lavfi_read_close(avctx);
357
31
    return ret;
358
}
359
360
9832
static int create_subcc_packet(AVFormatContext *avctx, AVFrame *frame,
361
                               int sink_idx)
362
{
363
9832
    LavfiContext *lavfi = avctx->priv_data;
364
    AVFrameSideData *sd;
365
    int stream_idx, i, ret;
366
367
9832
    if ((stream_idx = lavfi->sink_stream_subcc_map[sink_idx]) < 0)
368
9360
        return 0;
369
944
    for (i = 0; i < frame->nb_side_data; i++)
370
944
        if (frame->side_data[i]->type == AV_FRAME_DATA_A53_CC)
371
472
            break;
372
472
    if (i >= frame->nb_side_data)
373
        return 0;
374
472
    sd = frame->side_data[i];
375
472
    if ((ret = av_new_packet(&lavfi->subcc_packet, sd->size)) < 0)
376
        return ret;
377
472
    memcpy(lavfi->subcc_packet.data, sd->data, sd->size);
378
472
    lavfi->subcc_packet.stream_index = stream_idx;
379
472
    lavfi->subcc_packet.pts = frame->pts;
380
472
    lavfi->subcc_packet.pos = frame->pkt_pos;
381
472
    return 0;
382
}
383
384
10339
static int lavfi_read_packet(AVFormatContext *avctx, AVPacket *pkt)
385
{
386
10339
    LavfiContext *lavfi = avctx->priv_data;
387
10339
    double min_pts = DBL_MAX;
388
10339
    int stream_idx, min_pts_sink_idx = 0;
389
10339
    AVFrame *frame = lavfi->decoded_frame;
390
    AVDictionary *frame_metadata;
391
    int ret, i;
392
10339
    int size = 0;
393
394
10339
    if (lavfi->subcc_packet.size) {
395
472
        *pkt = lavfi->subcc_packet;
396
472
        av_init_packet(&lavfi->subcc_packet);
397
472
        lavfi->subcc_packet.size = 0;
398
472
        lavfi->subcc_packet.data = NULL;
399
472
        return pkt->size;
400
    }
401
402
    /* iterate through all the graph sinks. Select the sink with the
403
     * minimum PTS */
404
19764
    for (i = 0; i < lavfi->nb_sinks; i++) {
405
9897
        AVRational tb = av_buffersink_get_time_base(lavfi->sinks[i]);
406
        double d;
407
        int ret;
408
409
9897
        if (lavfi->sink_eof[i])
410
40
            continue;
411
412
9889
        ret = av_buffersink_get_frame_flags(lavfi->sinks[i], frame,
413
                                            AV_BUFFERSINK_FLAG_PEEK);
414
9889
        if (ret == AVERROR_EOF) {
415
            ff_dlog(avctx, "EOF sink_idx:%d\n", i);
416
32
            lavfi->sink_eof[i] = 1;
417
32
            continue;
418
9857
        } else if (ret < 0)
419
            return ret;
420
9857
        d = av_rescale_q_rnd(frame->pts, tb, AV_TIME_BASE_Q, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
421
        ff_dlog(avctx, "sink_idx:%d time:%f\n", i, d);
422
9857
        av_frame_unref(frame);
423
424
9857
        if (d < min_pts) {
425
9841
            min_pts = d;
426
9841
            min_pts_sink_idx = i;
427
        }
428
    }
429
9867
    if (min_pts == DBL_MAX)
430
35
        return AVERROR_EOF;
431
432
    ff_dlog(avctx, "min_pts_sink_idx:%i\n", min_pts_sink_idx);
433
434
9832
    av_buffersink_get_frame_flags(lavfi->sinks[min_pts_sink_idx], frame, 0);
435
9832
    stream_idx = lavfi->sink_stream_map[min_pts_sink_idx];
436
437
9832
    if (frame->width /* FIXME best way of testing a video */) {
438
1028
        size = av_image_get_buffer_size(frame->format, frame->width, frame->height, 1);
439
1028
        if ((ret = av_new_packet(pkt, size)) < 0)
440
            return ret;
441
442
1028
        av_image_copy_to_buffer(pkt->data, size, (const uint8_t **)frame->data, frame->linesize,
443
1028
                                frame->format, frame->width, frame->height, 1);
444
8804
    } else if (frame->channels /* FIXME test audio */) {
445
8804
        size = frame->nb_samples * av_get_bytes_per_sample(frame->format) *
446
8804
                                   frame->channels;
447
8804
        if ((ret = av_new_packet(pkt, size)) < 0)
448
            return ret;
449
8804
        memcpy(pkt->data, frame->data[0], size);
450
    }
451
452
9832
    frame_metadata = frame->metadata;
453
9832
    if (frame_metadata) {
454
        uint8_t *metadata;
455
430
        AVDictionaryEntry *e = NULL;
456
        AVBPrint meta_buf;
457
458
430
        av_bprint_init(&meta_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
459
2557
        while ((e = av_dict_get(frame_metadata, "", e, AV_DICT_IGNORE_SUFFIX))) {
460
2127
            av_bprintf(&meta_buf, "%s", e->key);
461
2127
            av_bprint_chars(&meta_buf, '\0', 1);
462
2127
            av_bprintf(&meta_buf, "%s", e->value);
463
2127
            av_bprint_chars(&meta_buf, '\0', 1);
464
        }
465

860
        if (!av_bprint_is_complete(&meta_buf) ||
466
430
            !(metadata = av_packet_new_side_data(pkt, AV_PKT_DATA_STRINGS_METADATA,
467
430
                                                 meta_buf.len))) {
468
            av_bprint_finalize(&meta_buf, NULL);
469
            return AVERROR(ENOMEM);
470
        }
471
430
        memcpy(metadata, meta_buf.str, meta_buf.len);
472
430
        av_bprint_finalize(&meta_buf, NULL);
473
    }
474
475
9832
    if ((ret = create_subcc_packet(avctx, frame, min_pts_sink_idx)) < 0) {
476
        av_frame_unref(frame);
477
        av_packet_unref(pkt);
478
        return ret;
479
    }
480
481
9832
    pkt->stream_index = stream_idx;
482
9832
    pkt->pts = frame->pts;
483
9832
    pkt->pos = frame->pkt_pos;
484
9832
    pkt->size = size;
485
9832
    av_frame_unref(frame);
486
9832
    return size;
487
}
488
489
#define OFFSET(x) offsetof(LavfiContext, x)
490
491
#define DEC AV_OPT_FLAG_DECODING_PARAM
492
493
static const AVOption options[] = {
494
    { "graph",     "set libavfilter graph", OFFSET(graph_str),  AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
495
    { "graph_file","set libavfilter graph filename", OFFSET(graph_filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC},
496
    { "dumpgraph", "dump graph to stderr",  OFFSET(dump_graph), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
497
    { NULL },
498
};
499
500
static const AVClass lavfi_class = {
501
    .class_name = "lavfi indev",
502
    .item_name  = av_default_item_name,
503
    .option     = options,
504
    .version    = LIBAVUTIL_VERSION_INT,
505
    .category   = AV_CLASS_CATEGORY_DEVICE_INPUT,
506
};
507
508
AVInputFormat ff_lavfi_demuxer = {
509
    .name           = "lavfi",
510
    .long_name      = NULL_IF_CONFIG_SMALL("Libavfilter virtual input device"),
511
    .priv_data_size = sizeof(LavfiContext),
512
    .read_header    = lavfi_read_header,
513
    .read_packet    = lavfi_read_packet,
514
    .read_close     = lavfi_read_close,
515
    .flags          = AVFMT_NOFILE,
516
    .priv_class     = &lavfi_class,
517
};