1. 项目背景与核心目标
在现代多媒体应用开发中,视频采集与编码是基础且关键的技术环节。FFmpeg作为业界广泛使用的开源多媒体框架,提供了强大的音视频处理能力。然而,直接使用FFmpeg的C API进行开发往往面临接口复杂、资源管理困难等问题。本项目旨在通过现代C++(C++17及以上)对FFmpeg进行封装,构建一个从摄像头采集到H.264编码的完整解决方案。
核心目标包括:
- 封装FFmpeg底层API,提供类型安全、资源自动管理的现代C++接口
- 实现摄像头视频采集的跨平台支持(Linux/v4l2, Windows/DShow)
- 构建高效的H.264编码流水线,支持硬件加速(如Intel QSV, NVIDIA NVENC)
- 设计合理的线程模型,平衡实时性与资源消耗
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备与FFmpeg集成
2.1 FFmpeg编译与配置
现代C++项目通常使用CMake作为构建系统,我们需要首先确保FFmpeg正确集成到CMake项目中:
cmake复制# CMakeLists.txt片段示例
find_package(PkgConfig REQUIRED)
pkg_check_modules(FFMPEG REQUIRED
libavcodec
libavformat
libavutil
libswscale
libavdevice)
target_include_directories(YourTarget PRIVATE ${FFMPEG_INCLUDE_DIRS})
target_link_libraries(YourTarget PRIVATE ${FFMPEG_LIBRARIES})
对于需要自定义编译FFmpeg的情况,推荐以下配置选项:
bash复制./configure \
--enable-shared \
--enable-gpl \
--enable-libx264 \
--enable-encoder=h264_nvenc \
--enable-encoder=h264_qsv \
--enable-nonfree
2.2 现代C++基础框架
我们使用RAII(Resource Acquisition Is Initialization)原则设计基础封装类:
cpp复制class AVFormatContextWrapper {
public:
explicit AVFormatContextWrapper(const std::string& filename) {
ctx_ = avformat_alloc_context();
if (!ctx_) throw std::runtime_error("Failed to allocate format context");
}
~AVFormatContextWrapper() {
if (ctx_) avformat_free_context(ctx_);
}
// 删除拷贝构造和赋值
AVFormatContextWrapper(const AVFormatContextWrapper&) = delete;
AVFormatContextWrapper& operator=(const AVFormatContextWrapper&) = delete;
// 允许移动语义
AVFormatContextWrapper(AVFormatContextWrapper&& other) noexcept {
std::swap(ctx_, other.ctx_);
}
AVFormatContext* get() const { return ctx_; }
private:
AVFormatContext* ctx_ = nullptr;
};
3. 摄像头采集实现
3.1 跨平台设备枚举
不同操作系统下摄像头设备的访问方式差异很大,我们需要抽象出统一的设备接口:
cpp复制class VideoDevice {
public:
struct DeviceInfo {
std::string id;
std::string name;
std::vector<std::pair<int, int>> resolutio
