V4l2架构之主要结构体

V4l2是Linux用来处理视频的一个子框架。

先来看下v4l2 子框架的几个重要级别的结构体:
  • struct v4l2_device: 一个摄像头硬件设备可能包含多个子设备,而 v4l2_device 则是所有设备的根,负责管理所有设备, 这个结构体可以看做是所有设备和子设备的基类。

struct v4l2_device {
    struct device *dev;  // V4l2的父 struct device
    struct media_device *mdev; // 指向 V4l2 设备所属的 media_device 对象,主要处理媒体控制框架
    struct list_head subdevs;  // 子设备列表
    spinlock_t lock;  // 锁
    char name[V4L2_DEVICE_NAME_SIZE];  // 这个 V4l2 设备的唯一名称, 
    void (*notify)(struct v4l2_subdev *sd, 
            unsigned int notification, void *arg); // 由子设备调用以向此 V4L2 设备通知某些事件 
    struct v4l2_ctrl_handler *ctrl_handler; // 关联的控件处理程序,可以用来跟踪此V4l2 设备具有的所有控件,不需要则设置为NULL。
    struct v4l2_prio_state prio;  // 设备的优先级状态
    struct kref ref;  // 核心内部用于引用(reference) 计数
    void (*release)(struct v4l2_device *v4l2_dev); // 改结构体的最后一个用户关闭时要调用的回调函数
};

==》 dev 参数通常是桥接总线相关设备数据结构的结构体: pci_dev 、 usb_device 或 platform_device。
==》 如果 dev->driver_data 字段为NULL,则此函数将使其指定正在注册的实际 V4l2_dev对象。如果V4l2->name 为空,那么将由 dev driver name + dev device name 连接产生的值。
=》 如果 dev 参数为NULL, 则必须在调用 v4l2_device_register() 之前设置 v4l2_dev ->name。
  • struct video_device: 这个结构体的主要目的就是提供众所周知的 /dev/videoX 和 /dev/v4l_subdevX 的设备节点。-- 桥接驱动程序结构体

struct video_device
{
#if defined(CONFIG_MEDIA_CONTROLLER)  // entity、 intf_node 和 pipe 是媒体框架集成的一部分。
    struct media_entity entity;   // entity 可从媒体框架内部抽象出视频设备(成为一个实体)
    struct media_intf_devnode *intf_devnode; // intf_node 代表媒体接口设备节点
    struct media_pipeline pipe; // pipe 则代表实体所属的流管道
#endif
    const struct v4l2_file_operations *fops;  // 代表视频设备文件节点的文件操作。V4L2 核心可使用子系统所需要的一些额外逻辑来覆盖虚拟设备文件操作。

    u32 device_caps; // v4l2_capabilities 中使用的设备功能

    /* sysfs */
    struct device dev; // 
    struct cdev *cdev; // 字符设备结构体,抽象了底层/dev/videoX 文件节点

    struct v4l2_device *v4l2_dev; // 内嵌的v4l2_device 结构体
    struct device *dev_parent;  // 该设备的父设备,未设置使用 Vdev->v4l2_dev->dev

    struct v4l2_ctrl_handler *ctrl_handler; // 默认值 vdev->v4l2_dev->ctrl_handler

    struct vb2_queue *queue;  // 与此设备节点关联的缓冲区管理队列,但可能是NULL, 尤其是子设备驱动程序

    struct v4l2_prio_state *prio; // 指向设备优先级状态,设为NULL, 则继承 V4l2_dev->prio

    /* device info */
    char name[32];   // 视频设备名称
    enum vfl_devnode_type vfl_type; // V4L 设备的类型
/*
 enum vfl_devnode_type {
    VFL_TYPE_GRABBER    = 0,  // 用于视频输入、输出设备
    VFL_TYPE_VBI,             // 用于垂直空白间隙(VBI)数据(未解码)
    VFL_TYPE_RADIO,           // 无线电卡
    VFL_TYPE_SUBDEV,          // V4l2 子设备
    VFL_TYPE_SDR,             // 软件定义无线电
    VFL_TYPE_TOUCH,           // 触摸传感器
    VFL_TYPE_MAX /* Shall be the last one */
};
*/
    enum vfl_devnode_direction vfl_dir;  // V4l 接收器、发送器或者内存到内存(m2m / mem2mem)
/*
enum vfl_devnode_direction {
    VFL_DIR_RX,            // 用于采集设备
    VFL_DIR_TX,            // 输出设备
    VFL_DIR_M2M,           // 内存到内存
};
*/
    int minor;            // 设备节点“minor”。如果注册失败,则设置为-1
    u16 num;              // 核心分配的实际设备节点索引,对应得是/dev/videoX 中的 X
    unsigned long flags;  // 视频设备标志, 通常使用位操作设置、清除、测试标志,用的是
/*
enum v4l2_video_device_flags {
    V4L2_FL_REGISTERED    = 0,  // 表示设备处于测试状态,无法正常使用
    V4L2_FL_USES_V4L2_FH    = 1, // 表示设备已经就绪,可以正常使用
};
*/
    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);  // 设备的最后一个用户退出是调用,不能为NULL··
    const struct v4l2_ioctl_ops *ioctl_ops;  // 定义一组输入输出控件(iotcl)回调函数
    DECLARE_BITMAP(valid_ioctls, BASE_VIDIOC_PRIVATE);

    struct mutex *lock;
};
  • struct vb2_queue : 视频驱动程序中的主要数据结构体,与 struct vb2_v4l_buffer 一起作用于数据流的实际逻辑和 DMA 操作的中心部分。

struct vb2_queue {
    unsigned int            type;8
    unsigned int            io_modes;
    struct device            *dev;
    unsigned long            dma_attrs;
    unsigned            bidirectional:1;
    unsigned            fileio_read_once:1;
    unsigned            fileio_write_immediately:1;
    unsigned            allow_zero_bytesused:1;
    unsigned           quirk_poll_must_check_waiting_for_buffers: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;
    unsigned int            buf_struct_size;
    u32                timestamp_flags;
    gfp_t                gfp_flags;
    u32                min_buffers_needed;

    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[VB2_MAX_FRAME];
    unsigned int            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            is_multiplanar:1;
    unsigned int            is_output:1;
    unsigned int            copy_timestamp:1;
    unsigned int            last_buffer_dequeued:1;

    struct vb2_fileio_data        *fileio;
    struct vb2_threadio_data    *threadio;

#ifdef CONFIG_VIDEO_ADV_DEBUG
    /*
     * Counters for how often these queue-related ops are
     * called. Used to check for unbalanced ops.
     */
    u32                cnt_queue_setup;
    u32                cnt_wait_prepare;
    u32                cnt_wait_finish;
    u32                cnt_start_streaming;
    u32                cnt_stop_streaming;
#endif
};
  • struct v4l2_subdev : 这是负责SOC 的视频系统中实现特定功能和抽象特定功能的子设备(ISP、3A 等)。

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[V4L2_SUBDEV_NAME_SIZE];
    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 v4l2_async_subdev *asd;
    struct v4l2_async_notifier *notifier;
    struct v4l2_async_notifier *subdev_notifier;
    struct v4l2_subdev_platform_data *pdata;
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值