Para dispositivos com o Android 14 QPR1 ou mais recente, o Android oferece suporte ao
uso de uma webcam USB. Os dispositivos Android com suporte a esse recurso são anunciados
como dispositivos UVC (link em inglês), o que permite que vários 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 será exibido na máquina host antes do início do streaming.
Personalize o feed da webcam enviado ao host das seguintes maneiras:
- Selecione a câmera para transmitir, frontal ou traseira.
- Selecionar o nível de zoom usando um controle deslizante ou botões.
- Tocar em uma região específica da visualização para focar ou remover o foco em 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
está selecionado. - O servidor do sistema faz o seguinte:
- Informa a HAL do gadget USB para extrair a função do gadget UVC por meio de uma
chamada de interface da HAL
setUsbFunctions
. - Informa a HAL do gadget USB para configurar o driver do gadget UVC usando ConfigFs.
- Informa a HAL do gadget USB para extrair a função do gadget UVC por meio de uma
chamada de interface da HAL
- Ao receber um callback da HAL do gadget, o
system_server
envia uma transmissão para o framework para ser selecionada pelo serviçoDeviceAsWebcam
. - O driver do gadget USB inicia o stream da webcam ao receber comandos de configuração
do host pelos nós da V4L2 em
/dev/video*
.
Figura 2. Arquitetura 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 em versões mais recentes, a imagem genérica do kernel (GKI, na sigla em inglês) ativa o driver de gadget UVC por padrão. Confira mais detalhes em Patch do AOSP.
Suporte a UVC na HAL de gadget
No Android 14 e versões mais recentes, a função UVC está incluída na
interface da HAL GadgetFunction.aidl
. Para a HAL de gadget, o gadget
de UVC é montado no ConfigFS da mesma maneira que outras funções do ConfigFS, como
MTP ou ADB.
Para implementar a HAL de gadget, faça modificações para ativar a função UVC no ConfigFS. Confira abaixo um exemplo de snippet de implementação da HAL de 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 webcam, confira se a HAL do gadget USB está anunciando as combinações adequadas de VID/PID.
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:
Definir o ConfigFS com configurações de UVC
Para informar ao driver do gadget UVC quais formatos, tamanhos e frame rates têm suporte da webcam do Android, defina o ConfigFS com as configurações de UVC. Para mais informações, consulte a documentação upstream do Linux na ABI do gadget UVC ConfigFS.
Confira abaixo um exemplo de como o init do fornecedor pode configurar o driver do gadget de UVC (snippet 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 resoluções e frame rates com suporte.
Veja a seguir as diretrizes gerais para selecionar as configurações que a webcam divulga:
- Os dois formatos de stream com suporte ao serviço
DeviceAsWebcam
são MJPEG e YUYV descompactado. - 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.
- Streams não compactados (YUYV, na sigla em inglês): a 30 QPS, o tamanho máximo de frame com suporte é 720p, porque o YUYV é de 2 bytes por pixel.
- Streams MJPEG compactados: considerando uma proporção de compactação de 1:10 da YUV, o USB 2.0 oferece suporte a 4K (1,18 MB por frame).
- Os principais dispositivos de câmera frontal e traseira precisam oferecer suporte a todos os tamanhos de quadro anunciados. Isso ocorre porque o usuário pode alternar entre os IDs da câmera usando a interface de visualização. Para streams MJPEG, recomendamos que os fornecedores anunciem tamanhos de frame de 480p (640 x 480), 720p (1.280 x 820) e 1080p (1920 x 1080), porque esses são tamanhos normalmente usados por apps host.
- 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 streaming de webcam (ConfigFS), consulte Exemplo de patch do AOSP.
Ativar 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 no dispositivo host.
Figura 3. Preferências de USB no app Configurações.
Você também pode configurar o dispositivo para a função de webcam USB pelo adb usando este comando:
adb shell svc usb setFunctions uvc
Considere as preocupações com energia e temperatura
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 as soluções recomendadas para manter o consumo de energia abaixo dos limites:
- Para melhorar o desempenho de energia da HAL da câmera, ative
STREAM_USE_CASE_VIDEO_CALL
no serviçoDeviceAsWebcam
. Se a energia for uma preocupação mesmo com a
STREAM_USE_CASE_VIDEO_CALL
ativada, o serviçoDeviceAsWebcam
oferecerá uma opção para diminuir ainda mais o consumo de energia usando streams físicos. É possível usar sobreposições de recursos no ambiente de execução (RROs, na sigla em inglês) para especificar qual câmera física será usada. 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 recomendada para aumentar as preocupações. Para mais informações sobre 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 do verificador CTS webcam: teste se os formatos, tamanhos e frame rates são compatíveis com o dispositivo.
- Testes manuais: teste se o recurso de webcam funciona com vários apps host em vários sistemas operacionais host.
Problemas conhecidos
Confira 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 de upstream e na GKI.
Dispositivos Android no modo webcam não funcionam com cabos USB 3.0 ou mais recente em hosts do macOS devido a um bug com o driver UVC da Apple.