Android 源码分析 - 声音 - 流程

本文深入剖析了Android音频系统的初始化过程,包括AudioPolicyService的构造、策略创建、输出流的管理和音效配置加载。接着,详细阐述了设备接入、音量设置以及策略路由的计算方法,展示了如何根据流类型选择合适的输出设备。此外,还涵盖了AudioService的构造和AudioFlinger在处理输出流、音量控制和策略变更时的角色。整个流程展示了Android音频系统在不同场景下的灵活管理和智能路由策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

初始化(AudioPolicy)

  • AudioPolicyService构造
  1. new AudioCommandThread【ApmTone】
  2. new AudioCommandThread【ApmAudio】
  3. new AudioCommandThread【ApmOutput】
  4. hw_get_module()【打开策略模块】
  5. audio_policy_dev_open()【创建策略设备】
  6. mpAudioPolicyDev->create_audio_policy()【创建策略,步骤二】
  7. mpAudioPolicy->init_check()
  8. loadPreProcessorConfig()【加载音效配置文件】
    1. 文件/system/etc/audio_effects.conf
    2. 文件/vendor/etc/audio_effects.conf
  • legacy_audio_policy创建策略

默认策略HAL实现,读取audio_policy.conf文件,打开连接主类型设备的输出流(default_output_device,只有一个类型)。

  1. new AudioPolicyCompatClient【新老接口转换audio_policy_service_ops】
  2. createAudioPolicyManager()
    1. new AudioPolicyManagerDefault()【继承AudioPolicyManagerBase】
      1. loadAudioPolicyConfig()
        1. 文件/vendor/etc/audio_policy.conf
        2. 文件/system/etc/audio_policy.conf
        3. loadGlobalConfig()【解析全局配置】
        4. loadHwModules()【解析模块配置,mHwModules】
          1. loadHwModule【解析一个模块的配置,HwModule】
            1. loadOutput【IOProfile】
            2. loadInput【IOProfile】
      2. foreach mHwModules
        1. mpClientInterface->loadHwModule()【加载模块和声音设备】
        2. foreach module->mOutputProfiles
          1. if 【模块包含attached_output_devices,且没有AUDIO_OUTPUT_FLAG_DIRECT】
            1. mpClientInterface->openOutput()【打开设备输出流】
              1. aps_open_output()
                1. af->openOutput()【步骤三】
            2. addOutput()【增加到mOutputs】
            3. setOutputDevice()【更改输出设备路由】
              1. mOutputs.valueFor()【查找对应的AudioOutputDescriptor】
              2. if (outputDesc->isDuplicated())【分别设置内部的两个Output】
                1. setOutputDevice(outputDesc->mOutput1->mId)
                2. setOutputDevice(outputDesc->mOutput2->mId)
                3. return
              3. checkDeviceMuteStrategies()【改变路由前静音,步骤四】
              4. mpClientInterface->setParameters()【设置routing】
                1. aps_set_parameters()
                  1. audioPolicyService->setParameters()【步骤五】
      3. updateDevicesAndOutputs()
        1. for [0, NUM_STRATEGIES)
          1. getDeviceForStrategy()【计算具体策略表】
  • AudioFlinger打开输出流(openOutput,对应PlaybackThread)
  1. AudioFlinger::openOutput()
    1. findSuitableHwDev_l()【查找适合的模块】
      1. if (module == 0)【没有指定模块】
      2. else【指定了模块】
        1. find mAudioHwDevs by module
        2. return audioHwDevice
  2. outHwDev->hwDevice()【获取audio_hw_device设备】
  3. nextUniqueId()【生成唯一ID】
  4. hwDevHal->open_output_stream()【打开流audio_stream_out_t】
  5. new AudioStreamOut
  6. if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)
    1. new OffloadThread
  7. else if 【AUDIO_OUTPUT_FLAG_DIRECT或!PCM_16_BIT或!STEREO】
    1. new DirectOutputThread
  8. else
    1. new MixerThread
  9. mPlaybackThreads.add(id,thread)【id对应thread】
  10. thread->audioConfigChanged_l(AudioSystem::OUTPUT_OPENED)
    1. mAudioFlinger->audioConfigChanged_l()【通知所有客户端】
      1. foreach mNotificationClients
        1. client->audioFlingerClient()->ioConfigChanged()
  • AudioPolicyManagerBase策略静音(checkDeviceMuteStrategies)
  1. AudioPolicyManagerBase::checkDeviceMuteStrategies()
    1. 《TO BE CONTINUED》
  • AudioPolicyService设置参数(setParameters)
  1. AudioPolicyService::setParameters()
    1. mAudioCommandThread->parametersCommand()
      1. new AudioCommand
      2. new ParametersData
      3. insertCommand_l()
        1. mAudioCommands.insertAt()
      4. mWaitWorkCV.signal()
  • AudioCommandThread线程里面处理(SET_PARAMETERS)
  1. AudioPolicyService::AudioCommandThread::threadLoop()
    1. case SET_PARAMETERS
      1. AudioSystem::setParameters()
        1. af->setParameters()【AudioFlinger】
  • AudioFlinger处理(setParameters)
  1. AudioFlinger::setParameters()
    1. checkPlaybackThread_l()【查找】
    2. if (thread == primaryPlaybackThread_l())
      1. foreach mRecordThreads【通知输入线程】
        1. thread->setParameters()
    3. thread->setParameters()【ThreadBase】
      1. mNewParameters.add()
      2. mWaitWorkCV.signal()
  • PlaybackThread处理(setParameters)
  1. PlaybackThread::threadLoop()
    1. checkForNewParameters_l()【MixerThread、DirectOutputThread】
      1. mOutput->stream->common.set_parameters()【HAL audio_stream】

初始化(AudioService)

  1. AudioService.AudioService()【构造】
    1. mAppOps【AppOpsManager,Context.APP_OPS_SERVICE】
    2. mVoiceCapable【是否支持电话,config_voice_capable】
    3. mAudioEventWakeLock【部分消息处理中不能待机,pm.newWakeLock()】
    4. mHasVibrator【是否有振动器,VIBRATOR_SERVICE】
    5. MAX_STREAM_VOLUME[STREAM_VOICE_CALL]【ro.config.vc_call_vol_steps】
    6. sSoundEffectVolumeDb【config_soundEffectVolumeDb】
    7. mVolumePanel【UI】
    8. createAudioSystemThread()【AudioHandler消息处理线程】
      1. new AudioSystemThread().start()
      2. waitForAudioHandlerCreation()【等待线程内部Handler创建】
    9. mMediaFocusControl【new MediaFocusControl】
    10. AudioSystem.setErrorCallback()
    11. mCameraSoundForced【config_camera_sound_forced】
    12. sendMsg(MSG_SET_FORCE_USE)
    13. mSafeMediaVolumeState【Settings.Global.AUDIO_SAFE_VOLUME_STATE】
    14. mSafeMediaVolumeIndex【config_safe_media_volume_index】
    15. mUseFixedVolume【每个流类型统一音量,config_useFixedVolume】
    16. updateStreamVolumeAlias()
      1. if (mVoiceCapable)
        1. mStreamVolumeAlias = STREAM_VOLUME_ALIAS
      2. else
        1. mStreamVolumeAlias = STREAM_VOLUME_ALIAS_NON_VOICE
    17. readPersistedSettings()
      1. mRingerMode【Settings.Global.MODE_RINGER】
      2. mVibrateSetting
      3. updateRingerModeAffectedStreams()
      4. readDockAudioSettings()
      5. mMuteAffectedStreams【System.MUTE_STREAMS_AFFECTED】
      6. masterMute【System.VOLUME_MASTER_MUTE】
      7. if (mUseFixedVolume)
        1. masterMute = false
        2. AudioSystem.setMasterVolume(1.0f) 【设置主音量】
      8. AudioSystem.setMasterMute()【设置主静音模式】
      9. broadcastMasterMuteStatus()【AudioManager.MASTER_MUTE_CHANGED_ACTION】
      10. broadcastRingerMode()【AudioManager.RINGER_MODE_CHANGED_ACTION】
      11. broadcastVibrateSetting()【AudioManager.VIBRATE_SETTING_CHANGED_ACTION】
      12. mMediaFocusControl.restoreMediaButtonReceiver()
    18. mSettingsObserver【new SettingsObserver()】
    19. createStreamStates()
      1. for i = 0 ~ AudioSystem.getNumStreamTypes()
        1. new VolumeStreamState
          1. mStreamType【i】
          2. mIndexMax【MAX_STREAM_VOLUME[i] * 10】
          3. AudioSystem.initStreamVolume()
          4. mDeathHandlers【】
          5. readSettings()
            1. if (mUseFixedVolume)
              1. mIndex.put(AudioSystem.DEVICE_OUT_DEFAULT)【mIndexMax】
              2. return
            2. mIndex.put(AudioSystem.DEVICE_OUT_DEFAULT)【DEFAULT_STREAM_VOLUME * 10】
            3. forall AudioSystem.DEVICE_OUT_ALL【所有设备】
              1. getSettingNameForDevice()【设置项目名称】
              2. Settings.System.getIntForUser()
              3. mIndex.put()【】
    20. readAndSetLowRamDevice()
    21. setRingerModeInt()
    22. new IntentFilter()【计算广播过滤器,mReceiver】
    23. mMonitorOrientation【ro.audio.monitorOrientation】
      1. setOrientationForAudioSystem()
    24. mMonitorRotation【ro.audio.monitorRotation】
      1. setRotationForAudioSystem()
    25. context.registerReceiver()
    26. mUseMasterVolume【config_useMasterVolume】
    27. mMasterVolumeRamp【数组,config_masterVolumeRamp】

设备接入

  • 外部报告设备接入

谁是外部?

  1. AudioSystem::setDeviceConnectionState()【AVAILABLE】
    1. aps->setDeviceConnectionState【IAudioPolicyService】
      1. mpAudioPolicy->set_device_connection_state()
        1. AudioPolicyManagerBase::setDeviceConnectionState()
  • AudioPolicyManagerBase处理设备状态更新
  1. AudioPolicyManagerBase::setDeviceConnectionState()【AVAILABLE】
    1. if (audio_is_output_device(device))
      1. checkOutputsForDevice()【打开该设备的所有流,返回所有与该设备相关的outputs,步骤三】
      2. mAvailableOutputDevices【登记新设备】
      3. device_address【转换为参数paramStr】
      4. foreach outputs
        1. mpClientInterface->setParameters()
      5. checkA2dpSuspend()
      6. checkOutputForAllStrategies()【检查几种策略】
        1. checkOutputForStrategy()【执行策略变化,步骤四】
      7. foreach outputs【关闭FLAG_DIRECT,mDirectOpenCount==0】
        1. closeOutput()
          1. mpClientInterface->closeOutput()
      8. updateDevicesAndOutputs()【更新策略表mDeviceForStrategy】
      9. foreach mOutputs
        1. getNewDevice()
          1. 【根据流上激活的策略,按照一定的策略优先级顺序,计算输出设备】
        2. setOutputDevice()【更新输出流的设备路由,见初始化流程中】
      10. 【输出转输入,继续处理,WIRED_HEADSET、BLUETOOTH_SCO】
    2. 【输出设备处理结束】
    3. if (audio_is_input_device(device))
    4. 【输入设备处理结束】
  • 打开该设备的所有流(checkOutputsForDevice)
  1. foreach mOutputs【查找已经打开可以路由到该设备的输出流】
  2. foreach mHwModules/mOutputProfiles【查找可以路由到该设备的输出端口】
  3. foreach profiles【没有打开的profile,都打开】
    1. mpClientInterface->openOutput()
    2. if (desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT)
      1. addOutput()
    3. else【非DIRECT,增加DuplicateOutput复制主output】
      1. addOutput()
      2. applyStreamVolumes()
      3. mpClientInterface->openDuplicateOutput()
      4. addOutput()
      5. applyStreamVolumes()
    4. outputs.add(output)【添加到输出集合中】
  • 执行某个策略变化(checkOutputForStrategy)

根据新老情形,以及输入策略类型,计算新老目标输出流集合。老的通过缓存(fromCache)和备份的所有流集合(mPreviousOutputs)计算。

  1. getDeviceForStrategy()【老的和新的】
  2. getOutputsForDevice()【老的和新的】
  3. if (!vectorsEqual(srcOutputs,dstOutputs))【有变化】
    1. foreach srcOutputs【老的目标输出流集合】
      1. if (output->isStrategyActive())【该流上的本策略是激活的】
        1. setStrategyMute()【移动策略时静音】
    2. if (strategy == STRATEGY_MEDIA)
      1. mpClientInterface->moveEffects()
    3. for (i = 0 to NUM_STREAM_TYPES)
      1. if (getStrategy(i) == strategy)
        1. mpClientInterface->setStreamOutput()【移动Track】
          1. aps_set_stream_output()
            1. af->setStreamOutput()【步骤五】
  • AudioFlinger切换输出流(setStreamOutput)

