作者:阆中猫猫覀_648 | 来源:互联网 | 2024-11-12 18:52
在分析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.cpp
、AudioPolicyCompatClient.cpp
和audio_policy_hal.cpp
生成。
通过hw_get_module_by_class
函数加载HAL模块,具体加载的模块包括audio_policy.stub.so
、audio_policy.default.so
和audio_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->apm
由create_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_ops
和this
参数。
最终,mpAudioPolicy->get_input
将调用hardware/libhardware_legacy/audio/AudioPolicyManagerBase.cpp
中的getInput
函数。在AudioPolicyManagerBase
中,会调用AudioPolicyCompatClient
的openInput
方法,根据audio_policy.conf
文件的配置信息选择合适的音频设备,并确定audio_module_handle_t
的值。
在openInput
中,通过本cpp传入的aps_ops
回调本cpp中的aps_open_input_on_module
,后者调用AudioFlinger
的openInput
方法。AudioFlinger
的openInput
会产生一个唯一整数作为audio_io_handle_t
,并根据选定的音频设备的audio_module_handle_t
在mAudioHwDevs
中查找对应的设备的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
中找出对应线程的索引。