media_device

介绍

日期作者备注
2025/04/06Manfredxxc初版
  • 内核版本:kernel-4.1.15
  • 参考源码:drivers/media/platform/omap3isp/isp.c

在v4l2框架里,media framework通过硬件抽象和动态拓扑管理,管理复杂多媒体设备的子系统(如camera、isp等),定制视频处理流水线

  • 通过将硬件设备抽象成一个个的entity,并通过padslinks建立联系,形成Pipeline
  • 运行时调整Pipeline即可动态改变数据流

media_device

struct media_device表示一个media设备,通常会嵌入到一个更大的私有结构体

数据类型简要说明

struct media_device {
	/* dev->driver_data points to this struct. */
	struct device *dev;
	struct media_devnode devnode; // cdev封装,用于创建/dev/media<X>

	char model[32]; // 设备型号描述,会通过sysfs设备属性导出,例:/sys/bus/media/devices/media0/model
	char serial[40]; // 设备序列号
	char bus_info[32]; // 唯一的设备位置标识符 todo@Manfredxxc:查清作用
	u32 hw_revision; // 硬件设备版本
	u32 driver_version; // 驱动版本

	u32 entity_id; // 下一个要注册的entity的ID,初始化值为1
	struct list_head entities; // entity链表

    // link状态变化回调
	int (*link_notify)(struct media_link *link, u32 flags,
			   unsigned int notification);
};

API简要说明