AudioFlinger仅仅把指定类型的流置为invalid状态。

  1. foreach mPlaybackThreads
    1. thread->invalidateTracks()
      1. foreach mTracks
        1. if (t->streamType() == streamType)【类型匹配】
          1. t->invalidate()

音量设置

  • AudioManager处理音量按键事件(handleKeyDown、handleKeyUp)

音量按键事件由PhoneWindowManager在interceptKeyBeforeQueueing方法中转发给AudioManager处理。

  1. AudioManager:: handleKeyDown()
    1. case KeyEvent.KEYCODE_VOLUME_UP
    2. case KeyEvent.KEYCODE_VOLUME_DOWN
      1. if (mUseMasterVolume)
        1. adjustMasterVolume()【加减一个等级】
          1. service.adjustMasterVolume()【步骤二】
      2. else
        1. adjustSuggestedStreamVolume()
          1. service.adjustSuggestedStreamVolume()【步骤二】
    3. case KeyEvent.KEYCODE_VOLUME_MUTE
      1. if (mUseMasterVolume)
        1. setMasterMute(!isMasterMute())
          1. service.setMasterMute()【步骤二】
  • AudioService调整音量处理

设置主音量直接设置的底层了,设置流类型的音量在Handler线程处理。

  1. AudioService.adjustMasterVolume()【调整主音量】
    1. findVolumeDelta()【根据当前音量,调整量不同】
    2. setMasterVolume()
      1. mAppOps.noteOp(OP_AUDIO_MASTER_VOLUME)
      2. doSetMasterVolume()
        1. AudioSystem.setMasterVolume()【JNI方法】
          1. AudioSystem::setMasterVolume()【Native方法】
            1. af->setMasterVolume()【步骤四】
        2. if (newVolume != oldVolume)
          1. sendMsg(MSG_PERSIST_MASTER_VOLUME)【保存到系统设置里面Settings.System.VOLUME_MASTER】
        3. sendMasterVolumeUpdate()
          1. sendBroadcastToAll(MASTER_VOLUME_CHANGED_ACTION)【通知UI更新】
  2. AudioService.setMasterMute()【设置主音量静音状态】
    1. AudioSystem.setMasterMute(state) 【JNI方法】
      1. AudioSystem::setMasterMute ()【Native方法】
        1. af->setMasterMute()【步骤四】
    2. sendMsg(MSG_PERSIST_MASTER_VOLUME_MUTE) 【保存到系统设置里面Settings.System.VOLUME_MASTER_MUTE】
    3. sendMasterMuteUpdate()【通知UI更新】
  3. AudioService.adjustSuggestedStreamVolume()【调整某种流的音量】
    1. getActiveStreamType()【获取当前活动流类型】
    2. adjustStreamVolume()
      1. 【转换为替代类型,mStreamVolumeAlias,后面都是先设置替代类型】
      2. getDeviceForStream()
        1. AudioSystem.getDevicesForStream()
      3. mAppOps.noteOp()
      4. rescaleIndex()【使用数值10,缩放到Alias类型的范围】
      5. streamState.adjustIndex()【VolumeStreamState记录某个流类型各设备的音量】
        1. setIndex()
          1. getValidIndex()【限制在0~mIndexMax之间】
          2. foreach 【被替代的流,Alias,跟着一起改变】
            1. rescaleIndex()【从Alias的音量范围缩放到该类型的范围】
      6. sendMsg(MSG_SET_DEVICE_VOLUME)【线程里面处理】
      7. sendVolumeUpdate()【通知UI更新】
  • AudioHandler线程处理
  1. AudioService.AudioHandler.handleMessage()
    1. case MSG_SET_DEVICE_VOLUME
      1. setDeviceVolume()
        1. streamState.applyDeviceVolume()【index+5/10,四舍五入】
          1. AudioSystem.setStreamVolumeIndex()【JNI方法】
            1. AudioSystem::setStreamVolumeIndex()【Native方法】
              1. aps->setStreamVolumeIndex()【步骤五】
        2. foreach 【被替代的流,Alias,跟着一起改变】
          1. getDeviceForStream()
          2. stream.applyDeviceVolume()
        3. sendMsg(MSG_PERSIST_VOLUME) 【保存到系统设置里面Settings.System.VOLUME_MASTER】
  • AudioFlinger设置主音量
  1. AudioFlinger::setMasterVolume()
    1. foreach mAudioHwDevs【如果HAL支持,设置到HAL中】
      1. dev->hwDevice()->set_master_volume()
    2. foreach mPlaybackThreads
      1. thread->set_master_volume()
        1. if (mOutput->audioHwDev->canSetMasterVolume())
          1. mMasterVolume = 1.0【如果HAL支持,不需要软件实现】
        2. else
          1. mMasterVolume = value
  2. AudioFlinger::setMasterMute()
    1. foreach mAudioHwDevs【如果HAL支持,设置到HAL中】
      1. dev->hwDevice()->set_master_mute()
    2. foreach mPlaybackThreads
      1. thread->set_master_volume()
        1. if (mOutput->audioHwDev->canSetMasterMute())
          1. mMasterMute = false【如果HAL支持,不需要软件实现】
        2. else
          1. mMasterMute = muted
  • AudioPolicyService设置流类型音量(setStreamVolumeIndex)
  1. AudioPolicyService::setStreamVolumeIndex()
    1. if (mpAudioPolicy->set_stream_volume_index_for_device)
      1. mpAudioPolicy->set_stream_volume_index_for_device()【步骤六】
    2. else
      1. mpAudioPolicy->set_stream_volume_index()【不指定设备】
  • AudioPolicyManagerBase设置音量(setStreamVolumeIndex)
  1. AudioPolicyManagerBase::setStreamVolumeIndex()
    1. 更新到mStreams【StreamDescriptor记录一种流的每个设备的音量设置】
    2. foreach mOutputs【音量设置到每个输出流上】
      1. getDeviceForVolume()【多个设备,由其中的SPEAKER或者ALL_A2DP代表】
      2. if ((device == AUDIO_DEVICE_OUT_DEFAULT) || (device == curDevice))【当前输出流的设备与目标设备一样,或者没有确定的目标】
        1. checkAndSetVolume()【修改输出流上该类型流的音量】
          1. computeVolume()【计算音量,见细节“音量计算”】
            1. volIndexToAmpl()【等级标准值】
          2. if 【AudioOutputDescriptor记录每个流类型的当前音量,如果新老音量值不一样】
            1. mpClientInterface->setStreamVolume()
              1. aps_set_stream_volume()
                1. audioPolicyService->setStreamVolume()【步骤七】
  • AudioPolicyService设置音量(setStreamVolume)
  1. mAudioCommandThread->volumeCommand()
    1. new AudioCommand
    2. new VolumeData
    3. insertCommand_l()
    4. mWaitWorkCV.signal()
  • AudioCommandThread线程里面处理(SET_VOLUME)
  1. AudioPolicyService::AudioCommandThread::threadLoop()
    1. case SET_VOLUME
      1. AudioSystem::setStreamVolume()
        1. af->setStreamVolume()【AudioFlinger,步骤九】
  • AudioFlinger处理(setStreamVolume)
  1. AudioFlinger::setStreamVolume()
    1. checkPlaybackThread_l()【查找】
    2. if (thread == NULL)【没有指定输出流】
      1. foreach mPlaybackThreads【通知输入线程】
        1. thread->setStreamVolume()【PlaybackThread】
          1. 【mStreamTypes记录每个流类型的音量和静音状态】
          2. broadcast_l()
    3. else
      1. thread->setStreamVolume()【同上】
  • MixerThread使用音量(prepareTracks_l)

打开输出轨道

  • 应用与AudioFlinger连接

连接由AudioSystem管理,上层逻辑不会主动与AudioFlinger连接,当调用到AudioFlinger接口方法时,AudioSystem连接到AudioFlinger服务,并将当前进程注册到AudioFlinger内部。

  1. AudioSystem::get_audio_flinger()
    1. ServiceManager::getService()【进程单例,等待并循环】
    2. new AudioFlingerClient【进程单例】
    3. gAudioFlinger->registerClient()
      1. new NotificationClient()
      2. mNotificationClients.add()
      3. foreach mPlaybackThreads
        1. thread->sendIoConfigEvent(OUTPUT_OPENED)
          1. sendIoConfigEvent_l【使用内部线程发送,防止死锁】
            1. new IoConfigEvent
            2. mConfigEvents.add()
            3. mWaitWorkCV.signal()
      4. foreach mRecordThreads
        1. thread->sendIoConfigEvent(OUTPUT_OPENED)
  • 应用内部创建AudioTrack
  1. AudioTrack::AudioTrack()
    1. AudioTrack::set()
      1. transferType【参数检查,默认值设置】
      2. streamType【默认AUDIO_STREAM_MUSIC】
      3. sampleRate【默认根据streamType计算】
      4. format【默认AUDIO_FORMAT_PCM_16_BIT】
      5. channelMask【默认AUDIO_CHANNEL_OUT_STEREO】
      6. AudioSystem::getOutput()
        1. aps->getOutput()【使用策略,步骤三】
      7. if (cbf != NULL)
        1. new AudioTrackThread【创建线程调用回调】
      8. createTrack_l()
        1. AudioSystem::getLatency()【output的latency】
          1. AudioSystem::get_audio_flinger()【与AudioFlinger连接,步骤一】
        2. AudioSystem::getFrameCount()【output的framecount】
        3. AudioSystem::getSamplingRate【output的samplerate】
        4. audioFlinger->createTrack()【创建Track,步骤四】
        5. track->getCblk()【获取内存控制块】
        6. mAudioTrack->attachAuxEffect()
        7. new AudioTrackClientProxy【创建客户缓存管理对象】
      9. AudioSystem::acquireAudioSessionId()【增加当前进程对该会话的引用计数】
  • AudioPolicyService计算策略
  1. AudioPolicyService::getOutput()
    1. mpAudioPolicy->get_output()【HAL的ap_get_output】
      1. AudioPolicyManagerBase::getOutput()

