7.8. Intel Image Processing Unit 3 (IPU3) Imaging Unit (ImgU) 驱动

版权所有 © 2018 Intel Corporation

7.8.1. 简介

本文档介绍了位于 drivers/media/pci/intel/ipu3 (CIO2) 以及 drivers/staging/media/ipu3 (ImgU) 下的 Intel IPU3(第三代图像处理单元)成像单元驱动程序。

在某些 Kaby Lake(以及某些 Sky Lake)平台(U/Y 处理器系列)中发现的 Intel IPU3 由两部分组成,即成像单元 (ImgU) 和 CIO2 设备(MIPI CSI2 接收器)。

CIO2 设备从传感器接收原始 Bayer 数据,并以 IPU3 特定的格式输出帧(供 IPU3 ImgU 使用)。 CIO2 驱动程序位于 drivers/media/pci/intel/ipu3/ipu3-cio2* 中,并通过 CONFIG_VIDEO_IPU3_CIO2 配置选项启用。

成像单元 (ImgU) 负责处理由 IPU3 CIO2 设备捕获的图像。 ImgU 驱动程序的源代码可以在 drivers/staging/media/ipu3 目录下找到。 该驱动程序通过 CONFIG_VIDEO_IPU3_IMGU 配置选项启用。

这两个驱动模块分别命名为 ipu3_csi2 和 ipu3_imgu。

该驱动程序已在 Kaby Lake 平台(U/Y 处理器系列)上进行了测试。

这两个驱动程序都实现了 V4L2、媒体控制器和 V4L2 子设备接口。 IPU3 CIO2 驱动程序通过 V4L2 子设备传感器驱动程序支持连接到 CIO2 MIPI CSI-2 接口的摄像头传感器。

7.8.2. CIO2

CIO2 表示为单个 V4L2 子设备,它为用户空间提供 V4L2 子设备接口。 每个 CSI-2 接收器都有一个视频节点,整个设备只有一个媒体控制器接口。

CIO2 包含四个独立的捕获通道,每个通道都有自己的 MIPI CSI-2 接收器和 DMA 引擎。 每个通道都被建模为一个 V4L2 子设备,作为 V4L2 子设备节点暴露给用户空间,并有两个 pad

Pad

方向

目的

0

sink

MIPI CSI-2 输入,连接到传感器子设备

1

source

原始视频捕获,连接到 V4L2 视频接口

V4L2 视频接口对 DMA 引擎进行建模。 它们作为 V4L2 视频设备节点暴露给用户空间。

7.8.2.1. 以原始 Bayer 格式捕获帧

CIO2 MIPI CSI2 接收器用于从连接到 CSI2 端口的原始传感器捕获帧(以压缩原始 Bayer 格式)。 捕获的帧用作 ImgU 驱动程序的输入。

由于 IPU3 的以下独特要求和/或功能,使用 IPU3 ImgU 进行图像处理需要 raw2pnm [1] 和 yavta [2] 等工具。

-- IPU3 CSI2 接收器以 IPU3 特定的压缩原始 Bayer 格式输出从传感器捕获的帧。

-- 必须同时运行多个视频节点。

让我们以连接到 CSI2 端口 0 的 ov5670 传感器为例,进行 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
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")

使用上述命令,以 2592x1944 分辨率捕获 10 帧,格式为 sGRBG10,并输出为 IPU3_SGRBG10 格式。

捕获的帧可用作 /tmp/frame-#.bin 文件。

7.8.3. ImgU

ImgU 表示为两个 V4L2 子设备,每个子设备都为用户空间提供 V4L2 子设备接口。

每个 V4L2 子设备表示一个管道,最多可以支持 2 个流。 这有助于支持高级摄像头功能,例如连续取景器 (CVF) 和视频期间快照 (SDV)。

ImgU 包含两个独立的管道,每个管道都被建模为一个 V4L2 子设备,作为 V4L2 子设备节点暴露给用户空间。

每个管道都有两个 sink pad 和三个 source pad,用于以下目的

Pad

方向

目的

0

sink

输入原始视频流

1

sink

处理参数

2

source

输出处理后的视频流

3

source

输出取景器视频流

4

source

3A 统计

每个 pad 都连接到相应的 V4L2 视频接口,作为 V4L2 视频设备节点暴露给用户空间。

7.8.3.1. 设备操作

使用 ImgU,一旦输入视频节点(“ipu3-imgu 0/1”:0,格式为 <entity>:<pad-number>)排队包含缓冲区(以压缩原始 Bayer 格式),ImgU 就会开始处理缓冲区,并在相应的输出节点上生成 YUV 格式的视频输出和统计信息输出。 当输入视频节点排队包含缓冲区时,驱动程序应准备好所有参数、输出和统计信息节点的缓冲区。

至少应启用所有输入、主输出、3A 统计信息和取景器视频节点,IPU3 才能开始图像处理。

