关于ffmpeg的简介和使用总结

主要参考:

全网最全FFmpeg教程,从新手到高手的蜕变指南 - 知乎 (zhihu.com)

FFmpeg入门教程(非常详细)从零基础入门到精通,看完这一篇就够了。-CSDN博客

FFmpeg教程(超级详细版) - 个人文章 - SegmentFault 思否

FFmpeg 是一个开源的跨平台音视频处理框架,在多媒体领域堪称 "神器"。它如同一个万能工具箱,涵盖了录制、转换、流化等一系列音视频处理功能,支持诸如 AVI、MP4、MOV、FLV、WMV、MPEG、MKV 等海量音视频格式,并且能在 Windows、Mac OS、Linux 等多种操作系统上稳定运行。

最初由法国计算机程序员 Fabrice Bellard 于 2000 年创建,这个项目的名称是 "FF"(代表 "Fast Forward",快进之意)与 "mpeg"(流行的视频压缩标准 MPEG,即运动图像专家组)的组合。后来由 Michael Niedermayer 接手并持续开发,众多来自 MPlayer 项目的开发者也参与其中,为 FFmpeg 添砖加瓦,使其逐渐成长为功能完备的强大工具。

和其他音视频处理软件相比,FFmpeg 优势显著。比如格式工厂,虽然操作相对简便,有图形化界面,但在功能深度和定制化程度上远不及 FFmpeg,像复杂的滤镜添加、精准的码率控制等高级操作难以实现;再看 Adobe Premiere,虽专业剪辑功能强大,可学习成本高、授权费用不菲,而 FFmpeg 免费开源,学习资源丰富,能满足从基础格式转换到高级编解码、滤镜处理等多样化需求。

FFmpeg是音视频领域的底层基础设施,无论是开发者还是普通用户(通过GUI工具间接使用),几乎所有的多媒体处理背后都有它的身影。掌握FFmpeg的基本用法,能高效解决音视频转码、编辑、流媒体等问题。

ffmpeg是什么语言写的

FFmpeg 主要是用 C 语言 编写的,同时也包含少量 汇编语言 (针对关键性能模块的优化)和 脚本语言(如 Shell、Python 用于构建和测试)。以下是详细说明:

核心语言构成

|------|----------------|-----------------------------------------|
| 部分 | 语言 | 用途 |
| 主代码库 | C 语言 | 实现音视频编解码、封装/解封装、滤镜处理等核心功能(占比90%以上)。 |
| 性能优化 | 汇编语言(ASM) | 针对CPU指令集(如x86 SSE/AVX、ARM NEON)的硬件加速优化。 |
| 构建系统 | Shell/Makefile | 自动化编译配置(如configure脚本)。 |
| 测试工具 | Python/Perl | 部分测试脚本和工具开发(如fate测试框架)。 |

为什么选择C语言?

高性能:C语言直接操作硬件和内存,适合音视频编解码的高效处理。

跨平台:易于移植到嵌入式设备(如ARM)、桌面系统(Windows/macOS/Linux)等。

生态成熟:大量音视频标准库(如libx264、libvpx)均以C接口提供。

关键代码示例

C语言核心逻辑(解码示例)

复制代码
// 简化的FFmpeg解码流程(C代码)
AVFormatContext *fmt_ctx = avformat_alloc_context();
avformat_open_input(&fmt_ctx, "input.mp4", NULL, NULL); // 打开文件
AVCodecContext *codec_ctx = avcodec_alloc_context3(codec);
avcodec_open2(codec_ctx, codec, NULL); // 初始化解码器
AVPacket pkt;
av_read_frame(fmt_ctx, &pkt); // 读取数据包
avcodec_send_packet(codec_ctx, &pkt); // 发送到解码器

汇编优化(x86 SIMD示例)

复制代码
; FFmpeg中H.264解码的x86 SIMD优化(片段)
movdqu      xmm0, [rsi]   ; 加载16字节数据
paddw       xmm0, xmm1    ; SIMD加法指令

其他语言的辅助角色

Python :用于测试和工具开发(如ffmpeg-python封装库)。

Perl:历史代码中的少量脚本(如生成文档)。

Rust/Go :社区有封装库(如go-ffmpeg),但FFmpeg本身未使用。

如何参与开发?

必备技能

  • 熟练使用C语言(指针、内存管理、多线程)。

  • 了解音视频基础(编解码、容器格式)。

学习代码

  • 从简单模块入手(如libavformat中的文件读写)。

提交补丁

  • 遵循FFmpeg的代码规范(如变量命名、提交日志格式)。

总结

FFmpeg的底层实现是C语言+汇编优化 ,确保了极致的性能和跨平台能力。如果需要调用FFmpeg的功能,可通过其C API,或使用高级语言(如Python)的封装库(如ffmpeg-python)。

嵌入式中能使用ffmpeg吗

在嵌入式系统中使用 FFmpeg 是可行的,但需要根据硬件资源和应用场景进行裁剪和优化。以下是关键要点和具体实施方案:

能否使用FFmpeg?

可以,但有条件: FFmpeg 本身支持跨平台,但嵌入式设备通常资源有限(内存、CPU性能),需通过以下方式适配:

代码裁剪:禁用非必需模块(如视频编解码器、滤镜)。

交叉编译:针对目标平台(如ARM Cortex-A/MIPS)编译。

硬件加速:利用芯片的编解码引擎(如Rockchip VPU、NVIDIA Jetson NVENC)。

适用场景

|-----------------|---------------------------------------------------|
| 场景 | 推荐方案 |
| 低端MCU(无OS) | 不推荐,FFmpeg依赖文件系统和动态内存,适合RTOS或裸机定制化轻量库(如TinyH264)。 |
| 嵌入式Linux(ARM-A) | 裁剪后的FFmpeg + 硬件加速(如树莓派、瑞芯微RK系列)。 |
| 实时音视频处理 | 启用FFmpeg的快速解码模式(如-fast参数),或改用WebRTC(更低延迟)。 |

如何裁剪FFmpeg?

① 配置时禁用非必需功能

复制代码
# 示例:仅启用H.264解码和MP3解码,禁用其他模块
./configure \
  --enable-cross-compile \
  --arch=armv7-a \
  --target-os=linux \
  --enable-decoder=h264 \
  --enable-decoder=mp3 \
  --disable-avdevice \
  --disable-swresample \
  --disable-postproc \
  --disable-everything-else

关键选项

--disable-everything + 按需启用模块。

--enable-small:启用优化以减少内存占用。

② 手动裁剪源文件

删除libavcodec中未使用的编解码器源码(如删除vp9.c以减少体积)。

替换动态内存分配为静态分配(需修改FFmpeg源码,风险较高)。

资源占用参考

|----------------|------------|---------------|----------------------|
| 配置 | 内存占用 | 存储占用 | 适用硬件 |
| 全功能FFmpeg | >50MB RAM | >20MB Flash | 高性能SoC(如Jetson) |
| 仅H.264解码+MP3解码 | <10MB RAM | <2MB Flash | Cortex-A7(512MB RAM) |
| 仅Opus音频解码 | <1MB RAM | <500KB Flash | Cortex-M7(带MMU) |

硬件加速集成

方案一:调用芯片厂商SDK

如Rockchip的mpp库、NVIDIA的V4L2接口,通过FFmpeg的hwaccel选项启用:

ffmpeg -hwaccel rkmpp -i input.h264 output.yuv

方案二:使用VAAPI/VDPAU

在Linux嵌入式平台(如树莓派)启用GPU加速:

ffmpeg -hwaccel vaapi -i input.mp4 output.mp4

替代方案(资源极度受限时)

音频

轻量库:Opus(编码)、libmad(MP3解码)。

视频

纯解码:TinyH264(无B帧支持)。

硬件方案:直接调用芯片厂商的编解码API(如海思Hi35xx的SDK)。

实战示例:树莓派视频播放

① 安装裁剪版FFmpeg

编译时仅启用H.264和硬件加速 ./configure --enable-mmal --enable-decoder=h264 --enable-hwaccel=h264_mmal make -j4

② 播放视频流

使用硬件加速解码 ffmpeg -hwaccel mmal -i input.h264 -f sdl2 "Video Output"

注意事项

许可协议:FFmpeg部分模块为GPL,商用需注意合规性(可选用LGPL配置)。

实时性:默认FFmpeg不保证实时性,需调整线程模型和缓冲策略。

调试工具 :使用strace监控系统调用,valgrind检测内存泄漏。

总结

能用,但需裁剪:FFmpeg适合资源较丰富的嵌入式Linux平台(如ARM Cortex-A),通过禁用非必需模块和启用硬件加速可大幅降低资源占用。

替代方案:对于MCU级设备,优先选择轻量库(如Opus、TinyH264)或硬件编解码芯片。

关键步骤:交叉编译、硬件加速集成、动态内存优化。

如果需要具体平台的配置示例(如STM32MP157或全志H3),可进一步提供细节!

嵌入式里编解码库推荐

在嵌入式系统中选择编解码库时,需综合考虑硬件资源 (CPU性能、内存大小)、功耗实时性许可协议。以下是针对嵌入式环境的推荐编解码库,按音频和视频分类:

一、音频编解码库

轻量级语音编解码

|-----------|--------|---------------------|-------------------|
| 库名称 | 格式/算法 | 特点 | 适用场景 |
| Opus | Opus | 低延迟(<50ms),支持语音/音乐 | VoIP、语音助手(如Alexa) |
| Speex | Speex | 专为语音优化,低复杂度 | 对讲机、低功耗设备 |
| Codec2 | Codec2 | 超低比特率(2400bps) | 军事、卫星通信 |
| AMR-NB/WB | AMR | 3GPP标准,移动通信兼容 | 老旧嵌入式设备 |

音乐/通用音频

|----------|-----|------------------|--------------|
| 库名称 | 格式 | 特点 | 适用场景 |
| libmad | MP3 | 定点运算,低内存占用 | MP3播放器 |
| AAC ELD | AAC | 低延迟扩展,适合实时流 | 无线音频传输 |
| TinyALSA | PCM | 轻量级ALSA接口,支持硬件加速 | Linux嵌入式音频驱动 |

二、视频编解码库

软件编解码(无硬件加速)

|----------|---------|--------------------|-------------|
| 库名称 | 格式 | 特点 | 适用场景 |
| TinyH264 | H.264 | 纯解码,适合MCU(需外部RAM) | 低分辨率监控摄像头 |
| libvpx | VP8/VP9 | 开源,支持实时编码 | WebRTC嵌入式终端 |
| x264 | H.264 | 裁剪后可适配ARM Cortex-A | 视频录像机 |
| uAVS3e | AVS3 | 国产标准,低专利费 | 广电、监控设备 |

硬件加速方案

|------------|--------------|-------------------|
| 平台/芯片 | 支持编解码 | 特点 |
| Rockchip | H.265/H.264 | 支持4K解码(如RK3399) |
| TI DaVinci | H.264/MPEG-4 | 工业级稳定性(如DM8148) |
| NXP i.MX | VPU加速 | 低功耗(如i.MX8M Plus) |
| Allwinner | H.264 | 低成本(如V3s) |

三、嵌入式专用工具链

开源框架

|-----------|---------------|---------------|
| 名称 | 功能 | 适用场景 |
| GStreamer | 模块化音视频流水线 | 复杂多媒体处理(如树莓派) |
| FFmpeg | 裁剪版(禁用非必需模块) | 定制化需求 |
| Live555 | RTSP/RTP流媒体传输 | 网络摄像头 |

商业解决方案

|------------|------------------|----------------|
| 名称 | 特点 | 典型客户 |
| Dolby MS12 | 杜比音效编解码 | 高端智能音箱 |
| ARM CMSIS | Cortex-M DSP优化库 | 低功耗MCU(如STM32) |
| Ittiam | H.265/AV1硬件优化SDK | 专业视频设备 |

四、选型建议

资源受限设备(MCU级别)

音频:Opus(实时语音)或 libmad(MP3播放)。

视频:TinyH264(仅解码) + 硬件加速芯片(如ESP32-CAM)。

内存优化 :启用固定点运算(如Opus的 FIXED_POINT 模式)。

中高端嵌入式(Linux SoC)

音频:GStreamer + ALSA插件(支持AAC/Opus)。

视频:FFmpeg裁剪版(保留H.264) + V4L2硬件加速。

示例命令(FFmpeg裁剪)

./configure --disable-everything --enable-decoder=h264 --enable-parser=h264 --enable-demuxer=avi

实时性要求高的场景

协议栈:WebRTC(Opus/VP8) + UDP传输。

延迟优化:禁用B帧、降低GOP大小。

五、实战示例

STM32 + Opus编码

复制代码
// 使用libopus在STM32上编码语音
include <opus.h> 
OpusEncoder *encoder = opus_encoder_create(16000, 1, OPUS_APPLICATION_VOIP, &error);
uint8_t output[100];
int bytes = opus_encode(encoder, pcm_data, frame_size, output, 100);

树莓派视频解码

使用GStreamer播放H.264流 gst-launch-1.0 udpsrc port=5000 ! application/x-rtp,encoding-name=H264 ! rtph264depay ! h264parse ! omxh264dec ! autovideosink

六、注意事项

许可协议

  • 避免GPL库(如FFmpeg完整版),优先选择MIT/LGPL(如libvpx)。

硬件兼容性

  • 确认芯片是否支持硬件编解码(如海思Hi3518EV300的H.264加速)。

功耗管理

  • 编码时动态调整CPU频率(如DVFS技术)。

总结

语音首选:Opus(实时)、Speex(老旧设备)。

视频首选:TinyH264(低端)、libvpx(中端)、硬件加速(高端)。

开发框架:GStreamer(灵活)或 FFmpeg裁剪(高效)。

根据具体需求平衡性能、资源和成本,优先利用硬件加速以降低CPU负载。

相关推荐
winfredzhang18 小时前
实战:从零构建一个支持屏幕录制与片段合并的视频管理系统 (Node.js + FFmpeg)
ffmpeg·node.js·音视频·录屏
winfredzhang19 小时前
自动化视频制作:深入解析 FFmpeg 图片转视频脚本
ffmpeg·自动化·音视频·命令行·bat·图片2视频
胖_大海_2 天前
【FFmpeg+Surface 底层渲染,实现超低延迟100ms】
ffmpeg
冷冷的菜哥2 天前
springboot调用ffmpeg实现对视频的截图,截取与水印
java·spring boot·ffmpeg·音视频·水印·截图·截取
进击的CJR2 天前
redis哨兵实现主从自动切换
mysql·ffmpeg·dba
huahualaly2 天前
重建oracle测试库步骤
数据库·oracle·ffmpeg
aqi003 天前
FFmpeg开发笔记(九十九)基于Kotlin的国产开源播放器DKVideoPlayer
android·ffmpeg·kotlin·音视频·直播·流媒体
lizongyao3 天前
FFMPEG命令行典型案例
ffmpeg
冷冷的菜哥3 天前
ASP.NET Core调用ffmpeg对视频进行截图,截取,增加水印
开发语言·后端·ffmpeg·asp.net·音视频·asp.net core
冷冷的菜哥3 天前
go(golang)调用ffmpeg对视频进行截图、截取、增加水印
后端·golang·ffmpeg·go·音视频·水印截取截图