APIs de administración de búfer de la HAL3 de la cámara

Android 10 introduce un campo Búfer de cámara HAL3 de administración de identidades y accesos, que te permiten implementar la lógica de administración de búfer para lograr diferentes compensaciones de latencia en las implementaciones de la HAL de la cámara.

La HAL de la cámara requiere N solicitudes (donde N es igual a la profundidad de la canalización) en cola en su canalización, pero a menudo no requiere todos N conjuntos de búferes de salida al mismo tiempo.

Por ejemplo, la HAL puede tener ocho solicitudes en cola en la canalización, solo requiere búferes de salida para las dos solicitudes en las últimas etapas del en una canalización de integración continua. En los dispositivos que ejecutan Android 9 y versiones anteriores, el framework de la cámara asigna cuando la solicitud se pone en cola en la HAL, por lo que podría haber seis conjuntos búferes de la HAL que no están en uso. En Android 10, Las APIs de administración de búfer de la HAL3 de la cámara permiten separar la salida. búferes para liberar los seis conjuntos de búferes. Esto puede dar lugar a cientos de de ahorro de memoria en dispositivos de alta gama y puede ser dispositivos con poca memoria.

En la figura 1, se muestra un diagrama de la interfaz de la HAL de la cámara para dispositivos que ejecutan Android 9 y versiones anteriores En la Figura 2, se muestra la interfaz de la HAL de la cámara en Android. 10 con se implementaron las APIs de administración de búfer de la HAL3 de la cámara.

Administración del búfer en 9 o menos

Figura 1: Interfaz de la HAL de la cámara en Android 9 y versiones anteriores

Administración de búfer en Android 10

Figura 2: Interfaz de la HAL de la cámara en Android 10 con las APIs de administración de búfer

Implementa las APIs de administración de búfer

Para implementar las APIs de administración de búfer, la HAL de la cámara debe hacer lo siguiente:

La HAL de la cámara usa requestStreamBuffers y returnStreamBuffers métodos en ICameraDeviceCallback.hal para solicitar y devolver búferes. La HAL también debe implementar signalStreamFlush método de ICameraDeviceSession.hal para indicarle a la HAL de la cámara que devuelva búferes.

requestStreamBuffers

Usa el requestStreamBuffers para solicitar búferes desde el framework de la cámara. Cuando se usa la HAL3 de la cámara las APIs de administración de búfer, las solicitudes de captura del framework de la cámara contienen búferes de salida, es decir, el campo bufferId en StreamBuffer es 0. Por lo tanto, la HAL de la cámara debe usar requestStreamBuffers para solicitar búferes del framework de la cámara.

El método requestStreamBuffers permite que el llamador solicite varios búferes de varias transmisiones de salida en una sola llamada, lo que permite una menor cantidad de IPC de HIDL llamadas. Sin embargo, las llamadas demoran más cuando se solicitan más búferes en el mismo tiempo y esto podría afectar negativamente la latencia total de solicitud a resultado. Además, debido a que las llamadas a requestStreamBuffers se serializan en la cámara servicio, se recomienda que la HAL de la cámara use una puerta de enlace para solicitar búferes.

Si falla la solicitud de búfer, la HAL de la cámara debe poder controlarla correctamente errores recuperables. En la siguiente lista, se describen los motivos comunes por los que fallan y cómo debe controlarlas la HAL de la cámara.

  • La app se desconecta del flujo de salida: Este es un error recuperable. La HAL de la cámara debería enviar ERROR_REQUEST para cualquier solicitud de captura orientar una transmisión desconectada y estar listo para procesar solicitudes posteriores normalmente.
  • Tiempo de espera: Puede ocurrir cuando una app está ocupada. de procesamiento intensivo mientras retienen algunos búferes. La HAL de la cámara debería enviar ERROR_REQUEST para las solicitudes de captura que no se puedan completar debido a un de tiempo de espera y estar listo para procesar las solicitudes posteriores de forma normal.
  • El framework de la cámara está preparando una nueva configuración de transmisión: La HAL de la cámara debería esperar hasta la siguiente configureStreams la llamada finalice antes de volver a llamar a requestStreamBuffers.
  • La HAL de la cámara alcanzó su límite de búfer (el campo maxBuffers): La HAL de la cámara debería esperar hasta que devuelva al menos un búfer de la transmisión antes de llamar requestStreamBuffers de nuevo.

returnStreamBuffers

Usa el returnStreamBuffers para mostrar búferes adicionales al framework de la cámara. Normalmente, la HAL de la cámara devuelve búferes al framework de la cámara a través del processCaptureResult pero solo puede tener en cuenta las solicitudes de captura que se enviaron al HAL de la cámara. Con el método requestStreamBuffers, es posible que el valor implementación de la HAL de la cámara para retener más búferes de los que solicitó el marco de la cámara. En ese momento, el método returnStreamBuffers debería ser que se usan. Si la implementación de la HAL nunca tiene más búferes de los solicitados, el La implementación de la HAL de la cámara no necesita llamar a returnStreamBuffers. .

SeñalStreamFlush

El signalStreamFlush de la cámara para notificar a la HAL de la cámara que devuelva todos tiempos de reserva a mano. Normalmente, se llama a este método cuando el framework de la cámara está a punto de llamar configureStreams y debe vaciar la canalización de captura de la cámara. Similar a returnStreamBuffers método, si una implementación de la HAL de la cámara no tiene más búferes que solicitado, es posible tener una implementación vacía de este método.

