1. RK3588相机驱动中的图像格式基础第一次接触RK3588的相机驱动时我被各种图像格式搞得晕头转向。Mbus Code、FourCC、V4L2这些名词像天书一样直到在实际项目中踩了几个坑才真正理解它们的含义。简单来说图像格式在相机驱动中分为两个层面物理总线传输格式Mbus Code和内存存储格式FourCC。Mbus Code就像是快递运输时的包装方式决定了数据在传感器、MIPI总线和ISP之间如何打包传输。而FourCC则是数据到达内存后的拆包存储方式相当于快递送到你家后如何摆放。举个例子同样是YUV数据在总线上可能是MEDIA_BUS_FMT_UYVY8_2X8到了内存就变成了V4L2_PIX_FMT_UYVY。在RK3588的开发板上我常用media-ctl工具查看支持的Mbus格式media-ctl --known-mbus-fmts这个命令会列出所有支持的格式但实际摄像头通常只支持其中几种。记得第一次调试时我花了半天时间才发现摄像头只支持MEDIA_BUS_FMT_SBGGR10_1X10而我却配置了错误的格式。2. Mbus Code详解与常用格式Mbus Code定义在内核的media-bus-format.h中每种格式都有一个唯一的十六进制编码。通过分析RK3588的驱动代码我发现最常用的格式主要集中在三类2.1 RGB格式家族MEDIA_BUS_FMT_RGB888_1X24最常见的24位RGB每个像素占3字节MEDIA_BUS_FMT_RGB565_1X16节省带宽的16位RGB适合嵌入式显示MEDIA_BUS_FMT_ARGB8888_1X32带alpha通道的32位RGB2.2 YUV格式变种MEDIA_BUS_FMT_UYVY8_2X8UYVY交错格式视频采集常用MEDIA_BUS_FMT_YUYV8_2X8YUYV排列与V4L2的PIX_FMT_YUYV对应MEDIA_BUS_FMT_YUV8_1X24平面YUV格式适合后期处理2.3 RAW Bayer格式MEDIA_BUS_FMT_SBGGR8_1X8BGGR排列的8位RAWMEDIA_BUS_FMT_SGRBG10_1X10GRBG排列的10位RAWMEDIA_BUS_FMT_SRGGB12_1X12RGGB排列的12位高精度RAW在调试OV13850传感器时我遇到过一个问题传感器输出MEDIA_BUS_FMT_SBGGR10_1X10但驱动里错误地配置成了MEDIA_BUS_FMT_SGRBG10_1X10导致图像颜色完全错乱。通过下面的代码可以枚举支持的Mbus格式struct v4l2_subdev_mbus_code_enum code {0}; code.index 0; while (!ioctl(fd, VIDIOC_SUBDEV_ENUM_MBUS_CODE, code)) { printf(Found mbus code: 0x%x\n, code.code); code.index; }3. FourCC格式解析与内存布局FourCC用四个字符直观表示格式特征比如NV12、YUYV。在RK3588的V4L2驱动中我经常需要处理这些格式转换。以下是几种典型格式的内存布局3.1 NV12/NV21系列# NV12内存布局 Y Y Y Y Y Y Y Y U V U V这种半平面格式Y和UV分开存储RK3588的硬件加速器特别擅长处理。实测NV12转RGB时使用RGA加速比CPU快20倍以上。3.2 YUYV/UYVY打包格式# YUYV排列 Y U Y V | Y U Y V这种格式在USB摄像头中很常见但在RK3588上处理时要注意字节序。我曾经因为忽略字节序导致图像出现绿色偏色。3.3 RAW Bayer格式转换Bayer格式的FourCC比较特殊比如V4L2_PIX_FMT_SBGGR8BA81V4L2_PIX_FMT_SGRBG10GR10在调试IMX586传感器时需要特别注意10位RAW的处理。RK3588的ISP要求特定的对齐方式错误的配置会导致ISP流水线崩溃。建议配置如下struct v4l2_format fmt { .type V4L2_BUF_TYPE_VIDEO_CAPTURE, .fmt.pix { .width 3840, .height 2160, .pixelformat V4L2_PIX_FMT_SGRBG10, .field V4L2_FIELD_NONE, .bytesperline 3840*2, .sizeimage 3840*2160*2 } };4. 格式映射实战与问题排查4.1 典型映射关系表Mbus CodeFourCC适用场景MEDIA_BUS_FMT_YUYV8_2X8V4L2_PIX_FMT_YUYVUSB摄像头MEDIA_BUS_FMT_SBGGR10_1X10V4L2_PIX_FMT_SBGGR10工业相机MEDIA_BUS_FMT_UYVY8_2X8V4L2_PIX_FMT_UYVY视频会议MEDIA_BUS_FMT_YUV8_1X24V4L2_PIX_FMT_YUV420视频解码4.2 常见问题排查指南颜色错乱检查Mbus Code与FourCC的匹配关系比如YUV顺序是否一致图像撕裂确认bytesperline参数是否正确特别是对齐要求ISP崩溃检查RAW格式的位宽是否匹配传感器输出性能低下尽量使用NV12等硬件加速友好格式在调试SC200AI传感器时我遇到过一个棘手问题图像间歇性出现横纹。最终发现是Mbus Code配置为MEDIA_BUS_FMT_YUYV8_2X8但应用层请求的是V4L2_PIX_FMT_NV12。由于驱动没有自动转换功能导致DMA传输异常。解决方法是在驱动中显式添加格式转换支持static const struct rk3588_format_table fmt_table[] { { .mbus_code MEDIA_BUS_FMT_YUYV8_2X8, .fourcc V4L2_PIX_FMT_NV12, .csi_fmt CSI_YUV422_8BIT, .isp_fmt ISP_FMT_YUV422, .hw_fmt RKCIF_YUV422 }, // 其他格式映射... };4.3 性能优化技巧优先使用NV12格式RK3588的NPU和RGA都有硬件加速对于高分辨率(4K以上)建议启用ISP的降频功能RAW格式处理时开启ISP的Bayer降噪模块多路摄像头场景注意内存带宽分配记得在一个人脸识别项目中我将格式从YUYV改为NV12后整体帧率从15fps提升到了30fps。关键配置如下v4l2-ctl --set-fmt-videowidth1920,height1080,pixelformatNV12
RK3588 camera驱动解析:从Mbus Code到FourCC的图像格式映射与实战
1. RK3588相机驱动中的图像格式基础第一次接触RK3588的相机驱动时我被各种图像格式搞得晕头转向。Mbus Code、FourCC、V4L2这些名词像天书一样直到在实际项目中踩了几个坑才真正理解它们的含义。简单来说图像格式在相机驱动中分为两个层面物理总线传输格式Mbus Code和内存存储格式FourCC。Mbus Code就像是快递运输时的包装方式决定了数据在传感器、MIPI总线和ISP之间如何打包传输。而FourCC则是数据到达内存后的拆包存储方式相当于快递送到你家后如何摆放。举个例子同样是YUV数据在总线上可能是MEDIA_BUS_FMT_UYVY8_2X8到了内存就变成了V4L2_PIX_FMT_UYVY。在RK3588的开发板上我常用media-ctl工具查看支持的Mbus格式media-ctl --known-mbus-fmts这个命令会列出所有支持的格式但实际摄像头通常只支持其中几种。记得第一次调试时我花了半天时间才发现摄像头只支持MEDIA_BUS_FMT_SBGGR10_1X10而我却配置了错误的格式。2. Mbus Code详解与常用格式Mbus Code定义在内核的media-bus-format.h中每种格式都有一个唯一的十六进制编码。通过分析RK3588的驱动代码我发现最常用的格式主要集中在三类2.1 RGB格式家族MEDIA_BUS_FMT_RGB888_1X24最常见的24位RGB每个像素占3字节MEDIA_BUS_FMT_RGB565_1X16节省带宽的16位RGB适合嵌入式显示MEDIA_BUS_FMT_ARGB8888_1X32带alpha通道的32位RGB2.2 YUV格式变种MEDIA_BUS_FMT_UYVY8_2X8UYVY交错格式视频采集常用MEDIA_BUS_FMT_YUYV8_2X8YUYV排列与V4L2的PIX_FMT_YUYV对应MEDIA_BUS_FMT_YUV8_1X24平面YUV格式适合后期处理2.3 RAW Bayer格式MEDIA_BUS_FMT_SBGGR8_1X8BGGR排列的8位RAWMEDIA_BUS_FMT_SGRBG10_1X10GRBG排列的10位RAWMEDIA_BUS_FMT_SRGGB12_1X12RGGB排列的12位高精度RAW在调试OV13850传感器时我遇到过一个问题传感器输出MEDIA_BUS_FMT_SBGGR10_1X10但驱动里错误地配置成了MEDIA_BUS_FMT_SGRBG10_1X10导致图像颜色完全错乱。通过下面的代码可以枚举支持的Mbus格式struct v4l2_subdev_mbus_code_enum code {0}; code.index 0; while (!ioctl(fd, VIDIOC_SUBDEV_ENUM_MBUS_CODE, code)) { printf(Found mbus code: 0x%x\n, code.code); code.index; }3. FourCC格式解析与内存布局FourCC用四个字符直观表示格式特征比如NV12、YUYV。在RK3588的V4L2驱动中我经常需要处理这些格式转换。以下是几种典型格式的内存布局3.1 NV12/NV21系列# NV12内存布局 Y Y Y Y Y Y Y Y U V U V这种半平面格式Y和UV分开存储RK3588的硬件加速器特别擅长处理。实测NV12转RGB时使用RGA加速比CPU快20倍以上。3.2 YUYV/UYVY打包格式# YUYV排列 Y U Y V | Y U Y V这种格式在USB摄像头中很常见但在RK3588上处理时要注意字节序。我曾经因为忽略字节序导致图像出现绿色偏色。3.3 RAW Bayer格式转换Bayer格式的FourCC比较特殊比如V4L2_PIX_FMT_SBGGR8BA81V4L2_PIX_FMT_SGRBG10GR10在调试IMX586传感器时需要特别注意10位RAW的处理。RK3588的ISP要求特定的对齐方式错误的配置会导致ISP流水线崩溃。建议配置如下struct v4l2_format fmt { .type V4L2_BUF_TYPE_VIDEO_CAPTURE, .fmt.pix { .width 3840, .height 2160, .pixelformat V4L2_PIX_FMT_SGRBG10, .field V4L2_FIELD_NONE, .bytesperline 3840*2, .sizeimage 3840*2160*2 } };4. 格式映射实战与问题排查4.1 典型映射关系表Mbus CodeFourCC适用场景MEDIA_BUS_FMT_YUYV8_2X8V4L2_PIX_FMT_YUYVUSB摄像头MEDIA_BUS_FMT_SBGGR10_1X10V4L2_PIX_FMT_SBGGR10工业相机MEDIA_BUS_FMT_UYVY8_2X8V4L2_PIX_FMT_UYVY视频会议MEDIA_BUS_FMT_YUV8_1X24V4L2_PIX_FMT_YUV420视频解码4.2 常见问题排查指南颜色错乱检查Mbus Code与FourCC的匹配关系比如YUV顺序是否一致图像撕裂确认bytesperline参数是否正确特别是对齐要求ISP崩溃检查RAW格式的位宽是否匹配传感器输出性能低下尽量使用NV12等硬件加速友好格式在调试SC200AI传感器时我遇到过一个棘手问题图像间歇性出现横纹。最终发现是Mbus Code配置为MEDIA_BUS_FMT_YUYV8_2X8但应用层请求的是V4L2_PIX_FMT_NV12。由于驱动没有自动转换功能导致DMA传输异常。解决方法是在驱动中显式添加格式转换支持static const struct rk3588_format_table fmt_table[] { { .mbus_code MEDIA_BUS_FMT_YUYV8_2X8, .fourcc V4L2_PIX_FMT_NV12, .csi_fmt CSI_YUV422_8BIT, .isp_fmt ISP_FMT_YUV422, .hw_fmt RKCIF_YUV422 }, // 其他格式映射... };4.3 性能优化技巧优先使用NV12格式RK3588的NPU和RGA都有硬件加速对于高分辨率(4K以上)建议启用ISP的降频功能RAW格式处理时开启ISP的Bayer降噪模块多路摄像头场景注意内存带宽分配记得在一个人脸识别项目中我将格式从YUYV改为NV12后整体帧率从15fps提升到了30fps。关键配置如下v4l2-ctl --set-fmt-videowidth1920,height1080,pixelformatNV12