Android 10 introduit des API de gestion de tampon HAL3 de caméra en option qui vous permettent d'implémenter une logique de gestion de tampon pour obtenir différents compromis de mémoire et de capture de latence dans les implémentations HAL de caméra.
La caméra HAL nécessite N requêtes (où N est égal à la profondeur du pipeline ) mises en file d'attente dans son pipeline, mais elle ne nécessite souvent pas tous les N ensembles de tampons de sortie en même temps.
Par exemple, la couche HAL peut avoir huit requêtes en file d'attente dans le pipeline, mais elle ne nécessite que des tampons de sortie pour les deux requêtes dans les dernières étapes du pipeline. Sur les appareils exécutant Android 9 et versions antérieures, la structure de la caméra alloue des tampons lorsque la demande est mise en file d'attente dans HAL, de sorte qu'il peut y avoir six ensembles de tampons dans HAL qui ne sont pas utilisés. Dans Android 10, les API de gestion des tampons HAL3 de la caméra permettent le découplage des tampons de sortie pour libérer les six ensembles de tampons. Cela peut entraîner des centaines de mégaoctets d'économies de mémoire sur les appareils haut de gamme et peut également être bénéfique pour les appareils à faible mémoire.
La figure 1 montre un schéma de l'interface HAL de la caméra pour les appareils exécutant Android 9 et versions antérieures. La figure 2 montre l'interface HAL de la caméra dans Android 10 avec les API de gestion de tampon HAL3 de la caméra implémentées.
Figure 1. Interface HAL de la caméra sous Android 9 et versions antérieures
Figure 2. Interface HAL de la caméra dans Android 10 à l'aide des API de gestion des tampons
Implémentation des API de gestion des tampons
Pour implémenter les API de gestion des tampons, la HAL de la caméra doit :
- Implémentez HIDL
ICameraDevice@3.5
. - Définissez la clé de caractéristiques de la caméra
android.info.supportedBufferManagementVersion
surHIDL_DEVICE_3_5
.
La caméra HAL utilise les méthodes requestStreamBuffers
et returnStreamBuffers
dans ICameraDeviceCallback.hal
pour demander et renvoyer des tampons. La couche HAL doit également implémenter la méthode signalStreamFlush
dans ICameraDeviceSession.hal
pour signaler à la couche HAL de la caméra de renvoyer des tampons.
requestStreamBuffers
Utilisez la méthode requestStreamBuffers
pour demander des tampons à la structure de la caméra. Lors de l'utilisation des API de gestion de tampon HAL3 de la caméra, les demandes de capture provenant de la structure de la caméra ne contiennent pas de tampons de sortie, c'est-à-dire que le champ bufferId
dans StreamBuffer
est 0
. Par conséquent, la couche HAL de la caméra doit utiliser requestStreamBuffers
pour demander des tampons au framework de la caméra.
La méthode requestStreamBuffers
permet à l'appelant de demander plusieurs tampons à partir de plusieurs flux de sortie en un seul appel, ce qui permet moins d'appels HIDL IPC. Cependant, les appels prennent plus de temps lorsque plusieurs tampons sont demandés en même temps, ce qui peut affecter négativement la latence totale de la demande au résultat. De plus, étant donné que les appels dans requestStreamBuffers
sont sérialisés dans le service de caméra, il est recommandé que la caméra HAL utilise un thread haute priorité dédié pour demander des tampons.
Si une demande de tampon échoue, la caméra HAL doit être capable de gérer correctement les erreurs non fatales. La liste suivante décrit les raisons courantes de l'échec des demandes de tampon et la manière dont elles doivent être gérées par la couche HAL de la caméra.
- L'application se déconnecte du flux de sortie : il s'agit d'une erreur non fatale. La caméra HAL doit envoyer
ERROR_REQUEST
pour toute demande de capture ciblant un flux déconnecté et être prête à traiter normalement les demandes suivantes. - Délai d'expiration : cela peut se produire lorsqu'une application est occupée à effectuer un traitement intensif tout en conservant certains tampons. La caméra HAL doit envoyer
ERROR_REQUEST
pour les demandes de capture qui ne peuvent pas être satisfaites en raison d'une erreur de délai d'attente et être prête à traiter les demandes suivantes normalement. - La structure de la caméra prépare une nouvelle configuration de flux : la couche HAL de la caméra doit attendre que le prochain appel
configureStreams
soit terminé avant d'appeler à nouveaurequestStreamBuffers
. - La caméra HAL a atteint sa limite de tampon (le champ
maxBuffers
) : La caméra HAL doit attendre jusqu'à ce qu'elle renvoie au moins un tampon du flux avant d'appeler à nouveaurequestStreamBuffers
.
returnStreamBuffers
Utilisez la méthode returnStreamBuffers
pour renvoyer des tampons supplémentaires au framework de la caméra. La caméra HAL renvoie normalement les tampons au framework de la caméra via la méthode processCaptureResult
, mais elle ne peut prendre en compte que les demandes de capture qui ont été envoyées à la caméra HAL. Avec la méthode requestStreamBuffers
, il est possible que l'implémentation HAL de la caméra conserve plus de tampons que ce qui a été demandé par le framework de la caméra. C'est à ce moment que la méthode returnStreamBuffers
doit être utilisée. Si l'implémentation HAL ne contient jamais plus de tampons que demandé, l'implémentation HAL de la caméra n'a pas besoin d'appeler la méthode returnStreamBuffers
.
signalStreamFlush
La méthode signalStreamFlush
est appelée par le framework de la caméra pour notifier à la caméra HAL de renvoyer tous les tampons à portée de main. Ceci est normalement appelé lorsque le framework de la caméra est sur le point d'appeler configureStreams
et doit vider le pipeline de capture de la caméra. Semblable à la méthode returnStreamBuffers
, si une implémentation HAL de caméra ne contient pas plus de tampons que demandé, il est possible d'avoir une implémentation vide de cette méthode.
Une fois que la structure de la caméra a appelé signalStreamFlush
, la structure arrête d'envoyer de nouvelles demandes de capture à la caméra HAL jusqu'à ce que tous les tampons aient été renvoyés à la structure de la caméra. Lorsque tous les tampons sont renvoyés, les appels de la méthode requestStreamBuffers
échouent et la structure de la caméra peut continuer son travail dans un état propre. La structure de la caméra appelle ensuite la méthode configureStreams
ou processCaptureRequest
. Si la structure de la caméra appelle la méthode configureStreams
, la couche HAL de la caméra peut recommencer à demander des tampons après le retour réussi de l'appel configureStreams
. Si le framework de la caméra appelle la méthode processCaptureRequest
, la couche HAL de la caméra peut commencer à demander des tampons pendant l'appel processCaptureRequest
.
La sémantique est différente pour la méthode signalStreamFlush
et la méthode flush
. Lorsque la méthode flush
est appelée, HAL peut abandonner les demandes de capture en attente avec ERROR_REQUEST
pour vider le pipeline dès que possible. Lorsque la méthode signalStreamFlush
est appelée, HAL doit terminer normalement toutes les demandes de capture en attente et renvoyer tous les tampons au framework de la caméra.
Une autre différence entre la méthode signalStreamFlush
et les autres méthodes est que signalStreamFlush
est une méthode HIDL unidirectionnelle , ce qui signifie que la structure de la caméra peut appeler d'autres API de blocage avant que HAL ne reçoive l'appel signalStreamFlush
. Cela signifie que la méthode signalStreamFlush
et d'autres méthodes (en particulier la méthode configureStreams
) peuvent arriver à la caméra HAL dans un ordre différent de celui dans lequel elles ont été appelées dans le cadre de la caméra. Pour résoudre ce problème d'asynchronisme, le champ streamConfigCounter
a été ajouté à StreamConfiguration
et ajouté en tant qu'argument à la méthode signalStreamFlush
. L'implémentation HAL de la caméra doit utiliser l'argument streamConfigCounter
pour déterminer si un appel signalStreamFlush
arrive plus tard que son appel configureStreams
correspondant. Voir la figure 3 pour un exemple.
Figure 3. Comment la caméra HAL 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
Lors de l'utilisation des API de gestion des tampons pour implémenter la logique de gestion des tampons, tenez compte des changements de comportement possibles suivants pour la caméra et l'implémentation HAL de la caméra :
Les demandes de capture arrivent à la caméra HAL plus rapidement et plus fréquemment : sans les API de gestion des tampons, le cadre de la caméra demande des tampons de sortie pour chaque demande de capture avant d'envoyer une demande de capture à la caméra HAL. Lors de l'utilisation des API de gestion des tampons, le framework de la caméra n'a plus besoin d'attendre les tampons et peut donc envoyer des demandes de capture à la caméra HAL plus tôt.
De plus, sans API de gestion des tampons, la structure de la caméra arrête d'envoyer des requêtes de capture si l'un des flux de sortie de la requête de capture a atteint le nombre maximal de tampons que la HAL peut contenir en même temps (cette valeur est désignée par la HAL de la caméra dans le champ
HalStream::maxBuffers
dans la valeur de retour d'un appelconfigureStreams
). Avec les API de gestion des tampons, ce comportement de limitation n'existe plus et l'implémentation HAL de la caméra ne doit pas accepter les appelsprocessCaptureRequest
lorsque HAL a trop de demandes de capture en file d'attente.La latence des appels
requestStreamBuffers
varie considérablement : il existe de nombreuses raisons pour lesquelles un appelrequestStreamBuffers
peut prendre plus de temps que la moyenne. Par exemple:- Pour les premiers tampons d'un flux nouvellement créé, les appels peuvent prendre plus de temps car l'appareil doit allouer de la mémoire.
- La latence attendue augmente proportionnellement au nombre de tampons demandés dans chaque appel.
- L'application contient des tampons et est en cours de traitement. Cela peut ralentir les requêtes de tampon ou atteindre un délai d'attente en raison d'un manque de tampons ou d'un processeur occupé.
Stratégies de gestion des tampons
Les API de gestion de tampon permettent de mettre en œuvre différents types de stratégies de gestion de tampon. Certains exemples sont:
- Rétrocompatible : la couche HAL demande des tampons pour une demande de capture lors de l'appel
processCaptureRequest
. Cette stratégie ne fournit aucune économie de mémoire, mais peut servir de première implémentation des API de gestion de tampon, nécessitant très peu de modifications de code sur la caméra HAL existante. - Économies de mémoire maximisées : la caméra HAL ne demande que les tampons de sortie juste avant qu'un ne doive être rempli. Cette stratégie permet de maximiser les économies de mémoire. L'inconvénient potentiel est plus de jank de pipeline de caméra lorsque les demandes de tampon prennent un temps inhabituellement long pour se terminer.
- En cache : la caméra HAL met en cache quelques tampons afin qu'elle soit moins susceptible d'être affectée par une demande de tampon lente occasionnelle.
La caméra HAL peut adopter différentes stratégies pour des cas d'utilisation particuliers, par exemple, en utilisant la stratégie d'économie de mémoire maximisée pour les cas d'utilisation qui utilisent beaucoup de mémoire et en utilisant la stratégie de compatibilité descendante pour d'autres cas d'utilisation.
Exemple d'implémentation dans la caméra externe HAL
La caméra externe HAL a été introduite dans Android 9 et peut être trouvée dans l'arborescence source à hardware/interfaces/camera/device/3.5/
. Dans Android 10, il a été mis à jour pour inclure ExternalCameraDeviceSession.cpp
, une implémentation de l'API de gestion des tampons. Cette caméra externe HAL implémente la stratégie d'économie de mémoire maximisée mentionnée dans Stratégies de gestion des tampons en quelques centaines de lignes de code C++.
Android 10 introduit des API de gestion de tampon HAL3 de caméra en option qui vous permettent d'implémenter une logique de gestion de tampon pour obtenir différents compromis de mémoire et de capture de latence dans les implémentations HAL de caméra.
La caméra HAL nécessite N requêtes (où N est égal à la profondeur du pipeline ) mises en file d'attente dans son pipeline, mais elle ne nécessite souvent pas tous les N ensembles de tampons de sortie en même temps.
Par exemple, la couche HAL peut avoir huit requêtes en file d'attente dans le pipeline, mais elle ne nécessite que des tampons de sortie pour les deux requêtes dans les dernières étapes du pipeline. Sur les appareils exécutant Android 9 et versions antérieures, la structure de la caméra alloue des tampons lorsque la demande est mise en file d'attente dans HAL, de sorte qu'il peut y avoir six ensembles de tampons dans HAL qui ne sont pas utilisés. Dans Android 10, les API de gestion des tampons HAL3 de la caméra permettent le découplage des tampons de sortie pour libérer les six ensembles de tampons. Cela peut entraîner des centaines de mégaoctets d'économies de mémoire sur les appareils haut de gamme et peut également être bénéfique pour les appareils à faible mémoire.
La figure 1 montre un schéma de l'interface HAL de la caméra pour les appareils exécutant Android 9 et versions antérieures. La figure 2 montre l'interface HAL de la caméra dans Android 10 avec les API de gestion de tampon HAL3 de la caméra implémentées.
Figure 1. Interface HAL de la caméra sous Android 9 et versions antérieures
Figure 2. Interface HAL de la caméra dans Android 10 à l'aide des API de gestion des tampons
Implémentation des API de gestion des tampons
Pour implémenter les API de gestion des tampons, la HAL de la caméra doit :
- Implémentez HIDL
ICameraDevice@3.5
. - Définissez la clé de caractéristiques de la caméra
android.info.supportedBufferManagementVersion
surHIDL_DEVICE_3_5
.
La caméra HAL utilise les méthodes requestStreamBuffers
et returnStreamBuffers
dans ICameraDeviceCallback.hal
pour demander et renvoyer des tampons. La couche HAL doit également implémenter la méthode signalStreamFlush
dans ICameraDeviceSession.hal
pour signaler à la couche HAL de la caméra de renvoyer des tampons.
requestStreamBuffers
Utilisez la méthode requestStreamBuffers
pour demander des tampons à la structure de la caméra. Lors de l'utilisation des API de gestion de tampon HAL3 de la caméra, les demandes de capture provenant de la structure de la caméra ne contiennent pas de tampons de sortie, c'est-à-dire que le champ bufferId
dans StreamBuffer
est 0
. Par conséquent, la couche HAL de la caméra doit utiliser requestStreamBuffers
pour demander des tampons au framework de la caméra.
La méthode requestStreamBuffers
permet à l'appelant de demander plusieurs tampons à partir de plusieurs flux de sortie en un seul appel, ce qui permet moins d'appels HIDL IPC. Cependant, les appels prennent plus de temps lorsque plusieurs tampons sont demandés en même temps, ce qui peut affecter négativement la latence totale de la demande au résultat. De plus, étant donné que les appels dans requestStreamBuffers
sont sérialisés dans le service de caméra, il est recommandé que la caméra HAL utilise un thread haute priorité dédié pour demander des tampons.
Si une demande de tampon échoue, la caméra HAL doit être capable de gérer correctement les erreurs non fatales. La liste suivante décrit les raisons courantes de l'échec des demandes de tampon et la manière dont elles doivent être gérées par la couche HAL de la caméra.
- L'application se déconnecte du flux de sortie : il s'agit d'une erreur non fatale. La caméra HAL doit envoyer
ERROR_REQUEST
pour toute demande de capture ciblant un flux déconnecté et être prête à traiter normalement les demandes suivantes. - Délai d'expiration : cela peut se produire lorsqu'une application est occupée à effectuer un traitement intensif tout en conservant certains tampons. La caméra HAL doit envoyer
ERROR_REQUEST
pour les demandes de capture qui ne peuvent pas être satisfaites en raison d'une erreur de délai d'attente et être prête à traiter les demandes suivantes normalement. - La structure de la caméra prépare une nouvelle configuration de flux : la couche HAL de la caméra doit attendre que le prochain appel
configureStreams
soit terminé avant d'appeler à nouveaurequestStreamBuffers
. - La caméra HAL a atteint sa limite de tampon (le champ
maxBuffers
) : La caméra HAL doit attendre jusqu'à ce qu'elle renvoie au moins un tampon du flux avant d'appeler à nouveaurequestStreamBuffers
.
returnStreamBuffers
Utilisez la méthode returnStreamBuffers
pour renvoyer des tampons supplémentaires au framework de la caméra. La caméra HAL renvoie normalement les tampons au framework de la caméra via la méthode processCaptureResult
, mais elle ne peut prendre en compte que les demandes de capture qui ont été envoyées à la caméra HAL. Avec la méthode requestStreamBuffers
, il est possible que l'implémentation HAL de la caméra conserve plus de tampons que ce qui a été demandé par le framework de la caméra. C'est à ce moment que la méthode returnStreamBuffers
doit être utilisée. Si l'implémentation HAL ne contient jamais plus de tampons que demandé, l'implémentation HAL de la caméra n'a pas besoin d'appeler la méthode returnStreamBuffers
.
signalStreamFlush
La méthode signalStreamFlush
est appelée par le framework de la caméra pour notifier à la caméra HAL de renvoyer tous les tampons à portée de main. Ceci est normalement appelé lorsque le framework de la caméra est sur le point d'appeler configureStreams
et doit vider le pipeline de capture de la caméra. Semblable à la méthode returnStreamBuffers
, si une implémentation HAL de caméra ne contient pas plus de tampons que demandé, il est possible d'avoir une implémentation vide de cette méthode.
Une fois que la structure de la caméra a appelé signalStreamFlush
, la structure arrête d'envoyer de nouvelles demandes de capture à la caméra HAL jusqu'à ce que tous les tampons aient été renvoyés à la structure de la caméra. Lorsque tous les tampons sont renvoyés, les appels de la méthode requestStreamBuffers
échouent et la structure de la caméra peut continuer son travail dans un état propre. La structure de la caméra appelle ensuite la méthode configureStreams
ou processCaptureRequest
. Si la structure de la caméra appelle la méthode configureStreams
, la couche HAL de la caméra peut recommencer à demander des tampons après le retour réussi de l'appel configureStreams
. Si le framework de la caméra appelle la méthode processCaptureRequest
, la couche HAL de la caméra peut commencer à demander des tampons pendant l'appel processCaptureRequest
.
La sémantique est différente pour la méthode signalStreamFlush
et la méthode flush
. Lorsque la méthode flush
est appelée, HAL peut abandonner les demandes de capture en attente avec ERROR_REQUEST
pour vider le pipeline dès que possible. Lorsque la méthode signalStreamFlush
est appelée, HAL doit terminer normalement toutes les demandes de capture en attente et renvoyer tous les tampons au framework de la caméra.
Une autre différence entre la méthode signalStreamFlush
et les autres méthodes est que signalStreamFlush
est une méthode HIDL unidirectionnelle , ce qui signifie que la structure de la caméra peut appeler d'autres API de blocage avant que HAL ne reçoive l'appel signalStreamFlush
. Cela signifie que la méthode signalStreamFlush
et d'autres méthodes (en particulier la méthode configureStreams
) peuvent arriver à la caméra HAL dans un ordre différent de celui dans lequel elles ont été appelées dans le cadre de la caméra. Pour résoudre ce problème d'asynchronisme, le champ streamConfigCounter
a été ajouté à StreamConfiguration
et ajouté en tant qu'argument à la méthode signalStreamFlush
. L'implémentation HAL de la caméra doit utiliser l'argument streamConfigCounter
pour déterminer si un appel signalStreamFlush
arrive plus tard que son appel configureStreams
correspondant. Voir la figure 3 pour un exemple.
Figure 3. Comment la caméra HAL 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
Lors de l'utilisation des API de gestion des tampons pour implémenter la logique de gestion des tampons, tenez compte des changements de comportement possibles suivants pour la caméra et l'implémentation HAL de la caméra :
Les demandes de capture arrivent à la caméra HAL plus rapidement et plus fréquemment : sans les API de gestion des tampons, le cadre de la caméra demande des tampons de sortie pour chaque demande de capture avant d'envoyer une demande de capture à la caméra HAL. Lors de l'utilisation des API de gestion des tampons, le framework de la caméra n'a plus besoin d'attendre les tampons et peut donc envoyer des demandes de capture à la caméra HAL plus tôt.
De plus, sans API de gestion des tampons, la structure de la caméra arrête d'envoyer des requêtes de capture si l'un des flux de sortie de la requête de capture a atteint le nombre maximal de tampons que la HAL peut contenir en même temps (cette valeur est désignée par la HAL de la caméra dans le champ
HalStream::maxBuffers
dans la valeur de retour d'un appelconfigureStreams
). Avec les API de gestion des tampons, ce comportement de limitation n'existe plus et l'implémentation HAL de la caméra ne doit pas accepter les appelsprocessCaptureRequest
lorsque HAL a trop de demandes de capture en file d'attente.La latence des appels
requestStreamBuffers
varie considérablement : il existe de nombreuses raisons pour lesquelles un appelrequestStreamBuffers
peut prendre plus de temps que la moyenne. Par exemple:- Pour les premiers tampons d'un flux nouvellement créé, les appels peuvent prendre plus de temps car l'appareil doit allouer de la mémoire.
- La latence attendue augmente proportionnellement au nombre de tampons demandés dans chaque appel.
- L'application contient des tampons et est en cours de traitement. Cela peut ralentir les requêtes de tampon ou atteindre un délai d'attente en raison d'un manque de tampons ou d'un processeur occupé.
Stratégies de gestion des tampons
Les API de gestion de tampon permettent de mettre en œuvre différents types de stratégies de gestion de tampon. Certains exemples sont:
- Rétrocompatible : la couche HAL demande des tampons pour une demande de capture lors de l'appel
processCaptureRequest
. Cette stratégie ne fournit aucune économie de mémoire, mais peut servir de première implémentation des API de gestion de tampon, nécessitant très peu de modifications de code sur la caméra HAL existante. - Économies de mémoire maximisées : la caméra HAL ne demande que les tampons de sortie juste avant qu'un ne doive être rempli. Cette stratégie permet de maximiser les économies de mémoire. L'inconvénient potentiel est plus de jank de pipeline de caméra lorsque les demandes de tampon prennent un temps inhabituellement long pour se terminer.
- En cache : la caméra HAL met en cache quelques tampons afin qu'elle soit moins susceptible d'être affectée par une demande de tampon lente occasionnelle.
La caméra HAL peut adopter différentes stratégies pour des cas d'utilisation particuliers, par exemple, en utilisant la stratégie d'économie de mémoire maximisée pour les cas d'utilisation qui utilisent beaucoup de mémoire et en utilisant la stratégie de compatibilité descendante pour d'autres cas d'utilisation.
Exemple d'implémentation dans la caméra externe HAL
La caméra externe HAL a été introduite dans Android 9 et peut être trouvée dans l'arborescence source à hardware/interfaces/camera/device/3.5/
. Dans Android 10, il a été mis à jour pour inclure ExternalCameraDeviceSession.cpp
, une implémentation de l'API de gestion des tampons. Cette caméra externe HAL implémente la stratégie d'économie de mémoire maximisée mentionnée dans Stratégies de gestion des tampons en quelques centaines de lignes de code C++.
Android 10 introduit des API de gestion de tampon HAL3 de caméra en option qui vous permettent d'implémenter une logique de gestion de tampon pour obtenir différents compromis de mémoire et de capture de latence dans les implémentations HAL de caméra.
La caméra HAL nécessite N requêtes (où N est égal à la profondeur du pipeline ) mises en file d'attente dans son pipeline, mais elle ne nécessite souvent pas tous les N ensembles de tampons de sortie en même temps.
Par exemple, la couche HAL peut avoir huit requêtes en file d'attente dans le pipeline, mais elle ne nécessite que des tampons de sortie pour les deux requêtes dans les dernières étapes du pipeline. Sur les appareils exécutant Android 9 et versions antérieures, la structure de la caméra alloue des tampons lorsque la demande est mise en file d'attente dans HAL, de sorte qu'il peut y avoir six ensembles de tampons dans HAL qui ne sont pas utilisés. Dans Android 10, les API de gestion des tampons HAL3 de la caméra permettent le découplage des tampons de sortie pour libérer les six ensembles de tampons. Cela peut entraîner des centaines de mégaoctets d'économies de mémoire sur les appareils haut de gamme et peut également être bénéfique pour les appareils à faible mémoire.
La figure 1 montre un schéma de l'interface HAL de la caméra pour les appareils exécutant Android 9 et versions antérieures. La figure 2 montre l'interface HAL de la caméra dans Android 10 avec les API de gestion de tampon HAL3 de la caméra implémentées.
Figure 1. Interface HAL de la caméra sous Android 9 et versions antérieures
Figure 2. Interface HAL de la caméra dans Android 10 à l'aide des API de gestion des tampons
Implémentation des API de gestion des tampons
Pour implémenter les API de gestion des tampons, la HAL de la caméra doit :
- Implémentez HIDL
ICameraDevice@3.5
. - Définissez la clé de caractéristiques de la caméra
android.info.supportedBufferManagementVersion
surHIDL_DEVICE_3_5
.
La caméra HAL utilise les méthodes requestStreamBuffers
et returnStreamBuffers
dans ICameraDeviceCallback.hal
pour demander et renvoyer des tampons. La couche HAL doit également implémenter la méthode signalStreamFlush
dans ICameraDeviceSession.hal
pour signaler à la couche HAL de la caméra de renvoyer des tampons.
requestStreamBuffers
Utilisez la méthode requestStreamBuffers
pour demander des tampons à la structure de la caméra. Lors de l'utilisation des API de gestion de tampon HAL3 de la caméra, les demandes de capture provenant de la structure de la caméra ne contiennent pas de tampons de sortie, c'est-à-dire que le champ bufferId
dans StreamBuffer
est 0
. Par conséquent, la couche HAL de la caméra doit utiliser requestStreamBuffers
pour demander des tampons au framework de la caméra.
La méthode requestStreamBuffers
permet à l'appelant de demander plusieurs tampons à partir de plusieurs flux de sortie en un seul appel, ce qui permet moins d'appels HIDL IPC. Cependant, les appels prennent plus de temps lorsque plusieurs tampons sont demandés en même temps, ce qui peut affecter négativement la latence totale de la demande au résultat. De plus, étant donné que les appels dans requestStreamBuffers
sont sérialisés dans le service de caméra, il est recommandé que la caméra HAL utilise un thread haute priorité dédié pour demander des tampons.
Si une demande de tampon échoue, la caméra HAL doit être capable de gérer correctement les erreurs non fatales. La liste suivante décrit les raisons courantes de l'échec des demandes de tampon et la manière dont elles doivent être gérées par la couche HAL de la caméra.
- L'application se déconnecte du flux de sortie : il s'agit d'une erreur non fatale. La caméra HAL doit envoyer
ERROR_REQUEST
pour toute demande de capture ciblant un flux déconnecté et être prête à traiter normalement les demandes suivantes. - Délai d'expiration : cela peut se produire lorsqu'une application est occupée à effectuer un traitement intensif tout en conservant certains tampons. La caméra HAL doit envoyer
ERROR_REQUEST
pour les demandes de capture qui ne peuvent pas être satisfaites en raison d'une erreur de délai d'attente et être prête à traiter les demandes suivantes normalement. - La structure de la caméra prépare une nouvelle configuration de flux : la couche HAL de la caméra doit attendre que le prochain appel
configureStreams
soit terminé avant d'appeler à nouveaurequestStreamBuffers
. - La caméra HAL a atteint sa limite de tampon (le champ
maxBuffers
) : La caméra HAL doit attendre jusqu'à ce qu'elle renvoie au moins un tampon du flux avant d'appeler à nouveaurequestStreamBuffers
.
returnStreamBuffers
Utilisez la méthode returnStreamBuffers
pour renvoyer des tampons supplémentaires au framework de la caméra. La caméra HAL renvoie normalement les tampons au framework de la caméra via la méthode processCaptureResult
, mais elle ne peut prendre en compte que les demandes de capture qui ont été envoyées à la caméra HAL. Avec la méthode requestStreamBuffers
, il est possible que l'implémentation HAL de la caméra conserve plus de tampons que ce qui a été demandé par le framework de la caméra. C'est à ce moment que la méthode returnStreamBuffers
doit être utilisée. Si l'implémentation HAL ne contient jamais plus de tampons que demandé, l'implémentation HAL de la caméra n'a pas besoin d'appeler la méthode returnStreamBuffers
.
signalStreamFlush
La méthode signalStreamFlush
est appelée par le framework de la caméra pour notifier à la caméra HAL de renvoyer tous les tampons à portée de main. Ceci est normalement appelé lorsque le framework de la caméra est sur le point d'appeler configureStreams
et doit vider le pipeline de capture de la caméra. Semblable à la méthode returnStreamBuffers
, si une implémentation HAL de caméra ne contient pas plus de tampons que demandé, il est possible d'avoir une implémentation vide de cette méthode.
Une fois que la structure de la caméra a appelé signalStreamFlush
, la structure arrête d'envoyer de nouvelles demandes de capture à la caméra HAL jusqu'à ce que tous les tampons aient été renvoyés à la structure de la caméra. Lorsque tous les tampons sont renvoyés, les appels de la méthode requestStreamBuffers
échouent et la structure de la caméra peut continuer son travail dans un état propre. La structure de la caméra appelle ensuite la méthode configureStreams
ou processCaptureRequest
. Si la structure de la caméra appelle la méthode configureStreams
, la couche HAL de la caméra peut recommencer à demander des tampons après le retour réussi de l'appel configureStreams
. Si le framework de la caméra appelle la méthode processCaptureRequest
, la couche HAL de la caméra peut commencer à demander des tampons pendant l'appel processCaptureRequest
.
La sémantique est différente pour la méthode signalStreamFlush
et la méthode flush
. Lorsque la méthode flush
est appelée, HAL peut abandonner les demandes de capture en attente avec ERROR_REQUEST
pour vider le pipeline dès que possible. Lorsque la méthode signalStreamFlush
est appelée, HAL doit terminer normalement toutes les demandes de capture en attente et renvoyer tous les tampons au framework de la caméra.
Une autre différence entre la méthode signalStreamFlush
et les autres méthodes est que signalStreamFlush
est une méthode HIDL unidirectionnelle , ce qui signifie que la structure de la caméra peut appeler d'autres API de blocage avant que HAL ne reçoive l'appel signalStreamFlush
. Cela signifie que la méthode signalStreamFlush
et d'autres méthodes (en particulier la méthode configureStreams
) peuvent arriver à la caméra HAL dans un ordre différent de celui dans lequel elles ont été appelées dans le cadre de la caméra. Pour résoudre ce problème d'asynchronisme, le champ streamConfigCounter
a été ajouté à StreamConfiguration
et ajouté en tant qu'argument à la méthode signalStreamFlush
. L'implémentation HAL de la caméra doit utiliser l'argument streamConfigCounter
pour déterminer si un appel signalStreamFlush
arrive plus tard que son appel configureStreams
correspondant. Voir la figure 3 pour un exemple.
Figure 3. Comment la caméra HAL 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
Lors de l'utilisation des API de gestion des tampons pour implémenter la logique de gestion des tampons, tenez compte des changements de comportement possibles suivants pour la caméra et l'implémentation HAL de la caméra :
Les demandes de capture arrivent à la caméra HAL plus rapidement et plus fréquemment : sans les API de gestion des tampons, le cadre de la caméra demande des tampons de sortie pour chaque demande de capture avant d'envoyer une demande de capture à la caméra HAL. Lors de l'utilisation des API de gestion des tampons, le framework de la caméra n'a plus besoin d'attendre les tampons et peut donc envoyer des demandes de capture à la caméra HAL plus tôt.
De plus, sans API de gestion des tampons, la structure de la caméra arrête d'envoyer des requêtes de capture si l'un des flux de sortie de la requête de capture a atteint le nombre maximal de tampons que la HAL peut contenir en même temps (cette valeur est désignée par la HAL de la caméra dans le champ
HalStream::maxBuffers
dans la valeur de retour d'un appelconfigureStreams
). Avec les API de gestion des tampons, ce comportement de limitation n'existe plus et l'implémentation HAL de la caméra ne doit pas accepter les appelsprocessCaptureRequest
lorsque HAL a trop de demandes de capture en file d'attente.La latence des appels
requestStreamBuffers
varie considérablement : il existe de nombreuses raisons pour lesquelles un appelrequestStreamBuffers
peut prendre plus de temps que la moyenne. Par exemple:- Pour les premiers tampons d'un flux nouvellement créé, les appels peuvent prendre plus de temps car l'appareil doit allouer de la mémoire.
- La latence attendue augmente proportionnellement au nombre de tampons demandés dans chaque appel.
- L'application contient des tampons et est en cours de traitement. Cela peut ralentir les requêtes de tampon ou atteindre un délai d'attente en raison d'un manque de tampons ou d'un processeur occupé.
Stratégies de gestion des tampons
Les API de gestion de tampon permettent de mettre en œuvre différents types de stratégies de gestion de tampon. Certains exemples sont:
- Rétrocompatible : la couche HAL demande des tampons pour une demande de capture lors de l'appel
processCaptureRequest
. Cette stratégie ne fournit aucune économie de mémoire, mais peut servir de première implémentation des API de gestion de tampon, nécessitant très peu de modifications de code sur la caméra HAL existante. - Économies de mémoire maximisées : la caméra HAL ne demande que les tampons de sortie juste avant qu'un ne doive être rempli. Cette stratégie permet de maximiser les économies de mémoire. L'inconvénient potentiel est plus de jank de pipeline de caméra lorsque les demandes de tampon prennent un temps inhabituellement long pour se terminer.
- En cache : la caméra HAL met en cache quelques tampons afin qu'elle soit moins susceptible d'être affectée par une demande de tampon lente occasionnelle.
La caméra HAL peut adopter différentes stratégies pour des cas d'utilisation particuliers, par exemple, en utilisant la stratégie d'économie de mémoire maximisée pour les cas d'utilisation qui utilisent beaucoup de mémoire et en utilisant la stratégie de compatibilité descendante pour d'autres cas d'utilisation.
Exemple d'implémentation dans la caméra externe HAL
La caméra externe HAL a été introduite dans Android 9 et peut être trouvée dans l'arborescence source à hardware/interfaces/camera/device/3.5/
. In Android 10, it has been updated to include ExternalCameraDeviceSession.cpp
, an implementation of the buffer management API. This external camera HAL implements the maximized memory savings strategy mentioned in Buffer management strategies in a few hundred lines of C++ code.