音视频基础 (九)---FFmpeg过滤器框架

ffmpeg的filter⽤起来是和Gstreamer的plugin是⼀样的概念,通过avfilter_link,将各个创建好的filter按
⾃⼰想要的次序链接到⼀起,然后avfilter_graph_config之后,就可以正常使⽤。
⽐较常⽤的滤镜有:scale、trim、overlay、rotate、movie、yadif。scale 滤镜⽤于缩放,trim 滤镜⽤
于帧级剪切,overlay 滤镜⽤于视频叠加,rotate 滤镜实现旋转,movie 滤镜可以加载第三⽅的视频,
yadif 滤镜可以去隔⾏

1、主要结构体和API介绍

1.1 AVFilterGraph-对filters系统的整体管理

AVFilterGraph是FFmpeg中用于管理音视频滤镜的数据结构。它表示一个完整的滤镜图,可以包含多个输入输出,并通过连接不同的滤镜节点来实现各种音视频处理操作。

AVFilterGraph提供了创建、配置和管理滤镜的接口,允许用户构建复杂的滤镜拓扑结构,以实现音视频的处理和编辑。通AVFilterGraph,用户可以添加各种滤镜(如变换、剪切、合并、调节等)并将它们连接起来,最终实现所需的音视频处理效果。

在使用AVFilterGraph时,通常的流程包括创建滤镜图、添加输入输出流、添加滤镜节点、连接滤镜节点、设置参数等。一旦完成了滤镜图的构建,就可以将音视频帧送入滤镜图进行处理,最终得到处理后的输出。
**重点
struct AVFilterGraph
{
AVFilterContext filters;
unsigned nb_filters;
}

1.2 AVFilter-定义filter本身的能⼒

AVFilter 是 FFmpeg 中用于实现音视频滤镜的基本单位。它代表了一个特定的音视频处理功能,比如色彩转换、尺寸调整、去噪等。AVFilter 可以单独使用,也可以通过 AVFilterGraph 组合成复杂的滤镜链。
AVFilter 结构的作用主要是定义了一个滤镜的基本属性和行为,以及提供了滤镜初始化、销毁、格式查询等相关的回调函数接口。通过这些接口,用户可以对滤镜进行初始化配置,并将其应用到音视频流数据上,实现各种音视频处理效果。

在使用 AVFilter 时,通常的步骤包括:

  • 创建 AVFilterContext 对象,表示一个具体的 AVFilter 实例。
  • 设置滤镜参数和选项,可以通过 priv_class定义的私有类进行配置。
  • 连接输入输出端口,将 AVFilterContext 对象连接到其他滤镜或音视频流中。
  • 将音视频帧数据送入滤镜进行处理,得到处理后的输出数据。

重点
**const char *name; // overlay
const AVFilterPad inputs;
const AVFilterPad outputs;

typedef struct AVFilter {
    const char *name;			//滤镜的名称,用于唯一标识滤镜。
    const char *description;	//对滤镜功能的文字描述。
    const AVFilterPad *inputs;	//
    const AVFilterPad *outputs;
    const AVClass *priv_class; //用于指定滤镜的私有类,定义了滤镜的参数和选项。
    int flags;
    int (*preinit)(AVFilterContext *ctx);
    int (*init)(AVFilterContext *ctx);	//用于初始化滤镜的回调函数,可以在滤镜被创建时执行一些初始化操作。
    int (*init_dict)(AVFilterContext *ctx, AVDictionary **options);
    void (*uninit)(AVFilterContext *ctx);	//用于销毁滤镜的回调函数,在滤镜不再需要时执行清理操作。
    int (*query_formats)(AVFilterContext *);	//用于查询支持的输入输出格式的回调函数。
    int priv_size;      //滤镜私有数据的大小,用于分配存储私有数据的内存空间。
    int flags_internal; ///< Additional flags for avfilter internal use only.
    struct AVFilter *next;
    int (*process_command)(AVFilterContext *, const char *cmd, const char *arg, char *res, int res_len, int flags);
    int (*init_opaque)(AVFilterContext *ctx, void *opaque);
    int (*activate)(AVFilterContext *ctx);
} AVFilter;

1.3 AVFilterContext-filter实例,管理filter与外部的联系

AVFilterContext 是 FFmpeg 中用于表示一个特定 AVFilter 实例的数据结构。它包含了一个 AVFilter 的所有信息和状态,以便在音视频处理中对该滤镜进行配置、连接和处理。
AVFilterContext 结构的作用是管理一个 AVFilter 实例的输入输出端口,通过输入端口接收数据并经过滤镜处理后输出到输出端口。它还负责与滤镜图(AVFilterGraph)进行交互,将滤镜上下文与其他滤镜连接起来以实现复杂的音视频处理链。

在使用 AVFilterContext 时,通常的步骤包括:

  • 创建 AVFilterContext 对象,可以通过 avfilter_alloc_context() 函数创建。
  • 配置 AVFilterContext 的输入输出端口,可以通过 avfilter_link() 函数连接输入输出端口。
  • 设置滤镜参数和选项,可以通过 AVFilterContext 的属性进行配置。
  • 将音视频帧数据送入 AVFilterContext 进行处理,得到处理后的输出数据。

**重点
struct AVFilterContext
{
const AVFilter *filter;
char *name;
AVFilterPad *input_pads;
AVFilterLink **inputs;
unsigned nb_inputs
AVFilterPad *output_pads;
AVFilterLink *outputs;
unsigned nb_outputs;
struct AVFilterGraph graph; // 从属于哪个AVFilterGraph
}

1.4 AVFilterLink-定义两个filters之间的联接

AVFilterLink用于连接滤镜图中两个滤镜之间的输入和输出。它包含了连接两个滤镜所需的所有信息,例如输入和输出的样本格式、缓冲区、时间戳等等。AVFilterLink还包含了有关滤镜链中帧的信息,如PTS(Presentation Time Stamp,显示时间戳)和DTS(Decoding Time Stamp,解码时间戳)。通过AVFilterLink,不同的滤镜可以在滤镜图中相互连接,从而实现视频和音频处理的各种功能。

**重点
struct AVFilterLink
{
AVFilterContext *src;
AVFilterPad *srcpad;
AVFilterContext *dst;
AVFilterPad dstpad;
struct AVFilterGraph graph;
}

1.5 AVFilterPad-定义filter的输⼊/输出接⼝

AVFilterPad是FFmpeg中的结构,用于描述滤镜的输入或输出端口。滤镜可以有多个输入和输出端口,每个端口都由一个AVFilterPad结构表示。该结构包含了端口的名称、类型(输入或输出)、滤镜所支持的样本格式、是否支持多通道等信息。
在滤镜图中,滤镜之间的连接通过连接它们的输入和输出端口来实现。因此,AVFilterPad在滤镜之间建立连接时起到了关键的作用。通过AVFilterPad,FFmpeg能够正确地识别滤镜之间的连接,从而实现音视频数据的流动和处理。
**重点
struct AVFilterPad
{
const char *name;
AVFrame *(*get_video_buffer)(AVFilterLink *link, int w, int h);
AVFrame *(*get_audio_buffer)(AVFilterLink *link, int nb_samples);
int (*filter_frame)(AVFilterLink *link, AVFrame *frame);
int (request_frame)(AVFilterLink link);
}

1.6AVFilterInOut-过滤器链输⼊/输出的链接列表

在AVFilter模块中定义了AVFilter结构,很个AVFilter都是具有独⽴功能的节点,如scale filter的作⽤就是进⾏图像尺⼨变换,overlay filter的作⽤就是进⾏图像的叠加。
这⾥需要重点提的是两个特别的filter,⼀个是buffer,⼀个是buffersink,

  • 滤波器buffer代表filter graph中的源头,原始数据就往这个filter节点输⼊的;
  • ⽽滤波器buffersink代表filter graph中的输出节点,处理完成的数据从这个filter节点输出。
typedef struct AVFilterInOut {
	/** unique name for this input/output in the list */
	char *name;
	/** filter context associated to this input/output */
	AVFilterContext *filter_ctx;
	/** index of the filt_ctx pad to use for linking */
	int pad_idx;
	/** next input/input in the list, NULL if this is the last */
	struct AVFilterInOut *next;
} AVFilterInOut;

2、函数使用

2.1 获取指定名称的滤镜–avfilter_get_by_name

// 获取FFmpeg中定义的filter,调⽤该⽅法前需要先调⽤avfilter_register_all();进⾏滤波器注册
AVFilter avfilter_get_by_name(const char name);
如果找到了指定名称的滤镜,该函数将返回一个指向对应AVFilter结构体的指针。如果未找到匹配的滤镜,函数将返回NULL。

2.2 向FFmpeg中的缓冲源滤镜(Buffer Source Filter)添加视频帧或音频帧–av_buffersrc_add_frame

/*
 *参数ctx是指向Buffer Source Filter的AVFilterContext结构体指针,通过它可以访问和控制Buffer Source Filter的属性和状态。
 *参数frame是要添加到Buffer Source Filter中的AVFrame结构体指针,它包含了要添加的视频帧或音频帧的数据和相关信息。
 *函数返回一个整数值,表示操作是否成功。如果成功添加帧数据,则返回0;如果发生错    误,则返回负值。
 */
int av_buffersrc_add_frame(AVFilterContext ctx, AVFrame frame);

通过调用av_buffersrc_add_frame函数,你可以将视频帧或音频帧添加到Buffer Source Filter中,从而使得该帧数据成为滤镜链的输入。

2.3 从缓冲汇滤镜(Buffer Sink Filter)中获取输出帧数据–

av_buffersink_get_frame

/* 
 *参数 ctx 是指向 Buffer Sink Filter 的 AVFilterContext 结构体指针,通过它可以访问和控制 Buffer Sink Filter 的属性和状态。
 *函数返回一个指向 AVFrame 结构体的指针,该结构体包含了从 Buffer Sink Filter 中获取的输出帧数据。如果没有可用的输出帧数据,函数将返回 NULL。
 */
int av_buffersink_get_frame(AVFilterContext ctx, AVFrame frame);

2.4 分配并初始化一个空的滤镜图–avfilter_graph_alloc

//分配并初始化一个空的滤镜图`在这里插入代码片`
AVFilterGraph *avfilter_graph_alloc(void);

在使用滤镜图进行音视频处理时,首先需要通过 avfilter_graph_alloc 分配一个滤镜图,然后在该滤镜图上添加各种滤镜节点,构建滤镜链,最后配置和链接这些滤镜节点,从而完成音视频处理任务。

2.5 在滤镜图中创建一个新的滤镜–avfilter_graph_create_filter

/* 
 * filt_ctx: 指向指针的指针,用于返回创建的滤镜实例的 AVFilterContext 结构体指针。
 * filt: 要创建的滤镜的 AVFilter 结构体指针。
 * name: 滤镜实例的名称。
 * args: 滤镜实例的参数,可以是滤镜实例初始化时需要的参数字符串。
 * opaque: 不透明指针,可以传递给滤镜的初始化函数。
 * graph_ctx: 滤镜图的上下文 AVFilterGraph 结构体指针,表示滤镜实例将要被添加到的滤镜图。
 * 该函数返回一个整数值,表示操作是否成功。如果成功创建滤镜实例并将其添加到滤镜图中,则返回0;如果发生错误,则返回负值。
 */
int avfilter_graph_create_filter(AVFilterContext **filt_ctx, 
								const AVFilter *filt,const char name, 
								const char args, void *opaque,
								AVFilterGraph *graph_ctx);

avfilter_graph_create_filter函数用于在滤镜图中创建一个新的滤镜实例,并将其添加到滤镜链中。通过调用 avfilter_graph_create_filter 函数,可以在滤镜图中创建一个指定类型的滤镜实例,并配置其参数。

2.6 在滤镜图中连接两个滤镜–avfilter_link

/*
 * src: 源滤镜的 AVFilterContext 结构体指针,表示连接的起始滤镜。
 * srcpad: 源滤镜的输出端口索引,表示连接的起始滤镜的输出端口。
 * dst: 目标滤镜的 AVFilterContext 结构体指针,表示连接的目标滤镜。
 * dstpad: 目标滤镜的输入端口索引,表示连接的目标滤镜的输入端口。
 * 该函数返回一个整数值,表示连接是否成功。如果成功连接两个滤镜,则返回0;如果发生错误,则返回负值。
 */ 
int avfilter_link(AVFilterContext *src, unsigned srcpad,AVFilterContext *dst, unsigned dstpad);

通过调用 avfilter_link 函数,可以在滤镜图中连接两个滤镜,从而构建滤镜链。连接的源滤镜的输出端口将与目标滤镜的输入端口相连。连接后,数据将从源滤镜流向目标滤镜,进行进一步的处理。

