前言
本系列文章基于Android14源码进行分析解读,部分框图直接使用了原作者的图片,侵权必删。
我们既生成文章,也是各路文章的搬运工。
一、What&Why AudioFlinger
AudioHAL(AHAL)提供隔离Vendor硬件差异的抽象,通过tinyalsa实现对底层硬件声卡节点的利用。AHAL作为一个独立的service,在Android系统中肯定有client通过binder与其通信,实现数据流与控制流的交互,完成对声卡节点数据的访问。
AudioTrack.java和AudioRecord.java是应用层的API,透过GNI访问了Native层的AudioTrack.cpp和AudioRecord.cpp,AudioTrack和AudioRecord又是如何把数据写进和读出底层声卡的呢?
Linux声卡设备节点是一个互斥的节点,每次只能被一个应用打开,其他应用尝试open一个已经打开的节点会返回device busy的错误。但是在实际Android使用过程中又存在多个音频数据流同时播放的场景,这是如何做到的呢?
所有这些疑问都会在AudioFlinger服务中解决。AudioFlinger向下访问AudioHardware,实现输出音频数据,控制音频参数;AudioFlinger向上通过IAudioFinger接口对AudioTrack和AudioRecord供服务。AudioFlinger在Android的音频系统框架中起着承上启下的作用,地位相当告急。
AudioFlinger创建PlaybackThread/RecordThread服务线程,实现对AHAL层音频节点的独占利用。多个AudioTrack/AudioRecord作为Clinet端同PlaybackThread/RecordThread服务线程交互,Thread实现音频流的mix/snoop,来实现整个音频框架。
下面通过分析代码,完成对AudioFlinger的深入明白。
二、AudioFlinger初始化
AudioFlinger在audioserver中启动,代码在:
frameworks/av/media/audioserver/main_audioserver.cpp
- #define LOG_TAG "audioserver"
- int main(int argc __unused, char **argv)
- {
- ......
- 这里修改了AudioFling和AudioPolicyService的初始化方式,以解决独立初始化模式下引起的
- 服务启动时间差,这个时间差会导致部分服务时间检测异常而强行退出。
- // Instantiating AudioFlinger (making it public, e.g. through ::initialize())
- // and then instantiating AudioPolicy (and making it public)
- // leads to situations where AudioFlinger is accessed remotely before
- // AudioPolicy is initialized. Not only might this
- // cause inaccurate results, but if AudioPolicy has slow audio HAL
- // initialization, it can cause a TimeCheck abort to occur on an AudioFlinger
- // call which tries to access AudioPolicy.
- //
- // We create AudioFlinger and AudioPolicy locally then make it public to ServiceManager.
- // This requires both AudioFlinger and AudioPolicy to be in-proc.
- //
- /* 1、创建AudioFling实例,必须在AudioPolicyService之前,因为aps会访问af中的接口 */
- const auto af = sp<AudioFlinger>::make();
- const auto afAdapter = sp<AudioFlingerServerAdapter>::make(af);
-
- /* 2、创建AudioPolicyService实例 */
- const auto aps = sp<AudioPolicyService>::make();
- /* 3、添加AudioFlinger和AudioPolicyService服务到ServiceManager */
- // Add AudioFlinger and AudioPolicy to ServiceManager.
- sp<IServiceManager> sm = defaultServiceManager();
- sm->addService(String16(IAudioFlinger::DEFAULT_SERVICE_NAME), afAdapter,
- false /* allowIsolated */, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT);
- sm->addService(String16(AudioPolicyService::getServiceName()), aps,
- false /* allowIsolated */, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT);
-
- // AAudioService should only be used in OC-MR1 and later.
- // And only enable the AAudioService if the system MMAP policy explicitly allows it.
- std::vector<AudioMMapPolicyInfo> policyInfos;
- status_t status = af->getMmapPolicyInfos(
- AudioMMapPolicyType::DEFAULT, &policyInfos);
- // Initialize aaudio service when querying mmap policy succeeds and
- // any of the policy supports MMAP.
- if (status == NO_ERROR &&
- std::any_of(policyInfos.begin(), policyInfos.end(), [](const auto& info) {
- return info.mmapPolicy == AudioMMapPolicy::AUTO ||
- info.mmapPolicy == AudioMMapPolicy::ALWAYS;
- })) {
-
- /* 4、创建AAudioService实例 */
- AAudioService::instantiate();
- }
- ......
- IPCThreadState::self()->joinThreadPool();
- }
- }
复制代码 主函数里面没有做太多的任务,创建了AudioFlinger和AudioPolicyService两个实例,并将服务注册到servicemanager中,除此之外还检测并创建了AAudioService。
1、AudioFlinger实例构建
- AudioFlinger::AudioFlinger() {
- ......
- // reset battery stats.
- // if the audio service has crashed, battery stats could be left
- // in bad state, reset the state upon service start.
- BatteryNotifier::getInstance().noteResetAudio();
- /* 构建音频device和音效effect实例 */
- mDevicesFactoryHal = DevicesFactoryHalInterface::create();
- mEffectsFactoryHal = EffectsFactoryHalInterface::create();
- }
复制代码 AudioFlinger的实例没有做太多的工作:
- 完成电池状态的复位;
- 构建音频设备Device工厂实例;
- 构建音效Effect工厂实例;
- sp<DevicesFactoryHalInterface> DevicesFactoryHalInterface::create() {
- return createPreferredImpl<DevicesFactoryHalInterface>(true /* isDevice */);
- }
- void *createPreferredImpl(bool isDevice) {
- ......
- if (...) {
- .....
- /* 1、创建AudioHal服务 */
- if (createHalService(std::max(*ifaceVersionIt, *siblingVersionIt), isDevice,
- &rawInterface)) {
- return rawInterface;
- }
- return nullptr;
- }
- bool createHalService(const AudioHalVersionInfo& version, bool isDevice, void** rawInterface) {
- const std::string libName = "libaudiohal@" + version.toVersionString() + ".so";
- const std::string factoryFunctionName =
- isDevice ? "createIDevicesFactory" : "createIEffectsFactory";
- constexpr int dlMode = RTLD_LAZY;
- void* handle = nullptr;
- dlerror(); // clear
- /* 2、打开 libaudiohal@version.so 动态库 */
- handle = dlopen(libName.c_str(), dlMode);
- ......
- void* (*factoryFunction)();
- /*3、函数进来后首先初始化factoryFunctionName为createIDevicesFactory, 所以这里获取到的factoryFunction句柄为createIDevicesFactory函数 */
- *(void **)(&factoryFunction) = dlsym(handle, factoryFunctionName.c_str());
- if (!factoryFunction) {
- ......
- }
- /* 4、调用libaudiohal动态库的createIDevicesFactory函数,完成AHAL句柄的创建 */
- *rawInterface = (*factoryFunction)();
- return true;
- }
- extern "C" __attribute__((visibility("default"))) void* createIDevicesFactory() {
- return createIDevicesFactoryImpl();
- }
- extern "C" __attribute__((visibility("default"))) void* createIDevicesFactoryImpl() {
- auto service = hardware::audio::CPP_VERSION::IDevicesFactory::getService();
- return service ? new DevicesFactoryHalHidl(service) : nullptr;
- }
复制代码- DevicesFactoryHalEntry.cpp::createIDevicesFactory() ->
- DevicesFactoryHalHidl.cpp::createIDevicesFactoryImpl() ->
- DevicesFactoryHalHidl.cpp::DevicesFactoryHalHidl()
复制代码 具体逻辑这里不做深入的分析了,后面有机会再展开。
整个AudioFlinger完成初始化之后,并没有做太多的任务。而是作为一个服务运行在系统中,等候客户端与其进行通信:这也符合AF的功能,我只做一个执行者,不做决策。那谁优势决策者呢?别忘了我们还没有分析AudioPolicyService呢。
2、AudioPolicyService实例构建
- AudioPolicyService::AudioPolicyService()
- : BnAudioPolicyService(),
- mAudioPolicyManager(NULL),
- mAudioPolicyClient(NULL),
- mPhoneState(AUDIO_MODE_INVALID),
- mCaptureStateNotifier(false),
- /* 1 - 初始化mCreateAudioPolicyManager为createAudioPolicyManager */
- mCreateAudioPolicyManager(createAudioPolicyManager),
- mDestroyAudioPolicyManager(destroyAudioPolicyManager) {
- setMinSchedulerPolicy(SCHED_NORMAL, ANDROID_PRIORITY_AUDIO);
- }
- /* 在完成实例后,首先调用的函数就是onFirstRef,具体原因请搜索其他文章 */
- void AudioPolicyService::onFirstRef()
- {
- {
- Mutex::Autolock _l(mLock);
- /* 2 - 创建两个命令线程,用于接收并处理其他服务发送的命令 */
- // start audio commands thread
- mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);
- // start output activity command thread
- mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this);
-
- /* 3 - 构造AudioPolicyClient实例:APC是AF的clinet端,很多任务都是通过跨进程调用到AF中 */
- mAudioPolicyClient = new AudioPolicyClient(this);
- /* 4 - 加载用户自定义的的AudioPolicyManager实现:libaudiopolicymanagercustom.so */
- loadAudioPolicyManager();
- /* 5 - 调用createAudioPolicyManager接口 */
- mAudioPolicyManager = mCreateAudioPolicyManager(mAudioPolicyClient);
- }
复制代码 2.1、createAudioPolicyManager
- static AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)
- {
- AudioPolicyManager *apm = nullptr;
- media::AudioPolicyConfig apmConfig;
- /* 1、与AHAL交互获取modules信息,以确定是否存在用户自定义的configurable AudioPolicyConfig */
- if (status_t status = clientInterface->getAudioPolicyConfig(&apmConfig); status == OK) {
- auto config = AudioPolicyConfig::loadFromApmAidlConfigWithFallback(apmConfig);
- LOG_ALWAYS_FATAL_IF(config->getEngineLibraryNameSuffix() !=
- AudioPolicyConfig::kDefaultEngineLibraryNameSuffix,
- "Only default engine is currently supported with the AIDL HAL");
- apm = new AudioPolicyManager(config,
- loadApmEngineLibraryAndCreateEngine(
- config->getEngineLibraryNameSuffix(), apmConfig.engineConfig),
- clientInterface);
- } else {
- /* 2、加载系统预定义的audio_policy_configuration配置 */
- auto config = AudioPolicyConfig::loadFromApmXmlConfigWithFallback();
- /* 3、config->getEngineLibraryNameSuffix()返回的
- 字符串为“default”(kDefaultEngineLibraryNameSuffix),
- 加载libaudiopolicyengine.default.so并完成AudioPolicyManager实例构造 */
- apm = new AudioPolicyManager(config,
- loadApmEngineLibraryAndCreateEngine(config->getEngineLibraryNameSuffix()),
- clientInterface);
- }
- /* 4、初始化AudioPolicyManager */
- status_t status = apm->initialize();
- if (status != NO_ERROR) {
- delete apm;
- apm = nullptr;
- }
- return apm;
- }
- // static
- sp<const AudioPolicyConfig> AudioPolicyConfig::loadFromApmXmlConfigWithFallback(
- const std::string& xmlFilePath) {
- /* 2.1 - xmlFilePath为空,audio_get_audio_policy_config_file获取到的路径为/vendor/etc/audio_policy_configuration.xml */
- const std::string filePath =
- xmlFilePath.empty() ? audio_get_audio_policy_config_file() : xmlFilePath;
- auto config = sp<AudioPolicyConfig>::make();
- /* 2.2 - 解析audio_policy_configuration.xml 文件并获得音频策略配置信息 */
- if (status_t status = config->loadFromXml(filePath, false /*forVts*/); status == NO_ERROR) {
- return config;
- }
- /* 2.3 - 不会运行到这里 */
- return createDefault();
- }
- status_t AudioPolicyConfig::loadFromXml(const std::string& xmlFilePath, bool forVts) {
- ...
- status_t status = deserializeAudioPolicyFile(xmlFilePath.c_str(), this);
- ...
- }
- status_t deserializeAudioPolicyFile(const char *fileName, AudioPolicyConfig *config)
- {
- PolicySerializer serializer;
- return status = serializer.deserialize(fileName, config);
- }
- status_t PolicySerializer::deserialize(const char *configFile, AudioPolicyConfig *config,
- bool ignoreVendorExtensions)
- {
- /* 完成audio_policy_configuration.xml的解析*/
- ......
- }
复制代码 以Android的car/emulator的audio_policy_configuration.xml文件为例,下图是xml文件剖析后得到的结果,整个剖析按照mixPort,devicePort和route的属性剖析并终极形成HwModule,条理比力简单,读者自行撸代码也能看懂。
得益于Android丰富的工具,可以通过 dumpsys media.audio_policy 命令查看终极配置的路由计谋。
- dumpsys media.audio_policy
- Supported System Usages:
- AUDIO_USAGE_CALL_ASSISTANT, AUDIO_USAGE_EMERGENCY, AUDIO_USAGE_SAFETY, AUDIO_USAGE_VEHICLE_STATUS, AUDIO_USAGE_ANNOUNCEMENT
- UID Policy:
- mObserverRegistered=True
- Assistants UIDs:
- No UIDs present.
- Active Assistants UIDs:
- No UIDs present.
- Accessibility UIDs:
- No UIDs present.
- Input Method Service UID=1010067
- Is RTT Enabled: False
- AudioCommandThread: 0xb400007416624090
- - Commands:
- Command Time Wait pParam
- Last Command
- 05 092141.687 0 0xb40000739666f2e0
- OutputCommandThread: 0xb400007416625950
- - Commands:
- Command Time Wait pParam
- Last Command
- 09 092141.966 0 0xb400007306620340
- AudioPolicyManager Dump: 0xb4000074466246b0
- Primary Output I/O handle: 13
- Phone state: AUDIO_MODE_NORMAL
- Force use for communications: 0
- Force use for media: 10
- Force use for record: 0
- Force use for dock: 9
- Force use for system: 0
- Force use for HDMI system audio: 0
- Force use for encoded surround output: 0
- Force use for vibrate ringing: 0
- TTS output not available
- Master mono: off
- Communication Strategy id: 14
- Config source: /vendor/etc/audio_policy_configuration.xml
- Available output devices (17):
- 1. Port ID: 50; "bus1000_mirror_device"; {AUDIO_DEVICE_OUT_BUS, @:bus1000_mirror_device}
- Encapsulation modes: 0, metadata types: 0
- - Profiles (1):
- 1. ""; AUDIO_FORMAT_PCM_16_BIT (0x1)
- sampling rates: 48000
- channel masks: 0x0003
- AUDIO_ENCAPSULATION_TYPE_NONE
- - gains:
- Gain 1:
- - mode: 00000001
- - channel_mask: 00000000
- - min_value: -3200 mB
- - max_value: 600 mB
- - default_value: 0 mB
- - step_value: 100 mB
- - min_ramp_ms: 0 ms
- - max_ramp_ms: 0 ms
- 2. Port ID: 47; "bus211_audio_zone_2"; {AUDIO_DEVICE_OUT_BUS, @:bus211_audio_zone_2}
- Encapsulation modes: 0, metadata types: 0
- - Profiles (1):
- 1. ""; AUDIO_FORMAT_PCM_16_BIT (0x1)
- sampling rates: 48000
- channel masks: 0x0003
- AUDIO_ENCAPSULATION_TYPE_NONE
- - gains:
- Gain 1:
- - mode: 00000001
- - channel_mask: 00000000
- - min_value: -3200 mB
- - max_value: 600 mB
- - default_value: 0 mB
- - step_value: 100 mB
- - min_ramp_ms: 0 ms
- - max_ramp_ms: 0 ms
- ...
- 6. Port ID: 35; "bus111_audio_zone_1"; {AUDIO_DEVICE_OUT_BUS, @:bus111_audio_zone_1}
- Encapsulation modes: 0, metadata types: 0
- - Profiles (1):
- 1. ""; AUDIO_FORMAT_PCM_16_BIT (0x1)
- sampling rates: 48000
- channel masks: 0x0003
- AUDIO_ENCAPSULATION_TYPE_NONE
- - gains:
- Gain 1:
- - mode: 00000001
- - channel_mask: 00000000
- - min_value: -3200 mB
- - max_value: 600 mB
- - default_value: 0 mB
- - step_value: 100 mB
- - min_ramp_ms: 0 ms
- - max_ramp_ms: 0 ms
- ...
- 10. Port ID: 23; "bus7_system_sound_out"; {AUDIO_DEVICE_OUT_BUS, @:bus7_system_sound_out}
- Encapsulation modes: 0, metadata types: 0
- - Profiles (1):
- 1. ""; AUDIO_FORMAT_PCM_16_BIT (0x1)
- sampling rates: 48000
- channel masks: 0x0003
- AUDIO_ENCAPSULATION_TYPE_NONE
- - gains:
- Gain 1:
- - mode: 00000001
- - channel_mask: 00000000
- - min_value: -3200 mB
- - max_value: 600 mB
- - default_value: 0 mB
- - step_value: 100 mB
- - min_ramp_ms: 0 ms
- - max_ramp_ms: 0 ms
- 17. Port ID: 2; "bus0_media_out"; {AUDIO_DEVICE_OUT_BUS, @:bus0_media_out}
- Encapsulation modes: 0, metadata types: 0
- - Profiles (1):
- 1. ""; AUDIO_FORMAT_PCM_16_BIT (0x1)
- sampling rates: 48000
- channel masks: 0x0003
- AUDIO_ENCAPSULATION_TYPE_NONE
- - gains:
- Gain 1:
- - mode: 00000001
- - channel_mask: 00000000
- - min_value: -3200 mB
- - max_value: 600 mB
- - default_value: 0 mB
- - step_value: 100 mB
- - min_ramp_ms: 0 ms
- - max_ramp_ms: 0 ms
- Available input devices (7):
- 1. Port ID: 53; "Built-In Mic"; {AUDIO_DEVICE_IN_BUILTIN_MIC, @:Built-In Mic}
- Encapsulation modes: 0, metadata types: 0
- - Profiles (1):
- 1. ""; AUDIO_FORMAT_PCM_16_BIT (0x1)
- sampling rates: 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
- channel masks: 0x000c, 0x0010, 0x0030
- AUDIO_ENCAPSULATION_TYPE_NONE
- 2. Port ID: 54; "Built-In Back Mic"; {AUDIO_DEVICE_IN_BACK_MIC, @:Built-In Back Mic}
- Encapsulation modes: 0, metadata types: 0
- - Profiles (1):
- 1. ""; AUDIO_FORMAT_PCM_16_BIT (0x1)
- sampling rates: 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
- channel masks: 0x000c, 0x0010, 0x0030
- AUDIO_ENCAPSULATION_TYPE_NONE
- ...
- Hardware modules (3):
- 1. Handle: 10; "primary"
- - Output MixPorts (17):
- 1. "mixport_bus0_media_out"; 0x0002 (AUDIO_OUTPUT_FLAG_PRIMARY)
- - Profiles (1):
- 1. ""; AUDIO_FORMAT_PCM_16_BIT (0x1)
- sampling rates: 48000
- channel masks: 0x0003
- AUDIO_ENCAPSULATION_TYPE_NONE
- - Supported devices (1):
- 1. Port ID: 2; "bus0_media_out"; {AUDIO_DEVICE_OUT_BUS, @:bus0_media_out}
- Encapsulation modes: 0, metadata types: 0
- - maxOpenCount: 1; curOpenCount: 1
- - maxActiveCount: 1; curActiveCount: 0
- - recommendedMuteDurationMs: 0 ms
- 2. "mixport_bus1_navigation_out"; 0x0000 (AUDIO_OUTPUT_FLAG_NONE)
- - Profiles (1):
- 1. ""; AUDIO_FORMAT_PCM_16_BIT (0x1)
- sampling rates: 48000
- channel masks: 0x0003
- AUDIO_ENCAPSULATION_TYPE_NONE
- - Supported devices (1):
- 1. Port ID: 5; "bus1_navigation_out"; {AUDIO_DEVICE_OUT_BUS, @:bus1_navigation_out}
- Encapsulation modes: 0, metadata types: 0
- - maxOpenCount: 1; curOpenCount: 1
- - maxActiveCount: 1; curActiveCount: 0
- - recommendedMuteDurationMs: 0 ms
- ...
- - Input MixPorts (4):
- 1. "primary input"; 0x0000 (AUDIO_INPUT_FLAG_NONE)
- - Profiles (1):
- 1. ""; AUDIO_FORMAT_PCM_16_BIT (0x1)
- sampling rates: 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
- channel masks: 0x000c, 0x0010, 0x0030
- AUDIO_ENCAPSULATION_TYPE_NONE
- - Supported devices (3):
- 1. Port ID: 53; "Built-In Mic"; {AUDIO_DEVICE_IN_BUILTIN_MIC, @:Built-In Mic}
- Encapsulation modes: 0, metadata types: 0
- 2. Port ID: 54; "Built-In Back Mic"; {AUDIO_DEVICE_IN_BACK_MIC, @:Built-In Back Mic}
- Encapsulation modes: 0, metadata types: 0
- 3. Port ID: 55; "Echo-Reference Mic"; {AUDIO_DEVICE_IN_ECHO_REFERENCE, @:Echo-Reference Mic}
- Encapsulation modes: 0, metadata types: 0
- - maxOpenCount: 1; curOpenCount: 0
- - maxActiveCount: 1; curActiveCount: 0
- - recommendedMuteDurationMs: 0 ms
- ...
- - Declared devices (23):
- 1. Port ID: 50; "bus1000_mirror_device"; {AUDIO_DEVICE_OUT_BUS, @:bus1000_mirror_device}
- Encapsulation modes: 0, metadata types: 0
- - Profiles (1):
- 1. ""; AUDIO_FORMAT_PCM_16_BIT (0x1)
- sampling rates: 48000
- channel masks: 0x0003
- AUDIO_ENCAPSULATION_TYPE_NONE
- - gains:
- Gain 1:
- - mode: 00000001
- - channel_mask: 00000000
- - min_value: -3200 mB
- - max_value: 600 mB
- - default_value: 0 mB
- - step_value: 100 mB
- - min_ramp_ms: 0 ms
- - max_ramp_ms: 0 ms
- ...
- - Audio Routes (21):
- 1. Mix; Sink: "bus0_media_out"
- Sources: "mixport_bus0_media_out"
- 2. Mix; Sink: "bus1_navigation_out"
- Sources: "mixport_bus1_navigation_out"
- 3. Mix; Sink: "bus2_voice_command_out"
- Sources: "mixport_bus2_voice_command_out"
- ...
-
复制代码 2.2 AudioPolicyManager实例构建
- static AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)
- {
- ...
- apm = new AudioPolicyManager(config,
- loadApmEngineLibraryAndCreateEngine(config->getEngineLibraryNameSuffix()),
- clientInterface);
- }
复制代码 2.2.1 loadApmEngineLibraryAndCreateEngine
在2.1章的第3步中config->getEngineLibraryNameSuffix()返回的字符串为“default”(kDefaultEngineLibraryNameSuffix),以是loadApmEngineLibraryAndCreateEngine传入的参数为("default”,null)。
- EngineInstance loadApmEngineLibraryAndCreateEngine(const std::string& librarySuffix,
- const std::string& configXmlFilePath)
- {
- /* 1 - 加载libaudiopolicyengine.default.so,获取createEngineInstance句柄并赋值给mCreateEngineInstance */
- auto engLib = EngineLibrary::load(librarySuffix);
- if (!engLib) {
- ALOGE("%s: Failed to load the engine library, suffix "%s"",
- __func__, librarySuffix.c_str());
- return nullptr;
- }
- /* 2 - 创建ape,这里的configXmlFilePath为空 */
- auto engine = engLib->createEngineUsingXmlConfig(configXmlFilePath);
- if (engine == nullptr) {
- ALOGE("%s: Failed to instantiate the APM engine", __func__);
- return nullptr;
- }
- return engine;
- }
- EngineInstance EngineLibrary::createEngineUsingXmlConfig(const std::string& xmlFilePath)
- {
- auto instance = createEngine();
- if (instance != nullptr) {
- /* 2.1 - xmlFilePath为空,加载engine 配置文件*/
- if (status_t status = instance->loadFromXmlConfigWithFallback(xmlFilePath);
- status == OK) {
- return instance;
- } else {
- ALOGE("%s: loading of the engine config with XML configuration file "%s" failed: %d",
- __func__, xmlFilePath.empty() ? "default" : xmlFilePath.c_str(), status);
- }
- }
- return nullptr;
- }
- status_t Engine::loadFromXmlConfigWithFallback(const std::string& xmlFilePath) {
- return loadWithFallback(xmlFilePath);
- }
- template<typename T>
- status_t Engine::loadWithFallback(const T& configSource) {
- /* 2.1.1 - 加载engineConfig::DEFAULT_PATH("/vendor/etc/audio_policy_engine_configuration.xml") 下的ape配置文件 */
- auto result = EngineBase::loadAudioPolicyEngineConfig(configSource);
- auto legacyStrategy = getLegacyStrategy();
- for (const auto &strategy : legacyStrategy) {
- mLegacyStrategyMap[getProductStrategyByName(strategy.name)] = strategy.id;
- }
- return OK;
- }
复制代码 APE的调用逻辑比力繁琐,但是原理很清楚:起首确定是否存在用户自定义的configurable engine,如果不存在则使用default engine;确认之后渐渐调用并剖析相干的APE配置文件。譬如车机的APE配置如下:/frameworks/av/services/audiopolicy/engineconfigurable/config/example/automotive/audio_policy_engine_configuration.xml
- <configuration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
- <xi:include href="audio_policy_engine_product_strategies.xml"/>
- <xi:include href="audio_policy_engine_criterion_types.xml"/>
- <xi:include href="audio_policy_engine_criteria.xml"/>
- <xi:include href="audio_policy_engine_volumes.xml"/>
- </configuration>
复制代码 具体内容在后续使用的过程中分析。
2.3、AudioPolicyManager::initialize
回到2.1的第4步,也是最后一步:AudioPolicyManager的initialize。
- status_t AudioPolicyManager::initialize() {
- /* 1 - 这里的mEngine就是上面分析的APE,肯定非空了 */
- if (mEngine == nullptr) {
- return NO_INIT;
- }
- /* 2 - 将APM设置为Engine的观察器(mApmObserver=APM),
- 允许Engine检索Devices、Streams、HwModules的信息:
- Engine通过APM获取/设置相关信息 */
- mEngine->setObserver(this);
-
- /* 3 - 检测Engine是否被正确初始化:mApmObserver!=null, 这不是废话吗?
- 前面刚设置完成*/
- status_t status = mEngine->initCheck();
- if (status != NO_ERROR) {
- LOG_FATAL("Policy engine not initialized(err=%d)", status);
- return status;
- }
- // The actual device selection cache will be updated when calling `updateDevicesAndOutputs`
- // at the end of this function.
- /* 4 - 使用产品策略初始化设备,这些设备的策略会在音频模块初始化后更新。*/
- mEngine->initializeDeviceSelectionCache();
- mCommunnicationStrategy = mEngine->getProductStrategyForAttributes(
- mEngine->getAttributesForStreamType(AUDIO_STREAM_VOICE_CALL));
- /* 5 - 有音频模块可用(实际上是首次初始化),完成模块的初始化。*/
- // after parsing the config, mConfig contain all known devices;
- // open all output streams needed to access attached devices
- onNewAudioModulesAvailableInt(nullptr /*newDevices*/);
- // make sure default device is reachable
- if (const auto defaultOutputDevice = mConfig->getDefaultOutputDevice();
- defaultOutputDevice == nullptr ||
- !mAvailableOutputDevices.contains(defaultOutputDevice)) {
- ALOGE_IF(defaultOutputDevice != nullptr, "Default device %s is unreachable",
- defaultOutputDevice->toString().c_str());
- status = NO_INIT;
- }
-
- /* 6 - 第5步中完成了整个音频模块的初始化,跟新相关信息到Cache缓存中。
- 在音频系统稳定后,为了加快处理速度,引擎会缓存基于AudioAttribute/Streams的设备选择。当一个设备连接时,Android的模式会发生变化,引擎会收到通知并更新缓存。如果某个输出上音频流的启动/停止可能影响通知时,引擎需要通过updateDevicesAndOutputs函数更新缓存。*/
- updateDevicesAndOutputs();
- return status;
- }
复制代码 2.3.1、AudioPolicyManager:nNewAudioModulesAvailableInt
经过2.2章节的分析,我们已经清楚系统已经完成xml配置文件的剖析并形成HwModule的多维数据,该函数就是根据先前分析的数据完成音频系统的最告急的一步:调用AF->AHAL完成设备节
点的open,并在AF中创建数据流播放/录制线程,为后面AudioTrack做好预备
- void AudioPolicyManager::onNewAudioModulesAvailableInt(DeviceVector *newDevices)
- {
- ALOGD("AudioAnt: onNewAudioModulesAvailableInt enter ......");
- /* 1. 遍历audio_policy_configuration.xml中配置的所有模块 */
- for (const auto& hwModule : mConfig->getHwModules()) {
- if (std::find(mHwModules.begin(), mHwModules.end(), hwModule) != mHwModules.end()) {
- continue;
- }
- if (hwModule->getHandle() == AUDIO_MODULE_HANDLE_NONE) {
- ALOGD("AudioAnt: loadHwModule with module name %s", hwModule->getName());
- /* 2. 加载相关module,获取module的句柄handle */
- if (audio_module_handle_t handle = mpClientInterface->loadHwModule(hwModule->getName());
- handle != AUDIO_MODULE_HANDLE_NONE) {
- hwModule->setHandle(handle);
- } else {
- ALOGW("could not load HW module %s", hwModule->getName());
- continue;
- }
- }
- /* 3. 如果xml中配置的module存在,则记录到mHwModules容器中以便后面访问使用 */
- mHwModules.push_back(hwModule);
-
- /* 4. 遍历当前模块支持的profiles */
- for (const auto& outProfile : hwModule->getOutputProfiles()) {
- ALOGD("AudioAnt: outProfile with name: %s", outProfile->getTagName().c_str());
-
- /* 5. 获取当前profile支持的设备 */
- const DeviceVector &supportedDevices = outProfile->getSupportedDevices();
- for(auto& device: supportedDevices) {
- ALOGD("AudioAnt: supportedDevices with name: %s", device->getTagName().c_str());
- }
- DeviceVector availProfileDevices = supportedDevices.filter(mConfig->getOutputDevices());
- sp<DeviceDescriptor> supportedDevice = 0;
- if (supportedDevices.contains(mConfig->getDefaultOutputDevice())) {
- supportedDevice = mConfig->getDefaultOutputDevice();
- } else {
- // choose first device present in profile's SupportedDevices also part of
- // mAvailableOutputDevices.
- if (availProfileDevices.isEmpty()) {
- continue;
- }
- supportedDevice = availProfileDevices.itemAt(0);
- }
- if (!mConfig->getOutputDevices().contains(supportedDevice)) {
- continue;
- }
- sp<SwAudioOutputDescriptor> outputDesc = new SwAudioOutputDescriptor(outProfile, mpClientInterface);
- audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
-
- /* 6. 打开设备,涉及AHAL的open操作,并在AF中创建相关播放/录制线程 */
- status_t status = outputDesc->open(nullptr /* halConfig */, nullptr /* mixerConfig */,
- DeviceVector(supportedDevice),
- AUDIO_STREAM_DEFAULT,
- AUDIO_OUTPUT_FLAG_NONE, &output);
- if (status != NO_ERROR) {
- ALOGW("Cannot open output stream for devices %s on hw module %s",
- supportedDevice->toString().c_str(), hwModule->getName());
- continue;
- }
- for (const auto &device : availProfileDevices) {
- ALOGD("AudioAnt: availProfileDevices with name: %s", device->getTagName().c_str());
- // give a valid ID to an attached device once confirmed it is reachable
- if (!device->isAttached()) {
- device->attach(hwModule);
- mAvailableOutputDevices.add(device);
- device->setEncapsulationInfoFromHal(mpClientInterface);
- if (newDevices) newDevices->add(device);
- setEngineDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
- }
- }
- if (mPrimaryOutput == nullptr &&
- outProfile->getFlags() & AUDIO_OUTPUT_FLAG_PRIMARY) {
- mPrimaryOutput = outputDesc;
- }
- if ((outProfile->getFlags() & AUDIO_OUTPUT_FLAG_DIRECT) != 0) {
- outputDesc->close();
- } else {
- addOutput(output, outputDesc);
- setOutputDevices(outputDesc,
- DeviceVector(supportedDevice),
- true,
- 0,
- NULL);
- }
- }
-
- /* 7. 同输出设置一样的操作逻辑,不赘述 */
- // open input streams needed to access attached devices to validate
- // mAvailableInputDevices list
- for (const auto& inProfile : hwModule->getInputProfiles()) {
- }
- }
- /* 8. 如果有声场相关输出,在使用之前先关闭它 */
- // Check if spatializer outputs can be closed until used.
- // mOutputs vector never contains duplicated outputs at this point.
- std::vector<audio_io_handle_t> outputsClosed;
- for (size_t i = 0; i < mOutputs.size(); i++) {
- sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
- if ((desc->mFlags & AUDIO_OUTPUT_FLAG_SPATIALIZER) != 0
- && !isOutputOnlyAvailableRouteToSomeDevice(desc)) {
- outputsClosed.push_back(desc->mIoHandle);
- desc->close();
- }
- }
- for (auto output : outputsClosed) {
- removeOutput(output);
- }
- }
复制代码 终极的利用输出如下:
- 06-06 21:51:06.077 16876 16876 D APM_AudioPolicyManager: AudioAnt: onNewAudioModulesAvailableInt enter ......
- 06-06 21:51:06.077 16876 16876 D APM_AudioPolicyManager: AudioAnt: loadHwModule with module name primary
- 06-06 21:51:09.092 16876 16876 D APM_AudioPolicyManager: AudioAnt: outProfile with name: mixport_bus0_media_out
- 06-06 21:51:09.092 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: bus0_media_out
- 06-06 21:51:09.096 16876 16876 I AudioFlinger: AudioAnt: openOutput() this 0xb40000738661f010, module 10 Device AUDIO_DEVICE_OUT_BUS, @:bus0_media_out, SamplingRate
- 48000, Format 0x000001, Channels 0x3, flags 0x2
- 06-06 21:51:09.266 16876 16876 D APM_AudioPolicyManager: AudioAnt: availProfileDevices with name: bus0_media_out
- 06-06 21:51:09.316 16876 16876 D APM_AudioPolicyManager: AudioAnt: outProfile with name: mixport_bus1_navigation_out
- 06-06 21:51:09.316 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: bus1_navigation_out
- 06-06 21:51:09.316 16876 16876 I AudioFlinger: AudioAnt: openOutput() this 0xb40000738661f010, module 10 Device AUDIO_DEVICE_OUT_BUS, @:bus1_navigation_out, Samplin
- gRate 48000, Format 0x000001, Channels 0x3, flags 0
- 06-06 21:51:09.327 16876 16876 D APM_AudioPolicyManager: AudioAnt: availProfileDevices with name: bus1_navigation_out
- 06-06 21:51:09.354 16876 16876 D APM_AudioPolicyManager: AudioAnt: outProfile with name: mixport_bus2_voice_command_out
- 06-06 21:51:09.354 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: bus2_voice_command_out
- 06-06 21:51:09.354 16876 16876 I AudioFlinger: AudioAnt: openOutput() this 0xb40000738661f010, module 10 Device AUDIO_DEVICE_OUT_BUS, @:bus2_voice_command_out, Samp
- lingRate 48000, Format 0x000001, Channels 0x3, flags 0
- 06-06 21:51:09.365 16876 16876 D APM_AudioPolicyManager: AudioAnt: availProfileDevices with name: bus2_voice_command_out
- 06-06 21:51:09.391 16876 16876 D APM_AudioPolicyManager: AudioAnt: outProfile with name: mixport_bus3_call_ring_out
- 06-06 21:51:09.392 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: bus3_call_ring_out
- 06-06 21:51:09.392 16876 16876 I AudioFlinger: AudioAnt: openOutput() this 0xb40000738661f010, module 10 Device AUDIO_DEVICE_OUT_BUS, @:bus3_call_ring_out, Sampling
- Rate 48000, Format 0x000001, Channels 0x3, flags 0
- 06-06 21:51:09.403 16876 16876 D APM_AudioPolicyManager: AudioAnt: availProfileDevices with name: bus3_call_ring_out
- 06-06 21:51:09.416 16876 16876 D APM_AudioPolicyManager: AudioAnt: outProfile with name: mixport_bus4_call_out
- 06-06 21:51:09.416 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: bus4_call_out
- 06-06 21:51:09.416 16876 16876 I AudioFlinger: AudioAnt: openOutput() this 0xb40000738661f010, module 10 Device AUDIO_DEVICE_OUT_BUS, @:bus4_call_out, SamplingRate
- 48000, Format 0x000001, Channels 0x3, flags 0
- 06-06 21:51:09.423 16876 16876 D APM_AudioPolicyManager: AudioAnt: availProfileDevices with name: bus4_call_out
- 06-06 21:51:09.441 16876 16876 D APM_AudioPolicyManager: AudioAnt: outProfile with name: mixport_bus5_alarm_out
- 06-06 21:51:09.442 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: bus5_alarm_out
- 06-06 21:51:09.442 16876 16876 I AudioFlinger: AudioAnt: openOutput() this 0xb40000738661f010, module 10 Device AUDIO_DEVICE_OUT_BUS, @:bus5_alarm_out, SamplingRate
- 48000, Format 0x000001, Channels 0x3, flags 0
- 06-06 21:51:09.451 16876 16876 D APM_AudioPolicyManager: AudioAnt: availProfileDevices with name: bus5_alarm_out
- 06-06 21:51:09.463 16876 16876 D APM_AudioPolicyManager: AudioAnt: outProfile with name: mixport_bus6_notification_out
- 06-06 21:51:09.463 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: bus6_notification_out
- 06-06 21:51:09.463 16876 16876 I AudioFlinger: AudioAnt: openOutput() this 0xb40000738661f010, module 10 Device AUDIO_DEVICE_OUT_BUS, @:bus6_notification_out, Sampl
- ingRate 48000, Format 0x000001, Channels 0x3, flags 0
- 06-06 21:51:09.471 16876 16876 D APM_AudioPolicyManager: AudioAnt: availProfileDevices with name: bus6_notification_out
- 06-06 21:51:09.491 16876 16876 D APM_AudioPolicyManager: AudioAnt: outProfile with name: mixport_bus7_system_sound_out
- 06-06 21:51:09.491 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: bus7_system_sound_out
- 06-06 21:51:09.491 16876 16876 I AudioFlinger: AudioAnt: openOutput() this 0xb40000738661f010, module 10 Device AUDIO_DEVICE_OUT_BUS, @:bus7_system_sound_out, Sampl
- ingRate 48000, Format 0x000001, Channels 0x3, flags 0
- 06-06 21:51:09.499 16876 16876 D APM_AudioPolicyManager: AudioAnt: availProfileDevices with name: bus7_system_sound_out
- 06-06 21:51:09.519 16876 16876 D APM_AudioPolicyManager: AudioAnt: outProfile with name: mixport_bus100_audio_zone_1
- 06-06 21:51:09.519 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: bus100_audio_zone_1
- 06-06 21:51:09.520 16876 16876 I AudioFlinger: AudioAnt: openOutput() this 0xb40000738661f010, module 10 Device AUDIO_DEVICE_OUT_BUS, @:bus100_audio_zone_1, Samplin
- gRate 48000, Format 0x000001, Channels 0x3, flags 0
- 06-06 21:51:09.530 16876 16876 D APM_AudioPolicyManager: AudioAnt: availProfileDevices with name: bus100_audio_zone_1
- 06-06 21:51:09.557 16876 16876 D APM_AudioPolicyManager: AudioAnt: outProfile with name: mixport_bus101_audio_zone_1
- 06-06 21:51:09.558 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: bus101_audio_zone_1
- 06-06 21:51:09.558 16876 16876 I AudioFlinger: AudioAnt: openOutput() this 0xb40000738661f010, module 10 Device AUDIO_DEVICE_OUT_BUS, @:bus101_audio_zone_1, Samplin
- gRate 48000, Format 0x000001, Channels 0x3, flags 0
- 06-06 21:51:09.569 16876 16876 D APM_AudioPolicyManager: AudioAnt: availProfileDevices with name: bus101_audio_zone_1
- 06-06 21:51:09.598 16876 16876 D APM_AudioPolicyManager: AudioAnt: outProfile with name: mixport_bus110_audio_zone_1
- 06-06 21:51:09.598 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: bus110_audio_zone_1
- 06-06 21:51:09.598 16876 16876 I AudioFlinger: AudioAnt: openOutput() this 0xb40000738661f010, module 10 Device AUDIO_DEVICE_OUT_BUS, @:bus110_audio_zone_1, Samplin
- gRate 48000, Format 0x000001, Channels 0x3, flags 0
- 06-06 21:51:09.604 16876 16876 D APM_AudioPolicyManager: AudioAnt: availProfileDevices with name: bus110_audio_zone_1
- 06-06 21:51:09.630 16876 16876 D APM_AudioPolicyManager: AudioAnt: outProfile with name: mixport_bus111_audio_zone_1
- 06-06 21:51:09.630 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: bus111_audio_zone_1
- 06-06 21:51:09.631 16876 16876 I AudioFlinger: AudioAnt: openOutput() this 0xb40000738661f010, module 10 Device AUDIO_DEVICE_OUT_BUS, @:bus111_audio_zone_1, Samplin
- gRate 48000, Format 0x000001, Channels 0x3, flags 0
- 06-06 21:51:09.642 16876 16876 D APM_AudioPolicyManager: AudioAnt: availProfileDevices with name: bus111_audio_zone_1
- 06-06 21:51:09.678 16876 16876 D APM_AudioPolicyManager: AudioAnt: outProfile with name: mixport_bus200_audio_zone_2
- 06-06 21:51:09.679 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: bus200_audio_zone_2
- 06-06 21:51:09.679 16876 16876 I AudioFlinger: AudioAnt: openOutput() this 0xb40000738661f010, module 10 Device AUDIO_DEVICE_OUT_BUS, @:bus200_audio_zone_2, Samplin
- gRate 48000, Format 0x000001, Channels 0x3, flags 0
- 06-06 21:51:09.690 16876 16876 D APM_AudioPolicyManager: AudioAnt: availProfileDevices with name: bus200_audio_zone_2
- 06-06 21:51:09.713 16876 16876 D APM_AudioPolicyManager: AudioAnt: outProfile with name: mixport_bus201_audio_zone_2
- 06-06 21:51:09.713 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: bus201_audio_zone_2
- 06-06 21:51:09.713 16876 16876 I AudioFlinger: AudioAnt: openOutput() this 0xb40000738661f010, module 10 Device AUDIO_DEVICE_OUT_BUS, @:bus201_audio_zone_2, Samplin
- gRate 48000, Format 0x000001, Channels 0x3, flags 0
- 06-06 21:51:09.720 16876 16876 D APM_AudioPolicyManager: AudioAnt: availProfileDevices with name: bus201_audio_zone_2
- 06-06 21:51:09.742 16876 16876 D APM_AudioPolicyManager: AudioAnt: outProfile with name: mixport_bus210_audio_zone_2
- 06-06 21:51:09.742 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: bus210_audio_zone_2
- 06-06 21:51:09.742 16876 16876 I AudioFlinger: AudioAnt: openOutput() this 0xb40000738661f010, module 10 Device AUDIO_DEVICE_OUT_BUS, @:bus210_audio_zone_2, Samplin
- gRate 48000, Format 0x000001, Channels 0x3, flags 0
- 06-06 21:51:09.747 16876 16876 D APM_AudioPolicyManager: AudioAnt: availProfileDevices with name: bus210_audio_zone_2
- 06-06 21:51:09.773 16876 16876 D APM_AudioPolicyManager: AudioAnt: outProfile with name: mixport_bus211_audio_zone_2
- 06-06 21:51:09.773 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: bus211_audio_zone_2
- 06-06 21:51:09.773 16876 16876 I AudioFlinger: AudioAnt: openOutput() this 0xb40000738661f010, module 10 Device AUDIO_DEVICE_OUT_BUS, @:bus211_audio_zone_2, Samplin
- gRate 48000, Format 0x000001, Channels 0x3, flags 0
- 06-06 21:51:09.779 16876 16876 D APM_AudioPolicyManager: AudioAnt: availProfileDevices with name: bus211_audio_zone_2
- 06-06 21:51:09.810 16876 16876 D APM_AudioPolicyManager: AudioAnt: outProfile with name: mixport_bus1000_mirror_device
- 06-06 21:51:09.810 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: bus1000_mirror_device
- 06-06 21:51:09.810 16876 16876 I AudioFlinger: AudioAnt: openOutput() this 0xb40000738661f010, module 10 Device AUDIO_DEVICE_OUT_BUS, @:bus1000_mirror_device, Sampl
- ingRate 48000, Format 0x000001, Channels 0x3, flags 0
- 06-06 21:51:09.817 16876 16876 D APM_AudioPolicyManager: AudioAnt: availProfileDevices with name: bus1000_mirror_device
- 06-06 21:51:09.881 16876 16876 D APM_AudioPolicyManager: AudioAnt: loadHwModule with module name a2dp
- 06-06 21:51:09.882 16876 16876 D APM_AudioPolicyManager: AudioAnt: loadHwModule with module name usb
- 06-06 21:51:09.884 16876 16876 D APM_AudioPolicyManager: AudioAnt: outProfile with name: usb_accessory output
- 06-06 21:51:09.884 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: USB Host Out
- 06-06 21:51:09.884 16876 16876 D APM_AudioPolicyManager: AudioAnt: outProfile with name: usb_device output
- 06-06 21:51:09.884 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: USB Device Out
- 06-06 21:51:09.885 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: USB Headset Out
- 06-06 21:51:09.885 16876 16876 D APM_AudioPolicyManager: AudioAnt: loadHwModule with module name r_submix
- 06-06 21:51:09.888 16876 16876 D APM_AudioPolicyManager: AudioAnt: outProfile with name: r_submix output
- 06-06 21:51:09.888 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: Remote Submix Out
复制代码 可以看到此时系统已经创建了多个AudioOut线程(主历程为audioservice),随后如果应用创建了AudioTrack,就可以根据strategy绑定到相干线程,触发或者加入到播放/录制线程。
- auto8678p1_64_bsp_vm:/ # ps -ef | grep audioserver
- audioserver 16876 1 0 21:51:04 ? 00:00:02 audioserver
- auto8678p1_64_bsp_vm:/ # ps -T -p 16876
- USER PID TID PPID VSZ RSS WCHAN ADDR S CMD
- audioserver 16876 16876 1 12552792 50996 binder_th+ 0 S audioserver
- audioserver 16876 16884 1 12552792 50996 binder_th+ 0 S binder:16876_1
- audioserver 16876 16885 1 12552792 50996 futex_wai+ 0 S AudioFlinger_Pa
- audioserver 16876 16886 1 12552792 50996 binder_th+ 0 S binder:16876_2
- audioserver 16876 16887 1 12552792 50996 binder_th+ 0 S HwBinder:16876_
- audioserver 16876 16888 1 12552792 50996 binder_th+ 0 S HwBinder:16876_
- audioserver 16876 16889 1 12552792 50996 binder_th+ 0 S HwBinder:16876_
- audioserver 16876 16891 1 12552792 50996 futex_wai+ 0 S AudioUtilThread
- audioserver 16876 16892 1 12552792 50996 futex_wai+ 0 S ApmAudio
- audioserver 16876 16893 1 12552792 50996 futex_wai+ 0 S ApmOutput
- audioserver 16876 16913 1 12552792 50996 futex_wai+ 0 S TimerThread
- audioserver 16876 16914 1 12552792 50996 futex_wai+ 0 S AudioOut_D
- audioserver 16876 16915 1 12552792 50996 futex_wai+ 0 S AudioOut_15
- audioserver 16876 16916 1 12552792 50996 futex_wai+ 0 S AudioOut_1D
- audioserver 16876 16917 1 12552792 50996 futex_wai+ 0 S AudioOut_25
- audioserver 16876 16918 1 12552792 50996 futex_wai+ 0 S AudioOut_2D
- audioserver 16876 16919 1 12552792 50996 futex_wai+ 0 S AudioOut_35
- audioserver 16876 16920 1 12552792 50996 futex_wai+ 0 S AudioOut_3D
- audioserver 16876 16921 1 12552792 50996 futex_wai+ 0 S AudioOut_45
- audioserver 16876 16922 1 12552792 50996 futex_wai+ 0 S AudioOut_4D
- audioserver 16876 16923 1 12552792 50996 futex_wai+ 0 S AudioOut_55
- audioserver 16876 16924 1 12552792 50996 futex_wai+ 0 S AudioOut_5D
- audioserver 16876 16925 1 12552792 50996 futex_wai+ 0 S AudioOut_65
- audioserver 16876 16926 1 12552792 50996 futex_wai+ 0 S AudioOut_6D
- audioserver 16876 16927 1 12552792 50996 futex_wai+ 0 S AudioOut_75
- audioserver 16876 16928 1 12552792 50996 futex_wai+ 0 S AudioOut_7D
- audioserver 16876 16929 1 12552792 50996 futex_wai+ 0 S AudioOut_85
- audioserver 16876 16930 1 12552792 50996 futex_wai+ 0 S AudioOut_8D
- audioserver 16876 16945 1 12552792 50996 binder_th+ 0 S binder:16876_3
- audioserver 16876 16948 1 12552792 50996 binder_th+ 0 S binder:16876_4
- audioserver 16876 17743 1 12552792 50996 binder_th+ 0 S binder:16876_5
复制代码 总结
团体音频链路的预备工作暂时画上一个句号,复杂但是容易明白。音频服务端已经预备停当,等候音频客户端(AudioTrack/AudioRecord)的加入并开始奥妙的音频之旅。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |