启用多客户端摄像头

您可以允许多个客户端同时访问摄像头。为此,请使用本页中所述的 Java 和 Android NDK 系统 API 来共享对系统相机客户端的访问权限。

  • 主要客户:共享客户中优先级最高的客户。主客户端可以创建捕获请求并修改捕获参数。

  • 次要客户:所有其他共享客户均为次要客户。 辅助客户端无法创建捕获请求,也无法修改捕获参数。辅助客户端只能发送开始或停止流式传输的请求。

    对于流式传输,相机服务使用预览模板的默认捕获请求参数。如果主客户端正在进行流式传输,服务会使用主客户端指定的捕获请求参数。

配置共享会话

如需共享相机设备,请在位于 /system_ext/etc/ 中的名为 shared_session_config.xml 的文件中提供共享会话配置。在此代码示例中,相机 ID 0 支持相机共享,其配置包含两个数据流:ImageReaderSurfaceView

<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

CameraManagerCameraDevice 提供用于在共享模式下打开相机的 API。

CameraManager API

CameraManager 提供以下 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 以共享模式打开相机:

测试共享摄像头

请参阅以下针对多客户端摄像头的测试:

限制

共享摄像头模式支持以下选项:

  • 连拍捕获请求
  • 扩展会话
  • 高速会话
  • 离线会话
  • OutputConfiguration(支持 surface 共享)
  • 可重新处理的捕获会话
  • 第三方应用

当优先级较高的客户端在正常模式下打开相机时,系统会逐出所有共享相机客户端。