AAOS音频路由 问题分析

问题描述

多屏设备,没有按照配置car_audio_configuration.xml配置输出。也即是每个屏幕播放的音频没有对应输出到想对应的bus设备。

问题分析

  1. 首先根据hal层的log,确认框架层配置的bus,确认框架配置的是主屏的bus0
  2. 确认userID displayID audioZoneId 三者之间的映射关系 userID 代表了每个屏幕对应的用户,zoneID 和 occupation ID 对应,occupation ID 和 display ID对应, zoneID 就和displayID 对应起来了。
 zoneId=0 config={userId=10 displays={displayId=0 displayType=1} audioZoneId=0}
 zoneId=1 config={userId=11 displays={displayId=6 displayType=1} audioZoneId=1}
 zoneId=2 config={userId=12 displays={displayId=3 displayType=1} audioZoneId=2}
 zoneId=3 config={userId=13 displays={displayId=2 displayType=1} audioZoneId=3}
 zoneId=4 config={userId=14 displays={displayId=4 displayType=1} audioZoneId=none}
 zoneId=5 config={userId=15 displays={displayId=5 displayType=1} audioZoneId=none}

通过dumpsys car_service | grep user可以看到对应的关系
比如上面的代码可以看出audioZoneid -----> displayID ------> userID之间的关系, 这个映射关系是对的。

  1. 查看audio的信息
    可以通过dumpsys audio 或者media.audio_policy(如果忘记命令可以dumpsys -l | grep audio)
    dumpsys audio 可以看到usrID 和address的映射关系
 Uid Device Affinities:
 UserId Device Affinities:
     UserId: 10
        Type: 0x1000000 Address: bus6_notification_out
        Type: 0x1000000 Address: bus0_media_out
        Type: 0x1000000 Address: bus2_voice_command_out
        Type: 0x1000000 Address: bus1_navigation_out
        Type: 0x1000000 Address: bus4_call_out
        Type: 0x1000000 Address: bus3_call_ring_out
        Type: 0x1000000 Address: bus7_system_sound_out
        Type: 0x1000000 Address: bus5_alarm_out
     UserId: 11
        Type: 0x1000000 Address: bus100_audio_zone_1
     UserId: 12
        Type: 0x1000000 Address: bus200_audio_zone_2
     UserId: 13
        Type: 0x1000000 Address: bus300_audio_zone_3

dumpsys media.audio_policy可以看到所有注册到policy 中的mix路径。其中的critertion 代表路由到这个mix的规则
比如下面的表示usage是AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE 并且不是user 11 12 13的使用这个policyMix。

 Audio Policy Mix 4 (0xb4000075f6ddab30):
  - mix type: MIX_TYPE_PLAYERS
  - Route Flags: MIX_ROUTE_FLAG_RENDER
  - device type: AUDIO_DEVICE_OUT_BUS
  - device address: bus1_navigation_out
  - output: 21
    - Criterion 0: RULE_MATCH_ATTRIBUTE_USAGE AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE
    - Criterion 1: RULE_EXCLUDE_USERID 11
    - Criterion 2: RULE_EXCLUDE_USERID 12
    - Criterion 3: RULE_EXCLUDE_USERID 13
  1. 查看显示的信息

可以通过dumpsys display 和 dumpsys SurfaceFlinger确认屏幕的类型, 比如下面surfaceflinger的信息可以看到某个屏幕的信息。 找到对应的屏幕。

isplayId=243, Connector 438, Type = DP-1, Connector state = DRM_MODE_CONNECTED

但这样也不容易看到,可以通过scrcpy --display 加上后面的displayId来确认哪个屏。 比如想要调试audioZoneId 为4 的,那么就是–display 2 这样。

流程梳理

  • 根据经验路由的规则是由用户id决定的,一般路由不对,就是用户id配置的不对。但是通过上面的信息可以看到用户id 和 audioZone是对应的。查看policy 发现没有新加入的zone300 address 相关的路由。

  • 从audioPolicyManager出发,看registerPolicyMixes 中注册了多少个mixes,manger中只注册了10个mix。 先略过中间的流程 从应用carAudioService开始
    在添加mix 的地方确认,所有的mix 都加入总共11个。 那就是从应用加mix 到manager 中间少掉了一个mix。

  • 上层路由添加流程: 是遍历所有group中的address, 每个address 生成一个mixingRule, 然后每个group 中的context 转成usage,对于每个usage 生成一个rule,这个rule添加到mix 的critertion中,android所有的有效的context总共10个,可以对应到20个usage,就是每个mix最高有20个critertion。

  • 生成的每个mixrule 添加到audiopolicy 中。 这个audiopolicy 通过audioservice 注册到registerAudioPolicy框架中,在注册的调用中调用connectMixes 中
    mAudioSystem.registerPolicyMixes(mMixes, true); 将mixer注册的system。 这个是通过android_media_AudioSystem_registerPolicyMixes的jni调用到AudioSystem::registerPolicyMixes audioSystem在调用到aps->registerPolicyMixes(mixesAidl, registration)其中aps是AudioPolicyService 也就是调用的
    AudioPolicyService::registerPolicyMixes。最后这边调用到了AudioPolicyManager::registerPolicyMixes。

  • 这整条链路中
    android_media_AudioSystem_registerPolicyMixes
    AudioSystem::registerPolicyMixes
    AudioPolicyService::registerPolicyMixes
    这三个地方都有mix的size判断。

问题原因

  • carAudioService 中跟xml解析 构造好mix的rule 之后,将这些rule 注册到audiopolicymanager。
  • 播放音频 创建track 获取输出设备的时候从注册的mix rule中找到符合输出的rule, 这个rule 包含了userid的信息。
  • 因为框架中限制了外部注册的mix数量,导致最后一个usrid为13的 rule没有注册进去。
    后面在找的时候找不到,就默认用了rule中的第一个了。

猜你喜欢

转载自blog.csdn.net/H2008066215019910120/article/details/132769555