Auf Geräten mit Android 14-QPR1 oder höher unterstützt Android die Verwendung des Geräts als USB-Webcam. Android-Geräte, die diese Funktion unterstützen, werden als UVC-Gerät beworben. Dadurch kann die Kamera des Geräts als Webcam von einer Vielzahl von USB-Hosts mit verschiedenen Betriebssystemen (z. B. Linux, macOS, Windows und ChromeOS) verwendet werden. Der Dienst DeviceAsWebcam
unterstützt diese Funktion, damit das Gerät als Webcam verwendet werden kann.
„Gerät als Webcam“-Dienst
Der DeviceAsWebcam
-Dienst in AOSP enthält eine Vorschauaktivität (DeviceAsWebcamPreview.java
), mit der Nutzer die Szene einrahmen können. In der Vorschau können Nutzer Folgendes tun:
Sie können sich eine Vorschau des Webcam-Feeds auf dem Hostcomputer ansehen, bevor der Stream beginnt.
Sie können den an den Host gesendeten Webcam-Feed auf folgende Weise anpassen:
- Auswahl der Kamera für den Stream, entweder Front- oder Rückkamera.
- Die Zoomstufe wird über einen Schieberegler oder Schaltflächen ausgewählt.
- Tippen Sie auf einen bestimmten Bereich der Vorschau, um den Fokus auf diesen Bereich zu legen oder zu entfernen.
Die Vorschauaktivität funktioniert mit allgemeinen Bedienungshilfen unter Android wie TalkBack, Schalterzugriff und Voice Access.
Abbildung 1: Webcam-Feed wird an einen Host gestreamt, der den Feed über die Vorschau steuert.
Architektur
Die Architektur, die die Verwendung eines Geräts als Webcam unterstützt, ist in Abbildung 2 dargestellt. Im Folgenden wird der Interaktionsablauf des DeviceAsWebcam
-Dienstes mit dem Rest des Android-Frameworks beschrieben:
- Der Nutzer wählt in den Einstellungen die Option „USB-Webcam“ aus.
- Die Einstellungen-App sendet über die Klasse
UsbManager
einen Binder-Aufruf ansystem_server
und informiert sie darüber, dassFUNCTION_UVC
ausgewählt ist. - Der Systemserver führt folgende Schritte aus:
- Informiert die USB-Gadget-HAL, dass die UVC-Gadget-Funktion über einen
setUsbFunctions
-HAL-Schnittstellenaufruf abgerufen werden soll. - Informiert die USB-Gadget-HAL, den UVC-Gadget-Treiber mit ConfigFs zu konfigurieren.
- Informiert die USB-Gadget-HAL, dass die UVC-Gadget-Funktion über einen
- Nachdem
system_server
einen Callback von der Gadget-HAL erhalten hat, sendet es einen Broadcast an das Framework, der vomDeviceAsWebcam
-Dienst empfangen wird. - Der USB-Gadget-Treiber startet den Webcam-Stream, wenn er Konfigurationsbefehle vom Host über V4L2-Knoten unter
/dev/video*
empfängt.
Abbildung 2: DeviceAsWebcam-Architektur.
Implementierung
In diesem Abschnitt wird beschrieben, wie Sie die Verwendung eines Android-Geräts als Webcam unterstützen.
Kernel-Unterstützung
Unter Android 14 oder höher wird der UVC-Gadget-Treiber standardmäßig durch das Generic Kernel Image (GKI) aktiviert (siehe Details im AOSP-Patch).
UVC im Gadget-HAL unterstützen
Ab Android 14 ist die UVC-Funktion in der HAL-Schnittstelle GadgetFunction.aidl
enthalten. Für das Gadget-HAL wird das UVC-Gadget auf dieselbe Weise in ConfigFS eingebunden wie andere ConfigFS-Funktionen wie MTP oder ADB.
Um das Gadget-HAL zu implementieren, müssen Sie Änderungen vornehmen, um die UVC-Funktion in ConfigFS einzubinden. Das folgende Snippet ist ein Beispiel für eine Gadget HAL-Implementierung, die die UVC-Funktion unterstützt:
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
...
}
...
}
Wenn das Gerät als Webcam fungiert, muss die USB-Gadget-HAL die richtigen VID/PID-Kombinationen ankündigen.
Da sich die gesamte UVC-Logik entweder in der Anbieterinitialisierung oder im DeviceAsWebcam
-Dienst befindet, ist im Gadget-HAL keine UVC-spezifische Logik erforderlich, außer dem Erstellen eines symbolischen Links für die UVC-Funktion zu ConfigFS.
Weitere Informationen zur Implementierung finden Sie im folgenden Beispielcode in AOSP:
ConfigFS mit UVC-Konfigurationen einrichten
Damit der UVC-Gadget-Treiber weiß, welche Formate, Größen und Bildraten von der Android-Webcam unterstützt werden, müssen Sie ConfigFS mit UVC-Konfigurationen einrichten. Weitere Informationen finden Sie in der Upstream-Linux-Dokumentation zum ConfigFS UVC-Gadget-ABI.
Das folgende Beispiel zeigt, wie der UVC-Gadget-Treiber mit der Anbieterinitialisierung eingerichtet werden kann (Code-Snippet in 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
# ...
Mit diesem Snippet wird der UVC-Gadget-Treiber so eingerichtet, dass ein 1080p-MJPEG-Stream mit 30 fps beworben wird. Diese Funktionen werden dem USB-Host mitgeteilt, wenn er unterstützte Auflösungen und Frameraten abfragt.
Im Folgenden finden Sie allgemeine Richtlinien für die Auswahl der Konfigurationen, die die Webcam bewirbt:
- Die beiden vom
DeviceAsWebcam
-Dienst unterstützten Streamformate sind MJPEG und unkomprimiertes YUYV. - USB 2.0 unterstützt die Übertragung von Daten mit 480 Mbit/s (60 MB/s). Das bedeutet, dass bei 30 fps jeder Frame eine maximale Größe von 2 MB und bei 60 fps eine maximale Größe von 1 MB haben darf.
- Unkomprimierte Streams (YUYV): Bei 30 fps beträgt die maximal unterstützte Framegröße 720p, da YUYV 2 Byte pro Pixel umfasst.
- Komprimierte MJPEG-Streams: Bei einem Komprimierungsverhältnis von 1:10 von YUV kann USB 2.0 4K (1,18 MB pro Frame) unterstützen.
- Die primären Front- und Rückkameras müssen alle beworbenen Bildgrößen unterstützen. Das liegt daran, dass der Nutzer über die Vorschau-UI zwischen Kamera-IDs wechseln kann. Für MJPEG-Streams empfehlen wir Anbietern, die Bildgrößen 480p (640 × 480), 720p (1280 × 820) und 1080p (1920 × 1080) anzugeben, da diese Größen häufig von Host-Apps verwendet werden.
- Die primären Geräte für die Front- und Rückkamera müssen alle beworbenen Bildraten unterstützen. Wir empfehlen Anbietern dringend, 30 fps zu unterstützen.
Ein Beispiel für das Hinzufügen von Webcam-Stream-Konfigurationen (ConfigFS) finden Sie im AOSP-Beispielpatch.
Webcam im Build aktivieren
Wenn Sie den Dienst DeviceAsWebcam
aktivieren möchten, müssen Sie das Systemattribut ro.usb.uvc.enabled
in der Datei device.mk
auf true
festlegen.
# Enable UVC support
PRODUCT_VENDOR_PROPERTIES += \
ro.usb.uvc.enabled=true
Wenn diese Systemeigenschaft aktiviert ist, wird in den Einstellungen unter USB-Einstellungen die Option Webcam angezeigt (siehe Abbildung 3). Wenn die Option ausgewählt ist, wird das Android-Gerät auf dem Hostgerät als USB-Webcam angezeigt.
Abbildung 3: USB-Einstellungen in der App „Einstellungen“
Sie können das Gerät auch über ADB mit diesem Befehl auf die USB-Webcam-Funktion einstellen:
adb shell svc usb setFunctions uvc
Leistungs- und thermische Aspekte berücksichtigen
Wenn die Kamera eines Geräts mehrere Stunden am Tag eingeschaltet ist, empfehlen wir, Maßnahmen zu ergreifen, um sicherzustellen, dass der Stromverbrauch und die Wärmeentwicklung des Geräts innerhalb bestimmter Grenzwerte bleiben. Im Folgenden finden Sie empfohlene Lösungen, um den Stromverbrauch unter den Grenzwerten zu halten:
- Damit die Kamera-HAL eine bessere Leistung erzielt, aktivieren Sie
STREAM_USE_CASE_VIDEO_CALL
imDeviceAsWebcam
-Dienst. Wenn der Stromverbrauch auch bei aktivierter
STREAM_USE_CASE_VIDEO_CALL
ein Problem darstellt, bietet derDeviceAsWebcam
-Dienst die Möglichkeit, den Stromverbrauch durch die Verwendung physischer Streams weiter zu senken. Mit RROs (Runtime Resource Overlays) können Sie angeben, welche physische Kamera verwendet werden soll. Physische Streams verschlechtern die Videoqualität erheblich und führen zu einer verwirrenden Benutzeroberfläche. Verwenden Sie diese Lösung daher nur als letzten Ausweg. Die Optimierung vonSTREAM_USE_CASE_VIDEO_CALL
ist die bevorzugte Lösung, um Probleme mit der Stromversorgung zu beheben. Weitere Informationen zu den vomDeviceAsWebcam
-Dienst unterstützten RROs finden Sie in der Datei readme.md.Im Folgenden sehen Sie ein Beispiel für ein RRO, das für die Verwendung der physischen Kamera-ID 3 anstelle der logischen Kamera-ID 0 eingerichtet ist. Ein Beispiel in AOSP finden Sie unter DeviceAsWebcamRaven.
// For logical camera id 0 - use physical camera id 3 {"0": {"3" : "UW"}}
Bestätigung
Verwenden Sie die folgenden Tests, um die Implementierung des DeviceAsWebcam
-Dienstes auf Ihrem Gerät zu testen:
- CTS-Verifier-Test Webcam: Testen, ob Formate, Größen und Bildraten vom Gerät unterstützt werden.
- Manuelle Tests: Testen Sie, ob die Webcam-Funktion mit einer Vielzahl von Host-Apps auf einer Vielzahl von Host-Betriebssystemen funktioniert.
Bekannte Probleme
Die folgenden Probleme sind für den DeviceAsWebcam
-Dienst bekannt:
Der Stream des UVC-Gadget-Treibers flackert manchmal und zeigt anscheinend beschädigte Frames. Dieses Problem wurde behoben und in Upstream und GKI zusammengeführt.
Android-Geräte im Webcam-Modus funktionieren aufgrund eines Fehlers im UVC-Treiber von Apple nicht mit USB 3.0-Kabeln auf macOS-Hosts.