Android 音频栈是 AOSP 中对性能要求最高的子系统之一。它必须将音频采样数据从 Java 应用程序一直输送到硬件 DAC,同时具备确定的延迟;还要同时支持音效处理、策略驱动的路由、带头部追踪的空间音频,以及面向专业级录音的低延迟 MMAP 通路。本章沿着 AOSP 树中的实际源码文件,逐层梳理整个音频栈,从 Java 层AudioTrackAPI 一直向下追踪到 Audio HAL 硬件接口。
音频核心服务位于frameworks/av/目录下,仅AudioFlinger就包含约 5 万行 C++ 代码;音频策略引擎、AAudio/Oboe 服务、音效库、头部追踪流水线还另有 3 万行代码。我们将阅读关键数据结构,逐行解析混音线程循环,并讲解每一处优化 —— 从运行在SCHED_FIFO优先级 3 级的 FastMixer,到完全绕过 AudioFlinger 的 MMAP 零拷贝通路。
15.1 音频架构概述
15.1.1 整体视图
Android 音频系统是一套分层流水线。音频数据经过多次进程边界传递,从应用代码流转至硬件:
应用层(Java / NDK)
|
v
AudioTrack / AAudio (客户端库,运行在应用进程)
| Binder IPC
v
AudioFlinger (audioserver进程 —— 混音、音效处理)
| HAL接口
v
Audio HAL (厂商进程,或通过HIDL/AIDL运行于同进程)
|
v
硬件(编解码器 / DSP / DAC)
AudioPolicyService与AudioFlinger共同运行在audioserver进程内。它不处理音频数据,只负责路由决策:选择输出设备、确定要施加的音效、音量处理逻辑。
15.1.2 进程与服务
audioserver进程托管三大核心服务:
| AudioFlinger | IAudioFlinger | frameworks/av/services/audioflinger/AudioFlinger.cpp(5288 行) |
| AudioPolicyService | IAudioPolicyService | frameworks/av/services/audiopolicy/service/AudioPolicyService.cpp(2759 行) |
| AAudioService | IAAudioService | frameworks/av/services/oboeservice/AAudioService.cpp(527 行) |
AudioFlinger 优先完成注册:
// AudioFlinger.cpp,第303‑308行
void AudioFlinger::instantiate() {
sp<IServiceManager> sm(defaultServiceManager());
sm->addService(String16(IAudioFlinger::DEFAULT_SERVICE_NAME),
new AudioFlingerServerAdapter(new AudioFlinger()), false,
IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT);
}
15.1.3 信号流向图

15.1.4 数据通路与控制通路
音频系统存在两条完全独立的通路:
数据通路 —— 实际 PCM 采样数据。普通混音通路的数据流向:
控制通路 —— 路由决策、音量变更、设备连接事件:
15.1.5 共享内存架构
客户端与服务端之间所有音频数据传输均使用共享内存,不使用 Binder 事务。核心结构体audio_track_cblk_t定义位置:
frameworks/av/include/private/media/AudioTrackShared.h
该控制块包含:
- 读位置(服务端)、写位置(客户端)
- 欠载 / 过载检测标志位
- 音量与静音状态
- 基于 futex 的低延迟唤醒信号机制
实际音频缓冲区存放在另一块独立共享内存区域,同时映射至客户端、服务端地址空间。进程间音频数据传输完全消除数据拷贝。
15.1.6 audioserver 进程
audioserver二进制程序是托管全部音频服务的原生守护进程,由 init 在开机早期启动:
# audioserver.rc(简化版)
service audioserver /system/bin/audioserver
class core
user audioserver
group audio camera drmrpc media mediadrm net_bt net_bt_admin
capabilities BLOCK_SUSPEND SYS_NICE
ioprio rt 4
task_profiles ProcessCapacityHigh HighPerformance
onrestart restart vendor.audio‑hal
audioserver 进程关键特性:
- 以audioserver用户运行,具备 audio 用户组权限。
- 拥有BLOCK_SUSPEND能力,播放期间可阻止设备休眠。
- 拥有SYS_NICE能力,用于设置实时线程优先级。
- I/O 优先级设置为实时 rt 4。
- 应用ProcessCapacityHigh与HighPerformance任务配置,做 CPU 调度优化。
- 重启 audioserver 的同时会重启厂商音频 HAL。
进程内部结构

