Linux media子系统

21 篇文章 65 订阅

为什么会有media这样的一个子系统?

在多媒体的框架中,总是复杂多样的,为了解决多媒体设备的复杂性和数据流动性,创建了media子系统。Media使用一个树状结构,将多媒体数据通路的各个设备连接在一起,方便各个设备的管理和控制。

media 框架

在开机的时候,将会在[media-devnode.c]中,通过media_devnode_init()函数为media设备分配一个主设备号,次设备号从0~255,同时注册一个名字为“media”的bus总线。这个时候,只是申请分配了一个名为media的设备号而已,具体的media设备注册,将在相应的设备驱动中进行注册登记。

下面以camera为例,介绍media框架流程。在了解media框架前,先了解camera设备的注册流程,在注册 /dev/videoX 节点时,主要操作流程如下:

  1. 通过 platform probe,初始化各个 v4l2 subdevice;
  2. 先通过 v4l2_device_register() 函数,注册 v4l2 device;
  3. 先后通过调用 media_device_init()、 media_device_register() 函数,注册 /dev/mediaX 设备,这个时候,将 v4l2_dev->mdev = media_dev;
  4. 注册各 v4l2 subdevice,同时,在注册各个subdevice时,subdevice 将会作为一个 entity,登记到media_dev;
  5. 通过 video_register_device() 函数注册 /dev/videoX 节点,到目前为止,各个 v4l2 subdevice 已经注册完成,接下来将是根据各个各个子设备的需求,进行相应的连接,设置数据通路;
media 设备与 entity

实际上 /dev/mediaX 设备是一个字符设备,只不过是通过 media 框架的一层封装,只是注册设备的主设备号与此设备号都是从之前预分配的 media 设备获取。
怎么理解 media device 与 entity ,可以简单的理解,media device是一个部门的主管,而 entity 是各个下属,media device 将负责统筹 entity,管理各个数据通路的流向。所以,下面再来看看,entity又是怎样注册的。

我们是以camera为例了解media框架的,在 /dev/videox jieidan 节点设备中,通过struct video_device结构体管理节点,而在该结构体中,又将会包含 v4l2 device 的结构体struct v4l2_device,而在 v4l2 device 的结构体中,又将会包含media device的结构体struct media_device,就是这样,层层包含。

在通过 v4l2_device_register_subdev() 函数注册 v4l2 subdevice 时,将会调用 media_device_register_entity() 函数,将该 v4l2 subdevice 当成一个 entity 注册到 media device,于此同时,还将会有 entity 的 pads 初始化等操作。

media框架的目标之一是发现设备内部拓扑,实时配置。为了实现这个目标,硬件设备被建模为一些图形积木,称为用垫子(pads)连接的实体(entity)。一个entity是一个基本的媒体硬件积木。它可以和大量的逻辑模块–譬如物理硬件设备(CMOS传感器), 逻辑硬件设备(一个SOC图形处理流水线积木),DMA通道或者物理连接器通信。pad是用于entity和其他entity互通的连接端点。entity产生的数据(不仅是video)从该entity的输出流向一个或多个entity的输入。pads不能与芯片的物理pin脚弄混了。一个link是两个pads之间的点对点连接,可以是同一个entity或者不同的entity之间。数据从pad源流向pad终点。
各个entity都已经注册到 media ,那么,接下来看看 entity 间的 link 又是怎样操作的。

entity link

media entity link 是通过media_create_pad_link(struct media_entity *source, u16 source_pad, struct media_entity *sink, u16 sink_pad, u32 flags) 函数完成的。如该函数的声明,需要输入source entity以及source pad、sink entity以及sink pad。各个 entity pad数目是预先已知的,所以在连接的时候,自然知道需要使用哪个pad。
link 时,其实就是分别针对 source、sink 创建一个 media link,都添加到 media device中,并将赋值 link 到 source 与 sink 。
到这里,简单的理解了 media device、entity、pad、link,那么,我们究竟使用这一套框架干嘛呢,继续往下看。

media 框架有什么用?
协商

我们知道,在使用camera的过程中,有各个模块需要互相协助,简单的数据流如下:

sensor ---> CPHY ---> csi ---> isp ---> stream