media_device_register

  • 描述:注册一个media设备
  • 原型:media_device_register(struct media_device *mdev)
  • 注意:调用前需要初始化mdevmdev->model必须得到填充
  • 详情:初始化mdev->devnode,注册一个字符设备节点/dev/media,该节点的fops仅ioctl有意义:`media_device_ioctl

media_device_ioctl

  • 描述:media设备支持的ioctl操作
  • 原型:static long media_device_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
  • @cmd:
    1. MEDIA_IOC_DEVICE_INFO :查看媒体设备信息
    2. MEDIA_IOC_ENUM_ENTITIES :枚举entity信息
    3. MEDIA_IOC_ENUM_LINKS :枚举links信息
    4. MEDIA_IOC_SETUP_LINK :设置link flag (ENABLE | IMMUTABLE | DYNAMIC)

media_graph

media framework中,通过struct media_entitystruct media_linkstruct media_pad抽象出一个硬件拓扑关系media graph

#------------#                #------------#
|          __|__            __|__          |
|         |     |   link   |     |         |
|         | pad |--------->| pad |         |
|         |     |<---------|     |         |
|         |__ __| backlink |__ __|         |
|   entity   |                |   entity   |
#------------#                #------------# 

通过动态配置硬件拓扑来控制数据流Pipeline,并提供开启/关闭、效果/节点控制等功能

例:sensor => isp => encoder => /dev/video

数据类型简要说明

struct media_link:代表一个link,链接两个pad

struct media_link {
	struct media_pad *source;	/* Source pad */
	struct media_pad *sink;		/* Sink pad  */
	struct media_link *reverse;	/* 反向link */
	unsigned long flags;		/* ENABLE | IMMUTABLE | DYNAMIC */
};

struct media_pad:代表entity上的一个pad

struct media_pad {
	struct media_entity *entity;	/* 指向所属entity */
	u16 index;			/* 在所属entity的pad数组上的索引 */
	unsigned long flags;		/* SINK | SOURCE | MUST_CONNECT */
};

struct entity在media graph中表示一个entity

struct media_entity {
	struct list_head list; // media_device->entities链表
	struct media_device *parent;	/* 该entity所属的 Media device */
	u32 id;				/* 所属 Media device上下文的唯一entity ID */
	const char *name;		/* Entity名 */
	u32 type;			/* Entity类型 (MEDIA_ENT_T_*) */
	u32 revision;			/* 驱动指定的entity版本 */
	unsigned long flags;		/* Entity flags (MEDIA_ENT_FL_*) */
	u32 group_id;			/* Entity group ID */

	u16 num_pads;			/* sink/source pad数量 */
	u16 num_links;			/* 已经创建的enable/disable links数量(分配内存后,起始为0,每次create_link,num_link++) */
	u16 num_backlinks;		/* backlinks数量 */
	u16 max_links;			/* inks最大值 */

	struct media_pad *pads;		/* Pads数组 */
	struct media_link *links;	/* Links数组 */

	const struct media_entity_operations *ops;	/* Entity支持的操作 */

	int stream_count;		/* 该entity上的stream数量 */
	int use_count;			/* 该entity引用计数 */

	struct media_pipeline *pipe;	/* 该entity从属的Pipeline */

	union {
		/* Node specifications */
		struct {
			u32 major;
			u32 minor;
		} dev;

		/* Sub-device specifications */
		/* Nothing needed yet */
	} info;
};

struct media_entity_graph:显示栈+位图,实现非递归的拓扑遍历,对深度和ID进行限制保证健壮性

struct media_entity_graph {
	struct {
		struct media_entity *entity; // 当前处理的entity
		int link;					 // 当前处理的link索引
	} stack[MEDIA_ENTITY_ENUM_MAX_DEPTH]; // 栈空间

	DECLARE_BITMAP(entities, MEDIA_ENTITY_ENUM_MAX_ID); // entity标记位图
	int top;
};

API简要说明

media_entity_init

  • 描述:初始化一个media entity,为entity->links分配num_pads+extra_linkslink大小的内存,绑定相应的entity、pads、links

  • 原型:int media_entity_init(struct media_entity *entity, u16 num_pads, struct media_pad *pads, u16 extra_links)

  • 参数:

    • @entity:待初始化entity
    • @num_pads:该entity上的pads数量
    • @pads:pads数组
    • @extra_links:预估的额外links数量

media_device_register_entity

  • 描述:注册一个entity到media device,为entity->id分配一个唯一ID,并将其添加到media_device->entities链表上
  • 原型:int __must_check media_device_register_entity(struct media_device *mdev, struct media_entity *entity)

media_entity_create_link

  • 描述:在两个entity pad之间创建一个link和一个backlink
  • 原型:int media_entity_create_link(struct media_entity *source, u16 source_pad, struct media_entity *sink, u16 sink_pad, u32 flag)
  • 参数:
    • @source:source entity
    • @souce_pad:link连接到的source pad,backlink的sink pad
    • @sink:sink entity
    • @sink_pad:link链接到的sink pad,backlink的source pad
    • @flag:ENABLE(开启) | IMMUTABLE(不可变的) | DYNAMIC(动态的)

media_entity_setup_link

  • 描述:配置media link,配置link的大部分工作由该link链接的entity处理,此函数会通知这两个entity,它们的link配置发生了变化。如果link不可变或者与设置的相同,直接返回

  • 原型:int media_entity_setup_link(struct media_link *link, u32 flag)

  • 细节:
    - 配置前后都会调用media_device->link_notify(),分别传递 MEDIA_DEV_NOTIFY_PRE_LINK_CH、MEDIA_DEV_NOTIFY_POST_LINK_CH
    - 配置函数:__media_entity_setup_link_notify(link, flag),分别调用source/sink pad的 entity->ops->link_setup()

media_entity_find_link

  • 描述:返回连接两个pad的link,如果不存在则返回NULL
  • 原型:struct media_link *media_entity_find_link(struct media_pad *source, struct media_pad *sink)

media_entity_remote_pad

  • 描述:返回与local pad相连(link必须是enable)的remote pad,不存在则返回NULL
  • 原型:struct media_pad *media_entity_remote_pad(struct media_pad *pad)

media_entity_pipeline_start

  • 描述:图遍历给定的初始entity,利用位图将管道标记为streaming(流式传输状态)
  • 原型:__must_check int media_entity_pipeline_start(struct media_entity *entity, struct media_pipeline *pipe)

media_entity_call

  • 描述:辅助宏,调用entity->ops->operation(entity, args)
  • 原型:media_entity_call(entity, operation, args...)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值