Skip to content

RGA_FormatTool

SweerItTer edited this page Feb 21, 2026 · 4 revisions

FormatTool API 文档

概述

FormatTool 是 utilsCore RGA 模块的工具函数集合,提供 RGA、DRM、V4L2 格式之间的转换功能。

职责

  • DRM 格式转 RGA 格式
  • RGA 格式转 DRM 格式
  • V4L2 格式转 RGA 格式
  • RGA 格式转 V4L2 格式

适用场景

  • 跨模块格式转换
  • RGA 处理
  • 显示和编码格式匹配

依赖关系

  • 依赖: Rockchip RGA SDK
  • 依赖: DRM 格式定义
  • 依赖: V4L2 格式定义
  • 被依赖: RgaConverter, RgaProcessor 等模块

格式说明

RGA 和 DRM 字节序差异

重要: RGA 采用低地址到高地址 B | G | R | A 命名,而 DRM 使用 fourcc_code 从高到低 A | R | G | B 命名。

例如:

  • RGA: RK_FORMAT_RGBA_8888 → DRM: DRM_FORMAT_ABGR8888
  • RGA: RK_FORMAT_BGRA_8888 → DRM: DRM_FORMAT_ARGB8888

静态方法

convertDRMtoRGAFormat() - DRM 格式转 RGA 格式

namespace utils::rga {
    int convertDRMtoRGAFormat(uint32_t drmFmt) noexcept;
}

参数说明:

  • drmFmt (输入): DRM 格式(如 DRM_FORMAT_NV12)

返回值:

  • 成功: RGA 格式(如 RK_FORMAT_YCbCr_420_SP)
  • 失败: -1(表示无效或不受支持的格式)

所有权归属:

  • 无所有权转移

性能优化:

  1. 使用编译时 constexpr 数组作为查找表,避免运行时哈希计算
  2. 线性查找优化,支持编译器自动向量化
  3. noexcept 保证不抛出异常

错误处理:

  1. 自动验证输入格式有效性
  2. 返回明确的错误码(-1)
  3. 支持格式验证函数 isValidDrmFormat()

使用例程:

#include "utils/rga/formatTool.h"

// DRM NV12 转 RGA 格式
int rga_fmt = convertDRMtoRGAFormat(DRM_FORMAT_NV12);
if (rga_fmt != -1) {
    printf("RGA format: %d\n", rga_fmt);  // 输出: RK_FORMAT_YCbCr_420_SP
} else {
    printf("Unsupported DRM format\n");
}

// 验证格式有效性
if (isValidDrmFormat(DRM_FORMAT_ABGR8888)) {
    int rga_fmt = convertDRMtoRGAFormat(DRM_FORMAT_ABGR8888);
    printf("RGA format: %d\n", rga_fmt);  // 输出: RK_FORMAT_RGBA_8888
}

// 使用命名空间版本
using namespace utils::rga;
int rga_fmt2 = convertDRMtoRGAFormat(DRM_FORMAT_NV21);

convertRGAtoDrmFormat() - RGA 格式转 DRM 格式

namespace utils::rga {
    uint32_t convertRGAtoDrmFormat(int rgaFmt) noexcept;
}

参数说明:

  • rgaFmt (输入): RGA 格式(如 RK_FORMAT_YCbCr_420_SP)

返回值:

  • 成功: DRM 格式(如 DRM_FORMAT_NV12)
  • 失败: 0xFFFFFFFF(表示无效或不受支持的格式)

所有权归属:

  • 无所有权转移

性能优化:

  1. 编译时查找表,零动态内存分配
  2. 缓存友好的线性布局
  3. noexcept 保证异常安全

错误处理:

  1. 输入格式预验证
  2. 统一的错误返回值
  3. 支持 isValidRgaFormat() 验证函数

使用例程:

#include "utils/rga/formatTool.h"

// RGA YCbCr_420_SP 转 DRM 格式
uint32_t drm_fmt = convertRGAtoDrmFormat(RK_FORMAT_YCbCr_420_SP);
if (drm_fmt != 0xFFFFFFFF) {
    printf("DRM format: 0x%x\n", drm_fmt);  // 输出: DRM_FORMAT_NV12
}

// RGA RGBA_8888 转 DRM 格式(注意字节序)
drm_fmt = convertRGAtoDrmFormat(RK_FORMAT_RGBA_8888);
printf("DRM format: 0x%x\n", drm_fmt);  // 输出: DRM_FORMAT_ABGR8888

convertV4L2toRGAFormat() - V4L2 格式转 RGA 格式

namespace utils::rga {
    int convertV4L2toRGAFormat(uint32_t v4l2Fmt) noexcept;
}

参数说明:

  • v4l2Fmt (输入): V4L2 格式(如 V4L2_PIX_FMT_NV12)

返回值:

  • 成功: RGA 格式(如 RK_FORMAT_YCbCr_420_SP)
  • 失败: -1(表示无效或不受支持的格式)

所有权归属:

  • 无所有权转移

性能优化:

  1. 编译时查找表,零运行时开销
  2. 缓存友好的数据布局
  3. noexcept 异常安全保证

错误处理:

  1. 输入格式自动验证
  2. 统一的错误返回值
  3. 支持 isValidV4l2Format() 验证函数

使用例程:

#include "utils/rga/formatTool.h"

// V4L2 NV12 转 RGA 格式
int rga_fmt = convertV4L2toRGAFormat(V4L2_PIX_FMT_NV12);
if (rga_fmt != -1) {
    printf("RGA format: %d\n", rga_fmt);  // 输出: RK_FORMAT_YCbCr_420_SP
}

// 验证格式有效性
if (isValidV4l2Format(V4L2_PIX_FMT_YUYV)) {
    int rga_fmt = convertV4L2toRGAFormat(V4L2_PIX_FMT_YUYV);
    // 处理转换结果
}

convertRGAtoV4L2Format() - RGA 格式转 V4L2 格式

namespace utils::rga {
    uint32_t convertRGAtoV4L2Format(int rgaFmt) noexcept;
}

参数说明:

  • rgaFmt (输入): RGA 格式(如 RK_FORMAT_YCbCr_420_SP)

返回值:

  • 成功: V4L2 格式(如 V4L2_PIX_FMT_NV12)
  • 失败: 0xFFFFFFFF(表示无效或不受支持的格式)

所有权归属:

  • 无所有权转移

性能优化:

  1. 反向查找优化,避免重复计算
  2. 编译时确定的查找算法
  3. 内存访问局部性优化

错误处理:

  1. 输入格式预检查
  2. 明确的错误返回值
  3. 支持格式验证链

使用例程:

#include "utils/rga/formatTool.h"

// RGA YCbCr_420_SP 转 V4L2 格式
uint32_t v4l2_fmt = convertRGAtoV4L2Format(RK_FORMAT_YCbCr_420_SP);
if (v4l2_fmt != 0xFFFFFFFF) {
    printf("V4L2 format: 0x%x\n", v4l2_fmt);  // 输出: V4L2_PIX_FMT_NV12
}

// 完整的格式转换链示例
int rga_fmt = convertDRMtoRGAFormat(DRM_FORMAT_NV12);
if (rga_fmt != -1) {
    uint32_t v4l2_fmt = convertRGAtoV4L2Format(rga_fmt);
    if (v4l2_fmt != 0xFFFFFFFF) {
        printf("DRM->RGA->V4L2 conversion successful\n");
    }
}

格式映射表

DRM 到 RGA 格式映射

