本页介绍了增强型视觉系统 (EVS) 与 Camera2 之间的区别。还介绍了如何设置 Camera2 实现。
打开和关闭相机
EVS
openCamera
将打开设备和配置单个数据流的操作结合在一起。
Camera2
如需使用 Camera2 打开和关闭设备,请执行以下操作:
选择以下模式之一:
独占模式,在原生开发套件 (NDK) 上使用
CameraManager.openCamera
(Java) 或ACameraManager_openCamera
。共享模式,使用
openSharedCamera
或ACameraManager_openSharedCamera
。启用摄像头共享功能时,请提供共享会话配置。
如需配置流,请创建包含相关输出源的捕获会话。例如,来自具有
CameraDevice.createCaptureSession()
(Java) 或ACameraDevice_createCaptureSession()
(NDK) 的 ImageReader 或 SurfaceView。Camera2 支持同时处理多个信息流。创建多个流,用于预览、录制和图像处理等目的。 信息流充当并行流水线,可按顺序处理来自相机的原始帧。
如需关闭相机设备,请使用
CameraDevice.close()
(Java) 或ACameraDevice_close()
(NDK)。
请考虑以下代码段示例:
Java
CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try {
manager.openCamera(cameraId, new CameraDevice.StateCallback() {
@Override
public void onOpened(@NonNull CameraDevice camera) {
// Camera opened, now create session
}
@Override
public void onDisconnected(@NonNull CameraDevice camera) {}
@Override
public void onError(@NonNull CameraDevice camera, int error) {}
}, handler);
} catch (CameraAccessException e) {
// Handle exception
}
NDK
ACameraManager *cameraManager = ACameraManager_create();
ACameraDevice *cameraDevice = nullptr;
camera_status_t status = ACameraManager_openCamera(
cameraManager, cameraId, &deviceStateCallbacks, &cameraDevice);
流式传输相机数据
本部分介绍了如何流式传输相机数据。
EVS
在 EVS 上,从:
- 启动直播,使用
startVideoStream
。 - 停止直播,使用
stopVideoStream
。
Camera2
在 Camera2 上,执行以下操作:
创建适合预览的
CaptureRequest
,请在 Java 中使用CameraDevice.createCaptureRequest()
的TEMPLATE_PREVIEW
或在 NDK 中使用ACameraDevice_createCaptureRequest()
。提交持续流式传输请求,使用
CameraCaptureSession.setSingleRepeatingRequest
(Java) 或ACameraCaptureSession_setRepeatingRequestV2
(NDK)。停止直播,使用
CameraCaptureSession.stopRepeating
(Java) 或ACameraCaptureSession_stopRepeating
(NDK)。
缓冲区管理
在 EVS 上,
setMaxFramesInFlight
之前控制着缓冲区数量,这可能会在流中间发生变化。当摄像头开始流式传输时,EVS 为每个图像帧提供了一个缓冲区 ID,该 ID 与内存中的同一硬件缓冲区地址相关联。在 Camera2 上,
AImageReader
或ImageReader
的图片数量上限在初始化会话时通过AImageReader_new
或ImageReader.newInstance
设置。会话开始后,此设置无法动态更改。为了获取每个帧的缓冲区 ID,客户端可以维护一个将从Image
对象获得的硬件缓冲区地址与唯一标识符相关联的映射。
暂停和恢复直播
EVS 使用了
pauseVideoStream
和resumeVideoStream
。Camera2 没有直接对等项。而是:
- 暂停,使用
stopRepeating
- 恢复,使用
setSingleRepeatingRequest
- 暂停,使用
相机参数
EVS 使用了
setIntParameter
等方法来更改相机拍摄请求参数。在 Camera2 上,如需修改参数,请针对
CaptureRequest
构建器调用 set API,然后提交。
请考虑以下代码示例:
Java
CaptureRequest.Builder builder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
builder.set(CaptureRequest.CONTROL_EFFECT_MODE, CaptureRequest.CONTROL_EFFECT_MODE_MONO);
// Submit this request
NDK
ACaptureRequest_setEntry_i32(captureRequest, ACAMERA_CONTROL_EFFECT_MODE, 1, &effectMode);
逻辑相机
EVS:对于环视等逻辑摄像头,EVS 管理器会打开所有关联的实体摄像头,启动视频流,并提供一个连贯的图像阵列。
Camera2:如果需要使用 Camera2 实现类似的功能,应用必须管理逻辑摄像头,这需要您执行以下操作:
- 确定与逻辑摄像头关联的物理子摄像头。
- 打开每个必需的实体摄像头。
- 在每个摄像头上启动视频流。
- 根据需要同步帧。最好在 HAL 级别处理此问题,以实现硬件级同步。
我们将为现有 EVS 客户端提供兼容性库(shim 层),以方便过渡。目的是以最少的代码更改来支持 Camera2 API。
权限
本部分介绍了权限方面的变化。
EVS
访问权限仅限于具有特权的唯一标识符 (UID)。例如,AID_AUTOMOTIVE_EVS
。已弃用的权限包括 android.car.permission.USE_CAR_EVS_CAMERA
。
Camera2
Camera2 需要 android.permission.CAMERA
。特殊情况:
android.permission.SYSTEM_CAMERA
:用于访问对第三方应用隐藏的相机。还需要CAMERA
权限。如需了解详情,请参阅系统摄像头。android.permission.CAMERA_HEADLESS_SYSTEM_USER
:允许从User 0
进行访问,对于必须在用户切换时运行的服务(例如后视摄像头)至关重要。需要预先授予的 CAMERA 权限。android.permission.CAMERA_PRIVACY_ALLOWLIST
:允许 OEM 将某些安全关键型应用从用户控制的摄像头隐私切换开关中排除。
安全关键型相机应用必须遵循 Design for Driving 中提供的 Google 内置预授权政策。
主要客户和次要客户
对于共享摄像头使用权限:
EVS 提供了显式 API
setPrimaryClient
和forcePrimaryClient
来管理主要客户端,该客户端有权修改参数。在共享模式下打开相机时(Android 16 及更高版本),访问相机的客户端的优先级决定了主客户端。优先级最高的客户端(通常是前台应用)可以修改捕获请求参数。没有使用任何直接 API 来强制设置主状态。主状态由框架管理。
系统相机
如需限制仅允许系统或第一方应用访问某个相机设备,请在相应设备的相机 HAL 中声明 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_SYSTEM_CAMERA
功能。客户端必须具有 android.permission.SYSTEM_CAMERA
,并且还必须连接到此摄像头设备。android.permission.CAMERA
后视摄像头
EVS
EVS 之前支持在 Android 启动之前访问摄像头,这对于后视摄像头等功能来说至关重要。车辆 OEM 负责遵守并获得联邦机动车辆安全标准 (FMVSS) 第 111 号“后方视野”规定的认证。此外,车辆 OEM 必须遵守其他后视摄像头法规。
合规性取决于硬件、HAL 实现和整体系统集成。在参考平台完成 Android 启动后,EVS 通常需要 4 到 6 秒才能正常运行并授予摄像头访问权限。
Camera2
由 AID_AUTOMOTIVE_EVS UID
标识的特权客户端可以在 Android 启动过程完成之前使用 Camera2 API 访问摄像头。这种提前访问仅限于位于车身外部的系统摄像头。Camera2 在提早使用摄像头方面的性能 KPI 与 EVS 相同,通常在 Android 启动后 4 到 6 秒内即可使用。
为了确保后视摄像头能够持续显示清晰的画面,尤其是在用户切换时或当其他应用可能会遮挡预览画面时,我们建议在通过 Camera2 实现后视摄像头时遵循以下准则:
将后视摄像头指定为系统摄像头,以限制第三方应用访问。
运行以
User 0
身份访问相机的服务或应用,以使用 CAMERA_HEADLESS_SYSTEM_USER 权限。这样可确保无论前台用户如何切换,摄像头画面流式传输都不会中断。将应用添加到摄像头隐私许可名单,以便即使在启用用户控制的摄像头隐私切换开关时,也能授予摄像头访问权限。
CarEVSManager 和 CarEVSService
CarEVSManager 之前向 Java 应用提供摄像头访问权限。过渡到 Camera2 后,此功能将由 standard android.hardware.camera2.CameraManager
取代。
我们计划弃用 CarEVSService
,这是一项可选服务,用于监控 GEAR_SELECTION VHAL
属性并启动 OEM 指定的后视摄像头 activity。使用此功能的 OEM 必须将相关联的逻辑迁移到 OEM 拥有的应用。
- 监控
GEAR_SELECTION VHAL
属性。 - 在倒车档激活时启动后视摄像头 activity。
- 使用 Camera2 API 显示摄像头画面。
显示渲染
EVS 显示屏和车载显示屏服务
这些已弃用。
Camera2
使用标准 Android 渲染方法(包括 Surface、android.hardware.display.DisplayManager
和 android.view.Display
)。
对于需要提前显示摄像头的场景,Camera2 ImageReader 可以直接访问硬件缓冲区,以便您将其与现有的基于 DRM 的显示实现集成以进行渲染。
这种提前访问摄像头仅允许具有 AID_AUTOMOTIVE_EVS_UID
的特权客户端进行,并且仅限于位于车辆外部的系统摄像头。
模拟器 HAL(EVS 模拟 HAL)
我们计划弃用 EVS 模拟 HAL。相反,OEM 应使用 Camera2 模拟相机 HAL hardware/google/camera/devices/EmulatedCamera/
,我们计划在该 HAL 中支持:
- 可配置的摄像头数量。
- 彩条测试图案。
- 视频文件模拟。
如需在 build 中包含此 HAL,请执行以下操作:
# In device.mk
PRODUCT_SOONG_NAMESPACES += hardware/google/camera/devices/EmulatedCamera
PRODUCT_PACKAGES += com.google.emulated.camera.provider.hal
此外,还需要适当的安全增强型 Linux (SELinux) 政策,以允许 cameraserver
与模拟相机 HAL 服务进行交互。
V4L2 UVC 相机 HAL
我们计划弃用 EVS V4L2 HAL。使用 Camera2 外部相机支持功能来支持 USB 相机 (UVC)。如需了解详情,请参阅外部 USB 相机。
超声波 API
我们计划弃用 EVS 超声波 API。请改用 Android 15 中引入的以下 VHAL 属性进行超声波传感器检测。
属性 | 类型 | 定义 |
---|---|---|
ULTRASONICS_SENSOR_POSITION |
静态 | {<x>, <y>, <z>}
以毫米为单位,每个值表示传感器沿相关轴相对于 AAOS 传感器坐标系的位置。 |
ULTRASONICS_SENSOR_ORIENTATION |
静态 | {<qw>, <qx>, <qy>, <qz>}
这是传感器相对于 AAOS 传感器坐标系的四元数旋转: $$w+xi+yj+zk$$ |
ULTRASONICS_SENSOR_FIELD_OF_VIEW |
静态 | {<horizontal>, <vertical>}
传感器的水平和垂直视野范围(以度为单位)。 |
ULTRASONICS_SENSOR_DETECTION_RANGE |
静态 | {<minimum>, <maximum>}
传感器的检测范围(以毫米为单位)。 |
ULTRASONICS_SENSOR_DETECTION_RANGES |
静态 | {<range_min_1>, <range_max_1>, <range_min_2>,
<range_max_2>}
以毫米为单位(含),表示传感器支持的检测范围的数组。 |
ULTRASONICS_SENSOR_DETECTION_RANGES |
连续 | {<distance>, <distance_error>}
以毫米为单位的传感器测量距离和距离误差。如果仅支持某个范围,则这是检测到的范围内的最小距离。 |