Data Structure struct software_node { const char *name; const struct software_node *parent; const struct property_entry *properties; }; struct swnode { struct kobject kobj; struct fwnode_handle fwnode; const struct software_node *node; int id; /* hierarchy */ struct ida child_ids; struct list_head entry; struct list_head children; struct swnode *parent; unsigned int allocated:1; unsigned int managed:1; }; Provider software_node_register()注册单个 software node, software_node_register_node_group()注册一组 software nodes. 都是将 software nodes 挂入一个全局链表. // 定义属性 static const struct property_entry my_device_properties[] = { PROPERTY_ENTRY_U32("reg", 0), PROPERTY_ENTRY_U32("my_property", 1234), { } }; // 定义 software node static const struct software_node my_device_node = { ....

2 min

2.14 V4L2 events V4L2 events 提供了一种方法给 userspace 传递 events. struct v4l2_subscribed_event { struct list_head list; u32 type; u32 id; u32 flags; struct v4l2_fh *fh; struct list_head node; const struct v4l2_subscribed_event_ops *ops; unsigned int elems; unsigned int first; unsigned int in_use; struct v4l2_kevent events[] __counted_by(elems); }; list: 加入到 v4l2_fh->subscribed list 的链表节点。 type: event type, 在 videodev2.h 中定义。 id: event 的 control id, 根据 event 的 (type, id) 二元组就能找到对应的 event. flags: 从 userspace 传入的 v4l2_event_subscription->flags 中拷贝过来。...

1 min

2.15 V4L2 controls V4L2 controls 用于控制和调整视频设备的各种参数。 2.15.2 Objects in the framework struct v4l2_ctrl 描述了 control properties 和对应的 value. struct v4l2_ctrl_handler 用来跟踪 v4l2_ctrl objects. 2.15.3 Basic usage for V4L2 and sub-device drivers prepare the driver 通常把 v4l2_ctrl_handler 放在 top-level struct: // v4l2 drvier: struct foo_dev { ... struct v4l2_device v4l2_dev; ... struct v4l2_ctrl_handler ctrl_handler; ... }; // sub-dev driver: struct foo_dev { ... struct v4l2_subdev sd; ... struct v4l2_ctrl_handler ctrl_handler; ... }; 通过 v4l2_ctrl_handler_init(&foo->ctrl_handler, nr_of_controls) 初始化 v4l2_ctrl_handler....

3 min

struct vb2_queue { unsigned int type; unsigned int io_modes; struct device *dev; unsigned long dma_attrs; unsigned int bidirectional:1; unsigned int fileio_read_once:1; unsigned int fileio_write_immediately:1; unsigned int allow_zero_bytesused:1; unsigned int quirk_poll_must_check_waiting_for_buffers:1; unsigned int supports_requests:1; unsigned int requires_requests:1; unsigned int uses_qbuf:1; unsigned int uses_requests:1; unsigned int allow_cache_hints:1; unsigned int non_coherent_mem:1; struct mutex *lock; void *owner; const struct vb2_ops *ops; const struct vb2_mem_ops *mem_ops; const struct vb2_buf_ops *buf_ops; void *drv_priv; u32 subsystem_flags; unsigned int buf_struct_size; u32 timestamp_flags; gfp_t gfp_flags; u32 min_queued_buffers; u32 min_reqbufs_allocation; struct device *alloc_devs[VB2_MAX_PLANES]; /* private: internal use only */ struct mutex mmap_lock; unsigned int memory; enum dma_data_direction dma_dir; struct vb2_buffer **bufs; unsigned long *bufs_bitmap; unsigned int max_num_buffers; struct list_head queued_list; unsigned int queued_count; atomic_t owned_by_drv_count; struct list_head done_list; spinlock_t done_lock; wait_queue_head_t done_wq; unsigned int streaming:1; unsigned int start_streaming_called:1; unsigned int error:1; unsigned int waiting_for_buffers:1; unsigned int waiting_in_dqbuf:1; unsigned int is_multiplanar:1; unsigned int is_output:1; unsigned int is_busy:1; unsigned int copy_timestamp:1; unsigned int last_buffer_dequeued:1; struct vb2_fileio_data *fileio; struct vb2_threadio_data *threadio; char name[32]; }; type: buffer 的类型,enum v4l2_buf_type, vendor driver 初始化时设置。...

