13.uvc视频初始化
13.1 uvc数据流控制
struct uvc_streaming_control {
__u16 bmHint;
__u8 bFormatIndex; //视频格式索引
__u8 bFrameIndex; //视频帧索引
__u32 dwFrameInterval; //视频帧间隔
__u16 wKeyFrameRate; //
__u16 wPFrameRate;
__u16 wCompQuality;
__u16 wCompWindowSize;
__u16 wDelay; //延时
__u32 dwMaxVideoFrameSize; //最大视频帧大小
__u32 dwMaxPayloadTransferSize;
__u32 dwClockFrequency; //时钟频率
__u8 bmFramingInfo;
__u8 bPreferedVersion;
__u8 bMinVersion; //版本
__u8 bMaxVersion; //版本
} __attribute__((__packed__));
13.2 uvc_video_init
int uvc_video_init(struct uvc_streaming *stream)
{
struct uvc_streaming_control *probe = &stream->ctrl; //获取uvc数据流的uvs数据流控制对象
struct uvc_format *format = NULL;
struct uvc_frame *frame = NULL;
unsigned int i;
int ret;
if (stream->nformats == 0) {
uvc_printk(KERN_INFO, "No supported video formats found.\n");
return -EINVAL;
}
atomic_set(&stream->active, 0);
uvc_queue_init(&stream->queue, stream->type, !uvc_no_drop_param); //初始化视频缓冲区队列
usb_set_interface(stream->dev->udev, stream->intfnum, 0); //选择Alt.Setting 0
if (uvc_get_video_ctrl(stream, probe, 1, UVC_GET_DEF) == 0) //VS_PROBE_CONTROL(GET_DEF)
uvc_set_video_ctrl(stream, probe, 1); //VS_PROBE_CONTROL(SET_DEF)
ret = uvc_get_video_ctrl(stream, probe, 1, UVC_GET_CUR); //VS_PROBE_CONTROL(GET_CUR)
if (ret < 0)
return ret;
for (i = stream->nformats; i > 0; --i) { //获取对应的uvc格式
format = &stream->format[i-1];
if (format->index == probe->bFormatIndex) //匹配uvc格式索引值
break;
}
if (format->nframes == 0) {
uvc_printk(KERN_INFO, "No frame descriptor found for the default format.\n");
return -EINVAL;
}
for (i = format->nframes; i > 0; --i) {
frame = &format->frame[i-1]; //获取对应的uvc帧
if (frame->bFrameIndex == probe->bFrameIndex) //匹配uvc帧索引值
break;
}
probe->bFormatIndex = format->index; //设置uvc视频流控制的格式索引为uvc格式的索引
probe->bFrameIndex = frame->bFrameIndex; //设置uvc视频流控制的帧索引为uvc帧的索引
stream->cur_format = format; //设置uvc格式为uvc数据流的cur_format成员
stream->cur_frame = frame; //设置uvc帧未uvc数据流的cur_frame成员
/* Select the video decoding function 选择视频解码函数*/
if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { //视频采集
if (stream->dev->quirks & UVC_QUIRK_BUILTIN_ISIGHT)
stream->decode = uvc_video_decode_isight;
else if (stream->intf->num_altsetting > 1)
stream->decode = uvc_video_decode_isoc; //同步方式
else
stream->decode = uvc_video_decode_bulk; //bluk方式
}
else { //视频播放
if (stream->intf->num_altsetting == 1)
stream->decode = uvc_video_encode_bulk;
else {
uvc_printk(KERN_INFO, "Isochronous endpoints are not supported for video output devices.\n");
return -EINVAL;
}
}
return 0;
}
13.2.1 初始化uvc队列
void uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type,int drop_corrupted)
{
mutex_init(&queue->mutex);
spin_lock_init(&queue->irqlock);
INIT_LIST_HEAD(&queue->main