Usar um dispositivo como webcam

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.

feed da webcam transmitido para o host

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:

  1. O usuário seleciona a opção de webcam USB no app Configurações.
  2. O app Configurações envia uma chamada de binder para system_server pela classe UsbManager, informando que FUNCTION_UVC está selecionado.
  3. O servidor do sistema faz o seguinte:
    1. Informa ao HAL do gadget USB para recuperar a função do gadget UVC por uma chamada de interface 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, que será capturada pelo serviço DeviceAsWebcam.
  5. 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*.

arquitetura de dispositivo como webcam

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 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.

Preferências de USB no app Configurações

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ço DeviceAsWebcam.
  • Se o consumo de energia for uma preocupação mesmo com o STREAM_USE_CASE_VIDEO_CALL ativado, o serviço DeviceAsWebcam oferece 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 de STREAM_USE_CASE_VIDEO_CALL é a solução preferida para problemas de energia. 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 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: