? output是个什么玩意儿?为什么会根据它作为key来找线程呢?
看来,我们得去Output的来源那看看了。
我们知道,output的来源是由AT的set函数得到的:如下: audio_io_handle_t output = AudioSystem::getOutput( (AudioSystem::stream_type)streamType, //MUSIC类型 sampleRate, //8000 format, //PCM_16 channels, //2两个声道
(AudioSystem::output_flags)flags//0 );
上面这几个参数后续不再提示了,大家知道这些值都是由AT做为切入点传进去的 然后它在调用AT自己的createTrack,最终把这个output值传递到AF了。其中audio_io_handle_t类型就是一个int类型。
//叫handle啊?好像linux下这种叫法的很少,难道又是受MS的影响吗? 我们进到AudioSystem::getOutput看看。注意,大家想想这是系统的第一次调用,而且发生在AudioTrack那个进程里边。AudioSystem的位置在framework/base/media/libmedia/AudioSystem.cpp中
audio_io_handle_t AudioSystem::getOutput(stream_type stream, uint32_t samplingRate, uint32_t format, uint32_t channels, output_flags flags) {
audio_io_handle_t output = 0;
if ((flags & AudioSystem::OUTPUT_FLAG_DIRECT) == 0 && ((stream != AudioSystem::VOICE_CALL && stream != AudioSystem::BLUETOOTH_SCO) ||
channels != AudioSystem::CHANNEL_OUT_MONO || (samplingRate != 8000 && samplingRate != 16000))) { Mutex::Autolock _l(gLock); //根据我们的参数,我们会走到这个里边来
//喔,又是从map中找到stream=music的output。可惜啊,我们是第一次进来 //output一定是0
output = AudioSystem::gStreamOutputMap.valueFor(stream);
}
if (output == 0) {
//我晕,又到AudioPolicyService(APS) //由它去getOutput
const sp
output = aps->getOutput(stream, samplingRate, format, channels, flags); if ((flags & AudioSystem::OUTPUT_FLAG_DIRECT) == 0) { Mutex::Autolock _l(gLock);
//如果取到output了,再把output加入到AudioSystem维护的这个map中去 //说白了,就是保存一些信息吗。免得下次又这么麻烦去骚扰APS! AudioSystem::gStreamOutputMap.add(stream, output); } }
return output; }
怎么办?需要到APS中才能找到output的信息?
没办法,硬着头皮进去吧。那先得看看APS是如何创建的。不过这个刚才已经说了,是和AF一块在那个Main_mediaService.cpp中实例化的。
位置在framework/base/lib/libaudioflinger/ AudioPolicyService.cpp中 AudioPolicyService::AudioPolicyService()
: BnAudioPolicyService() , mpPolicyManager(NULL) {
// 下面两个线程以后再说
mTonePlaybackThread = new AudioCommandThread(String8(\
mAudioCommandThread = new AudioCommandThread(String8(\
#if (defined GENERIC_AUDIO) || (defined AUDIO_POLICY_TEST) //喔,使用普适的AudioPolicyManager,把自己this做为参数 //我们这里先使用普适的看看吧
mpPolicyManager = new AudioPolicyManagerBase(this); //使用硬件厂商提供的特殊的AudioPolicyManager //mpPolicyManager = createAudioPolicyManager(this);
} }
我们看看AudioManagerBase的构造函数吧,在framework/base/lib/audioFlinger/ AudioPolicyManagerBase.cpp中。
AudioPolicyManagerBase::AudioPolicyManagerBase(AudioPolicyClientInterface *clientInterface)
: mPhoneState(AudioSystem::MODE_NORMAL), mRingerMode(0), mMusicStopTime(0), mLimitRingtoneVolume(false) {
mpClientInterface = clientInterface;这个client就是APS,刚才通过this传进来了
AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(); outputDesc->mDevice = (uint32_t)AudioSystem::DEVICE_OUT_SPEAKER; mHardwareOutput = mpClientInterface->openOutput(&outputDesc->mDevice, &outputDesc->mSamplingRate, &outputDesc->mFormat, &outputDesc->mChannels, &outputDesc->mLatency, outputDesc->mFlags); openOutput又交给APS的openOutput来完成了,真绕.... }
唉,看来我们还是得回到APS,
audio_io_handle_t AudioPolicyService::openOutput(uint32_t *pDevices, uint32_t *pSamplingRate, uint32_t *pFormat, uint32_t *pChannels, uint32_t *pLatencyMs,
AudioSystem::output_flags flags) {
sp
//绕了这么一个大圈子,竟然回到AudioFlinger中了啊??
return af->openOutput(pDevices, pSamplingRate, (uint32_t *)pFormat, pChannels,
pLatencyMs, flags); }
在我们再次被绕晕之后,我们回眸看看足迹吧:
? 在AudioTrack中,调用set函数
? 这个函数会通过AudioSystem::getOutput来得到一个output的句柄 ? AS的getOutput会调用AudioPolicyService的getOutput
? 然后我们就没继续讲APS的getOutPut了,而是去看看APS创建的东西 ? 发现APS创建的时候会创建一个AudioManagerBase,这个AMB的创建又会调用APS的openOutput。
? APS的openOutput又会调用AudioFlinger的openOutput
有一个疑问,AT中set参数会和APS构造时候最终传入到AF的openOutput一样吗?如果不一样,那么构造时候openOutput的又是什么参数呢? 先放下这个悬念,我们继续从APS的getOutPut看看。
audio_io_handle_t AudioPolicyService::getOutput(AudioSystem::stream_type stream,
uint32_t samplingRate, uint32_t format, uint32_t channels,
AudioSystem::output_flags flags) {
Mutex::Autolock _l(mLock); //自己又不干活,由AudioManagerBase干活
return mpPolicyManager->getOutput(stream, samplingRate, format, channels, flags); } 进去看看吧
audio_io_handle_t AudioPolicyManagerBase::getOutput(AudioSystem::stream_type stream,
uint32_t samplingRate, uint32_t format, uint32_t channels,
AudioSystem::output_flags flags) {
audio_io_handle_t output = 0; uint32_t latency = 0; // open a non direct output
output = mHardwareOutput; //这个是在哪里创建的?在AMB构造的时候..
return output; }
具体AMB的分析待以后Audio系统策略的时候我们再说吧。反正,到这里,我们知道了,在APS构造的时候会open一个Output,而这个Output又会调用AF的openOutput。 int AudioFlinger::openOutput(uint32_t *pDevices, uint32_t *pSamplingRate, uint32_t *pFormat, uint32_t *pChannels, uint32_t *pLatencyMs, uint32_t flags) {
status_t status;
PlaybackThread *thread = NULL; mHardwareStatus = AUDIO_HW_OUTPUT_OPEN;
uint32_t samplingRate = pSamplingRate ? *pSamplingRate : 0; uint32_t format = pFormat ? *pFormat : 0; uint32_t channels = pChannels ? *pChannels : 0; uint32_t latency = pLatencyMs ? *pLatencyMs : 0;
Mutex::Autolock _l(mLock);
//由Audio硬件HAL对象创建一个AudioStreamOut对象
AudioStreamOut *output = mAudioHardware->openOutputStream(*pDevices, (int *)&format, &channels, &samplingRate, &status); mHardwareStatus = AUDIO_HW_IDLE; if (output != 0) { //创建一个Mixer线程
thread = new MixerThread(this, output, ++mNextThreadId); }