Używanie urządzenia jako kamery internetowej

Na urządzeniach z Androidem 14-QPR1 lub nowszym można używać ich jako kamery internetowej USB. Urządzenia z Androidem obsługujące tę funkcję są reklamowane jako urządzenia UVC, które umożliwiają wielu hostom USB z różnymi systemami operacyjnymi (np. Linux, macOS, Windows i ChromeOS) używanie 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 działanie podglądu (DeviceAsWebcamPreview.java), które umożliwia użytkownikom kadrowanie sceny. Podgląd pozwala użytkownikowi:

  • Przed rozpoczęciem transmisji sprawdź, jak obraz z kamery internetowej będzie wyglądał na hoście.

  • Dostosuj obraz z kamery internetowej wysyłany do hosta w jeden z tych sposobów:

    • wybór kamery do transmitowania – z przodu lub z tyłu;
    • Wybieranie poziomu powiększenia za pomocą suwaka lub przycisków.
    • Kliknij wybrany obszar podglądu, aby ustawić lub usunąć zaznaczenie.

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

transmisja z kamery internetowej na serwer

Rysunek 1. Przesyłany obraz z kamery internetowej do hosta z podglądem, który kontroluje kanał.

Architektura

Architektura umożliwiająca korzystanie z urządzenia jako kamery internetowej przedstawiamy na rys. 2. Poniżej opisujemy przepływ interakcji usługi DeviceAsWebcam z resztą platformy Androida:

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

urządzenie jako architektura kamery internetowej

Rysunek 2. Architektura DeviceAsWebcam.

Implementacja

W tej sekcji opisano obsługę korzystania z urządzenia z Androidem jako kamery internetowej.

Obsługa jądra systemu

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

Obsługa UVC w HAL gadżetów

Od Androida 14 funkcja UVC jest dostępna w interfejsie HAL GadgetFunction.aidl. gadżet UVC w HAL gadżetów podłącza się do ConfigFS w taki sam sposób, jak inne funkcje ConfigFS, takie jak MTP lub ADB.

Aby wdrożyć HAL gadżetów, wprowadź zmiany w celu podłączenia funkcji UVC do pliku ConfigFS. Poniżej znajdziesz przykładowy fragment kodu HAL gadżetu, który obsługuje 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
       ...
   }
   ...
}

Jeśli urządzenie działa jak kamera internetowa, upewnij się, że HAL gadżetu USB reklamuje odpowiednie kombinacje VID i PID.

Ponieważ cała logika UVC znajduje się w inicjowaniu dostawcy lub w usłudze DeviceAsWebcam, w HAL gadżetów nie jest wymagana żadna logika UVC poza powiązaniem symbolicznym funkcji UVC z konfiguracją ConfigFS.

Więcej wskazówek dotyczących implementacji znajdziesz w tym przykładowym kodzie w AOSP:

Konfigurowanie ConfigFS z konfiguracjami UVC

Aby przekazać sterownikowi gadżetu UVC informacje o formatach, rozmiarach i liczbach klatek obsługiwanych przez kamerę internetową z Androidem, skonfiguruj ConfigFS z konfiguracjami UVC. Więcej informacji znajdziesz w dokumentacji dotyczącej systemu Linux poświęconej gadżetowi ABI UVC i interfejsowi ConfigFS UVC.

Poniżej znajduje się 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 do reklamowania strumienia MJPEG w rozdzielczości 1080p z szybkością 30 kl./s. Te możliwości są przekazywane do hosta USB, gdy wysyła zapytanie o obsługiwane rozdzielczości i liczbę klatek.

Oto ogólne wskazówki dotyczące wyboru konfiguracji reklamowanych przez kamerę internetową:

  • Usługa DeviceAsWebcam obsługuje dwa formaty strumienia, czyli MJPEG i nieskompresowany YUYV.
  • USB 2.0 umożliwia przesyłanie danych z szybkością 480 Mb/s (60 Mb/s). Oznacza to, że przy 30 klatkach na sekundę maksymalna klatka to 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 YUV 1:10 USB 2.0 obsługuje rozdzielczość 4K (1,18 MB na klatkę).
  • Główne urządzenia z przednim i tylnym aparatem muszą obsługiwać wszystkie reklamowane rozmiary klatek. 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, by dostawcy reklamowali rozmiary 480p (640 x 480), 720p (1280 x 820) i 1080p (1920 x 1080), ponieważ są to rozmiary powszechnie używane w aplikacjach hostujących.
  • Główne urządzenia z przednim i tylnym aparatem muszą obsługiwać wszystkie reklamowane liczby klatek. Zdecydowanie zalecamy, by dostawcy obsługiwały 30 klatek na sekundę.

Przykład dodawania konfiguracji strumienia z kamery internetowej (ConfigFS) znajdziesz na stronie z przykładową poprawką AOSP.

Włącz kamerę internetową w kompilacji

Aby włączyć usługę DeviceAsWebcam, ustaw 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 usługa systemowa jest włączona, w aplikacji Ustawienia w sekcji Ustawienia USB pojawia się opcja Kamera internetowa, tak jak na ilustracji 3. Po wybraniu tej opcji urządzenie z Androidem będzie widoczne dla urządzenia jako kamera internetowa USB.

Rysunek 3. Ustawienia USB w aplikacji Ustawienia.

Możesz też ustawić na urządzeniu funkcję kamery internetowej USB, korzystając z tego polecenia:

adb shell svc usb setFunctions uvc

Weź pod uwagę problemy z zasilaniem i temperaturą

Działanie kamery internetowej oznacza, że kamera w urządzeniu może być włączona przez kilka godzin dziennie, dlatego zalecamy, aby zużywać energię i utrzymywać w niej temperaturę. Oto zalecane rozwiązania pozwalające utrzymać zużycie energii poniżej limitów:

  • Aby uzyskać większą wydajność z poziomu HAL aparatu, włącz STREAM_USE_CASE_VIDEO_CALL w usłudze DeviceAsWebcam.
  • Jeśli nawet przy włączonym STREAM_USE_CASE_VIDEO_CALL masz problem z zasilaniem, usługa DeviceAsWebcam udostępnia opcję dalszego ograniczenia zużycia energii za pomocą strumieni fizycznych. Możesz użyć nakładek zasobów środowiska wykonawczego, aby określić, którego fizycznego aparatu chcesz używać. Strumieniowanie fizyczne znacznie obniża jakość filmu i prowadzi użytkownika w błąd, dlatego należy korzystać z tego rozwiązania tylko w ostateczności. Optymalizowanie STREAM_USE_CASE_VIDEO_CALL to preferowane rozwiązanie do rozwiązywania problemów. Więcej informacji na temat RRO obsługiwanych przez usługę DeviceAsWebcam znajdziesz w pliku readme.md.

    Poniżej znajdziesz przykład konfiguracji RRO korzystającej z identyfikatora fizycznego aparatu 3 zamiast logicznego identyfikatora kamery 0. Przykład w AOSP znajdziesz na stronie DeviceAsWebcamRaven.

    // For logical camera id 0 - use physical camera id 3
    {"0": {"3" : "UW"}}
    

Weryfikacja

Aby sprawdzić implementację usługi DeviceAsWebcam na urządzeniu, przeprowadź te testy:

  • Kamera internetowa – test weryfikatora CTS: sprawdź, czy urządzenie obsługuje formaty, rozmiary i liczba klatek.
  • Testy ręczne: sprawdź, czy funkcja kamery internetowej współpracuje z różnymi aplikacjami hostującymi na różnych systemach operacyjnych.

Znane problemy

Oto znane problemy dotyczące usługi DeviceAsWebcam: