Używanie urządzenia jako kamery internetowej

W przypadku urządzeń z Androidem 14 QPR1 lub nowszym Android obsługuje używanie urządzenia jako kamery internetowej USB. Urządzenia z Androidem obsługujące tę funkcję są reklamowane jako urządzenie UVC, co umożliwia korzystanie z aparatu urządzenia jako kamery internetowej na wielu hostach USB z różnymi systemami operacyjnymi (np. Linux, macOS, Windows i ChromeOS). Usługa DeviceAsWebcam obsługuje tę funkcję, dzięki czemu można 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 wykonanie tych czynności:

  • Wyświetlanie podglądu tego, jak obraz z kamery internetowej będzie wyglądać na komputerze hosta przed rozpoczęciem transmisji.

  • Dostosowywanie obrazu z kamery internetowej wysyłanego do hosta na te sposoby:

    • Wybieranie kamery do transmisji – przedniej lub tylnej.
    • Wybieranie poziomu powiększenia za pomocą suwaka lub przycisków.
    • Klikanie określonego regionu podglądu, aby ustawić ostrość lub ją usunąć.

Aktywność podglądu działa z ogólnymi funkcjami ułatwień dostępu w Androidzie, takimi jak TalkBack, Switch Access i Voice Access.

przekaz z kamery internetowej przesyłany do hosta,

Rysunek 1. Obraz z kamery internetowej przesyłany do hosta z podglądem sterującym obrazem.

Architektura

Architekturę obsługi używania urządzenia jako kamery internetowej przedstawia rysunek 2. Poniżej opisujemy przepływ interakcji usługi DeviceAsWebcam z resztą platformy Android:

  1. Użytkownik wybiera opcję kamery internetowej USB w aplikacji Ustawienia.
  2. Aplikacja Ustawienia wysyła wywołanie bindera do system_server za pomocą klasy UsbManager, informując ją, że wybrano FUNCTION_UVC.
  3. Serwer systemowy wykonuje te czynności:
    1. Informuje komponent HAL gadżetu USB, aby pobrać funkcję gadżetu UVC za pomocą wywołania interfejsu HAL setUsbFunctions.
    2. Informuje komponent HAL gadżetu USB, aby skonfigurować sterownik gadżetu UVC za pomocą ConfigFS.
  4. Po otrzymaniu wywołania zwrotnego z komponentu HAL gadżetu system_server wysyła transmisję do platformy, która ma zostać odebrana przez usługę DeviceAsWebcam.
  5. Sterownik gadżetu USB uruchamia strumień kamery internetowej po otrzymaniu poleceń konfiguracji od hosta za pomocą węzłów V4L2 w /dev/video*.

architektura urządzenia jako kamery internetowej,

Rysunek 2. Architektura DeviceAsWebcam.

Implementacja

W tej sekcji opisujemy, jak obsługiwać używanie urządzenia z Androidem jako kamery internetowej.

Obsługa jądra

W Androidzie 14 lub nowszym ogólny obraz jądra (GKI) domyślnie włącza sterownik gadżetu UVC (szczegóły znajdziesz w poprawce AOSP).

Obsługa UVC w komponencie HAL gadżetu

Od Androida 14 funkcja UVC jest zawarta w GadgetFunction.aidl interfejsie HAL. W przypadku komponentu HAL gadżetu gadżet UVC jest montowany w ConfigFS w taki sam sposób jak inne funkcje ConfigFS, takie jak MTP czy ADB.

Aby zaimplementować komponent HAL gadżetu, wprowadź zmiany, aby zamontować funkcję UVC w ConfigFS. Oto przykładowy fragment implementacji komponentu 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, upewnij się, że komponent HAL gadżetu USB reklamuje prawidłowe kombinacje VID/PID.

Ponieważ cała logika UVC znajduje się w inicjowaniu dostawcy lub w usłudze DeviceAsWebcam, w komponencie HAL gadżetu nie jest wymagana żadna logika specyficzna dla UVC poza symlinkowaniem 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, jakie formaty, rozmiary i liczby klatek na sekundę są obsługiwane przez kamerę internetową Androida, skonfiguruj ConfigFS za pomocą konfiguracji UVC. Więcej informacji znajdziesz w dokumentacji upstreamu Linuxa na temat ConfigFS UVC gadżetu ABI.

