《OKT536N-C测评 》之V4L2控制UVC摄像头显示方案
-
《OKT536N-C测评 》之V4L2控制UVC摄像头显示方案
硬件平台
T536芯片配置:
- CPU:1.6GHz,集成四核 Cortex A55、64 位玄铁 E907 RISC V MCU
- 显示:LinuxFB支
- 关键限制:无Mali GPU,无OpenGL硬件加速
测试硬件:720P USB摄像头 + 1080P USB摄像头,通过USB Hub连接。
技术架构
V4L2核心实现
基于V4L2接口的UVC摄像头控制,关键代码实现:
1. 设备初始化与兼容性处理
// 打开设备 v4l2Capture1->openDevice(VIDEO_DEVICE_1, false); // 查询基本信息 v4l2Capture1->ioctlQueryCapability(); v4l2Capture1->ioctlEnumInput(); v4l2Capture1->ioctlSetInput(0); // 设置流参数和格式 v4l2Capture1->ioctlSetStreamParm(2, 25); v4l2Capture1->ioctlSetStreamFmt(V4L2_PIX_FMT_YUYV, FRAME_WIDTH, FRAME_HEIGHT); // 申请缓冲区并映射到用户空间 v4l2Capture1->ioctlRequestBuffers(); return v4l2Capture1->ioctlMmapBuffers();
2. Select机制异步采集
// 双缓冲避免数据竞争 uchar *curRgbFrameBuf = selectRgbFrameBuf; fd_set fds; FD_ZERO(&fds); FD_SET(cameraFd, &fds); while(isStreamOn) { // select等待数据就绪 ret = select(cameraFd+1, &tmp_fds, NULL, NULL, &tv); if(ret > 0) { // 切换双缓冲 curRgbFrameBuf = (curRgbFrameBuf == selectRgbFrameBuf2) ? selectRgbFrameBuf : selectRgbFrameBuf2; // 取帧并转换格式 if(ioctlDequeueBuffers(curRgbFrameBuf, originFrameAddr)) { emit captureRgb24FrameSig(curRgbFrameBuf); } } }
3. 内存映射与缓冲区管理
for(int i = 0; i < BUFFER_COUNT; i++) { // 查询内核缓冲区信息 ioctl(cameraFd, VIDIOC_QUERYBUF, &vbuffer); // mmap映射到用户空间 bufferMmapPtr[i].addr = (unsigned char *)mmap(NULL, vbuffer.length, PROT_READ, MAP_SHARED, cameraFd, vbuffer.m.offset); if(bufferMmapPtr[i].addr == MAP_FAILED) { printf("mmap failed.\n"); return false; } }
Qt显示框架
因为没有Mali GPU,无OpenGL硬件加速,软件渲染方案
// 创建视频显示组件 videoOutput1 = new PixmapWidget(this); videoOutput1->setMinimumSize(480, 360); // 信号连接:RGB24数据到Qt显示 connect(v4l2Capture1, &V4L2Capture::captureRgb24FrameSig, this, [this](uchar *rgb24Frame){ QImage selectImage1(rgb24Frame, FRAME_WIDTH, FRAME_HEIGHT, FRAME_WIDTH*3, QImage::Format_RGB888); videoOutput1->setPixmap(QPixmap::fromImage(selectImage1)); videoOutput1->update(); });
界面展示
[UI界面截图]
**[实时视频显示效果]**展示640x480分辨率下的实时视频流效果,YUYV格式转RGB24显示
测试结果
1. USB带宽限制,这里尝试两路UVC摄像头同时显示,但不行
- 问题:URB错误-28,
Failed to submit URB 0 (-28)
- 解决:降低分辨率,使用MJPEG压缩,
modprobe uvcvideo quirks=128
3. CPU占用率
抓拍功能
**[抓拍照片样例]**展示保存的PNG格式截图,640x480分辨率
抓拍实现代码
void saveImage1BtnClickedSlot() { isSaveImage1 = true; // 设置保存标志 } // 在信号处理中实际保存 if(isSaveImage1) { isSaveImage1 = false; selectImage1.save("camera1_" + QTime::currentTime().toString("HHmmsszzz") + ".png", nullptr, 100); }
核心优势与限制
优势:
- V4L2标准接口,UVC设备兼容性好
- Select机制多线程处理,响应及时
- 代码结构清晰,易于维护和扩展
限制:
- USB 2.0带宽限制,不能同时两路UVC显示
- 无GPU加速,CPU软件渲染性能有限
- 640x480以上分辨率CPU占用率超过20%
总体而言,OKT536N-C在成本控制和基础性能之间找到了很好的平衡点,特别适合对成本敏感但要求稳定可靠的工业应用场景。而且其实因为我这边只有UVC摄像头,没有MIPI CSI摄像头,所以没办法测试和评价,MIPI CSI摄像头是支持多路的,这里的USB2.0本身也不是用作两路UVC摄像头的。
Copyright © 2024 深圳全志在线有限公司 粤ICP备2021084185号 粤公网安备44030502007680号