该系列文章总纲链接:专题分纲目录 Android Framework 音频子系统
本章关键点总结 & 说明:
本章节主要关注➕ 以上思维导图左上 AudioFlinger启动分析 部分 即可。主要是对 AudioFlinger启动的分析,涉及从AudioFlinger启动到Audio构造器执行结束、AudioFlinger的loadHwModule分析(HAL操作)、AudioFlinger的openOutput实现(创建MixerThread),同时承接了上一节的部分流程分析。
1 从AudioFlinger启动到Audio构造器执行结束
AudioFlinger的启动是在Main_mediaserver.cpp中实现,代码如下:
int main(int argc __unused, char** argv)
{
signal(SIGPIPE, SIG_IGN);
char value[PROPERTY_VALUE_MAX];
//...
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
//...
AudioFlinger::instantiate();//AudioFlinger
MediaPlayerService::instantiate();
CameraService::instantiate();
AudioPolicyService::instantiate();//AudioPolicyService
SoundTriggerHwService::instantiate();
registerExtensions();
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
//...
}
这里专注分析AudioFlinger::instantiate()的实现,代码如下:
static void instantiate() { publish(); }
继续分析publish,代码如下:
static status_t publish(bool allowIsolated = false) {
sp<IServiceManager> sm(defaultServiceManager());
return sm->addService(//注册服务到servicemanager中
String16(SERVICE::getServiceName()),
new SERVICE(), allowIsolated);
}
这里将服务注册到service_manager 中。同时这里会 创建 一个AudioFlinger,即执行AudioFlinger的构造器,代码如下:
AudioFlinger::AudioFlinger()
: BnAudioFlinger(),
mPrimaryHardwareDev(NULL),
//...
mGlobalEffectEnableTime(0),
mPrimaryOutputSampleRate(0)
{
getpid_cached = getpid();
char value[PROPERTY_VALUE_MAX];
//...
}
主要是一些变量的初始化,之后主要看onFirstRef的实现,代码如下:
void AudioFlinger::onFirstRef()
{
int rc = 0;
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);
} else {
mStandbyTimeInNsecs = kDefaultStandbyTimeInNsecs;
}
}
//这里将AudioFlinger传递给PatchPanel,其他并没有做什么
mPatchPanel = new PatchPanel(this);
mMode = AUDIO_MODE_NORMAL;
}
经过上面的分析可以知道,AudioFlinger注册服务后 还是很被动的,并不会主动创建线程和执行操作。之后便一直等待被调用。这里基于上一章节的loadHwModule 和 openOutput 进行分析。
2 AudioFlinger的loadHwModule分析
这里继续上一章节af->loadHwModule(name);进行分析,AudioFlinger的loadHwModle代码实现如下:
audio_module_handle_t AudioFlinger::loadHwModule(const char *name)
{
if (name == NULL) {
return 0;
}
if (!settingsAllowed()) {
return 0;
}
Mutex::Autolock _l(mLock);
return loadHwModule_l(name);
}
这里继续分析loadHwModule_l,代码实现如下:
// loadHwModule_l() must be called with AudioFlinger::mLock held
audio_module_handle_t AudioFlinger::loadHwModule_l(const char *name)
{
//是否已经加载过这个interface
for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
if (strncmp(mAudioHwDevs.valueAt(i)->moduleName(), name, strlen(name)) == 0) {
ALOGW("loadHwModule() module %s already loaded", name);
return mAudioHwDevs.keyAt(i);
}
}
audio_hw_device_t *dev;
//关键点:打开audio.primary.XXX.so,构造audio_hw_device
int rc = load_audio_interface(name, &dev);
//...
mHardwareStatus = AUDIO_HW_INIT;
//初始化
rc = dev->init_check(dev);
mHardwareStatus = AUDIO_HW_IDLE;
AudioHwDevice::Flags flags = static_cast<AudioHwDevice::Flags>(0);
//...
audio_module_handle_t handle = nextUniqueId();
//通过dev构建AudioHwDevice,将AudioHwDevice加入到mAudioHwDevs中
mAudioHwDevs.add(handle, new AudioHwDevice(handle, name, dev, flags));
return handle;
}
这里继续分析load_audio_interface,代码实现如下:
static int load_audio_interface(const char *if_name, audio_hw_device_t **dev)
{
const hw_module_t *mod;
int rc;
//通过hw_get_module_by_class->load->dlopen->dlsym->dlclose)
//获得第三方厂家库的hw_module_t结构体指针 &mod
rc = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, if_name, &mod);
//...
//通过&mod构建audio_hw_device_t类型结构体 dev
rc = audio_hw_device_open(mod, dev);
//...
}
这里总结下 loadHwModule对硬件的封装:
- AudioFlinger : AudioHwDevice (放入mAudioHwDevs数组中)
- audio_hw_hal.cpp : audio_hw_device
- 厂家 : AudioHardware (派生自: AudioHardwareInterface)
- AudioHwDevice :对audio_hw_device的封装,
- audio_hw_device :函数的实现要通过AudioHardware类对象
3 AudioFlinger的openOutput实现
这里继续上一章节af->openOutput(module, output, config, devices, address, latencyMs, flags);进行分析,AudioFlinger的openOutput代码实现如下:
status_t AudioFlinger::openOutput(audio_module_handle_t module,
audio_io_handle_t *output,
audio_config_t *config,
audio_devices_t *devices,
const String8& address,
uint32_t *latencyMs,
audio_output_flags_t flags)
{
//...
Mutex::Autolock _l(mLock);
//关键点
sp<PlaybackThread> thread = openOutput_l(module, output, config, *devices, address, flags);
if (thread != 0) {
*latencyMs = thread->latency();
// notify client processes of the new output creation
thread->audioConfigChanged(AudioSystem::OUTPUT_OPENED);
// the first primary output opened designates the primary hw device
if ((mPrimaryHardwareDev == NULL) && (flags & AUDIO_OUTPUT_FLAG_PRIMARY)) {
ALOGI("Using module %d has the primary audio interface", module);
mPrimaryHardwareDev = thread->getOutput()->audioHwDev;
AutoMutex lock(mHardwareLock);
mHardwareStatus = AUDIO_HW_SET_MODE;
mPrimaryHardwareDev->hwDevice()->set_mode(mPrimaryHardwareDev->hwDevice(), mMode);
mHardwareStatus = AUDIO_HW_IDLE;
mPrimaryOutputSampleRate = config->sample_rate;
}
return NO_ERROR;
}
return NO_INIT;
}
这里专注openOutput_l的实现,代码如下:
sp<AudioFlinger::PlaybackThread> AudioFlinger::openOutput_l(audio_module_handle_t module,
audio_io_handle_t *output,
audio_config_t *config,
audio_devices_t devices,
const String8& address,
audio_output_flags_t flags)
{
//查找相应的audio interface
AudioHwDevice *outHwDev = findSuitableHwDev_l(module, devices);
//...
audio_hw_device_t *hwDevHal = outHwDev->hwDevice();
if (*output == AUDIO_IO_HANDLE_NONE) {
*output = nextUniqueId();
}
mHardwareStatus = AUDIO_HW_OUTPUT_OPEN;
audio_stream_out_t *outStream = NULL;
//对于每个module中每一个output profile,
//如果flags不是特殊的则执行open_output_stream
status_t status = hwDevHal->open_output_stream(hwDevHal,
*output,
devices,
flags,
config,
&outStream,
address.string());
mHardwareStatus = AUDIO_HW_IDLE;
//创建playbackThread
if (status == NO_ERROR && outStream != NULL) {
AudioStreamOut *outputStream = new AudioStreamOut(outHwDev, outStream, flags);
PlaybackThread *thread;
if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
thread = new OffloadThread(this, outputStream, *output, devices);
} else if ((flags & AUDIO_OUTPUT_FLAG_DIRECT)
|| !isValidPcmSinkFormat(config->format)
|| !isValidPcmSinkChannelMask(config->channel_mask)) {
thread = new DirectOutputThread(this, outputStream, *output, devices);
} else {
//一般是创建混音线程,代表AudioStreamOut对象的output也传递进去了
thread = new MixerThread(this, outputStream, *output, devices);
}
//将创建的线程添加到播放线程列表 mPlaybackThreads中
mPlaybackThreads.add(*output, thread);
return thread;
}
return 0;
}
这里最关键的是创建了一个MixerThread。这里的每一个线程都对应一个output。