Después de las llamadas al framework de la cámara signalStreamFlush: el framework deja de enviar nuevas solicitudes de captura a la HAL de la cámara hasta que se devolvieron búferes al framework de la cámara. Cuando todos los tiempos de reserva están que se muestran, las llamadas al método requestStreamBuffers fallan y la cámara puede continuar su trabajo en un estado limpio. Luego, el framework de la cámara llama a configureStreams o processCaptureRequest . Si el framework de la cámara llama al método configureStreams, la cámara La HAL puede volver a solicitar búferes después de que se muestra la llamada a configureStreams. con éxito. Si el framework de la cámara llama al método processCaptureRequest, la HAL de la cámara puede comenzar a solicitar búferes durante la processCaptureRequest. llamada.

La semántica es diferente para el método signalStreamFlush y para flush . Cuando se llama al método flush, la HAL puede anular la captura pendiente. solicitudes con ERROR_REQUEST para vaciar la canalización lo antes posible. Cuándo se llama al método signalStreamFlush, la HAL debe finalizar todos los procesos captar solicitudes normalmente y devolver todos los búferes al framework de la cámara.

Otra diferencia entre el método signalStreamFlush y otros es que signalStreamFlush es un método HIDL unidireccional, lo que significa que la cámara puede llamar a otras APIs de bloqueo antes de que la HAL reciba signalStreamFlush llamada. Esto significa que signalStreamFlush y otros métodos (específicamente, el método configureStreams) pueden llegar a la HAL de la cámara en un orden diferente. que el orden en que se llamaron en el framework de la cámara. Para solucionar esto, sigue estos pasos: problema de asíncrona, el campo streamConfigCounter se agregó al StreamConfiguration y se agregó como argumento a signalStreamFlush . La implementación de la HAL de la cámara debe usar el streamConfigCounter. para determinar si una llamada a signalStreamFlush llega después de su llamada configureStreams correspondiente. Consulta la Figura 3 para ver un ejemplo.

Cómo manejar las llamadas que llegan tarde

Figura 3: Cómo debe detectar y controlar las llamadas de signalStreamFlush que llegan tarde la HAL de la cámara

Cambios de comportamiento cuando se implementan las APIs de administración de búfer

Cuando uses las APIs de administración de búferes para implementar su lógica, considera los siguientes posibles cambios de comportamiento de la cámara y la implementación de la HAL de la cámara:

  • Las solicitudes de captura llegan a la HAL de la cámara más rápido y con mayor frecuencia con frecuencia: Sin las APIs de administración de búfer, el framework de la cámara solicita búferes de salida para cada solicitud de captura antes de enviar una solicitud de captura a la HAL de la cámara. Cuando se usan las APIs de administración de búfer, el framework de la cámara ya no necesita esperar los búferes y, por lo tanto, puede enviar solicitudes de captura a la HAL de la cámara anteriormente.

    Además, sin las APIs de administración de búfer, el framework de la cámara se detiene enviar solicitudes de captura si una de las transmisiones de salida de la captura alcanzó la cantidad máxima de búferes que la HAL puede contener una vez (este valor lo designa la HAL de la cámara en la Campo HalStream::maxBuffers en el valor que se muestra de un configureStreams llamada). Con las APIs de administración de búfer, este comportamiento de limitación ya no y la implementación de la HAL de la cámara no debe aceptar Llamadas processCaptureRequest cuando la HAL tiene demasiadas solicitudes de captura en la fila.

  • La latencia de llamadas de requestStreamBuffers varía significativamente: Hay muchos motivos por los que una llamada a requestStreamBuffers puede tardar más tiempo que promedio. Por ejemplo:

    • Para los primeros búferes de una transmisión recién creada, las llamadas puede tardar más porque el dispositivo necesita asignar memoria.
    • La latencia esperada aumenta en proporción a la cantidad de los búferes requeridos en cada llamada.
    • La app contiene búferes y está ocupado procesando. Esta Puede hacer que las solicitudes de búfer se ralenticen o alcancen un tiempo de espera debido a una la falta de búferes o una CPU ocupada.

Estrategias de administración del búfer

Las APIs de administración de búferes permiten diferentes tipos de administración estrategias que se implementarán. Por ejemplo:

  • Retrocompatible: La HAL solicita búferes para una solicitud de captura. durante la llamada de processCaptureRequest. Esta estrategia no proporciona de memoria, pero puede servir como la primera implementación del búfer de administración de Google Cloud, que requieren muy pocos cambios de código en la HAL de la cámara existente.
  • Ahorro de memoria maximizado: La HAL de la cámara solo solicita búferes de salida. justo antes de que se deba rellenar uno. Esta estrategia permite maximiza el ahorro de memoria. La posible desventaja es más canalización de la cámara Los bloqueos se producen cuando las solicitudes de los búferes tardan más en completarse.
  • En caché: La HAL de la cámara almacena en caché algunos búferes para reducir las probabilidades de que se almacenen en caché. se verán afectados por una solicitud de búfer lento ocasional.

La HAL de la cámara puede adoptar diferentes estrategias para casos de uso particulares, por ejemplo: ejemplo, usando la estrategia de ahorro de memoria maximizado para casos de uso que usan mucha de memoria y usar la estrategia retrocompatible en otros casos de uso.

Ejemplo de implementación en la HAL de la cámara externa

La HAL de cámara externa se introdujo en Android 9 y se puede encontrar en la árbol de fuentes en hardware/interfaces/camera/device/3.5/ En Android 10, se actualizó para incluir ExternalCameraDeviceSession.cpp: una implementación de la API de administración de búfer. Esta HAL de cámara externa implementa la estrategia de ahorro de memoria maximizado que se menciona en Administración de búfer estrategias en unos pocos cientos de líneas código C++.