Design für reduzierte Latenz

Mit der Version Android 4.1 wurden interne Framework-Änderungen für einen Audioausgabepfad mit geringerer Latenz eingeführt. Es gab nur minimale Änderungen an der öffentlichen Client-API oder HAL-API. Dieses Dokument beschreibt den ursprünglichen Entwurf, der im Laufe der Zeit weiterentwickelt wurde. Ein gutes Verständnis dieses Designs sollte Geräte-OEMs und SoC-Anbietern dabei helfen, das Design korrekt auf ihren jeweiligen Geräten und Chipsätzen zu implementieren. Dieser Artikel richtet sich nicht an Anwendungsentwickler.

Verfolgen Sie die Erstellung

Der Client kann optional das Bit AUDIO_OUTPUT_FLAG_FAST im Parameter audio_output_flags_t des AudioTrack C++-Konstruktors oder AudioTrack::set() setzen. Derzeit sind die einzigen Kunden, die dies tun:

Die AudioTrack C++-Implementierung überprüft die AUDIO_OUTPUT_FLAG_FAST Anfrage und kann die Anfrage optional auf Clientebene ablehnen. Wenn es sich entscheidet, die Anfrage weiterzuleiten, verwendet es TRACK_FAST Bit des track_flags_t Parameters der IAudioTrack Factory-Methode IAudioFlinger::createTrack() .

Der AudioFlinger-Audioserver überprüft die TRACK_FAST Anfrage und kann die Anfrage optional auf Serverebene ablehnen. Es informiert den Client über das Bit CBLK_FAST des Shared-Memory-Steuerblocks darüber, ob die Anfrage angenommen wurde oder nicht.

Zu den Faktoren, die die Entscheidung beeinflussen, gehören:

  • Vorhandensein eines schnellen Mixer-Threads für diese Ausgabe (siehe unten)
  • Abtastrate verfolgen
  • Vorhandensein eines Client-Threads zum Ausführen von Callback-Handlern für diesen Track
  • Puffergröße verfolgen
  • Verfügbare Fast-Track-Slots (siehe unten)

Wenn die Anfrage des Kunden angenommen wurde, spricht man von einem „Fast Track“. Ansonsten spricht man von einer „normalen Strecke“.

Mixer-Threads

Wenn AudioFlinger einen normalen Mixer-Thread erstellt, entscheidet es, ob auch ein schneller Mixer-Thread erstellt werden soll oder nicht. Sowohl der normale Mixer als auch der schnelle Mixer sind nicht einer bestimmten Spur zugeordnet, sondern einer Reihe von Spuren. Es gibt immer einen normalen Mixer-Thread. Der schnelle Mixer-Thread, sofern vorhanden, ist dem normalen Mixer-Thread untergeordnet und agiert unter seiner Kontrolle.

Schnellmixer

Merkmale

Der Fast-Mixer-Thread bietet folgende Funktionen:

  • Mischen des Submixes des normalen Mixers und bis zu 7 Client-Fast-Tracks
  • Dämpfung pro Spur

Ausgelassene Funktionen:

  • Konvertierung der Sample-Rate pro Spur
  • Effekte pro Spur
  • Pro-Mix-Effekte

Zeitraum

Der schnelle Mixer läuft periodisch, mit einem empfohlenen Zeitraum von zwei bis drei Millisekunden (ms) oder einem etwas längeren Zeitraum von fünf ms, wenn dies für die Planungsstabilität erforderlich ist. Diese Zahl wurde so gewählt, dass die Gesamtlatenz unter Berücksichtigung der gesamten Pufferpipeline in der Größenordnung von 10 ms liegt. Kleinere Werte sind möglich, können jedoch abhängig von der Vorhersagbarkeit der CPU-Planung zu einem erhöhten Stromverbrauch und der Wahrscheinlichkeit von Störungen führen. Größere Werte bis zu 20 ms sind möglich, führen jedoch zu einer verringerten Gesamtlatenz und sollten daher vermieden werden.

Terminplanung

Der schnelle Mixer läuft mit erhöhter SCHED_FIFO Priorität. Es benötigt sehr wenig CPU-Zeit, muss jedoch häufig und mit geringem Planungsjitter ausgeführt werden. Jitter drückt die Schwankung der Zykluszeit aus: Er ist die Differenz zwischen der tatsächlichen Zykluszeit und der erwarteten Zykluszeit. Zu spätes Laufen führt zu Störungen aufgrund von Unterschreitung. Wenn Sie zu früh laufen, kommt es zu Störungen, da Sie von einer Überholspur abfahren, bevor die Strecke Daten bereitgestellt hat.

Blockierung

Im Idealfall blockiert der Fast-Mixer-Thread nie, außer bei HAL write() . Andere Blockierungen innerhalb des Schnellmischers werden als Fehler betrachtet. Insbesondere werden Mutexe vermieden. Stattdessen werden nicht blockierende Algorithmen (auch Lock-Free-Algorithmen genannt) verwendet. Weitere Informationen zu diesem Thema finden Sie unter Prioritätsumkehr vermeiden .

Beziehung zu anderen Komponenten

Der schnelle Mixer hat wenig direkte Interaktion mit Kunden. Insbesondere werden Vorgänge auf Ordnerebene nicht erkannt, es wird jedoch auf den Steuerblock des gemeinsam genutzten Speichers des Clients zugegriffen.

Der schnelle Mixer empfängt Befehle vom normalen Mixer über eine Statuswarteschlange.

Abgesehen vom Abrufen von Track-Daten erfolgt die Interaktion mit Clients über den normalen Mixer.

Die Hauptsenke des schnellen Mixers ist der Audio-HAL.

Normaler Mixer

Merkmale

Alle Funktionen sind aktiviert:

  • Bis zu 32 Titel
  • Dämpfung pro Spur
  • Konvertierung der Sample-Rate pro Spur
  • Effektverarbeitung

Zeitraum

Die Periode wird als erstes ganzzahliges Vielfaches der Periode des schnellen Mischers berechnet, die >= 20 ms beträgt.

Terminplanung

Der normale Mixer läuft mit erhöhter SCHED_OTHER Priorität.

Blockierung

Der normale Mixer darf blockieren und tut dies häufig an verschiedenen Mutexes sowie an einer Blockierungspipe, um seinen Untermix zu schreiben.

Beziehung zu anderen Komponenten

Der normale Mixer interagiert umfassend mit der Außenwelt, einschließlich Binder-Threads, Audio-Policy-Manager, Fast-Mixer-Thread und Client-Tracks.

Die Senke des Normalmischers ist eine Sperrleitung zur Spur 0 des Schnellmischers.

Flaggen

AUDIO_OUTPUT_FLAG_FAST Bit ist ein Hinweis. Es gibt keine Garantie, dass die Anfrage erfüllt wird.

AUDIO_OUTPUT_FLAG_FAST ist ein Konzept auf Clientebene. Es wird nicht auf dem Server angezeigt.

TRACK_FAST ist ein Client -> Server-Konzept.