后面见流程“策略路由”。

  • AudioFlinger创建输入轨道(createTrack)
  1. checkPlaybackThread_l()【根据output查找PlaybackThread】
  2. registerPid_l()【注册调用者pid】
    1. new Client【mClients保存所有Client】
  3. if 【指定了sessionId】
    1. 【查找包含该会话EffectChain的线程】
  4. else【如果没有指定】
    1. nextUniqueId()【分配一个】
  5. thread->createTrack_l()【创建一个Track,步骤五】
  6. moveEffectChain_l()【】
  7. SyncEvent【等待使用的同步处理】
  8. new TrackHandle【封装Track,代理跨进程访问】
  • PlaybackThread创建输入轨道(createTrack_l)
  1. 【参数检查TRACK_FAST】
  2. 【校验所有同一个sessionId的Track的strategy必须相同】
    1. AudioSystem::getStrategyForStream()【stream_type转换到routing_strategy】
  3. new Track【创建PlaybackThread::Track】
    1. TrackBase::TrackBase【TrackBase构造】
      1. if (client != 0)【有客户端】
        1. client->heap()->allocate()【需要更新内存】
      2. else
        1. new uint8_t[size]【申请私有内存】
      3. new(mCblk) audio_track_cblk_t()【控制块构造】
    2. new AudioTrackServerProxy()【缓存代理对象】
    3. thread->getTrackName_l()
  4. mTracks.add()
  5. getEffectChain_l()
  6. if (chain != 0)
    1. track->setMainBuffer(chain->inBuffer())
    2. chain->setStrategy()
    3. chain->incTrackCnt()

开始播放

  • AudioTrack开始播放(start)
  1. 【mState状态变化】
  2. if (!(flags & CBLK_INVALID))
    1. mAudioTrack->start()【步骤二】
  3. if (flags & CBLK_INVALID)【Track失效了,需要重新打开】
    1. restoreTrack_l("start")
      1. AudioSystem::clearAudioConfigCache()
      2. getOutput_l()【重新计算路由】
        1. AudioSystem::getOutput()【见流程“打开输出轨道”】
      3. createTrack_l()
      4. if (mState == STATE_ACTIVE)
        1. mAudioTrack->start()【步骤二】
  • AudioFlinger::PlaybackThread::Track开始播放(start)
  1. 【mState状态变化】
  2. playbackThread->addTrack_l()【将自己添加到PlaybackThread的激活Track集合】
    1. if (mActiveTracks.indexOf(track) < 0)
      1. AudioSystem::startOutput()
        1. aps->startOutput()
          1. mpAudioPolicy->start_output()【步骤三】
      2. mActiveTracks.add()
    2. broadcast_l()【通知播放线程】
  • AudioPolicyManagerBase启动输出(startOutput)
  1. outputDesc->changeRefCount()【增加引用计数】
  2. if (outputDesc->mRefCount[stream] == 1)
    1. getNewDevice()【计算新的输出设备】
    2. setOutputDevice()【更新设备路由】
    3. if (isInCall())
      1. handleIncallSonification()
    4. checkAndSetVolume()【应用音量设置,见流程“音量设置”】

播放线程

        省略了WakeLock处理,WakeLock在线程进入睡眠前释放,在线程重新唤醒后获取,并通过mWakeLockUids计算实际代表哪些进程持有WakeLock锁,PlaybackThread在增加、删除Track时在mWakeLockUids中增删对应的进程ID。

  1. AudioFlinger::PlaybackThread::threadLoop()
    1. cacheParameters_l()(计算并缓存mixBufferSize、activeSleepTime、idleSleepTime)
    2. CpuStats cpuStats【构建一个CPU使用统计对象】
    3. checkSilentMode_l()
      1. property_get("ro.audio.silent")
      2. setMasterMute_l()
    4. while (!exitPending())【没有要求退出】
      1. cpuStats.sample()【CPU状态做一次采样】
      2. processConfigEvents()【ThreadBase,处理mConfigEvents】
      3. mLock.lock()
      4. checkForNewParameters_l()【派生类,新配置mNewParameters】
      5. cacheParameters_l()【如果相关参数更新,重新计算】
      6. saveOutputTracks()【DuplicatingThread,保存mOutputTracks副本】
      7. if (waitingAsyncCallback_l())【使用异步写入输出流】
        1. mWaitWorkCV.wait()【需要等待异步ACK或其他事件发生】
        2. continue【重新循环】
      8. if 【mActiveTracks空,经过一定延迟standbyDelay,或者主动暂停】
        1. threadLoop_standby()【进入standby】
        2. if 【mActiveTracks、mConfigEvents都空】
          1. clearOutputTracks()【清空之前保存的副本】
          2. mWaitWorkCV.wait()【等待新的事情去做】
          3. continue【重新循环】
      9. prepareTracks_l()【准备数据】
      10. lockEffectChains_l()【锁定音效链,已有的不能修改】
      11. if (mBytesRemaining == 0)【需要混音生成更多数据】
        1. if (mMixerStatus == MIXER_TRACKS_READY)【数据准备好】
          1. threadLoop_mix()【执行混音,mCurrentWriteLength】
        2. else if 【不是MIXER_DRAIN_TRACK和MIXER_DRAIN_ALL】
          1. threadLoop_sleepTime()
        3. if (isSuspended())【暂停状态,直接丢弃数据】
        4. foreach effectChains【应用音效】
          1. effectChains[i]->process_l()
      12. unlockEffectChains【解锁音效链】
      13. if (!waitingAsyncCallback())【非异步写输出】
        1. if (sleepTime == 0)【意味着需要写数据到HAL】
          1. if (mBytesRemaining)
            1. threadLoop_write()
          2. else if 【MIXER_DRAIN_TRACK或者MIXER_DRAIN_ALL】
            1. threadLoop_drain()
        2. else
          1. usleep(sleepTime)
      14. threadLoop_removeTracks()
      15. clearOutputTracks()【清空之前保存的副本】
    5. 【循环边界】
    6. threadLoop_exit()
    7. mOutput->stream->common.standby()【使输出流进入standby模式】

策略路由

        策略的输入是:流类型(stream_type)

        策略的输出是:输出端口(audio_io_handle_t,对应播放线程PlaybackThread)

  1. AudioPolicyManagerBase::getOutput
    1. getStrategy()【stream_type转换为路由策略routing_strategy】
      1. 详见“算法>路由策略”
    2. getDeviceForStrategy()【根据routing_strategy选择输出设备类型】
    3. getOutputsForDevice()【查找所有支持设备类型的输出端口】
    4. selectOutput()【根据flags选择最匹配的输出端口】
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fighting Horse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值