uvc_entity结构体的申请uvc_alloc_entity函数
2024-03-19
73
0
uvc_entity结构体在使用uvc_alloc_entity申请时,其不仅包含该结构本身,也包括其它额外的内存。
内存的申请使用函数uvc_alloc_entity,其具体代码可见附录。
static struct uvc_entity *uvc_alloc_entity(u16 type, u8 id,
unsigned int num_pads, unsigned int extra_size)
使用uvc_alloc_entity申请的内存,大体包括4部分:
第一部分为绿色,为uvc_entity结构体本身的大小。sizeof(uvc_entity)
struct uvc_entity {
struct list_head list; /* Entity as part of a UVC device. */
struct list_head chain; /* Entity as part of a video device
* chain. */
unsigned int flags;
u8 id;
u16 type;
char name[64];
/* Media controller-related fields. */
struct video_device *vdev;
struct v4l2_subdev subdev;
unsigned int num_pads;
unsigned int num_links;
struct media_pad *pads;
union {
struct {
u16 wObjectiveFocalLengthMin;
u16 wObjectiveFocalLengthMax;
u16 wOcularFocalLength;
u8 bControlSize;
u8 *bmControls;
} camera;
struct {
u8 bControlSize;
u8 *bmControls;
u8 bTransportModeSize;
u8 *bmTransportModes;
} media;
struct {
} output;
struct {
u16 wMaxMultiplier;
u8 bControlSize;
u8 *bmControls;
u8 bmVideoStandards;
} processing;
struct {
} selector;
struct {
u8 guidExtensionCode[16];
u8 bNumControls;
u8 bControlSize;
u8 *bmControls;
u8 *bmControlsType;
} extension;
};
u8 bNrInPins;
u8 *baSourceID;
unsigned int ncontrols;
struct uvc_control *controls;
};
第二部分为extra_size,但因第二部分后续需跟struct media_pad,故extra_size会对齐struct media_pad的整数倍。
//对齐到1个sizeof(*entity->pads))大小
extra_size = roundup(extra_size, sizeof(*entity->pads));
extra_size的内容主要用于存储描述符bmControls,这些bmControls各位代表该单元支持的UVC特定类请求。如对于相机终端描述符其初始化如下:
if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA) {
term->camera.bControlSize = n;
term->camera.bmControls = (u8 *)term + sizeof(*term);
memcpy(term->camera.bmControls, &buffer[15], n);
其它支持UVC特定类请求的类似,如处理单元描述符,扩展单元描述符。
第三部和第四部分都是media_pad结构体,但第四部分其是额外多申请的一部分,用于存储描述符的baSourceID,故在申请时,都可以看到有+1情况。
unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, 0);//UVC_VC_SELECTOR_UNIT
term = uvc_alloc_entity(type | UVC_TERM_OUTPUT, buffer[3],1, 0);//UVC_VC_OUTPUT_TERMINAL
term = uvc_alloc_entity(type | UVC_TERM_INPUT, buffer[3],1, n + p);//UVC_VC_INPUT_TERMINAL
unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, 0);//UVC_VC_SELECTOR_UNIT
unit = uvc_alloc_entity(buffer[2], buffer[3], 2, n);//UVC_VC_PROCESSING_UNIT
至于第三部分,从申请内存来看,只有扩展单元申请到内存,至于怎么用,暂未分析到。
static struct uvc_entity *uvc_alloc_entity(u16 type, u8 id,
unsigned int num_pads, unsigned int extra_size)
{
struct uvc_entity *entity;
unsigned int num_inputs;
unsigned int size;
unsigned int i;
//对齐到1个sizeof(*entity->pads))大小
extra_size = roundup(extra_size, sizeof(*entity->pads));
//输入类型则少一个,输出类型保持不变
num_inputs = (type & UVC_TERM_OUTPUT) ? num_pads : num_pads - 1;
size = sizeof(*entity)
+ extra_size
+ sizeof(*entity->pads) * num_pads
+ num_inputs;
entity = kzalloc(size, GFP_KERNEL);
if (entity == NULL)
return NULL;
entity->id = id;
entity->type = type;
entity->num_links = 0;
entity->num_pads = num_pads;
entity->pads = ((void *)(entity + 1)) + extra_size;
for (i = 0; i < num_inputs; ++i)
entity->pads[i].flags = MEDIA_PAD_FL_SINK;
if (!UVC_ENTITY_IS_OTERM(entity))
entity->pads[num_pads-1].flags = MEDIA_PAD_FL_SOURCE;
entity->bNrInPins = num_inputs;
entity->baSourceID = (u8 *)(&entity->pads[num_pads]);
return entity;
}