daa 8能识别 video
root@OK8MP:/sys/devices/platform/vvcam-video.0/media1# media-ctl --device /dev/media1 --print-topology Media controller API version 5.4.70 Media device information ------------------------ driver vvcam-video model viv_media0 serial bus info hw revision 0x0 driver version 5.4.70 Device topology - entity 1: viv_v4l20 (1 pad, 1 link) type Node subtype V4L flags 0 device node name /dev/video1 pad0: Sink <- "vvcam-dwe.0":0 [ENABLED] - entity 5: vvcam-isp.0 (1 pad, 1 link) type Node subtype V4L flags 0 device node name /dev/v4l-subdev4 pad0: Source -> "vvcam-dwe.0":1 [ENABLED] - entity 7: vvcam-dwe.0 (2 pads, 2 links) type Node subtype V4L flags 0 device node name /dev/v4l-subdev5 pad0: Source -> "viv_v4l20":0 [ENABLED] pad1: Sink <- "vvcam-isp.0":0 [ENABLED]
root@OK8MP:~# media-ctl --device /dev/media1 --print-topology Media controller API version 5.4.70 Media device information ------------------------ driver vvcam-video model viv_media0 serial bus info hw revision 0x0 driver version 5.4.70 Device topology - entity 1: viv_v4l20 (1 pad, 1 link) type Node subtype V4L flags 0 device node name /dev/video0 pad0: Sink <- "vvcam-isp.0":0 [ENABLED] - entity 5: vvcam-dwe.0 (2 pads, 0 link) type Node subtype V4L flags 0 device node name /dev/v4l-subdev3 pad0: Source pad1: Sink - entity 8: vvcam-isp.0 (1 pad, 1 link) type Node subtype V4L flags 0 device node name /dev/v4l-subdev4 pad0: Source -> "viv_v4l20":0 [ENABLED]
root@OK8MP:/sys/devices/platform/vvcam-video.0# cat /sys/class/video4linux/v4l-subdev5/name vvcam-dwe.0 root@OK8MP:/sys/devices/platform/vvcam-video.0# cat /sys/class/video4linux/v4l-subdev4/name vvcam-isp.0
extra/vvcam/v4l2/video/video.c 实现各个entity的link
为什么 默认支持的工业摄像头能建立isp ->dwe->video de pipeline,imx577 驱动只能建立isp ->video
v4l2 -ctl --list-formats-ext -d /dev/video 不能显示摄像头参数,原因如下
isp的link建立是 默认操作,
extra/vvcam/v4l2/video/video.c static int viv_create_default_links(struct viv_video_device *dev) { struct media_entity *source, *sink; source = viv_find_entity(dev, ISP_DEVICE_NAME); sink = &dev->video->entity; return viv_create_link(source, ISP_PAD_SOURCE, sink, 0); } 建立默认的连接vvcam-isp.0 -> "viv_v4l20":0
extra/vvcam/v4l2/video/video.c static int viv_notifier_complete(struct v4l2_async_notifier *notifier) { struct viv_video_device *dev = container_of(notifier, struct viv_video_device, subdev_notifier); int rc; if (!dev) return 0; if (dev->sdcount > 0) { mutex_lock(&dev->mdev.graph_mutex); rc = viv_create_default_links(dev); mutex_unlock(&dev->mdev.graph_mutex); if (rc) { pr_err("failed to create media links!\n"); return rc; } } rc = v4l2_device_register_subdev_nodes(dev->v4l2_dev); if (!rc) rc = media_device_register(&dev->mdev); return rc; } static const struct v4l2_async_notifier_operations sd_async_notifier_ops = { .bound = viv_notifier_bound, .complete = viv_notifier_complete, };
dwe 的连接的建立,viv_config_dwe 是在 video_ioctl_ops->private_ioctl 调用 ,应用的isp 操作才会代用,使用imx577 可能没有调用
extra/vvcam/v4l2/video/video.c vdev->video->ioctl_ops = &video_ioctl_ops; static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_querycap = video_querycap, .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, .vidioc_reqbufs = vidioc_reqbufs, .vidioc_querybuf = vidioc_querybuf, .vidioc_qbuf = vidioc_qbuf, .vidioc_expbuf = vidioc_expbuf, .vidioc_dqbuf = vidioc_dqbuf, .vidioc_streamon = vidioc_streamon, .vidioc_streamoff = vidioc_streamoff, .vidioc_subscribe_event = subscribe_event, .vidioc_unsubscribe_event = unsubscribe_event, .vidioc_default = private_ioctl, .vidioc_enum_input = vidioc_enum_input, .vidioc_g_input = vidioc_g_input, .vidioc_s_input = vidioc_s_input, .vidioc_enum_framesizes = vidioc_enum_framesizes, .vidioc_enum_frameintervals = vidioc_enum_frameintervals, .vidioc_g_parm = vidioc_g_parm, .vidioc_s_parm = vidioc_s_parm, .vidioc_g_pixelaspect = vidioc_g_pixelaspect, .vidioc_g_selection = vidioc_g_selection, .vidioc_s_selection = vidioc_s_selection, };
static long private_ioctl(struct file *file, void *fh, bool valid_prio, unsigned int cmd, void *arg) case VIV_VIDIOC_S_DWECFG: viv_config_dwe(handle, !!*((int *)arg)); break; }