Android 14-QPR1 以降を搭載したデバイスには、そのデバイスを USB ウェブカメラとして使用できる機能が付いています。この機能をサポートする Android デバイスは、UVC デバイスとしてアドバタイズされており、Linux、macOS、Windows、ChromeOS などのオペレーティング システムを持つさまざまな USB ホストがデバイスのカメラをウェブカメラとして使用することを可能にします。DeviceAsWebcam
サービスは、デバイスをウェブカメラとして使用できるこの機能をサポートしています。
DeviceAsWebcam サービス
AOSP の DeviceAsWebcam
サービスには、ユーザーが撮影範囲を指定できるプレビュー アクティビティ(DeviceAsWebcamPreview.java
)の機能が含まれています。プレビュー アクティビティにおいて、ユーザーは以下のことができます。
ストリーミングを開始する前に、ホストマシン上でウェブカメラのフィードがどのように見えるかをプレビューできます。
以下の方法で、ホストに送信されるウェブカメラ フィードをカスタマイズできます。
- 前面カメラまたは背面カメラのどちらをストリーミングするかを選択します。
- スライダーまたはボタンを使用して、ズームレベルを選択します。
- プレビュー画面の特定の部分をタップして、その部分にピントを合わせたり、ピントを外したりします。
プレビュー アクティビティは、TalkBack、Switch Access、Voice Access などの Android の一般的なユーザー補助機能に対応しています。
図 1. ホストにストリーミングされているウェブカメラのフィードおよびフィードを制御しているプレビュー
アーキテクチャ
デバイスをウェブカメラとして使用することをサポートするアーキテクチャは、図 2 に示されているとおりです。以下は、DeviceAsWebcam
サービスと Android フレームワークの残りの部分のインタラクション フローです。
- ユーザーが設定アプリで USB ウェブカメラを選択します。
- 設定アプリが
UsbManager
クラスを介して、system_server
にバインダー呼び出しを送信し、FUNCTION_UVC
が選択されたことを通知します。 - システム サーバーは、以下の処理を行います。
setUsbFunctions
HAL インターフェース呼び出しを通じて、USB ガジェット HAL に UVC ガジェット機能を取得するよう通知します。- ConfigFs を使用して UVC ガジェット ドライバを構成するよう、USB ガジェット HAL に通知します。
- ガジェット HAL からコールバックを受信すると、
system_server
はフレームワークにブロードキャストを送信し、DeviceAsWebcam
サービスがそれを受け取ります。 - USB ガジェット ドライバは、V4L2 ノード
/dev/video*
を介してホストから構成コマンドを受信すると、ウェブカメラのストリーミングを開始します。
図 2. DeviceAsWebcam のアーキテクチャ
実装
このセクションでは、Android デバイスをウェブカメラとして使用することをサポートする方法について説明します。
カーネル サポート
Android 14 以降では、汎用カーネル イメージ(GKI)により UVC ガジェット ドライバがデフォルトで有効になります(詳細は AOSP パッチを参照)。
ガジェット HAL で UVC をサポートする
Android 14 以降では、GadgetFunction.aidl
HAL インターフェースに UVC 機能が含まれています。ガジェット HAL では、UVC ガジェットは MTP や ADB などの他の ConfigFS 機能と同じように ConfigFS にマウントされます。
ガジェット HAL を実装するには、UVC 機能が ConfigFS にマウントされるよう変更する必要があります。以下は、UVC 機能をサポートするガジェット HAL の実装についてのスニペットの例です。
UsbGadget::setCurrentUsbFunctions(long functions) {
...
// Existing functions
if ((functions & GadgetFunction::MTP) != 0) {
...
linkFunction("ffs.mtp"); // Mount to ConfigFS
...
}
...
// UVC function follows the same pattern!
if ((functions & GadgetFunction::UVC) != 0) {
...
linkFunction("uvc.0"); // Mount to ConfigFS
...
}
...
}
デバイスをウェブカメラとして使用する際は、USB ガジェット HAL が適切な VID と PID の組み合わせをアドバタイズしていることを確認してください。
すべての UVC ロジックは、ベンダーの init または DeviceAsWebcam
サービスにあるため、UVC 機能を ConfigFS にシンボリック リンクする以外、ガジェット HAL に UVC 特有のロジックは必要ありません。
実装に関する詳しいガイダンスについては、AOSP の以下のサンプルコードを参照してください。
UVC 構成で ConfigFS を設定する
Android ウェブカメラでサポートされている形式、サイズ、フレームレートを UVC ガジェット ドライバに知らせるには、UVC 構成で ConfigFS を設定します。詳細については、ConfigFS UVC ガジェット ABI に関するアップストリームの Linux のドキュメントをご覧ください。
以下の例は、ベンダー init で UVC ガジェット ドライバを設定する方法を示しています(AOSP のコード スニペット)。
# uvc function
mkdir /configfs_path/functions/uvc.0
write /configfs_path/functions/uvc.0/function_name "Android Webcam"
write /configfs_path/functions/uvc.0/streaming_maxpacket 3072
# setup control params
mkdir /configfs_path/functions/uvc.0/control/header/h
symlink /configfs_path/functions/uvc.0/control/header/h \
/configfs_path/functions/uvc.0/control/class/fs/h
symlink /configfs_path/functions/uvc.0/control/header/h \
/configfs_path/functions/uvc.0/control/class/ss/h
# advertise 1080p resolution for webcam encoded as mjpeg
mkdir /configfs_path/functions/uvc.0/streaming/mjpeg/m/1080p
write /configfs_path/functions/uvc.0/streaming/mjpeg/m/1080p/wHeight 1080
write /configfs_path/functions/uvc.0/streaming/mjpeg/m/1080p/wWidth 1920
write /configfs_path/functions/uvc.0/streaming/mjpeg/m/1080p/dwMaxVideoFrameBufferSize 4147200
# advertise 30 fps support for 1080p.
write /configfs_path/functions/uvc.0/streaming/mjpeg/m/1080p/dwDefaultFrameInterval 333333
write /configfs_path/functions/uvc.0/streaming/mjpeg/m/1080p/dwFrameInterval "333333"
# setup streaming params
mkdir /configfs_path/functions/uvc.0/streaming/header/h
symlink /configfs_path/functions/uvc.0/streaming/mjpeg/m \
/configfs_path/functions/uvc.0/streaming/header/h/m
symlink /configfs_path/functions/uvc.0/streaming/header/h \
/configfs_path/functions/uvc.0/streaming/class/fs/h
symlink /configfs_path/functions/uvc.0/streaming/header/h \
/configfs_path/functions/uvc.0/streaming/class/hs/h
symlink /configfs_path/functions/uvc.0/streaming/header/h \
/config/usb_gadget/g1/functions/uvc.0/streaming/class/ss/h
# ...
このスニペットにより、UVC ガジェット ドライバが 1080p MJPEG ストリームを 30 fps でアドバタイズするよう設定できます。これらの設定は、USB ホストがサポートされている解像度とフレームレートを問い合わせた際に通知されます。
以下は、ウェブカメラがアドバタイズする構成を選択する際の一般的なガイドラインです。
DeviceAsWebcam
サービスでサポートされているストリーム形式は、MJPEG と非圧縮 YUYV の 2 つです。- USB 2.0 は、480 Mbps(60 MBps)のデータ転送をサポートしています。つまり、30 fps の場合、各フレームの最大サイズは 2 MB、60 fps の場合、最大サイズは 1 MB である必要があります。
- 非圧縮ストリーム(YUYV): YUYV は 1 ピクセルあたり 2 バイトであるため、30 fps の場合、サポートされる最大フレームサイズは 720p です。
- 圧縮 MJPEG ストリーム: YUV の圧縮率を 1:10 と仮定すると、USB 2.0 は 4K(1 フレームあたり 1.18 MB)をサポートできます。
- メインの前面カメラと背面カメラを搭載したデバイスは、アドバタイズされているすべてのフレームサイズをサポートする必要があります。これは、ユーザーがプレビュー UI を使用してカメラ ID を切り替えることができるためです。MJPEG ストリームに関しては、480p(640 x 480)、720p(1280 x 820)、1080p(1920 x 1080)のフレームサイズをアドバタイズすることをベンダーに推奨しています。これらがホストアプリで一般的に使用されているサイズであるためです。
- メインの前面カメラと背面カメラを搭載したデバイスは、アドバタイズされているすべてのフレームレートをサポートする必要があります。ベンダーには、30 fps をサポートすることを強く推奨しています。
ウェブカメラのストリーム構成の追加(ConfigFS)に関する例については、AOSP のサンプルパッチを参照してください。
ビルド時にウェブカメラを有効化する
DeviceAsWebcam
サービスを有効にするには、device.mk
ファイルで ro.usb.uvc.enabled
のシステム プロパティを true
に設定する必要があります。
# Enable UVC support
PRODUCT_VENDOR_PROPERTIES += \
ro.usb.uvc.enabled=true
このシステム プロパティを有効にすると、図 3 に示すように、設定アプリの [USB の設定] にウェブカメラのオプションが表示されます。ウェブカメラが選択されると、ホストデバイスに USB ウェブカメラとして Android デバイスが表示されます。
図 3. 設定アプリの [USB の設定]
以下のコマンドを使用して、ADB 経由でデバイスを USB ウェブカメラのモードに設定することもできます。
adb shell svc usb setFunctions uvc
電力や熱に関する懸念を考慮する
デバイスをウェブカメラとして使用すると、デバイスのカメラがオンになっている状態が 1 日に何時間も続く可能性があるため、デバイスの消費電力と熱を一定の制限内に抑えるための対策を行うことをおすすめします。以下は、消費電力を制限内に抑えるために推奨される解決策です。
- カメラ HAL の電力パフォーマンスを向上させるために、
DeviceAsWebcam
サービスでSTREAM_USE_CASE_VIDEO_CALL
を有効にします。 STREAM_USE_CASE_VIDEO_CALL
を有効にしても、まだ消費電力が懸念される場合、DeviceAsWebcam
サービスでは、物理ストリームを使用することで、消費電力をさらに削減することが可能です。ランタイム リソース オーバーレイ(RRO)を使って、どの物理カメラを使用するかを指定することができます。ただし、物理ストリームは動画の品質を著しく低下させ、ユーザーに混乱を与えるため、この解決策は最後の手段として使用してください。電力についての懸念に対する解決策としては、STREAM_USE_CASE_VIDEO_CALL
の最適化をおすすめします。DeviceAsWebcam
サービスがサポートする RRO の詳細については、readme.md をご覧ください。以下は、論理カメラ ID 0 の代わりに物理カメラ ID 3 を使用する際の RRO の設定例です。また、AOSP の例については、DeviceAsWebcamRaven をご覧ください。
// For logical camera id 0 - use physical camera id 3 {"0": {"3" : "UW"}}
確認
デバイス上の DeviceAsWebcam
サービスの実装をテストするには、以下を使用します。
- CTS 検証ツールによるウェブカメラのテスト: 形式、サイズ、フレームレートがデバイスでサポートされているかをテストします。
- 手動テスト: ウェブカメラの機能がさまざまなホスト オペレーティング システム上のさまざまなホストアプリで動作するかをテストします。
既知の問題
以下は、DeviceAsWebcam
サービスに関する既知の問題です。
UVC ガジェット ドライバのストリームがときどきちらつき、フレームが破損しているように見えることがあります。この問題は修正され、アップストリームおよび GKI にマージされています。
Apple の UVC ドライバに存在するバグにより、Android デバイスがウェブカメラ モードで使用されている際、macOS ホストで USB 3.0 以上のケーブルが機能しません。