4. RAW图格式详解:Bayer Pattern、位深打包与MIPI数据包解析
在Camera驱动开发中,RAW图是图像传感器最原始的“底片”。理解RAW图的格式,是正确配置DMA控制器、解析MIPI数据流以及进行后续ISP处理的前提。本章将深入剖析Bayer Pattern的排列逻辑、RAW10/RAW12的打包方式以及MIPI CSI-2数据包的结构。
4.1 Bayer Pattern:色彩世界的起点
绝大多数CMOS图像传感器使用Bayer滤色阵列来捕捉彩色信息。每个像素只记录红、绿、蓝中的一种颜色分量,通过特定的排列模式来模拟全彩视觉。最常见的模式是RGGB和GRBG。
4.1.1 常见Bayer Pattern对比
| Pattern | 排列顺序(2x2单元) | 常见应用场景 | 特点 |
|---|---|---|---|
| RGGB | 第一行:R G R G ... 第二行:G B G B ... |
Sony、OmniVision等主流传感器 | 绿色像素数量是红/蓝的两倍,模拟人眼对绿色更敏感的特性 |
| GRBG | 第一行:G R G R ... 第二行:B G B G ... |
部分Samsung、Onsemi传感器 | 与RGGB相比,绿色像素位置偏移,影响ISP的插值方向 |
| BGGR | 第一行:B G B G ... 第二行:G R G R ... |
部分老式或特定传感器 | 与RGGB互为镜像,驱动配置时需注意 |
| GBRG | 第一行:G B G B ... 第二行:R G R G ... |
较少见,特定定制传感器 | 与GRBG类似,但绿色和蓝色位置互换 |
4.1.2 Bayer Pattern结构示意图
下图展示了RGGB和GRBG两种最常见模式的2x2像素单元结构。每个方格代表一个物理像素,字母代表该像素上覆盖的滤色片颜色。
4.2 RAW位深与打包格式
RAW数据的位深决定了每个像素的动态范围。常见的位深有RAW10(10-bit)和RAW12(12-bit)。由于MIPI CSI-2传输和DMA存储通常以字节(8-bit)为单位,因此需要特定的打包格式来高效存储这些非8-bit对齐的数据。
4.2.1 RAW10 打包格式
RAW10每个像素占用10-bit数据。为了在8-bit的字节流中传输,通常采用4像素打包成5字节的方式。这种格式称为“RAW10 Packed”。
- 存储效率: 100%(无浪费字节)。
- 打包规则: 4个像素(P0, P1, P2, P3)的10-bit数据,按位拼接成5个字节(B0, B1, B2, B3, B4)。
- 位分布:
- B0 = P0[9:2](高8位)
- B1 = P1[9:2](高8位)
- B2 = P2[9:2](高8位)
- B3 = P3[9:2](高8位)
- B4 = {P3[1:0], P2[1:0], P1[1:0], P0[1:0]}(每个像素的低2位,共8位)
4.2.2 RAW12 打包格式
RAW12每个像素占用12-bit数据。打包方式与RAW10类似,采用2像素打包成3字节的方式。
- 存储效率: 100%(无浪费字节)。
- 打包规则: 2个像素(P0, P1)的12-bit数据,按位拼接成3个字节(B0, B1, B2)。
- 位分布:
- B0 = P0[11:4](高8位)
- B1 = P1[11:4](高8位)
- B2 = {P1[3:0], P0[3:0]}(每个像素的低4位,共8位)
4.2.3 打包格式对比表
| 格式 | 位深 | 打包方式 | 每像素平均字节数 | 常见场景 |
|---|---|---|---|---|
| RAW8 | 8-bit | 1像素 = 1字节 | 1.0 | 低端摄像头、预览模式 |
| RAW10 | 10-bit | 4像素 = 5字节 | 1.25 | 主流手机、安防摄像头 |
| RAW12 | 12-bit | 2像素 = 3字节 | 1.5 | 工业相机、医疗影像 |
| RAW16 | 16-bit | 1像素 = 2字节 | 2.0 | 高动态范围(HDR)场景 |
4.2.4 RAW10 打包位分布示意图
下图展示了4个RAW10像素如何打包成5个字节。每个像素的高8位依次存放在前4个字节中,而每个像素的低2位则组合成第5个字节。
4.3 MIPI数据包解析
MIPI CSI-2协议定义了数据在D-PHY物理层上的传输格式。每一帧RAW图像数据被封装成多个数据包,通过差分信号线传输。理解数据包结构是正确解析RAW数据的关键。
4.3.1 MIPI CSI-2 数据包结构
一个标准的MIPI数据包由三部分组成:包首(Packet Header, PH)、数据负载(Payload)和包尾(Packet Footer, PF)。
- 包首(4字节):
- 数据标识符(Data Identifier, DI):1字节,包含虚拟通道号(VC, 2-bit)和数据类型(Data Type, 6-bit)。
- 字计数(Word Count, WC):2字节,表示数据负载的字节数。
- ECC(Error Correction Code):1字节,用于包首的纠错。
- 数据负载(可变长度): 实际的RAW像素数据,按RAW10/RAW12打包格式排列。
- 包尾(2字节): 校验和(Checksum),用于数据负载的完整性校验。
4.3.2 数据类型(Data Type)与RAW格式对应
MIPI CSI-2协议为不同的RAW格式定义了标准的数据类型值。驱动在解析数据包时,必须根据数据类型字段来判断负载的格式。
| 数据类型名称 | 数据类型值(Hex) | 对应RAW格式 | 说明 |
|---|---|---|---|
| RAW6 | 0x28 | 6-bit RAW | 较少使用 |
| RAW7 | 0x29 | 7-bit RAW | 较少使用 |
| RAW8 | 0x2A | 8-bit RAW | 常见于低端传感器 |
| RAW10 | 0x2B | 10-bit RAW | 最常用格式之一 |
| RAW12 | 0x2C | 12-bit RAW | 高精度应用 |
| RAW14 | 0x2D | 14-bit RAW | 工业/医疗高端应用 |
4.3.3 MIPI数据包解析流程示意图
下图展示了从MIPI物理层接收数据到解析出RAW像素数据的完整流程。驱动需要依次解析包首、提取负载、校验包尾,最后根据数据类型进行解包。
4.4 实战:从MIPI数据包到DMA缓冲区
在驱动中,MIPI接收到的数据包经过DMA引擎直接搬运到系统内存中。驱动开发者需要理解以下关键点:
- DMA传输粒度: DMA通常以字节为单位传输,因此RAW10/RAW12的打包格式必须与DMA的传输宽度对齐。
- 帧同步: MIPI协议通过帧起始(FS)和帧结束(FE)包来标记一帧的开始和结束。驱动需要监听这些包来触发DMA传输完成中断。
- 行同步: 部分传感器会发送行起始(LS)和行结束(LE)包,用于标记每一行的边界。这对于DMA的“行模式”传输非常重要。
4.4.1 DMA缓冲区与RAW数据映射示例
假设一个分辨率为1920x1080的RAW10图像,DMA缓冲区中每行存储2400字节。驱动在中断处理函数中,需要将缓冲区地址传递给ISP或直接保存为文件。以下是一个简化的DMA传输完成回调函数示例:
static void sensor_dma_callback(void *arg)
{
struct camera_device *cam = (struct camera_device *)arg;
struct dma_buf *buf = cam->current_buf;
u32 width = cam->fmt.width; // 1920
u32 height = cam->fmt.height; // 1080
u32 bpp = cam->fmt.bpp; // 10 (RAW10)
// 计算每行字节数
u32 bytes_per_line = width * bpp / 8; // 1920 * 10 / 8 = 2400
// 验证缓冲区大小
if (buf->size != bytes_per_line * height) {
dev_err(cam->dev, "DMA buffer size mismatch!\n");
return;
}
// 将缓冲区标记为就绪,等待ISP或应用层读取
cam->frame_ready = true;
wake_up_interruptible(&cam->wait_queue);
// 重新启动DMA传输,准备下一帧
start_dma_transfer(cam, buf);
}