那么,我们在设置camera的图像输出格式时,将会需要确认,整个 pipeline 都是支持该格式的,这个时候,我们就可以通过 media 框架提供的函数 media_entity_graph_walk_init()media_entity_graph_walk_start()media_entity_graph_walk_next() 等函数开始遍历 pipeline 的各个entity,确认每个entity都是支持该格式的,完成一个数据的协商过程。
同时,当平台支持 scaler 缩放时,又可以从同一个源,经过 scaler 之后,输出不同的分辨率大小等,这样的一个entity,多个输出,这样也是很方便通过 media 框架进行数据的管理。

控制

大部分soc厂商,对自己的ISP算法是不开源的,但是linux内核是开源的,这个时候,soc厂商会将自己的ISP算法放在应用层,这个时候,就需要通过应用层操作到内核,而 media 框架管理着数据的整条通路,所以,在这里,通过 media 框架操作ISP等硬件是非常便捷的。
在注册 media 设备时,在 __media_device_register() 函数,赋值 media devnode fops 为 media_device_fops。而 media_device_fops 主要是通过 ioctl 操作 media 设备。支持以下操作:

static const struct media_ioctl_info ioctl_info[] = {
	MEDIA_IOC(DEVICE_INFO, media_device_get_info, MEDIA_IOC_FL_GRAPH_MUTEX),
	MEDIA_IOC(ENUM_ENTITIES, media_device_enum_entities, MEDIA_IOC_FL_GRAPH_MUTEX),
	MEDIA_IOC(ENUM_LINKS, media_device_enum_links, MEDIA_IOC_FL_GRAPH_MUTEX),
	MEDIA_IOC(SETUP_LINK, media_device_setup_link, MEDIA_IOC_FL_GRAPH_MUTEX),
	MEDIA_IOC(G_TOPOLOGY, media_device_get_topology, MEDIA_IOC_FL_GRAPH_MUTEX),
};

通过这些ioctl,可以获取操作相应 entity 的句柄,进而控制相应的模块操作。

同时,在应用层打开各个 entity,通过 VIDIOC_SUBSCRIBE_EVENT 设置事件的监听,当在内核中产生相应的事件时,通过 v4l2_event_queue() 函数,将事件传递到应用层。

参考文章
  • 6
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
/bin: 是Binary的缩写,这个目录存放着系统必备执行命令 /boot:这里存放的是启动Linux时使用的一些核心文件,包括一些连接文件以及镜像文件,自己的安装别放这里 /dev: Device(设备)的缩写,该目录下存放的是Linux的外部设备,在Linux中访问设备的方式和访问文件的方式是相同的。 /etc: 所有的系统管理所需要的配置文件和子目录。 /home:存放普通用户的主目录,在Linux中每个用户都有一个自己的目录,一般该目录名是以用户的账号命名的,不能包含“_”下划线。 /lib: 系统开机所需要最基本的动态连接共享库,其作用类似于Windows里的DLL文件。几乎所有的应用程序都需要用到这些共享库。 /lost+found:这个目录一般情况下是空的,当系统非法关机后,这里就存放了一些文件。 /medialinux系统会自动识别一些设备,例如U盘、光驱等等,当识别后,linux会把识别的设备挂载到这个目录下。 /misc: 该目录可以用来存放杂项文件或目录,即那些用途或含义不明确的文件或目录可以存放在该目录下。 /mnt:系统提供该目录是为了让用户临时挂载别的文件系统的,我们可以将光驱挂载在/mnt/上,然后进入该目录就可以查看光驱里的内容了。 /net 存放着和网络相关的一些文件. /opt:这是给主机额外安装软件所摆放的目录。比如你安装一个ORACLE数据库则就可以放到这个目录下。默认是空的。 /proc:这个目录是一个虚拟的目录,它是系统内存的映射,我们可以通过直接访问这个目录来获取系统信息。 /root:该目录为系统管理员,也称作超级权限者的用户主目录。 /sbin:s就是Super User的意思,这里存放的是系统管理员使用的系统管理程序。 /selinux:这个目录是Redhat/CentOS所特有的目录,Selinux是一个安全机制,类似于windows的防火墙 /srv:service缩写,该目录存放一些服务启动之后需要提取的数据。 /sys: 这是linux2.6内核的一个很大的变化。该目录下安装了2.6内核中新出现的一个文件系统 sysfs 。 /tmp:这个目录是用来存放一些临时文件的。 /usr: 这是一个非常重要的目录,用户的很多应用程序和文件都放在这个目录下,类似与windows下的program files目录。 /var:这个目录中存放着在不断扩充着的东西,我们习惯将那些经常被修改的目录放在这个目录下。包括各种日志文件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chengwei_peng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值