Usar um dispositivo como webcam

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.

feed da webcam transmitido para o organizador

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:

  1. O usuário seleciona a opção de webcam USB no app Configurações.
  2. O app Configurações envia uma chamada de vinculação para system_server pela classe UsbManager informando que FUNCTION_UVC está selecionado.
  3. O servidor do sistema faz o seguinte:
    1. Informa a HAL do gadget USB para extrair a função do gadget UVC por meio de uma chamada de interface da HAL setUsbFunctions.
    2. Informa a HAL do gadget USB para configurar o driver do gadget UVC usando ConfigFs.
  4. Ao receber um callback da HAL do gadget, o system_server envia uma transmissão para o framework para ser selecionada pelo serviço DeviceAsWebcam.
  5. 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*.

dispositivo como arquitetura de webcam

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ço DeviceAsWebcam.
  • Se a energia for uma preocupação mesmo com a STREAM_USE_CASE_VIDEO_CALL ativada, o serviço DeviceAsWebcam 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. Otimizar STREAM_USE_CASE_VIDEO_CALL é a solução recomendada para aumentar as preocupações. Para mais informações sobre RROs compatíveis com o serviço DeviceAsWebcam, 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: