-
Notifications
You must be signed in to change notification settings - Fork 2
V4L2_Exception
SweerItTer edited this page Feb 1, 2026
·
3 revisions
V4L2Exception 是 utilsCore V4L2 模块的异常类,提供 V4L2 操作错误的异常处理机制。
- 封装 V4L2 操作错误
- 提供错误信息
- 支持异常抛出和捕获
- 错误码和错误消息
- V4L2 操作失败时的异常处理
- 错误诊断和调试
- 异常安全的代码设计
- 依赖: C++ STL
- 被依赖: CameraController, Frame 等所有 V4L2 相关类
V4L2Exception 是 V4L2 异常的封装类,提供:
- 错误码和错误消息
- 异常抛出和捕获
- 详细的错误信息
- 静态日志方法
- 异常模式: 标准异常类
V4L2Exception(const std::string& msg, int err = 0);参数说明:
-
msg(输入): 错误消息 -
err(输入): 错误码(可选,默认 0)
返回值: 无
所有权归属:
- V4L2Exception 持有错误消息的所有权
注意事项:
- 异常对象会在抛出时复制
- 使用标准异常接口
- 错误码通常是 errno
- 错误码会被包含在 what() 返回的消息中
使用例程:
// 抛出异常(无错误码)
throw V4L2Exception("Failed to open device");
// 抛出异常(带错误码)
throw V4L2Exception("Failed to open device", errno);const char* what() const noexcept override;参数说明: 无
返回值: 错误消息(包含错误码描述)
所有权归属:
- 只读访问
注意事项:
- 标准异常接口
- 返回的指针在异常对象生命周期内有效
- 如果提供了错误码,消息格式为 "msg: strerror(err)"
使用例程:
try {
// ... V4L2 操作
} catch (const V4L2Exception& e) {
fprintf(stderr, "Error: %s\n", e.what());
// 输出: "Failed to open device: Permission denied" (如果有错误码)
}static void log(const std::string& msg, int err = 0);参数说明:
-
msg(输入): 错误消息 -
err(输入): 错误码(可选,默认 0)
返回值: 无
所有权归属:
- 无所有权转移
注意事项:
- 静态方法,不需要创建异常对象
- 直接将错误信息输出到 stderr
- 格式:
[V4L2Exception] msg: strerror(err)
使用例程:
// 记录错误(无错误码)
V4L2Exception::log("Device not found");
// 记录错误(带错误码)
V4L2Exception::log("Failed to open device", errno);
// 输出: [V4L2Exception] Failed to open device: Permission deniedclass V4L2Exception : public std::runtime_error {
public:
V4L2Exception(const std::string& msg, int err = 0)
: std::runtime_error(msg + (err ? (": " + std::string(strerror(err))) : "")) {}
static void log(const std::string& msg, int err = 0) {
std::string full = msg;
if (err) {
full += ": ";
full += strerror(err);
}
fprintf(stderr, "[V4L2Exception] %s\n", full.c_str());
}
};// 抛出异常(无错误码)
if (fd < 0) {
throw V4L2Exception("Failed to open device");
}
// 抛出异常(带错误码)
if (ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0) {
throw V4L2Exception("Failed to query device capabilities", errno);
}try {
CameraController camera(cfg);
camera.start();
} catch (const V4L2Exception& e) {
fprintf(stderr, "V4L2 Error: %s\n", e.what());
} catch (const std::exception& e) {
fprintf(stderr, "Error: %s\n", e.what());
}// 直接记录错误,不抛出异常
if (fd < 0) {
V4L2Exception::log("Failed to open device", errno);
return -1;
}| 错误码 | 说明 | 常见原因 |
|---|---|---|
EBUSY |
设备忙 | 设备已被其他进程打开 |
ENOENT |
设备不存在 | 设备路径错误 |
EACCES |
权限不足 | 没有访问设备的权限 |
EINVAL |
参数无效 | 传入的参数不正确 |
ENOMEM |
内存不足 | 系统内存不足 |
EIO |
IO 错误 | 设备通信失败 |
ENOTTY |
不合适的 IO | 设备不支持该操作 |
int fd = open(device.c_str(), O_RDWR);
if (fd < 0) {
throw V4L2Exception("Failed to open device: " + device, errno);
}struct v4l2_capability cap;
if (ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0) {
throw V4L2Exception("Failed to query device capabilities", errno);
}struct v4l2_format fmt;
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = width;
fmt.fmt.pix.height = height;
fmt.fmt.pix.pixelformat = format;
if (ioctl(fd, VIDIOC_S_FMT, &fmt) < 0) {
throw V4L2Exception("Failed to set format", errno);
}struct v4l2_requestbuffers req;
req.count = buffer_count;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_DMABUF;
if (ioctl(fd, VIDIOC_REQBUFS, &req) < 0) {
throw V4L2Exception("Failed to request buffers", errno);
}// 启动流
enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (ioctl(fd, VIDIOC_STREAMON, &type) < 0) {
throw V4L2Exception("Failed to start stream", errno);
}
// 停止流
if (ioctl(fd, VIDIOC_STREAMOFF, &type) < 0) {
throw V4L2Exception("Failed to stop stream", errno);
}// 直接记录错误
if (fd < 0) {
V4L2Exception::log("Failed to open device", errno);
return -1;
}
// 记录错误信息
if (ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0) {
V4L2Exception::log("Failed to query device capabilities", errno);
return -1;
}- 异常传播: 异常会沿着调用栈传播,直到被捕获
- 资源泄漏: 使用 RAII 确保资源正确释放
- 错误码: 错误码包含在 what() 返回的消息中
- 日志方法: log() 是静态方法,不抛出异常
- 异常安全: 确保代码是异常安全的
- 性能: 异常处理有性能开销,不要用于正常流程
- 文档: 记录可能抛出的异常
- what() 返回: 返回完整的错误消息(包含错误码描述)
- CameraController - 摄像头控制器
- Frame - 帧数据接口
- V4L2 模块总览
主页
API 文档
DMA 模块
DRM 模块
- DRM 模块总览
- DeviceController - DRM 设备控制器
- DrmLayer - DRM 图层管理
- PlanesCompositor - DRM 平面合成器
- DrmBpp - DRM 格式定义
NET 模块
- NET 模块总览
- TcpServer - TCP 服务器
- SocketConnection - Socket 连接管理
- CommandHandler - 命令处理器
- DataPacket - 数据包
V4L2 模块
- V4L2 模块总览
- CameraController - V4L2 摄像头控制器
- Frame - V4L2 帧数据结构
- FormatTool - V4L2 格式工具
- Exception - V4L2 异常类
V4L2Param 模块
- V4L2Param 模块总览
- ParamControl - 参数控制
- ParamLogger - 参数日志
- ParamProcessor - 参数处理器
RGA 模块
- RGA 模块总览
- RgaConverter - RGA 转换器
- RgaProcessor - RGA 处理器
- FormatTool - RGA 格式工具
MPP 模块
- MPP 模块总览
- EncoderContext - 编码器上下文
- EncoderCore - 编码器核心
- JpegEncoder - JPEG 编码器
- StreamWriter - 流写入器
- MppResourceGuard - MPP 资源守护
- FileTools - 文件工具
- FormatTool - 格式工具
Sys 模块
- Sys 模块总览
- CpuMonitor - CPU 监控器
- MemoryMonitor - 内存监控器
- Base - 基础类
Mouse 模块
- Mouse 模块总览
- Watcher - 鼠标监视器
Utils 模块
- Utils 模块总览
- AsyncThreadPool - 异步线程池
- ConcurrentQueue - 并发队列
- FdWrapper - 文件描述符包装器
- FenceWatcher - 围栏监视器
- FixedSizePool - 固定大小对象池
- Logger - 日志记录器
- ObjectsPool - 对象池
- OrderedQueue - 有序队列
- ProgressBar - 进度条
- SafeQueue - 安全队列
- SharedBufferState - 共享缓冲区状态
- SimpleVariant - 简单变体类型
- ThreadPauser - 线程暂停器
- ThreadUtils - 线程工具
- Types - 类型定义
- UdevMonitor - Udev 监视器