Oto przykład, jak inicjowanie dostawcy 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 konfiguruje sterownik gadżetu UVC do reklamowania strumienia MJPEG o rozdzielczości 1080p i 30 klatkach na sekundę. Te możliwości są przekazywane do hosta USB, gdy ten wysyła zapytanie o obsługiwane rozdzielczości i liczby klatek na sekundę.

Oto ogólne wytyczne dotyczące wybierania konfiguracji reklamowanych przez kamerę internetową:

  • 2 formaty strumieni obsługiwane przez usługę DeviceAsWebcam to MJPEG i nieskompresowany YUYV.
  • USB 2.0 obsługuje przesyłanie danych z szybkością 480 Mb/s (60 MB/s). Oznacza to, że przy 30 klatkach na sekundę każdy klatka musi mieć maksymalny rozmiar 2 MB, a przy 60 klatkach na sekundę – 1 MB.
    • Nieskompresowane strumienie (YUYV): przy 30 klatkach na sekundę 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ć rozdzielczość 4K (1,18 MB na klatkę).
  • Główne urządzenia z przednim i tylnym aparatem muszą obsługiwać wszystkie reklamowane rozmiary klatek. Użytkownik może bowiem przełączać się między identyfikatorami aparatów 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ą to rozmiary powszechnie używane przez aplikacje hosta.
  • Główne urządzenia z przednim i tylnym aparatem muszą obsługiwać wszystkie reklamowane liczby klatek na sekundę. Zdecydowanie zalecamy, aby dostawcy obsługiwali 30 klatek na sekundę.

Przykład dodawania konfiguracji strumienia kamery internetowej (ConfigFS) znajdziesz w przykładowej poprawce AOSP.

Włączanie kamery internetowej w kompilacji

Aby włączyć usługę DeviceAsWebcam, musisz ustawić właściwość systemową ro.usb.uvc.enabled na true w pliku device.mk.

# Enable UVC support
PRODUCT_VENDOR_PROPERTIES += \
    ro.usb.uvc.enabled=true

Gdy ta właściwość systemowa jest włączona, w aplikacji Ustawienia w sekcji Preferencje USB pojawia się opcja Kamera internetowa (jak pokazano na rysunku 3). Gdy ta opcja jest wybrana, urządzenie z Androidem jest widoczne dla urządzenia hosta jako kamera internetowa USB.

Ustawienia USB w aplikacji Ustawienia

Rysunek 3. Preferencje USB w aplikacji Ustawienia.

Możesz też ustawić urządzenie na funkcję kamery internetowej USB za pomocą ADB, używając tego polecenia:

adb shell svc usb setFunctions uvc

Uwzględnianie kwestii związanych z zasilaniem i temperaturą

Działanie kamery internetowej oznacza, że aparat urządzenia może być włączony przez wiele godzin dziennie, dlatego zalecamy podjęcie środków, aby zużycie energii i temperatura urządzenia nie przekraczały określonych limitów. Oto zalecane rozwiązania, które pozwolą utrzymać zużycie energii w określonych limitach:

  • Aby poprawić wydajność energetyczną komponentu HAL aparatu, włącz STREAM_USE_CASE_VIDEO_CALL w usłudze DeviceAsWebcam.
  • Jeśli zużycie energii jest problemem nawet po włączeniu STREAM_USE_CASE_VIDEO_CALL, usługa DeviceAsWebcam umożliwia dalsze zmniejszenie zużycia energii przez używanie strumieni fizycznych. Możesz użyć nakładek zasobów czasu działania (RRO), aby określić, którego aparatu fizycznego używać. Strumienie fizyczne znacznie obniżają jakość obrazu i prowadzą do mylącego UX, dlatego używaj tego rozwiązania tylko w ostateczności. Optymalizacja STREAM_USE_CASE_VIDEO_CALL jest preferowanym rozwiązaniem problemów z zasilaniem. Więcej informacji o RRO obsługiwanych przez usługę DeviceAsWebcam znajdziesz w pliku readme.md.

    Oto przykład konfiguracji RRO, która używa fizycznego identyfikatora aparatu 3 zamiast logicznego identyfikatora aparatu 0. Przykład w AOSP znajdziesz w 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:

Znane problemy

Oto znane problemy z usługą DeviceAsWebcam: