使用FFmpeg的AVFilter转换YUV到RGB

ops/2024/9/19 11:53:21/ 标签: ffmpeg

AVFilter 是 FFmpeg 库 libavfilter 的核心组件,提供了一套强大的音视频处理框架,用于对音视频流进行复杂的过滤、转换和效果处理。通过 AVFilter,开发者可以构建自定义的滤镜图(filter graph),实现各种音视频处理任务,如颜色空间转换、缩放、裁剪、特效添加等。

以下是对 AVFilter 的详细介绍,包括其架构、关键概念、使用方法以及示例代码。

1. AVFilter 概述

AVFilter 是 FFmpeg 提供的一个模块化框架,允许用户将多个滤镜(filters)串联起来,形成一个滤镜图(filter graph),以对音视频数据进行逐步处理。滤镜图定义了数据流的处理路径,每个滤镜节点负责特定的处理任务。

主要功能

  • 视频滤镜:调整分辨率(scale)、裁剪(crop)、旋转(transpose)、颜色调整(hue)、添加文本(drawtext)等。
  • 音频滤镜:调整音量(volume)、回声效果(aecho)、重采样(aresample)、声道平移(pan)等。
  • 混合滤镜:将多个视频流混合(blend)、拼接(concat)等。

2. AVFilter 架构

AVFilter 框架由几个关键组件组成:

2.1 AVFilterGraph

AVFilterGraph 是整个滤镜图的容器,负责管理滤镜节点及其连接关系。一个滤镜图可以包含多个滤镜节点,每个节点通过输入和输出端口连接起来。

2.2 AVFilter

AVFilter 代表一个具体的滤镜类型,例如 scalecropbuffersrcbuffersink 等。每个滤镜都有特定的功能和参数。

2.3 AVFilterContext

AVFilterContext 是某个滤镜在滤镜图中的具体实例,持有滤镜的状态和配置参数,并管理滤镜之间的数据流。

2.4 AVFilterInOut

AVFilterInOut 用于表示滤镜图中的输入和输出连接点,特别是在动态构建滤镜图时,用于连接不同滤镜的输入输出。

3. AVFilter 使用流程

使用 AVFilter 进行音视频处理通常包括以下步骤:

  1. 初始化 FFmpeg 库:确保所有必要的库和组件已初始化。
  2. 创建滤镜图:分配和初始化一个 AVFilterGraph 实例。
  3. 创建滤镜节点:根据需要添加输入、输出和处理滤镜,如 buffersrcscalebuffersink 等。
  4. 连接滤镜:将滤镜节点按照处理顺序连接起来,形成滤镜链。
  5. 配置滤镜图:完成滤镜图的配置,并进行优化和验证。
  6. 处理帧:将音视频帧输入滤镜图,通过滤镜链处理并获取输出帧。
  7. 释放资源:处理完成后,释放所有分配的资源。

4. 示例:使用 AVFilter 进行 YUV 到 RGB 转换

下面是一个使用 AVFilter 将 YUV 格式转换为 RGB 格式的示例代码。

4.1 初始化 FFmpeg

在开始任何操作之前,确保初始化 FFmpeg 库和注册所有滤镜。

#include <libavfilter/avfilter.h>
#include <libavfilter/buffersink.h>
#include <libavfilter/buffersrc.h>
#include <libavutil/opt.h>
#include <libavutil/imgutils.h>// 初始化 FFmpeg 库
av_register_all();
avfilter_register_all();

4.2 创建 AVFilterGraph

创建一个 AVFilterGraph,它将存储和管理所有滤镜节点及其连接。

AVFilterGraph *filter_graph = avfilter_graph_alloc();
if (!filter_graph) {fprintf(stderr, "Unable to create filter graph.\n");exit(1);
}

4.3 创建输入滤镜(buffersrc)和输出滤镜(buffersink)

