博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
FFmpeg-4.0 的filter机制的架构与实现.之二 结构体关系与定义
阅读量:2718 次
发布时间:2019-05-13

本文共 23142 字,大约阅读时间需要 77 分钟。

4. Filter的结构体关系图与定义

4.1 结构体间的关系图

filter涉及的结构体,主要包括:

> FilterGraph, AVFilterGraph

> InputFilter, InputStream, OutputFilter, OutputStream

> AVFilter, AVFilterContext

> AVFilterLink

> AVFilterPad;

 

它们之间的类关系如下图所示:

图5:滤镜结构体关系图

 

从上图可以看到,FFmpeg的滤镜相关的结构体三层组成:

1) filtergraph层

由结构体 FilterGraph, AVFilterGraph组成;

其中,

FilterGraph, 包含一个InputFilter, 它指示了整个Graph的第一个滤镜,并指示了InputStream, 从而作为整个Graph的输入;

包含一个OutputFilter, 它指示了整个Graph的最后一个滤镜,并指示了OutputStream,从而作为整个Graph的输出;

包含一个AVFilterGraph的实例,它指示的是组成本graph的filter;

 

2) filterchain层

它由AVFilter, AVFilterContext, AVFilterLink, AVFilterPad组成;

其中,AVFilterContext是AVFilter的实例;

而filter之间是用 AVFilterLink进行连接,意思是,滤镜之间并不是直接相连的,是通过AVFilterLink进行连接;

AVFilterContext 通过AVFilterLink进行连接后,就组成了Filterchain。

而AVFilterContext与AVFilterLink之间的AVFilterPad是直接相连的,对应的关系是

AVFilterContext的output_pad 连接它下游AVFilterLink的 srcpad;

AVFilterContext的input_pad 连接它上游AVFilterLink的 dstpad;

 

3) filter层

由AVFilterContext, AVFilterPad组成;

其中AVFilterContext是真正进行数据处理的滤镜实体;

 

AVFilterPad用于AVFilterContext之间的callback(回调):

第一个AVFilterContext的outputs[0]指针,指向第一个AVFilterLink,这个AVFilterLink的dst指针,指向第二个AVFilterContext。

如果在前一个AVFilterContext调用 outputs[0]->dstpad->filter_frame(Frame* input_frame1),

那其实就意味着,第一个过滤器,可以把处理好的一个frame(名字为input_frame1),可以通过这个调用,传递给第二个过滤器的input_pads的filter_frame函数。

而第二个过滤器,里面就是用户自己实现的filter_frame(),以对数据进行处理;

 

 

 

 

以 ./ffmpeg_g -i INPUT.mp4 -vn -acodec libfdk_aac -filter_complex "aresample=osf=s16,denoise" -ar 16000 -ac 1 -y OUTPUT.mp4 为例:

它们的实际数据流程如下图所示:

 

图6:-filter_complex "aresample=osf=s16,denoise"的滤镜实例图

 

从上图可以看到,虽然我们只使用了两个滤镜,但构建出来的filterchain实际上包含有:五个filter, 和四个link;

是因为ffmpeg系统会自动为用户设置的滤镜添加上必要的输入、输出滤镜,并将它们连接起来,组成一个完整的filterchain;

其中,ffmpeg默认是有3个filter的!分别是 "graph_0_in_0_0","format_out_0_0", "out_0_0"

它们对应的滤镜类型是: “buffersrc”, “format”, “buffersink”。

它们对应的源码位于: libavfilter/buffersrc.c libavfilter/vf_format.c(对应视频格式) libavfilter/format.c(对应音频格式) , libavfilter/buffersink.c

 

 

上图中:

蓝色和绿色连线 是 AVFilterContext 与 AVFilterLink的连接关系 ;

红色连线 是 AVFilterPad的连接关系;

灰色连线 是 组成AVFilterGraph的AVFilterContext;

 

上图中,上半部分是filtergraph层:

