Android プラットフォームは、標準の Android Camera2 API とカメラ HAL インターフェースにより、プラグアンドプレイ USB カメラ(ウェブカメラ)の使用をサポートしています。ウェブカメラは一般的に USB ビデオクラス(UVC)ドライバをサポートしています。Linux では標準の Video4Linux(V4L)ドライバを使用して UVC カメラを制御しています。
ウェブカメラのサポートにより、動画チャットやフォトキオスクなどのシンプルなユースケースにデバイスを使用できます。しかしこの機能は、Android スマートフォンで一般的な内蔵の Camera HAL に代わるものではなく、高解像度の高速ストリーミング、AR、およびマニュアルの ISP / センサー / レンズ制御など、高い性能が要求される複雑なタスク向けには設計されていません。
USB カメラの HAL プロセスは外部カメラ プロバイダが処理します。外部カメラ プロバイダは USB デバイスの可用性をリッスンし、それに応じて外部カメラデバイスを列挙します。このプロセスには、内蔵カメラの HAL プロセスと同様に、権限と SE ポリシーが適用されます。USB デバイスと直接通信するサードパーティのウェブカメラ アプリでも、UVC デバイスにアクセスするためには通常のカメラアプリと同じ権限が必要になります。
例とソース
USB カメラの実装方法の詳細については、ExternalCameraProvider
で外部カメラ プロバイダのリファレンス実装をご覧ください。外部カメラデバイスとセッションの実装は、ExternalCameraDevice
と ExternalCameraDeviceSession
に含まれています。API レベル 28 以降、Java クライアント API には EXTERNAL
ハードウェア レベルが含まれています。
実装
実装では、android.hardware.usb.host
システム機能をサポートする必要があります。
また、UVC デバイスのカーネル サポートも有効にする必要があります。このカーネル サポートは、各カーネルの defconfig
ファイルに以下のコードを追加することで有効にできます。
+CONFIG_USB_VIDEO_CLASS=y
+CONFIG_MEDIA_USB_SUPPORT=y
各デバイスビルドで外部カメラ プロバイダを有効にして、必要な SELinux 権限、外部カメラ構成、および外部カメラ プロバイダの依存関係を追加するには、次の手順を行います。
外部カメラ構成ファイルと外部カメラ ライブラリを
device.mk
に追加します。+PRODUCT_PACKAGES += android.hardware.camera.provider-V1-external-service +PRODUCT_COPY_FILES += \ +device/manufacturerX/productY/external_camera_config.xml:$(TARGET_COPY_OUT_VENDOR)/etc/external_camera_config.xml
外部カメラ プロバイダ名をデバイスの Treble HAL マニフェストに追加します。
<hal format="aidl"> <name>android.hardware.camera.provider</name> <version>1</version> <interface> <name>ICameraProvider</name> <instance>internal/0</instance> + <instance>external/0</instance> </interface> </hal>
(任意)デバイスが Treble パススルー モードで実行されている場合は、
sepolicy
を更新してcameraserver
が UVC カメラにアクセスできるようにします。+# for external camera +allow cameraserver device:dir r_dir_perms; +allow cameraserver video_device:dir r_dir_perms; +allow cameraserver video_device:chr_file rw_file_perms;
次に external_camera_config.xml
の例を示します(著作権情報は省略)。
<ExternalCamera> <Provider> <ignore> <!-- Internal video devices to be ignored by external camera HAL --> <id>0</id> <!-- No leading/trailing spaces --> <id>1</id> </ignore> </Provider> <!-- See ExternalCameraUtils.cpp for default values of Device configurations below --> <Device> <!-- Max JPEG buffer size in bytes--> <MaxJpegBufferSize bytes="3145728"/> <!-- 3MB (~= 1080p YUV420) --> <!-- Size of v4l2 buffer queue when streaming >= 30fps --> <!-- Larger value: more request can be cached pipeline (less janky) --> <!-- Smaller value: use less memory --> <NumVideoBuffers count="4"/> <!-- Size of v4l2 buffer queue when streaming < 30fps --> <NumStillBuffers count="2"/> <!-- List of maximum fps for various output sizes --> <!-- Any image size smaller than the size listed in Limit row will report fps (as minimum frame duration) up to the fpsBound value. --> <FpsList> <!-- width/height must be increasing, fpsBound must be decreasing--> <Limit width="640" height="480" fpsBound="30.0"/> <Limit width="1280" height="720" fpsBound="15.0"/> <Limit width="1920" height="1080" fpsBound="10.0"/> <!-- image size larger than the last entry will not be supported--> </FpsList> </Device> </ExternalCamera>
カスタマイズ
Android カメラは、一般的なカスタマイズ オプションまたはデバイス固有の最適化を使用して拡張できます。
一般的なカスタマイズ
外部カメラ プロバイダをカスタマイズするには、external_camera_config.xml
ファイルを修正します。具体的には、次のパラメータをカスタマイズできます。
- 内部カメラの動画ノードの除外
- サポートされている画像サイズとフレームレートの上限
- インフライト バッファ数(ジャンクとメモリのトレードオフ)
これらのパラメータに加えて、独自のパラメータを追加したり、独自の構成を作成したりできます。
デバイス固有の最適化
また、デバイス固有の最適化を追加してパフォーマンスを改善することもできます。
バッファのコピーおよびスケーリング、JPEG のデコードとエンコード
一般的な実装では CPU(libyuv / libjpeg)を使用しますが、デバイス固有の最適化で置換できます。
HAL 出力形式
一般的な実装では、次の出力形式を使用します。
YUV_420_888
(動画IMPLEMENTATION_DEFINED
バッファ向け)YUV12
(その他のIMPLEMENTATION_DEFINED
バッファ向け)
出力形式をデバイス固有の効率的な形式に置換することで、パフォーマンスを改善できます。カスタマイズした実装でその他の形式をサポートすることもできます。
検証
外部カメラをサポートしているデバイスは、カメラ CTS に合格する必要があります。テスト実行中は、外部 USB ウェブカメラを特定のデバイスに接続した状態を保持する必要があります。接続を解除すると、一部のテストケースで合格できなくなります。