Introduction
本文件记录了位于drivers/media/pci/intel/ipu3(CIO2)以及drivers/staging/media/ipu3(ImgU)下的Intel IPU3(第3代图像处理单元)Imaging Unit驱动程序。在某些Kaby Lake平台(以及某些Sky Lake平台)中发现的Intel IPU3由两个部分组成,即Imaging Unit(ImgU)和CIO2设备(MIPI CSI2接收器)。
CIO2设备从传感器接收原始Bayer数据,并以特定于IPU3的格式输出帧(供IPU3 ImgU使用)。CIO2驱动程序可在drivers/media/pci/intel/ipu3/ipu3-cio2*中找到,并通过CONFIG_VIDEO_IPU3_CIO2配置选项启用。Imaging Unit(ImgU)负责处理IPU3 CIO2设备捕获的图像。ImgU驱动程序源代码可以在drivers/staging/media/ipu3目录下找到。通过CONFIG_VIDEO_IPU3_IMGU配置选项启用该驱动程序。两个驱动程序模块分别命名为ipu3_csi2和ipu3_imgu。这两个驱动程序都实现了V4L2、Media Controller和V4L2子设备接口。IPU3 CIO2驱动程序支持通过V4L2子设备传感器驱动程序连接到CIO2 MIPI CSI-2接口的相机传感器。这些驱动程序已在Kaby Lake平台(U/Y处理器系列)上进行了测试。
CIO2
CIO2被表示为单个V4L2子设备,提供V4L2子设备接口给用户空间。每个CSI-2接收器都有一个视频节点,整个设备只有一个媒体控制器接口。CIO2包含四个独立的捕获通道,每个通道都有自己的MIPI CSI-2接收器和DMA引擎。每个通道被建模为V4L2子设备,在用户空间作为V4L2子设备节点公开,并有两个插孔:发送端(source)和接收端(sink)。为了方便使用,CIO2驱动程序还包括一些额外的功能,如自动曝光控制、自动白平衡控制等等。这些功能可以通过V4L2控制接口进行配置。此外,CIO2驱动程序还支持视频捕获调试框架,以帮助开发人员进行问题诊断和调试。
V4L2视频接口模型化DMA引擎,并将其作为V4L2视频设备节点公开给用户空间。
Capturing frames in raw Bayer format
CIO2的MIPI CSI2接收器用于从连接到CSI2端口的原始传感器中捕获帧(以打包的原始Bayer格式)。捕获的帧被用作ImgU驱动程序的输入。使用IPU3 ImgU进行图像处理需要使用像raw2pnm2和yavta3这样的工具,因为它们具有以下特定于IPU3的独特要求和/或功能。
- IPU3 CSI2接收器以特定于IPU3的打包原始Bayer格式输出从传感器捕获的帧。
- 必须同时操作多个视频节点。
我们以ov5670传感器连接到CSI2端口0并进行2592x1944图像捕获为例。
使用媒体控制器API,ov5670传感器被配置为以打包的原始Bayer格式发送帧到IPU3 CSI2接收器。
# This example assumes /dev/media0 as the CIO2 media device
export MDEV=/dev/media0
# and that ov5670 sensor is connected to i2c bus 10 with address 0x36
export SDEV=$(media-ctl -d $MDEV -e "ov5670 10-0036")
# Establish the link for the media devices using media-ctl [#f3]_
media-ctl -d $MDEV -l "ov5670:0 -> ipu3-csi2 0:0[1]"
# Set the format for the media devices
media-ctl -d $MDEV -V "ov5670:0 [fmt:SGRBG10/2592x1944]"
media-ctl -d $MDEV -V "ipu3-csi2 0:0 [fmt:SGRBG10/2592x1944]"
media-ctl -d $MDEV -V "ipu3-csi2 0:1 [fmt:SGRBG10/2592x1944]"
一旦媒体管道被配置,就可以使用yavta工具设置所需的传感器特定设置(例如曝光和增益设置)。
yavta -w 0x009e0903 444 $SDEV
yavta -w 0x009e0913 1024 $SDEV
yavta -w 0x009e0911 2046 $SDEV
一旦设置了所需的传感器设置,可以按照以下步骤进行帧捕获。
yavta --data-prefix -u -c10 -n5 -I -s2592x1944 --file=/tmp/frame-#.bin \
-f IPU3_SGRBG10 $(media-ctl -d $MDEV -e "ipu3-cio2 0")
捕获的帧以/tmp/frame-#.bin文件的形式可用。
ImgU
ImgU被表示为两个V4L2子设备,每个子设备都提供了一个 V4L2 子设备接口给用户空间。
每个 V4L2 子设备都表示一个管道,最多可以支持 2 个流。这有助于支持高级相机功能,如连续查找器 (CVF) 和视频快照 (SDV)。
ImgU 包含两个独立的管道,每个管道都建模为一个 V4L2 子设备,作为一个 V4L2 子设备节点暴露给用户空间。
每个管道都有两个接收端口和三个发送端口,具体如下:
每个端口都连接到相应的 V4L2 视频接口,作为一个 V4L2 视频设备节点暴露给用户空间。
Device operation
使用ImgU时,一旦将输入视频节点(使用“ipu3-imgu 0/1”:0,以<entity>:<pad-number>格式)入队到缓冲区(以紧密打包的原始Bayer格式),ImgU就开始处理缓冲区并在相应的输出节点上生成视频输出和统计输出。当将输入视频节点入队到缓冲区时,驱动程序应准备好所有参数、输出和统计节点的缓冲区。
至少应该启用所有输入、主输出、3A统计和取景器视频节点,才能使IPU3开始图像处理。
每个ImgU V4L2子设备具有以下一组视频节点。
input, output and viewfifinder video nodes
输入视频节点接收到的帧(特定于IPU3的紧密打包的原始Bayer格式)由IPU3成像单元处理,并输出到2个视频节点,分别针对不同的目的(主要输出和取景器输出)。
有关IPU3特定的Bayer格式的详细信息,请参见V4L2_PIX_FMT_IPU3_SBGGR10(“ip3b”),V4L2_PIX_FMT_IPU3_SGBRG10(“ip3g”),V4L2_PIX_FMT_IPU3_SGRBG10(“ip3G”),V4L2_PIX_FMT_IPU3_SRGGB10(“ip3r”)。
驱动程序支持定义在V4L2视频捕获接口上的V4L2视频采集接口。只支持多平面API。更多细节请参阅单平面和多平面API。
Parameters video node
参数视频节点接收用于配置ImgU算法如何处理图像的ImgU算法参数。
有关特定于IPU3的处理参数的详细信息,请参见V4L2_META_FMT_IPU3_PARAMS(“ip3p”),V4L2_META_FMT_IPU3_3A(“ip3s”)。
3A statistics video node
3A统计视频节点由ImgU驱动程序用于输出正在由ImgU处理的帧的3A(自动对焦、自动曝光和自动白平衡)统计数据,以供用户空间应用程序使用。用户空间应用程序可以使用此统计数据计算所需的ImgU算法参数。
Configuring the Intel IPU3
可以使用媒体控制器(定义在第IV部分 - 媒体控制器API中)来配置IPU3 ImgU管道。
Running mode and fifirmware binary selection
ImgU基于固件工作,目前ImgU固件支持在单个输入帧数据的时间共享下运行2个管道。每个管道可以以“VIDEO”或“STILL”模式运行,“VIDEO”模式通常用于视频帧捕获,“STILL”用于静态帧捕获。但是,如果您想以较小的系统负载和功率捕获图像,则也可以选择“VIDEO”来捕获静态帧。对于“STILL”模式,ImgU将尝试使用较小的BDS因子并输出更大的Bayer帧以进行进一步的YUV处理,从而获得高质量的图像。此外,“STILL”模式需要XNR3进行降噪,因此“STILL”模式将需要比“VIDEO”模式更多的电源和内存带宽。TNR将在“VIDEO”模式下启用,并由“STILL”模式绕过。ImgU默认以“VIDEO”模式运行,用户可以使用v4l2控件V4L2_CID_INTEL_IPU3_MODE(当前定义为drivers/staging/media/ipu3/include/uapi/intel-ipu3.h)查询和设置运行模式。对于用户而言,“VIDEO”模式和“STILL”模式之间的缓冲队列没有区别,必须启用强制输入和主输出节点,并排队缓冲区,统计信息和取景器队列是可选的。
固件二进制文件将根据当前运行模式进行选择,如果启用了ImgU动态调试,则可以观察到如“using binary if_to_osys_striped”或“using binary if_to_osys_primary_striped”的日志,if_to_osys_striped二进制文件用于“VIDEO”,if_to_osys_primary_striped二进制文件用于“STILL”。
Processing the image in raw Bayer format
Confifiguring ImgU V4L2 subdev for image processing
ImgU V4L2子设备必须使用媒体控制器API进行配置,以使所有视频节点正确设置。让我们以“ipu3-imgu 0”子设备为例。
media-ctl -d $MDEV -r
media-ctl -d $MDEV -l "ipu3-imgu 0 input":0 -> "ipu3-imgu 0":0[1]
media-ctl -d $MDEV -l "ipu3-imgu 0":2 -> "ipu3-imgu 0 output":0[1]
media-ctl -d $MDEV -l "ipu3-imgu 0":3 -> "ipu3-imgu 0 viewfinder":0[1]
media-ctl -d $MDEV -l "ipu3-imgu 0":4 -> "ipu3-imgu 0 3a stat":0[1]
对应的V4L2子设备的管道模式也应按照所需设置(例如,0表示视频模式,1表示静态模式),可以通过控制ID 0x009819a1 设置,如下所示:
yavta -w "0x009819A1 1" /dev/v4l-subdev7
在ImgU流水线中,某些硬件块可以通过裁剪或缩放来改变帧的分辨率,这些硬件块包括输入饲送器(IF)、Bayer缩放器(BDS)和几何畸变校正器(GDC)。还有一个块可以改变帧的分辨率——YUV缩放器,只适用于二次输出。
原始Bayer帧经过这些ImgU流水线硬件块,并将最终处理的图像输出到DDR内存。
Fig. 3: IPU3 resolution change hardware blocks
sensor binning什么意思:
传感器Binning是指将多个相邻像素合并成一个像素的过程,其目的是为了提高图像质量和灵敏度。在传感器binning过程中,要么将几个像素值加权平均,要么将它们简单平均。通过将多个像素合并成一个像素,可以减少图像的噪声和提高图像的信噪比。但是,它也会减少图像的分辨率。传感器binning通常用于低光条件下的拍摄,以提高传感器的感光度。
Input Feeder
输入饲送器(Input Feeder)从传感器获取Bayer帧数据,可以从帧中启用行和列的裁剪,然后将像素存储到设备的内部像素缓冲区中,准备由后续块读取输出。
Bayer Down Scaler
Bayer缩放器(Bayer Down Scaler)能够在Bayer域中进行图像缩放,缩小因子可以在每个轴上配置为1X到1/4X,并且配置步骤为0.03125(1/32)。
Geometric Distortion Correction
几何畸变校正器(Geometric Distortion Correction)用于执行失真和图像滤波的校正。它需要一些额外的滤波器和包络填充像素才能正常工作,因此GDC的输入分辨率应大于输出分辨率。
YUV Scaler
YUV缩放器(YUV Scaler)与BDS类似,但主要在YUV域中进行图像缩放,最多支持1/12X的缩小比例,但不能应用于主输出。在给定的输入分辨率下,ImgU V4L2子设备必须配置所有上述硬件块的支持分辨率。针对给定输入帧的支持分辨率,应将输入饲送器、BDS和GDC块配置为支持的分辨率,因为每个硬件块都有自己的对齐要求。
您必须聪明地配置硬件块的输出分辨率,以满足硬件要求并保持最大的视场。中间分辨率可以通过特定工具生成 - https://github.com/intel/intel-ipu3-pipecfg
该工具可用于生成中间分辨率。可通过查看以下IPU3 ImgU配置表获取更多信息。https://chromium.googlesource.com/chromiumos/overlays/board-overlays/+/master,在baseboard-poppy/media-libs/cros-camera-hal-configs-poppy/files/gcss目录下,graph_settings_ov5670.xml可用作示例。
以下步骤为图像处理准备ImgU管道。
1. 应使用VIDIOC_SUBDEV_S_FMT在pad 0上设置ImgU V4L2子设备数据格式,使用上面获取的GDC宽度和高度。
2. 应使用VIDIOC_SUBDEV_S_SELECTION在pad 0上设置ImgU V4L2子设备裁剪,V4L2_SEL_TGT_CROP作为目标,用作输入饲料器高度和宽度。
3. 应使用VIDIOC_SUBDEV_S_SELECTION在pad 0上设置ImgU V4L2子设备组合,V4L2_SEL_TGT_COMPOSE作为目标,用作BDS高度和宽度。
对于ov5670示例,对于分辨率为2592x1944的输入帧(输入到ImgU子设备pad 0),输入饲料器、BDS和GDC的相应分辨率分别为2592x1944、2592x1944和2560x1920。
完成此操作后,可以将接收到的原始Bayer帧作为以下方式输入到ImgU V4L2子设备中,使用开源应用程序v4l2n。
对于以2592x1945分辨率捕获的图像,期望的输出分辨率为2560x1920,取景器分辨率为2560x1920,则可以使用以下v4l2n命令。这有助于处理原始Bayer帧,并以NV12格式生成主输出和取景器输出的所需结果。
v4l2n --pipe=4 --load=/tmp/frame-#.bin --open=/dev/video4
--fmt=type:VIDEO_OUTPUT_MPLANE,width=2592,height=1944,pixelformat=0X47337069 \
--reqbufs=type:VIDEO_OUTPUT_MPLANE,count:1 --pipe=1 \
--output=/tmp/frames.out --open=/dev/video5 \
--fmt=type:VIDEO_CAPTURE_MPLANE,width=2560,height=1920,pixelformat=NV12 \
--reqbufs=type:VIDEO_CAPTURE_MPLANE,count:1 --pipe=2 \
--output=/tmp/frames.vf --open=/dev/video6 \
--fmt=type:VIDEO_CAPTURE_MPLANE,width=2560,height=1920,pixelformat=NV12 \
--reqbufs=type:VIDEO_CAPTURE_MPLANE,count:1 --pipe=3 --open=/dev/video7 \
--output=/tmp/frames.3A --fmt=type:META_CAPTURE,? \
--reqbufs=count:1,type:META_CAPTURE --pipe=1,2,3,4 --stream=5
v4l2n网址没搜到
你也可以用yavta命令做同样的事情:
yavta --data-prefix -Bcapture-mplane -c10 -n5 -I -s2592x1944 \
--file=frame-#.out-f NV12 /dev/video5 & \
yavta --data-prefix -Bcapture-mplane -c10 -n5 -I -s2592x1944 \
--file=frame-#.vf -f NV12 /dev/video6 & \
yavta --data-prefix -Bmeta-capture -c10 -n5 -I \
--file=frame-#.3a /dev/video7 & \
yavta --data-prefix -Boutput-mplane -c10 -n5 -I -s2592x1944 \
--file=/tmp/frame-in.cio2 -f IPU3_SGRBG10 /dev/video4
其中,/dev/video4、/dev/video5、/dev/video6和/dev/video7这些设备分别指向输入、输出、取景器和3A统计视频节点。在此语境中,输入节点是用于捕获原始图像流的节点,输出节点是用于生成处理后的图像流的节点,取景器节点允许用户查看正在捕获的图像流。3A统计信息节点提供有关自动对焦(AF)、自动曝光(AE)和自动白平衡(AWB)算法的信息。通常,Linux系统中的V4L2设备驱动程序会使用/dev/videoX这样的设备节点。
yavta是什么,官网是?
yavta是一个用于捕获视频帧的命令行工具。它可以在Linux操作系统下使用,并且支持多种格式和类型的视频设备。
yavta官网为:https://github.com/fastr/yavta //这就是最好的v4l2应用程序
Converting the raw Bayer image into YUV domain
在上述步骤之后处理的图像,可以按以下方式转换为YUV域。
Main output frames
raw2pnm -x2560 -y1920 -fNV12 /tmp/frames.out /tmp/frames.out.ppm
raw2pnm是什么:
raw2pnm是一种用于将RAW格式图像转换为PNM格式图像的在线工具。PNM是Portable aNy Map的缩写,是一种无损的位图格式,可以存储灰度图像、伪彩色图像和真彩色图像。该工具可以方便地将RAW格式图像转换为PNM格式,从而使用户能够轻松地编辑和操纵它们。
其中,2560x1920表示输出的分辨率,NV12是视频格式,后跟输入帧和输出PNM文件。
Viewfinder output frames
raw2pnm -x2560 -y1920 -fNV12 /tmp/frames.vf /tmp/frames.vf.ppm
其中,2560x1920表示输出的分辨率,NV12是视频格式,后跟输入帧和输出PNM文件。
Example user space code for IPU3
配置和使用IPU3的用户空间代码可以在以下链接中找到:https://chromium.googlesource.com/chromiumos/platform/arc-camera/+/master/。该源代码可以在hal/intel目录下找到。
Overview of IPU3 pipeline
IPU3管道有多个图像处理阶段,每个阶段都需要一组参数作为输入。管道的主要阶段如下所示:
Fig. 4: IPU3 ImgU Pipeline Diagram
下表是对以上算法的描述:
上表未列出的其他常见缩写:
管道的一些阶段将由运行在ISP处理器上的固件执行,而其他许多阶段将使用一组称为加速器集群(ACC)的固定硬件块来处理像素数据并生成统计信息。由struct ipu3_uapi_acc_param定义的各个算法的ACC参数可以通过嵌入在struct ipu3_uapi_params结构中的struct ipu3_uapi_flags由用户空间选择应用。对于被配置为未启用的参数,驱动程序将忽略相应的结构体,此时算法的现有配置将被保留。