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) use 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 a transmissão 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 visualização controlando o 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_server
pela classeUsbManager
, informando queFUNCTION_UVC
está 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,
system_server
envia 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
da HAL. Para a 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 a seguir 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. Esses recursos são comunicados 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
DeviceAsWebcam
sã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 uvc
Considere 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_CALL
no serviçoDeviceAsWebcam
. Se o consumo de energia for uma preocupação 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. Você pode 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": {&qu
ot;3" : "UW"}}
Verificação
Para testar a implementação do serviço DeviceAsWebcam
no seu dispositivo, use
os seguintes testes:
- Teste do CTS Verifier 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 pisca 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.