API de gestion de la mémoire tampon HAL3 de la caméra

Android 10 introduit des fonctionnalités tampon HAL3 de la caméra de gestion des API qui vous permettent pour implémenter une logique de gestion des tampons afin d'obtenir des capacités de mémoire et de capture différentes les compromis de latence dans les implémentations HAL de la caméra.

Le HAL de la caméra nécessite N requêtes (où N est égal à la valeur profondeur du pipeline). en file d'attente dans son pipeline, mais souvent, les N ensembles de tampons de sortie en même temps.

Par exemple, le HAL peut avoir huit requêtes en file d'attente dans le pipeline, mais il n'exige que des tampons de sortie pour les deux requêtes des dernières étapes du pipeline. Sur les appareils équipés d'Android 9 ou version antérieure, le framework de l'appareil photo lorsque la requête est mise en file d'attente dans le HAL. Il peut donc y avoir six ensembles tampons dans le HAL qui ne sont pas utilisés. Sous Android 10, Les API de gestion de la mémoire tampon HAL3 de la caméra permettent de découpler la sortie des tampons pour libérer les six ensembles de tampons. Cela peut conduire à des centaines de mégaoctets d'économies de mémoire sur les appareils haut de gamme et peut également être utile les appareils à faible mémoire.

La figure 1 présente l'interface HAL de la caméra pour les appareils exécutant Android 9 ou version antérieure La figure 2 illustre l'interface HAL de la caméra dans Android. 10 avec les API de gestion de la mémoire tampon HAL3 de la caméra implémentées ;

Gestion de la mémoire tampon dans la version 9 ou inférieure

Figure 1 : Interface HAL de la caméra sous Android 9 ou version antérieure

Gestion de la mémoire tampon sous Android 10

Figure 2. Interface HAL de la caméra sous Android 10 utilisant les API de gestion des tampons

Implémenter les API de gestion des tampons

Pour implémenter les API de gestion des tampons, le HAL de la caméra doit:

La couche d'abstraction de la caméra utilise l'API requestStreamBuffers et returnStreamBuffers méthodes dans ICameraDeviceCallback.hal pour demander et renvoyer des tampons. Le HAL doit également implémenter signalStreamFlush dans ICameraDeviceSession.hal pour signaler au HAL de la caméra qu'il doit renvoyer des tampons.

requestStreamBuffers

Utilisez les requestStreamBuffers pour demander des tampons au framework de l'appareil photo. Lorsque vous utilisez la caméra HAL3 les API de gestion de la mémoire tampon, les requêtes de capture du framework de l'appareil photo contenir des tampons de sortie, c'est-à-dire le champ bufferId dans StreamBuffer est 0. Par conséquent, l'HAL de la caméra doit utiliser requestStreamBuffers pour demander à partir du framework de l'appareil photo.

La méthode requestStreamBuffers permet à l'appelant de demander plusieurs tampons à partir de plusieurs flux de sortie en un seul appel, ce qui permet de réduire l'IPC HIDL appels. Toutefois, les appels prennent plus de temps lorsque davantage de tampons sont demandés au niveau en même temps, ce qui peut avoir un impact négatif sur la latence totale des requêtes aux résultats. De plus, comme les appels vers requestStreamBuffers sont sérialisés dans l'appareil photo nous vous recommandons d'utiliser un accès prioritaire pour demander des tampons.

Si une requête de mise en mémoire tampon échoue, le HAL de la caméra doit pouvoir gérer correctement non fatales. La liste suivante décrit les raisons courantes pour lesquelles la mise en mémoire tampon échouent et comment elles doivent être traitées par le HAL de la caméra.

  • L'application se déconnecte du flux de sortie: Il s'agit d'une erreur non fatale. Le HAL de la caméra doit envoyer ERROR_REQUEST pour toute demande de capture ciblant un flux déconnecté et être prêt à traiter les requêtes suivantes normalement.
  • Délai avant expiration:ce problème peut se produire lorsqu'une application est occupée. un traitement intensif tout en conservant des tampons. Le HAL de la caméra doit envoyer ERROR_REQUEST pour les demandes de capture qui ne peuvent pas être satisfaites de délai avant expiration et être prêt à traiter normalement les requêtes suivantes.
  • Le framework de l'appareil photo prépare une nouvelle configuration de flux: Le HAL de la caméra doit attendre le prochain configureStreams est terminé avant d'appeler à nouveau requestStreamBuffers.
  • Le HAL de la caméra a atteint sa limite de la mémoire tampon (champ maxBuffers): Le HAL de la caméra doit patienter jusqu'à ce qu'il renvoie au moins un tampon du flux avant d'appeler requestStreamBuffers.

returnStreamBuffers

Utilisez les returnStreamBuffers pour renvoyer des tampons supplémentaires au framework de l'appareil photo. Normalement, le HAL de la caméra renvoie des tampons au framework de l'appareil photo via processCaptureResult , mais elle ne peut prendre en compte que les demandes de capture envoyées au HAL de la caméra. Avec la méthode requestStreamBuffers, il est possible que l'implémentation de la couche HAL de la caméra afin de conserver plus de tampons que ce qui a été demandé par le cadre de l'appareil photo. La méthode returnStreamBuffers doit alors être utilisé. Si l'implémentation HAL ne contient jamais plus de tampons que demandé, L'implémentation de la couche HAL de la caméra n'a pas besoin d'appeler returnStreamBuffers .

signalStreamFlush

La signalStreamFlush est appelée par le framework de l'appareil photo pour demander au HAL de la caméra de renvoyer tampons à portée de main. Cette méthode est généralement appelée lorsque le framework de l'appareil photo est sur le point appel configureStreams et doivent drainer le pipeline de capture de la caméra. Semblable à returnStreamBuffers , si une implémentation HAL d'appareil photo ne contient pas plus de tampons que demandé, il est possible que l'implémentation de cette méthode soit vide.

Une fois que le framework de l'appareil photo a appelé signalStreamFlush, le framework cesse d'envoyer de nouvelles requêtes de capture au HAL de l'appareil photo tant que ont été renvoyés au framework d'appareil photo. Lorsque tous les tampons sont renvoyé, les appels de la méthode requestStreamBuffers échouent, et l'appareil photo peut continuer à fonctionner normalement. Le cadre de l'appareil photo appelle soit configureStreams ou processCaptureRequest . Si le framework de l'appareil photo appelle la méthode configureStreams, l'appareil photo HAL peut recommencer à demander des tampons après le retour de l'appel configureStreams avec succès. Si le framework de l'appareil photo appelle la méthode processCaptureRequest, le HAL de la caméra peut commencer à demander des tampons pendant la processCaptureRequest .

La sémantique diffère pour la méthode signalStreamFlush et la méthode flush . Lorsque la méthode flush est appelée, le HAL peut annuler la capture en attente de requêtes avec ERROR_REQUEST de drainer le pipeline dès que possible. Quand ? la méthode signalStreamFlush est appelée, le HAL doit terminer toutes les tâches de capturer les requêtes normalement et de renvoyer tous les tampons au framework de l'appareil photo.

Une autre différence entre la méthode signalStreamFlush et les autres méthodes est la suivante : que signalStreamFlush est une méthode HIDL unidirectionnelle, ce qui signifie que l'appareil photo framework peut appeler d'autres API de blocage avant que le HAL ne reçoive signalStreamFlush appel. Cela signifie que la méthode signalStreamFlush et d'autres méthodes (en particulier, méthode configureStreams) peuvent arriver au HAL de la caméra dans un ordre différent. que l'ordre dans lequel ils ont été appelés dans le cadre de l'appareil photo. Pour résoudre ce problème, problème asynchrone, le champ streamConfigCounter a été ajouté à StreamConfiguration et ajouté comme argument à signalStreamFlush . L'implémentation de la couche d'abstraction de la caméra (HAL) doit utiliser streamConfigCounter pour déterminer si un appel signalStreamFlush arrive après son l'appel configureStreams correspondant. Reportez-vous à la Figure 3 pour obtenir un exemple.

