开篇:拿到这个项目,我是怎么下手的
系列目录:
- 01 开篇:项目初印象(本篇)
- 02 从主函数开始看起
- 03 RKMedia 三大模块初始化(VI / VENC / RGA)
- 04 通道绑定与任务分发
- 05 数据是怎么流动的:三大工作线程
- 06 VIDEO_QUEUE:生产者消费者队列
- 07 FFmpeg 推流侧的初始化
- 08 AVPacket 搬运工与写帧
- 09 Makefile、交叉编译与踩坑总结
一、这个项目是干嘛的
一句话:RV1126 开发板采集摄像头画面 → 硬件编码成 H264 → 用 FFmpeg 打包推到流媒体服务器(RTMP)。
说白了就是一块板子当"直播摄像头"用。README 里写得很直白:
这个项目使用的是 RV1126 视频编码+音频编码,然后通过交叉编译的 ffmpeg 作为推流器进行推流,进行 RTMP 推流。主函数是
rv1126_ffmpeg_main.cpp,大家先从这个位置开始看。
另外 README 还提了一嘴:SRT 协议还没完全搞定,后面会持续改。这个坑我留到最后一篇说。
二、第一件事:看文件名,别急着看代码
刚打开项目目录的时候,十几个 cpp 文件堆在一起,直接硬看代码肯定懵。我的做法是先看文件名规律,结果发现这个项目的命名挺讲究的,甚至项目里还有一份《文件命名前缀规范说明.md》专门解释这件事:
| 前缀 | 是什么层次 | 干嘛的 |
|---|---|---|
rv1126_ |
硬件层 | 芯片平台相关,比如 ISP 图像处理 |
rkmedia_ |
SDK 层 | Rockchip 的 RKMedia API 封装 |
ffmpeg_ |
第三方库层 | 推流相关的数据结构(队列) |
sample_ |
官方示例 | Rockchip 给的参考代码,基本不动 |
它给的类比我觉得很形象:
rv1126_* = 地基和框架(硬件基础)
rkmedia_* = 水电管道(SDK 基础设施)
ffmpeg_* = 装修材料(第三方功能库)
sample_* = 装修图纸(官方参考方案)
main.cpp = 房子整体(你的应用)
有了这个地图,看代码的顺序就出来了:从 main 开始,先往硬件方向走一遍(初始化),再沿着数据流走一遍(线程和队列),最后到网络那一头(FFmpeg 推流)。这个系列博客就按这个顺序写。
三、整体架构:一张图说清楚

几个我一开始没意识到、后来才摸出味道的点:
- 两路码流不是两次采集。摄像头只采一次 1080P,高清路直接编码;低清路靠 RGA 硬件缩放成 720P 再进第二个编码通道。一路传感器出两档清晰度,直播场景很典型。
- RKMedia 和 FFmpeg 之间靠队列解耦。硬件那头出数据的节奏和网络上消费的节奏肯定对不上,中间塞了个带锁的队列,两边各跑各的线程。
- FFmpeg 在这里不负责编码 。编码是 RV1126 的硬件 VENC 干的,FFmpeg 只干"搬运 + 打包 + 发网络"的活。我一开始还以为要用 FFmpeg 编码,看了半天发现
avcodec_open2打开编码器只是为了拿它填参数,一帧都没编过。
四、看代码的实际路径
记录一下我真实的阅读顺序,给以后拿到陌生项目参考:
README.md→ 知道项目干什么的,入口在哪文件命名前缀规范说明.md→ 建立文件地图rv1126_ffmpeg_main.cpp→ 只有 30 多行,看程序骨架rkmedia_module_function.cpp→ 所有硬件模块的参数都在这,分辨率/帧率/码率一目了然rkmedia_assignment_manage.cpp→ 绑定关系 + 创建了哪些线程rkmedia_data_process.cpp→ 线程函数的实现,数据流的核心ffmpeg_video_queue.cpp/ffmpeg_audio_queue.cpp→ 独立的小组件,纯数据结构rkmedia_ffmpeg_config.cpp→ FFmpeg 侧的初始化Makefile→ 最后看,确认链接了哪些库
这个顺序的基本逻辑:先骨架再血肉,先硬件侧再网络侧,顺着数据流方向走。
五、这个系列怎么写
后面每篇我会按这个套路来:
- 这部分代码在干嘛(一句话)
- 关键代码贴出来,配我的理解
- 我卡住过 / 想错过的点(这个最重要,光看别人讲懂了不算懂)
- 留下的疑问(有些问题我到现在也没完全确认,写出来防止自己忘了)
声明一下:我是边学边写的,理解不一定全对,发现的坑也会如实记录。如果哪篇有说错的地方,以后回头改。
下一篇:从主函数开始看起 ------ 一个 30 行的 main 里藏着整个程序的生命周期。