八、V4L2 ioctl 控制接口 调用流程
一、V4L2应用层调用流程
二、V4L2设备注册
三、video设备初始化
四、V4L2 control结构框架图
五、v4l2 ctrl 函数初始化—增加标准接口v4l2_ctrl_new_std
六、v4l2 ctrl 函数初始化—增加自定义接口v4l2_ctrl_new_custom
七、V4L2 ioctl 标准接口 调用流程
八、V4L2 ioctl 控制接口 调用流程
V4L2 ioctl 控制接口 调用流程
当 使用v4l2打开配置好video节点后,还可能需要对设备进行参数 sensor 或者ISP的参数配置,例如自动对焦、自动曝光、亮度、对比度、锐度、色度、白平衡、测试图案等等
V4L2_CID_BRIGHTNESS
我们举例 设置亮度
static void set_sensor_brightness(int videofd, int brightness)
{
struct v4l2_control ctrl;
ctrl.id = V4L2_CID_BRIGHTNESS;
ctrl.value = brightness;
if (-1 == ioctl (videofd, VIDIOC_S_CTRL, &ctrl)) {
printf("Do sensor brightness failed\n");
}
}
VIDIOC_S_CTRL跟前面七、V4L2 ioctl 标准接口 调用流程 一样
不过ret = info->func(ops, file, fh, arg); 函数调用的是 v4l_s_ctrl
v4l_s_ctrl
static int v4l_s_ctrl(const struct v4l2_ioctl_ops *ops,
struct file *file, void *fh, void *arg)
{
struct video_device *vfd = video_devdata(file);
struct v4l2_control *p = arg;
struct v4l2_fh *vfh =
test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
struct v4l2_ext_controls ctrls;
struct v4l2_ext_control ctrl;
if (vfh && vfh->ctrl_handler)
return v4l2_s_ctrl(vfh, vfh->ctrl_handler, p);
if (vfd->ctrl_handler)
return v4l2_s_ctrl(NULL, vfd->ctrl_handler, p);
if (ops->vidioc_s_ctrl)
return ops->vidioc_s_ctrl(file, fh, p);
if (ops->vidioc_s_ext_ctrls == NULL)
return -ENOTTY;
ctrls.which = V4L2_CTRL_ID2WHICH(p->id);
ctrls.count = 1;
ctrls.controls = &ctrl;
ctrl.id = p->id;
ctrl.value = p->value;
if (check_ext_ctrls(&ctrls, 1))
return ops->vidioc_s_ext_ctrls(file, fh, &ctrls);
return -EINVAL;
}
v4l2_s_ctrl(vfh, vfh->ctrl_handler, p);
int v4l2_s_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
struct v4l2_control *control)
{
struct v4l2_ctrl *ctrl = v4l2_ctrl_find(hdl, control->id);
struct v4l2_ext_control c = { control->id };
int ret;
if (ctrl == NULL || !ctrl->is_int)
return -EINVAL;
if (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY)
return -EACCES;
c.value = control->value;
ret = set_ctrl_lock(fh, ctrl, &c);
control->value = c.value;
return ret;
}
set_ctrl_lock
static int set_ctrl_lock(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl,
struct v4l2_ext_control *c)
{
int ret;
v4l2_ctrl_lock(ctrl);
user_to_new(c, ctrl);
ret = set_ctrl(fh, ctrl, 0);
if (!ret)
cur_to_user(c, ctrl);
v4l2_ctrl_unlock(ctrl);
return ret;
}
set_ctrl
static int set_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 ch_flags)
{
struct v4l2_ctrl *master = ctrl->cluster[0];
int ret;
int i;
/* Reset the 'is_new' flags of the cluster */
for (i = 0; i < master->ncontrols; i )
if (master->cluster[i])
master->cluster[i]->is_new = 0;
ret = validate_new(ctrl, ctrl->p_new);
if (ret)
return ret;
/* For autoclusters with volatiles that are switched from auto to
manual mode we have to update the current volatile values since
those will become the initial manual values after such a switch. */
if (master->is_auto && master->has_volatiles && ctrl == master &&
!is_cur_manual(master) && ctrl->val == master->manual_mode_value)
update_from_auto_cluster(master);
ctrl->is_new = 1;
return try_or_set_cluster(fh, master, true, ch_flags);
}
try_or_set_cluster
static int try_or_set_cluster(struct v4l2_fh *fh, struct v4l2_ctrl *master,
bool set, u32 ch_flags)
{
...
ret = call_op(master, s_ctrl);
}
#define has_op(master, op) \
(master->ops && master->ops->op)
#define call_op(master, op) \
(has_op(master, op) ? master->ops->op(master) : 0)
//这里面的master就是 v4l2_ctrl,指向的ops就是 初始化增加一个ctrl的
那这个call_op(master, op)最终的调用地方就是到
static int xxx_v4l2_ctrl_s_ctrl_standard( struct v4l2_ctrl *ctrl )
{
switch ( ctrl->id ) {
case V4L2_CID_BRIGHTNESS:
xxx
break;
}
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgakbji
系列文章
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01