3、 AVFilter主体框架流程

在利⽤AVFilter进⾏⾳视频数据处理前先将在进⾏的处理流程绘制出来,现在以FFmpeg filter官⽅⽂档中的⼀个例⼦为例进⾏说明。
在这里插入图片描述
这个例⼦的处理流程如上所示,⾸先使⽤split滤波器将input流分成两路流(main和tmp),然后分别对两路流进⾏处理。对于tmp流,先经过crop滤波器进⾏裁剪处理,再经过flip滤波器进⾏垂直⽅向上的翻转操作,输出的结果命名为flip流。再将main流和flip流输⼊到overlay滤波器进⾏合成操作。上图的input就是上⾯提过的buffer源滤波器,output就是上⾯的提过的buffersink滤波器。上图中每个节点都是⼀个AVFilterContext,每个连线就是AVFliterLink。所有这些信息都统⼀由AVFilterGraph来管理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/503991.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Rabbit简单模式理解

简单模式 我们以最普通的方式去理解&#xff0c;并没有整合Springboot的那种 这是最简单的模式&#xff0c;一个生产者&#xff0c;一个消费者&#xff0c;一个队列 测试 1、 导包&#xff0c;没整合&#xff0c;不需要编写配置 2、需要生产者消费者 导包 <dependency…

深度学习:基于PyTorch的模型解释工具Captum

深度学习&#xff1a;基于PyTorch的模型解释工具Captum 引言简介示例安装解释模型的预测解释文本模型情绪分析问答 解释视觉模型特征分析特征消融鲁棒性 解释多模态模型 引言 当我们训练神经网络模型时&#xff0c;我们通常只关注模型的整体性能&#xff0c;例如准确率或损失函…

cocos2.x => node 属性修改

简介 与节点属性相关的几个核心变量_trs、_matrix、_worldMatrix、_localMatDirty、_worldMatDirty。 _trs&#xff1a;存储节点的position、rotation、scale _matrix&#xff1a;存储节点的缩放、位移、旋转三者合一的变化矩陈&#xff08;仿射矩陈&#xff09; _worldMat…

csp资料

头文件 #include <bits/stdc.h> using namespace std isdigit(c); isalpha(c); switch(type){case value : 操作 } continue;//结束本轮循环 break;//结束所在的整个循环tips: //除法变乘法来算 //减法变加法 num1e42;//"1e4"表示10的4次方//用于移除容器中相…

【面试专题】MySQL

1.什么是BufferPool&#xff1f; Buffer Pool基本概念 Buffer Pool&#xff1a;缓冲池&#xff0c;简称BP。其作用是用来缓存表数据与索引数据&#xff0c;减少磁盘IO操作&#xff0c;提升效率。 Buffer Pool由缓存数据页(Page) 和 对缓存数据页进行描述的控制块 组成, 控制…

鹏哥C语言复习——指针

目录 一.指针基础概念 二.指针和指针类型 三.野指针介绍 四.规避野指针的办法 五.指针运算 六.指针和数组 七.指针和数组传参 八.二级指针 九. 函数指针 十.qsort( )函数 十一.字符指针 一.指针基础概念 指针是什么&#xff1f; 指针理解的2个要点&#xff1a; 1.指…

java内存分析工具visualvm

java内存分析工具visualvm 下载地址:https://visualvm.github.io/

开源推荐榜【Taichi 专为高性能计算机图形学设计的编程语言】

Taichi是一个高性能的并行编程语言&#xff0c;它被嵌入在Python中&#xff0c;使得开发者能够轻松编写可移植的、高性能的并行程序。这个库的核心优势在于它能够将计算密集型的Python代码在运行时通过即时编译器(Just-In-Time, JIT)转换成快速的机器代码&#xff0c;从而加速P…

MT9630全制式Android智能商显解决方案

一、方案描述 商用显示通常是指专业显示器设备&#xff0c;可靠性和高清晰显示能力远强于普通显示器&#xff0c;在成像处理与色彩、亮度和对比度还有可视视角几方面具备优势&#xff0c;主要应用于商业场景&#xff0c;中国商业显示市场细分产品包括电子白板、商用电视、广告…

012_control_flow_in_Matlab中的控制流

Matlab中的控制流 虽然&#xff0c;我们说Matlab中的计算是向量化的&#xff0c;但是在某些情况下&#xff0c;作为一个“程序设计语言”&#xff0c;Matlab也提供了一些控制流结构&#xff0c;来帮助我们实现一些复杂的逻辑。 我会在介绍控制流的时候&#xff0c;提醒如何用…

大数据学习-2024/3/30-MySQL5.6版本的安装

1、下载好文件后打开bin目录&#xff1a; 2、在这个位置进入输入cmd进入命令行界面&#xff0c;进入命令行界面后输入如下&#xff1a;mysqld install 进行数据库安装&#xff1a; 注意&#xff1a;显示Service successfully installed表示安装成功 3、安装好后启动服务&…

通过mapreduce程序统计旅游订单(wordcount升级版)

通过mapreduce程序统计旅游订单&#xff08;wordcount升级版&#xff09; 本文将结合一个实际的MapReduce程序案例&#xff0c;探讨如何通过分析旅游产品的预订数据来揭示消费者的偏好。 程序概览 首先&#xff0c;让我们来看一下这个MapReduce程序的核心代码。这个程序的目…

上门家政按摩H5小程序源码

《服务器环境配置》 1、服务器环境&#xff1a;CentOS7 宝塔 Nginx php 2、环境&#xff1a;PHP7.2 MySQL5.6 3、安装扩展&#xff1a;fileinfo、redis 《程序安装配置》 1、新建站点及数据库&#xff0c;然后申请创建SSL证书&#xff0c;配置到站点&#xff0c;开启强…

GT20L16S1Y标准汉字字库芯片完全解析(3)

接前一篇文章&#xff1a;GT20L16S1Y标准汉字字库芯片完全解析&#xff08;2&#xff09; 本文内容参考&#xff1a; 字库芯片GT20L16S1Y使用记录-CSDN博客 GT20L16S1Y字库IC驱动_gt20l16s1y字库芯片测试程序-CSDN博客 《GT20L16S1Y 标准点阵汉字库芯片产品规格书 V4.0I_K 2…

信息工程大学第五届超越杯程序设计竞赛 题解

信息工程大学第五届超越杯程序设计竞赛 \huge{信息工程大学第五届超越杯程序设计竞赛} 信息工程大学第五届超越杯程序设计竞赛 写在前面 本篇题解按照题目难易顺序进行排序 大致难易顺序为&#xff1a;A<M<F<D<C<E<G<K<H<B<I<J A. 遗失的…

PCL点云处理之 基于垂直度检测与距离聚类 的路面点云提取方案 (二百三十九)

PCL点云处理之 基于垂直度检测与距离聚类 的路面点云提取方案 (二百三十九) 一、算法流程二、具体步骤1.垂直度检测与渲染1.代码2.效果2.水平分布点云提取1.代码2.效果3.路面连通点云提取1.代码2.效果三、完整代码四、参考文献一、算法流程

开发指南020-banner

<dependency><groupId>org.qlm</groupId><artifactId>qlm-common</artifactId><version>1.0-SNAPSHOT</version> </dependency> 以上组件封装了平台的banner&#xff0c;不做任何配置的话&#xff0c;将输出平台的banner 想修…

如何过得更幸福?我推荐你读这5本书

快乐不等于幸福。快乐是一种短暂的体验&#xff0c;随着多巴胺的消退而迅速减退。快乐是有捷径的&#xff0c;那就是戏弄相关的神经回路。 幸福是有意义、有目的和积极的生活的持久体验。 今天&#xff0c;为大家推荐一份“幸福书单”。 01 《幸福的勇气》 岸见一郎、古贺史…

【Linux实践室】Linux用户管理实战指南:用户权限切换操作详解

&#x1f308;个人主页&#xff1a;聆风吟_ &#x1f525;系列专栏&#xff1a;Linux实践室、网络奇遇记 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 一. ⛳️任务描述二. ⛳️相关知识2.1 &#x1f514;图形化界面登录2.2 &#x1f514;使用login…

OSCP靶场--Twiggy

OSCP靶场–Twiggy 考点(CVE-2020-11651[RCE]) 1.nmap扫描 ## ┌──(root㉿kali)-[~/Desktop] └─# nmap 192.168.216.62 -sV -sC -Pn --min-rate 2500 -p- Starting Nmap 7.92 ( https://nmap.org ) at 2024-03-30 06:43 EDT Nmap scan report for 192.168.216.62 Host i…