Skip to content

V4L2Param_ParamProcessor

SweerItTer edited this page Feb 1, 2026 · 3 revisions

ParamProcessor API 文档

概述

ParamProcessor 是 utilsCore V4L2 参数模块的核心类,提供 V4L2 参数自动处理和监控功能。

职责

  • 自动应用目标参数设置
  • 参数变化监控和日志记录
  • 错误回调通知
  • 线程安全参数处理

适用场景

  • 参数批量设置
  • 参数变化监控
  • 调试和日志记录
  • 参数自动应用

依赖关系

  • 依赖: ParamControl, ParamLogger
  • 被依赖: VisionPipeline, RecordPipeline 等模块

类分析

ParamProcessor 类

职责与用途

ParamProcessor 是 V4L2 参数处理器的封装类,提供:

  • 目标参数设置和自动应用
  • 参数变化监控
  • 成功/错误回调通知
  • 调试日志记录

设计模式

  • 观察者模式: 回调通知参数变化
  • RAII: 自动管理资源
  • 移动语义: 支持移动构造和移动赋值

回调类型定义

Callback - 成功回调

using Callback = std::function<void(const std::string& name, int value)>;

参数说明:

  • name (输入): 参数名称
  • value (输入): 参数值

ErrorCallback - 错误回调

using ErrorCallback = std::function<void(const std::string& msg)>;

参数说明:

  • msg (输入): 错误消息

公共 API 方法

构造函数

explicit ParamProcessor(const std::string& devicePath);  // 自动打开设备
explicit ParamProcessor(int externalFd);                 // 使用外部 fd
~ParamProcessor();

参数说明:

  • devicePath (输入): V4L2 设备路径(如 "/dev/video0")
  • externalFd (输入): 外部文件描述符

返回值: 无

所有权归属:

  • devicePath 构造: ParamProcessor 拥有 ParamControl 的所有权
  • externalFd 构造: ParamProcessor 使用外部 fd,不负责关闭

注意事项:

  1. 构造时会创建 ParamControl 实例
  2. devicePath 构造会自动打开设备
  3. externalFd 构造使用外部 fd,不负责关闭
  4. 禁止拷贝构造和拷贝赋值

使用例程:

// 使用设备路径构造
ParamProcessor processor("/dev/video0");

// 使用外部 fd 构造
int camera_fd = open("/dev/video0", O_RDWR);
ParamProcessor processor(camera_fd);
// ...
close(camera_fd);  // 调用者负责关闭

移动构造和移动赋值

ParamProcessor(ParamProcessor&& other) noexcept;
ParamProcessor& operator=(ParamProcessor&& other) noexcept;

参数说明:

  • other (输入): 右值引用

返回值:

  • 移动构造: 无
  • 移动赋值: 返回 *this 引用

所有权归属:

  • 资源所有权从 other 转移到 this
  • other 处于有效但未定义状态

注意事项:

  1. 支持移动语义
  2. 移动后 other 处于有效但未定义状态
  3. 禁止拷贝构造和拷贝赋值

enableDebugLog() - 启用调试日志

void enableDebugLog(bool enable);

参数说明:

  • enable (输入): 是否启用调试日志

返回值: 无

所有权归属:

  • 无所有权转移

注意事项:

  1. 启用后会在参数变化时输出调试信息
  2. 默认不启用

setSuccessCallback() - 设置成功回调

void setSuccessCallback(Callback cb);

参数说明:

  • cb (输入): 成功回调函数

返回值: 无

所有权归属:

  • callback 由 ParamProcessor 持有

注意事项:

  1. 参数成功应用时调用
  2. 回调参数为参数名称和值
  3. 可以覆盖之前的回调

使用例程:

processor.setSuccessCallback([](const std::string& name, int value) {
    printf("Parameter %s set to %d\n", name.c_str(), value);
});

setErrorCallback() - 设置错误回调

void setErrorCallback(ErrorCallback cb);

参数说明:

  • cb (输入): 错误回调函数

返回值: 无

所有权归属:

  • callback 由 ParamProcessor 持有

注意事项:

  1. 参数应用失败时调用
  2. 回调参数为错误消息
  3. 可以覆盖之前的回调

使用例程:

processor.setErrorCallback([](const std::string& msg) {
    printf("Error: %s\n", msg.c_str());
});

start() - 启动处理

void start();

参数说明: 无

返回值: 无

所有权归属:

  • 无所有权转移

注意事项:

  1. 启动参数处理线程
  2. 开始自动应用目标参数
  3. 必须先调用 setTargetControls() 设置目标参数
  4. 线程安全操作

使用例程:

processor.start();

stop() - 停止处理

void stop();

参数说明: 无

返回值: 无

所有权归属:

  • 无所有权转移

注意事项:

  1. 停止参数处理线程
  2. 等待线程退出
  3. 线程安全操作

使用例程:

processor.stop();

setTargetControls() - 设置目标参数

void setTargetControls(const ParamControl::ControlInfos& controlList);