DRM 格式 RGA 格式
DRM_FORMAT_RGB565 RK_FORMAT_RGB_565
DRM_FORMAT_RGB888 RK_FORMAT_RGB_888
DRM_FORMAT_BGR888 RK_FORMAT_BGR_888
DRM_FORMAT_ABGR8888 RK_FORMAT_RGBA_8888
DRM_FORMAT_ARGB8888 RK_FORMAT_BGRA_8888
DRM_FORMAT_BGRA8888 RK_FORMAT_ARGB_8888
DRM_FORMAT_RGBA8888 RK_FORMAT_ABGR_8888
DRM_FORMAT_BGRX8888 RK_FORMAT_XRGB_8888
DRM_FORMAT_RGBX8888 RK_FORMAT_XBGR_8888
DRM_FORMAT_XBGR8888 RK_FORMAT_RGBX_8888
DRM_FORMAT_XRGB8888 RK_FORMAT_BGRX_8888
DRM_FORMAT_NV12 RK_FORMAT_YCbCr_420_SP
DRM_FORMAT_NV21 RK_FORMAT_YCrCb_420_SP
DRM_FORMAT_YUV420 RK_FORMAT_YCbCr_420_P
DRM_FORMAT_YVU420 RK_FORMAT_YCrCb_420_P
DRM_FORMAT_NV16 RK_FORMAT_YCbCr_422_SP
DRM_FORMAT_NV61 RK_FORMAT_YCrCb_422_SP
DRM_FORMAT_YUV422 RK_FORMAT_YCbCr_422_P
DRM_FORMAT_YVU422 RK_FORMAT_YCrCb_422_P

RGA 到 DRM 格式映射

RGA 格式 DRM 格式
RK_FORMAT_RGB_565 DRM_FORMAT_RGB565
RK_FORMAT_RGB_888 DRM_FORMAT_RGB888
RK_FORMAT_BGR_888 DRM_FORMAT_BGR888
RK_FORMAT_RGBA_8888 DRM_FORMAT_ABGR8888
RK_FORMAT_BGRA_8888 DRM_FORMAT_ARGB8888
RK_FORMAT_ARGB_8888 DRM_FORMAT_BGRA8888
RK_FORMAT_ABGR_8888 DRM_FORMAT_RGBA8888
RK_FORMAT_XRGB_8888 DRM_FORMAT_BGRX8888
RK_FORMAT_XBGR_8888 DRM_FORMAT_RGBX8888
RK_FORMAT_RGBX_8888 DRM_FORMAT_XBGR8888
RK_FORMAT_BGRX_8888 DRM_FORMAT_XRGB8888
RK_FORMAT_YCbCr_420_SP DRM_FORMAT_NV12
RK_FORMAT_YCrCb_420_SP DRM_FORMAT_NV21
RK_FORMAT_YCbCr_420_P DRM_FORMAT_YUV420
RK_FORMAT_YCrCb_420_P DRM_FORMAT_YVU420
RK_FORMAT_YCbCr_422_SP DRM_FORMAT_NV16
RK_FORMAT_YCrCb_422_SP DRM_FORMAT_NV61
RK_FORMAT_YCbCr_422_P DRM_FORMAT_YUV422
RK_FORMAT_YCrCb_422_P DRM_FORMAT_YVU422

V4L2 到 RGA 格式映射

V4L2 格式 RGA 格式
V4L2_PIX_FMT_RGB565 RK_FORMAT_RGB_565
V4L2_PIX_FMT_RGB24 RK_FORMAT_RGB_888
V4L2_PIX_FMT_BGR24 RK_FORMAT_BGR_888
V4L2_PIX_FMT_ARGB32 RK_FORMAT_ARGB_8888
V4L2_PIX_FMT_ABGR32 RK_FORMAT_ABGR_8888
V4L2_PIX_FMT_NV12 RK_FORMAT_YCbCr_420_SP
V4L2_PIX_FMT_NV21 RK_FORMAT_YCrCb_420_SP
V4L2_PIX_FMT_YUV420 RK_FORMAT_YCbCr_420_P
V4L2_PIX_FMT_YVU420 RK_FORMAT_YCrCb_420_P
V4L2_PIX_FMT_NV16 RK_FORMAT_YCbCr_422_SP
V4L2_PIX_FMT_NV61 RK_FORMAT_YCrCb_422_SP
V4L2_PIX_FMT_YUYV RK_FORMAT_YUYV_422
V4L2_PIX_FMT_UYVY RK_FORMAT_UYVY_422

RGA 到 V4L2 格式映射

