当前位置:   article > 正文

Android音频子系统,Audiopolicyservice音频策略的制定(五)_android音频子系统,audiopolicyservice音频策略的制定

android音频子系统,audiopolicyservice音频策略的制定

Audiopolicyservice的路由实现:

Audiopolicyservice作为音频策略的制定者,功能的实现跟audiotrack(使用者)有较大关联,所以在紧接着audiotrack看下路由的过程。

路由,就要有发送方,接收方,这个场景中发送发就是Audiotrack,接收方就是audioflinger(策略的执行者),audiopolicyservice是这两者的桥梁,它内部拥有当前系统中所有音频设备的信息,实现音频策略的算法也不是固定的,是可以由厂商定制的。

依据前面的分析,在audiotrack中的set方法,调用audiosystem:: getOutputForAttr()来分析策略的实现:

  1. status_t AudioTrack::createTrack_l()@AudioTrack.cpp{
  2. status = AudioSystem::getOutputForAttr(attr, &output,…);
  3. }
  4. status_t AudioSystem::getOutputForAttr(…)@ AudioSystem.cpp {
  5. const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
  6. return aps->getOutputForAttr(…);
  7. }

AudioSystem是一个中介,实现是由AudioPolicyService完成的。

  1. audio_io_handle_t AudioPolicyService::getOutput(…)@ AudioPolicyInterfaceImplLegacy.cpp{
  2. return mpAudioPolicy->get_output(…);
  3. }

前面分析过,mpAudioPolicy就是lap (类型:legacy_audio_policy)中的policy(类型:audio_policy),根据其相应函数指针的实现:

  1. static int create_legacy_ap(…)@ audio_policy_hal.cpp {
  2. struct legacy_audio_policy *lap;
  3. lap->policy.get_output = ap_get_output;
  4. }
  5. static audio_io_handle_t ap_get_output(…) @ audio_policy_hal.cpp {
  6. lap->apm->getOutput(…);
  7. }

Getoutput最终的实现在AudioPolicyManagerBase中。

  1. audio_io_handle_t AudioPolicyManagerBase::getOutput(AudioSystem::stream_type stream,
  2. uint32_t samplingRate,
  3. audio_format_t format,
  4. audio_channel_mask_t channelMask,
  5. AudioSystem::output_flags flags,
  6. const audio_offload_info_t *offloadInfo)@ AudioPolicyManagerBase.cpp {
  7. //step1,获取stream音频类型对应的strategy。
  8. routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream);
  9. audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
  10. //step2,依据策略,判断哪些output符合传入的stream类型。
  11. SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs);
  12. //step3,选择最优的output
  13. output = selectOutput(outputs, flags);
  14. }

Step1,每种stream类型,都有对应的路由策略routing_strategy,stream type和routing_strategy的对应关系:


不同的stream类型,可能使用同一个strategy,可以通过重载getStrategy定制策略。

找到stream类型对应的strategy后,getDeviceForStrategy将为strategy匹配最佳的音频设备。

  1. audio_devices_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy strategy,
  2. bool fromCache){
  3. switch (strategy) {
  4. case STRATEGY_MEDIA: {
  5. uint32_t device2 = AUDIO_DEVICE_NONE;
  6. if ((device2 == AUDIO_DEVICE_NONE) &&
  7. mHasA2dp && (mForceUse[AudioSystem::FOR_MEDIA] != AudioSystem::FORCE_NO_BT_A2DP) &&
  8. (getA2dpOutput() != 0) && !mA2dpSuspended) {
  9. device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
  10. if (device2 == AUDIO_DEVICE_NONE) {
  11. device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
  12. }
  13. if (device2 == AUDIO_DEVICE_NONE) {
  14. device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
  15. }
  16. }
  17. if (device2 == AUDIO_DEVICE_NONE) {
  18. device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
  19. }
  20. if (device2 == AUDIO_DEVICE_NONE) {
  21. device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_WIRED_HEADSET;
  22. }
  23. if (device2 == AUDIO_DEVICE_NONE) {
  24. device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_ACCESSORY;
  25. }
  26. if (device2 == AUDIO_DEVICE_NONE) {
  27. device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_DEVICE;
  28. }
  29. }
  30. device |= device2;
  31. //如果匹配到合适的device,跳出switch。
  32. if (device) break;
  33. //否则,使用默认的device
  34. device = mDefaultOutputDevice;
  35. }
  36. }
以上匹配的过程是有优先级的,从上到下依次匹配,优先级递减,前一个优先级匹配成功,device2就不为AUDIO_DEVICE_NONE了,所以下面的就不在判断了。


Step2,上一步找到匹配的device,这一步为device选择合适的output通道。

  1. SortedVector<audio_io_handle_t> AudioPolicyManagerBase::getOutputsForDevice(audio_devices_t device,
  2. DefaultKeyedVector<audio_io_handle_t, AudioOutputDescriptor *> openOutputs){
  3. SortedVector<audio_io_handle_t> outputs;
  4. for (size_t i = 0; i < openOutputs.size(); i++) {
  5. if ((device & openOutputs.valueAt(i)->supportedDevices()) == device) {
  6. outputs.add(openOutputs.keyAt(i));
  7. }
  8. }
  9. }

所有支持device设备的output都被添加到outputs中,这里的output就是前面AudioFlinger::openOutput的执行结果,因为每个output通常支持若干种音频设备,不同的output支持的音频设备类型没有限制,所以可能存在多个支持同一个device的output。

Step3,既然符合要求的output不止一个,就选择一个最合适的。

  1. audio_io_handle_t AudioPolicyManagerBase::selectOutput(
  2. const SortedVector<audio_io_handle_t>& outputs,
  3. AudioSystem::output_flags flags)){
  4. //如果没有output存在,只能返回0,如果只有一个output,就直接返回这个output。
  5. if (outputs.size() == 0) {
  6. return 0;
  7. }
  8. if (outputs.size() == 1) {
  9. return outputs[0];
  10. }
  11. //选择最优的一个,针对每个output循环计算:outputDesc->mProfile->mFlags & flags的最大值,也就是计算其中的1的个数。
  12. for (size_t i = 0; i < outputs.size(); i++) {
  13. AudioOutputDescriptor *outputDesc = mOutputs.valueFor(outputs[i]);
  14. if (!outputDesc->isDuplicated()) {
  15. int commonFlags = (int)AudioSystem::popCount(outputDesc->mProfile->mFlags & flags);
  16. if (commonFlags > maxCommonFlags) {
  17. outputFlags = outputs[i];
  18. maxCommonFlags = commonFlags;
  19. }
  20. if (outputDesc->mProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {
  21. outputPrimary = outputs[i];
  22. }
  23. }
  24. }
  25. }

这个择优判断的规则,也是有优先级的:

首先:请求策略的flags,值最大的那个output,也就是:outputDesc->mProfile->mFlags和flags的值最大的那个。

然后:the primaryoutput

最后:the first output in thelist。
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/499741
推荐阅读
相关标签
  

闽ICP备14008679号