嵌入式音视频开发(一)ffmpeg框架及内核解析
系列文章目录
嵌入式音视频开发(零)移植ffmpeg及推流测试
嵌入式音视频开发(一)ffmpeg框架及内核解析
文章目录
- 系列文章目录
- 前言
- 一、ffmpeg的内核
- 1.1 框架解析
- 1.2 内核解析
- 1.3 FFmpeg内部数据流
- 1.3.1 典型的解码流程
- 1.3.2 典型的编码与推流流程
- 1.3.3 典型的滤镜处理流程
- 二、常用命令行工具及语法
- 2.1 基本语法
- 2.2 视频/音频格式转换
- 2.3 视频编辑
- 2.3 音频处理
- 2.4 录屏与推流
前言
前节简单介绍了ffmpeg,本节进行FFmpeg的整体架构和内核解读,以及常用命令行的使用。
一、ffmpeg的内核
1.1 框架解析

从图像中,我们可以看到FFmpeg 主要由以下核心库组成,每个库负责不同的功能:
- libavformat —— 负责解析和封装多媒体文件(如 MP4、FLV、MKV)。
- libavcodec —— 负责音视频编解码(支持 H.264、AAC、MP3 等)。
- libavfilter —— 提供音视频滤镜功能(如添加水印、调整亮度)。
除此之外还有附件库:
- libavutil —— 提供通用工具函数(如内存管理、日志处理)。
- libswscale —— 处理视频像素格式转换和缩放(如 RGB 转 YUV)。
- libswresample —— 处理音频格式转换(如 44.1kHz 到 48kHz)。
1.2 内核解析
FFmpeg 的底层由 C 语言实现,核心包含多个关键部分,如下图所示:

