热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

深入解析AndroidAudio系统中的mpAudioPolicy->get_input

在分析Android的Audio系统时,我们对mpAudioPolicy->get_input进行了详细探讨,发现其背后涉及的机制相当复杂。本文将详细介绍这一过程及其背后的实现细节。

在分析Android的Audio系统时,我们对mpAudioPolicy->get_input进行了详细探讨,发现其背后涉及的机制相当复杂。本文将详细介绍这一过程及其背后的实现细节。

首先,调用mpAudioPolicy->get_input方法,该方法是在mpAudioPolicyDev->create_audio_policy(mpAudioPolicyDev, &aps_ops, this, &mpAudioPolicy)中赋值的。这里涉及到几个关键结构体:

  • struct audio_policy_device *mpAudioPolicyDev;
  • struct audio_policy *mpAudioPolicy;

mpAudioPolicyDev的赋值是在audio_policy_dev_open函数中完成的,该函数定义如下:

static inline int audio_policy_dev_open(const hw_module_t* module, struct audio_policy_device** device) {
    return module->methods->open(module, AUDIO_POLICY_INTERFACE, (hw_device_t**)device);
}

接下来需要找到module的来源。Android的AudioPolicy接口继承关系如下:

  • AudioPolicyInterface
  • AudioPolicyManagerBase
  • AudioPolicyManagerDefault

AudioPolicyManagerDefault编译成audio_policy.default.so,该库依赖于静态库libaudiopolicy_legacy.a,后者由AudioPolicyManagerBase.cppAudioPolicyCompatClient.cppaudio_policy_hal.cpp生成。

通过hw_get_module_by_class函数加载HAL模块,具体加载的模块包括audio_policy.stub.soaudio_policy.default.soaudio_policy.msm8960.so。模拟器中加载的是audio_policy.default.so

hw_get_module(AUDIO_POLICY_HARDWARE_MODULE_ID, &module)获取到的module类型为hw_module_t。接着调用module->methods->open(module, AUDIO_POLICY_INTERFACE, (hw_device_t**)device),将hw_device_t类型转换成audio_policy_device返回给mpAudioPolicyDev

audio_policy_hal.cpp中,module->methods->open将调用legacy_ap_dev_open函数。最终,mpAudioPolicyDev将成为legacy_ap_dev_open函数的最后一个参数hw_device_t** device

通过以下代码:

dev->device.create_audio_policy = create_legacy_ap;
*device = &dev->device.common;

知道mpAudioPolicy将成为create_legacy_ap的最后一个参数struct audio_policy **ap。再通过以下代码:

lap->policy.get_input = ap_get_input;
*ap = &lap->policy;

知道mpAudioPolicy->get_input(...)最终将调用ap_get_input函数。

ap_get_input函数的内容如下:

struct legacy_audio_policy *lap = to_lap(pol);
return lap->apm->getInput((int) inputSource, sampling_rate, (int) format, channelMask, (AudioSystem::audio_in_acoustics)acoustics);

其中,lap->apmcreate_legacy_ap中的以下语句创建:

lap->apm = createAudioPolicyManager(lap->service_client);

因此,apm实际上是new AudioPolicyManagerDefault(lap->service_client)对象,而lap->service_client = new AudioPolicyCompatClient(aps_ops, service)。这里的参数是本cpp中调用create_audio_policy(mpAudioPolicyDev, &aps_ops, this, &mpAudioPolicy)中传入的aps_opsthis参数。

最终,mpAudioPolicy->get_input将调用hardware/libhardware_legacy/audio/AudioPolicyManagerBase.cpp中的getInput函数。在AudioPolicyManagerBase中,会调用AudioPolicyCompatClientopenInput方法,根据audio_policy.conf文件的配置信息选择合适的音频设备,并确定audio_module_handle_t的值。

