Usa un dispositivo como cámara web

En dispositivos que ejecutan Android 14-QPR1 o versiones posteriores, Android admite el uso del dispositivo como cámara web USB. Los dispositivos Android que admiten esta función se anuncian como dispositivos UVC, lo que permite que una amplia variedad de hosts USB con diferentes sistemas operativos (por ejemplo, Linux, macOS, Windows y ChromeOS) usen la cámara del dispositivo como cámara web. El servicio DeviceAsWebcam admite esta función para usar el dispositivo como cámara web.

Servicio de DeviceAsWebcam

El servicio DeviceAsWebcam en AOSP incluye una actividad de vista previa (DeviceAsWebcamPreview.java) que permite a los usuarios encuadrar la escena. La actividad de vista previa permite al usuario hacer lo siguiente:

  • Obtén una vista previa de cómo se verá el feed de la cámara web en la máquina host antes de que comience la transmisión.

  • Personaliza el feed de la cámara web que se envía al organizador de las siguientes maneras:

    • Seleccionar la cámara para transmitir, frontal o posterior
    • Seleccionar el nivel de zoom con un control deslizante o botones
    • Presionar una región específica de la vista previa para enfocarla o quitar el enfoque de una región

La actividad de vista previa funciona con las funciones de accesibilidad generales en Android, como TalkBack, Accesibilidad mejorada y Acceso por voz.

Feed de la cámara web transmitido al host

Figura 1: Se transmite el feed de la cámara web a un host con la vista previa que controla el feed.

Arquitectura

En la Figura 2, se ilustra la arquitectura para admitir el uso de un dispositivo como cámara web. A continuación, se describe el flujo de interacción del servicio DeviceAsWebcam con el resto del framework de Android:

  1. El usuario selecciona la opción de cámara web USB en la app de Configuración.
  2. La app de Configuración envía una llamada de vinculador a system_server a través de la clase UsbManager para informarle que se seleccionó FUNCTION_UVC.
  3. El servidor del sistema hace lo siguiente:
    1. Informa al HAL de gadget USB que recupere la función de gadget UVC a través de una llamada a la interfaz HAL de setUsbFunctions.
    2. Informa al HAL del gadget USB que configure el controlador del gadget UVC con ConfigFs.
  4. Cuando recibe una devolución de llamada del HAL del dispositivo, system_server envía una transmisión al framework para que la recoja el servicio DeviceAsWebcam.
  5. El controlador de dispositivo USB inicia la transmisión de la cámara web cuando recibe comandos de configuración del host a través de nodos V4L2 en /dev/video*.

Arquitectura de dispositivo como cámara web

Figura 2: Arquitectura de DeviceAsWebcam.

Implementación

En esta sección, se describe cómo admitir el uso de un dispositivo Android como cámara web.

Compatibilidad con kernel

En Android 14 y versiones posteriores, la imagen genérica de kernel (GKI) habilita el controlador de gadget UVC de forma predeterminada (consulta los detalles en el parche del AOSP).

Compatibilidad con UVC en la HAL de Gadget

A partir de Android 14, la función de UVC se incluye en la interfaz de la HAL de GadgetFunction.aidl. Para el HAL de Gadget, el gadget UVC se activa en ConfigFS de la misma manera que otras funciones de ConfigFS, como MTP o ADB.

Para implementar el HAL de Gadget, realiza modificaciones para montar la función UVC en ConfigFS. A continuación, se muestra un ejemplo de fragmento de una implementación del HAL de Gadget que admite la función 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
       ...
   }
   ...
}

Cuando el dispositivo actúa como cámara web, asegúrate de que la HAL de gadget USB anuncie las combinaciones de VID/PID adecuadas.

Dado que toda la lógica de la UVC se encuentra en la inicialización del proveedor o en el servicio DeviceAsWebcam, no se requiere ninguna lógica específica de la UVC, aparte de la vinculación simbólica de la función de la UVC a ConfigFS, en el HAL de Gadget.

Para obtener más orientación sobre la implementación, consulta el siguiente código de muestra en el AOSP:

Cómo configurar ConfigFS con configuraciones de UVC

Para informar al controlador del dispositivo UVC qué formatos, tamaños y velocidades de fotogramas admite la cámara web de Android, configura ConfigFS con configuraciones de UVC. Para obtener más información, consulta la documentación de Linux sobre la ABI del gadget UVC de ConfigFS.