15.1.7 线程类型总览
AudioFlinger 会根据输出设备创建不同类型线程:
| Mixer | MixerThread | 多路 PCM 音轨混音 | Threads.cpp 约 3700 行起 |
| Direct | DirectOutputThread | 单路 PCM 或压缩音轨 | Threads.cpp |
| Offload | OffloadThread | 硬件压缩播放 | Threads.cpp |
| Duplicating | DuplicatingThread | 输出镜像至多个输出设备 | Threads.cpp |
| Record | RecordThread | 音频输入采集 | Threads.cpp |
| Mmap | MmapPlaybackThread / MmapCaptureThread | MMAP 零拷贝通路 | Threads.cpp |
| Spatializer | SpatializerThread | 空间音频混音 | Threads.cpp |
每一类线程绑定一个 HAL 输入 / 输出流,运行在高优先级实时线程。
15.1.8 音频格式支持
Android 支持丰富的音频格式:
| PCM | 16‑bit、24‑bit packed、32‑bit、8.24 定点、float 浮点 |
| 有损压缩 | MP3、AAC、AAC‑LC、HE‑AAC、Vorbis、Opus |
| 无损压缩 | FLAC、ALAC |
| 空间音频 | Dolby Atmos、DTS:X(透传 passthrough) |
| 语音 | AMR‑NB、AMR‑WB、EVS |
PCM 格式流经混音器与音效链路。压缩格式可通过MediaCodec软件解码后送入 AudioTrack,也可直接下发至 HAL 做硬件解码(offload 通路)。
15.2 AudioFlinger
AudioFlinger 是 Android 音频的核心混音引擎,是音频栈中复杂度最高的组件。核心实现分布在 6 个源码文件,总代码量超 27000 行:
| AudioFlinger.cpp | 5288 | 服务入口、Binder 接口实现 |
| Threads.cpp | 12053 | 全部线程循环逻辑实现 |
| Tracks.cpp | 4057 | Track 对象(播放、录音、mmap) |
| Effects.cpp | 3898 | 音效链路管理 |
| PatchPanel.cpp | 1085 | 音频路由通路管理 |
| fastpath/FastMixer.cpp | 517 | 低延迟 fast mixer 通路 |
前 5 个文件位于frameworks/av/services/audioflinger/。fastpath 相关代码独立存放于fastpath/子目录(包含 FastMixer.cpp、FastCapture.cpp、FastThread.cpp、StateQueue.cpp 以及 dump/state 辅助文件);audioflinger 目录下还包含afutils/、datapath/、sounddose/、timing/子目录,分别存放工具函数、HAL 流、声音剂量、帧计数相关辅助代码。线程类声明在Threads.h(2573 行),实现在Threads.cpp。
15.2.1 AudioFlinger 初始化
AudioFlinger 构造函数逻辑十分简洁,繁重初始化工作在onFirstRef()中执行:
// AudioFlinger.cpp,第310‑341行
AudioFlinger::AudioFlinger()
{
// 随时间推移,移动音频会话唯一ID生成器起始基准值
// 降低audioserver重启后ID重复生成的风险
timespec ts{};
clock_gettime(CLOCK_MONOTONIC, &ts);
uint32_t movingBase = (uint32_t)std::max((long)1, ts.tv_sec);
for (unsigned use = AUDIO_UNIQUE_ID_USE_UNSPECIFIED;
use < AUDIO_UNIQUE_ID_USE_MAX; use++) {
mNextUniqueIds[use] =
((use == AUDIO_UNIQUE_ID_USE_SESSION
|| use == AUDIO_UNIQUE_ID_USE_CLIENT) ?
movingBase : 1) * AUDIO_UNIQUE_ID_USE_MAX;
}
BatteryNotifier::getInstance().noteResetAudio();
}
会话 ID 生成器基于单调时间偏移,避免 audioserver 重启后 ID 冲突。这一点至关重要:客户端重连时会复用之前分配的会话 ID。
onFirstRef()内部,基于工厂模式完成设备发现:
// AudioFlinger.cpp,第342‑363行
void AudioFlinger::onFirstRef()
{
audio_utils::lock_guard _l(mutex());
mMode = AUDIO_MODE_NORMAL;
mDeviceEffectManager = sp<DeviceEffectManager>::make(
sp<IAfDeviceEffectManagerCallback>::fromExisting(this)),
mDevicesFactoryHalCallback = new DevicesFactoryHalCallbackImpl;
mDevicesFactoryHal->setCallbackOnce(mDevicesFactoryHalCallback);
// …
mPatchPanel = IAfPatchPanel::create(
sp<IAfPatchPanelCallback>::fromExisting(this));
mMelReporter = sp<MelReporter>::make(
sp<IAfMelReporterCallback>::fromExisting(this),
mPatchPanel);
}
15.2.2 类继承关系
AudioFlinger 通过菱形继承模式实现多个回调接口:
// AudioFlinger.h,第60‑67行
class AudioFlinger
: public AudioFlingerServerAdapter::Delegate // IAudioFlinger客户端接口
, public IAfClientCallback
, public IAfDeviceEffectManagerCallback
, public IAfMelReporterCallback
, public IAfPatchPanelCallback
, public IAfThreadCallback
{

15.2.3 Binder 接口
AudioFlinger 对外暴露超过 50 个方法的 Binder 接口。完整方法列表以宏的形式定义在 AudioFlinger.cpp:
// AudioFlinger.cpp,第173‑244行
#define IAUDIOFLINGER_BINDER_METHOD_MACRO_LIST \\
BINDER_METHOD_ENTRY(createTrack) \\
BINDER_METHOD_ENTRY(createRecord) \\
BINDER_METHOD_ENTRY(sampleRate) \\
BINDER_METHOD_ENTRY(format) \\
BINDER_METHOD_ENTRY(frameCount) \\
BINDER_METHOD_ENTRY(latency) \\
BINDER_METHOD_ENTRY(setMasterVolume) \\
BINDER_METHOD_ENTRY(setMasterMute) \\
// … 40+个其余条目
BINDER_METHOD_ENTRY(getSoundDoseInterface) \\
BINDER_METHOD_ENTRY(getAudioPolicyConfig) \\
BINDER_METHOD_ENTRY(getAudioMixPort) \\
BINDER_METHOD_ENTRY(resetReferencesForTest) \\
每一个 Binder 方法都会通过MethodStatistics基础设施做统计与性能采集。
15.2.4 Track 创建流程
应用执行new AudioTrack()时,会调用 Binder 的createTrack方法。关键参数(AudioFlinger.h 第 82‑83 行):
status_t createTrack(const media::CreateTrackRequest& input,
media::CreateTrackResponse& output) final EXCLUDES_AudioFlinger_Mutex;
请求参数包含音频属性(usage、content type)、格式、采样率、通道掩码、帧计数、标志位。AudioFlinger 执行逻辑:
15.2.5 硬件模块加载
AudioFlinger 使用工厂模式加载 HAL 模块。已知模块 ID:
// AudioFlinger.cpp,第684‑688行
static const char * const audio_interfaces[] = {
AUDIO_HARDWARE_MODULE_ID_PRIMARY,
AUDIO_HARDWARE_MODULE_ID_A2DP,
AUDIO_HARDWARE_MODULE_ID_USB,
};
findSuitableHwDev_l()(第 690 行)遍历已加载 HAL 模块,筛选支持目标设备类型的硬件模块。
15.2.6 MixerThread 循环
混音工作发生在MixerThread。Threads.cpp中的threadLoop()是 Android 音频的核心心脏。循环逻辑结构:

Threads.cpp 中关键时间常量:
// Threads.cpp,第132‑134行
static const int8_t kMaxTrackRetries = 50;
static const int8_t kMaxTrackStartupRetries = 50;
// Threads.cpp,第154行
static const int32_t kMaxTrackRetriesDirectMs = 200;
// Threads.cpp,第169行
static const uint32_t kMinThreadSleepTimeUs = 5000;
// Threads.cpp,第175‑177行
static const uint32_t kMinNormalSinkBufferSizeMs = 20;
static const uint32_t kMaxNormalSinkBufferSizeMs = 24;
混音循环周期约 20ms。每个周期执行:
15.2.7 threadLoop_write () 方法
写通路存在两个分支(Threads.cpp 第 3557‑3616 行):
// Threads.cpp,第3557‑3626行
ssize_t PlaybackThread::threadLoop_write()
{
LOG_HIST_TS();
mInWrite = true;
ssize_t bytesWritten;
const size_t offset = mCurrentWriteLength – mBytesRemaining;
// 如果存在NBAIO sink,使用它写入普通混音器的子混音数据
if (mNormalSink != 0) {
const size_t count = mBytesRemaining / mFrameSize;
ATRACE_BEGIN(\”write\”);
// AudioFlinger::mScreenState变化时更新setpoint
const uint32_t screenState = mAfThreadCallback->getScreenState();
if (screenState != mScreenState) {
mScreenState = screenState;
MonoPipe *pipe = (MonoPipe *)mPipeSink.get();
if (pipe != NULL) {
pipe->setAvgFrames((mScreenState & 1) ?
(pipe->maxFrames() * 7) / 8 : mNormalFrameCount * 2);
}
}
ssize_t framesWritten = mNormalSink->write(
(char *)mSinkBuffer + offset, count);
ATRACE_END();
// …
} else {
// direct输出与offload线程
ATRACE_BEGIN(\”write\”);
bytesWritten = mOutput->write(
(char *)mSinkBuffer + offset, mBytesRemaining);
ATRACE_END();
}
// …
}
对于 MixerThread,写操作经过 NBAIO(非阻塞音频 I/O)MonoPipe转发至 FastMixer。Direct 与 Offload 线程直接写入 HAL 流。
屏幕状态优化逻辑值得关注:屏幕点亮时,管道平均帧阈值提升至最大值的 7/8,降低 UI 活跃时音频欠载概率;屏幕熄灭时,阈值降为普通帧数量的 2 倍,节省功耗。
15.2.8 待机管理
线程等待可配置时长(默认 3 秒)后进入待机状态:
// Threads.cpp,第252‑262行
static const nsecs_t kDefaultStandbyTimeInNsecs = seconds(3);
static nsecs_t getStandbyTimeInNanos() {
static nsecs_t standbyTimeInNanos = []() {
const int ms = property_get_int32(
\”ro.audio.flinger_standbytime_ms\”,
kDefaultStandbyTimeInNsecs / NANOS_PER_MILLISECOND);
ALOGI(\”%s: Using %d ms as standby time\”, __func__, ms);
return milliseconds(ms);
}();
return standbyTimeInNanos;
}
待机状态下,线程释放 HAL 流,释放唤醒锁,显著降低功耗。offload 输出的待机延迟更短:
// Threads.cpp,第184行
static const nsecs_t kOffloadStandbyDelayNs = seconds(1);
15.2.9 Tracks
Track 对象代表线程内部独立音频流。基类TrackBase定义在 Tracks.cpp:
// Tracks.cpp,第89‑138行
TrackBase::TrackBase(
IAfThreadBase *thread,
const sp<Client>& client,
const audio_attributes_t& attr,
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
size_t frameCount,
void *buffer,
size_t bufferSize,
audio_session_t sessionId,
pid_t creatorPid,
uid_t clientUid,
bool isOut,
const alloc_type alloc,
track_type type,
audio_port_handle_t portId,
std::string metricsId)
: mThread(thread),
mAllocType(alloc),
mClient(client),
mCblk(NULL),
mState(IDLE),
mAttr(attr),
mSampleRate(sampleRate),
mFormat(format),
mChannelMask(channelMask),
mChannelCount(isOut ?
audio_channel_count_from_out_mask(channelMask) :
audio_channel_count_from_in_mask(channelMask)),
mFrameSize(audio_bytes_per_frame(mChannelCount, format)),
mFrameCount(frameCount),
mSessionId(sessionId),
// …
每个 Track 拥有原子生成的唯一 ID:
// Tracks.cpp,第86行
static volatile int32_t nextTrackId = 55;
Track 继承层级:

15.2.10 FastMixer —— 低延迟通路
FastMixer 是独立高优先级线程,对延迟敏感的音轨可以绕过普通混音循环。定义位置:
frameworks/av/services/audioflinger/fastpath/FastMixer.cpp(517 行)
FastMixer 严格的设计约束(源码头部注释):
// FastMixer.cpp,第17‑21行
// <IMPORTANT_WARNING>
// threadLoop()的设计约束见StateQueue.h中“Fast mixer thread”章节注释。
// 特别注意:仅可在明确允许的位置调用库与系统调用。
// </IMPORTANT_WARNING>
FastMixer 支持 4 种工作策略:
// Threads.cpp,第202‑216行
static const enum {
FastMixer_Never, // 绝不初始化、绝不使用,仅用于调试
FastMixer_Always, // 始终初始化并启用,即使没有需求
FastMixer_Static, // 需要时初始化,之后持续运行
FastMixer_Dynamic, // 需要时初始化,动态启停
} kUseFastMixer = FastMixer_Static;
默认策略FastMixer_Static:一旦初始化完成,FastMixer 持续运行。优先级配置:
// Threads.cpp,第226‑228行
static const int kPriorityAudioApp = 2;
static const int kPriorityFastMixer = 3;
static const int kPriorityFastCapture = 3;
Fast track 乘数控制共享缓冲区大小:
// Threads.cpp,第237‑244行
static const int kFastTrackMultiplier = 2;
static const int kFastTrackMultiplierMin = 1;
static const int kFastTrackMultiplierMax = 2;
static int sFastTrackMultiplier = kFastTrackMultiplier;
FastMixer 线程循环
FastMixer 的onWork()(328 行)是紧凑内层循环:
// FastMixer.cpp,第328‑333行
void FastMixer::onWork()
{
const FastMixerState * const current =
(const FastMixerState *) mCurrent;
FastMixerDumpState * const dumpState =
(FastMixerDumpState *) mDumpState;
处理三类命令:
- MIX —— 将音轨混音写入混音缓冲区
- WRITE —— 将缓冲区写入输出 sink
- MIX_WRITE —— 同时执行混音与写操作
输出配置变更时,FastMixer 重新配置:
// FastMixer.cpp,第245‑270行
if (frameCount > 0 && mSampleRate > 0) {
mMixer = new AudioMixer(frameCount, mSampleRate);
// …
mPeriodNs = (frameCount * 1000000000LL) / mSampleRate; // 1.00
mUnderrunNs = (frameCount * 1750000000LL) / mSampleRate; // 1.75
mOverrunNs = (frameCount * 500000000LL) / mSampleRate; // 0.50
mForceNs = (frameCount * 950000000LL) / mSampleRate; // 0.95
mWarmupNsMin = (frameCount * 750000000LL) / mSampleRate; // 0.75
mWarmupNsMax = (frameCount * 1250000000LL) / mSampleRate; // 1.25
}
以上时间阈值定义判定标准:周期 1.75 倍判定欠载,0.5 倍判定过载。
FastMixer 内 Track 更新
单条音轨更新在updateMixerTrack()完成:
// FastMixer.cpp,第123‑191行
void FastMixer::updateMixerTrack(int index, Reason reason) {
// …
switch (reason) {
case REASON_REMOVE:
mMixer->destroy(index);
break;
case REASON_ADD: {
const status_t status = mMixer->create(
index, fastTrack->mChannelMask,
fastTrack->mFormat, AUDIO_SESSION_OUTPUT_MIX);
// …
}
[[fallthrough]];
case REASON_MODIFY:
mMixer->setBufferProvider(index, fastTrack->mBufferProvider);
// 设置音量、重采样、格式、通道掩码、触觉反馈参数
mMixer->enable(index);
break;
}
}
音量从 Track 的VolumeProvider获取:
// FastMixer.cpp,第155‑161行
float vlf, vrf;
if (fastTrack->mVolumeProvider != nullptr) {
const gain_minifloat_packed_t vlr =
fastTrack->mVolumeProvider->getVolumeLR();
vlf = float_from_gain(gain_minifloat_unpack_left(vlr));
vrf = float_from_gain(gain_minifloat_unpack_right(vlr));
} else {
vlf = vrf = AudioMixer::UNITY_GAIN_FLOAT;
}
15.2.11 PatchPanel —— 音频路由
PatchPanel 管理源端与接收端之间的音频路由通路:
frameworks/av/services/audioflinger/PatchPanel.cpp(1085 行)
一条 patch 连接多个音频端口;可以是硬件直通(设备‑设备)、设备‑混音器、混音器‑设备。创建逻辑处理多种场景:
// PatchPanel.cpp,第112‑135行
status_t PatchPanel::createAudioPatch_l(
const struct audio_patch* patch,
audio_patch_handle_t *handle,
bool endpointPatch)
{
// …
if (!audio_patch_is_valid(patch) ||
(patch->num_sinks == 0 && patch->num_sources != 2)) {
return BAD_VALUE;
}
// 当前限制源端数量最大为1;跨硬件模块特殊场景允许2个源端
if (patch->num_sources > 2) {
return INVALID_OPERATION;
}
源端数量等于 2 的特殊场景用于跨 HAL 模块路由,音频需要在两套不同 HAL 模块之间转发(例如主音频设备转发至 USB 音频)。

15.2.12 扩展声道与精度
MixerThread 支持立体声之外的扩展声道配置:
// Threads.cpp,第267行
constexpr bool kEnableExtendedChannels = true;
同时支持扩展精度格式:
// Threads.cpp,第301行
constexpr bool kEnableExtendedPrecision = true;
合法 PCM 输出 sink 格式(305‑317 行):
bool IAfThreadBase::isValidPcmSinkFormat(audio_format_t format) {
switch (format) {
case AUDIO_FORMAT_PCM_16_BIT:
return true;
case AUDIO_FORMAT_PCM_FLOAT:
case AUDIO_FORMAT_PCM_24_BIT_PACKED:
case AUDIO_FORMAT_PCM_32_BIT:
case AUDIO_FORMAT_PCM_8_24_BIT:
return kEnableExtendedPrecision;
default:
return false;
}
}
15.2.13 createTrack () 深度解析
完整createTrack()实现(AudioFlinger.cpp 第 1038 行)展示完整 Track 创建流水线:
// AudioFlinger.cpp,第1038‑1075行
status_t AudioFlinger::createTrack(
const media::CreateTrackRequest& _input,
media::CreateTrackResponse& _output)
{
ATRACE_CALL();
CreateTrackInput input =
VALUE_OR_RETURN_STATUS(CreateTrackInput::fromAidl(_input));
CreateTrackOutput output;
sp<IAfTrack> track;
sp<Client> client;
status_t lStatus;
audio_stream_type_t streamType;
audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
std::vector<audio_io_handle_t> secondaryOutputs;
bool isSpatialized = false;
bool isBitPerfect = false;
audio_io_handle_t effectThreadId = AUDIO_IO_HANDLE_NONE;
std::vector<int> effectIds;
audio_attributes_t localAttr = input.attr;
该方法校验调用来源;需要时分配会话 ID;向 AudioPolicyService 查询正确输出:
// AudioFlinger.cpp,第1069‑1091行
sessionId = input.sessionId;
if (sessionId == AUDIO_SESSION_ALLOCATE) {
sessionId = (audio_session_t)
newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
}
lStatus = AudioSystem::getOutputForAttr(
&localAttr, &output.outputId, sessionId,
&streamType, adjAttributionSource,
&input.config, input.flags,
&selectedDeviceIds, &portId, &secondaryOutputs,
&isSpatialized, &isBitPerfect);
获取输出之后,校验格式、通道掩码,定位播放线程,注册客户端,处理音效链路迁移:
// AudioFlinger.cpp,第1114‑1157行
{
audio_utils::lock_guard _l(mutex());
IAfPlaybackThread* thread =
checkPlaybackThread_l(output.outputId);
client = registerClient(
adjAttributionSource.pid,
adjAttributionSource.uid);
// 检查是否存在同session ID的音效链路运行在其他输出线程,需要迁移至此
for (const auto& [outputId, t] : mPlaybackThreads) {
if (outputId != output.outputId) {
uint32_t sessions =
t->hasAudioSession(sessionId);
if (sessions & IAfThreadBase::EFFECT_SESSION) {
effectThread = t.get();
break;
}
}
}
track = thread->createTrack_l(client, streamType,
localAttr, &output.sampleRate,
input.config.format,
input.config.channel_mask,
&output.frameCount,
&output.notificationFrameCount,
input.notificationsPerBuffer, input.speed,
input.sharedBuffer, sessionId,
&output.flags, callingPid,
adjAttributionSource,
input.clientInfo.clientTid,
&lStatus, portId,
input.audioTrackCallback,
isSpatialized, isBitPerfect,
&output.afTrackFlags);
输出结构体记录线程实际配置关键信息:
// AudioFlinger.cpp,第1161‑1167行
output.afFrameCount = thread->frameCount();
output.afSampleRate = thread->sampleRate();
output.afChannelMask =
static_cast<audio_channel_mask_t>(
thread->channelMask() |
thread->hapticChannelMask());
output.afFormat = thread->format();
output.afLatencyMs = thread->latency();
output.portId = portId;
15.2.14 dump () 调试输出系统
AudioFlinger 的 dump 系统功能完备,支持选择性调试:
// AudioFlinger.cpp,第838‑849行
static void dump_printHelp(int fd) {
constexpr static auto helpStr =
\”AudioFlinger dumpsys help options\\n\”
\” -h/–help: Print this help text\\n\”
\” –hal: Include dump of audio hal\\n\”
\” –stats: Include call/lock/watchdog stats\\n\”
\” –effects: Include effect definitions\\n\”
\” –memory: Include memory dump\\n\”
\” -a/–all: Print all except –memory\\n\”sv;
write(fd, helpStr.data(), helpStr.length());
}
dump 方法遍历全部线程类型:
// AudioFlinger.cpp,第930‑952行
// dump播放线程
for (const auto& [_, thread] : mPlaybackThreads) {
thread->dump(fd, args);
}
// dump录音线程
for (const auto& [_, thread] : mRecordThreads) {
thread->dump(fd, args);
}
// dump mmap线程
for (const auto& [_, thread] : mMmapThreads) {
thread->dump(fd, args);
}
// dump孤立音效链路
if (mOrphanEffectChains.size() != 0) {
writeStr(fd, \” Orphan Effect Chains\\n\”);
for (const auto& [_, effectChain] :
mOrphanEffectChains) {
effectChain->dump(fd, args);
}
}
同时输出电源管理、互斥锁统计、内存状态:
// AudioFlinger.cpp,第974‑979行
dprintf(fd, \”\\n ## BEGIN power dump\\n\”);
writeStr(fd, media::psh_utils::AudioPowerManager::
getAudioPowerManager().toString());
// AudioFlinger.cpp,第819‑822行
writeStr(fd, audio_utils::mutex::all_stats_to_string());
writeStr(fd, audio_utils::mutex::all_threads_to_string());
15.2.15 线程循环中的音效处理
混音线程循环内的音效处理阶段值得重点关注。混音完成后执行音效链路处理:
// Threads.cpp,第4322‑4348行
if (mSleepTimeUs == 0 && mType != OFFLOAD) {
for (size_t i = 0; i < effectChains.size(); i++) {
effectChains[i]->process_l();
// 处理音效链路输出的触觉反馈数据
if (activeHapticSessionId != AUDIO_SESSION_NONE
&& activeHapticSessionId ==
effectChains[i]->sessionId()) {
uint32_t hapticSessionChannelCount =
mEffectBufferValid ?
audio_channel_count_from_out_mask(
mMixerChannelMask) :
mChannelCount;
const size_t audioBufferSize =
mNormalFrameCount *
audio_bytes_per_frame(
hapticSessionChannelCount,
AUDIO_FORMAT_PCM_FLOAT);
memcpy_by_audio_format(
(uint8_t*)effectChains[i]->outBuffer()
+ audioBufferSize,
AUDIO_FORMAT_PCM_FLOAT,
(const uint8_t*)effectChains[i]->inBuffer()
+ audioBufferSize,
AUDIO_FORMAT_PCM_FLOAT,
mNormalFrameCount * mHapticChannelCount);
}
}
}
触觉反馈数据做特殊处理:直接从音效输入缓冲区拷贝至输出缓冲区,跳过后续音效处理。因为触觉通道由HapticGenerator生成,不应该被链路中后续音效修改。
offload 类型 Track 即使没有音频数据,依然执行音效处理:
// Threads.cpp,第4350‑4358行
if (mType == OFFLOAD) {
for (size_t i = 0; i < effectChains.size(); i++) {
effectChains[i]->process_l();
}
}
音效处理完成后,将音效缓冲区拷贝至 sink 缓冲区,对 float PCM 做限幅保护,保障 HAL 安全:
// Threads.cpp,第4398‑4405行
static constexpr float HAL_FLOAT_SAMPLE_LIMIT = 2.0f;
memcpy_to_float_from_float_with_clamping(
static_cast<float*>(mSinkBuffer),
static_cast<const float*>(effectBuffer),
framesToCopy,
HAL_FLOAT_SAMPLE_LIMIT /* absMax */);
限幅到 ±2.0f,用于保护无法处理 NaN、超大浮点数值的 HAL 实现。
15.2.16 写操作时间与抖动统计
写入 HAL 之后,线程循环统计时间抖动:
// Threads.cpp,第4436‑4476行
const int64_t lastIoBeginNs = systemTime();
ret = threadLo

