Linux 内核 Rockchip ISP1(rkisp1)图像信号处理器驱动详解:拓扑、版本与实战抓帧配置
【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux
本指南基于 Linux 内核源码树中的 Documentation/admin-guide/media/rkisp1.rst 编写,系统讲解 Rockchip ISP1(rkisp1)驱动的媒体控制器拓扑、ISP 硬件版本识别、四个视频节点与三个子设备节点的职责划分,并给出基于media-ctl/v4l2-ctl的完整抓帧命令行实战。读完本文,你将掌握 rkisp1 管线的实体连接关系、裁剪(crop)与缩放(resize)的传播规则、3A 统计/参数回环的使用方式,以及 YUV 全范围/限范围量化的配置方法。
驱动概览:面向 RK3288/RK3399 等 SoC 的 ISP1 驱动
rkisp1 是 Linux 内核中针对 Rockchip ISP1(Image Signal Processor)的 V4L2 驱动,该 ISP 集成于 RK3288、RK3399 等 SoC 中。驱动源码位于drivers/media/platform/rockchip/rkisp1/,目录下包含:
rkisp1-dev.c:设备注册、媒体实体与链接创建、电源与中断管理rkisp1-isp.c:ISP 主实体(sink/source pad 的格式与裁剪配置、CSI-2 协议配置)rkisp1-resizer.c:主路/自路缩放器子设备rkisp1-capture.c:mainpath/selfpath 捕获设备(DMA 引擎)及像素格式表rkisp1-stats.c/rkisp1-params.c:3A 统计输出节点与参数输入节点rkisp1-csi.c:MIPI CSI-2 接收器rkisp1-common.h:实体 pad 枚举与设备抽象
该驱动基于Media-Controller API实现,这意味着实体之间的连接、格式与裁剪需要通过media-ctl或应用程序调用媒体控制器 ioctl 显式配置,而不是像传统 V4L2 驱动那样自动串联。
ISP 硬件版本(Revisions)与识别方法
rkisp1 在后来的 SoC 中出现了多个小版本迭代。版本号定义在 UAPI 头文件 include/uapi/linux/rkisp1-config.h 的枚举rkisp1_cif_isp_version中:
| 版本枚举 | 实际值 | 已知应用平台 | 网格/直方图规模 |
|---|---|---|---|
RKISP1_V10 | 10 | 至少用于 rk3288、rk3399 | 5x5 网格、16 个直方图 bin |
RKISP1_V11 | 11 | 仅出现于原厂 vendor 代码,实际未使用 | 与 V10 相同 |
RKISP1_V12 | 12 | 至少用于 rk3326、px30 | 9x9 网格、32 个直方图 bin |
RKISP1_V13 | 13 | 至少用于 rk1808 | 与 V12 相同 |
RKISP1_V_IMX8MP | 14 | 至少用于 NXP i.MX8MP | 与 V10 相同 |
运行中 SoC 内 ISP 的具体版本,可以通过ioctl MEDIA_IOC_DEVICE_INFO返回的struct media_device_info的hw_revision字段读取。
硬件版本差异会直接影响 UAPI 结构体中数组的条目数,从源码结构看,这些差异通过成对的宏体现,例如:
RKISP1_CIF_ISP_AE_MEAN_MAX_V10(25)/_V12(81):自动曝光统计把图像划分为 5x5 或 9x9 块;RKISP1_CIF_ISP_HIST_BIN_N_MAX_V10(16)/_V12(32):直方图 bin 数量;RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE_V10(25)/_V12(81):直方图子窗口权重网格;RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10(17)/_V12(34):Gamma Out 曲线采样点数。
对应统计结构(如rkisp1_cif_isp_ae_stat的exp_mean、rkisp1_cif_isp_hist_stat的hist_bins)在 include/uapi/linux/rkisp1-config.h 中统一按最大值定义数组,具体有效条目数以hw_revision为准。因此,面向多平台开发的用户态 3A 库必须根据hw_revision动态确定数组长度。
媒体管线拓扑:4 个视频节点 + 3 个子设备节点
默认媒体管线拓扑图源文件见 Documentation/admin-guide/media/rkisp1.dot,其描述的实体与链接关系如下。
4 个视频(Video)设备
| 设备名 | 角色 | 说明 |
|---|---|---|
rkisp1_mainpath | 捕获设备 | 通常用于获取较高分辨率的图像 |
rkisp1_selfpath | 捕获设备 | 用于获取图像(低延迟/预览路径) |
rkisp1_stats | 元数据捕获设备 | 向用户态输出统计信息 |
rkisp1_params | 元数据输出设备 | 接收用户态的 ISP 参数配置 |
3 个子设备(Subdevice)
| 子设备名 | 角色 | 说明 |
|---|---|---|
rkisp1_resizer_mainpath | 缩放器 | 为 mainpath 捕获设备做缩放与降采样 |
rkisp1_resizer_selfpath | 缩放器 | 为 selfpath 捕获设备做缩放与降采样 |
rkisp1_isp | ISP 主实体 | 连接 sensor,负责全部 ISP 运算 |
在驱动源码 drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c 的rkisp1_create_links()中可以看到实体链接的建立过程:
- CSI 接收器 →
rkisp1_isp的 sink pad(RKISP1_ISP_PAD_SINK_VIDEO,启用); rkisp1_isp的 source pad(RKISP1_ISP_PAD_SOURCE_VIDEO)→ 各 resizer 的 sink pad(RKISP1_RSZ_PAD_SINK,启用);- resizer source pad → 捕获视频节点(启用且
MEDIA_LNK_FL_IMMUTABLE,即不可变链接); rkisp1_params→ ISP 的 params sink pad(RKISP1_ISP_PAD_SINK_PARAMS,启用且不可变);- ISP 的 stats source pad(
RKISP1_ISP_PAD_SOURCE_STATS)→rkisp1_stats(启用且不可变)。
从拓扑图可以确认默认的设备号分配:rkisp1_isp为/dev/v4l-subdev0,rkisp1_resizer_mainpath为/dev/v4l-subdev1,rkisp1_resizer_selfpath为/dev/v4l-subdev2;rkisp1_mainpath为/dev/video0,rkisp1_selfpath为/dev/video1,rkisp1_stats为/dev/video2,rkisp1_params为/dev/video3(实际编号取决于系统加载顺序)。
各实体的能力与限制
rkisp1_mainpath / rkisp1_selfpath:帧捕获节点
这两个节点是真正的 DMA 引擎,负责把处理后的帧写入内存:
- selfpath可捕获YUV/RGB格式。其输入为 YUV 编码流,能够将其转换为 RGB;但不能捕获 Bayer 格式。
- mainpath可捕获Bayer 与 YUV格式,但不能捕获 RGB 格式。
两者都支持V4L2_CAP_IO_MCcapability(见内核文档 Documentation/userspace-api/media/v4l/vidioc-querycap.rst 中关于 device capabilities 的描述),表明它们遵循 Media Controller 的 IO 语义,必须在配置好管线链接与子设备格式后才能使用。
rkisp1_resizer_mainpath / rkisp1_resizer_selfpath:缩放器子设备
两个缩放器实体可以为对应捕获路径做帧的放大、缩小,并且可以改变 YUV 采样率(例如 YUV 4:2:2 → YUV 4:2:0)。缩放器的 sink pad 还具备裁剪能力。
限制条件:缩放器实体只能操作 YUV 4:2:2 格式(总线格式MEDIA_BUS_FMT_YUYV8_2X8)。当 mainpath 以 Bayer 格式捕获时,mainpath 对应的缩放器会被设置为bypass 模式——即不进行任何运算,直接把帧转发给捕获设备。这一设计让 Bayer 原始数据得以无损直达内存。
rkisp1_isp:ISP 处理子设备
rkisp1_isp是 ISP 主实体:
- 通过sink pad 0连接 sensor,使用CSI-2 协议接收帧,并负责 CSI-2 协议的配置;
- sink pad 0上具备裁剪能力:定义从 sensor 获取的图像区域;
- source pad 2上具备裁剪能力:定义Image Stabilizer(IS,图像稳定器)的区域;
- 另外两个 pad(
RKISP1_ISP_PAD_SINK_PARAMS、RKISP1_ISP_PAD_SOURCE_STATS)分别对接 params 与 stats 视频节点。
rkisp1_stats:统计视频节点(3A 回环的数据出口)
rkisp1_stats向用户态应用输出正在被 rkisp1 处理的帧的3A 统计信息(自动对焦 AF、自动曝光 AE、自动白平衡 AWB)以及直方图统计。利用这些数据,应用可以实现 3A 算法,并通过rkisp1_params节点重新下发参数,在视频流过程中持续提升图像质量——这就是 ISP 的 3A 控制回环。
缓冲区格式由结构体struct rkisp1_stat_buffer(定义于 include/uapi/linux/rkisp1-config.h)定义,其头部包含meas_type(测量类型位掩码RKISP1_CIF_ISP_STAT_AWB/_AUTOEXP/_AFM/_HIST)与frame_id(用于与捕获帧同步)。用户态需要把数据格式设置为V4L2_META_FMT_RK_ISP1_STAT_3A,即 fourcc'RK1S'(见 include/uapi/linux/videodev2.h)。
rkisp1_params:参数视频节点(3A 回环的参数入口)
rkisp1_params在视频流运行期间接收用户态下发的一组参数并应用到硬件,支持动态修改诸如黑电平(black level)、串扰校正(cross talk corrections)等参数。
该驱动支持两种参数配置方式:
固定参数格式(fixed parameters format):缓冲区格式由
struct rkisp1_params_cfg定义,核心是三个掩码字段:module_en_update:标记哪些模块的使能位需要更新;module_ens:各模块的使能值,只有module_en_update中对应位置位的模块才会被更新;module_cfg_update:标记哪些模块的配置需要更新。
其下又分为测量配置(
rkisp1_cif_isp_isp_meas_cfg:AWB 测量、直方图、AE、AF)与其它配置(rkisp1_cif_isp_isp_other_cfg:DPCC 坏点校正、BLS 黑电平、SDG 传感器去 Gamma、LSC 镜头阴影、AWB 增益、FLT 滤波、BDM 去马赛克、CTK 串扰、GOC Gamma 输出、DPF 降噪预滤波、CPROC 色彩处理、IE 图像特效等 13 类)。数据格式设置为V4L2_META_FMT_RK_ISP1_PARAMS(fourcc'RK1P')。可扩展参数格式(extensible parameters format):缓冲区格式由
struct rkisp1_ext_params_cfg定义,数据格式设置为V4L2_META_FMT_RK_ISP1_EXT_PARAMS(fourcc'RK1E')。其核心是一系列带rkisp1_ext_params_block_header(type/flags/size)的配置块,块类型由枚举rkisp1_ext_params_block_type给出,涵盖 BLS、DPCC、SDG、AWB_GAIN、FLT、BDM、CTK、GOC、DPF、DPF_STRENGTH、CPROC、IE、LSC、AWB_MEAS、HST_MEAS、AEC_MEAS、AFC_MEAS、COMPAND_BLS、COMPAND_EXPAND/COMPRESS、WDR、CAC 共 22 类。每个块可独立启用/禁用(RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE/DISABLE),用户态还可通过只读控制RKISP1_CID_SUPPORTED_PARAMS_BLOCKS查询当前硬件支持的块位掩码。
实战:使用 media-ctl 与 v4l2-ctl 抓取自路视频帧
以下示例假设连接到rkisp1_isppad 0 的 sensor 是imx219,目标是从 selfpath 视频节点抓取900x800、YUV 4:2:2 平面格式的帧,并且用上了所有可用的裁剪能力。
第一步:配置媒体管线链接
# 清空并重建管线 media-ctl -d platform:rkisp1 -r # 建立 sensor -> ISP 链接 media-ctl -d platform:rkisp1 -l 'imx219 4-0010':0 -> 'rkisp1_isp':0 [1] # 启用 ISP -> selfpath 缩放器链接,禁用 ISP -> mainpath 缩放器链接 media-ctl -d platform:rkisp1 -l 'rkisp1_isp':2 -> 'rkisp1_resizer_selfpath':0 [1] media-ctl -d platform:rkisp1 -l 'rkisp1_isp':2 -> 'rkisp1_resizer_mainpath':0 [0]链接标志[1]表示启用(MEDIA_LNK_FL_ENABLED),[0]表示禁用。因为本例只从 selfpath 抓帧,所以把 mainpath 的链路关闭。
第二步:配置 sensor 与 ISP 的格式与裁剪
# 配置 imx219 sensor 输出为 10bit Bayer SRGGB,1640x1232 media-ctl -d platform:rkisp1 --set-v4l2 '"imx219 4-0010":0 [fmt:SRGGB10_1X10/1640x1232]' # 配置 ISP sink pad 0:与 sensor 完全相同的格式,并裁剪 (0,0)/1600x1200 media-ctl -d platform:rkisp1 --set-v4l2 '"rkisp1_isp":0 [fmt:SRGGB10_1X10/1640x1232 crop: (0,0)/1600x1200]' # 配置 ISP source pad 2:YUV 4:2:2,并对 IS(图像稳定器)区域裁剪 (0,0)/1500x1100 media-ctl -d platform:rkisp1 --set-v4l2 '"rkisp1_isp":2 [fmt:YUYV8_2X8/1600x1200 crop: (0,0)/1500x1100]'这里的关键规则:sensor 被配置为 Bayer 格式SRGGB10_1X10/1640x1232,rkisp1_isp:0pad 必须配置为与 sensor 相同的 mbus 格式和尺寸,否则流启动会以EPIPE错误失败。所以在示例中rkisp1_isp:0也被配置为SRGGB10_1X10/1640x1232,并叠加裁剪(0,0)/1600x1200。
裁剪的传播规则:ISP sink pad 0 的裁剪尺寸会自动传播为 ISP source pad(rkisp1_isp:2)的格式尺寸,因此在rkisp1_isp:2上先出现1600x1200,随后再对该 source pad 施加第二级裁剪(0,0)/1500x1100。
第三步:配置缩放器与捕获节点
# selfpath 缩放器 sink pad:格式必须与链路对端(ISP:2 的裁剪结果)一致,再叠加裁剪 media-ctl -d platform:rkisp1 --set-v4l2 '"rkisp1_resizer_selfpath":0 [fmt:YUYV8_2X8/1500x1100 crop: (300,400)/1400x1000]' # selfpath 缩放器 source pad:输出 900x800 media-ctl -d platform:rkisp1 --set-v4l2 '"rkisp1_resizer_selfpath":1 [fmt:YUYV8_2X8/900x800]' # 配置 selfpath 捕获节点:尺寸 900x800,像素格式 YUV 4:2:2 平面(422P) v4l2-ctl -z platform:rkisp1 -d rkisp1_selfpath -v width=900,height=800 v4l2-ctl -z platform:rkisp1 -d rkisp1_selfpath -v pixelformat=422P第四步:启动视频流抓帧
# 通过 mmap 方式抓取 10 帧 v4l2-ctl -z platform:rkisp1 -d rkisp1_selfpath --stream-mmap --stream-count 10链路中各裁剪/缩放的作用解析
整条链路的处理逻辑如下(尺寸从大到小逐级收敛):
- imx219 输出全幅
1640x1232Bayer; - ISP sink pad 0 裁剪出
(0,0)/1600x1200区域; - 该区域自动成为 ISP source pad 2 的格式,再对 IS 稳定器区域裁剪为
(0,0)/1500x1100; - 缩放器 sink pad 0 收到
1500x1100的 YUV 流后,先裁剪窗口(300,400)/1400x1000; - 缩放器把裁剪出的窗口缩放到 source pad 1 的目标尺寸
900x800; - 最终 selfpath 捕获节点以
900x800的 YUV 4:2:2 平面格式落盘。
也就是说,resizer 的动作是"先裁后缩":先切出感兴趣区域,再把该区域缩放到输出尺寸。
关于图像质量的提醒
需要注意:上面的示例没有运行 stats-params 控制回环。因此抓到的帧不会经过 3A 算法(AWB/AE 等调节),画质通常不佳,画面可能偏暗且发绿。要获得良好画质,用户态需要同时打开rkisp1_stats读取统计信息、运行 3A 算法,并通过rkisp1_params把计算出的参数回写硬件。
配置 YUV 量化范围(Quantization)
rkisp1 驱动对 YUV 格式支持限范围(limited)与全范围(full range)两种量化,其中默认是限范围。
切换方式:用户态应使用子设备的色彩空间转换 API(CSC)配置 ISP 的source pad 2(rkisp1_isp:2)。在该 pad 上配置的量化范围,就是 mainpath 与 selfpath 视频节点捕获帧的量化范围。
一个易踩的坑:resizer 与捕获实体即使把rkisp1_isp:2配置为全范围,也总是上报V4L2_QUANTIZATION_DEFAULT。因此应用若想获得实际生效的量化设置,应当从 padrkisp1_isp:2读取,而不是从捕获节点或缩放器读取。
小结
rkisp1 是典型的 Media-Controller 架构 ISP 驱动,其使用要点可归纳为:
- 版本感知:通过
MEDIA_IOC_DEVICE_INFO的hw_revision确定 UAPI 数组长度(V10 与 V12 网格规模不同); - 拓扑先行:先用
media-ctl建链,再逐级配置 sensor → ISP → resizer → capture 的格式与裁剪; - 格式强约束:ISP sink pad 0 必须与 sensor 同格式同尺寸(否则
EPIPE);resizer 只接受YUYV8_2X8;mainpath 收 Bayer/YUV、selfpath 收 YUV/RGB; - 3A 回环:
rkisp1_stats('RK1S')出统计、rkisp1_params('RK1P')或可扩展参数('RK1E')进参数,二者配合才能获得可用画质; - 量化配置:在
rkisp1_isp:2上通过 CSC 配置量化范围,注意 resizer/capture 恒上报V4L2_QUANTIZATION_DEFAULT。
如需深入源码,可继续阅读 drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c(格式/裁剪传播)、drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c(缩放实现)以及 drivers/media/platform/rockchip/rkisp1/rkisp1-stats.c 与 drivers/media/platform/rockchip/rkisp1/rkisp1-params.c(3A 回环内核侧实现)。
【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考