uvc摄像头代码解析6

本文详细解析了UVC(USB Video Class)摄像头的视频设备链扫描及注册过程,包括uvc视频链的构建,如何扫描并添加实体到链表中,以及uvc设备的状态初始化,特别是中断端点在状态控制中的作用。还提到了开启trace的方法和通过lsusb获取的描述符表信息来理解Unit和Terminal的关联。
摘要由CSDN通过智能技术生成

10.扫描视频设备链和注册视频设备

10.1 uvc视频链

struct uvc_video_chain {	//uvc视频链
	struct uvc_device *dev;			//uvc设备
	struct list_head list;			//uvc视频链链表头
	struct list_head entities;		//uvc实体链表头
	struct uvc_entity *processing;	//处理Unit实体
	struct uvc_entity *selector;	//选择器Unit实体
	struct mutex ctrl_mutex;		/* Protects ctrl.info */
};

10.2 uvc扫描设备

static int uvc_scan_device(struct uvc_device *dev)
{
	struct uvc_video_chain *chain;	//uvc视频链
	struct uvc_entity *term;	//uvc实体

	list_for_each_entry(term, &dev->entities, list) {	//遍历全局实体链表
		if (!UVC_ENTITY_IS_OTERM(term))	//获取实体链表中的输出Terminal实体
			continue;
		if (term->chain.next || term->chain.prev)	//已经添加到uvc视频链中了
			continue;
		chain = kzalloc(sizeof(*chain), GFP_KERNEL);	//分配uvc视频链内存(有多少个输入Terminal就有多少个uvc_video_chain)
		if (chain == NULL)
			return -ENOMEM;
		INIT_LIST_HEAD(&chain->entities);	//初始化视频链entities(实体)链表
		mutex_init(&chain->ctrl_mutex);
		chain->dev = dev;	//捆绑uvc视频链和uvc设备
		if (uvc_scan_chain(chain, term) < 0) {	//扫描uvc视频链(处理所有相关的输入pin)
			kfree(chain);
			continue;
		}
		uvc_trace(UVC_TRACE_PROBE, "Found a valid video chain (%s).\n",uvc_print_chain(chain));
		list_add_tail(&chain->list, &dev->chains);	//添加到uvc设备的uvc视频链链表
	}
	if (list_empty(&dev->chains)) {
		uvc_printk(KERN_INFO, "No valid video chain found.\n");
		return -1;
	}
	return 0;
}

10.3 uvc扫描视频链

static int uvc_scan_chain(struct uvc_video_chain *chain,struct uvc_entity *term)
{
	struct uvc_entity *entity, *prev;
	uvc_trace(UVC_TRACE_PROBE, "Scanning UVC chain:");
	entity = term;	//获取实体
	prev = NULL;	//前一个实体
	while (entity != NULL) {
		/* Entity must not be part of an existing chain */
		if (entity->chain.next || entity->chain.prev) {	//已经添加到uvc视频链中了
			uvc_trace(UVC_TRACE_DESCR, "Found reference to entity %d already in chain.\n", entity->id);
			return -EINVAL;
		}
		/* Process entity */
		if (uvc_scan_chain_entity(chain, entity) < 0)	//扫描当前实体
			return -EINVAL;
		/* Forward scan */
		if (uvc_scan_chain_forward(chain, entity, prev) < 0)	//向前扫描实体
			return -EINVAL;
		/* Backward scan */
		prev = entity;		//当前实体作为下一次while循环的前一个实体
		if (uvc_scan_chain_backward(chain, &entity) < 0)	//向后扫描实体
			return -EINVAL;
	}
	return 0;
}

将uvc视频链的输入实体添加到uvc视频链的entities链表中
将uvc视频链添加到uvc设备的chains链表中

10.3.1 扫描当前实体

static int uvc_scan_chain_entity(struct uvc_video_chain *chain,struct uvc_entity *entity)
{
	switch (UVC_ENTITY_TYPE(entity)) {
	case UVC_VC_EXTENSION_UNIT:	//扩展Unit
		if (uvc_trace_param & UVC_TRACE_PROBE)
			printk(" <- XU %d", entity->id);
		if (entity->bNrInPins != 1) {
			uvc_trace(UVC_TRACE_DESCR, "Extension unit %d has more than 1 input pin.\n", entity->id);
			return -1;
		}
		break;
	case UVC_VC_PROCESSING_UNIT:	//处理Unit
		if (uvc_trace_param & UVC_TRACE_PROBE)
			printk(" <- PU %d", entity->id);
		if (chain->processing != NULL) {
			uvc_trace(UVC_TRACE_DESCR, "Found multiple Processing Units in chain.\n");
			return -1;
		}
		chain->processing = entity;	//如果是处理Unit则
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值