AVFilterContext *buffersrc_ctx = NULL;
AVFilterContext *buffersink_ctx = NULL;const AVFilter *buffersrc = avfilter_get_by_name("buffer");
const AVFilter *buffersink = avfilter_get_by_name("buffersink");// 设置输入滤镜参数
char args[512];
snprintf(args, sizeof(args),"video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",width, height, AV_PIX_FMT_YUV420P,time_base.num, time_base.den,sample_aspect_ratio.num, sample_aspect_ratio.den);// 创建 buffersrc
int ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",args, NULL, filter_graph);
if (ret < 0) {fprintf(stderr, "Cannot create buffer source\n");exit(1);
}// 设置 buffersink 的输出像素格式
enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_RGB24, AV_PIX_FMT_NONE };
ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out",NULL, NULL, filter_graph);
if (ret < 0) {fprintf(stderr, "Cannot create buffer sink\n");exit(1);
}ret = av_opt_set_int_list(buffersink_ctx, "pix_fmts", pix_fmts,AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN);
if (ret < 0) {fprintf(stderr, "Cannot set output pixel format\n");exit(1);
}

4.4 添加颜色空间转换滤镜(scale)

const AVFilter *scale = avfilter_get_by_name("scale");
AVFilterContext *scale_ctx = NULL;// 创建 scale 滤镜
ret = avfilter_graph_create_filter(&scale_ctx, scale, "scale",NULL, NULL, filter_graph);
if (ret < 0) {fprintf(stderr, "Cannot create scale filter\n");exit(1);
}

4.5 连接滤镜

buffersrc 连接到 scale,然后将 scale 连接到 buffersink

ret = avfilter_link(buffersrc_ctx, 0, scale_ctx, 0);
if (ret >= 0) {ret = avfilter_link(scale_ctx, 0, buffersink_ctx, 0);
}
if (ret < 0) {fprintf(stderr, "Error connecting filters\n");exit(1);
}

4.6 配置滤镜图

完成滤镜图的配置,使其准备好处理帧。

ret = avfilter_graph_config(filter_graph, NULL);
if (ret < 0) {fprintf(stderr, "Error configuring the filter graph\n");exit(1);
}

4.7 处理帧

使用 av_buffersrc_add_frame() 向滤镜图中添加帧,并使用 av_buffersink_get_frame() 从图中获取转换后的帧。

AVFrame *frame = av_frame_alloc();
AVFrame *filt_frame = av_frame_alloc();// 假设 frame 已经填充了 YUV 数据// 将帧添加到滤镜图
ret = av_buffersrc_add_frame(buffersrc_ctx, frame);
if (ret < 0) {fprintf(stderr, "Error while adding frame to filter graph\n");exit(1);
}// 从滤镜图中获取处理后的帧
ret = av_buffersink_get_frame(buffersink_ctx, filt_frame);
if (ret < 0) {fprintf(stderr, "Error while getting frame from filter graph\n");exit(1);
}// 此时 filt_frame 包含 RGB 数据

4.8 释放资源

处理完成后,释放所有分配的资源。

av_frame_free(&frame);
av_frame_free(&filt_frame);
avfilter_graph_free(&filter_graph);


http://www.ppmy.cn/ops/105712.html

相关文章

大模型的实践应用28-基于ChatGLM大模型搭建智能自助用药问答系统、药物智能管理系统的应用详解

大家好,我是微学AI,今天给大家介绍一下大模型的实践应用28-基于ChatGLM大模型搭建智能自助用药问答系统、药物智能管理系统的应用详解。 随着人工智能技术的发展,我们的生活在许多方面都得到了改善。本文将介绍如何利用现有的大模型(如:ChatGLM2-6b,百川,通义千问)构建一…

C#使用MQTT(一):MQTT服务端

MQTT&#xff08;Message Queuing Telemetry Transport&#xff09; 即时通讯协议&#xff0c; 开发商 IBM MQTT(消息队列遥测传输)是ISO 标准(ISO/IEC PRF 20922)下基于发布/订阅范式的消息协议。它工作在 TCP/IP协议族上&#xff0c;是为硬件性能低下的远程设备以及网络状…

WPF-快速构建统计表、图表并认识相关框架

一、使用ScottPlot.Wpf 官网地址&#xff1a;https://scottplot.net/quickstart/wpf/ 1、添加NuGet包&#xff1a;ScottPlot.Wpf 2、XAML映射命名空间&#xff1a; xmlns:ScottPlot"clr-namespace:ScottPlot.WPF;assemblyScottPlot.WPF" 3、简单示例&#xff1a;…

【Qt窗口】—— 对话框

目录 &#xff08;一&#xff09; 对话框介绍 &#xff08;二&#xff09;对话框的分类 2.1 模态对话框 2.2 非模态对话框 2.3 混合属性对话框 &#xff08;三&#xff09;内置对话框 消息对话框 QMessageBox 颜色对话框 QColorDialog 字体对话框 QFontDialog 输入对…

RK3568 驱动RTC 使用

一、简介 RK3568开发板采用HYM8563作为RTC(Real Time Clock)&#xff0c;HYM8563是一款低功耗CMOS实时时钟/日历芯片,它提供一个可编程的时钟输出,一个中断输出和一个掉电检测器,所有的地址和数据都通过I2C总线接口串行传递。最大总线速度为 400Kbits/s,每次读写数据后,内嵌的…

大数据学习|理解和对比 Apache Hive 和 Apache Iceberg

文章目录 数据模型与存储事务支持性能优化使用场景总结数据模型与存储 Hive: Hive 使用的是传统的关系型数据模型,数据存储在 Hadoop 分布式文件系统 (HDFS) 中,通常是以文本格式(如 CSV 或 TSV)或者二进制格式(如 Parquet 或 ORC)。Hive 的表定义和元数据存储在一个外部…

【C/C++】web服务器项目开发总结【请求 | 响应 | CGI】

博客主页&#xff1a;花果山~程序猿-CSDN博客 文章分栏&#xff1a;Linux_花果山~程序猿的博客-CSDN博客 关注我一起学习&#xff0c;一起进步&#xff0c;一起探索编程的无限可能吧&#xff01;让我们一起努力&#xff0c;一起成长&#xff01; 目录 一&#xff0c;背景 二&…

Python(TensorFlow)和MATLAB及Java光学像差导图

&#x1f3af;要点 几何光线和波前像差计算入瞳和出瞳及近轴光学计算波前像差特征矩阵方法计算光谱反射率、透射率和吸光度透镜像差和绘制三阶光线像差图和横向剪切干涉图分析瞳孔平面焦平面和大气湍流建模神经网络光学像差计算透镜光线传播几何偏差计算像差和像散色差纠正对齐…

2024版最新渗透测试工具大全(非常详细)零基础入门到精通,收藏这一篇就够了

所有工具仅能在取得足够合法授权的企业安全建设中使用&#xff0c;在使用所有工具过程中&#xff0c;您应确保自己所有行为符合当地的法律法规。如您在使用所有工具的过程中存在任何非法行为&#xff0c;您将自行承担所有后果&#xff0c;所有工具所有开发者和所有贡献者不承担…

统计学习方法与实战——统计学习方法概论

统计学习方法概论 文章目录 统计学习方法概论前言章节目录导读 实现统计学习方法的步骤统计学习方法三要素模型模型是什么? 策略损失函数与风险函数常用损失函数ERM与SRM 算法 模型评估与模型选择过拟合与模型选择 正则化与交叉验证泛化能力生成模型与判别模型生成方法判别方法…

打卡第60天------图论

加油&#xff01;尽管前面的道路很困难&#xff0c;但是依然要坚持下去✊。 在算法训练营我学到了很多东西&#xff0c;对于算法的方法来说真的是涨知识了&#xff0c;对于我一个非科班出身&#xff0c;半路转行的干IT的人来说真的给予了我很大的帮助。我会继续回头看代码随想录…