(1)AVFormatContext:利用封装格式处理
- 创建输出格式上下文
- avformat_alloc_output_context2() 初始化一个输出格式上下文
- 文件 I/O:支持 avio_read()、avio_write() 操作
- 流管理:音视频数据流以 AVStream 形式存在
- 封装/解封装器:
- avformat_find_stream_info() 解析格式
- av_read_frame() 读取数据
- av_write_frame() 写入数据
(2) AVCodecContext:音视频编解码
- 编码器/解码器注册
- avcodec_register_all() 负责注册所有编解码器
- 帧处理
- avcodec_send_packet() 发送数据包
- avcodec_receive_frame() 获取解码数据
- 优化
- 采用 SIMD 指令集加速(x86 SSE、ARM NEON),内部使用 Threading API 进行多线程优化
(3) AVFilterContext :构建滤镜链
- 创建和配置滤镜链
- avfilter_graph_create_filter() 创建滤镜链
- avfilter_graph_parse_ptr() 解析滤镜链字符串,并添加到滤镜图中
- 编辑滤镜链
- av_buffersrc_add_frame() 将数据帧添加到滤镜图的输入端。
- av_buffersink_get_frame() 从滤镜图的输出端获取处理后的数据帧。
(4) libswscale:图像处理
- 图像缩放
- sws_getContext() 创建缩放上下文
- sws_scale() 执行缩放
- 颜色格式转换(如RGB->YUV)
- swsContext() 色彩转换上下文
- sws_getContext() 颜色空间转换
| 色彩格式 | 说明 |
|---|---|
| AV_PIX_FMT_YUV420P | YUV 4:2:0,常见于 H.264 编码 |
| AV_PIX_FMT_YUYV422 | YUV 4:2:2,部分摄像头格式 |
| AV_PIX_FMT_RGB24 | 每像素 24 位 RGB |
| AV_PIX_FMT_BGR24 | 每像素 24 位 BGR |
| AV_PIX_FMT_NV12 | 现代 GPU 常用的 YUV 4:2:0 |
(5) libswresample:音频格式转换
- 采样率转换、通道数调整
- swr_alloc_set_opts()(创建转换上下文)
- swr_convert()(执行转换)
(6) libavutil:通用工具库,如:数据类型转换、时间基准处理(AVRational)、日志管理、哈希计算(MD5、SHA)
1.3 FFmpeg内部数据流
1.3.1 典型的解码流程
avformat_open_input() // 打开媒体文件
avformat_find_stream_info() // 解析流信息
avcodec_find_decoder() // 查找解码器
avcodec_alloc_context3() // 分配解码上下文
avcodec_open2() // 打开解码器
while (av_read_frame()) {avcodec_send_packet() // 送入解码器avcodec_receive_frame() // 获取解码后数据
}
1.3.2 典型的编码与推流流程
avformat_alloc_output_context2() // 创建输出格式上下文
avcodec_find_encoder() // 查找编码器
avcodec_alloc_context3() // 分配编码上下文
avcodec_open2() // 打开编码器
while (获取原始帧) {avcodec_send_frame() // 送入编码器avcodec_receive_packet() // 获取压缩数据av_interleaved_write_frame() // 推流
}
1.3.3 典型的滤镜处理流程
avfilter_graph_alloc() // 创建滤镜图
avfilter_graph_parse_ptr() // 解析滤镜描述
avfilter_graph_config() // 配置滤镜
while (处理帧) {av_buffersrc_add_frame() // 送入滤镜av_buffersink_get_frame() // 获取输出
}
二、常用命令行工具及语法
2.1 基本语法
ffmpeg <global-options> <input-options> -i <input> <output-options> <output>
- 全局参数(global-options):日志输出,文件覆盖等全局选项.
- 输入文件参数(input-options):读取文件的输入选项
- 输出文件参数(output-options):转换(编解码器,质量等)或过滤或流映射
常用高频命令行参数如下所示:
| 参数 | 说明 |
|---|---|
| -c | 指定编码器 |
| -c copy | 直接复制,不经过重新编码 |
| -c:v | 指定视频编码器 |
| -c:a | 指定音频编码器 |
| -i | 指定输入文件 |
| -an | 去除音频流 |
| -vn | 去除视频流 |
| -preset | 指定输出的视频质量,会影响文件的生成速度,有以下几个可用的值 ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow |
| -y | 不经过确认,输出时直接覆盖同名文件 |
2.2 视频/音频格式转换
格式转换
// 将 input.mp4 转换为 output.avi(自动检测编解码器)
ffmpeg -i input.mp4 output.avi// 将 MP3 转换为 WAV
ffmpeg -i input.mp3 output.wav
指定编码格式
// 使用 H.264 编码 和 AAC 音频编码 进行转换
ffmpeg -i input.mp4 -c:v libx264 -c:a aac output.mp4
2.3 视频编辑
裁剪视频
// 截取区间(截取 10-30 秒)
ffmpeg -i input.mp4 -ss 00:00:10 -to 00:00:30 -c copy output.mp4
-ss:起始时间(秒或 hh:mm:ss)
-to:结束时间// 按时长裁剪(从 10 秒处开始,截取 20 秒)
ffmpeg -i input.mp4 -ss 10 -t 20 -c copy output.mp4
-t:截取的持续时间// 裁剪视频画面(区域裁剪)
ffmpeg -i input.mp4 -vf "crop=640:480:100:50" output.mp4
- crop=width:height:x:y-(640, 480):裁剪后的宽高-(100, 50):裁剪起始位置(左上角坐标)
视频合并
// 直接合并多个相同格式的视频
ffmpeg -i "concat:input1.mp4|input2.mp4" -c copy output.mp4// 不同格式视频合并(需要重新编码)
ffmpeg -i input1.mp4 -i input2.mp4 -filter_complex "[0:v:0][0:a:0][1:v:0][1:a:0]concat=n=2:v=1:a=1[outv][outa]" /-map "[outv]" -map "[outa]" output.mp4
- concat=n=2:v=1:a=1:合并 2 个视频,带视频流 v=1 和音频流 a=1
2.3 音频处理
提取音频
ffmpeg -i input.mp4 -q:a 0 -map a output.mp3
替换视频的音频
ffmpeg -i input.mp4 -i new_audio.mp3 -c:v copy -c:a aac -strict experimental output.mp4
调整音量
ffmpeg -i input.mp3 -af "volume=2.0" output.mp3- volume=2.0:音量变为原来的 2 倍
2.4 录屏与推流
录屏
ffmpeg -f gdigrab -framerate 30 -i desktop output.mp4
录制摄像头
ffmpeg -f v4l2 -i /dev/video0 output.mp4- /dev/video0:摄像头设备
直播推流(RTMP)
ffmpeg -re -i input.mp4 -c:v libx264 -b:v 1000k -f flv rtmp://live_url- rtmp://live_url:推流服务器地址
免责声明:本文参考了网上公开的部分资料,仅供学习参考使用,若有侵权或勘误请联系笔者
相关文章:
嵌入式音视频开发(一)ffmpeg框架及内核解析
系列文章目录 嵌入式音视频开发(零)移植ffmpeg及推流测试 嵌入式音视频开发(一)ffmpeg框架及内核解析 文章目录 系列文章目录前言一、ffmpeg的内核1.1 框架解析1.2 内核解析1.3 FFmpeg内部数据流1.3.1 典型的解码流程1.3.2 典型的…...
javaEE-11.javaScript入门
目录 一.什么是javaScript 二.快速实现 三.JS引入方式 1.行内引入: 2.内部引入: 3.外部引入: 四.基础语法 1.变量 变量命名规则: 2.数据类型 3.运算符 五.JS对象 1.数组 创建数组: 2.操作数组 3.函数 函数注意事项: 函数参数: 4.对象 1.使用字面量 创建对象:…...
畅游Diffusion数字人(16):由音乐驱动跳舞视频生成
畅游Diffusion数字人(0):专栏文章导航 前言:从Pose到跳舞视频生成的工作非常多,但是还没有直接从音乐驱动生成的工作。最近字节跳动提出了MuseDance,无需复杂的动作引导输入(如姿势或深度序列),从而使不同专业水平的用户都能轻松进行灵活且富有创意的视频生成。 目录 贡…...
OnlyOffice docker 运行(详细)
下载镜像 推荐使用 GitHub Action 方式下载: Action 地址:https://github.com/Shixuebin/DockerTarBuilder 教程地址:https://www.bilibili.com/video/BV1EZ421M7mL/ docker 镜像安装 docker load -i xxx.tar镜像运行 docker run -i -t -…...
DeepSeek 助力 Vue 开发:打造丝滑的步骤条
前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 💕 目录 Deep…...
领略算法真谛:差分
嘿,各位技术潮人!好久不见甚是想念。生活就像一场奇妙冒险,而编程就是那把超酷的万能钥匙。此刻,阳光洒在键盘上,灵感在指尖跳跃,让我们抛开一切束缚,给平淡日子加点料,注入满满的pa…...
【Python深入浅出】Python3中os模块:开启系统交互的万能钥匙
目录 一、引言:os 模块初印象二、os 模块基础操作2.1 文件与目录操作2.1.1 创建操作2.1.2 读取操作2.1.3 删除操作2.1.4 信息获取 2.2 系统信息获取与环境变量管理2.2.1 系统信息获取2.2.2 环境变量管理 2.3 进程管理与工作目录操作2.3.1 进程管理2.3.2 工作目录操作…...
【图片转换PDF】多个文件夹里图片逐个批量转换成多个pdf软件,子文件夹单独合并转换,子文件夹单独批量转换,基于Py的解决方案
建筑设计公司在项目执行过程中,会产生大量的设计图纸、效果图、实景照片等图片资料。这些资料按照项目名称、阶段、专业等维度存放在多个文件夹和子文件夹中。 操作需求:为了方便内部管理和向客户交付完整的设计方案,公司需要将每个项目文件…...
在Linux上如何让ollama在GPU上运行模型
之前一直在 Mac 上使用 ollama 所以没注意,最近在 Ubuntu 上运行发现一直在 CPU 上跑。我一开始以为是超显存了,因为 Mac 上如果超内存的话,那么就只用 CPU,但是我发现 Llama3.2 3B 只占用 3GB,这远没有超。看了一下命…...
程序诗篇里的灵动笔触:指针绘就数据的梦幻蓝图<8>
大家好啊,我是小象٩(๑ω๑)۶ 我的博客:Xiao Xiangζั͡ޓއއ 很高兴见到大家,希望能够和大家一起交流学习,共同进步。 今天我们复习前面学习的指针知识 目录 关于指针数组和数组指针的区别指针数组(Array of Poi…...
快速集成DeepSeek到项目
DeepSeek API-KEY 获取 登录DeekSeek 官网,进入API 开放平台 2. 创建API-KEY 复制API-KEY进行保存,后期API调用使用 项目中集成DeepSeek 这里只展示部分核心代码,具体请查看源码orange-ai-deepseek-biz-starter Slf4j AllArgsConstructo…...
DeepSeek做赛车游戏
赛车模型 2D生成图片 任意AI图片软件SD,MJ 图片生成3D模型 车身 车轮 场景 Rodin,Tripo和Meshy 询问deepSeek如何开发 拷贝代码 将汽车运行代码拖到汽车上 再让AI写个摄像头跟随代码 再去提问deepseek控制轮胎和一些处理细节...
未来替代手机的产品,而非手机的本身
替代手机的产品包括以下几种: 可穿戴设备:智能手表、智能眼镜等可穿戴设备可以提供类似手机的功能,如通话、信息推送、浏览网页等。 虚拟现实(VR)技术:通过佩戴VR头显,用户可以进行语音通话、发…...
uniapp开发微信小程序请求超时设置【亲测有效】
在Hbuilderx中 使用uniapp开发微信小程序时 封装请求方法 请求代码如下 function requestFun(app) {// get请求app.config.globalProperties._get function(path, data, success, fail, complete) {data data || {};data.token uni.getStorageSync(token) || ;uni.request…...
Repmgr管理PostgreSQL服务器集群笔记
目录 Repmgr管理PostgreSQL服务器集群笔记一、概述(一)主要工具(二)用户和元数据 二、准备工作(一)基本环境(二)PostgreSQL用户创建、目录规划(三)互信配置&a…...
deepseek本地部署-linux
1、官网推荐安装方法(使用脚本,我绕不过github,未采用) 登录ollama下载网站https://ollama.com/download/linux,linux下有下载脚本。 正常来说,在OS系统下直接执行脚本即可。 2、手动安装方法 2.1获取ol…...
vite + axios 代理不起作用 404 无效
vite axios 代理不起作用 先看官方示例 export default defineConfig({server: {proxy: {// 字符串简写写法/foo: http://localhost:4567,// 选项写法/api: {target: http://jsonplaceholder.typicode.com,changeOrigin: true,rewrite: (path) > path.replace(/^\/api/, )…...
【Linux】从零开始:编写你的第一个Linux进度条小程序
Linux相关知识点可以通过点击以下链接进行学习一起加油!初识指令指令进阶权限管理yum包管理与vim编辑器GCC/G编译器make与Makefile自动化构建GDB调试器与Git版本控制工具 🌈个人主页:是店小二呀 🌈C语言专栏:C语言 &am…...
【办公类-53-04】20250209Python模仿制作2024学年第二学期校历
背景需求: 马上开学了,又要制作校历(删划节假日)。之前我都是用网络的图片,然后在PPT里修改。 存在问题: 网络校历是从周日开始的,但日常我们老师做教案,都是默认从周一到周五&…...
11vue3实战-----封装缓存工具
11vue3实战-----封装缓存工具 1.背景2.pinia的持久化思路3.以localStorage为例解决问题4.封装缓存工具 1.背景 在上一章节,实现登录功能时候,当账号密码正确,身份验证成功之后,把用户信息保存起来,是用的pinia。然而p…...
Unity 基础编程
在这个练习中将新建unity脚本,控制player的运动与转动,实现用代码检测碰撞与删除物体。 该练习将应用附件中的项目文件,该文件与Unity快速练习的文件是同一个项目文件。 一、构建Player运动脚本 该部分将构建一个在场景中由玩家控制游戏物…...
Spring Boot接入Deep Seek的API
1,首先进入deepseek的官网:DeepSeek | 深度求索,单击右上角的API开放平台。 2,单击API keys,创建一个API,创建完成务必复制!!不然关掉之后会看不看api key!!&…...
介绍下SpringBoot常用的依赖项
Spring Boot 是一个用于快速开发 Spring 应用程序的框架,它通过自动配置和依赖管理简化了开发过程。以下是一些 Spring Boot 项目中常用的依赖项: 1. Spring Boot Starter Web 作用: 用于构建 Web 应用程序,包括 RESTful 服务。依赖项: spr…...
解决 keep-alive 缓存组件中定时器干扰问题
当使用 keep-alive 缓存组件时,组件中的定时器可能会在组件被缓存后继续运行,从而干扰其他组件的逻辑。为了避免这种情况,可以通过以下方法解决: 1. 在组件的 deactivated 钩子中清理定时器 keep-alive 为缓存的组件提供了 acti…...
PostgreSQL插件-pg_stat_statements-安装和使用
文章目录 插件介绍插件安装1.修改配置文件postgresql.conf2.插件相关参数参数默认值参数说明特别注意pg_stat_statements.max参数设置太小日志会有警告 插件使用1.创建插件2.使用插件3.重置数据4.删除插件 可能会出现的问题1.没有编译安装插件2.没有配置shared_preload_librari…...
flutter安卓打包签名
flutter安卓打包签名 1.创建签名文件 keytool -genkeypair -v -keystore my-release-key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias my-key-aliaskeytool 是一个用于管理密钥和证书的命令行工具,通常与 Java 开发工具包 (JDK) 一起使用。my-release-…...
从Word里面用VBA调用NVIDIA的免费DeepSeekR1
看上去能用而已。 选中的文字作为输入,运行对应的宏即可;会先MSGBOX提示一下,然后相关内容追加到word文档中。 需要自己注册生成好用的apikey Option ExplicitSub DeepSeek()Dim selectedText As StringDim apiKey As StringDim response A…...
JavaScript 中的防抖和节流,它们的区别是什么,以及如何实现?
在前端开发中,防抖(Debounce)和节流(Throttle)是两种常用的优化高频率事件处理的技术。 它们能够有效减少事件处理函数的执行次数,从而提升页面性能和用户体验。 下面将详细解释这两种技术的概念、区别、…...
【Kubernetes的SpringCloud最佳实践】Spring Cloud netflix 能否被K8s资源完全替代?
在部署Spring Cloud微服务到Kubernetes(K8s)时, Spring Cloud netflix 是否需要完全替代?或者可以部分替代,结合使用? 例如,服务发现和负载均衡可以交给K8s处理, 但某些功能如API网关…...
MATLAB中extract 函数用法
目录 语法 说明 示例 从地址中提取邮政编码 提取在数值位置处的字符 extract函数的功能是从字符串中提取子字符串。 语法 newStr extract(str,pat) newStr extract(str,pos) 说明 newStr extract(str,pat) 返回 str 中与 pat 指定的模式匹配的任何子字符串。 如果 s…...
