The NVIDIA camera software architecture includes NVIDIA components that allow for ease of development and customization:
The camera architecture includes the following NVIDIA components:
•libargus—Provides a low-level API based on the camera core stack.
•nvarguscamerasrc—NVIDIA camera GStreamer plugin that provides options to control ISP properties using the ARGUS API.
•v4l2src—A standard Linux V4L2 application that uses direct kernel IOCTL calls to access V4L2 functionality.
向上管理V4L2设备,向应用暴露控制接口
//include/media/v4l2-dev.h 对上: 管理v4l2设备,向应用暴露控制接口
// 定义视频设备对象: 创建 /dev/video0, 把操作暴露给应用层,管理v4l2设备
struct video_device
{
const struct v4l2_file_operations *fops; //v4l2设备的文件操作
struct cdev *cdev; //继承于 字符设备
struct v4l2_device *v4l2_dev;
struct vb2_queue *queue; //videobuf2 的队列 -> 构建环形缓冲区(无锁化)
const struct v4l2_ioctl_ops *ioctl_ops; //v4l2的ioctl操作集
};
//v4l2设备的文件操作(暴露给应用层)
struct v4l2_file_operations {
struct module *owner;
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
unsigned int (*poll) (struct file *, struct poll_table_struct *);
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
unsigned long (*get_unmapped_area) (struct file *, unsigned long,
unsigned long, unsigned long, unsigned long);
int (*mmap) (struct file *, struct vm_area_struct *);
int (*open) (struct file *);
int (*release) (struct file *);
};
//include/media/v4l2-ioctl.h
struct v4l2_ioctl_ops {
/* ioctl callbacks */
//查询驱动能力的回调函数, 对应V4L2 应用的API ioctl(fd, VIDIOC_QUERYCAP, &capability);
/* VIDIOC_QUERYCAP handler */
int (*vidioc_querycap)(struct file *file, void *fh,
struct v4l2_capability *cap);
....
}
管理所有V4L2子设备(以链表方式)
//include/media/v4l2-device.h
struct v4l2_device { //定义对象 v4l2设备: 是v4l2子设备的组合
struct device *dev;
struct list_head subdevs;
spinlock_t lock;
char name[V4L2_DEVICE_NAME_SIZE];
void (*notify)(struct v4l2_subdev *sd,
unsigned int notification, void *arg);
struct v4l2_ctrl_handler *ctrl_handler;
};
对下:被驱动继承 实现具体内容
//include/media/v4l2-subdev.h 对下: 被驱动继承 实现具体内容
//定义对象 v4l2子设备
struct v4l2_subdev {
struct list_head list;
struct v4l2_device *v4l2_dev; //关联 v4l2设备
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];
struct video_device *devnode; //关联 video设备
struct device *dev;
};
//V4L2 子设备操作集
struct v4l2_subdev_ops {
const struct v4l2_subdev_core_ops *core; //核心操作
const struct v4l2_subdev_tuner_ops *tuner; //无线电模式下操作
const struct v4l2_subdev_audio_ops *audio; //音频操作
const struct v4l2_subdev_video_ops *video; //视频操作
const struct v4l2_subdev_vbi_ops *vbi;
const struct v4l2_subdev_ir_ops *ir;
const struct v4l2_subdev_sensor_ops *sensor;
const struct v4l2_subdev_pad_ops *pad;
};
//drivers/media/usb/uvc/uvc_v4l2.c USB Video Class driver USB摄像头 通用 v4l2 API
static int uvc_ioctl_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
{
struct uvc_fh *handle = fh;
struct uvc_streaming *stream = handle->stream;
if (!uvc_has_privileges(handle))
return -EBUSY;
return uvc_dequeue_buffer(&stream->queue, buf,
file->f_flags & O_NONBLOCK);
}
const struct v4l2_ioctl_ops uvc_ioctl_ops = { //应用层 ioctl(fd, VIDIOC_QUERYCAP, &cap) 时会回调它
.vidioc_querycap = uvc_ioctl_querycap,
.vidioc_reqbufs = uvc_ioctl_reqbufs,
.vidioc_querybuf = uvc_ioctl_querybuf,
.vidioc_qbuf = uvc_ioctl_qbuf,
.vidioc_dqbuf = uvc_ioctl_dqbuf,
.vidioc_streamon = uvc_ioctl_streamon,
};
const struct v4l2_file_operations uvc_fops = { //被驱动uvc_driver.c关联
.open = uvc_v4l2_open, //应用层 open("/dev/video0", O_RDWR, 0); 时会回调它
.release = uvc_v4l2_release,
.unlocked_ioctl = video_ioctl2,
.read = uvc_v4l2_read,
.mmap = uvc_v4l2_mmap,
.poll = uvc_v4l2_poll,
};