【原创】Linux v4l2框架分析 (2)

【原创】Linux v4l2框架分析

CSI:camera接口,接收图像数据,RGB/YUV/JPEG等;

CCDC:视频处理前端,CCDC为图像传感器和数字视频源提供接口,并处理图像数据;

Preview/Resizer:视频处理后端,Preview提供预览功能,可针对不同类型的传感器进行定制,Resizer提供将输入图像数据按所需的显示或视频编码分辨率调整大小的方法;

H3A/HIST:静态统计模块,H3A支持AF、AWB、AE的回路控制,HIST根据输入数据,提供各种3A算法所需的统计数据;

上述硬件模块,可以对应到驱动结构体struct isp_device中的各个字段。

omap3isp的硬件模块,支持多种数据流通路,它并不是唯一的,以RGB为例,如下图:

【原创】Linux v4l2框架分析

Raw RGB数据进入ISP模块后,可以在运行过程中,根据实际的需求进行通路设置;

所以,重点是:它需要动态设置路径!

那么,软件该如何满足这种需求呢?

3.2 框架

没错,pipeline框架的引入可以解决这个问题。说来很巧,我曾经也实现过一个类似的框架,在阅读media framework时有一种似曾相识的感觉,核心的思想大体一致。

【原创】Linux v4l2框架分析

模块之间相互独立,通过struct media_entity来进行抽象,通常会将struct media_entity嵌入到其他结构中,以支持media framework功能;

模块包含struct media_pad,pad可以认为是端口,与其他模块进行联系的媒介,针对特定模块来说它是确定的;

pad通过struct media_link来建立连接,指定source和sink,即可将通路建立起来;

各个模块之间最终建立一条数据流,便是一条pipeline了,同一条pipeline中的模块,可以根据前一个模块查找到下一个模块,因此也可以很方便进行遍历,并做进一步的设置操作;

因此,只需要将struct media_entity嵌入到特定子模块中,最终便可以将子模块串联起来,构成数据流。所以,omap3isp的驱动中,数据流就如下图所示:

【原创】Linux v4l2框架分析

video devnode代表video device,也就是前文中提到的导出到用户空间的节点,用于与用户进行控制及数据交互;

每个模块分别有source pad和sink pad,从连接图就可以看出,数据通路灵活多变;

至于数据通路选择问题,可以在驱动初始化的时候进行链接创建,比如isp_create_links;

还是看一下数据结构吧:

【原创】Linux v4l2框架分析

media_device:与v4l2_device类似,也是负责将各个子模块集中进行管理,同时在注册的时候,会向系统注册设备节点,方便用户层进行操作;

media_entity、media_pad、media_link等结构体的功能在上文中描述过,注意,这几个结构体会添加到media_device的链表中,同时它们结构体的开始字段都需是struct media_gobj,该结构中的mdev将会指向它所属的media_device。这种设计方便结构之间的查找;

media_entity中包含多个media_pad,同时media_pad又会指向它所属的media_entity;

media_graph和media_pipeline是media_entity的集合,直观来理解,就是由一些模块构成的一条数据通路,由一个统一的数据结构来组织管理;

罗列一下常见的几个接口吧,细节不表了:

/* 初始化entity的pads */ int media_entity_pads_init(struct media_entity *entity, u16 num_pads, struct media_pad *pads); /* 在两个entity之间创建link */ int media_create_pad_links(const struct media_device *mdev, const u32 source_function, struct media_entity *source, const u16 source_pad, const u32 sink_function, struct media_entity *sink, const u16 sink_pad, u32 flags, const bool allow_both_undefined); /* 开始graph的遍历,从指定的entity开始 */ void media_graph_walk_start(struct media_graph *graph, struct media_entity *entity); /* 启动pipeline */ __must_check int media_pipeline_start(struct media_entity *entity, struct media_pipeline *pipe);

将media framework和v4l2_device及v4l2_subdev结合起来,就可以将各个子设备构建pipeline,完美!

4. videobuf2 4.1 框架分析

框架可以分成两个部分看:控制流+数据流,上文已经大概描述了控制流,数据流的部分就是video buffer了。

V4L2的buffer管理是通过videobuf2来完成的,它充当用户空间和驱动之间的中间层,并提供low-level,模块化的内存管理功能;

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwxpdx.html