测试 Demo
打开相机的参数
override fun getCameraRequest(): CameraRequest {
return CameraRequest.Builder()
.setPreviewWidth(1920)
.setPreviewHeight(1080)
.setRenderMode(CameraRequest.RenderMode.NORMAL)//返回NV21格式
.setDefaultRotateType(RotateType.ANGLE_0)//旋转角度
.setExposureNum(11)
.setPreviewFps(10)
.setExposureMode(CameraRequest.ExposureMode.EXPOSURE_MANUAL)
.setPreviewFormat(CameraRequest.PreviewFormat.FORMAT_MJPEG)
.setAspectRatioShow(true)
.setCaptureRawImage(false)
.setRawPreviewData(false)
.create()
}
报错日志
2025-10-22 15:43:33.619 0-0 usb 2-1 kernel W usbfs: process 2572 (USBMonitor) did not claim interface 0 before use
2025-10-22 15:43:33.660 0-0 usb 2-1 kernel W usbfs: process 2576 (camera-17611190) did not claim interface 0 before use
2025-10-22 15:43:34.020 0-0 usb 2-1 kernel W Process 2577 (camera-17611190) called USBDEVFS_CLEAR_HALT for active endpoint 0x81
2025-10-22 15:43:34.099 2516-2579 libUVCCamera com.jiangdg.ausbc W [2579*UVCPreview.cpp:128:get_frame]:allocate new frame
2025-10-22 15:43:34.100 2516-2578 libUVCCamera com.jiangdg.ausbc W [2578*UVCPreview.cpp:128:get_frame]:allocate new frame
2025-10-22 15:43:34.131 2516-2579 libUVCCamera com.jiangdg.ausbc W [2579*UVCPreview.cpp:128:get_frame]:allocate new frame
2025-10-22 15:43:34.159 2516-2579 libUVCCamera com.jiangdg.ausbc W [2579*UVCPreview.cpp:128:get_frame]:allocate new frame
2025-10-22 15:43:34.185 2516-2578 ion com.jiangdg.ausbc E ioctl c0044901 failed with code -1: Inappropriate ioctl for device
2025-10-22 15:43:34.191 2516-2579 libUVCCamera com.jiangdg.ausbc W [2579*UVCPreview.cpp:128:get_frame]:allocate new frame
2025-10-22 15:43:34.199 2516-2578 libUVCCamera com.jiangdg.ausbc W [2578*UVCPreview.cpp:128:get_frame]:allocate new frame
2025-10-22 15:43:34.279 2516-2579 libUVCCamera com.jiangdg.ausbc W [2579*UVCPreview.cpp:128:get_frame]:allocate new frame
2025-10-22 15:43:34.375 2516-2579 libUVCCamera com.jiangdg.ausbc W [2579*UVCPreview.cpp:128:get_frame]:allocate new frame
2025-10-22 15:43:37.755 2516-2579 libUVCCamera com.jiangdg.ausbc W [2579*UVCPreview.cpp:128:get_frame]:allocate new frame
2025-10-22 15:43:40.648 0-0 usb 2-1 kernel W Process 2577 (camera-17611190) called USBDEVFS_CLEAR_HALT for active endpoint 0x81
2025-10-22 15:45:33.056 0-0 usb 2-1 kernel W Process 2577 (camera-17611190) called USBDEVFS_CLEAR_HALT for active endpoint 0x81
2025-10-22 15:45:37.736 0-0 usb 2-1 kernel W Process 2577 (camera-17611190) called USBDEVFS_CLEAR_HALT for active endpoint 0x81
2025-10-22 15:49:00.220 0-0 usb 2-1 kernel W Process 2577 (camera-17611190) called USBDEVFS_CLEAR_HALT for active endpoint 0x81
2025-10-22 15:49:35.812 0-0 usb 2-1 kernel W Process 2577 (camera-17611190) called USBDEVFS_CLEAR_HALT for active endpoint 0x81
日志解析-chatgpt
2025-10-22 15:43:33.619 0-0 usb 2-1 kernel W usbfs: process 2572 (USBMonitor) did not claim interface 0 before use
# USBMonitor进程访问UVC设备接口0之前没有调用claim接口。
# 警告级别,不会致命,但说明USB接口使用不够规范,可能导致后续数据传输异常。
2025-10-22 15:43:33.660 0-0 usb 2-1 kernel W usbfs: process 2576 (camera-17611190) did not claim interface 0 before use
# camera进程访问UVC设备接口0之前也没有claim。
# 与上一条类似,提示USB访问逻辑不够严格。
2025-10-22 15:43:34.020 0-0 usb 2-1 kernel W Process 2577 (camera-17611190) called USBDEVFS_CLEAR_HALT for active endpoint 0x81
# USB端点0x81发生STALL(数据传输中断),应用调用CLEAR_HALT尝试恢复。
# 多数出现在高带宽数据传输或长时间采集时,说明USB压力较大。
2025-10-22 15:43:34.099 2516-2579 libUVCCamera com.jiangdg.ausbc W [2579*UVCPreview.cpp:128:get_frame]:allocate new frame
2025-10-22 15:43:34.100 2516-2578 libUVCCamera com.jiangdg.ausbc W [2578*UVCPreview.cpp:128:get_frame]:allocate new frame
2025-10-22 15:43:34.131 2516-2579 libUVCCamera com.jiangdg.ausbc W [2579*UVCPreview.cpp:128:get_frame]:allocate new frame
2025-10-22 15:43:34.159 2516-2579 libUVCCamera com.jiangdg.ausbc W [2579*UVCPreview.cpp:128:get_frame]:allocate new frame
# libUVCCamera为每一帧分配新的缓冲区。
# 长时间高分辨率预览容易导致ION/CMA内存压力累积。
2025-10-22 15:43:34.185 2516-2578 ion com.jiangdg.ausbc E ioctl c0044901 failed with code -1: Inappropriate ioctl for device
# 核心错误,ION缓冲区分配或操作失败。
# 原因可能:
# 1. 内核IOCTL命令不匹配或权限不足
# 2. ION heap或CMA内存不足
# 这个错误会直接影响UVC预览稳定性,可能导致帧丢失或应用崩溃。
2025-10-22 15:43:34.191 2516-2579 libUVCCamera com.jiangdg.ausbc W [2579*UVCPreview.cpp:128:get_frame]:allocate new frame
2025-10-22 15:43:34.199 2516-2578 libUVCCamera com.jiangdg.ausbc W [2578*UVCPreview.cpp:128:get_frame]:allocate new frame
2025-10-22 15:43:34.279 2516-2579 libUVCCamera com.jiangdg.ausbc W [2579*UVCPreview.cpp:128:get_frame]:allocate new frame
2025-10-22 15:43:34.375 2516-2579 libUVCCamera com.jiangdg.ausbc W [2579*UVCPreview.cpp:128:get_frame]:allocate new frame
# 持续分配缓冲区,说明内存压力累积且没有复用缓冲池。
# 长时间运行可能触发OOM或ION失败。
2025-10-22 15:43:37.755 2516-2579 libUVCCamera com.jiangdg.ausbc W [2579*UVCPreview.cpp:128:get_frame]:allocate new frame
# 继续分配新帧缓冲,长时间采集仍在增加内存压力。
2025-10-22 15:43:40.648 0-0 usb 2-1 kernel W Process 2577 (camera-17611190) called USBDEVFS_CLEAR_HALT for active endpoint 0x81
2025-10-22 15:45:33.056 0-0 usb 2-1 kernel W Process 2577 (camera-17611190) called USBDEVFS_CLEAR_HALT for active endpoint 0x81
2025-10-22 15:45:37.736 0-0 usb 2-1 kernel W Process 2577 (camera-17611190) called USBDEVFS_CLEAR_HALT for active endpoint 0x81
2025-10-22 15:49:00.220 0-0 usb 2-1 kernel W Process 2577 (camera-17611190) called USBDEVFS_CLEAR_HALT for active endpoint 0x81
2025-10-22 15:49:35.812 0-0 usb 2-1 kernel W Process 2577 (camera-17611190) called USBDEVFS_CLEAR_HALT for active endpoint 0x81
# USB端点0x81持续STALL并清除。
# 频繁出现表示USB带宽不足或者主机/摄像头驱动无法稳定传输大量数据。
什么是ION内存
ION 内存是 Android 系统中专门用于多媒体和图形处理的内存分配机制。它的全称是 “Ion Memory Allocator”,由 Google 在 Android 4.x 开始引入,用于解决不同硬件模块之间共享物理内存的效率问题
- 解决连续性问题(连续内存) 视频流、图形渲染(比如 SurfaceFlinger 负责的)都需要一大块连续的内存。想象一下,如果一个视频帧的数据被分散存储在内存的各个角落,硬件(如视频解码器)就得花大量时间跳来跳去读取数据,效率极低。
ION 的作用: 它保证分配给你的内存是物理上连续的(或至少在地址空间上看起来是连续的),这样硬件就可以用最快的方式(DMA,直接内存访问)一次性读取或写入数据。
- 解决共享和安全问题(零拷贝) 在 Android 中,一个摄像头捕获的帧可能需要被多个组件使用:
- 摄像头驱动(写入数据)
- GPU(渲染预览)
- 视频编码器(压缩数据)
如果使用标准内存,每次组件切换都需要把数据从一个地方拷贝到另一个地方,这非常消耗 CPU 和时间(这就是“零拷贝”技术要解决的问题)。
ION 的作用: 它提供内存句柄(Handle)和文件描述符(FD)。组件 A 申请了一块 ION 内存,然后把这个“通行证”(Handle/FD)交给组件 B。组件 B 可以通过这个通行证直接访问同一块物理内存,无需拷贝。这叫零拷贝 (Zero-Copy),极大地提升了效率。
修改ION 内存大小
rockchip_defconfig
CONFIG_CMA_SIZE_MBYTES=64 # 将 16 改为 64 或更高
CONFIG_CMA_SIZE_SEL_MBYTES=y
dts
&reserved_memory {
linux,cma {
compatible = "shared-dma-pool";
inactive;
reusable;
reg = <0x0 0x10000000 0x0 0x04000000>; // 64MB
linux,cma-default;
};
假设系统参数:
- USB 相机分辨率:1920×1080
- 像素格式:YUYV (2 bytes/pixel)
- 帧率:30 FPS
- 双缓冲 (preview + capture)
单帧大小:1920 * 1080 * 2 = 4147200 bytes ≈ 4 MB 双缓冲:4 MB * 2 = 8 MB CMA 预留:8 MB * 2 = 16 MB(留一些余量)
NV21(YUV420SP)模式
1920 × 1080 × 1.5 ≈ 3.1 MB / 帧 双缓冲:3.1 MB × 2 ≈ 6.2 MB
修改后查看CMA内存方法
# 修改前
1|rk3568_r:/ $ cat proc/meminfo
MemTotal: 2004632 kB
CmaTotal: 8192 kB
CmaAllocated: 1976 kB
CmaReleased: 6216 kB
CmaFree: 0 kB
# 修改后
MemTotal: 1947176 kB
CmaTotal: 65536 kB
CmaAllocated: 1944 kB
CmaReleased: 63592 kB
CmaFree: 0 kB
新的报错
报错日志
Build fingerprint: 'WIF/rk3568_r/rk3568_r:11/RD2A.211001.002/20251022.183750:userdebug/release-keys'
Revision: '0'
ABI: 'arm64'
Timestamp: 2025-10-24 09:49:02+0800
pid: 2554, tid: 2615, name: camera-17612699 >>> com.jiangdg.ausbc <<<
uid: 10054
signal 11 (SIGSEGV), code 0 (SI_USER), fault addr --------
x0 0000000000000000 x1 0000000000000004 x2 00000072f8be530c x3 00000072f8be533a
x4 0000000000000001 x5 0000000000000000 x6 0000000000000308 x7 a4380f6a470e30ad
x8 000000000000013c x9 0000000000000001 x10 0000000000000000 x11 00000072f0e88a60
x12 ffffff80ffffffe0 x13 00000072f8be86c0 x14 0006cd283464d4cf x15 0000000029aaaaf1
x16 00000072f8be8ea0 x17 000000760ac912dc x18 00000072ee15e000 x19 0000000000000002
x20 0000007456f49974 x21 000000000000000c x22 0000000000000224 x23 0000000000000000
x24 0000007456f49b60 x25 00000073d6f26950 x26 0000007396f40378 x27 00000073c6f2b670
x28 0000000000000224 x29 00000072f0e88b20
lr 00000072f8bdf89c sp 00000072f0e88a60 pc 00000072f8bdf8b0 pst 0000000080001000
backtrace:
#00 pc 00000000000118b0 /data/app/~~JiTPoCSJyDFzOaO_rcKsBA==/com.jiangdg.ausbc-JJJd4tSsmNznAvhCbnZIBQ==/lib/arm64/libusb100.so (BuildId: 0a3128b26d7b110d699b38305536ccf99ac8ea1b)
#01 pc 000000000000d618 /data/app/~~JiTPoCSJyDFzOaO_rcKsBA==/com.jiangdg.ausbc-JJJd4tSsmNznAvhCbnZIBQ==/lib/arm64/libusb100.so (BuildId: 0a3128b26d7b110d699b38305536ccf99ac8ea1b)
#02 pc 000000000000d060 /data/app/~~JiTPoCSJyDFzOaO_rcKsBA==/com.jiangdg.ausbc-JJJd4tSsmNznAvhCbnZIBQ==/lib/arm64/libusb100.so (libusb_handle_events_timeout_completed+600) (BuildId: 0a3128b26d7b110d699b38305536ccf99ac8ea1b)
#03 pc 000000000000d774 /data/app/~~JiTPoCSJyDFzOaO_rcKsBA==/com.jiangdg.ausbc-JJJd4tSsmNznAvhCbnZIBQ==/lib/arm64/libusb100.so (libusb_handle_events+32) (BuildId: 0a3128b26d7b110d699b38305536ccf99ac8ea1b)
#04 pc 000000000001155c /data/app/~~JiTPoCSJyDFzOaO_rcKsBA==/com.jiangdg.ausbc-JJJd4tSsmNznAvhCbnZIBQ==/lib/arm64/libuvc.so (_uvc_handle_events+132) (BuildId: ecfb28a6291beb57fec7298797d8213c772ae2c1)
#05 pc 00000000000af880 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+64) (BuildId: 23b47e338fca2b85af1ec50fd590d7c7)
#06 pc 00000000000500d0 /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: 23b47e338fca2b85af1ec50fd590d7c7)
memory near x2 (/data/app/~~JiTPoCSJyDFzOaO_rcKsBA==/com.jiangdg.ausbc-JJJd4tSsmNznAvhCbnZIBQ==/lib/arm64/libusb100.so):
AI 分析:
- 崩溃发生在线程 camera-17612699 中,由 libusb100.so → libuvc.so 调用链触发。
- 线程执行的是 UVC 相机事件处理线程 (_uvc_handle_events),该线程负责监听摄像头数据流。
- 核心函数 libusb_handle_events_timeout_completed 崩溃,常见原因包括:
- libusb context 已被释放(即相机断开但事件线程未退出)
- 多线程访问 libusb context 导致内存竞争
- USB 设备异常断开时没有正确调用 uvc_close() 或 libusb_exit()
这次 SIGSEGV 崩溃是由 UVC 摄像头断开或事件线程访问已释放的 libusb context 导致的。
典型场景:
- 插拔 USB 摄像头时,Java 层的 UVCCamera.close() 没有同步停止 native 层线程;
- 或者设备被系统 USB service 强制重置(例如电源波动);
- 或者 UVC 库多线程访问同一 libusb_context(没加锁)。