FFmpeg源码分析:AVFilterGraph与AVFilter

FFmpeg在libavfilter模块提供简单与复杂的音视频滤镜,所有滤波器由AVFilterGraph滤波器图表连接起来。简单滤镜为一对一输出,复杂滤镜为多对一输出。重要的结构体包括:AVFilterGraph、AVFilterLink、AVFilterContext、AVFilter。支持在滤波器图表指定位置插入AVFilter滤波器,然后由AVFilterLink把滤波器连接起来。

1、AVFilterGraph

AVFilterGraph为滤波器图表结构体,保存滤波器上下文、滤波器数量、线程类型、线程数量、回调函数等,代码位于libavfilter/avfilter.h头文件中:

typedef struct AVFilterGraph {
   
    const AVClass *av_class;
	// 滤波器上下文
    AVFilterContext **filters;
	// 滤波器数量
    unsigned nb_filters;
 
    char *scale_sws_opts;
    int thread_type;
    int nb_threads;
    AVFilterGraphInternal *internal;
    void *opaque;
    // 用户设置的回调函数
    avfilter_execute_func *execute;
 
    char *aresample_swr_opts;
    AVFilterLink **sink_links;
    int sink_links_count;
    unsigned disable_auto_convert;
} AVFilterGraph;

2、AVFilterLink

AVFilterLink为滤波器的连接器,负责把两个滤波器连接起来,内部包含指向源滤波器和目标滤波器的指针。需要注意的是,应用程序不能直接访问AVFilterLink,使用buffersrc和buffersink的API代替。代码同样位于avfilter.h头文件中:

struct AVFilterLink {
   
	// 源滤波器上下文
    AVFilterContext *src;
    AVFilterPad *srcpad;
    // 目标滤波器上下文
    AVFilterContext *dst;
    AVFilterPad *dstpad;
    // 媒体类型
    enum AVMediaType type;
 
    // 视频参数
    int w;
    int h;
    AVRational sample_aspect_ratio;
    // 音频参数
    uint64_t channel_layout;
    int sample_rate;
    int format;
    // pts的时间基
    AVRational time_base;
 
    AVFilterFormatsConfig incfg;
    AVFilterFormatsConfig outcfg;
 
    // 连接器的初始化状态
    enum {
   
        AVLINK_UNINIT = 0, // 没初始化
        AVLINK_STARTINIT,  // 已初始化,没完成
        AVLINK_INIT        // 已完成初始化
    } init_state;
 
    struct AVFilterGraph *graph;
    // 当前pts时间戳
    int64_t current_pts;
    int64_t current_pts_us;
    int age_index;
    AVRational frame_rate;
    AVFrame *partial_buf;
    int partial_buf_size;
    int min_samples;
    int max_samples;
    int channels;
    int64_t frame_count_in, frame_count_out;
    void *frame_pool;
    int frame_wanted_out;
    AVBufferRef *hw_frames_ctx;
 
#ifndef FF_INTERNAL_FIELDS
 
    // 内部数据结构(保留)
    char reserved[0xF000];
 
#else /* FF_INTERNAL_FIELDS */
 
    // 滤波器的帧队列
    FFFrameQueue fifo;
    frame_blocked_in;
    int status_in;
    int64_t status_in_pts;
    int status_out;
 
#endif /* FF_INTERNAL_FIELDS */
};

3、AVFilterContext

AVFilterContext为滤波器上下文的结构体,包含滤波器实例、名字、输入Pad和Link、输出Pad和Link,还有ready字段表示滤波器准备就绪且带有优先级。具体代码如下:

struct AVFilterContext {
   
    const AVClass *av_class;
    // 滤波器实例
    const AVFilter *filter;
    // 滤波器名字
    char *name;
 
    AVFilterPad   *input_pads;
    AVFilterLink **inputs;
    unsigned    nb_inputs;
    AVFilterPad   *output_pads;
    AVFilterLink **outputs;
    unsigned    nb_outputs;
 
    void *priv;
    struct AVFilterGraph *graph;
    int thread_type;
    AVFilterInternal *internal;
    struct AVFilterCommand *command_queue;
    char *enable_str;
    void *enable;
    double *var_values;
    int is_disabled;
    AVBufferRef *hw_device_ctx;
    int nb_threads;
 
    // 滤波器准备就绪,带优先级
    unsigned ready;
    int extra_hw_frames;
};

4、AVFilter

AVFilter为滤波器的结构体,包含滤波器名字与描述、输入输出的AVFilterPad、滤波器操作的函数指针。具体代码如下:

typedef struct AVFilter {
   
    // 滤波器名字
    const char *name;
    // 滤波器描述
    const char *description;
    const AVFilterPad *inputs;
    const AVFilterPad *outputs;
    const AVClass *priv_class;
    int flags;
    int priv_size;
    int flags_internal;
 
    // 预初始化函数指针
    int (*preinit)(AVFilterContext *ctx);
    // 初始化函数指针
    int (*init)(AVFilterContext *ctx);
    // 带字典参数的初始化函数指针
    int (*init_dict)(AVFilterContext *ctx, AVDictionary **options);
    // 反初始化函数指针
    void (*uninit)(AVFilterContext *ctx);
    // 查询滤波器支持的输入输出格式
    int (*query_formats)(AVFilterContext *);
    // 处理命令函数指针
    int (*process_command)(AVFilterContext *, const char *cmd, 
	    const char *arg, char *res, 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值