每个 ImgU V4L2 子设备都具有以下一组视频节点。

7.8.3.2. 输入、输出和取景器视频节点

由输入视频节点接收的帧(以 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 视频捕获接口,如 接口 中所定义。

仅支持多平面 API。 更多详细信息可以在 单平面和多平面 API 中找到。

7.8.3.3. 参数视频节点

参数视频节点接收 ImgU 算法参数,这些参数用于配置 ImgU 算法如何处理图像。

有关 IPU3 特定的处理参数的详细信息,请参见 V4L2_META_FMT_IPU3_PARAMS ('ip3p')、V4L2_META_FMT_IPU3_3A ('ip3s')

7.8.3.4. 3A 统计视频节点

ImgU 驱动程序使用 3A 统计视频节点将 ImgU 正在处理的帧的 3A(自动对焦、自动曝光和自动白平衡)统计信息输出到用户空间应用程序。 用户空间应用程序可以使用此统计数据来计算 ImgU 的所需算法参数。

7.8.4. 配置 Intel IPU3

可以使用媒体控制器配置 IPU3 ImgU 管道,媒体控制器在 第四部分 - 媒体控制器 API 中定义。

7.8.4.1. 运行模式和固件二进制文件选择

ImgU 基于固件工作,目前 ImgU 固件支持使用单个输入帧数据分时运行 2 个管道。 每个管道都可以在特定模式下运行 - “VIDEO” 或 “STILL”,“VIDEO” 模式通常用于视频帧捕获,而 “STILL” 用于静止帧捕获。 但是,如果您想以更少的系统负载和功耗捕获图像,您也可以选择 “VIDEO” 来捕获静止帧。 对于 “STILL” 模式,ImgU 将尝试使用较小的 BDS 因子,并输出比 “VIDEO” 模式更大的 Bayer 帧,以便进一步进行 YUV 处理,从而获得高质量的图像。 此外,“STILL” 模式需要 XNR3 来进行降噪,因此 “STILL” 模式将比 “VIDEO” 模式需要更多的功耗和内存带宽。“VIDEO” 模式将启用 TNR,而 “STILL” 模式将绕过 TNR。 默认情况下,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”。

7.8.4.2. 以原始 Bayer 格式处理图像

7.8.4.2.1. 配置 ImgU V4L2 子设备以进行图像处理

必须使用媒体控制器 API 配置 ImgU V4L2 子设备,以使所有视频节点都正确设置。

让我们以 “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]

此外,应通过控制 ID 0x009819a1 将相应 V4L2 子设备的管道模式设置为所需的模式(例如,视频模式为 0,静止模式为 1),如下所示。

yavta -w "0x009819A1 1" /dev/v4l-subdev7

ImgU 管道中的某些硬件块可以通过裁剪或缩放来更改帧分辨率,这些硬件块包括输入馈送器 (IF)、Bayer 降采样器 (BDS) 和几何失真校正 (GDC)。 还有一个可以更改帧分辨率的块 - YUV 缩放器,它仅适用于辅助输出。

RAW Bayer 帧将通过这些 ImgU 管道硬件块,最终处理的图像将输出到 DDR 内存。

ipu3 resolution blocks image

IPU3 分辨率更改硬件块

输入馈送器

输入馈送器从传感器获取 Bayer 帧数据,它可以启用从帧中裁剪行和列,然后将像素存储到设备的内部像素缓冲区中,这些像素缓冲区已准备好被后续块读取。

Bayer 降采样器

Bayer 降采样器能够在 Bayer 域中执行图像缩放,可以在每个轴上将降采样因子配置为从 1X 到 1/4X,配置步长为 0.03125 (1/32)。

几何失真校正

几何失真校正用于执行失真校正和图像滤波。 它需要一些额外的滤波器和包络填充像素才能工作,因此 GDC 的输入分辨率应大于输出分辨率。

YUV 缩放器

YUV 缩放器与 BDS 类似,但它主要在 YUV 域中进行图像降采样,它可以支持高达 1/12X 的降采样,但它不能应用于主输出。

必须为给定的输入分辨率,使用所有上述硬件块中支持的分辨率来配置 ImgU V4L2 子设备。 对于输入帧的给定支持分辨率,应使用支持的分辨率来配置输入馈送器、Bayer 降采样器和 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。

完成此操作后,可以使用开源应用程序 v4l2n [1] 将收到的原始 Bayer 帧输入到 ImgU V4L2 子设备中,如下所示。

对于以 2592x1944 [3] 分辨率捕获的图像,所需的输出分辨率为 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

您还可以使用 yavta [2] 命令来执行与上述相同的操作

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 统计信息视频节点。

7.8.4.3. 将原始 Bayer 图像转换为 YUV 域

经过上述步骤处理后的图像可以如下所示转换为 YUV 域。

7.8.4.3.1. 主输出帧

raw2pnm -x2560 -y1920 -fNV12 /tmp/frames.out /tmp/frames.out.ppm

