Rockchip_Quick_Start_Linux_USB_Gadget_CN.pdf
Rockchip_Trouble_Shooting_Linux4.19_USB_Gadget_UVC_CN.pdf
uvc_app 代码
rk3568_linux/external/uvc_app$ tree
.
├── camera_uvc.c
├── CMakeLists.txt
├── main.c
├── readme.md
├── uvc
│ ├── drm.c
│ ├── drm.h
│ ├── mpi_enc.c
│ ├── mpi_enc.h
│ ├── mpp_common.h
│ ├── rk_type.h
│ ├── uevent.c
│ ├── uevent.h
│ ├── uvc_control.c
│ ├── uvc_control.h
│ ├── uvc_encode.cpp
│ ├── uvc_encode.h
│ ├── uvc-gadget.c
│ ├── uvc-gadget.h
│ ├── uvc_video.cpp
│ ├── uvc_video.h
│ ├── yuv.c
│ └── yuv.h
└── uvc_config.sh
Cmake
cmake_minimum_required(VERSION 2.8.0 FATAL_ERROR)
PROJECT(uvc_app)
include_directories(uvc)
set(LIB_SOURCE
uvc/uvc-gadget.c
uvc/uvc_video.cpp
uvc/yuv.c
uvc/uvc_control.c
uvc/uvc_encode.cpp
uvc/mpi_enc.c
uvc/uevent.c
uvc/drm.c
)
add_library(rkuvc SHARED ${LIB_SOURCE})
target_link_libraries(rkuvc pthread drm rockchip_mpp)
set(SOURCE
main.c
${LIB_SOURCE}
)
ADD_EXECUTABLE(uvc_app ${SOURCE})
target_link_libraries(uvc_app pthread drm rockchip_mpp)
set(CAMERA_SOURCE
camera_uvc.c
${LIB_SOURCE}
)
ADD_EXECUTABLE(camera_uvc ${CAMERA_SOURCE})
target_link_libraries(camera_uvc rkisp rkisp_api pthread drm rockchip_mpp)
install(TARGETS rkuvc DESTINATION lib)
install(DIRECTORY ./uvc DESTINATION include
FILES_MATCHING PATTERN "*.h")
install(TARGETS uvc_app DESTINATION bin)
install(DIRECTORY . DESTINATION bin
FILES_MATCHING PATTERN "*.sh"
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
GROUP_READ GROUP_WRITE GROUP_EXECUTE
WORLD_READ WORLD_WRITE WORLD_EXECUTE)
install(TARGETS camera_uvc DESTINATION bin)
rkisp rkisp_api
RKISP(Rockchip ISP 驱动)
- 定义:RKISP 是 Rockchip 芯片上集成的硬件图像信号处理单元(ISP)的驱动模块,负责对摄像头采集的原始图像数据进行预处理,比如去噪、自动曝光、自动白平衡、色彩校正等。
- 作用:ISP 硬件加速图像处理,提高图像质量并降低 CPU 负担。RKISP 驱动提供接口将摄像头采集的 raw 数据转换为可用的图像数据流。
- 硬件依赖:必须有 Rockchip SoC 集成的 ISP 硬件才支持。没有 ISP 硬件,RKISP 驱动及功能无法使用。
RKISP_API(RKISP 软件接口库)
- 定义:RKISP_API 是一套面向应用层或中间件的软件接口库,封装了对 RKISP 驱动的调用和操作,方便应用程序控制 ISP 功能,比如启动/停止 ISP,设置参数等。
- 作用:提供简洁的接口供摄像头应用或多媒体框架调用 ISP 功能。
- 硬件依赖:同样需要搭配带有 ISP 硬件的芯片使用。
芯片支持情况
芯片型号 | ISP 支持情况 | 备注 |
---|---|---|
RK3568 | 支持硬件 ISP | 具备高性能多功能 ISP,支持多路摄像头输入和高质量图像处理。适合中高端应用。 |
RV1106 | 支持硬件 ISP | 针对安防/智能摄像头优化,集成低功耗 ISP,支持 RKISP 驱动。 |
RK3506 | 不支持硬件 ISP | 主要面向低功耗音视频处理,无集成 ISP,需依赖外部 ISP 或软件处理。 |
rockchip_mpp
MPP 全称是 Media Processing Platform,是 Rockchip 提供的一套多媒体处理框架,主要用于视频编解码、图像处理等功能。
MPP 依赖于芯片内置的专用硬件多媒体加速器(比如视频编码器、解码器、图像处理单元)
芯片型号 | MPP 支持情况 | 备注 |
---|---|---|
RK3568 | 完整支持 | 内置强大多媒体硬件加速单元,支持视频编码、解码、图像处理。适合中高端多媒体应用。 |
RV1106 | 支持 | 具备低功耗多媒体硬件加速,针对智能摄像头及安防场景优化,支持基本的编码解码功能。 |
RK3506 | 不支持或支持有限 | 主要面向低功耗音视频处理,缺乏完整硬件多媒体加速单元,MPP 硬件加速功能有限或无。 |
drm
Direct Rendering Manager (DRM) 是 Linux 内核中的一个图形子系统,负责管理 GPU、显示控制器、帧缓冲等硬件资源。
需要硬件支持,因为 DRM 是直接管理图形硬件的
芯片型号 | DRM 支持情况 | 备注 |
---|---|---|
RK3568 | 完整支持 | 内置 GPU(Mali),Linux 下有成熟的 DRM 驱动支持,支持硬件加速和多显示输出。 |
RV1106 | 部分支持 | 集成较简单的图形处理单元,Linux DRM 支持有限,主要面向低功耗应用,如智能摄像头。 |
RK3506 | 支持较弱或无 | 图形硬件较弱或缺少独立 GPU,Linux DRM 驱动支持有限,适合轻量级显示需求。 |
main.c
#include <stdio.h>
#include <unistd.h>
#include "uvc_control.h"
#include "uvc_video.h"
#include "mpi_enc.h"
#include "drm.h"
int main(int argc, char* argv[])
{
int fd; // DRM 设备文件描述符
int ret; // 函数返回值存储变量
unsigned int handle; // DRM 申请的缓冲句柄
char *buffer; // 指向映射缓冲区的指针
int handle_fd; // DRM 缓冲的文件描述符
size_t size; // 缓冲大小(字节)
int width, height; // 输入的图像宽高
int y, uv; // 用于初始化缓冲区的偏移和大小计算
int extra_cnt = 0; // 额外计数器,用于传递给读取函数
uint32_t flags = 0; // 控制标志,传递给 uvc_control_run
// 检查命令行参数,必须传入宽和高两个参数
if (argc != 3) {
printf("Usage: uvc_app width height\n");
printf("e.g. uvc_app 640 480\n");
return -1;
}
// 解析宽高
width = atoi(argv[1]);
height = atoi(argv[2]);
if (width == 0 || height == 0) {
printf("Usage: uvc_app width height\n");
printf("e.g. uvc_app 640 480\n");
return -1;
}
// 打开 DRM 设备,返回文件描述符
fd = drm_open();
if (fd < 0)
return -1;
// 计算缓冲区大小(YUV420格式,宽高对齐16字节)
size = MPP_ALIGN(width, 16) * MPP_ALIGN(height, 16) * 3 / 2;
// 申请 DRM 缓冲区,size为大小,16为对齐,handle存储缓冲区句柄
ret = drm_alloc(fd, size, 16, &handle, 0);
if (ret)
return -1;
// 根据缓冲句柄获取文件描述符,用于映射和传递缓冲
ret = drm_handle_to_fd(fd, handle, &handle_fd, 0);
if (ret)
return -1;
// 映射缓冲区到用户空间,返回指向映射地址的指针
buffer = (char*)drm_map_buffer(fd, handle, size);
if (!buffer) {
printf("drm map buffer fail.\n");
return -1;
}
// 初始化buffer内容,下面部分根据宽高计算Y、UV分量的大小与偏移
y = width * height / 4;
memset(buffer, 128, y); // 设置buffer前1/4部分为128
memset(buffer + y, 64, y); // 后续部分设置不同的固定值(似乎是测试用)
memset(buffer + y * 2, 128, y);
memset(buffer + y * 3, 192, y);
uv = width * height / 8;
memset(buffer + y * 4, 0, uv);
memset(buffer + y * 4 + uv, 64, uv);
memset(buffer + y * 4 + uv * 2, 128, uv);
memset(buffer + y * 4 + uv * 3, 192, uv);
// 启动UVC控制线程,flags表示运行模式(这里是只运行一次)
flags = UVC_CONTROL_LOOP_ONCE;
uvc_control_run(flags);
// 主循环不断读取摄像头数据,处理并传递给UVC协议层发送
while(1) {
extra_cnt++;
// 读取摄像头数据填充buffer,handle_fd为缓冲文件描述符,size是读取大小
// extra_cnt和sizeof(extra_cnt)用于传递额外参数,具体含义依赖于实现
uvc_read_camera_buffer(buffer, handle_fd, size, &extra_cnt, sizeof(extra_cnt));
usleep(30000); // 延时约30ms,实现约30帧每秒的采样频率
}
// 等待UVC控制线程退出(理论上此处不会执行到,因为死循环)
uvc_control_join(flags);
// 清理资源,解除映射,释放缓冲,关闭设备
drm_unmap_buffer(buffer, size);
drm_free(fd, handle);
drm_close(fd);
return 0;
}
- 该程序通过 DRM 接口申请、映射缓冲区
- 使用 UVC 控制模块开启USB视频设备
- 在循环中持续读取摄像头数据放入缓冲,并通过 UVC 协议层发送出去
- 实现了一个基于 DRM 与 UVC 的简单USB摄像头采集发送示例
RV1106 是否支持 uvc_app
- RV1106 是支持视频处理和ISP的,但其 DRM 支持较弱或者不完整,主要聚焦于 ISP 和硬件编解码。
- 目前 Rockchip 官方对 RV1106 的视频框架主要是基于 ISP API 和硬件编码接口,而不是完整的 DRM/KMS 框架。
- 因此,这段程序中大量依赖 DRM 缓冲管理的部分在 RV1106 上可能无法直接运行,需要移植或者改用其他接口(比如直接使用 V4L2、ISP API)。
DRM + MPP 与 V4L2(使用虚拟图像填充) 模式的对比表
对比项 | DRM + MPP 模式 | V4L2 模式(虚拟图像填充) |
---|---|---|
图像来源 | 手动填充 buffer,走 DRM 分配显存,结合 MPP 编码 | 构造虚拟帧内存填充(如 YUYV 数据),写入 buffer |
内存分配方式 | 使用 drm_alloc() 获取 DMA 可映射显存 |
使用 malloc() 或 mmap 虚拟内存 |
编码流程 | 借助 MPP 硬件编解码库实现,如 H.264/MJPEG 编码 | 可选择软件/硬件编码,也可原始格式(如 YUYV)输出 |
硬件依赖 | 依赖 DRM 显存接口 + MPP 硬件(RK 系平台支持) | 只需标准 V4L2 支持(可用于虚拟摄像头模拟) |
典型用途 | 真实摄像头数据采集 + 编码推流,资源占用更低 | 无需摄像头,测试图像输出 / 自动化验证 |
开发复杂度 | 较高,需要初始化 DRM 和 MPP | 较低,逻辑简单,易于快速验证 |
可移植性 | 受限于 DRM 和 MPP API,特定平台依赖较重 | 高,通用 Linux 上的 V4L2 框架即可 |
UVC集成 | 通常需要适配 buffer FD 与 UVC 推送接口 | 可直接 read() 或自定义 uvc_read_camera_buffer() 推送 |
DRM + MPP 与 V4L2(虚拟图像)性能对比表
DRM + MPP 与 V4L2(虚拟图像)性能对比表
性能项 | DRM + MPP 模式 | V4L2 模式(虚拟图像填充) |
---|---|---|
图像生成速度 | 较快(直接填充显存,内存带宽高) | 快(CPU 填充,可能略慢于 DRM) |
编码速度 | 高(使用 MPP 硬件加速,支持 H.264/MJPEG) | 低(通常为软件编码或无编码) |
CPU 占用 | 低(编码由 MPP 处理) | 较高(图像构造和处理全由 CPU 执行) |
内存占用 | 低(显存管理高效,零拷贝路径) | 较高(内存复制或分配不够优化) |
实时性能 | 优(适合 30fps、60fps 视频) | 一般(依赖 CPU 性能和调度) |
功耗表现 | 好(利用硬件引擎,CPU 负担小) | 差(高 CPU 活动,尤其在 ARM SoC 上) |
系统负载稳定性 | 高(Mature Path) | 中(需小心内存泄漏、调度影响) |