您可以允许多个客户端同时访问摄像头。为此,请使用本页中所述的 Java 和 Android NDK 系统 API 来共享对系统相机客户端的访问权限。
主要客户:共享客户中优先级最高的客户。主客户端可以创建捕获请求并修改捕获参数。
次要客户:所有其他共享客户均为次要客户。 辅助客户端无法创建捕获请求,也无法修改捕获参数。辅助客户端只能发送开始或停止流式传输的请求。
对于流式传输,相机服务使用预览模板的默认捕获请求参数。如果主客户端正在进行流式传输,服务会使用主客户端指定的捕获请求参数。
配置共享会话
如需共享相机设备,请在位于 /system_ext/etc/ 中的名为 shared_session_config.xml 的文件中提供共享会话配置。在此代码示例中,相机 ID 0 支持相机共享,其配置包含两个数据流:ImageReader 和 SurfaceView。
<SharedCameraSessionConfigurations colorSpace="-1">
<!-- colorSpace: ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED -->
<SharedCameraSessionConfiguration cameraId="0">
<!-- First OutputConfiguration: All optional fields are provided -->
<OutputConfiguration>
<!-- surfaceType: SURFACE_TYPE_IMAGE_READER -->
<surfaceType>4</surfaceType>
<width>1920</width>
<height>1080</height>
<!-- physicalCameraId is omitted; defaults to "" -->
<!-- streamUseCase: ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT -->
<streamUseCase>0</streamUseCase>
<!-- timestampBase: TIMESTAMP_BASE_DEFAULT -->
<timestampBase>0</timestampBase>
<!-- mirrorMode: MIRROR_MODE_AUTO -->
<mirrorMode>0</mirrorMode>
<useReadoutTimestamp>0</useReadoutTimestamp>
<!-- format: HAL_PIXEL_FORMAT_RGBA_8888 -->
<format>1</format>
<!-- usage: AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN -->
<usage>3</usage>
<!-- dataSpace: HAL_DATASPACE_UNKNOWN -->
<dataSpace>0</dataSpace>
</OutputConfiguration>
<!-- Second OutputConfiguration: All optional fields are provided -->
<OutputConfiguration>
<!-- surfaceType: SURFACE_TYPE_SURFACE_VIEW -->
<surfaceType>0</surfaceType>
<width>1920</width>
<height>1080</height>
<!-- physicalCameraId is omitted; defaults to "" -->
<!-- streamUseCase: ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT -->
<streamUseCase>0</streamUseCase>
<!-- timestampBase: TIMESTAMP_BASE_DEFAULT -->
<timestampBase>0</timestampBase>
<!-- mirrorMode: MIRROR_MODE_AUTO -->
<mirrorMode>0</mirrorMode>
<useReadoutTimestamp>0</useReadoutTimestamp>
<!-- format: HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED -->
<format>34</format>
<!-- usage: AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE|AHARDWAREBUFFER_USAGE_COMPOSER_OVERLAY -->
<usage>256|2048</usage>
<!-- dataSpace: HAL_DATASPACE_UNKNOWN -->
<dataSpace>0</dataSpace>
</OutputConfiguration>
</SharedCameraSessionConfiguration>
</SharedCameraSessionConfigurations>
如需查询共享会话配置,客户端使用 CameraCharacteristics 进行 SHARED_SESSION_CONFIGURATION。以共享模式访问相机的客户端必须使用共享会话配置。如果客户端传递的会话配置与共享会话配置不匹配,则 createCaptureSession 调用会失败。
Java API
CameraManager 和 CameraDevice 提供用于在共享模式下打开相机的 API。
CameraManager API
CameraManager 提供以下 API:
isCameraDeviceSharingSupported:客户端使用此 API 来确定相机是否支持共享模式。openSharedCamera:如果相机支持共享模式,客户端会使用此 API 以共享模式打开相机。
CameraDevice.StateCallback API
CameraDevice.StateCallback 提供以下 API:
onOpenedInSharedMode:当摄像头以共享模式打开时,客户端会收到此回调。回调指示客户端是主客户端还是辅助客户端。onClientSharedAccessPriorityChanged:当共享会话打开时,如果优先级较高的客户端打开或关闭了同一摄像头,导致客户端的优先级发生变化,系统会触发此回调。
CameraSharedCaptureSession
CameraSharedCaptureSession 类表示共享的捕获会话。在共享相机模式下,创建会话的客户端必须使用 SESSION_SHARED 会话类型。
当系统创建会话时,将 CameraCaptureSession 强制转换为 CameraSharedCaptureSession。
辅助客户端无法使用 createCaptureRequest。次要客户端使用 startStreaming API 在指定界面上开始流式传输,并使用 stopStreaming API 停止流式传输。
Android NDK API
内置应用使用以下 Android NDK API 以共享模式打开相机:
ACameraManager_isCameraDeviceSharingSupportedACameraManager_openSharedCameraACameraCaptureSessionShared_startStreamingACameraCaptureSessionShared_logicalCamera_startStreamingACameraCaptureSessionShared_stopStreamingACameraDevice_ClientSharedAccessPriorityChangedCallbackonClientSharedAccessPriorityChanged
测试共享摄像头
请参阅以下针对多客户端摄像头的测试:
供应商测试套件 (VTS):请参阅
VtsAidlCameraServiceTargetTest中的SharedCameraTest兼容性测试套件 (CTS):请参阅
CtsCameraTestCases中的android.hardware.multiprocess.camera.cts.SharedCameraTest
限制
共享摄像头模式不支持以下选项:
- 连拍捕获请求
- 扩展会话
- 高速会话
- 离线会话
OutputConfiguration(支持 surface 共享)- 可重新处理的捕获会话
- 第三方应用
当优先级较高的客户端在正常模式下打开相机时,系统会逐出所有共享相机客户端。