左边连接的是InputFilter,用来引入filtergraph的输入流;

右边连接的是OutputFilter,用来导出filtergraph的输出流;

并且指示了组成本filtergraph的所有filter;

 

上图中,下半部分是filterchain层:

AVFilterContext与AVFilterLink是一种双向链表指针的关系,见图左的蓝色和绿色连线所示;

即 AVFilterContext的 outputs 指向 它的下游 AVFilterLink;

而 下游的AVFilterLink的 src 批向它上游的 AVFilterContext;

 

4.2 FilterGraph 滤镜图结构体定义

typedef struct FilterGraph {    int            index;    const char    *graph_desc;    AVFilterGraph *graph;                // 指向它的实例    int reconfiguration;    InputFilter   **inputs;    int          nb_inputs;    OutputFilter **outputs;    int         nb_outputs;} FilterGraph;

 

4.3 AVFilterGraph 滤镜图结构体定义

 

typedef struct AVFilterGraph {    const AVClass *av_class;    AVFilterContext **filters;                      // 本 滤镜图 包含的所有 filter, 包括系统自生成的    unsigned              nb_filters;                char *scale_sws_opts;                            ///< sws options to use for the auto-inserted scale filters#if FF_API_LAVR_OPTS    attribute_deprecated char *resample_lavr_opts;   ///< libavresample options to use for the auto-inserted resample filters#endif    /**     * Type of multithreading allowed for filters in this graph. A combination     * of AVFILTER_THREAD_* flags.     *     * May be set by the caller at any point, the setting will apply to all     * filters initialized after that. The default is allowing everything.     *     * When a filter in this graph is initialized, this field is combined using     * bit AND with AVFilterContext.thread_type to get the final mask used for     * determining allowed threading types. I.e. a threading type needs to be     * set in both to be allowed.     */    int thread_type;    /**     * Maximum number of threads used by filters in this graph. May be set by     * the caller before adding any filters to the filtergraph. Zero (the     * default) means that the number of threads is determined automatically.     */    int nb_threads;    /**     * Opaque object for libavfilter internal use.     */    AVFilterGraphInternal *internal;    /**     * Opaque user data. May be set by the caller to an arbitrary value, e.g. to     * be used from callbacks like @ref AVFilterGraph.execute.     * Libavfilter will not touch this field in any way.     */    void *opaque;    /**     * This callback may be set by the caller immediately after allocating the     * graph and before adding any filters to it, to provide a custom     * multithreading implementation.     *     * If set, filters with slice threading capability will call this callback     * to execute multiple jobs in parallel.     *     * If this field is left unset, libavfilter will use its internal     * implementation, which may or may not be multithreaded depending on the     * platform and build options.     */    avfilter_execute_func *execute;    char *aresample_swr_opts;                    ///< swr options to use for the auto-inserted aresample filters, Access ONLY through AVOptions    /**     * Private fields     *     * The following fields are for internal use only.     * Their type, offset, number and semantic can change without notice.     */    AVFilterLink **sink_links;    int                   sink_links_count;    unsigned disable_auto_convert;} AVFilterGraph;

4.4. 视频滤镜类型的宏定义

/** * 滤镜输入源的个数不能单由成员变量 AVFilter.inputs 来确定。 * 即依赖于 options 的支持与否,这个滤镜在初始化时可以添加额外的输入源; */#define AVFILTER_FLAG_DYNAMIC_INPUTS        (1 << 0)/** * 滤镜输出目的的个数不能单由成员变量 AVFilter.outputs来确定。 * 即依赖于 options 的支持与否,这个滤镜在初始化时可以添加额外的输出目的 */#define AVFILTER_FLAG_DYNAMIC_OUTPUTS       (1 << 1)/** * 这个滤镜通过将一帧划分成多个部分,然后使用多线程来并行处理它们; */#define AVFILTER_FLAG_SLICE_THREADS         (1 << 2)/** *  有些滤镜支持一个一般意义上的"enable"表达式选项。它可以用来在时间轴上开启或关闭滤镜。 * 如果滤镜支持这个选项就是设置这个标志。 * 当 enable 表达式为假时,默认的无操作的 filter_frame()函数将被调用,它会替换掉在每个输入pad上定义的回调函数 filter_frame();  * 因此,这一帧不做任何处理地透传到下一个滤镜; */#define AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC  (1 << 16)/** * 和 AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC一样, *  有些滤镜希望在 enable表达式为假时,调用自己的 filter_frame()回调函数。 *  例如,依据AVFilterCOntext->is_disable值,这个滤镜会使用它自己的filter_frame()回调来关闭它的处理。*/#define AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL (1 << 17)/** * 用来测试滤镜是否支持时间轴功能(internally or generically)的掩码 */#define AVFILTER_FLAG_SUPPORT_TIMELINE (AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL)

4.5. AVFilter 结构体定义详解

 

/** * 滤镜定义。 * 它定义了滤镜与外部进行交互的pad(管脚,这个概念来自集成电脑,表示滤镜和外部交互的接口), * 以及和本滤镜进行交互的所有回调函数; */typedef struct AVFilter {    /* 滤镜名。必须是非空且唯一的; */    const char *name;    /* 滤镜的描述,可以为空。 */    const char *description;    /**     *  Pad :  输入Pad列表,以零元素结束, 它是和它的上一个AVFilterLink的 dstpad 相连的;     *  如果没有(静态的)输入,则将其设置为空。     *  如果滤镜是  AVFILTER_FLAG_DYNAMIC_INPUTS  类型的实例,则在这个列表中可能有多个输入     */    const AVFilterPad *inputs;    /**     * Pad :  输出Pad列表,以零元素结束, 它是和它的下一个AVFilterLink的  srcpad 相连的;     *  如果没有(静态的)输出,则将其设置为空。     *  如果滤镜是 AVFILTER_FLAG_DYNAMIC_OUTPUTS 类型的实例,则在这个列表中可能有多个输出     */    const AVFilterPad *outputs;    /**     *  私有数据类,用于声明滤镜私有的 AVoptions 结构体;     *  如果滤镜没有任何可选项则将这个值初始化为NULL;     *  如果这个值不为空,那么滤镜私有数据的第一个成员变量必须是 AVClass指针;     */    const AVClass *priv_class;    /**     * 滤镜类型标志  , 其值为 AVFILTER_FLAG_*   宏定义     */    int flags;    /*****************************************************************     *  下面的变量不是公开的API,它们不能被libavfilter的外部使用     *****************************************************************/    /**     *   回调函数: 滤镜预初始化函数     *   当滤镜的 context 被分配后,将立即调用这个回调函数,来分配空间和初始化子对象。     *  如果 这个回调函数不为空, 当遇到空间分配失败时将调用  uninit 回调函数;     *   返回值: 0, 表示成功     *                  AVERROR,表示失败,但是这个错误码会被删除,并被调用代码视为 ENOMEM 。     */    int (*preinit)(AVFilterContext *ctx);    /**     *   回调函数: 滤镜初始化函数     *   在滤镜的整个生命周期中,这个回调函数只会在  所有可选项被设置后,滤镜链建立及格式协调之前 被调用 一次。     *   滤镜本身的基本初始化可以放在这里,     *   ----- 意思是只是初始化滤镜本身的状态,结构体,及本滤镜专用的参数(如输入参数再计算得到的参数)可以放在这里;     *          如果 这些初始化需要使用到本滤镜外的(如上下游滤镜,系统)参数,则需要把这样的初始化放在 config_input()中;     *          NOTE:输入参数的默认值是在 static const AVOption xxxx_options[] 中设置的,不需要再单独设置;     *      *   如果滤镜是多输入/输出类型的,那么应该在这里基于提供的可选项创建这些 inputs/outputs。      *  对于滤镜来说,当这个回调被调用后,就不能再有滤镜的inputs/outputs的改变了。     *      *  这个回调函数它假设滤镜链是有效的,或者帧参数是有效的      *  AVFilter.uninit 指针指向的 uninit  函数  保证了即使初始化失败时 ,这个函数将会被调用 , 因此失败时这个回调函数不需要清空      *      *  返回值: 0, 表示成功; 负数AVERROR,  表示失败。          */    int (*init)(AVFilterContext *ctx);    /**     * Should be set instead of @ref AVFilter.init "init" by the filters that     * want to pass a dictionary of AVOptions to nested contexts that are     * allocated during init.     *     * On return, the options dict should be freed and replaced with one that     * contains all the options which could not be processed by this filter (or     * with NULL if all the options were processed).     *     * Otherwise the semantics is the same as for @ref AVFilter.init "init".     *   回调函数: 这个变量是被滤镜设置,用来代替 AVFilter.init "init"  回调函数,     *           它会传递一个 AVOptions的字典 给 嵌套的 context (它是在初始化进分配的)      *  返回时,这个字典选项应当被释放,且被一个包含所有选项的     */    int (*init_dict)(AVFilterContext *ctx, AVDictionary **options);    /**     * 回调函数:  滤镜释放函数 , 它必须在滤镜释放前仅调用一次。     *  在这个回调函数中,应当释放滤镜的所有申请的内存,指针引用等。     *  但它不需要去释放 AVFilterContext.priv 内存空间本身;     *  即便 AVFilter.init "init" 函数没有被调用或调用失败,这个函数也可能会被调用。     *  因此,它必须能处理这种情况     */    void (*uninit)(AVFilterContext *ctx);    /**     *  回调函数: 检查本滤镜输入列表和输出列表支持的格式。     *  它是在滤镜初始化后(这时输入列表和输出列表都固定了),格式协商之前被调用。它可以被调用多次。     *     *  在这个回调函数中, 必须对每一个输入link 设置  AVFilterLink.out_formats, 对每一个输出link 设置 AVFilterLink.in_formats,     *  列出这个滤镜的link 支持的 像素/样本格式列表。     * 对于音频 link, 这个滤镜还需要设置的参数有:       *             @ref AVFilterLink.in_samplerates "in_samplerates" /     *             @ref AVFilterLink.out_samplerates "out_samplerates" and     *             @ref AVFilterLink.in_channel_layouts "in_channel_layouts" /     *             @ref AVFilterLink.out_channel_layouts "out_channel_layouts"     *      *   如果滤镜只有一个输入,那这个回调函数可以设置为空,     *  在这种情况下, libavfilter假设它支持所有的输入格式,并在输出时保留它们     *      *   返回值:  0, 表示成功; 负数,对应为AVERROR 码     */    int (*query_formats)(AVFilterContext *);    int priv_size;            ///<   滤镜分配的私有数据的大小    int flags_internal;     ///<  avfilter内部使用的额外的标志    /**     *  它是被滤镜注册系统使用的,任何其它代码都不需要去操作它     */    struct AVFilter *next;    /**     *   让滤镜实例执行一个命令;     *  参数: cmd   ,   要执行的命令,为简化处理,所有命令必须仅为字母数字;     *              arg   ,    命令的参数     *             res    ,    大小为 res_size的buffer, 用于存放滤镜的返回。当命令不支持时,不需要改变它。     *            flags  ,     如果设置为 AVFILTER_CMD_FLAG_FAST, 且这个命令是有时间消耗的时,这个滤镜将会不执行命令     *  返回值:  >=0, 表示成功。   否则为错误码,其中,AVERROR(ENOSYS) 为滤镜不支持这个命令     */    int (*process_command)(AVFilterContext *, const char *cmd, const char *arg, char *res, int res_len, int flags);    /**     *  回调函数: 滤镜初始化函数,它用来替代   init()回调函数。     *   参数中可以包含用户提供的参数  :  opaque是用于传输二进制数据     */    int (*init_opaque)(AVFilterContext *ctx, void *opaque);    /**     * Filter activation function.     *     * Called when any processing is needed from the filter, instead of any     * filter_frame and request_frame on pads.     *     * The function must examine inlinks and outlinks and perform a single     * step of processing. If there is nothing to do, the function must do     * nothing and not return an error. If more steps are or may be     * possible, it must use ff_filter_set_ready() to schedule another     * activation.     *  回调函数: 滤镜激活函数     *  当有处理需要这个滤镜时,就会调用这个函数。     */    int (*activate)(AVFilterContext *ctx);} AVFilter;

4.6 AVFilterContext 滤镜实例的结构体

/** An instance of a filter */struct AVFilterContext {    const AVClass *av_class;                       ///< needed for av_log() and filters common options    const AVFilter *filter;                              ///<  指明本实例是哪个AVFilter的实例    char *name;                                          ///< 当前滤镜实例的名称     AVFilterPad   *input_pads;                    ///< 输入Pad的数组             array of input pads    AVFilterLink  **inputs;                            ///< 输入link的指针数组       array of pointers to input links    unsigned         nb_inputs;                          ///< 输入Pad的个数             number of input pads    AVFilterPad   *output_pads;                ///< 输出Pad的数组              array of output pads    AVFilterLink **outputs;                        ///< 输出link的指针数组         array of pointers to output links    unsigned        nb_outputs;                     ///<  输出Pad的个数              number of output pads    void *priv;                                          ///< 本滤镜使用的私有数据    private data for use by the filter    struct AVFilterGraph *graph;            ///< 指明本滤镜是属于哪个filtergraph     /**     * Type of multithreading being allowed/used. A combination of     * AVFILTER_THREAD_* flags.     *     * May be set by the caller before initializing the filter to forbid some     * or all kinds of multithreading for this filter. The default is allowing     * everything.     *     * When the filter is initialized, this field is combined using bit AND with     * AVFilterGraph.thread_type to get the final mask used for determining     * allowed threading types. I.e. a threading type needs to be set in both     * to be allowed.     *     * After the filter is initialized, libavfilter sets this field to the     * threading type that is actually used (0 for no multithreading).     */    int thread_type;    /**     * An opaque struct for libavfilter internal use.     */    AVFilterInternal *internal;    struct AVFilterCommand *command_queue;    char *enable_str;                      ///< enable expression string    void *enable;                            ///< parsed expression (AVExpr*)    double *var_values;                 ///< variable values for the enable expression    int is_disabled;                        ///< the enabled state from the last expression evaluation    /**     * For filters which will create hardware frames, sets the device the     * filter should create them in.  All other filters will ignore this field:     * in particular, a filter which consumes or processes hardware frames will     * instead use the hw_frames_ctx field in AVFilterLink to carry the     * hardware context information.     */    AVBufferRef *hw_device_ctx;    /**     * Max number of threads allowed in this filter instance.     * If <= 0, its value is ignored.     * Overrides global number of threads set per filter graph.     */    int nb_threads;    /**     * Ready status of the filter.     * A non-0 value means that the filter needs activating;     * a higher value suggests a more urgent activation.     */    unsigned ready;    /**     * Sets the number of extra hardware frames which the filter will     * allocate on its output links for use in following filters or by     * the caller.     *     * Some hardware filters require all frames that they will use for     * output to be defined in advance before filtering starts.  For such     * filters, any hardware frame pools used for output must therefore be     * of fixed size.  The extra frames set here are on top of any number     * that the filter needs internally in order to operate normally.     *     * This field must be set before the graph containing this filter is     * configured.     */    int extra_hw_frames;};

4.7 AVFilterLink : 链接结构体定义

libavfilter/avfilter.h/** *  两个滤镜之间的链接; *  如果两个滤镜是有链接的,则这个链接结构体包含有指向源滤镜与目的滤镜的指针, *  及 源滤镜的输出Pad,  和 目的滤镜的输入Pad 指针; *  另外,这个链接还包含有这个两个滤镜经过协商并匹配成功的参数,如图像的分辨率,格式等; * *  应用程序不能直接去访问链接结构体,而是使用 buffersrc   和  buffersink API 来访问,如: *   */struct AVFilterLink {    AVFilterContext *src;                                  ///<  指向和它相连的上游的源滤镜    AVFilterPad *srcpad;                                  ///<  源Pad ,  和上游源滤镜的 output_pad  相连    AVFilterContext *dst;                                 ///< 指向和它相连的下游的目的滤镜    AVFilterPad *dstpad;                                ///<  目的Pad,    和下游目目的滤镜的  innput_pad  相连     enum AVMediaType type;                        ///< Link的媒体类型       /*  视频相关参数 */    int w;                                                        ///< agreed upon image width    int h;                                                        ///< agreed upon image height    AVRational sample_aspect_ratio;            ///< agreed upon sample aspect ratio    /* 音频相关参数 */    uint64_t channel_layout;                         ///< channel layout of current buffer (see libavutil/channel_layout.h)    int sample_rate;                                      ///< samples per second    int format;                                               ///< 协商后并匹配成功的媒体格式 ID     /**     *  定义将通过此链接的 帧/样本的PTS表示用的 时钟基,      *  在配置阶段,每个滤镜应当只能改变输出的时钟基,而输入的时钟基是不可以更改的     */    AVRational time_base;    /*****************************************************************     *  下面的所有成员属性与函数都不是公开API,它们不能被 libavfilter的外部使用     *****************************************************************     */    /**     *  输入滤镜与输出滤镜支持的格式、通道布局、采样率列表,这些列表用是用于实际的格式协商。     *  当协商成功后,匹配的格式与通道布局将会更新上面的 format 、channel_layout 、sample_rate 成员属性;     */    AVFilterFormats                        *in_formats;    AVFilterFormats                        *out_formats;    AVFilterFormats                        *in_samplerates;    AVFilterFormats                        *out_samplerates;    struct AVFilterChannelLayouts  *in_channel_layouts;    struct AVFilterChannelLayouts  *out_channel_layouts;    /**     *  仅用于音频;     *  输出滤镜会设置它为一个非零值,用于请求将有设定数量的样本缓冲区发送给它。     *  此时,对应输入Pad的 AVFilterPad.needs_fifo  也要做设置;     *  EOF之前的最后一个buffer将会使用静音数据填充;     */    int request_samples;    /** stage of the initialization of the link properties (dimensions, etc) */    enum {        AVLINK_UNINIT = 0,        ///< not started        AVLINK_STARTINIT,        ///< started, but incomplete        AVLINK_INIT                    ///< complete    } init_state;    /**     * 滤镜所属的滤镜图;     */    struct AVFilterGraph *graph;    /**     * 本链接的当前时间戳,由最近的帧定义,单位是 上面的 time_base;     */    int64_t current_pts;    /**     *  本链接的当前时间戳,由最近的帧定义,单位是 AV_TIME_BASE (即ffmpeg内部使用的时钟基)     */    int64_t current_pts_us;    /**     * Index in the age array.     */    int age_index;    /**     * 本滤镜链的流的帧率,当帧率是未知或可变时,设为 {1/0};      * 如果设置为 {0/0}, 将会自动从源滤镜的输入复制得到;     *     * 源滤镜应当将其设置为实际帧率的最佳估值。     *  如果源滤镜帧率是未知或是可变的,则将其设置为 {1/0}.     *  如果有必要,滤镜应当在它的处理函数中更新这个值;     *  Sink型滤镜可以用它来设置默认的输出帧率;      * 它和 AVStream中 的 r_frame_rate 类似;     */    AVRational frame_rate;    /**     * Buffer partially filled with samples to achieve a fixed/minimum size.     *        */    AVFrame *partial_buf;    /**     * Size of the partial buffer to allocate.Must be between min_samples and max_samples.     *      */    int partial_buf_size;    /**     *  滤镜一次能处理的最小样本数。     *  如果调用  filter_frame() 函数  时 的样本数小于这个值时,那这个函数将会在 partial_buf中将这些样本累积起来。     *  这个属性值 及 相关的属性在滤镜初始化完成后就不能再更改了;     *  如果设置为零,则所有相关的属性都被忽略;     */    int min_samples;    /**     *  滤镜一次能处理的最大样本数。     *  如果调用 filter_frame() 函数时的 样本数大于这个值时,那这个函数要将样本切分后再处理;     */    int max_samples;    /**     * 音频通道的个数     */    int channels;    /**     * Link processing flags.  链接处理标志     */    unsigned flags;    /**     *  通过链接的输入的帧数,输出的帧数;     */    int64_t frame_count_in, frame_count_out;    /**     * A pointer to a FFFramePool struct.     */    void *frame_pool;    /**     * True if a frame is currently wanted on the output of this filter.     * Set when ff_request_frame() is called by the output,     * cleared when a frame is filtered.     *  如果当前帧希望从滤镜输出,则此值为真。     */    int frame_wanted_out;    /**     * For hwaccel pixel formats, this should be a reference to the     * AVHWFramesContext describing the frames.     */    AVBufferRef *hw_frames_ctx;#ifndef FF_INTERNAL_FIELDS    /**     * Internal structure members.     * The fields below this limit are internal for libavfilter's use     * and must in no way be accessed by applications.     */    char reserved[0xF000];#else /* FF_INTERNAL_FIELDS */    /**     * Queue of frames waiting to be filtered.     */    FFFrameQueue fifo;    /**     * If set, the source filter can not generate a frame as is.     * The goal is to avoid repeatedly calling the request_frame() method on     * the same link.     */    int frame_blocked_in;    /**     * Link input status.     * If not zero, all attempts of filter_frame will fail with the     * corresponding code.     */    int status_in;    /**     * Timestamp of the input status change.     */    int64_t status_in_pts;    /**     * Link output status.     * If not zero, all attempts of request_frame will fail with the     * corresponding code.     */    int status_out;#endif /* FF_INTERNAL_FIELDS */};

4.8. AVFilterPad结构体定义

/** * @addtogroup lavu_media Media Type * @brief Media Type */enum AVMediaType {    AVMEDIA_TYPE_UNKNOWN = -1,  ///< Usually treated as AVMEDIA_TYPE_DATA    AVMEDIA_TYPE_VIDEO,    AVMEDIA_TYPE_AUDIO,    AVMEDIA_TYPE_DATA,          ///< Opaque data information usually continuous    AVMEDIA_TYPE_SUBTITLE,    AVMEDIA_TYPE_ATTACHMENT,    ///< Opaque data information usually sparse    AVMEDIA_TYPE_NB};/**  *  一个 filter pad 就是一个滤镜的输入/输出端口 */struct AVFilterPad {    /**     *  Pad名称, 在输入列表,或输出列表内部必须是唯一的,但输入列表,输出列表之间可以重名。     *  如果 这个 Pad  不会被以名称引用,则其值可以为NULL。     */    const char *name;    /**     * AVFilterPad 类型      */    enum AVMediaType type;    /**     *  获得一个视频 buffer的回调函数,如果为空,则滤镜系统会使用默认的  ff_default_get_video_buffer();      *   只对输入的视频 Pad 有效     */    AVFrame *(*get_video_buffer)(AVFilterLink *link, int w, int h);    /**     *  获得一个音频 buffer的回调函数,如果为空,则滤镜系统会使用默认的 ff_default_get_audio_buffer();      * 只对输入的 音频 Pad 有效     */    AVFrame *(*get_audio_buffer)(AVFilterLink *link, int nb_samples);    /**     *  调用滤镜进行处理的回调函数:当滤镜收到一帧 音频/视频 数据时,就要调用它进行处理。     *  它是滤镜处理的真正入口 , 只在输入 pad中使用;     *     *  返回值: >=0, 表示成功,负数,为AVERROR的错误。    *  这个函数必须确保 当滤镜的处理出现错误时未被不合适地引用,且不会将错误传递到下一个滤镜     */    int (*filter_frame)(AVFilterLink *link, AVFrame *frame);    /**     * Frame poll callback. This returns the number of immediately available     * samples. It should return a positive value if the next request_frame()     * is guaranteed to return one frame (with no delay).     *     * Defaults to just calling the source poll_frame() method.     *        * Output pads only.     *  回调函数: 帧轮询的回调函数, 它返回当前有效的样本个数;  只对输出Pad有效;     *  如果下一个 request_frame()函数是有帧数据返回,则它应该返回一个正数值;     */    int (*poll_frame)(AVFilterLink *link);    /**     * Frame request callback. A call to this should result in some progress     * towards producing output over the given link. This should return zero     * on success, and another value on error.     *     * Output pads only.     *   回调函数: 帧请求回调函数。只对输出Pad有效;     *   如果调用 了这个回调函数,应当在给定的link上生成经过处理后的输出数据;     *   返回值: 0,表示成功;否则为错误值;     */    int (*request_frame)(AVFilterLink *link);    /**     *   回调函数:  用于link的配置的回调函数     *   对于 输出 Pad, 它应当设置 link的属性,如  width/height等。     *   不要在这里设置 格式 属性;     *   因为格式属性是由滤镜系统调用这个回调函数之前,调用query_formats() 回调函数在滤镜间进行协调得到的。     *   对于输入 pad, 这个回调函数是用检查 link的属性,并由此更新滤镜内部的相关状态;     *       *  对于既有输入,又有输出的滤镜,这个回调函数在成功时返回零,其它返回值为出错。     */    int (*config_props)(AVFilterLink *link);    /**     * 这个滤镜需要有一个 FIFO插入它的输入link,通常是因为这个滤镜会有一个延迟的动作。     *   只在输入pad中使用     */    int needs_fifo;    /**     * 这个滤镜需要从它的输入 link中得到一个可写的帧,如果有需要,会复制数据buffer     *  只在输入pad中使用     */    int needs_writable;};

 

 

转载地址:http://znctd.baihongyu.com/

你可能感兴趣的文章
前端基础技术_浏览器同源政策(same-origin policy)及其规避方法
查看>>
前端基础技术_跨域资源共享(Cross-origin resource sharing)CORS
查看>>
Idea中初次部署 “若依RuoYI-Vue” 框架
查看>>
互联网常见坐标之间的转换(Python)
查看>>
高可用方案架构梳理-概念架构(数据库)
查看>>
理解SVN中trunk,branches,tags
查看>>
VS2012[Web应用程序项目***已配置为使用IIS。无法访问IIS元数据库]
查看>>
VS2003:您试图打开的项目是Web项目
查看>>
SQL2000:安装程序配置服务器失败
查看>>
SQL2000 突然“不能执行查询,因为一些文件丢失或未注册”
查看>>
System.Web.Optimization找不到引用
查看>>
如何给asp.net表单提交前置和后置函数
查看>>
不安装Office操作Excel文件(.xlsx)
查看>>
SQL Server 2005 不允许远程连接解决方法
查看>>
C# 编码规范
查看>>
如何考虑一个GIS项目——对GIS进行规划
查看>>
C#数据库连接字符串——dBase Dbf
查看>>
C#数据库连接字符串——Sybase
查看>>
C#数据库连接字符串——Informix
查看>>
C#数据库连接字符串——Excel
查看>>