其中 2560x1920 是输出分辨率,NV12 是视频格式,后跟输入帧和输出 PNM 文件。

7.8.4.3.2. 取景器输出帧

raw2pnm -x2560 -y1920 -fNV12 /tmp/frames.vf /tmp/frames.vf.ppm

其中 2560x1920 是输出分辨率,NV12 是视频格式,后跟输入帧和输出 PNM 文件。

7.8.5. IPU3 的用户空间代码示例

配置和使用 IPU3 的用户空间代码可在此处获得。

https://chromium.googlesource.com/chromiumos/platform/arc-camera/+/master/

源代码可以位于 hal/intel 目录下。

7.8.6. IPU3 管道概述

IPU3 管道有许多图像处理阶段,每个阶段都将一组参数作为输入。 管道的主要阶段如下所示

IPU3 ImgU Pipeline

IPU3 ImgU 管道图

下表介绍了上述算法。

名称

描述

光黑校正

光黑校正块从各个像素值中减去一个预定义的值,以获得更好的图像质量。 在 struct ipu3_uapi_obgrid_param 中定义。

线性化

此算法块使用线性化参数来解决非线性传感器效应。 查找表在 struct ipu3_uapi_isp_lin_vmem_params 中定义。

SHD

镜头阴影校正用于校正由于光学校正引起的像素响应的空间非均匀性。 这是通过为每个像素应用不同的增益来完成的。 增益、黑电平等在 struct ipu3_uapi_shd_config_static 中配置。

BNR

Bayer 噪声降低块通过应用双边滤波器来消除图像噪声。 有关详细信息,请参见 struct ipu3_uapi_bnr_static_config

ANR

高级噪声降低是一种基于块的算法,可在 Bayer 域中执行噪声降低。 卷积矩阵等可以在 struct ipu3_uapi_anr_config 中找到。

DM

去马赛克将 Bayer 格式的原始传感器数据转换为 RGB(红色、绿色、蓝色)表示。 然后添加 Y 通道估计的输出,以便固件进行后续流处理。 该结构定义为 struct ipu3_uapi_dm_config

颜色校正

颜色校正算法将传感器特定的颜色空间转换为标准 “sRGB” 颜色空间。 这是通过应用 struct ipu3_uapi_ccm_mat_config 中定义的 3x3 矩阵来完成的。

伽玛校正

伽玛校正 struct ipu3_uapi_gamma_config 是一种基本的非线性色调映射校正,它为每个像素组件逐像素应用。

CSC

颜色空间转换将每个像素从 RGB 主要表示转换为 YUV(Y:亮度,UV:亮度)表示。 这是通过应用 struct ipu3_uapi_csc_mat_config 中定义的 3x3 矩阵来完成的。

CDS

色度下采样 在执行CSC后,对于YUV 4:2:0,色度下采样通过一个4x2可配置滤波器对UV平面进行2倍的下采样,使用 struct ipu3_uapi_cds_params

CHNR

色度噪声降低 此模块仅处理色度像素,并通过清除高频噪声来执行降噪。请参阅 struct struct ipu3_uapi_yuvp1_chnr_config。

TCC

总颜色校正,如 struct struct ipu3_uapi_yuvp2_tcc_static_config 中定义。

XNR3

eXtreme Noise Reduction V3 (极限降噪V3)是用于提高图像质量的降噪算法的第三个版本。它可以消除捕获图像中的低频噪声。定义了两个相关的结构体,struct ipu3_uapi_isp_xnr3_params 用于ISP数据内存,以及 struct ipu3_uapi_isp_xnr3_vmem_params 用于向量内存。

TNR

时域噪声降低块比较时间上连续的帧,以消除像素值中的异常/噪声。struct ipu3_uapi_isp_tnr3_vmem_paramsstruct ipu3_uapi_isp_tnr3_params 分别为 ISP 向量和数据内存定义。

上面表格中未列出的其他常见首字母缩写词

ACC

加速器集群

AWB_FR

自动白平衡滤波器响应统计信息

BDS

拜耳降采样器参数

CCM

颜色校正矩阵系数

IEFd

图像增强滤波器定向

Obgrid

光学黑电平补偿

OSYS

输出系统配置

ROI

感兴趣区域

YDS

Y 向下采样

YTM

Y-色调映射

流水线的一些阶段将由在ISP处理器上运行的固件执行,而许多其他阶段将使用一组固定的硬件块(也称为加速器集群(ACC))来处理像素数据并生成统计信息。

struct ipu3_uapi_acc_param 定义的各个算法的ACC参数,可以通过嵌入在 struct ipu3_uapi_params 结构体中的 struct struct ipu3_uapi_flags,由用户空间选择应用。对于配置为不被用户空间启用的参数,驱动程序将忽略相应的结构体,在这种情况下,将保留算法的现有配置。

7.8.7. 参考