背景:
基于aosp15分析录音代码流程,并结合perfetto
应用进程层面分析
AudioRecord() (AudioRecord.java)
–>native_setup
–>android_media_AudioRecord_setup (android_media_AudioRecord.cpp)
–>new AudioRecord
–>lpRecorder->set
–>createRecord_l (AudioRecord.cpp)
–>audioFlinger->createRecord
audioserver层面分析
AudioFlinger::createRecord (AudioFlinger.cpp)
–>AudioSystem::getInputForAttr
–>AudioPolicyService::getInputForAttr
–>AudioPolicyManager::getInputForAttr
–> Engine::getInputDeviceForAttributes
–>getDeviceForInputSource
–>AudioPolicyManager::getInputForDevice
–>getInputProfile
–>new AudioInputDescriptor
–>inputDesc->open
–>mClientInterface->openInput
–>AudioFlinger::openInput (AudioFlinger.cpp)
–>openInput_l
–>findSuitableHwDev_l
–>inHwDev->openInputStream
–> IAfRecordThread::create (Threads.cpp)
–>sp::make
–>mRecordThreads.add
–>thread->createRecordTrack_l (Threads.cpp)
–> IAfRecordTrack::create
–> mTracks.add(track);
–> IAfRecordTrack::createIAudioRecordAdapter(recordTrack) (AudioFlinger.cpp)
–>sp::make
AudioRecord进行start录音
第一次唤醒剖析:
app程序在调用AudioRecord的start方法后就会触发RecordThread进行对应的Track数据读取操作,看代码以为是如下地方进行唤醒的:
status_t RecordThread::start(IAfRecordTrack* recordTrack,
AudioSystem::sync_event_t event,
audio_session_t triggerSession)
{
recordTrack->setState(IAfTrackBase::STARTING_1);
mActiveTracks.add(recordTrack);
if (recordTrack->isExternalTrack()) {
//调用到apm的startInput
status = AudioSystem::startInput(recordTrack->portId());
sendIoConfigEvent_l(
AUDIO_CLIENT_STARTED, recordTrack->creatorPid(), recordTrack->portId());
}
recordTrack->setState(IAfTrackBase::STARTING_2);
//唤醒
mWaitWorkCV.notify_all();
return status;
}
}
再看看RecordThread的运行情况:
bool RecordThread::threadLoop()
{
// loop while there is work to do
for (int64_t loopCount = 0;; ++loopCount) { // loopCount used for statistics tracking
// Note: these sp<> are released at the end of the for loop outside of the mutex() lock.
sp<IAfRecordTrack> activeTrack;
std::vector<sp<IAfRecordTrack>> oldActiveTracks;
Vector<sp<IAfEffectChain>> effectChains;
// activeTracks accumulates a copy of a subset of mActiveTracks
Vector<sp<IAfRecordTrack>> activeTracks;
// reference to the (first and only) active fast track
sp<IAfRecordTrack> fastTrack;
// reference to a fast track which is about to be removed
sp<IAfRecordTrack> fastTrackToRemove;
bool silenceFastCapture = false;
{
// if no active track(s), then standby and release wakelock
size_t size = mActiveTracks.size();
if (size == 0) {//这里会判断是否有mActiveTracks然后进入休眠
// go to sleep
mWaitWorkCV.wait(_l);
goto reacquire_wakelock;
}
//省略
上面可以看出在threadLoop中会有判断是否有Active的Track,没有就进行 mWaitWorkCV.wait等待,而上面的start方法刚好也有塞入mActiveTracks中然后进行唤醒。
但是明显这个地方显示的唤醒线程根本不是start那binder线程

而是:
所以上面分析的代码认为是start方法最后的mWaitWorkCV唤醒是不对的。
那么下面探讨一下为啥会是是ApmAudio [491] 线程呢?
明显可以看出来实际上是sendConfigEvent_l这个方法进行的唤醒,同时结合相关的日志:
04-13 00:46:24.087 369 404 V AudioPolicyService: inserting command: 5 at index 0, num commands 0
04-13 00:46:24.088 369 491 V AudioPolicyService: AudioCommandThread() processing create audio patch
04-13 00:46:24.088 369 491 V AudioFlinger::PatchPanel: createAudioPatch_l() num_sources 1 num_sinks 1 handle 0
04-13 00:46:24.088 369 491 V audio_utils::mutex: mutex_impl: audio_mutex initialized: ret:0 order:20
04-13 00:46:24.088 369 491 V AudioFlinger: sendConfigEvent_l() num events 1 event 3 //有调用sendConfigEvent_l方法而且event值为3
04-13 00:46:24.088 369 2648 V AudioFlinger: RecordThread: loop starting //RecordThread开始运行
看看这个sendConfigEvent_l是如何唤醒的

下面再来看看触发这个sendConfigEvent_l是如何触发的。
这里看看关键日志
AudioFlinger: sendConfigEvent_l() num events 1 event 3
可以看到这里是 event 3

可以知道实际上是CFG_EVENT_CREATE_AUDIO_PATCH
frameworks/av/services/audioflinger/Threads.cpp
status_t ThreadBase::sendCreateAudioPatchConfigEvent(
const struct audio_patch *patch,
audio_patch_handle_t *handle)
{
audio_utils::lock_guard _l(mutex());
sp<ConfigEvent> configEvent = (ConfigEvent *)new CreateAudioPatchConfigEvent(*patch, *handle);
status_t status = sendConfigEvent_l(configEvent);
if (status == NO_ERROR) {
CreateAudioPatchConfigEventData *data =
(CreateAudioPatchConfigEventData *)configEvent->mData.get();
*handle = data->mHandle;
}
return status;
}
而这里的sendCreateAudioPatchConfigEvent调用地方呢?
frameworks/av/services/audioflinger/PatchPanel.cpp
PatchPanel::createAudioPatch_l方法做有调用sendCreateAudioPatchConfigEvent方法
/* Connect a patch between several source and sink ports */
status_t PatchPanel::createAudioPatch_l(const struct audio_patch* patch,
audio_patch_handle_t *handle,
bool endpointPatch)
//省略
Patch newPatch{*patch, endpointPatch};
audio_module_handle_t insertedModule = AUDIO_MODULE_HANDLE_NONE;
switch (patch->sources[0].type) {
case AUDIO_PORT_TYPE_DEVICE: {
// manage patches requiring a software bridge
// - special patch request with 2 sources (reuse one existing output mix) OR
// - Device to device AND
// - source HW module != destination HW module OR
// - audio HAL does not support audio patches creation
if ((patch->num_sources == 2) ||
//省略
} else {
if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) {
status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle);
那么createAudioPatch_l方法又是哪里调用的呢?
日志中也可以寻找到线索
04-13 00:46:24.088 369 491 V AudioPolicyService: AudioCommandThread() processing create audio patch
到AudioPolicyService.cpp查一下这个日志:
frameworks/av/services/audiopolicy/service/AudioPolicyService.cpp
bool AudioPolicyService::AudioCommandThread::threadLoop()//APM专门有处理command的线程
{
case CREATE_AUDIO_PATCH: {
CreateAudioPatchData *data = (CreateAudioPatchData *)command->mParam.get();
ALOGV("AudioCommandThread() processing create audio patch");
sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
if (af == 0) {
command->mStatus = PERMISSION_DENIED;
} else {
ul.unlock();
command->mStatus = af->createAudioPatch(&data->mPatch, &data->mHandle);
ul.lock();
}
} break;
可以看出这里通过日志找到后发现就是会调用到AudioFlinger,再调用到
/* Connect a patch between several source and sink ports */
status_t AudioFlinger::createAudioPatch(
const struct audio_patch* patch, audio_patch_handle_t* handle)
{
return mPatchPanel->createAudioPatch_l(patch, handle);
}
那么接下来问题又是到底谁发了这个CREATE_AUDIO_PATCH这个command呢?
这里有需要看看创建CREATE_AUDIO_PATCH的方法createAudioPatchCommand被谁调用的。
status_t AudioPolicyService::AudioCommandThread::createAudioPatchCommand(
const struct audio_patch *patch,
audio_patch_handle_t *handle,
int delayMs)
{
sp<AudioCommand> command = new AudioCommand();
command->mCommand = CREATE_AUDIO_PATCH;
return status;
}
看看createAudioPatchCommand被谁调用呢?这里就又比较复杂了,直接上上过systrace看看

这个installPatch方法一路
start方法触发RecordThread运行,systrace总结图留下:

主要就涉及到了3个线程
2032

被折叠的 条评论
为什么被折叠?