openInput中,通过本cpp传入的aps_ops回调本cpp中的aps_open_input_on_module,后者调用AudioFlingeropenInput方法。AudioFlingeropenInput会产生一个唯一整数作为audio_io_handle_t,并根据选定的音频设备的audio_module_handle_tmAudioHwDevs中查找对应的设备的AudioHwDevice对象inHwDev

找到inHwDev设备后,调用该设备的HAL中的open_input_stream方法,即audio_hw.c中的adev_open_input_stream。在adev_open_input_stream中构造HAL层的自定义类型stream_in(如stub_stream_in),并在stream_in中植入自己定义的HAL层函数,然后把该stream_in返回给AudioFlinger

AudioFlinger使用HAL返回的stream_in以及前面找出的设备的AudioHwDevice构造AF中的AudioStreamIn类型对象input,然后创建一个新的RecordThread线程,并将该线程以前面传入的audio_io_handle_t做索引存入mRecordThreads中,返回audio_io_handle_t,即audio_io_handle_t是在AudioFlinger中找出对应线程的索引。


推荐阅读
  • Explore a common issue encountered when implementing an OAuth 1.0a API, specifically the inability to encode null objects and how to resolve it. ... [详细]
  • 使用 Azure Service Principal 和 Microsoft Graph API 获取 AAD 用户列表
    本文介绍了一段通用代码示例,该代码不仅能够操作 Azure Active Directory (AAD),还可以通过 Azure Service Principal 的授权访问和管理 Azure 订阅资源。Azure 的架构可以分为两个层级:AAD 和 Subscription。 ... [详细]
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
  • 本文深入探讨了Linux系统中网卡绑定(bonding)的七种工作模式。网卡绑定技术通过将多个物理网卡组合成一个逻辑网卡,实现网络冗余、带宽聚合和负载均衡,在生产环境中广泛应用。文章详细介绍了每种模式的特点、适用场景及配置方法。 ... [详细]
  • 本文详细介绍了Java中org.neo4j.helpers.collection.Iterators.single()方法的功能、使用场景及代码示例,帮助开发者更好地理解和应用该方法。 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • Explore how Matterverse is redefining the metaverse experience, creating immersive and meaningful virtual environments that foster genuine connections and economic opportunities. ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • 本文介绍了一款用于自动化部署 Linux 服务的 Bash 脚本。该脚本不仅涵盖了基本的文件复制和目录创建,还处理了系统服务的配置和启动,确保在多种 Linux 发行版上都能顺利运行。 ... [详细]
  • 本文详细介绍了Java中org.eclipse.ui.forms.widgets.ExpandableComposite类的addExpansionListener()方法,并提供了多个实际代码示例,帮助开发者更好地理解和使用该方法。这些示例来源于多个知名开源项目,具有很高的参考价值。 ... [详细]
  • 本文深入探讨了 Java 中的 Serializable 接口,解释了其实现机制、用途及注意事项,帮助开发者更好地理解和使用序列化功能。 ... [详细]
  • XNA 3.0 游戏编程:从 XML 文件加载数据
    本文介绍如何在 XNA 3.0 游戏项目中从 XML 文件加载数据。我们将探讨如何将 XML 数据序列化为二进制文件,并通过内容管道加载到游戏中。此外,还会涉及自定义类型读取器和写入器的实现。 ... [详细]
  • 本文详细介绍了如何构建一个高效的UI管理系统,集中处理UI页面的打开、关闭、层级管理和页面跳转等问题。通过UIManager统一管理外部切换逻辑,实现功能逻辑分散化和代码复用,支持多人协作开发。 ... [详细]
  • 本文详细介绍如何使用Samba软件配置CIFS文件共享服务,涵盖安装、配置、权限管理及多用户挂载等关键步骤。通过具体示例和命令行操作,帮助读者快速搭建并优化Samba服务器。 ... [详细]
  • OBS (Open Broadcaster Software) 架构解析
    本文介绍 OBS(Open Broadcaster Software),一款专为直播设计的开源软件。文章将详细探讨其技术架构、核心组件及其开发环境要求。 ... [详细]
author-avatar
阆中猫猫覀_648
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有