Android音频子系统,AudioPolicyService(三)
来源:互联网 发布:fifaonline3数据库app 编辑:程序博客网 时间:2024/05/22 13:24
AudioPolicyService
AudioFlinger是音频策略的执行者,AudioPolicyService是策略的制定者。
Android系统中声音被换分为多个种类:
AudioSystem.java
public class AudioSystem{public static final int STREAM_DEFAULT = -1;public static final int STREAM_VOICE_CALL = 0;public static final int STREAM_SYSTEM = 1;public static final int STREAM_RING = 2;public static final int STREAM_MUSIC = 3;public static final int STREAM_ALARM = 4;public static final int STREAM_NOTIFICATION = 5;/* @hide The audio stream for phone calls when connected on bluetooth */public static final int STREAM_BLUETOOTH_SCO = 6;/* @hide The audio stream for enforced system sounds in certain countries (e.g camera in Japan) */ public static final int STREAM_SYSTEM_ENFORCED = 7;/* @hide The audio stream for DTMF tones */public static final int STREAM_DTMF = 8;/* @hide The audio stream for text to speech (TTS) */public static final int STREAM_TTS = 9;}
系统中存在多个audiointerface,每一个audiointerface包含若干个output,每个output又支持若干种音频设备。
一个播放线程playbackThread的输出对应了一种设备。
在特定的时间,同一类型的音频对应的输出设备时统一的。比如说当前STREAM_MUSIC对应的是喇叭,那么多有这个类型的音频都会输出到喇叭。
所以,同一类型的音频对应的playbackThread也是一样的。
AudioPolicyService的启动,跟AudioFlinger一样,也跟它同进程,也是在audioserver.rc的解析中启动的。
在servicemanager中注册的名字是“media.audio_policy”。
看下他的构造函数及onFirstRef函数。
AudioPolicyService.cpp
void AudioPolicyService::onFirstRef(){//加载policy库,得到Audio Policy的hw_module_t,默认情况下audio policy的实现在audio_policy_hal.cpp。const struct hw_module_t *module;int rc = hw_get_module(AUDIO_POLICY_HARDWARE_MODULE_ID, &module);//通过hw_module_t打开audio policy设备,函数audio_policy_dev_open真正调用的是audio_policy_hal.cpp中的方法:legacy_ap_dev_open,生成了legacy_ap_device。rc = audio_policy_dev_open(module, &mpAudioPolicyDev);//通过mpAudioPolicyDev,也即是legacy_ap_device产生一个策略,具体实现在audio_policy_hal.cpp中的create_legacy_ap方法中,create_legacy_ap函数中先生成了一个legacy_audio_policy对象,mpAudioPolicy对应就是这个legacy_audio_policy中的policy。下面会列出legacy_audio_policy的结构。rc = mpAudioPolicyDev->create_audio_policy(mpAudioPolicyDev, &aps_ops, this,&mpAudioPolicy);}
legacy_audio_policy的结构,除了对应mpAudioPolicy的policy外,还有几个成员变量。
struct legacy_audio_policy { struct audio_policy policy; void *service; struct audio_policy_service_ops *aps_ops; AudioPolicyCompatClient *service_client; AudioPolicyInterface *apm;};
上面结构体的aps_ops变量,是有audiopolicyservice提供的函数指针,其中的函数集合是AudiopolicyService与外界沟通的桥梁,也即是下面的aps_ops。
struct audio_policy_service_ops aps_ops = { .open_output = aps_open_output, .open_duplicate_output = aps_open_dup_output, .close_output = aps_close_output, .suspend_output = aps_suspend_output, .restore_output = aps_restore_output, .open_input = aps_open_input, .close_input = aps_close_input, .set_stream_volume = aps_set_stream_volume, .invalidate_stream = aps_invalidate_stream, .set_parameters = aps_set_parameters, .get_parameters = aps_get_parameters, .start_tone = aps_start_tone, .stop_tone = aps_stop_tone, .set_voice_volume = aps_set_voice_volume, .move_effects = aps_move_effects, .load_hw_module = aps_load_hw_module, .open_output_on_module = aps_open_output_on_module, .open_input_on_module = aps_open_input_on_module, };
legacy_audio_policy结构体中的apm是AudioPolicyManager的缩写,AudioPolicyInterface是其基类,默认的实现是一个AudioPolicyManagerDefault对象,实现如下:
static int create_legacy_ap ()@audio_policy_hal.cpp{lap->apm = createAudioPolicyManager(lap->service_client);}AudioPolicyInterface* createAudioPolicyManager ()@AudioPolicyManagerDefault.cpp{return new AudioPolicyManagerDefault(clientInterface);}
相关类的关系图
从上图看:
AudioPolicyService持有一个类似接口类audio_policy的对象,也就是说audiopolicyservice与audio_policy之间的接口是固定不变的,但是audio_policy的内部实现有具体的厂商自由定制。
从audio_policy.h看,audio_policy是一个结构体,内部是各种函数指针,这些函数指针在初始化时,指向具体的函数实现,就对应了audio_policy_hal.cpp中的实现函数。在create_legacy_ap中有对函数指针的赋值:
audio_policy_hal.cpp
static int create_legacy_ap(const struct audio_policy_device *device,struct audio_policy_service_ops *aps_ops, void *service, struct audio_policy **ap){struct legacy_audio_policy *lap;lap->policy.set_ringer_mode = ap_set_ringer_mode;lap->policy.init_check = ap_init_check;lap->policy.get_output = ap_get_output;lap->policy.init_stream_volume = ap_init_stream_volume;……}
还是看上面的图,提到很多数据类型,那么谁去实现这些数据类型呢?就是AudioPolicyManager,与其相关的类有:AudioPolicyInterface是其基类,AudioPolicyManagerBase实现了一些基础的策略,AudioPolicyManagerDefault是最终的实现类。
AudioPolicyService什么时候会通过AudioFlinger去加载音频设备呢?
除了动态加载外,一个重要的途径是通过AudioPolicyManagerDefault的父类,及AudioPolicyManagerBase的构造函数来加载音频设备。
前面分析过,AudioPolicyService的启动过程中(onFirstRef),会创建一个mpAudioPolicyDev(audio_policy_device结构体类型),然后通过这个mpAudioPolicyDev创建一个策略(create_audio_policy),create_audio_policy实际的实现是audio_policy_hal.cpp中的create_legacy_ap函数,创建的音频策略就是legacy_audio_policy结构类型中的变量policy(audio_policy),这个legacy_audio_policy结构体中还有一个变量AudioPolicyInterface *apm,它通过函数createAudioPolicyManager被初始化为了AudioPolicyManagerDefault。
audio_policy_hal.cpp
static int create_legacy_ap(const struct audio_policy_device *device, struct audio_policy_service_ops *aps_ops, void *service, struct audio_policy **ap){struct legacy_audio_policy *lap;lap->service_client =new AudioPolicyCompatClient(aps_ops, service);lap->apm = createAudioPolicyManager(lap->service_client);*ap = &lap->policy;}
接着看AudioPolicyManagerBase的构造函数:
AudioPolicyManagerBase.cppAudioPolicyManagerBase::AudioPolicyManagerBase(AudioPolicyClientInterface *clientInterface){mpClientInterface = clientInterface;//这里加载解析配置文件(audio_policy.conf),如果配置文件不存在,就是使用默认配置。//配置文件的信息,当前设备支持的audio interface,及每一种audio interface的属性,每一种audio interface都有outputs,inputs,在这其中有具体的属性:如支持的采样率,formats,支持哪些音频设备等。 if (loadAudioPolicyConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE) != NO_ERROR) { if (loadAudioPolicyConfig(AUDIO_POLICY_CONFIG_FILE) != NO_ERROR) { defaultAudioPolicyConfig(); }}//打开这些音频设备,for (size_t i = 0; i < mHwModules.size(); i++) {mHwModules[i]->mHandle =mpClientInterface->loadHwModule(mHwModules[i]->mName);//打开这些设备中的outputs。for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++){audio_io_handle_t output = mpClientInterface->openOutput(outProfile->mModule->mHandle,&outputDesc->mDevice,&outputDesc->mSamplingRate,&outputDesc->mFormat, &outputDesc->mChannelMask,&outputDesc->mLatency,outputDesc->mFlags);}}}
音频策略的执行者是AudioFlinger,所以它也是打开这些音频设备的执行者。接下来看下,怎么转到AudioFlinger那边的?
上面AudioPolicyManagerBase的构造函数中第一行初始化了变量AudioPolicyClientInterface*mpClientInterface;回溯下,这个变量的来源:
AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)@ AudioPolicyManagerDefault.cpp{ return new AudioPolicyManagerDefault(clientInterface);}
继续向上回溯:
static int create_legacy_ap(const struct audio_policy_device *device, struct audio_policy_service_ops *aps_ops, void *service, struct audio_policy **ap)@ audio_policy_hal.cpp{lap->service_client =new AudioPolicyCompatClient(aps_ops, service);lap->apm = createAudioPolicyManager(lap->service_client);}
从上面的调用看出,AudioPolicyManagerBase构造函数中的clientInterface就是lap->service_client,也即是AudioPolicyCompatClient对象,而AudioPolicyCompatClient构造函数中的serviceOps 来自于aps_ops,aps_ops的根在AudioPolicyService那里:
void AudioPolicyService::onFirstRef()@AudioPolicyService.cpp{rc = mpAudioPolicyDev->create_audio_policy(mpAudioPolicyDev, &aps_ops, this,&mpAudioPolicy)}
就是上面调用create_audio_policy的第二个参数。
所以,在AudioPolicyManagerBase构造汉中的调用:mpClientInterface->loadHwModule(…),实际调用的是:aps_ops->load_hw_module(…);
看下aps_ops这个struct中的指针指向:
AudioPolicyService.cpp
struct audio_policy_service_ops aps_ops = { .open_output = aps_open_output, .open_duplicate_output = aps_open_dup_output, .close_output = aps_close_output, .suspend_output = aps_suspend_output, .restore_output = aps_restore_output, .open_input = aps_open_input, .close_input = aps_close_input, .set_stream_volume = aps_set_stream_volume, .invalidate_stream = aps_invalidate_stream, .set_parameters = aps_set_parameters, .get_parameters = aps_get_parameters, .start_tone = aps_start_tone, .stop_tone = aps_stop_tone, .set_voice_volume = aps_set_voice_volume, .move_effects = aps_move_effects, .load_hw_module = aps_load_hw_module, .open_output_on_module = aps_open_output_on_module, .open_input_on_module = aps_open_input_on_module,};
其中的load_hw_module指向aps_load_hw_module。aps_load_hw_module的实现在:
AudioPolicyClientImplLegacy.cpp
audio_module_handle_t aps_load_hw_module(void *service __unused, const char *name){ sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); return af->loadHwModule(name);}
这样就转到了AudioFlinger,其他的函数指针也是一样的,如:open_output。AudioFlinger中函数的实现前分析过了。
- Android音频子系统,AudioPolicyService(三)
- Android音频子系统,Audiopolicyservice音频策略的制定(五)
- 深入剖析Android音频(三)AudioPolicyService
- Android音频子系统,音频流(六)
- android 音频管理:AudioPolicyService 和 AudioPolicyManager
- android 音频管理:AudioPolicyService 和 AudioPolicyManager
- 深入剖析Android音频之AudioPolicyService
- 深入剖析Android音频之AudioPolicyService
- 深入剖析Android音频之AudioPolicyService
- 【转】深入剖析Android音频之AudioPolicyService
- 深入剖析Android音频之AudioPolicyService
- android 音频子系统框架(一)
- android 音频子系统-AudioFlinger(二)
- Android音频子系统,音频流的回放(四)
- Android-AudioPolicyService
- Android 音频子系统简要介绍
- Android音频子系统,音量的调节控制(七)
- 【Android Audio】Android Audio System 之三: AudioPolicyService 和 AudioPolicyManager
- 营销运营思维导图
- 一个快速获取/更新 Let's encrypt 证书的 shell script
- HTML文字波浪形移动和复原
- Spring Aop简单理解
- XTabLayout.setOnTabSelectedListener不切换fragment
- Android音频子系统,AudioPolicyService(三)
- 数据结构实验之图论二:图的深度遍历
- BottomSheetBehavior底部弹出的用法
- java类加载时机与过程
- 11月14日笔记及心得
- 一、Python编码问题
- oracle定时运行存储过程
- 天天开心
- 他为什么放弃五年专业所学转行到传智播客郑州校区学编程