Home > Net >  Could someone please explain this filter graph?
Could someone please explain this filter graph?

Time:02-27

https://www.ffmpeg.org/doxygen/trunk/filtering_video_8c-example.html

    filter_graph = avfilter_graph_alloc();
    // ...
    const AVFilter *buffersrc  = avfilter_get_by_name("buffer");
    const AVFilter *buffersink = avfilter_get_by_name("buffersink");
    // ...
    /* buffer video source: the decoded frames from the decoder will be inserted here. */
    snprintf(args, sizeof(args),
            "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
            dec_ctx->width, dec_ctx->height, dec_ctx->pix_fmt,
            time_base.num, time_base.den,
            dec_ctx->sample_aspect_ratio.num, dec_ctx->sample_aspect_ratio.den);
 
    ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",
                                       args, NULL, filter_graph);
    /* buffer video sink: to terminate the filter chain. */
    ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out",
                                       NULL, NULL, filter_graph);
    // ...
/*
     * Set the endpoints for the filter graph. The filter_graph will
     * be linked to the graph described by filters_descr.
     */
 
    /*
     * The buffer source output must be connected to the input pad of
     * the first filter described by filters_descr; since the first
     * filter input label is not specified, it is set to "in" by
     * default.
     */
    outputs->name       = av_strdup("in");
    outputs->filter_ctx = buffersrc_ctx;
    outputs->pad_idx    = 0;
    outputs->next       = NULL;
 
    /*
     * The buffer sink input must be connected to the output pad of
     * the last filter described by filters_descr; since the last
     * filter output label is not specified, it is set to "out" by
     * default.
     */
    inputs->name       = av_strdup("out");
    inputs->filter_ctx = buffersink_ctx;
    inputs->pad_idx    = 0;
    inputs->next       = NULL;
 
    if ((ret = avfilter_graph_parse_ptr(filter_graph, filters_descr,
                                    &inputs, &outputs, NULL)) < 0)

So I see these parts separately like this:

But I can't combine them in my head.
Are these in and out filters the same everywhere?
What filter or graph are these inputs and outputs? If the parsed graph takes the input from in filter, why is it (in filter) in outputs variable then (and vice versa)!? What is even the role of these variables?
Could you please explain the step by step algorithm how this code works

CodePudding user response:

Are these in and out filters the same everywhere?

They are the input and output buffers for filter_descr which must be a filter chain (single input, single output). If you have MIMO filtergraph, inputs and outputs would be arrays, each of their elements allocated by avfilter_inout_alloc().

What filter or graph are these inputs and outputs?

They are for the filter graph is defined in filter_descr

If the parsed graph takes the input from in filter, why is it (in filter) in outputs variable then (and vice versa)!? What is even the role of these variables?

Edited: They are treating (the decoder buffersrc) as a source system which outputs frames to the in pads of filter_descr filtergraph, and (buffersink the encoder) as a destination system which receives its inputs from the out pads of filter_descr filtergraph. Thus the variable naming conventions in this example.

Obviously, they are just variable naming convention, and I do agree with you to have them named backwards but |:shrug:|. Rename them so you won't get confused later. I remember going through the same years ago so I 100% understand.

Original answer below

Filtergraph itself should be defined in the string filters_descr which is parsed by avfilter_graph_parse_ptr(). Say a simple scaling filters_descr = "[in]scale=iw/2:-1[out]". This filtergraph has one filter scale which takes 1 input (has 1 input pad) and 1 output (has 1 output pad). [in] and [out] are the labels for these I/O pads.

Now, when implementing this filter, you need to connect [in] and [out] pads to the decoder and encoder, respectively. For that, you use buffersrc and buffersink endpoint filters so the data frames can be in/out of the graph. But, these filters are not explicitly specified in filters_descr. Thus, in the code snippet, these endpoint filters are created by avfilter_graph_create_filter() functions, and you can note that their pads are named as "in" and "out" accordingly.

Finally, avfilter_graph_parse_ptr creates a network as specified by filters_descr and connect inputs and outputs (they could be arrays to support filtergraphs with multiple inputs and outputs.

  • Related