RGA 格式 V4L2 格式
RK_FORMAT_RGB_565 V4L2_PIX_FMT_RGB565
RK_FORMAT_RGB_888 V4L2_PIX_FMT_RGB24
RK_FORMAT_BGR_888 V4L2_PIX_FMT_BGR24
RK_FORMAT_ARGB_8888 V4L2_PIX_FMT_ARGB32
RK_FORMAT_ABGR_8888 V4L2_PIX_FMT_ABGR32
RK_FORMAT_YCbCr_420_SP V4L2_PIX_FMT_NV12
RK_FORMAT_YCrCb_420_SP V4L2_PIX_FMT_NV21
RK_FORMAT_YCbCr_420_P V4L2_PIX_FMT_YUV420
RK_FORMAT_YCrCb_420_P V4L2_PIX_FMT_YVU420
RK_FORMAT_YCbCr_422_SP V4L2_PIX_FMT_NV16
RK_FORMAT_YCrCb_422_SP V4L2_PIX_FMT_NV61
RK_FORMAT_YUYV_422 V4L2_PIX_FMT_YUYV
RK_FORMAT_UYVY_422 V4L2_PIX_FMT_UYVY

典型使用场景

场景 1: V4L2 到 RGA 格式转换

// V4L2 相机输出 NV12 格式
uint32_t v4l2_fmt = V4L2_PIX_FMT_NV12;

// 转换为 RGA 格式
int rga_fmt = convertV4L2toRGAFormat(v4l2_fmt);

if (rga_fmt != -1) {
    // 使用 RGA 处理
    rga_buffer_t buffer = wrapbuffer_fd(fd, 1920, 1080, rga_fmt);
}

场景 2: RGA 到 DRM 格式转换

// RGA 处理输出 RGBA8888
int rga_fmt = RK_FORMAT_RGBA_8888;

// 转换为 DRM 格式(注意字节序)
uint32_t drm_fmt = convertRGAtoDrmFormat(rga_fmt);

if (drm_fmt != -1) {
    // 创建 DRM fb
    uint32_t fb_id = create_drm_fb(drm_fd, dma_fd, 1920, 1080, drm_fmt);
}

场景 3: DRM 到 V4L2 格式转换(通过 RGA)

// DRM 格式
uint32_t drm_fmt = DRM_FORMAT_NV12;

// DRM → RGA → V4L2
int rga_fmt = convertDRMtoRGAFormat(drm_fmt);
uint32_t v4l2_fmt = convertRGAtoV4L2Format(rga_fmt);

if (v4l2_fmt != -1) {
    printf("V4L2 format: 0x%x\n", v4l2_fmt);
}

场景 4: 字节序处理

// RGA RGBA8888 输出(注意字节序)
int rga_fmt = RK_FORMAT_RGBA_8888;
uint32_t drm_fmt = convertRGAtoDrmFormat(rga_fmt);

// DRM 格式是 ABGR8888(因为 RGA 的 RGBA 对应 DRM 的 ABGR)
printf("DRM format: 0x%x\n", drm_fmt);  // DRM_FORMAT_ABGR8888

场景 5: 格式验证

// 检查格式是否支持
uint32_t v4l2_fmt = V4L2_PIX_FMT_NV12;
int rga_fmt = convertV4L2toRGAFormat(v4l2_fmt);

if (rga_fmt == -1) {
    printf("Format not supported by RGA\n");
} else {
    printf("RGA format: %d\n", rga_fmt);
}

注意事项

  1. 字节序差异: RGA 和 DRM 字节序相反,注意转换
  2. 返回值检查: 未找到对应格式返回 -1
  3. 全局映射表: 使用 static const unordered_map 作为查找表
  4. 线程安全: 函数是线程安全的
  5. 格式支持: 只支持常用格式,不支持所有格式
  6. RGA SDK: 需要 RGA SDK 支持

相关文档


参考资料

主页

API 文档

DMA 模块

DRM 模块

NET 模块

V4L2 模块

V4L2Param 模块

RGA 模块

MPP 模块

Sys 模块

Mouse 模块

Utils 模块

Clone this wiki locally