
Android のカメラ ハードウェア抽象化レイヤ(HAL)は、Camera 2 の高レベルのカメラ フレームワーク API を、カメラの基礎となるドライバとハードウェアに接続します。カメラ サブシステムはカメラ パイプライン コンポーネントの実装を含み、一方 Camera HAL は、それらのコンポーネントの対象バージョンを実装する際に使用するインターフェースを提供します。
アーキテクチャ
次の図とリストでは、HAL コンポーネントについて説明しています。

図 1. カメラのアーキテクチャ
- アプリのフレームワーク
- アプリ フレームワーク レベルには、Camera 2 API を利用してカメラ ハードウェアと通信するアプリコードがあります。このコードは、対応する Binder インターフェースを内部で呼び出して、カメラと通信するネイティブ コードにアクセスします。
- AIDL
CameraService
に関連する Binder インターフェースは frameworks/av/camera/aidl/android/hardware にあります。生成されたコードは下位レベルのネイティブ コードを呼び出すことで物理カメラにアクセスできるようになり、CameraDevice
の生成、そして最終的にフレームワーク レベルでのCameraCaptureSession
オブジェクトの生成に使用するデータを返します。- ネイティブ フレームワーク
frameworks/av/
に存在するこのフレームワークは、CameraDevice
およびCameraCaptureSession
クラスに相当するネイティブ クラスを提供します。NDK camera2 のリファレンスもご覧ください。- binder IPC インターフェース
- binder IPC インターフェースは、プロセスの境界を越えた通信を可能にします。
frameworks/av/camera/camera/aidl/android/hardware
ディレクトリには、カメラサービスへの呼び出しを行う複数の camera binder クラスがあります。ICameraService
はカメラサービスへのインターフェースです。ICameraDeviceUser
はオープンになっている特定のカメラデバイスへのインターフェースです。ICameraServiceListener
とICameraDeviceCallbacks
はそれぞれ、アプリケーションフレームワークへのCameraService
コールバックとCameraDevice
コールバックです。 - カメラサービス
frameworks/av/services/camera/libcameraservice/CameraService.cpp
のカメラサービスは、HAL と通信する実際のコードです。- HAL
- ハードウェア抽象化レイヤは、カメラサービスの呼び出し先となり、カメラ ハードウェアを正しく機能させるために実装する必要がある標準インターフェースを定義します。
HAL を実装する
HAL は、カメラドライバと上位レベルの Android フレームワークの間にあり、アプリがカメラ ハードウェアを正しく操作できるようにするために実装する必要があるインターフェースを定義します。Camera HAL の HIDL インターフェースは、hardware/interfaces/camera で定義されます。
バインドされた一般的な HAL では、次の HIDL インターフェースを実装する必要があります。
ICameraProvider
: 個々のデバイスを列挙し、それらのステータスを管理します。ICameraDevice
: カメラデバイスのインターフェースとなります。ICameraDeviceSession
: アクティブなカメラデバイス セッションのインターフェースとなります。
リファレンス HIDL の実装は、CameraProvider.cpp
、CameraDevice.cpp
、および CameraDeviceSession.cpp
に使用できます。この実装では、レガシー API を現在も使用する古い HAL がラップされます。Android 8.0 から、Camera HAL の実装には HIDL API を使用する必要があります。レガシーのインターフェースの使用はサポートされていません。
レガシー HAL コンポーネント
このセクションでは、レガシー HAL コンポーネントのアーキテクチャとレガシー HAL の実装方法について説明します。Android 8.0 以降の Camera HAL 実装には、上記の HIDL API を使用する必要があります。
アーキテクチャ(レガシー)
次の図とリストでは、レガシー Camera HAL コンポーネントについて説明しています。