Gérer les appels qui arrivent en retard

Figure 3. Comment le HAL de la caméra doit détecter et gérer les appels signalStreamFlush qui arrivent en retard

Changements de comportement lors de la mise en œuvre des API de gestion des tampons

Lorsque vous utilisez les API de gestion des tampons pour implémenter la logique de gestion des tampons, Envisagez d'appliquer les modifications suivantes au fonctionnement de la caméra : et de la caméra HAL:

  • Les demandes de capture arrivent plus rapidement sur le HAL de la caméra et bien plus encore fréquemment:sans API de gestion des tampons, le framework d'appareil photo demande tampons de sortie pour chaque demande de capture avant d'envoyer une demande de capture le HAL de la caméra. Lorsque vous utilisez les API de gestion des tampons, le framework de l'appareil photo n'a plus besoin d'attendre la mise en mémoire tampon et peut donc envoyer des requêtes de capture au HAL de la caméra.

    De plus, sans API de gestion des tampons, le framework de l'appareil photo s'arrête. envoyant des requêtes de capture si l'un des flux de sortie de la capture a atteint le nombre maximal de tampons que le HAL peut contenir une seule fois (cette valeur est désignée par le HAL de la caméra dans Champ HalStream::maxBuffers dans la valeur renvoyée par configureStreams appel). Avec les API de gestion des tampons, ce comportement de limitation existe et que l'implémentation de l'HAL de la caméra ne doit pas accepter Appels processCaptureRequest lorsque le HAL a trop de requêtes de capture en file d'attente.

  • La latence des appels requestStreamBuffers varie considérablement : de nombreuses raisons pour lesquelles un appel requestStreamBuffers peut prendre plus de temps moyenne. Exemple :

    • Pour les premiers tampons d'un nouveau flux, les appels peut prendre plus de temps, car l'appareil doit allouer de la mémoire.
    • La latence attendue augmente proportionnellement au nombre tampons demandés dans chaque appel.
    • L'application contient des tampons et est en train d'effectuer un traitement. Ce les requêtes de tampon peuvent ralentir ou atteindre un délai d'inactivité en raison d'une manque de tampons ou un CPU occupé.

Stratégies de gestion de la mémoire tampon

Les API de gestion des tampons permettent différents types de gestion des tampons stratégies à mettre en œuvre. Par exemple :

  • Rétrocompatible:le HAL demande des tampons pour une requête de capture. pendant l'appel processCaptureRequest. Cette stratégie ne fournit d'économies de mémoire, mais il peut s'agir de la première implémentation du tampon de gestion des API, ce qui nécessite très peu de modifications du code du HAL de la caméra existante.
  • Économies de mémoire optimisées:le HAL de la caméra ne demande que des tampons de sortie. immédiatement avant qu'il soit nécessaire de le remplir. Cette stratégie permet et des économies de mémoire optimisées. L'inconvénient potentiel, c'est qu'il y a davantage de caméras des à-coups lorsque les requêtes de tampon prennent un temps anormalement long.
  • En cache:l'HAL de la caméra met en cache quelques tampons afin d'éviter être affecté par une requête de mise en mémoire tampon lente occasionnelle.

Le HAL de la caméra peut adopter différentes stratégies pour des cas d'utilisation particuliers, par exemple : exemple, en utilisant la stratégie d'économie de mémoire maximale pour les cas d'utilisation qui utilisent beaucoup de mémoire et la stratégie rétrocompatible pour d'autres cas d'utilisation.

Exemple d'implémentation dans le HAL de la caméra externe

Le HAL de la caméra externe a été introduit dans Android 9 et se trouve dans le à l'arborescence source hardware/interfaces/camera/device/3.5/ Dans Android 10, elle a été mise à jour pour inclure ExternalCameraDeviceSession.cpp, une implémentation de l'API de gestion des tampons. Cette caméra externe HAL met en œuvre la stratégie d'optimisation des économies de mémoire mentionnée dans la section Gestion des tampons stratégies en quelques centaines de lignes Code C++.