Mendesain untuk mengurangi latensi

Rilis Android 4.1 memperkenalkan perubahan framework internal untuk jalur output audio latensi lebih rendah. Ada perubahan API klien publik atau API HAL yang minimal. Dokumen ini menjelaskan desain awal, yang terus berkembang dari waktu ke waktu. Memahami desain ini dengan baik akan membantu OEM perangkat dan vendor SoC menerapkan desain dengan benar di perangkat dan chipset tertentu. Artikel ini tidak ditujukan untuk developer aplikasi.

Pembuatan jalur

Klien dapat menyetel bit AUDIO_OUTPUT_FLAG_FAST secara opsional dalam parameter audio_output_flags_t konstruktor C++ AudioTrack atau AudioTrack::set(). Saat ini, satu-satunya klien yang melakukannya adalah:

Implementasi C++ AudioTrack meninjau permintaan AUDIO_OUTPUT_FLAG_FAST dan dapat menolak permintaan secara opsional di tingkat klien. Jika memutuskan untuk meneruskan permintaan, metode ini melakukannya menggunakan TRACK_FAST bit parameter track_flags_t dari metode factory IAudioTrack IAudioFlinger::createTrack().

Server audio AudioFlinger meninjau permintaan TRACK_FAST dan dapat menolak permintaan tersebut di tingkat server. Fungsi ini memberi tahu klien apakah permintaan diterima atau tidak, melalui bit CBLK_FAST dari blok kontrol memori bersama.

Faktor-faktor yang memengaruhi keputusan tersebut meliputi:

  • Adanya thread mixer cepat untuk output ini (lihat di bawah)
  • Frekuensi sampel trek
  • Adanya thread klien untuk mengeksekusi pengendali callback untuk jalur ini
  • Ukuran buffer trek
  • Slot jalur cepat yang tersedia (lihat di bawah)

Jika permintaan klien diterima, permintaan tersebut disebut "jalur cepat". Jika tidak, jalur tersebut disebut "jalur normal".

Thread mixer

Saat AudioFlinger membuat thread mixer normal, thread tersebut akan memutuskan apakah akan membuat thread mixer cepat atau tidak. Mixer normal dan mixer cepat tidak dikaitkan dengan trek tertentu, tetapi dengan kumpulan trek. Selalu ada thread mixer normal. Thread mixer cepat, jika ada, tunduk pada thread mixer normal dan bertindak di bawah kontrolnya.

Mixer cepat

Fitur

Thread mixer cepat menyediakan fitur berikut:

  • Penggabungan sub-mix mixer normal dan hingga 7 jalur cepat klien
  • Attenuation per jalur

Fitur yang dihilangkan:

  • Konversi frekuensi sampel per trek
  • Efek per trek
  • Efek per mix

Titik

Mixer cepat berjalan secara berkala, dengan periode yang direkomendasikan dua hingga tiga milidetik (ms), atau periode yang sedikit lebih tinggi yaitu lima md jika diperlukan untuk stabilitas penjadwalan. Angka ini dipilih sehingga, dengan mempertimbangkan pipeline buffer lengkap, latensi totalnya berkisar 10 md. Nilai yang lebih kecil mungkin dapat dilakukan, tetapi dapat menyebabkan peningkatan konsumsi daya dan kemungkinan gangguan, bergantung pada prediktabilitas penjadwalan CPU. Nilai yang lebih besar dapat dilakukan, hingga 20 md, tetapi menghasilkan latensi total yang menurun sehingga harus dihindari.

Penjadwalan

Pengaduk cepat berjalan dengan prioritas SCHED_FIFO yang lebih tinggi. Proses ini memerlukan waktu CPU yang sangat sedikit, tetapi harus sering berjalan dan dengan jitter penjadwalan yang rendah. Jitter mengekspresikan variasi dalam waktu siklus: ini adalah perbedaan antara waktu siklus sebenarnya versus waktu siklus yang diharapkan. Berjalan terlalu lambat akan menyebabkan gangguan karena underrun. Berjalan terlalu awal akan menyebabkan gangguan karena menarik dari jalur cepat sebelum jalur tersebut memberikan data.

Pemblokiran

Idealnya, thread mixer cepat tidak pernah memblokir, selain di HAL write(). Kejadian pemblokiran lainnya dalam mixer cepat dianggap sebagai bug. Secara khusus, mutex dihindari. Sebagai gantinya, algoritma yang tidak memblokir (juga dikenal sebagai algoritma bebas kunci) digunakan. Lihat Menghindari inversi prioritas untuk mengetahui informasi selengkapnya tentang topik ini.

Hubungan dengan komponen lain

Penggabung cepat memiliki sedikit interaksi langsung dengan klien. Secara khusus, kode ini tidak melihat operasi tingkat binder, tetapi mengakses blok kontrol memori bersama klien.

Pengaduk cepat menerima perintah dari pengaduk normal melalui antrean status.

Selain mengambil data trek, interaksi dengan klien dilakukan melalui mixer normal.

Sink utama mixer cepat adalah HAL audio.

Mixer normal

Fitur

Semua fitur diaktifkan:

  • Maksimal 32 trek
  • Attenuation per jalur
  • Konversi frekuensi sampel per trek
  • Pemrosesan efek

Titik

Periode dihitung menjadi kelipatan integral pertama dari periode mixer cepat yang >= 20 mdtk.

Penjadwalan

Mixer normal berjalan dengan prioritas SCHED_OTHER yang lebih tinggi.

Pemblokiran

Mixer normal diizinkan untuk memblokir, dan sering melakukannya di berbagai mutex serta di pipa pemblokiran untuk menulis sub-mix-nya.

Hubungan dengan komponen lain

Mixer normal berinteraksi secara ekstensif dengan dunia luar, termasuk thread binder, pengelola kebijakan audio, thread mixer cepat, dan jalur klien.

Sink mixer normal adalah pipa pemblokiran ke jalur 0 mixer cepat.

Tanda

Bit AUDIO_OUTPUT_FLAG_FAST adalah petunjuk. Tidak ada jaminan bahwa permintaan akan dipenuhi.

AUDIO_OUTPUT_FLAG_FAST adalah konsep tingkat klien. File tidak muncul di server.

TRACK_FAST adalah konsep klien -> server.