W przypadku urządzeń z Androidem w wersji 14-QPR1 lub nowszej Android obsługuje korzystanie z urządzenia jako kamery internetowej USB. Urządzenia z Androidem obsługujące tę funkcję są reklamowane jako urządzenia UVC, co umożliwia wielu hostom USB z różnymi systemami operacyjnymi (np. Linux, macOS, Windows i ChromeOS) korzystanie z kamery urządzenia jako kamery internetowej. Usługa DeviceAsWebcam
obsługuje tę funkcję, aby można było używać urządzenia jako kamery internetowej.
Usługa DeviceAsWebcam
Usługa DeviceAsWebcam
w AOSP zawiera aktywność podglądu (DeviceAsWebcamPreview.java
), która umożliwia użytkownikom kadrowanie sceny. Aktywność podglądu umożliwia użytkownikowi:
Przed rozpoczęciem strumieniowania możesz wyświetlić podgląd obrazu z kamery internetowej na komputerze hosta.
Możesz dostosować obraz z kamery internetowej wysyłany do gospodarza na te sposoby:
- Wybór kamery do przesyłania strumieniowego: przednia lub tylna.
- Wybieranie poziomu powiększenia za pomocą suwaka lub przycisków.
- Kliknięcie konkretnego obszaru podglądu, aby go wyostrzyć lub usunąć.
Aktywność podglądu działa z ogólnymi funkcjami ułatwień dostępu na Androidzie, takimi jak TalkBack, Switch Access i Voice Access.
Rysunek 1. Podgląd obrazu z kamery internetowej przesyłanego do gospodarza.
Architektura
Architektura umożliwiająca używanie urządzenia jako kamery internetowej jest przedstawiona na rysunku 2. Poniżej opisujemy proces interakcji usługi DeviceAsWebcam
z resztą platformy Android:
- Użytkownik wybiera opcję kamery internetowej USB w aplikacji Ustawienia.
- Aplikacja Ustawienia wysyła do
system_server
wywołanie bindera za pomocą klasyUsbManager
, aby poinformować ją, że wybrana jestFUNCTION_UVC
. - Serwer systemowy wykonuje te czynności:
- Informuje interfejs HAL gadżetu USB o potrzebie pobrania funkcji gadżetu UVC za pomocą wywołania interfejsu
setUsbFunctions
. - Informuje HAL urządzenia USB, aby skonfigurować sterownik urządzenia UVC za pomocą ConfigFs.
- Informuje interfejs HAL gadżetu USB o potrzebie pobrania funkcji gadżetu UVC za pomocą wywołania interfejsu
- Po otrzymaniu wywołania zwrotnego z interfejsu HAL gadżetu
system_server
wysyła do frameworku transmisję danych, którą usługaDeviceAsWebcam
ma odebrać. - Sterownik gadżetu USB uruchamia strumień kamery internetowej po otrzymaniu poleceń konfiguracyjnych od hosta za pośrednictwem węzłów V4L2 na poziomie
/dev/video*
.
Rysunek 2. Architektura DeviceAsWebcam
Implementacja
Z tej sekcji dowiesz się, jak korzystać z urządzenia z Androidem jako kamery internetowej.
Obsługa jądra
W przypadku Androida 14 lub nowszego obraz Generic Kernel Image (GKI) domyślnie włącza sterownik gadżetu UVC (szczegóły znajdziesz w łatce AOSP).
Obsługa UVC w interfejsie HAL gadżetu
Począwszy od Androida 14 funkcja UVC jest dostępna w interfejsie HAL GadgetFunction.aidl
. W przypadku interfejsu HAL gadżetu urządzenie UVC jest montowane w systemie ConfigFS w taki sam sposób jak inne funkcje ConfigFS, takie jak MTP czy ADB.
Aby zaimplementować interfejs HAL gadżetu, wprowadź modyfikacje, aby zamontować funkcję UVC w ConfigFS. Oto przykładowy fragment implementacji interfejsu HAL gadżetu obsługującego funkcję UVC:
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
...
}
...
}
Gdy urządzenie działa jako kamera internetowa, sprawdź, czy interfejs HAL gadżetu USB reklamuje prawidłowe kombinacje VID/PID.
Ponieważ cała logika UVC znajduje się w inicjalizacji dostawcy lub w usłudze DeviceAsWebcam
, w interfejsie HAL gadżetu nie jest wymagana żadna logika związana z UVC, oprócz linku symbolicznego funkcji UVC do ConfigFS.
Więcej wskazówek dotyczących implementacji znajdziesz w tym przykładowym kodzie w AOSP:
Konfigurowanie ConfigFS za pomocą konfiguracji UVC
Aby poinformować sterownik gadżetu UVC, które formaty, rozmiary i szybkości klatek są obsługiwane przez kamerę internetową na Androida, skonfiguruj ConfigFS za pomocą konfiguracji UVC. Więcej informacji znajdziesz w dokumentacji upstream Linuxa dotyczącej interfejsu ConfigFS UVC gadget ABI.
Poniżej przedstawiamy przykład tego, jak dostawca może skonfigurować sterownik gadżetu UVC (fragment kodu w 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
# ...
Ten fragment kodu konfiguruje sterownik gadżetu UVC, aby wyświetlał strumień MJPEG 1080p z szybkością 30 fps. Te możliwości są przekazywane do hosta USB, gdy ten przesyła zapytania dotyczące obsługiwanych rozdzielczości i liczb klatek.
Oto ogólne wskazówki dotyczące wyboru konfiguracji reklamowanych przez kamerę internetową:
- Dwa formaty strumieni danych obsługiwane przez usługę
DeviceAsWebcam
to MJPEG i niezduplikowane YUYV. - USB 2.0 obsługuje transfer danych z prędkością 480 Mb/s (60 MBps). Oznacza to, że przy 30 fps rozmiar każdej klatki nie może przekraczać 2 MB, a przy 60 fps – 1 MB.
- Nieskompresowane strumienie (YUYV): przy 30 fps maksymalny obsługiwany rozmiar klatki to 720p, ponieważ YUYV to 2 bajty na piksel.
- Skompresowane strumienie MJPEG: przy założeniu współczynnika kompresji 1:10 z YUV USB 2.0 może obsługiwać 4K (1,18 MB na ramkę).
- Główne przednie i tylne aparaty muszą obsługiwać wszystkie rozmiary ramki, które są reklamowane. Dzieje się tak, ponieważ użytkownik może przełączać się między identyfikatorami kamer za pomocą interfejsu podglądu. W przypadku strumieni MJPEG zalecamy, aby dostawcy reklamowali rozmiary klatek 480p (640 x 480), 720p (1280 x 820) i 1080p (1920 x 1080), ponieważ są one często używane przez aplikacje hostujące.
- Główne przednie i tylne aparaty muszą obsługiwać wszystkie częstotliwości klatek, które są reklamowane. Zdecydowanie zalecamy, aby dostawcy obsługiwali 30 FPS.
Przykład dodawania konfiguracji strumienia z kamery internetowej (ConfigFS) znajdziesz w artykule Przykładowy pakiet poprawek AOSP.
Włączanie kamery internetowej w kompilacji
Aby włączyć usługę DeviceAsWebcam
, musisz w pliku device.mk
ustawić właściwość systemową ro.usb.uvc.enabled
na true
.
# Enable UVC support
PRODUCT_VENDOR_PROPERTIES += \
ro.usb.uvc.enabled=true
Gdy ta właściwość systemu jest włączona, w aplikacji Ustawienia w ustawieniach USB pojawia się opcja Kamera internetowa, jak pokazano na rysunku 3. Gdy ta opcja jest wybrana, urządzenie z Androidem będzie widoczne dla urządzenia hosta jako kamera USB.
Rysunek 3. Ustawienia USB w aplikacji Ustawienia.
Możesz też ustawić urządzenie jako kamerę internetową USB za pomocą ADB, używając tego polecenia:
adb shell svc usb setFunctions uvc
Zastanów się nad kwestiami związanymi z mocą i temperaturą.
Użycie kamery internetowej oznacza, że kamera urządzenia może być włączona przez wiele godzin dziennie, dlatego zalecamy podjęcie działań, aby zużycie energii i temperatura urządzenia nie przekraczały określonych limitów. Oto zalecane rozwiązania, które pozwolą ograniczyć zużycie energii:
- Aby uzyskać lepszą wydajność energetyczną komponentu HAL aparatu, włącz
STREAM_USE_CASE_VIDEO_CALL
w usłudzeDeviceAsWebcam
. Jeśli zasilanie jest problemem nawet przy włączonym trybie
STREAM_USE_CASE_VIDEO_CALL
, usługaDeviceAsWebcam
umożliwia dalsze zmniejszenie zużycia energii przez wykorzystanie strumieni fizycznych. Aby określić, której kamery fizycznej użyć, możesz użyć nakładek zasobów w czasie wykonywania (RRO). Strumienie fizyczne znacznie obniżają jakość obrazu i powodują dezorientację użytkownika, dlatego stosuj to rozwiązanie tylko w ostateczności. OptymalizacjaSTREAM_USE_CASE_VIDEO_CALL
jest preferowanym rozwiązaniem w przypadku problemów z zasilaniem. Więcej informacji o RRO obsługiwanych przez usługęDeviceAsWebcam
znajdziesz w pliku readme.md.Poniżej przedstawiamy przykład konfiguracji RRO, która używa fizycznego identyfikatora kamery 3 zamiast logicznego identyfikatora kamery 0. Przykład w AOSP: DeviceAsWebcamRaven.
// For logical camera id 0 - use physical camera id 3 {"0": {"3" : "UW"}}
Weryfikacja
Aby przetestować implementację usługi DeviceAsWebcam
na urządzeniu, użyj tych testów:
- Test weryfikatora CTS dotyczący kamery internetowej: sprawdź, czy urządzenie obsługuje formaty, rozmiary i liczbę klatek na sekundę.
- Testy ręczne: sprawdź, czy funkcja kamery internetowej działa z różnymi aplikacjami hosta w różnych systemach operacyjnych.
Znane problemy
Poniżej opisaliśmy znane problemy z usługą DeviceAsWebcam
:
Strumień sterownika gadżetu UVC czasami miga i wyświetla zniekształcone klatki. Ten problem został rozwiązany i połączony w upstream oraz w GKI.
Urządzenia z Androidem w trybie kamery internetowej nie działają z kablami USB 3.0 i nowszymi na hostach z macOS z powodu błędu w sterowniku UVC firmy Apple.