Design per una latenza ridotta

La versione Android 4.1 ha introdotto modifiche al framework interno per un percorso di output audio a latenza inferiore . Sono state apportate modifiche minime all'API del client pubblico o all'API HAL. Questo documento descrive il progetto iniziale, che ha continuato ad evolversi nel tempo. Avere una buona comprensione di questo design dovrebbe aiutare i fornitori di dispositivi OEM e SoC a implementare correttamente il design sui loro dispositivi e chipset particolari. Questo articolo non è destinato agli sviluppatori di applicazioni.

Creazione traccia

Il client può facoltativamente impostare il bit AUDIO_OUTPUT_FLAG_FAST nel parametro audio_output_flags_t del costruttore AudioTrack C++ o AudioTrack::set() . Attualmente gli unici clienti che lo fanno sono:

L'implementazione AudioTrack C++ esamina la richiesta AUDIO_OUTPUT_FLAG_FAST e può facoltativamente rifiutare la richiesta a livello di client. Se decide di inoltrare la richiesta, lo fa utilizzando il bit TRACK_FAST del parametro track_flags_t del metodo factory IAudioTrack IAudioFlinger::createTrack() .

Il server audio AudioFlinger esamina la richiesta TRACK_FAST e può facoltativamente negare la richiesta a livello di server. Comunica al client se la richiesta è stata accettata o meno, tramite il bit CBLK_FAST del blocco di controllo della memoria condivisa.

I fattori che influenzano la decisione includono:

  • Presenza di un thread mixer veloce per questa uscita (vedi sotto)
  • Traccia la frequenza di campionamento
  • Presenza di un thread client per eseguire gestori di callback per questa traccia
  • Traccia la dimensione del buffer
  • Posti veloci disponibili (vedi sotto)

Se la richiesta del cliente è stata accettata, si parla di "fast track". Altrimenti si chiama "traccia normale".

Fili del miscelatore

Nel momento in cui AudioFlinger crea un normale thread del mixer, decide se creare o meno anche un thread del mixer veloce. Sia il mixer normale che il mixer veloce non sono associati a una particolare traccia, ma piuttosto a un insieme di tracce. C'è sempre un normale thread del mixer. Il thread del mixer veloce, se esiste, è sottomesso al thread del mixer normale e agisce sotto il suo controllo.

Impastatrice veloce

Caratteristiche

Il thread del mixer veloce offre queste funzionalità:

  • Mixaggio del sub-mix del normale mixer e fino a 7 tracce veloci client
  • Attenuazione per traccia

Caratteristiche omesse:

  • Conversione della frequenza di campionamento per traccia
  • Effetti per traccia
  • Effetti per mix

Periodo

Il mixer veloce viene eseguito periodicamente, con un periodo consigliato di due o tre millisecondi (ms) o un periodo leggermente superiore di cinque ms, se necessario per la stabilità della pianificazione. Questo numero è stato scelto in modo tale che, tenendo conto dell'intera pipeline del buffer, la latenza totale sia dell'ordine di 10 ms. Sono possibili valori più piccoli, ma possono comportare un aumento del consumo energetico e la possibilità di problemi tecnici a seconda della prevedibilità della pianificazione della CPU. Sono possibili valori maggiori, fino a 20 ms, ma comportano una latenza totale degradata e pertanto dovrebbero essere evitati.

Programmazione

Il mixer veloce viene eseguito con priorità SCHED_FIFO elevata. Richiede pochissimo tempo di CPU, ma deve essere eseguito spesso e con un basso jitter di programmazione. Il jitter esprime la variazione del tempo di ciclo: è la differenza tra il tempo di ciclo effettivo rispetto al tempo di ciclo previsto. L'esecuzione troppo tardi provocherà problemi dovuti all'underrun. Correre troppo presto comporterà problemi dovuti all'estrazione da una pista veloce prima che la pista abbia fornito i dati.

Blocco

Idealmente il thread del mixer veloce non si blocca mai, tranne che in HAL write() . Altre occorrenze di blocco all'interno del mixer veloce sono considerate bug. In particolare, i mutex vengono evitati. Invece, vengono utilizzati algoritmi non bloccanti (noti anche come algoritmi senza blocco). Vedere Evitare l'inversione di priorità per ulteriori informazioni su questo argomento.

Relazione con altri componenti

Il mixer veloce ha poca interazione diretta con i clienti. In particolare, non vede le operazioni a livello di binder, ma accede al blocco di controllo della memoria condivisa del client.

Il mixer veloce riceve i comandi dal mixer normale tramite una coda di stato.

Oltre a estrarre i dati della traccia, l'interazione con i clienti avviene tramite il normale mixer.

Il dissipatore principale del mixer veloce è l'HAL audio.

Impastatrice normale

Caratteristiche

Tutte le funzionalità sono abilitate:

  • Fino a 32 tracce
  • Attenuazione per traccia
  • Conversione della frequenza di campionamento per traccia
  • Elaborazione degli effetti

Periodo

Il periodo viene calcolato come primo multiplo intero del periodo del mixer veloce che è >= 20 ms.

Programmazione

Il mixer normale viene eseguito con priorità SCHED_OTHER elevata.

Blocco

Al mixer normale è consentito il blocco, e spesso lo fa in vari mutex così come in una pipe di blocco per scrivere il suo sub-mix.

Relazione con altri componenti

Il mixer normale interagisce ampiamente con il mondo esterno, inclusi i thread del raccoglitore, il gestore delle politiche audio, il thread del mixer veloce e le tracce client.

Il lavandino del mixer normale è un tubo che blocca la traccia 0 del mixer veloce.

Bandiere

AUDIO_OUTPUT_FLAG_FAST bit è un suggerimento. Non c'è alcuna garanzia che la richiesta sarà soddisfatta.

AUDIO_OUTPUT_FLAG_FAST è un concetto a livello di client. Non appare nel server.

TRACK_FAST è un concetto client -> server.