赞
踩
Audiopolicyservice的路由实现:
Audiopolicyservice作为音频策略的制定者,功能的实现跟audiotrack(使用者)有较大关联,所以在紧接着audiotrack看下路由的过程。
路由,就要有发送方,接收方,这个场景中发送发就是Audiotrack,接收方就是audioflinger(策略的执行者),audiopolicyservice是这两者的桥梁,它内部拥有当前系统中所有音频设备的信息,实现音频策略的算法也不是固定的,是可以由厂商定制的。
依据前面的分析,在audiotrack中的set方法,调用audiosystem:: getOutputForAttr()来分析策略的实现:
- status_t AudioTrack::createTrack_l()@AudioTrack.cpp{
- status = AudioSystem::getOutputForAttr(attr, &output,…);
- }
- status_t AudioSystem::getOutputForAttr(…)@ AudioSystem.cpp {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
- return aps->getOutputForAttr(…);
- }
AudioSystem是一个中介,实现是由AudioPolicyService完成的。
- audio_io_handle_t AudioPolicyService::getOutput(…)@ AudioPolicyInterfaceImplLegacy.cpp{
- return mpAudioPolicy->get_output(…);
- }
前面分析过,mpAudioPolicy就是lap (类型:legacy_audio_policy)中的policy(类型:audio_policy),根据其相应函数指针的实现:
- static int create_legacy_ap(…)@ audio_policy_hal.cpp {
- struct legacy_audio_policy *lap;
- lap->policy.get_output = ap_get_output;
- }
- static audio_io_handle_t ap_get_output(…) @ audio_policy_hal.cpp {
- lap->apm->getOutput(…);
- }
Getoutput最终的实现在AudioPolicyManagerBase中。
- audio_io_handle_t AudioPolicyManagerBase::getOutput(AudioSystem::stream_type stream,
- uint32_t samplingRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
- AudioSystem::output_flags flags,
- const audio_offload_info_t *offloadInfo)@ AudioPolicyManagerBase.cpp {
- //step1,获取stream音频类型对应的strategy。
- routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream);
- audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
- //step2,依据策略,判断哪些output符合传入的stream类型。
- SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs);
- //step3,选择最优的output
- output = selectOutput(outputs, flags);
- }
Step1,每种stream类型,都有对应的路由策略routing_strategy,stream type和routing_strategy的对应关系:
不同的stream类型,可能使用同一个strategy,可以通过重载getStrategy定制策略。
找到stream类型对应的strategy后,getDeviceForStrategy将为strategy匹配最佳的音频设备。
- audio_devices_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy strategy,
- bool fromCache){
- switch (strategy) {
- case STRATEGY_MEDIA: {
- uint32_t device2 = AUDIO_DEVICE_NONE;
- if ((device2 == AUDIO_DEVICE_NONE) &&
- mHasA2dp && (mForceUse[AudioSystem::FOR_MEDIA] != AudioSystem::FORCE_NO_BT_A2DP) &&
- (getA2dpOutput() != 0) && !mA2dpSuspended) {
- device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
- if (device2 == AUDIO_DEVICE_NONE) {
- device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
- }
- if (device2 == AUDIO_DEVICE_NONE) {
- device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
- }
- }
-
- if (device2 == AUDIO_DEVICE_NONE) {
- device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
- }
- if (device2 == AUDIO_DEVICE_NONE) {
- device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_WIRED_HEADSET;
- }
- if (device2 == AUDIO_DEVICE_NONE) {
- device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_ACCESSORY;
- }
- if (device2 == AUDIO_DEVICE_NONE) {
- device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_DEVICE;
- }
- }
- device |= device2;
- //如果匹配到合适的device,跳出switch。
- if (device) break;
- //否则,使用默认的device
- device = mDefaultOutputDevice;
- }
- }
以上匹配的过程是有优先级的,从上到下依次匹配,优先级递减,前一个优先级匹配成功,device2就不为AUDIO_DEVICE_NONE了,所以下面的就不在判断了。
Step2,上一步找到匹配的device,这一步为device选择合适的output通道。
- SortedVector<audio_io_handle_t> AudioPolicyManagerBase::getOutputsForDevice(audio_devices_t device,
- DefaultKeyedVector<audio_io_handle_t, AudioOutputDescriptor *> openOutputs){
- SortedVector<audio_io_handle_t> outputs;
- for (size_t i = 0; i < openOutputs.size(); i++) {
- if ((device & openOutputs.valueAt(i)->supportedDevices()) == device) {
- outputs.add(openOutputs.keyAt(i));
- }
- }
- }
所有支持device设备的output都被添加到outputs中,这里的output就是前面AudioFlinger::openOutput的执行结果,因为每个output通常支持若干种音频设备,不同的output支持的音频设备类型没有限制,所以可能存在多个支持同一个device的output。
Step3,既然符合要求的output不止一个,就选择一个最合适的。
- audio_io_handle_t AudioPolicyManagerBase::selectOutput(
- const SortedVector<audio_io_handle_t>& outputs,
- AudioSystem::output_flags flags)){
- //如果没有output存在,只能返回0,如果只有一个output,就直接返回这个output。
- if (outputs.size() == 0) {
- return 0;
- }
- if (outputs.size() == 1) {
- return outputs[0];
- }
- //选择最优的一个,针对每个output循环计算:outputDesc->mProfile->mFlags & flags的最大值,也就是计算其中的1的个数。
- for (size_t i = 0; i < outputs.size(); i++) {
- AudioOutputDescriptor *outputDesc = mOutputs.valueFor(outputs[i]);
- if (!outputDesc->isDuplicated()) {
- int commonFlags = (int)AudioSystem::popCount(outputDesc->mProfile->mFlags & flags);
- if (commonFlags > maxCommonFlags) {
- outputFlags = outputs[i];
- maxCommonFlags = commonFlags;
- }
- if (outputDesc->mProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {
- outputPrimary = outputs[i];
- }
- }
- }
- }
这个择优判断的规则,也是有优先级的:
首先:请求策略的flags,值最大的那个output,也就是:outputDesc->mProfile->mFlags和flags的值最大的那个。
然后:the primaryoutput
最后:the first output in thelist。Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。