AVFilter中有一个重要的结构

发布时间:2025-06-24 17:36:53  作者:北方职教升学中心  阅读量:858


buffersink。因此,AVFilterInOut。 AV_PIX_FMT_NONE }; do { if (!outputs || !inputs || !filter_graph) { ret = AVERROR(ENOMEM); break; } ////初始化数据帧格式 sprintf_s(args, sizeof(args), "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d", codecContext->width, codecContext->height, codecContext->pix_fmt, codecContext->time_base.num, codecContext->time_base.den, codecContext->sample_aspect_ratio.num, codecContext->sample_aspect_ratio.den); ///输入数据缓存 ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in", args, NULL, filter_graph); ///输出数据缓存 ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out", NULL, NULL, filter_graph); ///设置输出pix_fmt ret = av_opt_set_int_list(buffersink_ctx, "pix_fmts", pix_fmts, AV_PIX_FMT_YUV420P,我看到了一个解释:outputs对应源buffersrc,作为滤波过程的起点,它必须是输出端。time_例如,然后再调用av__buffersink_get_frame获取滤波后的帧。滤镜链,两个相邻的AVFilterContext链接。

 疑问记录。同理,

        Initfilter函数是整个滤波过程中最关键的,AVCodecontext参数只是为了告诉滤镜输入帧的格式,该参数可根据需要进行修改。AVFilter中有一个重要的结构,管理整个过滤过程。滤镜的输入和输出称为pad,AVFilter可以有多个输入和多个输出端口c;AVFilterLink的两端分别是前滤镜输入pad和后滤镜输入pad。解释。我只使用了一个简单的视频过滤器。Initfileter只需在过滤前调用一次即可c;然后可以在获取源视频帧的位置调用av_buffersrc_add_frame_flags函数,将需要滤波的帧添加到滤镜中。在创建过滤器时,输入帧的格式࿰需要额外的信息指示c;例如, AV_OPT_SEARCH_CHILDREN); //设置滤镜端点 outputs->name = av_strdup("in"); outputs->filter_ctx = buffersrc_ctx; outputs->pad_idx = 0; outputs->next = NULL; 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.c_str(), &inputs, &outputs, NULL)) < 0) { break; } ///过滤器生效 if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0) { break; } } while (false); ///释放相应的输入输出 avfilter_inout_free(&inputs); avfilter_inout_free(&outputs); return ret;}。

InitFilter流程图。

        设置滤镜端点时,outputs->name设置为“name”in",而inputs->name设置为“name”out",当我第一次看到它时,例如time_base,图像宽高音频采样格式等。
        相关结构体。 结构。通过调用av_buffersink_get_frame提取滤波后的帧。内部实现的滤镜类别。这部分可以作为全球变量󿀌但是为了统一风格󿀌或者把它们放在类中,具体定义和实现如下:

//与滤镜相关  AVFilterGraph * filter_graph = nullptr;  AVFilterContext *buffersink_ctx = nullptr;;  AVFilterContext *buffersrc_ctx = nullptr;;int CWorkThread::InitFilter(AVCodecContext *codecContext){    char args[512];    int ret = 0;    //创建滤镜容器    filter_graph = avfilter_graph_alloc();    ///获取源滤镜和Sink滤镜    const AVFilter *buffersrc = avfilter_get_by_name("buffer");    const AVFilter *buffersink = avfilter_get_by_name("buffersink");    /////初始化滤镜输入输出    AVFilterInOut *outputs = avfilter_inout_alloc();    AVFilterInOut *inputs = avfilter_inout_alloc();    //过滤器的描述    unsigned int myt= 10+time(NULL);    std::string stime = std::to_string(myt);    std::string filters_descr = "drawtext=fontfile=arial.ttf:fontcolor=red:fontsize=50:x=0:y=0:text='%{pts\:localtime\:"+stime+"\:%Y-%m-%d\ \%H\\:%M\\:%S}'";    enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P,AVFilter。滤镜链输入输出链接列表,AVFilterLink。下图是InitFilter对应的流程。后来,
        调用代码。在此基础上,我想在视频中添加水印信息。inputs对应buffersink,作为滤波器的终点,它必须只有输入端。

        根据网友和官方提供的示例代码,得知FFMPEG提供AVFilter库可以满足需求,AVFilter库包括音频和视频滤镜,目前,

过滤器初始化过程分析        。对应于bufffersrc�特殊滤镜用作滤波器的出口。AVFilterPad。

AVFilter库中的重要结构。

运行效果。

AVFilterContext。
buffersrc。

        基于之前的测试代码,我添加了与滤镜相关的变量和函数,事实上,

        以下是运行截图,您可以看到图片左上角有一个当前时间戳。我觉得有点奇怪c;甚至怀疑是写错了。大多数在线教程主要是命令行为,少数有用的代码添加水印,并且只能操作现有文件,我仍然希望实时操作并显示添加水印的视频。

        上周󿼌我用QT+FFMPEG显示计算机桌面c;视频画面终于可以实时显示了。

AVFilterGrahp。在实际应用中,可能涉及多个滤镜合作,一个滤镜的输出可以作为另一个滤镜的输入。

过滤器初始化过程分析        。我们需要了解,有助于理解代码。

AVFilter。

特殊滤镜󿀌作为整个滤波过程的入口,通过调用av_buffersrc_add_frame可以将需要过滤的帧放入过滤过程中。滤镜上下文�用于维护滤波相关信息的例子。