RK3566 Android 11上UVC摄像头4K预览的完整解决方案最近在RK3566开发板上调试一款支持4K的UVC摄像头时遇到了一个奇怪的问题在PC上可以正常识别并使用3840x2160分辨率但在Android应用层却只能获取到最高1920x1080的预览分辨率列表。经过一周的深入排查终于找到了问题根源并成功解决了这个限制。本文将详细记录整个排查过程和技术细节。1. 问题现象与初步排查当我们在RK3566开发板上连接这款UVC摄像头后使用标准的Android Camera API获取支持的预览分辨率列表Camera cam Camera.open(CAMERA_ID); Camera.Parameters param cam.getParameters(); ListCamera.Size sizes param.getSupportedPreviewSizes();打印出来的结果令人失望D/startPreview: support preview 640x360 D/startPreview: support preview 640x480 D/startPreview: support preview 960x540 D/startPreview: support preview 800x600 D/startPreview: support preview 1280x720 D/startPreview: support preview 1280x960 D/startPreview: support preview 1920x1080 D/startPreview: support preview 1600x1200而同样的摄像头在PC上无论是Linux还是Windows都能正常识别3840x2160分辨率。这显然不是硬件或驱动层面的问题而是Android系统对UVC摄像头的某种限制。2. 底层验证使用v4l2工具为了确认底层驱动是否真的支持4K分辨率我们首先使用v4l2工具进行验证# 列出所有视频设备 ls /dev/video* # 查看设备信息 v4l2-ctl --list-devices # 查看指定设备支持的分辨率 v4l2-ctl -d /dev/video14 --list-framesizesYUYV输出结果显示设备确实支持3840x2160分辨率Size: Discrete 2048x1536 Size: Discrete 640x480 Size: Discrete 3840x2160 Size: Discrete 2592x1944 Size: Discrete 2688x1512 Size: Discrete 1920x1080 Size: Discrete 1600x1200 Size: Discrete 1280x960 Size: Discrete 1280x720 Size: Discrete 960x540 Size: Discrete 800x600 Size: Discrete 640x360这表明从硬件到Linux驱动层面4K分辨率都是完全支持的问题出在Android的Camera HAL层或Framework层。3. Android Camera架构分析Android的Camera系统架构相当复杂主要涉及以下几个关键部分层级主要组件功能描述应用层Camera API提供应用程序调用的接口Framework层CameraService管理所有Camera设备HAL层Camera HAL硬件抽象层与具体硬件交互驱动层V4L2驱动直接控制摄像头硬件在RK3566平台上相关源码主要分布在以下目录frameworks/base/core/java/android/hardware/Camera.java frameworks/base/core/jni/android_hardware_Camera.cpp frameworks/av/camera/ hardware/rockchip/camera hardware/interfaces/camera/4. 关键配置文件定位经过层层排查最终发现问题出在/vendor/etc/external_camera_config.xml这个配置文件中。这个文件定义了外部摄像头如UVC摄像头的各种参数限制包括支持的分辨率列表。原始配置文件中缺少3840x2160分辨率的定义FpsList !-- 其他分辨率定义 -- Limit width1920 height1080 fpsBound30.0 / !-- 缺少3840x2160的定义 -- /FpsList我们需要在FpsList节点中添加对应的分辨率限制Limit width3840 height2160 fpsBound30.0 /注意添加新分辨率时需要确保width/height是递增的fpsBound是递减的否则可能导致配置无效。5. RGA限制问题解决修改配置文件后我们遇到了另一个问题系统日志中频繁出现以下错误(dst_width RGA_VIRTUAL_W) || (dst_height RGA_VIRTUAL_H), switch to arm这是因为RK平台的RGARaster Graphic Acceleration硬件对处理尺寸有限制。我们需要修改相关定义// 修改前 #define RGA_ACTIVE_W (2048) #define RGA_VIRTUAL_W (4096) #define RGA_ACTIVE_H (2048) #define RGA_VIRTUAL_H (2048) // 修改后 #define RGA_ACTIVE_W (4096) #define RGA_VIRTUAL_W (4096) #define RGA_ACTIVE_H (4096) #define RGA_VIRTUAL_H (4096)这个修改位于hardware/interfaces/camera/device/3.4/default/RgaCropScale.cpp文件中。6. Framework层限制解除除了HAL层的修改Framework层也有对预览分辨率的硬编码限制。我们需要修改// 修改前 static const unsigned int MAX_PREVIEW_WIDTH 1920; static const unsigned int MAX_PREVIEW_HEIGHT 1920; // 修改后 static const unsigned int MAX_PREVIEW_WIDTH 3840; static const unsigned int MAX_PREVIEW_HEIGHT 2160;这个修改位于frameworks/av/services/camera/libcameraservice/api1/client2/Parameters.h文件中。7. 编译与验证完成所有修改后需要重新编译相关模块并推送到设备# 编译Camera HAL mmm hardware/interfaces/camera/device/3.4/default/ # 编译CameraService mmm frameworks/av/services/camera/libcameraservice/ # 推送更新到设备 adb push out/target/product/rk3566_r/vendor/lib64/hw/camera.rk30board.so /vendor/lib64/hw/ adb push out/target/product/rk3566_r/system/lib64/libcameraservice.so /system/lib64/重启设备后再次获取支持的预览分辨率列表现在应该能看到3840x2160分辨率了。8. 性能优化建议实现4K预览后还需要注意以下性能优化点内存占用4K分辨率需要更大的缓冲区建议增加NumVideoBuffers数量CPU负载高分辨率处理会增加CPU负担可能需要优化算法带宽限制USB2.0可能无法稳定传输4K30fps建议使用USB3.0接口可以在external_camera_config.xml中调整以下参数MaxJpegBufferSize bytes24883200/ NumVideoBuffers count4/ NumStillBuffers count2/9. 常见问题排查在实际项目中可能会遇到以下问题分辨率不生效检查配置文件语法是否正确特别是width/height的递增顺序预览卡顿尝试降低fpsBound值或增加缓冲区数量图像变形检查Orientation参数是否正确设置权限问题确保应用有正确的Camera权限10. 总结与经验分享这次排查过程让我深刻理解了Android Camera系统的复杂性。几个关键经验从底层开始验证先用v4l2确认硬件能力避免在错误的方向上浪费时间理解架构设计Android Camera是多层架构问题可能出现在任何一层注意版本差异不同Android版本和芯片平台可能有不同的实现细节日志是关键仔细分析系统日志往往能快速定位问题最终通过修改HAL配置、调整RGA参数和解除Framework限制我们成功在RK3566上实现了UVC摄像头的4K预览功能。这个解决方案不仅适用于RK3566对其他Rockchip平台也有参考价值。