La version Android 4.1 a introduit des modifications internes du framework pour un chemin de sortie audio à latence réduite. Les modifications apportées à l'API client publique ou à l'API HAL ont été minimes. Ce document décrit la conception initiale, qui a continué d'évoluer au fil du temps. Une bonne compréhension de cette conception devrait aider les OEM d'appareils et les fournisseurs de SoC à implémenter correctement la conception sur leurs appareils et chipsets spécifiques. Cet article n'est pas destiné aux développeurs d'applications.
Création de canal
Le client peut éventuellement définir le bit AUDIO_OUTPUT_FLAG_FAST
dans le paramètre audio_output_flags_t
du constructeur C++ AudioTrack ou AudioTrack::set()
. Actuellement, seuls les clients suivants peuvent le faire:
- Audio natif Android basé sur OpenSL ES ou AAudio
- android.media.SoundPool
- android.media.ToneGenerator
L'implémentation C++ d'AudioTrack examine la requête AUDIO_OUTPUT_FLAG_FAST
et peut éventuellement la refuser au niveau du client. S'il décide de transmettre la requête, il le fait à l'aide du bit TRACK_FAST
du paramètre track_flags_t
de la méthode d'usine IAudioTrack
IAudioFlinger::createTrack()
.
Le serveur audio AudioFlinger examine la requête TRACK_FAST
et peut éventuellement la refuser au niveau du serveur. Il informe le client si la requête a été acceptée ou non, via le bit CBLK_FAST
du bloc de contrôle de la mémoire partagée.
Voici quelques facteurs qui peuvent avoir une incidence sur cette décision:
- Présence d'un thread de mixeur rapide pour cette sortie (voir ci-dessous)
- Taux d'échantillonnage du canal
- Présence d'un thread client pour exécuter les gestionnaires de rappel pour ce canal
- Taille de la mémoire tampon de suivi
- Créneaux disponibles pour le traitement accéléré (voir ci-dessous)
Si la demande du client a été acceptée, elle est traitée en "voie rapide". Sinon, il s'agit d'un "canal normal".
Threads de mixeur
Au moment où AudioFlinger crée un thread de mixeur normal, il décide de créer ou non un thread de mixeur rapide. Le mixeur normal et le mixeur rapide ne sont pas associés à un canal spécifique, mais à un ensemble de canaux. Il existe toujours un thread de mixeur normal. Le thread de mixeur rapide, s'il existe, est subordonné au thread de mixeur normal et agit sous son contrôle.
Mélangeur rapide
Fonctionnalités
Le thread du mélangeur rapide fournit les fonctionnalités suivantes:
- Mélange du sous-mixage du mixeur normal et de jusqu'à sept pistes rapides client
- Atténuation par voie
Fonctionnalités omises:
- Conversion du taux d'échantillonnage par piste
- Effets par piste
- Effets par mix
Point
Le mélangeur rapide s'exécute périodiquement, avec une période recommandée de deux à trois millisecondes (ms), ou une période légèrement plus élevée de cinq ms si nécessaire pour la stabilité de la planification. Ce nombre a été choisi afin que, compte tenu du pipeline de tampon complet, la latence totale soit de l'ordre de 10 ms. Des valeurs plus faibles sont possibles, mais elles peuvent entraîner une augmentation de la consommation d'énergie et des risques de glitchs en fonction de la prévisibilité de la planification du processeur. Des valeurs plus élevées sont possibles, jusqu'à 20 ms, mais elles dégradent la latence totale et doivent donc être évitées.
Planification
Le mélangeur rapide s'exécute avec une priorité SCHED_FIFO
élevée. Il nécessite très peu de temps de processeur, mais doit s'exécuter fréquemment et avec un jitter de planification faible.
Le jitter exprime la variation du temps de cycle: il s'agit de la différence entre le temps de cycle réel et le temps de cycle attendu.
Si l'exécution est trop tardive, des glitchs peuvent se produire en raison d'un dépassement. L'exécution trop précoce entraînera des problèmes en raison de la récupération à partir d'un canal rapide avant que le canal n'ait fourni des données.
Vidéo bloquée
Idéalement, le thread du mélangeur rapide ne doit jamais se bloquer, sauf au niveau de HAL write()
. Les autres cas de blocage dans le mélangeur rapide sont considérés comme des bugs. En particulier, les mutexes sont évités.
À la place, des algorithmes non bloquants (également appelés algorithmes sans verrouillage) sont utilisés.
Pour en savoir plus, consultez Éviter l'inversion de priorité.
Relation avec les autres composants
Le mixeur rapide a peu d'interactions directes avec les clients. En particulier, il ne voit pas les opérations au niveau du liaisonneur, mais il accède au bloc de contrôle de la mémoire partagée du client.
Le mélangeur rapide reçoit des commandes du mélangeur normal via une file d'attente d'état.
En dehors de l'extraction des données de piste, l'interaction avec les clients s'effectue via le mixeur normal.
Le sink principal du mélangeur rapide est le HAL audio.
Mélangeur normal
Fonctionnalités
Toutes les fonctionnalités sont activées:
- Jusqu'à 32 pistes
- Atténuation par voie
- Conversion du taux d'échantillonnage par piste
- Traitement des effets
Point
La période est calculée comme étant le premier multiple entier de la période du mélangeur rapide qui est >= 20 ms.
Planification
Le mélangeur normal s'exécute avec une priorité SCHED_OTHER
élevée.
Vidéo bloquée
Le mélangeur normal est autorisé à bloquer, et le fait souvent à différents mutex ainsi qu'à un tube bloquant pour écrire son sous-mix.
Relation avec les autres composants
Le mixeur normal interagit de manière extensive avec le monde extérieur, y compris avec les threads de liaison, le gestionnaire de stratégie audio, le thread de mixeur rapide et les pistes client.
Le sink du mixeur normal est un tube bloquant vers le canal 0 du mixeur rapide.
Drapeaux
Le bit AUDIO_OUTPUT_FLAG_FAST
est un indice. Il n'est pas garanti que la demande sera traitée.
AUDIO_OUTPUT_FLAG_FAST
est un concept au niveau du client. Il n'apparaît pas sur le serveur.
TRACK_FAST
est un concept client-serveur.