Android 音频系统:从 AudioTrack 到 AudioFlinger
作者:互联网
https://blog.csdn.net/zyuanyun/article/details/60890534?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162398154816780269857280%2522%252C%2522scm%2522%253A%252220140713.130102334%E2%80%A6%2522%257D&request_id=162398154816780269857280&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-4-60890534.first_rank_v2_pc_rank_v29&utm_term=AudioFlinger&spm=1018.2226.3001.4187
audiotrack和audioflinger交互 添加链接描述
3.3. AudioFlinger 服务接口
AudioFlinger 对外提供的主要的服务接口如下:
可以归纳出 AudioFlinger 响应的服务请求主要有:
获取硬件设备的配置信息 sampleRate、format、frameCount、latency
音量调节 setMasterVolume、setStreamVolume、setVoiceVolume
静音操作 setMasterMute、setStreamMute、setMicMute
音频模式切换 setMode Normal、Ringtone、Call、Communicatoin
音频参数设置 setParameters
输入输出流设备管理 openOutput closeOutput openInput closeInput openRecord
音频流管理 createTrack start/stop/pause
- ThreadBase:PlaybackThread 和 RecordThread 的基类
- RecordThread:录制线程类,由 ThreadBase 派生
- PlaybackThread:回放线程基类,同由 ThreadBase 派生
- MixerThread:混音回放线程类,由 PlaybackThread 派生,负责处理标识为
AUDIO_OUTPUT_FLAG_PRIMARY、AUDIO_OUTPUT_FLAG_FAST、AUDIO_OUTPUT_FLAG_DEEP_BUFFER
的音频流,MixerThread 可以把多个音轨的数据混音后再输出 - DirectOutputThread:直输回放线程类,由 PlaybackThread 派生,负责处理标识为
AUDIO_OUTPUT_FLAG_DIRECT 的音频流,这种音频流数据不需要软件混音,直接输出到音频设备即可 - DuplicatingThread:复制回放线程类,由 MixerThread
派生,负责复制音频流数据到其他输出设备,使用场景如主声卡设备、蓝牙耳机设备、USB 声卡设备同时输出 - OffloadThread:硬解回放线程类,由 DirectOutputThread 派生,负责处理标识为
AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD 的音频流,这种音频流未经软件解码的(一般是 MP3、AAC
等格式的数据),需要输出到硬件解码器,由硬件解码器解码成 PCM 数据
PlaybackThread 中有个极为重要的函数 threadLoop(),当 PlaybackThread 被强引用时,threadLoop() 会真正运行起来进入循环主体,处理音频流数据相关事务,threadLoop() 大致流程如下(以 MixerThread 为例):
bool AudioFlinger::PlaybackThread::threadLoop()
{
// ......
while (!exitPending())
{
// ......
{ // scope for mLock
Mutex::Autolock _l(mLock);
processConfigEvents_l();
// ......
if ((!mActiveTracks.size() && systemTime() > mStandbyTimeNs) ||
isSuspended()) {
// put audio hardware into standby after short delay
if (shouldStandby_l()) {
threadLoop_standby();
mStandby = true;
}
// ......
}
// mMixerStatusIgnoringFastTracks is also updated internally
mMixerStatus = prepareTracks_l(&tracksToRemove);
// ......
} // mLock scope ends
// ......
if (mBytesRemaining == 0) {
mCurrentWriteLength = 0;
if (mMixerStatus == MIXER_TRACKS_READY) {
// threadLoop_mix() sets mCurrentWriteLength
threadLoop_mix();
}
// ......
}
// ......
if (!waitingAsyncCallback()) {
// mSleepTimeUs == 0 means we must write to audio hardware
if (mSleepTimeUs == 0) {
// ......
if (mBytesRemaining) {
// FIXME rewrite to reduce number of system calls
ret = threadLoop_write();
lastWriteFinished = systemTime();
delta = lastWriteFinished - mLastWriteTime;
if (ret < 0) {
mBytesRemaining = 0;
} else {
mBytesWritten += ret;
mBytesRemaining -= ret;
mFramesWritten += ret / mFrameSize;
}
}
// ......
}
// ......
}
// Finally let go of removed track(s), without the lock held
// since we can't guarantee the destructors won't acquire that
// same lock. This will also mutate and push a new fast mixer state.
threadLoop_removeTracks(tracksToRemove);
tracksToRemove.clear();
// ......
}
threadLoop_exit();
if (!mStandby) {
threadLoop_standby();
mStandby = true;
}
// ......
return false;
}
标签:AudioTrack,音频,threadLoop,AudioFlinger,音频系统,线程,PlaybackThread,Android,...... 来源: https://blog.csdn.net/weixin_34323585/article/details/118695849