Para dispositivos com Android 14 QPR1 ou mais recente, o Android oferece suporte ao uso do
dispositivo como uma webcam USB. Os dispositivos Android que oferecem suporte a esse recurso são anunciados
como um dispositivo UVC, que permite que uma ampla gama de hosts USB com diferentes
sistemas operacionais (por exemplo, Linux, macOS, Windows e ChromeOS) usem a
câmera do dispositivo como uma webcam. O serviço DeviceAsWebcam
oferece suporte a esse recurso para usar o dispositivo como uma webcam.
Serviço DeviceAsWebcam
O serviço DeviceAsWebcam
no AOSP inclui uma atividade de visualização
(DeviceAsWebcamPreview.java
) que permite que os usuários enquadrem a cena. A atividade de visualização
permite que o usuário faça o seguinte:
Confira como o feed da webcam vai ficar na máquina host antes do início da transmissão.
Personalize o feed da webcam enviado ao host das seguintes maneiras:
- Como selecionar a câmera para fazer a transmissão, frontal ou traseira.
- Selecionar o nível de zoom usando um controle deslizante ou botões.
- Toque em uma região específica da visualização para focar ou remover o foco de uma região.
A atividade de visualização funciona com recursos gerais de acessibilidade no Android, como TalkBack, Acesso com interruptor e Acesso por voz.
Figura 1. Feed da webcam sendo transmitido para um host com visualização controlando o feed.
Arquitetura
A arquitetura compatível com o uso de um dispositivo como webcam está ilustrada na
Figura 2. Veja a seguir o fluxo de interação do serviço DeviceAsWebcam
com o restante do framework do Android:
- O usuário seleciona a opção de webcam USB no app Configurações.
- O app Configurações envia uma chamada de vinculação para
system_server
pela classeUsbManager
, informando queFUNCTION_UVC
foi selecionado. - O servidor do sistema faz o seguinte:
- Informa o HAL do gadget USB para recuperar a função do gadget UVC por uma
chamada de interface HAL
setUsbFunctions
. - Informa a HAL do gadget USB para configurar o driver do gadget UVC usando ConfigFs.
- Informa o HAL do gadget USB para recuperar a função do gadget UVC por uma
chamada de interface HAL
- Ao receber um callback do HAL do gadget, o
system_server
envia uma transmissão para o framework ser recebida pelo serviçoDeviceAsWebcam
. - O driver do gadget USB inicia a transmissão da webcam ao receber comandos
de configuração do host por nós V4L2 em
/dev/video*
.
Figura 2. Arquitetura do DeviceAsWebcam.
Implementação
Esta seção descreve como oferecer suporte ao uso de um dispositivo Android como webcam.
Suporte do kernel
No Android 14 ou versões mais recentes, a imagem genérica do kernel (GKI) ativa o driver de gadget UVC por padrão. Confira os detalhes no patch do AOSP.
Suporte a UVC no HAL do gadget
A partir do Android 14, a função UVC é incluída na
interface da HAL GadgetFunction.aidl
. Para o HAL do gadget, o gadget
UVC é montado no ConfigFS da mesma forma que outras funções do ConfigFS, como
MTP ou ADB.
Para implementar o HAL do gadget, faça modificações para montar a função UVC no ConfigFS. Confira abaixo um exemplo de snippet de uma implementação de HAL do gadget com suporte à função 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
...
}
...
}
Quando o dispositivo estiver atuando como uma webcam, verifique se o HAL do gadget USB está anunciando as combinações VID/PID adequadas.
Como toda a lógica de UVC está no init do fornecedor ou no serviço DeviceAsWebcam
, nenhuma lógica específica da UVC, além da vinculação simbólica da função UVC ao
ConfigFS, é necessária na HAL do gadget.
Para mais orientações sobre a implementação, consulte o exemplo de código abaixo no AOSP:
Configurar o ConfigFS com configurações de UVC
Para informar ao driver do gadget UVC quais formatos, tamanhos e taxas de frames são compatíveis com a webcam do Android, configure o ConfigFS com configurações UVC. Para mais informações, consulte a documentação upstream do Linux na ABI do gadget UVC ConfigFS.
Confira a seguir um exemplo de como o fornecedor inicial pode configurar o driver do gadget UVC (fragmento de código no 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
# ...
Este snippet configura o driver do gadget UVC para anunciar um stream MJPEG de 1080p a 30 QPS. Esses recursos são comunicados ao host USB quando ele consulta as resoluções e as taxas de frames compatíveis.
Confira a seguir as diretrizes gerais para selecionar as configurações anunciadas pela webcam:
- Os dois formatos de transmissão aceitos pelo serviço
DeviceAsWebcam
são MJPEG e YUYV não compactado. - O USB 2.0 oferece suporte à transferência de dados de 480 Mbps (60 MBps). Isso
significa que, a 30 QPS, cada frame precisa ter um tamanho máximo de 2 MB,
e a 60 QPS, um tamanho máximo de 1 MB.
- Transmissões não compactadas (YUYV): a 30 qps, o tamanho máximo de frame com suporte é 720p, porque o YUYV tem 2 bytes por pixel.
- Fluxos MJPEG compactados: supondo uma taxa de compressão de 1:10 de YUV, o USB 2.0 pode oferecer suporte a 4K (1,18 MB por frame).
- Os dispositivos de câmera frontal e traseira principais precisam oferecer suporte a todos os tamanhos de frame que são anunciados. Isso ocorre porque o usuário pode alternar entre os IDs da câmera usando a interface de visualização. Para transmissões MJPEG, recomendamos que os fornecedores anunciem tamanhos de frame de 480p (640 x 480), 720p (1280 x 820) e 1080p (1920 x 1080), porque são tamanhos comumente usados por apps de hospedagem.
- Os principais dispositivos de câmera frontal e traseira precisam oferecer suporte a todos os frame rates que são divulgados. Recomendamos que os fornecedores ofereçam suporte a 30 qps.
Para conferir um exemplo de como adicionar configurações de transmissão de webcam (ConfigFS), consulte Protótipo de amostra do AOSP.
Ativar a webcam no build
Para ativar o serviço DeviceAsWebcam
, defina a propriedade do sistema ro.usb.uvc.enabled
como true
no arquivo device.mk
.
# Enable UVC support
PRODUCT_VENDOR_PROPERTIES += \
ro.usb.uvc.enabled=true
Quando essa propriedade do sistema está ativada, uma opção Webcam aparece no app Configurações, em "Preferências de USB", como mostrado na Figura 3. Quando a opção é selecionada, o dispositivo Android aparece como uma webcam USB para o dispositivo host.
Figura 3. Preferências de USB no app Configurações.
Também é possível definir o dispositivo para a função de webcam USB pelo ADB usando este comando:
adb shell svc usb setFunctions uvc
Considere questões de energia e térmicas
As operações da webcam significam que a câmera de um dispositivo pode ficar ligada por várias horas por dia. Por isso, recomendamos tomar medidas para garantir que o consumo de energia e a temperatura do dispositivo permaneçam abaixo de determinados limites. Confira a seguir as soluções recomendadas para manter o consumo de energia abaixo dos limites:
- Para melhorar o desempenho de energia do HAL da câmera, ative
STREAM_USE_CASE_VIDEO_CALL
no serviçoDeviceAsWebcam
. Se o consumo de energia for um problema mesmo com o
STREAM_USE_CASE_VIDEO_CALL
ativado, o serviçoDeviceAsWebcam
oferece uma opção para diminuir ainda mais o consumo de energia usando streams físicos. É possível usar sobreposições de recursos de execução (RROs, na sigla em inglês) para especificar qual câmera física usar. Transmissões físicas reduzem significativamente a qualidade do vídeo e levam a uma UX confusa. Portanto, use essa solução apenas como último recurso. OtimizarSTREAM_USE_CASE_VIDEO_CALL
é a solução preferida para problemas de energia. Para mais informações sobre as RROs compatíveis com o serviçoDeviceAsWebcam
, consulte readme.md.Confira abaixo um exemplo de RRO configurado para usar o ID de câmera física 3 em vez do ID de câmera lógico 0. Para ver um exemplo no AOSP, consulte DeviceAsWebcamRaven.
// For logical camera id 0 - use physical camera id 3 {"0": {"3" : "UW"}}
Verificação
Para testar a implementação do serviço DeviceAsWebcam
no dispositivo, use
os seguintes testes:
- Teste de verificador do CTS da câmera: teste se o dispositivo oferece suporte a formatos, tamanhos e taxas de quadros.
- Testes manuais: teste se o recurso de webcam funciona com vários apps host em vários sistemas operacionais host.
Problemas conhecidos
Veja a seguir problemas conhecidos do serviço DeviceAsWebcam
:
O fluxo do driver do gadget UVC às vezes pisca e mostra o que parece ser frames corrompidos. Esse problema foi corrigido e mesclado na versão upstream e no GKI.
Dispositivos Android no modo de webcam não funcionam com cabos USB 3.0 ou mais recentes em hosts do macOS devido a um bug no driver UVC da Apple.