FFMPEG 使用总结
好,我们系统讲一遍 FFmpeg 编解码流程,并且给出完整可运行 C 代码 + 详细注释。内容覆盖:
1️⃣ 解码流程(输入 → 解封装 → 解码 → 得到原始数据) 2️⃣ 编码流程(原始数据 → 编码 → 封装 → 输出文件) 3️⃣ 必知关键函数说明 4️⃣ 常见坑与经验
🟥 一、FFmpeg 解码流程(Demux + Decode)
🎯 目标:
把 input.mp4 → 解封装 → 解码 → 得到
原始视频帧(YUV) 或音频 PCM 数据。
✅ 解码流程概念图
1 | 文件 / 流 |
✅ FFmpeg 视频解码示例 (C)
解码视频,输出每一帧信息(可改成保存 YUV)
1 |
|
🧠 关键 API 解释
| 函数 | 作用 |
|---|---|
avformat_open_input |
打开文件/流 |
avformat_find_stream_info |
读取媒体信息 |
avcodec_find_decoder |
找到解码器 |
avcodec_open2 |
打开解码器 |
av_read_frame |
从封装读取 Packet |
avcodec_send_packet |
把 Packet 送入解码器 |
avcodec_receive_frame |
得到原始 Frame |
avcodec_send_packet(NULL) |
flush |
av_packet_unref |
释放 packet 引用 |
🟩 二、FFmpeg 编码流程(Encode + Mux)
🎯 目标:
把 原始 YUV/PCM → 编码成 H264 → 封装 MP4
✅ 编码总体流程图
1 | 原始数据 (Frame) |
✅ FFmpeg 视频编码示例 (H264 → MP4)
演示:生成一个假的视频帧,编码写 MP4 (真实项目你会把 frame 数据替换成 camera / YUV 数据)
1 |
|
🧠 编码关键 API
| 函数 | 作用 |
|---|---|
avformat_alloc_output_context2 |
创建输出 |
avcodec_find_encoder |
找编码器 |
avcodec_open2 |
打开编码器 |
av_frame_get_buffer |
分配 Frame 数据区 |
avcodec_send_frame |
输入 Frame |
avcodec_receive_packet |
得到压缩 Packet |
av_interleaved_write_frame |
写入封装文件 |
av_write_trailer |
写尾 |
⚠️ 常见坑
❌ 不 flush → 会少帧
1 | avcodec_send_packet(NULL) |
必须要!
❌ Packet vs Frame 弄混
- Frame = 原始数据(YUV / PCM)
- Packet = 压缩数据(H264 / AAC)
❌ 忘记 av_packet_unref
必泄漏。
❌ pts / time_base 处理错误
视频会抖 / 播放不了。
如果你告诉我:
- Android / Linux / macOS?
- 你要做:
- 播放器?
- 转码?
- 推流(RTMP / WebRTC)?
- OpenGL + YUV 渲染?
- FFmpeg + 多线程?
我可以把 流程改成你项目专用版本 + 完整可运行工程模板(非常适合你现在的视频 SDK 项目 👍)。