A continuación, se muestra un ejemplo de cómo init del proveedor puede configurar el controlador del gadget UVC (fragmento de código en 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 fragmento configura el controlador de dispositivos UVC para anunciar una transmisión MJPEG de 1080 p a 30 FPS. Estas capacidades se comunican al host USB cuando consulta las resoluciones y las velocidades de fotogramas admitidas.

A continuación, se incluyen lineamientos generales para seleccionar las configuraciones que anuncia la cámara web:

  • Los dos formatos de transmisión admitidos por el servicio DeviceAsWebcam son MJPEG y YUYV sin comprimir.
  • USB 2.0 admite la transferencia de datos a 480 Mbps (60 MBps). Esto significa que, a 30 fps, cada fotograma debe tener un tamaño máximo de 2 MB y, a 60 fps, un tamaño máximo de 1 MB.
    • Transmisiones sin comprimir (YUYV): A 30 FPS, el tamaño de fotograma máximo admitido es de 720p porque YUYV es de 2 bytes por píxel.
    • Flujos MJPEG comprimidos: Suponiendo una relación de compresión de 1:10 desde YUV, USB 2.0 puede admitir 4K (1.18 MB por fotograma).
  • Los dispositivos de cámara principal frontal y posterior deben admitir todos los tamaños de fotogramas que se anuncian. Esto se debe a que el usuario puede cambiar entre los IDs de cámara con la IU de vista previa. En el caso de las transmisiones MJPEG, recomendamos que los proveedores anuncien tamaños de fotogramas de 480p (640 x 480), 720p (1280 x 820) y 1080p (1920 x 1080), ya que son los tamaños que suelen usar las apps host.
  • Los dispositivos de cámara principal frontal y posterior deben admitir todas las velocidades de fotogramas anunciadas. Te recomendamos que los proveedores admitan 30 FPS.

Para ver un ejemplo de cómo agregar configuraciones de transmisión de cámara web (ConfigFS), consulta el parche de muestra de AOSP.

Habilita la cámara web en la compilación

Para habilitar el servicio DeviceAsWebcam, debes establecer la propiedad del sistema ro.usb.uvc.enabled en true en el archivo device.mk.

# Enable UVC support
PRODUCT_VENDOR_PROPERTIES += \
    ro.usb.uvc.enabled=true

Cuando esta propiedad del sistema está habilitada, aparece una opción de Webcam en la app de Configuración, en las preferencias de USB, como se muestra en la figura 3. Cuando se selecciona la opción, el dispositivo Android aparece como una cámara web USB en el dispositivo host.

Preferencias de USB en la app de Configuración

Figura 3: Preferencias de USB en la app de Configuración

También puedes configurar el dispositivo para que funcione como cámara web por USB a través de ADB con este comando:

adb shell svc usb setFunctions uvc

Consideraciones sobre la potencia y la temperatura

Las operaciones de la cámara web implican que la cámara de un dispositivo puede estar encendida durante varias horas al día, por lo que recomendamos tomar medidas para garantizar que el consumo de energía y la temperatura del dispositivo permanezcan dentro de ciertos límites. Las siguientes son soluciones recomendadas para mantener el consumo de energía dentro de los límites:

  • Para obtener un mejor rendimiento de energía de la HAL de la cámara, habilita STREAM_USE_CASE_VIDEO_CALL en el servicio DeviceAsWebcam.
  • Si la energía es un problema incluso con STREAM_USE_CASE_VIDEO_CALL habilitado, el servicio de DeviceAsWebcam proporciona una opción para reducir aún más el consumo de energía con transmisiones físicas. Puedes usar superposiciones de recursos de tiempo de ejecución (RRO) para especificar qué cámara física usar. Las transmisiones físicas reducen significativamente la calidad del video y generan una UX confusa, por lo que esta solución solo debe usarse como último recurso. La optimización de STREAM_USE_CASE_VIDEO_CALL es la solución preferida para los problemas de energía. Para obtener más información sobre los RR.OO. compatibles con el servicio de DeviceAsWebcam, consulta readme.md.

    A continuación, se muestra un ejemplo de un RRO configurado para usar el ID de cámara física 3 en lugar del ID de cámara lógica 0. Para ver un ejemplo en AOSP, consulta DeviceAsWebcamRaven.

    // For logical camera id 0 - use physical camera id 3
    {"0": {"3" : "UW"}}
    

Verificación

Para probar la implementación del servicio DeviceAsWebcam en tu dispositivo, usa las siguientes pruebas:

  • Prueba de cámara web del verificador de CTS: Prueba que el dispositivo admita formatos, tamaños y velocidades de fotogramas.
  • Pruebas manuales: Prueba que la función de cámara web funcione con una variedad de apps anfitrionas en una variedad de sistemas operativos anfitriones.

Problemas conocidos

Los siguientes son problemas conocidos del servicio de DeviceAsWebcam: