当前位置: 首页 > article >正文

嵌入式音视频开发(一)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_YUV420PYUV 4:2:0,常见于 H.264 编码
AV_PIX_FMT_YUYV422YUV 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:推流服务器地址

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


http://www.kler.cn/a/541378.html

相关文章:

  • 多头自注意力中的多头作用及相关思考
  • c语言函数学习
  • Django在终端创建项目(pycharm Windows)
  • 12c及以后 ADG主备切换
  • Django项目中创建app并快速上手(pycharm Windows)
  • Linux(21)——系统日志
  • hive数仓的分层与建模
  • 食品饮料生产瓶颈?富唯智能协作机器人来 “破壁”
  • 使用 DeepSeek 进行图像描述:多模态 AI 技术实践
  • 【Linux】Linux命令:crontab
  • SpringBoot和Spring主要区别
  • React Vite 项目增加 eslint 和 prettier
  • 【网络法医】基线取证和常见反取证技术
  • 【DeepSeek】Deepseek辅组编程-通过卫星轨道计算终端距离、相对速度和多普勒频移
  • Ajax-介绍
  • 深度学习|表示学习|Layer Normalization 全面总结|24
  • CSS入门学习笔记(二)
  • 客户端渲染和服务端渲染
  • bitcoinjs学习笔记0(预备知识)
  • SpringBoot 接口防抖的一些实现方案
  • Unity Dots理论学习-5.与ECS相关的概念
  • R18 2Rx XR devices
  • React 中的 useMemo 和 useCallback 有什么区别?
  • Gaea: 去中心化人工智能平台的未来
  • 智慧机房解决方案(文末联系,领取整套资料,可做论文)
  • 使用Qt+opencv实现游戏辅助点击工具-以阴阳师为例