RGA解压缩librockit.so模块的volayer的AFBC失败

目前我遇到一个问题,就是我用rockit的库,设置了VO模块是RGB888,采用COMPRESS_AFBC_16x16模式。
我调用RK_MPI_VO_GetLayerFrame获取到视频层的帧之后,把数据给到rga进行缩放处理,RGA会报错
rga3_reg: irq handler err! INTR[0x20], HW_STATUS[0xaaabf], CMD_STATUS[0x1]
[ 781.268351] rga3_reg: RGA3 core[2] soft reset complete.
[ 781.268370] rga3_reg: win0 FBC decoder error, please check the fbc image of the source.
[ 781.268395] rga_job: rga request[30211] commit failed!
[ 781.268402] rga: request[30211] submit failed!
[ 781.298901] rga3_reg: irq handler err! INTR[0x20], HW_STATUS[0xaaaaf], CMD_STATUS[0x1]
[ 781.298918] rga3_reg: RGA3 core[1] soft reset complete.
[ 781.299002] rga3_reg: win0 FBC decoder error, please check the fbc image of the source.
[ 781.299025] rga_job: rga request[30212] commit failed!
[ 781.299031] rga: request[30212] submit failed!
[ 781.300127] rk_iommu fdb60f00.iommu: Enable stall request timed out, retry_count = 0, status: 0x000011
[ 781.301199] rk_iommu fdb60f00.iommu: Disable paging request timed out, retry_count = 0, status: 0x000011
[ 781.339106] rga3_reg: irq handler err! INTR[0x20], HW_STATUS[0xaaaaf], CMD_STATUS[0x1]
[ 781.339115] rga3_reg: RGA3 core[2] soft reset complete.
[ 781.339135] rga3_reg: win0 FBC decoder error, please check the fbc image of the source.
[ 781.339162] rga_job: rga request[30215] commit failed!
[ 781.339168] rga: request[30215] submit failed!
[ 781.369394] rga3_reg: irq handler err! INTR[0x20], HW_STATUS[0xaaabf], CMD_STATUS[0x1]
[ 781.369404] rga3_reg: RGA3 core[2] soft reset complete.
如果我从VPSS设置COMPRESS_AFBC_16x16模式,然后获取vpss的帧给到RGA进行处理就能正确。
请问这个问题是由于ROCKIT的显示模块使用的压缩方式不一致导致的?我该怎样解决

使用的平台是RK3588,
RGA固件 RGA multicore Device Driver: v1.3.3
RGA库是 1.10.0

问题确实是由于 VO 模块使用的 AFBC 压缩格式与 RGA 的 FBC 解码器不兼容导致的。这不是 bug,而是不同模块的 AFBC 编解码器在内部实现上的差异。

方案一:VO 模块关闭 AFBC 压缩(推荐,最简单)

将 VO 模块的压缩模式改为线性(不压缩),这样 RK_MPI_VO_GetLayerFrame 获取到的帧是线性格式,RGA 可以直接处理:

// 将 VO 层的压缩模式设置为不压缩
VO_COMPRESS_MODE_E enCompressMode = VO_COMPRESS_MODE_NONE;
RK_MPI_VO_SetLayerCompressMode(layer, enCompressMode);

或者在初始化 VO 层属性时就不启用压缩。这样获取到的帧是标准线性 RGB888,RGA 处理没有任何问题。

代价​:VO 显示时不再享受 AFBC 带来的带宽节省,但对于你需要从 VO 取帧做后处理的场景,这是最稳妥的方案。

方案二:从 VPSS 获取帧而非 VO(你已验证可行)

正如你已经发现的,从 VPSS 设置 COMPRESS_AFBC_16x16 并获取帧给 RGA 处理是可以正常工作的。如果你的流水线允许,建议调整架构:

VDEC → VPSS(AFBC_16x16)→ 分两路:
  ├── → VO 显示
  └── → GetChnFrame → RGA 缩放处理

这样 VPSS 产出的 AFBC 帧既能被 VO 正确显示,也能被 RGA 的 FBCD 正确解码。

方案三:VO 关闭压缩 + VPSS 开启压缩(兼顾显示带宽和后处理)

如果你既希望 VO 显示时享受 AFBC 的带宽优势,又需要用 RGA 处理帧数据,可以采用混合方案:

VDEC → VPSS(COMPRESS_AFBC_16x16)→ VO(VO 自动使用 AFBC 帧显示)
                 ↓
         VPSS GetChnFrame → RGA 处理

关键点:​不要在 VO 层面单独设置 AFBC 压缩​,而是让 VPSS 输出 AFBC 帧,VO 绑定 VPSS 后直接使用 AFBC 帧显示(VOP 的 Cluster 窗口支持直接消费 AFBC 帧),同时从 VPSS 通道取帧给 RGA。

方案四:如果必须从 VO 取帧,手动解压缩

如果架构上必须从 VO 取帧,且必须保持 VO 的 AFBC 压缩,那么需要:

  1. 获取 VO 帧后,先用 CPU 或 GPU 将 AFBC 压缩帧解码为线性格式
  2. 再将线性帧送给 RGA 处理

但这种方式效率很低,不推荐。

感谢您的解惑。在我的用法上我是在vo图层上进行窗口的叠加,然后把叠加完的画面给回vpss进行缩放编码。在4k的场景下如果不用压缩的话,GPU的使用率会很高。所以综合起来,好像只能用方案4去尝试,但是方案4的AFBC解码应该怎样解决,我尝试过转换成RGA能识别的AFBC帧,但是也转换不成功

VO 开启 AFBC 是为了降低 4K 下的 DDR 带宽压力,而 RGA 又无法直接消费 VO 产出的 AFBC 帧。先说结论:你尝试的"把 VO 的 AFBC 帧转换成 RGA 能识别的格式"这条路,在用户态几乎走不通。

因为AFBC 并不是一个简单的"压缩算法",它是一整套包含多个硬件参数的帧格式,不同模块之间的差异体现在以下几个层面:

  • YTR(YUV-like Transform)标志位:VOP 的 AFBC 解码器强制假设输入使用了 YTR 变换,而 RGA 的 FBCD 对 YTR 的要求不同。Rockchip 的 DRM 驱动补丁中明确提到过这个问题——YTR 标志位不匹配会导致解码器把非 YTR 的帧当成 YTR 来解,产生严重的数据错乱。
  • Superblock 布局:RK3588 的 VOP2 Cluster 窗口支持 32x8 superblock 的 AFBC 格式,而 RGA 的 FBCD 期望的是标准的 16x16 superblock。两者的 tile 排列、header 结构、body 偏移都不同。
  • Header 格式:AFBC 的 header 包含了每个 superblock 的压缩参数(transform 类型、split 标志等),VOP 和 RGA 对这些字段的解析方式不一致。

你在用户态拿到的只是一个 opaque 的压缩 buffer,没有 API 可以读取或修改其中的 YTR 标志、superblock 布局等元信息,所以"转换"这条路从设计上就缺少必要的接口。

好的,感谢