自 2025 年 3 月 27 日起,我们建议您使用 android-latest-release
而非 aosp-main
构建 AOSP 并为其做出贡献。如需了解详情,请参阅 AOSP 的变更。
用于减少延迟的设计
使用集合让一切井井有条
根据您的偏好保存内容并对其进行分类。
Android 4.1 版本更改了内部框架,缩短了音频输出路径的延迟时间。该版本还对公开客户端 API 或 HAL API 进行了细微更改。本文档介绍了初始设计,此设计也在不断发展。
充分了解这一设计应该有助于设备的原始设备制造商 (OEM) 和 SoC 供应商在其特定设备和芯片组上正确地实施此设计。本文不适用于应用开发者。
创建音轨
客户端可以选择性地在 AudioTrack C++ 构造函数或 AudioTrack::set()
的 audio_output_flags_t
参数中设置位 AUDIO_OUTPUT_FLAG_FAST
。目前能执行此操作的客户端仅包括:
AudioTrack C++ 实现会审核 AUDIO_OUTPUT_FLAG_FAST
请求,并且可以选择性地拒绝客户端级别的请求。如果它决定传递该请求,则会使用 IAudioTrack
工厂方法 IAudioFlinger::createTrack()
的 track_flags_t
参数的 TRACK_FAST
位来实现。
AudioFlinger 音频服务器会审核 TRACK_FAST
请求,并且可以选择性地拒绝服务器级别的请求。它通过共享存储器控制块的位 CBLK_FAST
通知客户端是否已接受该请求。
影响决定的因素包括:
- 此输出的快速混音器线程分布(见下文)
- 音轨采样率
- 为音轨执行回调处理程序的客户端线程分布
- 音轨缓冲区的大小
- 可用的快速音轨槽(见下文)
如果客户端的请求被接受,则称为“快速音轨”,否则称为“常规音轨”。
混音器线程
AudioFlinger 在创建常规混音器线程时,会决定是否也要创建快速混音器线程。常规混音器和快速混音器都不与特定的音轨相关联,而是与一组音轨相关联。一直都会存在一个常规混音器线程。快速混音器线程(如果存在)的运行优先级低于常规混音器线程并在其控制下运行。
快速混音器
功能
快速混音器线程具备以下功能:
- 对常规混音器的子混音和最多 7 个客户端快速音轨进行混音
- 每条音轨的衰减
删减的功能:
- 每条音轨的采样率转换
- 每条音轨的效果
- 每次混音的效果
周期
快速混音器按周期运行,推荐周期为 2 到 3 毫秒 (ms),但如果有调度稳定性需求,则可采用略久的 5 毫秒为周期。
之所以选择这个数字,是为了确保在考虑完整的缓冲区流水线的情况下,总延迟时间大约为 10 毫秒。可以采用更小的值,但这样可能导致功耗增加以及出现异常,具体取决于 CPU 调度的可预测性。也可以采用更大的值(最高 20 毫秒),但这样会导致总延迟时间降级,因此应避免采用。
调度
快速混音器以较高的 SCHED_FIFO
优先级运行。它只需要很短的 CPU 时间,但必须经常运行并且具有低调度抖动。
抖动表示周期时间的变化:它是实际周期时间与预计周期时间之间的差值。运行太迟会因欠载而导致异常。运行过早则会因从快速音轨中提取数据时音轨尚未提供数据而导致异常。
屏蔽
在理想情况下,除了在 HAL write()
时,快速混音器线程不会屏蔽。快速混音器内的其他屏蔽事件将被视为 bug。尤其要避免互斥情况。
相反,应使用非屏蔽算法(也称为无锁算法)。
有关此主题的更多信息,请参阅避免优先级倒置。
与其他组件的关系
快速混音器几乎不与客户端直接交互。尤其是,快速混音器看不到 Binder 级别的操作,但它确实会访问客户端的共享存储器控制块。
快速混音器通过状态队列接收来自常规混音器的命令。
除了提取音轨数据,快速混音器通过常规混音器与客户端进行交互。
快速混音器的主接收器是音频 HAL。
常规混音器
功能
已启用所有功能:
- 最多 32 条音轨
- 每条音轨的衰减
- 每条音轨的采样率转换
- 效果处理
周期
该周期被计算为快速混音器周期(大于等于 20 毫秒)的第一个整数倍数。
调度
常规混音器以较高的 SCHED_OTHER
优先级运行。
屏蔽
允许常规混音器屏蔽,并且通常在各种互斥体以及屏蔽管中发生屏蔽,以写入其子混音。
与其他组件的关系
常规混音器与外界广泛交互,包括 Binder 线程、音频策略管理器、快速混音器线程和客户端音轨。
常规混音器的接收器是快速混音器音轨 0 的屏蔽管。
标志
AUDIO_OUTPUT_FLAG_FAST
位是一个提示。无法保证满足要求。
AUDIO_OUTPUT_FLAG_FAST
是一个客户端级别的概念。它不会出现在服务器中。
TRACK_FAST
是一个客户端到服务器的概念。
本页面上的内容和代码示例受内容许可部分所述许可的限制。Java 和 OpenJDK 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2025-03-26。
[[["易于理解","easyToUnderstand","thumb-up"],["解决了我的问题","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["没有我需要的信息","missingTheInformationINeed","thumb-down"],["太复杂/步骤太多","tooComplicatedTooManySteps","thumb-down"],["内容需要更新","outOfDate","thumb-down"],["翻译问题","translationIssue","thumb-down"],["示例/代码问题","samplesCodeIssue","thumb-down"],["其他","otherDown","thumb-down"]],["最后更新时间 (UTC):2025-03-26。"],[],[],null,["# Design for reduced latency\n\nVendors can implement two key features to reduce audio latency:\n\n- **FAST Mixer in AudioFlinger:** Introduced in Android 4.1, this feature supports apps using Java AudioTrack and AAudio. The FAST Mixer involves minimal public client API or HAL API changes.\n- **AAudio MMAP:** Introduced in Android 8.1, this feature enables native apps to achieve even lower latency through AAudio. See [AAudio and MMAP](/docs/core/audio/aaudio) for more information.\n\n\nThis page describes the initial audio latency design, which has continued to evolve over time. A\nstrong understanding of this design is crucial for device OEMs and SoC vendors to ensure correct\nimplementation on their specific devices and chipsets. This page isn't intended for app\ndevelopers.\n\nTrack creation\n--------------\n\n\nThe client can optionally set bit `AUDIO_OUTPUT_FLAG_FAST` in the\n`audio_output_flags_t` parameter of AudioTrack C++ constructor or\n`AudioTrack::set()`. Currently the only clients that do so are:\n\n- Android native audio based on [OpenSL\n ES](https://developer.android.com/ndk/guides/audio/opensl/index.html) or [AAudio](https://developer.android.com/ndk/guides/audio/aaudio/aaudio.html)\n- [`android.media.SoundPool`](http://developer.android.com/reference/android/media/SoundPool.html)\n- [`android.media.ToneGenerator`](http://developer.android.com/reference/android/media/ToneGenerator.html)\n\n\nThe AudioTrack C++ implementation reviews the `AUDIO_OUTPUT_FLAG_FAST`\nrequest and may optionally deny the request at client level. If it\ndecides to pass the request on, it does so using `TRACK_FAST` bit of\nthe `track_flags_t` parameter of the `IAudioTrack` factory method\n`IAudioFlinger::createTrack()`.\n\n\nThe AudioFlinger audio server reviews the `TRACK_FAST` request and may\noptionally deny the request at server level. It informs the client\nwhether or not the request was accepted, through bit `CBLK_FAST` of the\nshared memory control block.\n\n\nThe factors that impact the decision include:\n\n- Presence of a fast mixer thread for this output (see below)\n- Track sample rate\n- Presence of a client thread to execute callback handlers for this track\n- Track buffer size\n- Available fast track slots (see below)\n\n\nIf the client's request was accepted, it's called a *fast track* . Otherwise it's called a\n*normal track*.\n\nMixer threads\n-------------\n\n\nAt the time AudioFlinger creates a normal mixer thread, it decides\nwhether or not to also create a fast mixer thread. Both the normal\nmixer and fast mixer are not associated with a particular track,\nbut rather with a set of tracks. There is always a normal mixer\nthread. The fast mixer thread, if it exists, is subservient to the\nnormal mixer thread and acts under its control.\n\n### Fast mixer\n\n#### Features\n\n\nThe fast mixer thread provides these features:\n\n- Mixing of the normal mixer's sub-mix and up to seven client fast tracks\n- Per track attenuation\n\n\nOmitted features:\n\n- Per track sample rate conversion\n- Per track effects\n- Per mix effects\n\n#### Period\n\n\nThe fast mixer runs periodically, with a recommended period of two\nto three milliseconds, or a slightly higher period of 5 ms if needed for scheduling\nstability.\nThis number was chosen so that, accounting for the complete\nbuffer pipeline, the total latency is on the order of 10 ms. Smaller\nvalues are possible but may result in increased power consumption\nand chance of glitches depending on CPU scheduling predictability.\nLarger values are possible, up to 20 ms, but result in degraded\ntotal latency and so should be avoided.\n\n#### Scheduling\n\n\nThe fast mixer runs at elevated `SCHED_FIFO` priority. It needs very\nlittle CPU time, but must run often and with low scheduling jitter.\n[Jitter](http://en.wikipedia.org/wiki/Jitter)\nexpresses the variation in cycle time: it's the difference between the\nactual cycle time versus the expected cycle time.\nRunning too late results in glitches due to underrun. Running\ntoo early results in glitches due to pulling from a fast track\nbefore the track has provided data.\n\n#### Blocking\n\n\nIdeally the fast mixer thread never blocks, other than at HAL\n`write()`. Other occurrences of blocking within the fast mixer are\nconsidered bugs. In particular, mutexes are avoided.\nInstead, [non-blocking algorithms](http://en.wikipedia.org/wiki/Non-blocking_algorithm)\n(also known as lock-free algorithms) are used.\nSee [Avoid priority inversion](/docs/core/audio/avoiding_pi) for more on this topic.\n\n#### Relationship to other components\n\n\nThe fast mixer has little direct interaction with clients. In\nparticular, it does not see binder-level operations, but it does\naccess the client's shared memory control block.\n\n\nThe fast mixer receives commands from the normal mixer through a state queue.\n\n\nOther than pulling track data, interaction with clients is through the normal mixer.\n\n\nThe fast mixer's primary sink is the audio HAL.\n\n### Normal mixer\n\n#### Features\n\n\nAll features are enabled:\n\n- Up to 32 tracks\n- Per track attenuation\n- Per track sample rate conversion\n- Effects processing\n\n#### Period\n\n\nThe period is computed to be the first integral multiple of the\nfast mixer period that is \\\u003e= 20 ms.\n\n#### Scheduling\n\n\nThe normal mixer runs at elevated `SCHED_OTHER` priority.\n\n#### Blocking\n\n\nThe normal mixer is permitted to block, and often does so at various\nmutexes as well as at a blocking pipe to write its sub-mix.\n\n#### Relationship to other components\n\n\nThe normal mixer interacts extensively with the outside world,\nincluding binder threads, audio policy manager, fast mixer thread,\nand client tracks.\n\n\nThe normal mixer's sink is a blocking pipe to the fast mixer's track 0.\n\nFlags\n-----\n\n\n`AUDIO_OUTPUT_FLAG_FAST` bit is a hint. There's no guarantee the\nrequest will be fulfilled.\n\n\n`AUDIO_OUTPUT_FLAG_FAST` is a client-level concept. It does not appear\nin server.\n\n\n`TRACK_FAST` is a client -\\\u003e server concept."]]