参数说明:

  • controlList (输入): 目标参数列表(ParamControl::ControlInfos = std::vector<V4L2ControlInfo>

返回值: 无

所有权归属:

  • 无所有权转移

注意事项:

  1. 设置目标参数列表
  2. 调用 start() 后会自动应用这些参数
  3. 线程安全操作

使用例程:

// 获取当前参数
auto controls = paramControl.queryAllControls();

// 修改目标值
for (auto& ctrl : controls) {
    if (ctrl.name == "exposure_absolute") {
        ctrl.current = 100;  // 设置目标值
    }
}

// 设置目标参数
processor.setTargetControls(controls);

// 启动处理
processor.start();

getCurrentControls() - 获取当前参数

ParamControl::ControlInfos& getCurrentControls();

参数说明: 无

返回值: 当前参数列表的引用

所有权归属:

  • 返回引用,不转移所有权

注意事项:

  1. 返回当前参数列表
  2. 可以修改参数值
  3. 线程安全操作(需要外部同步)

使用例程:

auto& controls = processor.getCurrentControls();

for (const auto& ctrl : controls) {
    printf("%s: %d\n", ctrl.name.c_str(), ctrl.current);
}

getCurrentController() - 获取当前 ParamController

ParamControl& getCurrentController();

参数说明: 无

返回值: ParamControl 引用

所有权归属:

  • 返回引用,不转移所有权

注意事项:

  1. 返回内部的 ParamControl 实例
  2. 可以直接操作 ParamControl
  3. 线程安全操作

使用例程:

auto& controller = processor.getCurrentController();

// 直接使用 ParamControl
auto controls = controller.queryAllControls();
controller.setControl(V4L2_CID_EXPOSURE_ABSOLUTE, 100);

内部实现

数据成员

class ParamProcessor {
private:
    ParamControl param_;                                    // ParamControl 实例
    std::thread thread_;                                    // 处理线程
    std::mutex mutex_;                                      // 互斥锁
    std::atomic<bool> running_ {false};                     // 运行标志
    ParamControl::ControlInfos currentControls_;            // 当前参数
    ParamControl::ControlInfos pendingControls_;             // 待处理参数
    Callback successCallback_;                              // 成功回调
    ErrorCallback errorCallback_;                            // 错误回调
};

处理流程

1. start() 启动处理线程
2. 线程循环:
   - 对比 currentControls_ 和 pendingControls_
   - 检测变化
   - 调用 applyChange() 应用变化
   - 成功:调用 successCallback_
   - 失败:调用 errorCallback_
3. stop() 停止处理线程

线程安全说明

同步机制

  1. 运行状态: std::atomic<bool> 保护
  2. 参数访问: std::mutex 保护
  3. 回调调用: 在处理线程中调用

线程安全建议

  • 可以并发调用 setTargetControls()
  • 可以并发调用 getCurrentControls()
  • 其他操作需要外部同步

典型使用场景

场景 1: 基本使用

// 创建处理器
ParamProcessor processor("/dev/video0");

// 设置回调
processor.setSuccessCallback([](const std::string& name, int value) {
    printf("%s = %d\n", name.c_str(), value);
});

processor.setErrorCallback([](const std::string& msg) {
    printf("Error: %s\n", msg.c_str());
});

// 获取并修改目标参数
auto& controls = processor.getCurrentControls();
for (auto& ctrl : controls) {
    if (ctrl.name == "exposure_absolute") {
        ctrl.current = 100;
    }
}

// 设置目标参数
processor.setTargetControls(controls);

// 启动处理
processor.start();

// 运行一段时间...
sleep(10);

// 停止处理
processor.stop();

场景 2: 使用外部 fd

int camera_fd = open("/dev/video0", O_RDWR);

// 创建处理器
ParamProcessor processor(camera_fd);

// 设置参数...
auto& controls = processor.getCurrentControls();
// ... 修改参数 ...

processor.setTargetControls(controls);
processor.start();

// 运行...
sleep(10);

processor.stop();

// 关闭 fd
close(camera_fd);

场景 3: 调试日志

ParamProcessor processor("/dev/video0");

// 启用调试日志
processor.enableDebugLog(true);

// 设置参数...
// ... 处理 ...

// 输出调试信息到 stderr

场景 4: 直接使用 ParamControl

ParamProcessor processor("/dev/video0");

// 获取 ParamControl 实例
auto& controller = processor.getCurrentController();

// 直接操作 ParamControl
auto controls = controller.queryAllControls();
controller.setControl(V4L2_CID_EXPOSURE_ABSOLUTE, 100);

// 或者通过 ParamProcessor 设置
processor.setTargetControls(controls);
processor.start();

注意事项

  1. 构造方式: 两种构造方式(devicePath 和 externalFd)
  2. 移动语义: 支持移动构造和移动赋值,禁止拷贝
  3. 目标参数: 必须先调用 setTargetControls() 再调用 start()
  4. 回调类型: Callback 参数是 const std::string& nameint value
  5. 线程安全: getCurrentControls() 返回引用,需要外部同步
  6. 资源管理: 析构时自动停止处理线程
  7. fd 所有权: externalFd 构造时不负责关闭 fd
  8. 参数列表: 使用 ParamControl::ControlInfosstd::vector<V4L2ControlInfo>

相关文档


参考资料

主页

API 文档

DMA 模块

DRM 模块

NET 模块

V4L2 模块

V4L2Param 模块

RGA 模块

MPP 模块

Sys 模块

Mouse 模块

Utils 模块

Clone this wiki locally