本页介绍了增强型视觉系统 (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.CAMERA
之外,客户端还必须具有 android.permission.SYSTEM_CAMERA
才能连接到此摄像头设备。
CarEVSManager 和 CarEVSService
对于 API 访问,Java 应用应使用标准 android.hardware.camera2.CameraManager
而不是 CarEVSManager
。
对于后视摄像头,CarEVSService
中用于监控 GEAR_SELECTION
VHAL 属性并启动 activity 的逻辑必须迁移到 OEM 拥有的应用。此应用:
- 监控
GEAR_SELECTION
VHAL 属性。 - 在挂入倒车档时启动后视摄像头 activity。
- 使用 Camera2 API 显示摄像头画面。
为了确保后视摄像头能够以一致且不受阻碍的方式显示画面,尤其是在用户切换时或当其他应用可能会遮挡预览画面时,我们建议在通过 Camera2 实现后视摄像头功能时遵循以下准则:
将后视摄像头标记为系统摄像头。
使用
CAMERA_HEADLESS_SYSTEM_USER
权限以User 0
身份运行访问摄像头的服务或应用。将应用添加到摄像头隐私许可名单。
显示渲染
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 相机。
提前访问摄像头
EVS 相机访问权限仅限于具有 AID_AUTOMOTIVE_EVS
UID 的特权客户端。在 Android 启动过程完成之前访问摄像头,前提是 UID 保持为 AID_AUTOMOTIVE_EVS
。不过,提前访问摄像头仅限于位于车身外部的系统摄像头。
超声波 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>}
以毫米为单位的传感器测量距离和距离误差。如果仅支持某个范围,则这是检测到的范围内的最小距离。 |