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, o que permite que uma ampla variedade 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
é compatível com esse recurso para usar o dispositivo como uma webcam.
Serviço DeviceAsWebcam
O serviço DeviceAsWebcam no AOSP inclui uma atividade de prévia
(DeviceAsWebcamPreview.java) que permite aos usuários enquadrar a cena. A atividade de
prévia permite que o usuário faça o seguinte:
Confira como o feed da webcam vai aparecer na máquina host antes de iniciar a transmissão.
Personalize o feed da webcam enviado ao organizador das seguintes maneiras:
- Selecionar 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 prévia para focar ou remover o foco em uma região.
A atividade de prévia 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 controle de visualização do feed.
Arquitetura
A arquitetura para usar um dispositivo como webcam é ilustrada na Figura 2. A seguir, descrevemos o fluxo de interação do serviço DeviceAsWebcam
com o restante do framework Android:
- O usuário seleciona a opção de webcam USB no app Configurações.
- O app Configurações envia uma chamada de binder para
system_serverpela classeUsbManager, informando queFUNCTION_UVCestá selecionado. - O servidor do sistema faz o seguinte:
- Informa ao 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 ao HAL do gadget USB para recuperar a função do gadget UVC por uma
chamada de interface HAL
- Ao receber um callback da HAL do gadget, o
system_serverenvia uma transmissão para o framework, que será capturada pelo serviçoDeviceAsWebcam. - O driver de gadget USB inicia o stream da webcam ao receber comandos de configuração
do host por nós V4L2 em
/dev/video*.
Figura 2. Arquitetura DeviceAsWebcam.
Implementação
Esta seção descreve como usar 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. Consulte detalhes no patch do AOSP.
Suporte ao UVC no HAL do gadget
No Android 14 e versões mais recentes, a função UVC está incluída na interface
GadgetFunction.aidl HAL. 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 do HAL do gadget que oferece 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 funcionando como uma webcam, verifique se o HAL do gadget USB está anunciando as combinações VID/PID corretas.
Como toda a lógica da UVC está na inicialização do fornecedor ou no serviço DeviceAsWebcam, nenhuma lógica específica da UVC, além de criar um link simbólico da função da UVC para o ConfigFS, é necessária no HAL do gadget.
Para mais orientações sobre a implementação, consulte o exemplo de código a seguir 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 Android, configure o ConfigFS com configurações UVC. Para mais informações, consulte a documentação do Linux sobre a ABI do gadget UVC do ConfigFS.
Confira um exemplo de como a inicialização do fornecedor pode configurar o driver de gadget 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 fps. Essas capacidades são comunicadas ao host USB quando ele consulta resoluções e frame rates compatíveis.
Confira a seguir as diretrizes gerais para selecionar as configurações que a webcam anuncia:
- Os dois formatos de stream compatíveis com o serviço
DeviceAsWebcamsão MJPEG e YUYV não compactado. - O USB 2.0 oferece suporte a transferência de dados de 480 Mbps (60 MBps). Isso significa que, a 30 fps, cada frame precisa ter um tamanho máximo de 2 MB, e a 60 fps, um tamanho máximo de 1 MB.
- Streams não compactados (YUYV): a 30 fps, o tamanho máximo de frame compatível é 720p porque YUYV tem 2 bytes por pixel.
- Fluxos MJPEG compactados: considerando uma taxa de compactação de 1:10 de YUV, o USB 2.0 pode oferecer suporte a 4K (1,18 MB por frame).
- Os dispositivos principais de câmera frontal e traseira precisam oferecer suporte a todos os tamanhos de frame anunciados. Isso acontece porque o usuário pode alternar entre IDs de 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 (1280 x 820) e 1080p (1920 x 1080), porque esses são tamanhos comumente usados por apps host.
- Os dispositivos principais de câmera frontal e traseira precisam oferecer suporte a todas as taxas de frames anunciadas. Recomendamos que os fornecedores ofereçam suporte a 30 fps.
Para um exemplo de como adicionar configurações de stream da webcam (ConfigFS), consulte Patch de exemplo 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 no dispositivo host.
Figura 3. Preferências de USB no app Configurações.
Você também pode definir o dispositivo para a função de webcam USB usando o ADB com este comando:
adb shell svc usb setFunctions uvcConsidere questões de energia e térmicas
As operações de 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 dentro de determinados limites. Confira a seguir as soluções recomendadas para manter o consumo de energia dentro dos limites:
- Para melhorar o desempenho de energia da HAL da câmera, ative
STREAM_USE_CASE_VIDEO_CALLno serviçoDeviceAsWebcam. Se o consumo de energia for uma preocupação mesmo com o
STREAM_USE_CASE_VIDEO_CALLativado, o serviçoDeviceAsWebcamoferece uma opção para diminuir ainda mais o consumo de energia usando streams físicos. É possível usar sobreposições de recursos de tempo de execução (RROs, na sigla em inglês) para especificar qual câmera física usar. Os fluxos físicos reduzem significativamente a qualidade do vídeo e levam a uma UX confusa. Portanto, use essa solução apenas como último recurso. A otimização deSTREAM_USE_CASE_VIDEO_CALLé a solução preferida para problemas de energia. 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 da câmera física 3 em vez do ID da câmera lógica 0. Para 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 seu dispositivo, use
os seguintes testes:
- Teste do verificador do CTS webcam: teste se os formatos, tamanhos e taxas de frames 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
Estes são os problemas conhecidos do serviço DeviceAsWebcam:
Às vezes, o fluxo do driver do gadget UVC fica instável e mostra o que parecem ser frames corrompidos. Esse problema foi corrigido e mesclado no upstream e no GKI.
Os dispositivos Android no modo webcam não funcionam com cabos USB 3.0+ em hosts macOS devido a um bug no driver UVC da Apple.