audio flinger流程分析

本文深入探讨了ToneGenerator如何通过构造函数和startTone调用initAudioTrack创建AudioTrack,利用audioCallback获取tonesample并填充AudioTrack的Buffer结构。详细解析了AudioTrack、AudioTrackThread、AudioFlinger等关键组件在音视频生成与播放过程中的角色与交互,以及它们如何通过IPC在内存中传递和处理音频帧。

ToneGenerator.cpp

ToneGenerator中构造函数或者startTone会调用initAudioTrack:

mpAudioTrack = new AudioTrack(); 
mpAudioTrack->set(..., audioCallback, ...); 

创建了AudioTrack,并将audioCallback传入AudioTrack。

audioCallback调用ToneGenerator::WaveGenerator类的getSamples来获取tone sample,填入AudioTrack传过来的AudioTrack::Buffer结构的中:

ToneGenerator *lpToneGen = static_cast<ToneGenerator *>(user); 
short *lpOut = buffer->i16; 
lpWaveGen->getSamples(lpOut, lGenSmp, lWaveCmd); 

AudioTrack.cpp

set函数检查有没有传入callback,若有,则创建AudioTrackThread线程:

if (cbf != 0) {         
  mAudioTrackThread = new AudioTrackThread(*this, threadCanCallJava); 

AudioTrackThread线程调用AudioTrack::processAudioBuffer(),调用callback来获取frame:

obtainBuffer(&audioBuffer, 1); 
mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer); releaseBuffer(&audioBuffer); 

obtainBuffer填充audioBuffer各域,最重要的是

audioBuffer->raw = (int8_t *)cblk->buffer(u); 

cblk指向mCblk。mCblk在createTrack时赋值,实际为AudioFlinger通过IPC传递的内存空间:

sp<IAudioTrack> track = audioFlinger->createTrack() 
sp<IMemory> cblk = track->getCblk(); 
mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer()); 

AudioFinger.cpp

AudioFlinger::DirectOutputThread的函数threadLoop:

activeTrack->getNextBuffer(&buffer); 
mOutput->write(mMixBuffer, mixBufferSize); 

getNextBuffer从cblk中取得帧:

audio_track_cblk_t* cblk = this->cblk(); 
buffer->raw = getBuffer(s, framesReq); 

对于MixerThread,情况会复杂一些。创建MixerThread时,创建了AudioMixer:

mAudioMixer = new AudioMixer(mFrameCount, mSampleRate); 

MixerThread的threadLoop:

mAudioMixer->process(curBuf); 
mOutput->write(curBuf, mixBufferSize); 

进入AudioMixer::process

mState.hook(&mState, output); 

hook为AudioMixer被enable时设定,以process__nop为例:

t.bufferProvider->getNextBuffer(&t.buffer); 
t.bufferProvider->releaseBuffer(&t.buffer); 

hook调用AudioFinger的getNextBuffer来获取buffer


总体来说,应用程序使用tone generator来发送tone音,tone generator与AudioTrack打交道。AudioTrack将audio frame放入audio flinger通过IPC传递过来的一块内存中。AudioFlinger作为消费者从这一块内存中读取audio frame。

AudioFlinger 的 `instantiate()` 方法执行流程主要涉及 Android 系统的 Binder 机制以及服务的注册与实例化过程。以下是详细的分析: ### 流程分析 1. **调用 `instantiate()` 函数** AudioFlinger 类的 `instantiate()` 是一个静态函数,它调用了其父类 `BinderService` 的 `publish()` 方法。这一过程确保了 AudioFlinger 服务的创建和注册 [^4]。 ```cpp static void instantiate() { publish(); } ``` 2. **调用 `publish()` 函数** `BinderService` 提供了 `publish()` 函数,它通过 `defaultServiceManager()` 获取到 ServiceManager 的实例。接着,`addService()` 被调用,将 AudioFlinger 服务注册到 ServiceManager 的服务列表中 [^4]。 ```cpp static status_t publish(bool allowIsolated = false) { sp<IServiceManager> sm(defaultServiceManager()); return sm->addService( String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated); } ``` 3. **ServiceManager 注册服务** `addService()` 函数负责将服务名称和对应的 Binder 实例注册到 ServiceManager 中。这样,其他组件就可以通过服务名称查询到 AudioFlinger 的 Binder 接口,并与其交互 [^1]。 4. **创建 AudioFlinger 实例** 在注册过程中,`new SERVICE()` 会创建一个 AudioFlinger 的实例。该实例是通过 Binder 机制实现的,可以作为服务端与客户端进行跨进程通信 [^4]。 5. **服务管理与查询** 一旦服务注册成功,其他进程可以通过 `ServiceManager` 查询到 AudioFlinger 的服务,并获取其 Binder 接口。例如,AudioPolicyService 也会通过 `instantiate()` 方法注册到系统中,且可能通过 ServiceManager 获取 AudioFlinger 的服务 [^2]。 ### 核心类与机制 - **BinderService** BinderService 是一个模板类,提供了 `instantiate()` 和 `publish()` 等静态方法,用于简化 Binder 服务的注册流程。它封装了 ServiceManager 的调用逻辑 。 - **ServiceManager** ServiceManager 是 Android Binder 机制中的核心组件之一,负责管理系统中所有的 Binder 服务。通过 `addService()` 和 `getService()` 等接口,可以实现服务的注册和查询 [^1]。 - **Binder 机制** Android 的 Binder 机制提供了跨进程通信 (IPC) 的能力。AudioFlinger 作为一个 Binder 服务,允许客户端通过 Binder 接口与其交互,而无需关心底层的进程间通信细节 [^1]。 ### 总结 AudioFlinger 的 `instantiate()` 方法通过调用父类 `BinderService` 的 `publish()` 函数,完成了服务的注册与实例化。最终,AudioFlinger 的实例被添加到 ServiceManager 的服务列表中,使其能够被其他组件访问和使用。这一过程体现了 Android Binder 机制的核心思想,即通过 ServiceManager 管理服务,并利用 Binder 实现跨进程通信 [^1]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值