无人机之传感器篇

无人机的传感器系统是其实现自主飞行、导航、避障、目标识别和环境感知等功能的关键部分。以下是对无人机中常见传感器的详细解析&#xff1a; 一、主要传感器类型 GPS&#xff08;全球卫星定位系统&#xff09; 功能&#xff1a;提供无人机的位置和导航信息。 原理&#x…

Vulnhub:hacksudo search

靶机下载地址。下载完成后&#xff0c;在VirtualBox中导入虚拟机&#xff0c;系统处理器修改为2&#xff0c;网卡配置修改为桥接。 信息收集 主机发现 扫描攻击机同网段存活主机。 nmap 192.168.31.0/24 -Pn -T4 靶机ip&#xff1a;192.168.31.218 端口扫描 nmap 192.168…

HTTP协议到HTTPS的Java客户端改造

前言 由于安全原因&#xff0c;我们公司对外暴露的接口通过HTTP协议的方式在未来的某一天将被彻底关闭。 从那以后&#xff0c;外部客户在调用我公司的接口时就只能通过HTTPS协议。 本篇文章的目的就是安全的指导外部客户的客户端开发人员或者有类似需求的Java开发人员&…

【TheMisto.AI】Flux最强线稿模型实际效果测评(附安装方法)

原文链接&#xff1a;【TheMisto.AI】Flux最强线稿模型实际效果测评&#xff08;附安装方法&#xff09; (chinaz.com) 不知道有没有小伙伴去测试一下哈&#xff0c;上一篇文章用的都是官方提供的参考图&#xff0c;经常关注Flux的小伙伴也知道那些ControlNet买家秀和卖家秀基…

Express Response类深度解析:全面掌握属性与方法,提升开发效率

在Express框架中&#xff0c;Response对象是一个非常重要的组成部分。它代表了HTTP响应&#xff0c;并提供了一系列的方法和属性来操作这个响应。本文将深入全面地讲解Express的Response类&#xff0c;包括其所有属性和方法&#xff0c;并通过代码示例进行说明。 Response对象…

GPT-4 vs LLaMA3.1:核心技术架构与应用场景对比

目录 前言 一、GPT-4 的核心技术架构 1.1 Transformer 结构概述 1.2 GPT-4 的主要组成部分 1.3 GPT-4 的创新与改进 二、LLaMA3.1 的核心技术架构 2.1 模型概述 2.2 LLaMA3.1 的主要组成部分 2.3 LLaMA3.1 的创新与改进 三、GPT-4 和 LLaMA3.1 的主要差异 3.1 模型规…

python学习11:函数/方法的定义与调用

# 1&#xff09;定义和调用 # def 方法名([参数]): # 方法体 # [return 返回值]# 调用 方法名([参数]) 案例1&#xff1a;没有返回值 # 案例1&#xff1a;没有返回值 def login_info():username xxxpwd 123456print(我的信息是&#xff1a;用户名{username},密码是…

【Redis】Redis 典型应⽤ - 缓存 (cache)

Redis 典型应⽤ - 缓存 cache 什么是缓存使⽤ Redis 作为缓存缓存的更新策略1) 定期⽣成2) 实时⽣成 缓存预热, 缓存穿透, 缓存雪崩 和 缓存击穿关于缓存预热 (Cache preheating)关于缓存穿透 (Cache penetration)关于缓存雪崩 (Cache avalanche)关于缓存击穿 (Cache breakdown…

centOS如何查看并放行防火墙3306端口

在CentOS系统中&#xff0c;您可以使用firewall-cmd命令来检查防火墙规则&#xff0c;确认是否放行了3306端口。以下是步骤和示例代码&#xff1a; 首先&#xff0c;确保您的系统上安装了firewalld服务。如果未安装&#xff0c;请使用以下命令安装&#xff1a; sudo yum insta…