Для устройств под управлением Android 14-QPR1 или выше Android поддерживает использование устройства в качестве USB-веб-камеры. Устройства Android, поддерживающие эту функцию, рекламируются как UVC-устройство , что позволяет широкому спектру USB-хостов с различными операционными системами (например, Linux, macOS, Windows и ChromeOS) использовать камеру устройства в качестве веб-камеры. Служба DeviceAsWebcam
поддерживает эту функцию для использования устройства в качестве веб-камеры.
Сервис DeviceAsWebcam
Служба DeviceAsWebcam
в AOSP включает в себя действие предварительного просмотра ( DeviceAsWebcamPreview.java
), которое позволяет пользователям кадрировать сцену. Действие предварительного просмотра позволяет пользователю делать следующее:
Перед началом трансляции просмотрите, как будет выглядеть трансляция с веб-камеры на хост-компьютере.
Настройте трансляцию с веб-камеры, отправляемую на хост, следующими способами:
- Выбор камеры для трансляции: передняя или задняя.
- Выбор уровня масштабирования с помощью ползунка или кнопок.
- Нажатие на определенную область предварительного просмотра позволяет сфокусироваться на ней или снять фокус.
Функция предварительного просмотра работает с общими функциями специальных возможностей на Android, такими как TalkBack , Switch Access и Voice Access .
Рисунок 1. Трансляция с веб-камеры на хост с предварительным просмотром, управляющим трансляцией.
Архитектура
Архитектура для поддержки использования устройства в качестве веб-камеры представлена на рисунке 2. Ниже описывается поток взаимодействия службы DeviceAsWebcam
с остальной частью фреймворка Android:
- Пользователь выбирает опцию USB-веб-камеры в приложении «Настройки».
- Приложение «Настройки» отправляет вызов связывателя в
system_server
через классUsbManager
, информируя его о том, что выбранFUNCTION_UVC
. - Системный сервер выполняет следующие действия:
- Сообщает HAL USB-гаджета о необходимости извлечения функции UVC-гаджета посредством вызова интерфейса HAL
setUsbFunctions
. - Сообщает HAL USB-гаджета о необходимости настройки драйвера UVC-гаджета с помощью ConfigFs.
- Сообщает HAL USB-гаджета о необходимости извлечения функции UVC-гаджета посредством вызова интерфейса HAL
- Получив обратный вызов от HAL гаджета,
system_server
отправляет широковещательный сигнал фреймворку для его приема службойDeviceAsWebcam
. - Драйвер USB-гаджета запускает поток веб-камеры после получения команд конфигурации от хоста через узлы V4L2 в
/dev/video*
.
Рисунок 2. Архитектура DeviceAsWebcam.
Выполнение
В этом разделе описывается, как использовать Android-устройство в качестве веб-камеры.
Поддержка ядра
Для Android 14 и выше образ Generic Kernel Image (GKI) включает драйвер гаджета UVC по умолчанию (подробности см. в патче AOSP ).
Поддержка UVC в гаджете HAL
Начиная с Android 14, функция UVC включена в интерфейс GadgetFunction.aidl
HAL. Для Gadget HAL гаджет UVC монтируется в ConfigFS так же, как и другие функции ConfigFS, такие как MTP или ADB.
Для реализации Gadget HAL внесите изменения для монтирования функции UVC в ConfigFS. Ниже приведен пример фрагмента реализации Gadget HAL, поддерживающего функцию 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
...
}
...
}
Когда устройство работает как веб-камера, убедитесь, что HAL USB-гаджета сообщает правильные комбинации VID/PID.
Поскольку вся логика UVC находится либо в init поставщика, либо в службе DeviceAsWebcam
, в HAL гаджета не требуется никакой специфической логики UVC, кроме символической ссылки функции UVC на ConfigFS.
Дополнительные рекомендации по реализации см. в следующем примере кода в AOSP:
Настройте ConfigFS с конфигурациями UVC
Чтобы сообщить драйверу гаджета UVC, какие форматы, размеры и частоты кадров поддерживаются веб-камерой Android, настройте ConfigFS с конфигурациями UVC. Для получения дополнительной информации см. документацию Linux upstream по ABI гаджета UVC ConfigFS .
Ниже приведен пример того, как вендор 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 кадров в секунду. Эти возможности передаются хосту USB, когда он запрашивает поддерживаемые разрешения и частоты кадров.
Ниже приведены общие рекомендации по выбору конфигураций, предлагаемых веб-камерой:
- Служба
DeviceAsWebcam
поддерживает два формата потока: MJPEG и несжатый YUYV. - USB 2.0 поддерживает передачу данных со скоростью 480 Мбит/с (60 МБ/с). Это означает, что при 30 кадрах в секунду каждый кадр должен иметь максимальный размер 2 МБ; а при 60 кадрах в секунду — максимальный размер 1 МБ.
- Несжатые потоки (YUYV): при 30 кадрах в секунду максимальный поддерживаемый размер кадра составляет 720p, поскольку YUYV составляет 2 байта на пиксель.
- Сжатые потоки MJPEG: при коэффициенте сжатия 1:10 от YUV USB 2.0 может поддерживать 4K (1,18 МБ на кадр).
- Основные устройства передней и задней камеры должны поддерживать все заявленные размеры кадра. Это связано с тем, что пользователь может переключаться между идентификаторами камер с помощью пользовательского интерфейса предварительного просмотра. Для потоков MJPEG мы рекомендуем поставщикам заявлять о размерах кадра 480p (640 x 480), 720p (1280 x 820) и 1080p (1920 x 1080), поскольку эти размеры обычно используются хост-приложениями.
- Основные устройства передней и задней камеры должны поддерживать все заявленные частоты кадров. Мы настоятельно рекомендуем поставщикам поддерживать 30 кадров в секунду.
Пример добавления конфигураций потока веб-камеры (ConfigFS) см. в примере патча AOSP .
Включить веб-камеру в сборке
Чтобы включить службу DeviceAsWebcam
, необходимо установить системное свойство ro.usb.uvc.enabled
в значении true
в файле device.mk
.
# Enable UVC support
PRODUCT_VENDOR_PROPERTIES += \
ro.usb.uvc.enabled=true
Если это системное свойство включено, в приложении «Настройки» в разделе настроек USB появляется опция «Веб-камера» , как показано на рисунке 3. Если эта опция выбрана, устройство Android отображается на хост-устройстве как веб-камера USB.
Рисунок 3. Настройки USB в приложении «Настройки».
Вы также можете настроить устройство на функцию USB-веб-камеры через ADB, используя следующую команду:
adb shell svc usb setFunctions uvc
Рассмотрите вопросы электропитания и теплоснабжения
Работа веб-камеры означает, что камера устройства может быть включена в течение нескольких часов в день, поэтому мы рекомендуем принять меры, чтобы гарантировать, что энергопотребление и тепловыделение устройства остаются в определенных пределах. Ниже приведены рекомендуемые решения для поддержания энергопотребления в пределах ограничений:
- Для повышения производительности HAL камеры включите
STREAM_USE_CASE_VIDEO_CALL
в службеDeviceAsWebcam
. Если питание вызывает беспокойство даже при включенном
STREAM_USE_CASE_VIDEO_CALL
, службаDeviceAsWebcam
предоставляет возможность дальнейшего снижения энергопотребления за счет использования физических потоков. Вы можете использовать наложения ресурсов времени выполнения (RRO), чтобы указать, какую физическую камеру использовать. Физические потоки значительно снижают качество видео и приводят к запутанному UX, поэтому используйте это решение только в крайнем случае. ОптимизацияSTREAM_USE_CASE_VIDEO_CALL
является предпочтительным решением для проблем с питанием. Для получения дополнительной информации о RRO, поддерживаемых службойDeviceAsWebcam
, см. readme.md .Ниже приведен пример настройки RRO для использования физического идентификатора камеры 3 вместо логического идентификатора камеры 0. Пример в AOSP см. в DeviceAsWebcamRaven .
// For logical camera id 0 - use physical camera id 3 {"0": {"3" : "UW"}}
Проверка
Чтобы протестировать реализацию сервиса DeviceAsWebcam
на вашем устройстве, используйте следующие тесты:
- Тестирование веб-камеры с помощью CTS-верификатора: проверка того, поддерживаются ли устройством форматы, размеры и частота кадров.
- Ручное тестирование: проверьте работу функции веб-камеры с различными хост-приложениями на различных хост-операционных системах.
Известные проблемы
Ниже перечислены известные проблемы службы DeviceAsWebcam
:
Поток драйвера гаджета UVC иногда мерцает и показывает то, что выглядит как поврежденные кадры. Эта проблема была исправлена и объединена в апстриме и в GKI.
Исправления в восходящем направлении:
Устройства Android в режиме веб-камеры не работают с кабелями USB 3.0+ на хостах macOS из-за ошибки в драйвере UVC от Apple.