概述
1. audioflinger创建过程
在Android8.0的音频系统中,AudioFlinger是一个C++的Binder服务,运行在HAL进程中,它是在audioserver.c
//frameworks/av/media/audioserver/audioserver.rc
service audioserver /system/bin/audioserver
class main
user audioserver
# media gid needed for /dev/fm (radio) and for /data/misc/media (tee)
group audio camera drmrpc inet media mediadrm net_bt net_bt_admin net_bw_acct oem_2901
ioprio rt 4
writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks
onrestart restart audio-hal-2-0
on property:vts.native_server.on=1
stop audioserver
on property:vts.native_server.on=0
start audioserver
audioserver的入口函数是main(),代码如下:
int main(int argc __unused, char **argv)
{
......
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
ALOGI("ServiceManager: %p", sm.get());
AudioFlinger::instantiate(); //创建AudioFlinger服务
AudioPolicyService::instantiate(); //创建AudioPolicyService服务
AAudioService::instantiate(); //创建AAudioService服务
RadioService::instantiate(); //创建RadioService服务
SoundTriggerHwService::instantiate();
#ifdef VRAUDIOSERVICE_ENABLE
VRAudioServiceNative::instantiate();
#endif
ProcessState::self()->startThreadPool();
// FIXME: remove when BUG 31748996 is fixed
android::hardware::ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
AudioFlinger::instantiate()并不属于AudioFlinger的内部类,而是BinderService类的一个实现包括AudioFlinger,AudioPolicy等在内的几个服务都继承自这个统一的Binder的服务类,具体实现在BinderService.h中
// frameworks/native/include/binder/BinderService.h
static status_t publish(bool allowIsolated = false) {
sp<IServiceManager> sm(defaultServiceManager());
//SERVICE是文件中定义的一个模板,AudioFlinger调用了instantiate()函数,
//所以当前的SERVICE为AudioFlinger
return sm->addService(
String16(SERVICE::getServiceName()),
new SERVICE(), allowIsolated);
}
static void instantiate() { publish(); }
可以看出publish()函数所做的事获取到ServiceManager的代理,然后new一个调用instantiate的那个service的对象并把它添加到ServiceManager中。
所以下一步就是去分析AudioFlinger的构造函数了
AudioFlinger::AudioFlinger()
: BnAudioFlinger(),
mMediaLogNotifier(new AudioFlinger::MediaLogNotifier()),
mPrimaryHardwareDev(NULL),
mAudioHwDevs(NULL),
mHardwareStatus(AUDIO_HW_IDLE),
mMasterVolume(1.0f),
mMasterMute(false),
// mNextUniqueId(AUDIO_UNIQUE_ID_USE_MAX),
mMode(AUDIO_MODE_INVALID),
mBtNrecIsOff(false),
mIsLowRamDevice(true),
mIsDeviceTypeKnown(false),
mGlobalEffectEnableTime(0),
mSystemReady(false)
{
// unsigned instead of audio_unique_id_use_t, because ++ operator is unavailable for enum
for (unsigned use = AUDIO_UNIQUE_ID_USE_UNSPECIFIED; use < AUDIO_UNIQUE_ID_USE_MAX; use++) {
// zero ID has a special meaning, so unavailable
mNextUniqueIds[use] = AUDIO_UNIQUE_ID_USE_MAX;
}
getpid_cached = getpid();
const bool doLog = property_get_bool("ro.test_harness", false);
if (doLog) {
mLogMemoryDealer = new MemoryDealer(kLogMemorySize, "LogWriters",
MemoryHeapBase::READ_ONLY);
(void) pthread_once(&sMediaLogOnce, sMediaLogInit);
}
// 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();
//创建设备HAL层接口,用于hidl绑定
mDevicesFactoryHal = DevicesFactoryHalInterface::create();
//创建效果HAL层接口,用于hidl绑定
mEffectsFactoryHal = EffectsFactoryHalInterface::create();
mMediaLogNotifier->run("MediaLogNotifier");
}
1.1 DevicesFactoryHalInterface
sp<DevicesFactoryHalInterface> DevicesFactoryHalInterface::create() {
return new DevicesFactoryHalHybrid();
}
DevicesFactoryHalHybrid::DevicesFactoryHalHybrid()
: mLocalFactory(new DevicesFactoryHalLocal()),
mHidlFactory(
#ifdef USE_LEGACY_LOCAL_AUDIO_HAL
nullptr
#else
new DevicesFactoryHalHidl()
#endif
) {
}
DevicesFactoryHalHybrid::~DevicesFactoryHalHybrid() {
}
1.2 EffectsFactoryHalInterface
sp<EffectsFactoryHalInterface> EffectsFactoryHalInterface::create() {
return new EffectsFactoryHalHidl();
}
EffectsFactoryHalHidl::EffectsFactoryHalHidl() : ConversionHelperHidl("EffectsFactory") {
mEffectsFactory = IEffectsFactory::getService();
if (mEffectsFactory == 0) {
ALOGE("Failed to obtain IEffectsFactory service, terminating process.");
exit(1);
}
}
接下来再看看它的onFirstRef()函数。
void AudioFlinger::onFirstRef()
{
Mutex::Autolock _l(mLock);
/* TODO: move all this work into an Init() function */
char val_str[PROPERTY_VALUE_MAX] = { 0 };
if (property_get("ro.audio.flinger_standbytime_ms", val_str, NULL) >= 0) {
uint32_t int_val;
if (1 == sscanf(val_str, "%u", &int_val)) {
mStandbyTimeInNsecs = milliseconds(int_val);
ALOGI("Using %u mSec as standby time.", int_val);
} else {
mStandbyTimeInNsecs = kDefaultStandbyTimeInNsecs;
ALOGI("Using default %u mSec as standby time.",
(uint32_t)(mStandbyTimeInNsecs / 1000000));
}
}
mPatchPanel = new PatchPanel(this);
mMode = AUDIO_MODE_NORMAL;
gAudioFlinger = this;
}
onFirstRef()函数也很简单,仅仅读取属性"ro.audio.flinger_standbytime_ms"的值并赋给变量mStandbyTimeInNsecs ,若这个属性没有设置,则使用默认值kDefaultStandbyTimeInNsecs。
2. audioflinger中的线程关系图
PlaybackThread和RecordThread分别用于播放与录音。PlaybackThread中派生出DirectOutputThread与MixerThread。AudioFlinger中创建的播放线程大都是MixerThread,用于混合多路声音输出,而DirectOutputThread用于将声音直接发送给底层播放,不需要混音处理。
DuplicatingThread用于将声音同时输出到蓝牙设备和其他设备,因为蓝牙设备和其他设备的连接是分开的,所以输出蓝牙音频数据需要一条单独的通道,而输出到DSP的数据也需要一条单独的通道。
3.小结
本文旨在介绍一下audioflinger的启动过程及它包含线程之间的关系。具体audioflinger是如何工作的?后面会深入的一步步分析。下一篇将会先介绍audiopolicyservice以及它如何关联audioflinger等等,未完待续。。。
最后
以上就是平常小土豆为你收集整理的AndroidO audio系统之audioflinger启动分析(二)的全部内容,希望文章能够帮你解决AndroidO audio系统之audioflinger启动分析(二)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复