図 2. レガシー カメラ アーキテクチャ
- アプリのフレームワーク
- アプリ フレームワーク レベルには、
android.hardware.Camera
API を利用してカメラ ハードウェアと通信するアプリコードがあります。このコードは対応する JNI グルークラスを内部で呼び出して、カメラと通信するネイティブ コードにアクセスします。 - JNI
android.hardware.Camera
に関連する JNI コードはframeworks/base/core/jni/android_hardware_Camera.cpp
にあります。このコードは下位レベルのネイティブ コードを呼び出すことで物理カメラにアクセスできるようになり、フレームワーク レベルでのandroid.hardware.Camera
オブジェクトの生成に使用するデータを返します。- ネイティブ フレームワーク
frameworks/av/camera/Camera.cpp
で定義されたネイティブ フレームワークは、android.hardware.Camera
クラスに相当するネイティブ クラスを提供します。このクラスは IPC バインダ プロキシを呼び出すことで、カメラサービスにアクセスできるようになります。- バインダ IPC プロキシ
- IPC バインダ プロキシは、プロセスの境界を越えた通信を可能にします。カメラサービスを呼び出す
frameworks/av/camera
ディレクトリには、3 つのカメラ バインダ クラスがあります。ICameraService
はカメラサービスへのインターフェースです。ICamera
はオープンになっている特定のカメラデバイスへのインターフェースです。ICameraClient
はアプリのフレームワークにコールバックを行うデバイスのインターフェースです。 - カメラサービス
frameworks/av/services/camera/libcameraservice/CameraService.cpp
のカメラサービスは、HAL と通信する実際のコードです。- HAL
- ハードウェア抽象化レイヤは、カメラサービスの呼び出し先となり、カメラ ハードウェアを正しく機能させるために実装する必要がある標準インターフェースを定義します。
- カーネル ドライバ
- カメラのドライバは、実際のカメラ ハードウェアおよび実装されている HAL と通信します。カメラとドライバは、ディスプレイでのカメラ画像のプレビューと動画の録画をサポートするために YV12 と NV21 の画像形式に対応している必要があります。
HAL(レガシー)を実装する
HAL は、カメラドライバと上位レベルの Android フレームワークの間にあり、アプリがカメラ ハードウェアを正しく操作できるようにするために実装する必要があるインターフェースを定義します。HAL インターフェースは、hardware/libhardware/include/hardware/camera.h
ヘッダーファイルと hardware/libhardware/include/hardware/camera_common.h
ヘッダーファイルで定義されます。
camera_common.h
は camera_module
を定義します。これはカメラ ID やすべてのカメラに共通するプロパティ(カメラが前面カメラか背面カメラであるかなど)など、カメラの一般的な情報を取得するための標準的な仕組みです。
camera.h
には android.hardware.Camera
に対応するコードが含まれています。このヘッダーファイルは camera_device
構造体を宣言し、この構造体は HAL インターフェースを実装する関数へのポインタを持つ camera_device_ops
構造体を含みます。デベロッパーが設定できるカメラ パラメータに関するドキュメントについては、frameworks/av/include/camera/CameraParameters.h
を参照してください。これらのパラメータは、HAL の int
(*set_parameters)(struct camera_device *, const char *parms)
によってポイントされる関数で設定されます。
HAL 実装の例については、hardware/ti/omap4xxx/camera
の Galaxy Nexus HAL の実装を参照してください。
共有ライブラリを構成する
Android ビルドシステムを設定し、Android.mk
ファイルの作成によって HAL 実装を共有ライブラリに正しくパッケージ化して、適切な場所にその共有ライブラリをコピーします。
- ライブラリのソースファイルを格納する
device/<company_name>/<device_name>/camera
ディレクトリを作成します。 Android.mk
ファイルを作成して、共有ライブラリをビルドします。makefile に次の行が含まれていることを確認します。LOCAL_MODULE := camera.<device_name> LOCAL_MODULE_RELATIVE_PATH := hw
Android でライブラリを正しくロードできるように、ライブラリの名前は
camera.<device_name>
とします(.so
は自動的に付加されます)。例については、hardware/ti/omap4xxx/Android.mk
にある Galaxy Nexus カメラの makefile を参照してください。- デバイスにカメラ機能があることを指定するには、デバイスの makefile を使用して必要となる機能 XML ファイルを
frameworks/native/data/etc
ディレクトリにコピーします。たとえば、デバイスにカメラ フラッシュと自動フォーカス機能があることを指定するには、デバイスの<device>/<company_name>/<device_name>/device.mk
makefile に次の行を追加します。PRODUCT_COPY_FILES := \ ... PRODUCT_COPY_FILES += \ frameworks/native/data/etc/android.hardware.camera.flash-autofocus.xml:system/etc/permissions/android.hardware.camera.flash-autofocus.xml \
デバイスの makefile の例については、
device/samsung/tuna/device.mk
を参照してください。 - カメラのメディア コーデック、フォーマット、解像度を
device/<company_name>/<device_name>/media_profiles.xml
XML ファイルとdevice/<company_name>/<device_name>/media_codecs.xml
XML ファイルで宣言します。詳細については、フレームワークにコーデックを公開するをご覧ください。 - デバイスの
device/<company_name>/<device_name>/device.mk
makefile に次の行を追加して、media_profiles.xml
ファイルとmedia_codecs.xml
ファイルを適切な場所にコピーします。# media config xml file PRODUCT_COPY_FILES += \ <device>/<company>/<device>/media_profiles.xml:system/etc/media_profiles.xml # media codec config xml file PRODUCT_COPY_FILES += \ <device>/<company>/<device>/media_codecs.xml:system/etc/media_codecs.xml
- デバイスの
device/<company>/<device>/device.mk
makefile のPRODUCT_PACKAGES
変数でカメラアプリを指定して、デバイスのシステム イメージにカメラアプリを含めます。PRODUCT_PACKAGES := \ Gallery2 \ ...