3 min

2.2 Structure of a V4L driver device instances | +-sub-device instances | \-V4L2 device nodes | \-filehandle instances 2.4 Video device video device 用于抽象系统注册的 v4l2 /dev 设备节点,以便用户空间可以进行交互。 可以通过 video_device_alloc() 分配,也可以嵌入在更大的结构体中,这样则需要自定义 release 函数。 如果是嵌入在更大的结构体中,并且没有要释放的资源,可以使用 video_device_release_empty()。 最后通过 video_register_device() 注册。 struct video_device { #if defined(CONFIG_MEDIA_CONTROLLER) struct media_entity entity; struct media_intf_devnode *intf_devnode; struct media_pipeline pipe; #endif const struct v4l2_file_operations *fops; u32 device_caps; /* sysfs */ struct device dev; struct cdev *cdev; struct v4l2_device *v4l2_dev; struct device *dev_parent; struct v4l2_ctrl_handler *ctrl_handler; struct vb2_queue *queue; struct v4l2_prio_state *prio; /* device info */ char name[64]; enum vfl_devnode_type vfl_type; enum vfl_devnode_direction vfl_dir; int minor; u16 num; unsigned long flags; int index; /* V4L2 file handles */ spinlock_t fh_lock; struct list_head fh_list; int dev_debug; v4l2_std_id tvnorms; /* callbacks */ void (*release)(struct video_device *vdev); const struct v4l2_ioctl_ops *ioctl_ops; DECLARE_BITMAP(valid_ioctls, BASE_VIDIOC_PRIVATE); struct mutex *lock; }; entity:...

4 min

2.5 V4L2 device v4l2 用来抽象最顶层的 v4l2 设备,包含一系列子设备。 通过v4l2_device_register (dev, v4l2_dev)注册,在注册前需要调用 dev_set_drvdata() 设置 dev->drier_data 为包含 v4l2_device 的 driver-specific 结构体。 还需要设置好 v4l2->mdev 为 media_device 结构体。 通过v4l2_device_unregister()注销,如果是 hotpluggable 设备,在此之前还需要调用v4l2_device_disconnect() v4l2-device.h: struct v4l2_device { struct device *dev; struct media_device *mdev; struct list_head subdevs; spinlock_t lock; char name[36]; void (*notify)(struct v4l2_subdev *sd, unsigned int notification, void *arg); struct v4l2_ctrl_handler *ctrl_handler; struct v4l2_prio_state prio; struct kref ref; void (*release)(struct v4l2_device *v4l2_dev); }; dev: 底层 device 设备。...

1 min

2.6 V4L2 File handlers struct v4l2_fh 提供了一种方式,使得 file 方便地处理 V4L2 中的一些 specific data. 初始化:v4l2_fh_init(), 必须在 driver 的 v4l2_file_operations->open() 回调中调用, 会置起 video_device 的 V4L2_FL_USES_V4L2_FH flag. 在 userspace open device node 后,调用到 v4l2_fh_open, 会把 file->private_data 设置为 fh. 许多情况下 v4l2_fh 都会嵌入在更大的结构体中,这时需要调用 v4l2_fh_init() 和 v4l2_fh_add 在.open() 回调 v4l2_fh_del() 和 v4l2_fh_exit() 在.release() 回调 struct v4l2_fh { struct list_head list; struct video_device *vdev; struct v4l2_ctrl_handler *ctrl_handler; enum v4l2_priority prio; wait_queue_head_t wait; struct mutex subscribe_lock; struct list_head subscribed; struct list_head available; unsigned int navailable; u32 sequence; struct v4l2_m2m_ctx *m2m_ctx; }; list: 链接到 video_device 的 fh_list....

1 min

2.7 V4L2 sub-devices 许多 drivers 需要和 sub-devices 交流,这些子设备可以处理 audio, video muxing, encoding, decoding 等等。 对于 webcams, 常见的 sub-devices 有 sensors, camera controllers. 通过 v4l2_subdev_init(sd, &ops) 来初始化 v4l2_subdev. 接着需要设置 sd->name. 如果需要和 media framework 聚合,那么需要初始化 media_entity 成员,如果 entity 有 pads 还需要调用media_entity_pads_init. struct v4l2_subdev { #if defined(CONFIG_MEDIA_CONTROLLER) struct media_entity entity; #endif struct list_head list; struct module *owner; bool owner_v4l2_dev; u32 flags; struct v4l2_device *v4l2_dev; const struct v4l2_subdev_ops *ops; const struct v4l2_subdev_internal_ops *internal_ops; struct v4l2_ctrl_handler *ctrl_handler; char name[52]; u32 grp_id; void *dev_priv; void *host_priv; struct video_device *devnode; struct device *dev; struct fwnode_handle *fwnode; struct list_head async_list; struct list_head async_subdev_endpoint_list; struct v4l2_async_notifier *subdev_notifier; struct list_head asc_list; struct v4l2_subdev_platform_data *pdata; struct mutex *state_lock; struct led_classdev *privacy_led; struct v4l2_subdev_state *active_state; u64 enabled_streams; }; owner_v4l2_dev: 如果和 v4l2_dev->dev 的 owner 一致,则为 true....

7 min

Media Controller devices 5.1.1 Abstract media device model entity 用来抽象一个 media hardware block, 可以表示一个物理硬件设备 (CMOS sensor), 也可以表示一个逻辑硬件设备 (isp pipeline) 等。 pad 用来在 entity 之间传输数据,数据从 source pad 流向 sink pad. link 是两个 pad 之间 point-to-point 的连接。 5.1.2 Media device struct media_device 注册 media_device 需要调用:media_device_init(), media_device_register(). 注销:media_device_unregister(), media_device_cleanup(). struct media_device { struct device *dev; struct media_devnode *devnode; char model[32]; char driver_name[32]; char serial[40]; char bus_info[32]; u32 hw_revision; u64 topology_version; u32 id; struct ida entity_internal_idx; int entity_internal_idx_max; struct list_head entities; struct list_head interfaces; struct list_head pads; struct list_head links; struct list_head entity_notify; struct mutex graph_mutex; struct media_graph pm_count_walk; const struct media_device_ops *ops; struct mutex req_queue_mutex; atomic_t request_id; }; dev: 底层的 device parent....

4 min

IPCam 3917 isp 模块图: 信号处理路径模块: Crop:裁剪模块,用于裁剪图像的特定区域 BLC:黑电平补偿(Black level Correction) DPC: 坏点校正(Defect Pixel Correction) 2DNR: 2D降噪(2D Noise Reduction) GE: 边缘增强(Gain Enhancement) 3DNR & GE:3D降噪和增益增强 AE Short/Long Gain:自动曝光短/长时间增益控制 HDR Fusion:高动态范围图像融合,合并不同曝光的图像 镜头校正模块: Circle Lens Shading:圆形镜头阴影校正 Grid Lens Shading:网格镜头阴影校正 色彩处理模块: YUV to RGB:YUV色彩空间转换为RGB INTP:demosaic颜色插值, 从raw格式转换到rgb格式 CCM:色彩校正矩阵(Color Correction Matrix) RGB Gamma:RGB伽马校正 WDR:宽动态范围(Wide Dynamic Range)处理 YUV处理模块: YUV420 To YUV422:YUV色彩格式转换 YUV422 To YUV444:YUV色彩格式转换 RGB2YUV444:RGB转YUV444格式 Global Curve:全局曲线调整 UV Tune & UVS:UV通道调整和UV抑制 统计和分析模块: AF Statistics:自动对焦统计数据 AE Short/Long Statistics:自动曝光短/长时间统计数据 Raw Statistics:原始图像统计数据...

1 min