Android USB Camera 的实现方案
Android 设备基于 linux kernel, 自带 V4L2 支持,但是 OEM 厂商实现不同,大多默认关闭该功能。所以一般开发者或终端用户想要在 Android 设备上使用 usb camera 不是一件容易的事情。
这里简单介绍几种针对开发者来说,可选择的实现方案.
基于 libuvc 开发libuvc 是一个跨平台开发库,基于 libusb,功能包括 UVC 设备识别与控制,视频流传输,视频流格式转换等。
Android 平台上已有一个 Usb Camera 的开源项目,基于 libucv 的Android 应用,UVCCamera 无需 root 权限即可预览显示连接到手机的 usb camera 设备。
libuvc 官网介绍:
libuvc is a cross-platform library for USB video devices, built atop libusb. It enables fine-grained control over USB video devices exporting the standard USB Video Cla ...
V4L2 Camera HALv3 介绍
camera.v4l2 实现了 Camera HALv3 接口,底层调用了 Video For Linux 2(V4L2),因此适用范围比较广泛,可以适配兼容 V4L2 接口的所有设备。不过相对于 Android Camera 来说,V4L2 存在一些局限性,内置相机具备的一些功能可能不支持,但对于大多数应用场景来说,是没有问题的。
这篇文章根据官方介绍,结合实践经验来介绍一下 camera.v4l2 的一些特性。有空再补充一些细节~
当前状态camera.v4l2 可以自由使用,但是它不是由 Android Camera team 官方维护的, 实际上官方维护的是另外一个随着 Android P 一起更新发布的实现:External USB Cameras
该 HAL 实现在现有 Android 系统默认是关闭的,不会编译到系统里面。可以按照如下方式打开
编译方法修改 .mk 文件,增加如下配置:
123USE_CAMERA_V4L2_HAL := truePRODUCT_PACKAGES += camera.v4l2PRODUCT_PROPERTY_OVERRIDES += r ...
Android Camera HAL 介绍
Android Camera HAL 作为 Framework 层 Camera2 API 接口与底层硬件实现的桥梁,起着承上启下的作用。另外从 Android 8.0 开始使用了新的 Treble 架构(HAL 接口与实现代码在 hardware/interfaces/camera/),舍弃了原本旧的架构实现(Legacy HAL: hardware/libhardware/modules/camera/)。
Legacy HAL 当前还保留的内容:
hardware/libhardware/include/hardware/camera*.h, Camera Hal 接口定义,持续更新
hardware/libhardware/modules/camera/3_0/, camera.default Legacy 默认实现
hardware/libhardware/modules/camera/3_4/, camera.v4l2 非官方实现(树莓派)0
截止目前最新版本是 HALv3,高端机型基本上都支持。Camera HAL 属于相对比较复杂的一个硬件模块,随着硬件模组的发展, ...
Android HAL 介绍
一个硬件设备对应一个模块(动态库),可以各自独立更新,模块版本与设备版本需要保持兼容性,也就是特定版本的模块,只能加载与之兼容的设备。通常情况模块具有向后兼容性,支持最高版本及其以下版本的设备。
模块封装了该类型设备的通用操作,接口很少发生变动或者只是增加新接口,确保二进制兼容性,兼容低版本设备。
设备封装了特定版本的硬件设备,接口变化更频繁,类似 camera 从 HALv1, HALv2 到目前的 HALv3,封装成不同的设备子类,具体硬件根据其硬件特性选择实现不同版本的 device 接口。
hw_device_t 作为 device 的基类,放置于继承的具体设备类型 struct 子类的第一个位置,好处是首地址相同,可以直接做类型转换。子类型需要实现对应版本的接口函数,hw_module_t 作为 module 的基类,放置于继承的具体模块类型 struct 子类的第一个位置,好处是首地址相同,可以直接做类型转换。基类定义了唯一一个接口函数。
hw_module_methods_t.open, 打开硬件设备。所有模块都需要实现该接口。不同类型的模块可以定义自己的接口函数,比 ...
