嵌入式音视频开发(一)ffmpeg框架及内核解析

系列文章目录

嵌入式音视频开发(零)移植ffmpeg及推流测试

嵌入式音视频开发(一)ffmpeg框架及内核解析


文章目录

  • 系列文章目录
  • 前言
  • 一、ffmpeg的内核
    • [1.1 框架解析](#1.1 框架解析)
    • [1.2 内核解析](#1.2 内核解析)
    • [1.3 FFmpeg内部数据流](#1.3 FFmpeg内部数据流)
      • [1.3.1 典型的解码流程](#1.3.1 典型的解码流程)
      • [1.3.2 典型的编码与推流流程](#1.3.2 典型的编码与推流流程)
      • [1.3.3 典型的滤镜处理流程](#1.3.3 典型的滤镜处理流程)
  • 二、常用命令行工具及语法
    • [2.1 基本语法](#2.1 基本语法)
    • [2.2 视频/音频格式转换](#2.2 视频/音频格式转换)
    • [2.3 视频编辑](#2.3 视频编辑)
    • [2.3 音频处理](#2.3 音频处理)
    • [2.4 录屏与推流](#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 典型的解码流程

c 复制代码
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 典型的编码与推流流程

c 复制代码
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 典型的滤镜处理流程

c 复制代码
avfilter_graph_alloc()  // 创建滤镜图
avfilter_graph_parse_ptr()  // 解析滤镜描述
avfilter_graph_config()  // 配置滤镜
while (处理帧) {
    av_buffersrc_add_frame()  // 送入滤镜
    av_buffersink_get_frame()  // 获取输出
}

二、常用命令行工具及语法

2.1 基本语法

bash 复制代码
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 视频/音频格式转换

格式转换

bash 复制代码
// 将 input.mp4 转换为 output.avi(自动检测编解码器)
ffmpeg -i input.mp4 output.avi

// 将 MP3 转换为 WAV
ffmpeg -i input.mp3 output.wav

指定编码格式

bash 复制代码
// 使用 H.264 编码 和 AAC 音频编码 进行转换
ffmpeg -i input.mp4 -c:v libx264 -c:a aac output.mp4

2.3 视频编辑

裁剪视频

bash 复制代码
// 截取区间(截取 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):裁剪起始位置(左上角坐标)

视频合并

bash 复制代码
// 直接合并多个相同格式的视频
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 音频处理

提取音频

bash 复制代码
ffmpeg -i input.mp4 -q:a 0 -map a output.mp3

替换视频的音频

bash 复制代码
ffmpeg -i input.mp4 -i new_audio.mp3 -c:v copy -c:a aac -strict experimental output.mp4

调整音量

bash 复制代码
ffmpeg -i input.mp3 -af "volume=2.0" output.mp3
	- volume=2.0:音量变为原来的 2 倍

2.4 录屏与推流

录屏

bash 复制代码
ffmpeg -f gdigrab -framerate 30 -i desktop output.mp4

录制摄像头

bash 复制代码
ffmpeg -f v4l2 -i /dev/video0 output.mp4
 - /dev/video0:摄像头设备

直播推流(RTMP)

bash 复制代码
ffmpeg -re -i input.mp4 -c:v libx264 -b:v 1000k -f flv rtmp://live_url
 - rtmp://live_url:推流服务器地址

免责声明:本文参考了网上公开的部分资料,仅供学习参考使用,若有侵权或勘误请联系笔者

相关推荐
9527华安1 小时前
FPGA视频缩放转GTY光口传输,基于Aurora 8b/10b编解码架构,提供3套工程源码和技术支持
fpga开发·音视频·aurora·8b/10b·图像缩放·高速接口·gty
weixin_452600691 小时前
芯麦GC6208:革新摄像机与医疗设备的智能音频解决方案
单片机·嵌入式硬件·音视频·健康医疗·医疗器械·白色家电电源
#岩王爷1 小时前
cv2小练习
音视频·pyqt
电子科技圈2 小时前
XMOS的多项音频技术创新将大模型与边缘AI应用密切联系形成生态化合
人工智能·mcu·物联网·设计模式·音视频·语音识别·iot
rockyou6665 小时前
ffmpeg学习:ubuntu下编译Android版ffmpeg-kit
ubuntu·ffmpeg·ffmpeg-kit
SimpleForest7 小时前
ffmpeg -hwaccels
ffmpeg
春末的南方城市18 小时前
Stability AI 联合 UIUC 提出单视图 3D 重建方法SPAR3D,可0.7秒完成重建并支持交互式用户编辑。
人工智能·计算机视觉·3d·aigc·音视频·图像生成
tadus_zeng1 天前
FFmpeg(一) 简介
ffmpeg
余~~185381628001 天前
矩阵 NFC 碰一碰发视频源码搭建技术解析,支持OEM
线性代数·矩阵·音视频