Câmeras USB externas

A plataforma Android oferece suporte ao uso de câmeras USB plug and play (ou seja, webcams) com a API Android Camera2 padrão e a interface HAL da câmera. As webcams geralmente oferecem suporte a drivers de classe de vídeo USB (UVC) e, no Linux, o driver padrão Video4Linux (V4L) é usado para controlar câmeras UVC.

Com o suporte a webcams, os dispositivos podem ser usados em casos de uso leves, como chat por vídeo e quiosques de fotos. Esse recurso não substitui as HALs de câmera interna típicas em smartphones Android e não foi projetado para oferecer suporte a tarefas complexas que exigem muito desempenho, como streaming de alta resolução e alta velocidade, RA e controle manual de ISP/sensor/lente.

O processo HAL da câmera USB faz parte do provedor de câmera externa que detecta a disponibilidade do dispositivo USB e enumera os dispositivos de câmera externa de acordo. O processo tem permissões e uma política de SE semelhante ao processo HAL integrado da câmera. Apps de webcam de terceiros que se comunicam diretamente com dispositivos USB precisam das mesmas permissões de câmera para acessar dispositivos UVC, assim como qualquer app de câmera normal.

Exemplos e origens

Para mais informações sobre como implementar câmeras USB, consulte a implementação de referência do provedor de câmera externa em ExternalCameraProvider. As implementações de dispositivo de câmera externa e de sessão estão incluídas em ExternalCameraDevice e ExternalCameraDeviceSession. A partir do nível 28 da API, a API cliente Java inclui o nível de hardware EXTERNAL.

Implementação

A implementação precisa oferecer suporte ao recurso do sistema android.hardware.usb.host.

O suporte do kernel para dispositivos UVC também precisa estar ativado. Para ativar essa opção, adicione o seguinte aos respectivos arquivos defconfig do kernel.

+CONFIG_USB_VIDEO_CLASS=y
+CONFIG_MEDIA_USB_SUPPORT=y

Para ativar o provedor de câmera externa no build do dispositivo, o que adiciona as permissões SELinux necessárias, a configuração da câmera externa e a dependência do provedor de câmera externa, siga estas etapas:

  • Adicione o arquivo de configuração e a biblioteca da câmera externa a device.mk.

    +PRODUCT_PACKAGES += android.hardware.camera.provider-V1-external-service
    
    +PRODUCT_COPY_FILES += \
    +device/manufacturerX/productY/external_camera_config.xml:$(TARGET_COPY_OUT_VENDOR)/etc/external_camera_config.xml
    
  • Adicionamos o nome do provedor de câmera externa ao manifesto HAL do Treble do dispositivo.

    <hal format="aidl">
        <name>android.hardware.camera.provider</name>
        <version>1</version>
        <interface>
            <name>ICameraProvider</name>
            <instance>internal/0</instance>
    +       <instance>external/0</instance>
        </interface>
    </hal>
    
  • (Opcional) Se o dispositivo for executado no modo de transferência Treble, atualize sepolicy para que cameraserver possa acessar a câmera UVC.

    +# for external camera
    +allow cameraserver device:dir r_dir_perms;
    +allow cameraserver video_device:dir r_dir_perms;
    +allow cameraserver video_device:chr_file rw_file_perms;
    

Confira um exemplo de external_camera_config.xml (linhas de direitos autorais omitidas).

<ExternalCamera>
    <Provider>
        <ignore> <!-- Internal video devices to be ignored by external camera HAL -->
            <id>0</id> <!-- No leading/trailing spaces -->
            <id>1</id>
        </ignore>
    </Provider>
    <!-- See ExternalCameraUtils.cpp for default values of Device configurations below -->
    <Device>
        <!-- Max JPEG buffer size in bytes-->
        <MaxJpegBufferSize bytes="3145728"/> <!-- 3MB (~= 1080p YUV420) -->
        <!-- Size of v4l2 buffer queue when streaming >= 30fps -->
        <!-- Larger value: more request can be cached pipeline (less janky)  -->
        <!-- Smaller value: use less memory -->
        <NumVideoBuffers count="4"/>
        <!-- Size of v4l2 buffer queue when streaming < 30fps -->
        <NumStillBuffers count="2"/>

        <!-- List of maximum fps for various output sizes -->
        <!-- Any image size smaller than the size listed in Limit row will report
            fps (as minimum frame duration) up to the fpsBound value. -->
        <FpsList>
            <!-- width/height must be increasing, fpsBound must be decreasing-->
            <Limit width="640" height="480" fpsBound="30.0"/>
            <Limit width="1280" height="720" fpsBound="15.0"/>
            <Limit width="1920" height="1080" fpsBound="10.0"/>
            <!-- image size larger than the last entry will not be supported-->
        </FpsList>
    </Device>
</ExternalCamera>

Personalização

É possível melhorar a câmera do Android usando opções de personalização gerais ou otimizações específicas do dispositivo.

Personalizações gerais

É possível personalizar o provedor de câmera externa modificando o arquivo external_camera_config.xml. Mais especificamente, os clientes podem personalizar os seguintes parâmetros:

  • Como excluir nós de vídeo de câmeras internas
  • Tamanho da imagem e limite máximo da frame rate compatíveis
  • Número de buffers em andamento (troca de jank x memória)

Além desses parâmetros, você pode adicionar seus próprios parâmetros ou desenvolver suas próprias configurações.

Otimizações específicas do dispositivo

Você também pode melhorar a performance adicionando otimizações específicas para o dispositivo.

Cópia/dimensionamento do buffer e decodificação/codificação JPEG

As implementações genéricas usam a CPU (libyuv/libjpeg), mas você pode substituí-las por otimizações específicas do dispositivo.

Formato de saída do HAL

As implementações genéricas usam os seguintes formatos de saída:

  • YUV_420_888 para buffers de IMPLEMENTATION_DEFINED de vídeo
  • YUV12 para todos os outros buffers IMPLEMENTATION_DEFINED

Para melhorar o desempenho, substitua os formatos de saída por formatos eficientes específicos para dispositivos. Você também pode oferecer suporte a outros formatos em uma implementação personalizada.

Validação

Os dispositivos com suporte a câmera externa precisam passar no CTS da câmera. A webcam USB externa precisa permanecer conectada ao dispositivo específico durante todo o teste. Caso contrário, alguns casos de teste vão falhar.