Camera2 に移行する

このページでは、拡張ビューシステム(EVS)と Camera2 の違いについて説明します。また、Camera2 の実装を設定する方法についても説明します。

カメラを開閉する

EVS

openCamera は、デバイスを開くことと単一のストリームを構成することを組み合わせます。

Camera2

Camera2 でデバイスを開閉するには:

  1. 次のいずれかのモードを選択します。

  2. ストリームを構成するには、関連する出力サーフェスを使用してキャプチャ セッションを作成します。たとえば、CameraDevice.createCaptureSession()(Java)または ACameraDevice_createCaptureSession()(NDK)の ImageReader または SurfaceView から取得します。

    Camera2 は、複数のストリームの同時使用をサポートしています。プレビュー、録画、画像処理などの目的で複数のストリームを作成します。ストリームは並列パイプラインとして機能し、カメラからの未加工フレームを順次処理します。

  3. カメラ デバイスを閉じるには、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 で、次の操作を行います。

  1. ストリーミングを開始します。startVideoStream を使用します。
  2. ストリーミングを停止するには、stopVideoStream を使用します。

Camera2

Camera2 では、

  1. プレビューに適した CaptureRequest を作成します。Java では CameraDevice.createCaptureRequest() を使用して TEMPLATE_PREVIEW を、NDK では ACameraDevice_createCaptureRequest() を使用します。

  2. 継続的なストリーミングのリクエストを送信するには、CameraCaptureSession.setSingleRepeatingRequest(Java)または ACameraCaptureSession_setRepeatingRequestV2(NDK)を使用します。

  3. ストリーミングを停止するには、CameraCaptureSession.stopRepeating(Java)または ACameraCaptureSession_stopRepeating(NDK)を使用します。

バッファ管理

  • EVS では、以前は setMaxFramesInFlight がバッファ数を制御しており、ストリームの途中で変更される可能性がありました。カメラ ストリーミングが開始されると、EVS は各画像フレームのバッファ ID を提供しました。これは、メモリ内の同じハードウェア バッファ アドレスに関連付けられていました。

  • Camera2 では、セッションの初期化時に AImageReader_new または ImageReader.newInstanceAImageReader または ImageReader の画像の最大数が設定されます。セッションが開始されると、この設定を動的に変更することはできません。各フレームのバッファ ID を取得するために、クライアントは Image オブジェクトから取得したハードウェア バッファ アドレスを一意の識別子に関連付けるマップを維持できます。

ストリーミングを一時停止、再開する

  • EVS は pauseVideoStreamresumeVideoStream を使用していました。

  • Camera2 に直接相当するものはありません。代わりに、次のようにします。

カメラ パラメータ

  • 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 Manager は関連するすべての物理カメラを開き、動画ストリームを開始して、一貫性のある画像配列を提供しました。

  • Camera2: Camera2 で同様の機能が必要な場合、アプリは論理カメラを管理する必要があります。そのためには、次の操作が必要です。

    • 論理カメラに関連付けられている物理サブカメラを特定します。
    • 必要な物理カメラをそれぞれ開きます。
    • 各カメラでストリームを開始します。
    • 必要に応じてフレームを同期します。最適には、これはハードウェア レベルの同期のために HAL で処理されます。

移行を容易にするため、既存の EVS クライアントに互換性ライブラリ(シムレイヤ)を提供します。コードの変更を最小限に抑えながら 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(setPrimaryClientforcePrimaryClient)を提供していました。

  • Camera2 では、カメラが共有モードで開かれた場合(Android 16 以降)、カメラにアクセスするクライアントの優先度によってプライマリ クライアントが決定されます。優先度が最も高いクライアント(通常はフォアグラウンド アプリ)は、キャプチャ リクエスト パラメータを変更できます。プライマリ ステータスを強制するために直接 API は使用されません。プライマリ ステータスはフレームワークによって管理されます。

システムカメラ

カメラデバイスへのアクセスをシステムアプリまたはファーストパーティ製アプリのみに制限するには、そのデバイスのカメラ HAL で ANDROID_REQUEST_AVAILABLE_CAPABILITIES_SYSTEM_CAMERA 機能を宣言します。クライアントは、このカメラ デバイスに接続された android.permission.CAMERA に加えて、android.permission.SYSTEM_CAMERA も必要です。

リアビュー カメラ

EVS

EVS は以前、Android の起動前にカメラへのアクセスを有効にしていました。これは、リアビュー カメラなどの機能にとって重要なイベントです。自動車 OEM は、連邦自動車安全基準(FMVSS)第 111 号「後方視界」に規定されている規制の遵守と認証の責任を負います。また、自動車 OEM は他のリアビュー カメラの規制にも準拠する必要があります。

準拠は、ハードウェア、HAL 実装、システム全体の統合によって異なります。リファレンス プラットフォームの Android 起動後、EVS が動作可能になり、カメラへのアクセスを許可するまでに通常 4 ~ 6 秒かかります。

Camera2

AID_AUTOMOTIVE_EVS UID で識別される特権クライアントは、Android の起動プロセスが完了する前に Camera2 API を使用してカメラにアクセスできます。この早期アクセスは、車両の外部にあるシステムカメラに限定されています。Camera2 は、EVS と同じ早期カメラアクセスのパフォーマンス KPI を満たしています。通常、Android の起動後 4 ~ 6 秒以内に利用可能になります。

特にユーザーの切り替え時や、他のアプリがプレビューを隠す可能性がある場合に、リアビュー カメラを常に妨げなく表示するため、Camera2 でリアビュー カメラを実装する際は、以下のガイドラインに沿うことをおすすめします。

  1. リアビュー カメラをシステム カメラとして指定し、サードパーティ アプリのアクセスを制限します。

  2. CAMERA_HEADLESS_SYSTEM_USER 権限を使用して、カメラにアクセスするサービスまたはアプリを User 0 として実行します。これにより、フォアグラウンド ユーザーの切り替えがあろうとなかろうと、カメラ ストリーミングが中断されることはありません。

  3. アプリをカメラのプライバシー許可リストに追加して、ユーザーが制御するカメラのプライバシー切り替えが有効になっている場合でも、カメラへのアクセスを許可します。

CarEVSManager と CarEVSService

CarEVSManager は以前、Java アプリにカメラへのアクセスを提供していました。Camera2 への移行により、この機能は standard android.hardware.camera2.CameraManager に置き換えられます。

GEAR_SELECTION VHAL プロパティをモニタリングし、OEM 指定のバックミラー カメラ アクティビティの開始に使用されるオプション サービスである CarEVSService を非推奨にする予定です。この機能を使用する OEM は、関連するロジックを OEM 所有のアプリに移行する必要があります。

  • GEAR_SELECTION VHAL プロパティをモニタリングします。
  • リバース ギアが有効になったときに、バックカメラ アクティビティを起動します。
  • Camera2 API を使用してカメラフィードを表示します。

ディスプレイのレンダリング

EVS ディスプレイと自動車ディスプレイ サービス

これらは非推奨です。

Camera2

Surface、android.hardware.display.DisplayManagerandroid.view.Display で標準の Android レンダリング メソッドを使用します。

カメラの早期表示が必要なシナリオでは、Camera2 ImageReader がハードウェア バッファへの直接アクセスを提供するため、既存の DRM ベースのディスプレイ実装と統合してレンダリングできます。

カメラへの早期アクセスは、AID_AUTOMOTIVE_EVS_UID を持つ特権クライアントにのみ許可され、車両の外部に配置されたシステムカメラに限定されます。

エミュレータ HAL(EVS モック HAL)

EVS Mock HAL は非推奨となる予定です。代わりに、OEM は Camera2 エミュレート カメラ HAL hardware/google/camera/devices/EmulatedCamera/ を使用する必要があります。この HAL では、次のサポートを予定しています。

  • 構成可能なカメラの数。
  • カラーバーのテストパターン。
  • 動画ファイルのエミュレーション。

この HAL をビルドに含めるには:

# In device.mk
PRODUCT_SOONG_NAMESPACES += hardware/google/camera/devices/EmulatedCamera
PRODUCT_PACKAGES += com.google.emulated.camera.provider.hal

また、cameraserver がエミュレートされたカメラ HAL サービスとやり取りできるように、適切なセキュリティ強化された Linux(SELinux)ポリシーも必要です。

V4L2 UVC カメラ HAL

EVS V4L2 HAL は非推奨となる予定です。USB カメラ(UVC)に Camera2 外部カメラのサポートを使用します。詳しくは、外部 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>}

センサーの測定距離と距離誤差(ミリメートル単位)。範囲のみがサポートされている場合、これは検出された範囲の最小距離です。