Android-UVC摄像头总结

一、什么是UVC

UVC,全称为:USB video(device) class,是微软与另外几家设备厂商联合推出的为USB视频捕获设备定义的协议标准,目前已成为USB org标准之一。
USB协议中,除了通用的软硬件电气接口规范等,还包含了各种各样的Class协议,用来为不同的功能定义各自的标准接口和具体的总线上的数据交互格式和内容。这些Class协议的数量非常多,最常见的比如支持U盘功能的Mass Storage Class,以及通用的数据交换协议:CDC class。此外还包括Video、Audio Class, Print Class等等。正是由于这些Class协议,大大促进了USB设备的普及,比如说各个厂商生产的U盘都能通过操作系统自带的驱动程序来使用。
所以说UVC仅仅只是USB规范协议中设备类规范的其中一种,是用作USB接口的视频设备的一个统一的数据交换规范。使用 UVC 的好处 USB 在 Video这块也成为一项标准了之后,硬件在各个程序之间彼此运行会更加顺利,而且也省略了驱动程序安装这一环节,操作系统只要是 Windows XP SP2 之后的版本都可以支持 UVC,Linux系统自2.4以后的内核都支持了大量的设备驱动,其中支持UVC设备。

http://www.usbzh.com/article/detail-80.html

二、Android-UVC开源驱动

目前Android端的开源驱动主要有UVCCamera,目前多数开源项目都是基于此处,感谢saki4510t大神。https://github.com/saki4510t/UVCCamera
此处开源项目的每个Demo实例:

1)USBCameraTest0
            显示如何使用SurfaceView来启动/停止预览。

2)USBCameraTest
            显示如何启动/停止预览。这与USBCameraTest0几乎相同,
            但是使用自定义的TextureView来显示相机图像而不是使用SurfaceView。

3)USBCameraTest2
            演示如何使用MediaCodec编码器将UVC相机(无音频)的视频记录为.MP4文件。
            此示例需要API>=18,因为MediaMuxer仅支持API>=18。

4)USBCameraTest3
            演示如何将音频(来自内部麦克风)的视频(来自UVC相机)录制为.MP4文件。
            这也显示了几种捕捉静止图像的方式。此示例可能最适用于您的定制应用程序的基础项目。

5)USBCameraTest4
            显示了访问UVC相机并将视频图像保存到后台服务的方式。
            这是最复杂的示例之一,因为这需要使用AIDL的IPC。

6)USBCameraTest5
            和USBCameraTest3几乎相同,但使用IFrameCallback接口保存视频图像,
            而不是使用来自MediaCodec编码器的输入Surface。
            在大多数情况下,您不应使用IFrameCallback来保存图像,因为IFrameCallback比使用Surface要慢很多。
            但是,如果您想获取视频帧数据并自行处理它们或将它们作为字节缓冲区传递给其他外部库,
            则IFrameCallback将非常有用。

7)USBCameraTest6
            这显示了如何将视频图像分割为多个Surface。你可以在这个应用程序中看到视频图像并排观看。
            这个例子还展示了如何使用EGL来渲染图像。
            如果您想在添加视觉效果/滤镜效果后显示视频图像,则此示例可能会对您有所帮助。

8)USBCameraTest7
            这显示了如何使用两个摄像头并显示来自每个摄像头的视频图像。这仍然是实验性的,可能有一些问题。

9)usbCameraTest8
            这显示了如何设置/获取uvc控件。目前这只支持亮度和对比度。

目前此项目结构驱动层面-共用库-示例
驱动层面原生C#语言编写,根据自己使用的架构可以编译不同架构so

libuvccamera/src/main/jni/Application.mk
#NDK_TOOLCHAIN_VERSION := 4.9
# NDK编译版版本根据issue修复NDK14版本错误
APP_PLATFORM := android-15
# 修改支持平台CPU架构取消了x86mips编译
APP_ABI := armeabi armeabi-v7a arm64-v8a
#APP_OPTIM := debug
APP_OPTIM := release

目前我是用的是ndk15版本编译,其他版本编译都有多少问题
目前我将上传我处理过的编译版本给大家参考,修复了在issue提的问题。并且对项目结构进行了调整其中的usblq和usbcw个人项目的lib库大家可以去掉

三、打包aar/jar

一般我们添加依赖都是通过aar和jar方便管理
这里顺带说下我是怎么打包aar和jar的,目前网上方法较多,我就以我觉得最为方便的方法示之。

  • aar


    1.png
2.png

需要混淆压缩的需要在此处编译release版本


3.png
libuvccamera/build/outputs/aar/libuvccamera-debug.aar
libuvccamera/build/outputs/aar/libuvccamera-release.aar
  • jar
    在module的build.gradle的android中添加
//生成jar包
    task makeJar(type: Copy) {
        delete 'build/outputs/uvc_camera.jar'
        // jar文件来源
        from('build/intermediates/aar_main_jar/release/')
        // 生成路径
        into('build/libs/')
        include('classes.jar')
        // 命名为network.jar
        rename('classes.jar', 'uvc_camera.jar')
    }

点击运行或者在task中找到名为makeJar的命令

四、常见错误问题

UVCCamera nativeConnect 返回的错误码 集合:

/** Success (no error) /
UVC_SUCCESS = 0,
/* Input/output error /
UVC_ERROR_IO = -1,
/* Invalid parameter /
UVC_ERROR_INVALID_PARAM = -2,
/* Access denied /
UVC_ERROR_ACCESS = -3,
/* No such device /
UVC_ERROR_NO_DEVICE = -4,
/* Entity not found /
UVC_ERROR_NOT_FOUND = -5,
/* Resource busy /
UVC_ERROR_BUSY = -6,
/* Operation timed out /
UVC_ERROR_TIMEOUT = -7,
/* Overflow /
UVC_ERROR_OVERFLOW = -8,
/* Pipe error /
UVC_ERROR_PIPE = -9,
/* System call interrupted /
UVC_ERROR_INTERRUPTED = -10,
/* Insufficient memory /
UVC_ERROR_NO_MEM = -11,
/* Operation not supported /
UVC_ERROR_NOT_SUPPORTED = -12,
/* Device is not UVC-compliant /
UVC_ERROR_INVALID_DEVICE = -50,
/* Mode not supported /
UVC_ERROR_INVALID_MODE = -51,
/* Resource has a callback (can’t use polling and async) /
UVC_ERROR_CALLBACK_EXISTS = -52,
/* Undefined error */
UVC_ERROR_OTHER = -99

项目中常见问题:

  • a查看是否支持UVC,adb命令
cd sys/bus/usb/drivers
ls dev/v*
  • b下载以及修改ndk路径
    在Android studio 打开sdk manager->sdk tool ->show package details 勾选ndk 本版
    旧版本ndk 需要到官网下载
    设置ndk路径在AndroidStudio菜单栏,选择File->Project Struture中配置ndk
  • c拔出usb摄像头,crash异常导致应用退出


    5.png
diff --git a/libuvccamera/src/main/jni/libusb/libusb/os/android_usbfs.c b/libuvccamera/src/main/jni/libusb/libusb/os/android_usbfs.c
index 8626595..c4842c4 100644
--- a/libuvccamera/src/main/jni/libusb/libusb/os/android_usbfs.c
+++ b/libuvccamera/src/main/jni/libusb/libusb/os/android_usbfs.c
@@ -2726,6 +2726,12 @@ static int handle_iso_completion(struct libusb_device_handle *handle,    // XXX add

        usbi_mutex_lock(&itransfer->lock);
        for (i = 0; i < num_urbs; i++) {
+           //+Add by york.zhou on 2021.05.19,fix issue app crash on remove usb device
+           if (tpriv->iso_urbs == NULL){
+            break;
+        }
+        //-Add by york.zhou on 2021.05.19,fix issue app crash on remove usb device
+
                if (urb == tpriv->iso_urbs[i]) {
                        urb_idx = i + 1;
                        break;
diff --git a/libuvccamera/src/main/jni/libuvc/src/stream.c b/libuvccamera/src/main/jni/libuvc/src/stream.c
index 8a1e90a..b7cedcc 100644
--- a/libuvccamera/src/main/jni/libuvc/src/stream.c
+++ b/libuvccamera/src/main/jni/libuvc/src/stream.c
@@ -641,7 +641,8 @@ static void _uvc_delete_transfer(struct libusb_transfer *transfer) {
                                libusb_cancel_transfer(strmh->transfers[i]);    // XXX 20141112追加
                                UVC_DEBUG("Freeing transfer %d (%p)", i, transfer);
                                free(transfer->buffer);
-                               libusb_free_transfer(transfer);
+                               //+Add york.zhou 2021.05-19,fix remove usb devices,app crash
+                               //libusb_free_transfer(transfer);
                                strmh->transfers[i] = NULL;
                                break;
                        }
  • d有些usb摄像头识别不了
    在xml 目录下的device_filter.xml中配置下

     

你可能感兴趣的:(Android-UVC摄像头总结)