ue->irqlock); ?
? ? INIT_LIST_HEAD(&queue->mainqueue); ? //初始化uvc视频队列mainqueue链表 ?
? ? INIT_LIST_HEAD(&queue->irqqueue); ? ?//初始化uvc视频队列irqqueue链表 ?
? ? queue->flags = drop_corrupted ? UVC_QUEUE_DROP_CORRUPTED : 0; ?
? ? queue->type = type; ?
} ?
?
14.uvc V4L2设备
14.1 V4L2操作函数集
[cpp]?
const struct v4l2_file_operations uvc_fops = { ?
? ? .owner ? ? ?= THIS_MODULE, ?
? ? .open ? ? ? = uvc_v4l2_open, ? ?//打开方法 ?
? ? .release ? ? ? ? ? ? = uvc_v4l2_release, ? ?//释放方法 ?
? ? .unlocked_ioctl = uvc_v4l2_ioctl, ? //控制方法 ?
? ? .read ? ? ? = uvc_v4l2_read, ? ?//读方法 ?
? ? .mmap ? ? ? = uvc_v4l2_mmap, ? ?//映射方法 ?
? ? .poll ? ? ? = uvc_v4l2_poll, ? ?//轮询方法 ?
}; ?
14.2 打开方法
14.2.1 相关结构体
[cpp] ?
struct uvc_fh {//uvc句柄 ?
? ? struct uvc_video_chain *chain; ?//uvc视频链 ?
? ? struct uvc_streaming *stream; ? //uvc视频流 ?
? ? enum uvc_handle_state state; ?
}; ?
14.2.2 open
[cpp] ?
static int uvc_v4l2_open(struct file *file) ?
{ ?
? ? struct uvc_streaming *stream; ?
? ? struct uvc_fh *handle; ?
? ? int ret = 0; ?
??
? ? uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_open\n"); ?
? ? stream = video_drvdata(file); ? //获取uvc视频流 ?
? ? if (stream->dev->state & UVC_DEV_DISCONNECTED) ? ?//设备没连接 ?
? ? ? ? return -ENODEV; ?
? ? ret = usb_autopm_get_interface(stream->dev->intf); ? ?//唤醒设备 ?
? ? if (ret < 0) ?
? ? ? ? return ret; ?
? ? /* Create the device handle. */ ?
? ? handle = kzalloc(sizeof *handle, GFP_KERNEL); ? //创建uvc句柄 ?
? ? if (handle == NULL) { ?
? ? ? ? usb_autopm_put_interface(stream->dev->intf); ?
? ? ? ? return -ENOMEM; ?
? ? } ?
? ? if (atomic_inc_return(&stream->dev->users) == 1) { ?
? ? ? ? ret = uvc_status_start(stream->dev); //uvc状态开始 ?
? ? ? ? if (ret < 0) { ?
? ? ? ? ? ? usb_autopm_put_interface(stream->dev->intf); ?
? ? ? ? ? ? atomic_dec(&stream->dev->users); ?
? ? ? ? ? ? kfree(handle); ?
? ? ? ? ? ? return ret; ?
? ? ? ? } ?
? ? } ?
? ? handle->chain = stream->chain; ? ?//捆绑uvc句柄和uvc视频链 ?
? ? handle->stream = stream; //捆绑uvc句柄和uvc视频流 ?
? ? handle->state = UVC_HANDLE_PASSIVE; ?//设置uvc状态为未激活 ?
? ? file->private_data = handle; //将uvc句柄作为文件的私有数据 ?
? ? return 0; ?
} ?
14.2.2.1 uvc_status_start启动状态
[cpp] ?
int uvc_status_start(struct uvc_device *dev) ?
{ ?
? ? if (dev->int_urb == NULL) ?
? ? ? ? return 0; ?
? ? return usb_submit_urb(dev->int_urb, GFP_KERNEL); //提交urb ?
} ?
参看 12.uvc状态初始化
14.3 控制方法
14.3.1 V4L2的控制方式可以参考下面的资料
linux媒体接口API
?
常用的命令
[cpp] ?
VIDIOC_REQBUFS:分配内存 ??
VIDIOC_QUERYBUF:把VIDIOC_REQBUFS中分配的数据缓存转换成物理地址 ??
VIDIOC_QUERYCAP:查询驱动功能 ??
VIDIOC_ENUM_FMT:获取当前驱动支持的视频格式 ??
VIDIOC_S_FMT:设置当前驱动的频捕获格式 ??
VIDIOC_G_FMT:读取当前驱动的频捕获格式 ??
VIDIOC_TRY_FMT:验证当前驱动的显示格式 ??
VIDIOC_CROPCAP:查询驱动的修剪能力 ??
VIDIOC_S_CROP:设置视频信号的边框 ??
VIDIOC_G_CROP:读取视频信号的边框 ??
VIDIOC_QBUF:把数据从缓存中读取出来 ??
VIDIOC_DQBUF:把数据放回缓存队列 ??
VIDIOC_STREAMON:开始视频显示函数 ??
VIDIOC_STREAMOFF:结束视频显示函数 ??
VIDIOC_QUERYSTD:检查当前视频设备支持的标准,例如PAL或NTSC。 ??
14.3.2 uvc设备V4L2控制方法uvc_v4l2_do_ioctl
[cpp] ?
static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) ?
{ ?
? ? struct video_device *vdev = video_devdata(file);//获取V4L2设备 ?
? ? struct uvc_fh *handle = file->private_data;//获取uvc句柄 ?
? ? struct uvc_video_chain *chain = handle->chain;//获取uvc视频链 ?
? ? struct uvc_streaming *stream = handle->stream;//获取uvc视频流 ?
? ? long ret = 0; ?