热门标签 | 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中找出对应线程的索引。


推荐阅读
  • 本文详细解析了 Android 系统启动过程中的核心文件 `init.c`,探讨了其在系统初始化阶段的关键作用。通过对 `init.c` 的源代码进行深入分析,揭示了其如何管理进程、解析配置文件以及执行系统启动脚本。此外,文章还介绍了 `init` 进程的生命周期及其与内核的交互方式,为开发者提供了深入了解 Android 启动机制的宝贵资料。 ... [详细]
  • 属性类 `Properties` 是 `Hashtable` 类的子类,用于存储键值对形式的数据。该类在 Java 中广泛应用于配置文件的读取与写入,支持字符串类型的键和值。通过 `Properties` 类,开发者可以方便地进行配置信息的管理,确保应用程序的灵活性和可维护性。此外,`Properties` 类还提供了加载和保存属性文件的方法,使其在实际开发中具有较高的实用价值。 ... [详细]
  • 本文详细介绍了 PHP 中对象的生命周期、内存管理和魔术方法的使用,包括对象的自动销毁、析构函数的作用以及各种魔术方法的具体应用场景。 ... [详细]
  • C#实现文件的压缩与解压
    2019独角兽企业重金招聘Python工程师标准一、准备工作1、下载ICSharpCode.SharpZipLib.dll文件2、项目中引用这个dll二、文件压缩与解压共用类 ... [详细]
  • Android 自定义 RecycleView 左滑上下分层示例代码
    为了满足项目需求,需要在多个场景中实现左滑删除功能,并且后续可能在列表项中增加其他功能。虽然网络上有很多左滑删除的示例,但大多数封装不够完善。因此,我们尝试自己封装一个更加灵活和通用的解决方案。 ... [详细]
  • 如果应用程序经常播放密集、急促而又短暂的音效(如游戏音效)那么使用MediaPlayer显得有些不太适合了。因为MediaPlayer存在如下缺点:1)延时时间较长,且资源占用率高 ... [详细]
  • Spring – Bean Life Cycle
    Spring – Bean Life Cycle ... [详细]
  • 本文探讨了如何在 Java 中将多参数方法通过 Lambda 表达式传递给一个接受 List 的 Function。具体分析了 `OrderUtil` 类中的 `runInBatches` 方法及其使用场景。 ... [详细]
  • 单片微机原理P3:80C51外部拓展系统
      外部拓展其实是个相对来说很好玩的章节,可以真正开始用单片机写程序了,比较重要的是外部存储器拓展,81C55拓展,矩阵键盘,动态显示,DAC和ADC。0.IO接口电路概念与存 ... [详细]
  • oracle c3p0 dword 60,web_day10 dbcp c3p0 dbutils
    createdatabasemydbcharactersetutf8;alertdatabasemydbcharactersetutf8;1.自定义连接池为了不去经常创建连接和释放 ... [详细]
  • 深入解析 Lifecycle 的实现原理
    本文将详细介绍 Android Jetpack 中 Lifecycle 组件的实现原理,帮助开发者更好地理解和使用 Lifecycle,避免常见的内存泄漏问题。 ... [详细]
  • 题目《BZOJ2654: Tree》的时间限制为30秒,内存限制为512MB。该问题通过结合二分查找和Kruskal算法,提供了一种高效的优化解决方案。具体而言,利用二分查找缩小解的范围,再通过Kruskal算法构建最小生成树,从而在复杂度上实现了显著的优化。此方法不仅提高了算法的效率,还确保了在大规模数据集上的稳定性能。 ... [详细]
  • 如何将TS文件转换为M3U8直播流:HLS与M3U8格式详解
    在视频传输领域,MP4虽然常见,但在直播场景中直接使用MP4格式存在诸多问题。例如,MP4文件的头部信息(如ftyp、moov)较大,导致初始加载时间较长,影响用户体验。相比之下,HLS(HTTP Live Streaming)协议及其M3U8格式更具优势。HLS通过将视频切分成多个小片段,并生成一个M3U8播放列表文件,实现低延迟和高稳定性。本文详细介绍了如何将TS文件转换为M3U8直播流,包括技术原理和具体操作步骤,帮助读者更好地理解和应用这一技术。 ... [详细]
  • 本文探讨了如何通过编程手段在Linux系统中禁用硬件预取功能。基于Intel® Core™微架构的应用性能优化需求,文章详细介绍了相关配置方法和代码实现,旨在帮助开发人员有效控制硬件预取行为,提升应用程序的运行效率。 ... [详细]
  • Spring框架中枚举参数的正确使用方法与技巧
    本文详细阐述了在Spring Boot框架中正确使用枚举参数的方法与技巧,旨在帮助开发者更高效地掌握和应用枚举类型的数据传递,适合对Spring Boot感兴趣的读者深入学习。 ... [详细]
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社区 版权所有