基于Android 9.0
1.概述
在《Android 音频子系统--03:从开机到audioserver启动》章节中,分析的audioserver启动过程中,audioserver的main()方法中会启动音频框架中两大服务:AudioFlinger和AudioPolicyService,这章将继续从启动AudioFlinger服务开始,分析AudioFlinger相关的流程。
本章节关注上面思维导图即可。主要是对AudioFlinger启动的分析,涉及从AudioFlinger启动到Audio构造器执行结束、AudioFlinger的loadHwModule分析(HAL操作)、AudioFlinger的openOutput实现(创建MixerThread),。
2.初始化
AudioFinger和AudioPolicyService一样在main_audioserver.cpp中启动,流程上基本一样。会创建一个AudioFinger并将其注册到service_manager中,然后会执行onFirstRef做一些初始化工作。
// frameworks/av/media/audioserver/main_audioserver.cpp
int main(int argc __unused, char **argv)
{
// ......
android::hardware::configureRpcThreadpool(4, false /*callerWillJoin*/);
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
ALOGI("ServiceManager: %p", sm.get());
AudioFlinger::instantiate(); // 启动AudioFlinger
AudioPolicyService::instantiate(); // 启动AudioPolicyService
// .....
}
这里专注分析AudioFlinger::instantiate()的实现,代码如下:
// frameworks/native/include/binder/BinderService.h
static void instantiate() { publish(); }
继续分析publish,代码如下:
// frameworks/native/libs/binder/include/binder/BinderService.h
static status_t publish(bool allowIsolated = false,
int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {
sp<IServiceManager> sm(defaultServiceManager());
return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated,
dumpFlags);//注册服务到servicemanager中
}
这里会创建 一个AudioFlinger,并将该服务注册到service_manager 中。创建服务会执行AudioFlinger的构造器,代码如下:
// frameworks/av/services/audioflinger/AudioFlinger.cpp
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),
mTotalMemory(0),
// Clitent对应的内存大小,一个应用一个Clitent许多个AudioTrack的和AudioFlinger内存共享从这里分配
mClientSharedHeapSize(kMinimumClientSharedHeapSizeBytes),
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();
mDevicesFactoryHal = DevicesFactoryHalInterface::create();
mEffectsFactoryHal = EffectsFactoryHalInterface::create();
mMediaLogNotifier->run("MediaLogNotifier");
}
主要是一些变量的初始化,之后主要看onFirstRef的实现,代码如下:
// frameworks/av/services/audioflinger/AudioFlinger.cpp
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;
// 这里只是将AudioFlinger对象传递给了gAudioFlinger
gAudioFlinger = this;
}
经过上面的分析可以知道,AudioFlinger注册服务后还是很被动的,并不会主动创建线程和执行操作。之后便一直等待被调用。这里基于上一章节的loadHwModule和openOutput 进行分析。
3.AudioFlinger的loadHwModule分析
这里继续上一章节af->loadHwModule(name);进行分析,AudioFlinger的loadHwModle代码实现如下:
// frameworks/av/services/audioflinger/AudioFlinger.cpp
audio_module_handle_t AudioFlinger::loadHwModule(const char *name)
{
if (name == NULL) {
return AUDIO_MODULE_HANDLE_NONE;
}
if (!settingsAllowed()) {
return AUDIO_MODULE_HANDLE_NONE;
}
Mutex::Autolock _l(mLock);
return loadHwModule_l(name);
}
这里继续分析loadHwModule_l,代码实现如下:
// frameworks/av/services/audioflinger/AudioFlinger.cpp
audio_module_handle_t AudioFlinger::loadHwModule_l(const char *name)
{
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);
}
}
sp<DeviceHalInterface> dev;
//关键点:打开audio.primary.XXX.so,构造audio_hw_device
int rc = mDevicesFactoryHal->openDevice(name, &dev);
if (rc) {
ALOGE("loadHwModule() error %d loading module %s", rc, name);
return AUDIO_MODULE_HANDLE_NONE;
}
mHardwareStatus = AUDIO_HW_INIT;
//初始化
rc = dev->initCheck();
mHardwareStatus = AUDIO_HW_IDLE;
// ......
audio_module_handle_t handle = (audio_module_handle_t) nextUniqueId(AUDIO_UNIQUE_ID_USE_MODULE);
//通过dev构建AudioHwDevice,将AudioHwDevice加入到mAudioHwDevs中
mAudioHwDevs.add(handle, new AudioHwDevice(handle, name, dev, flags));
ALOGI("loadHwModule() Loaded %s audio interface, handle %d", name, handle);
return handle;
}
这里继续分析openDevice()方法,代码实现如下:
// frameworks/av/media/libaudiohal/DevicesFactoryHalHybrid.cpp
status_t DevicesFactoryHalHybrid::openDevice(const char *name, sp<DeviceHalInterface> *device) {
if (mHidlFactory != 0 && strcmp(AUDIO_HARDWARE_MODULE_ID_A2DP, name) != 0 &&
strcmp(AUDIO_HARDWARE_MODULE_ID_HEARING_AID, name) != 0) {
return mHidlFactory->openDevice(name, device);
}
return mLocalFactory->openDevice(name, device);
}
继续分析一下mLocalFactory->openDevice,代码实现如下:
// frameworks/av/media/libaudiohal/DevicesFactoryHalLocal.cpp
status_t DevicesFactoryHalLocal::openDevice(const char *name, sp<DeviceHalInterface> *device) {
audio_hw_device_t *dev;
status_t rc = load_audio_interface(name, &dev);
if (rc == OK) {
*device = new DeviceHalLocal(dev);
}
return rc;
}
继续看一下load_audio_interface,代码实现:
// frameworks/av/media/libaudiohal/DevicesFactoryHalLocal.cpp
static status_t 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);
if (rc) {
ALOGE("%s couldn't load audio hw module %s.%s (%s)", __func__,
AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc));
goto out;
}
//通过&mod构建audio_hw_device_t类型结构体 dev
rc = audio_hw_device_open(mod, dev);
if (rc) {
ALOGE("%s couldn't open audio hw device in %s.%s (%s)", __func__,
AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc));
goto out;
}
if ((*dev)->common.version < AUDIO_DEVICE_API_VERSION_MIN) {
ALOGE("%s wrong audio hw device version %04x", __func__, (*dev)->common.version);
rc = BAD_VALUE;
audio_hw_device_close(*dev);
goto out;
}
return OK;
out:
*dev = NULL;
return rc;
}
继续分析audio_hw_device_open()方法,代码实现如下:
// hardware/libhardware/include/hardware/audio.h
static inline int audio_hw_device_open(const struct hw_module_t* module,
struct audio_hw_device** device)
{
return module->methods->open(module, AUDIO_HARDWARE_INTERFACE,
TO_HW_DEVICE_T_OPEN(device));
}
这里会调用到了HAL层的legacy_adev_open方法,代码实现如下:
// hardware/libhardware_legacy/audio/audio_hw_hal.cpp
static int legacy_adev_open(const hw_module_t* module, const char* name,
hw_device_t** device)
{
struct legacy_audio_device *ladev;
int ret;
if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
return -EINVAL;
ladev = (struct legacy_audio_device *)calloc(1, sizeof(*ladev));
if (!ladev)
return -ENOMEM;
//结构体赋值
ladev->device.common.tag = HARDWARE_DEVICE_TAG;
ladev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
ladev->device.common.module = const_cast<hw_module_t*>(module);
ladev->device.common.close = legacy_adev_close;
ladev->device.init_check = adev_init_check;
ladev->device.set_voice_volume = adev_set_voice_volume;
ladev->device.set_master_volume = adev_set_master_volume;
ladev->device.get_master_volume = adev_get_master_volume;
ladev->device.set_mode = adev_set_mode;
ladev->device.set_mic_mute = adev_set_mic_mute;
ladev->device.get_mic_mute = adev_get_mic_mute;
ladev->device.set_parameters = adev_set_parameters;
ladev->device.get_parameters = adev_get_parameters;
ladev->device.get_input_buffer_size = adev_get_input_buffer_size;
ladev->device.open_output_stream = adev_open_output_stream;
ladev->device.close_output_stream = adev_close_output_stream;
ladev->device.open_input_stream = adev_open_input_stream;
ladev->device.close_input_stream = adev_close_input_stream;
ladev->device.dump = adev_dump;
/* 关键点:
* audio_hw_device_t结构体 和 hwif(hardwareInterface)接口之间建立联系
* 这里通过createAudioHardware 获取 实现hardwareInterface接口的厂商指针
* 后面调用hwif的相关操作 <=等价=> 使用厂商的库函数中的方法
*/
ladev->hwif = createAudioHardware();
if (!ladev->hwif) {
ret = -EIO;
goto err_create_audio_hw;
}
*device = &ladev->device.common;
return 0;
err_create_audio_hw:
free(ladev);
return ret;
}
这里总结下 loadHwModule对硬件的封装:
- AudioFlinger: AudioHwDevice (放入mAudioHwDevs数组中);
- audio_hw_hal.cpp:audio_hw_device;
- 厂家: AudioHardware (派生自: AudioHardwareInterface);
- AudioHwDevice: 对audio_hw_device的封装;
- audio_hw_device: 函数的实现要通过AudioHardware类对象。
4.AudioFlinger的openOutput实现
这里继续上一章节af->openOutput(module, output, config, devices, address, latencyMs, flags);进行分析,AudioFlinger的openOutput代码实现如下:
// frameworks/av/services/audioflinger/AudioFlinger.cpp
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)
{
ALOGI("openOutput() this %p, module %d Device %#x, SamplingRate %d, Format %#08x, "
"Channels %#x, flags %#x",
this, module,
(devices != NULL) ? *devices : 0,
config->sample_rate,
config->format,
config->channel_mask,
flags);
if (devices == NULL || *devices == AUDIO_DEVICE_NONE) {
return BAD_VALUE;
}
Mutex::Autolock _l(mLock);
//关键点
sp<ThreadBase> thread = openOutput_l(module, output, config, *devices, address, flags);
if (thread != 0) {
if ((flags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) == 0) {
PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
*latencyMs = playbackThread->latency();
// notify client processes of the new output creation
playbackThread->ioConfigChanged(AUDIO_OUTPUT_OPENED);
// the first primary output opened designates the primary hw device
if ((mPrimaryHardwareDev == NULL) && (flags & AUDIO_OUTPUT_FLAG_PRIMARY)) {
ALOGI("Using module %d as the primary audio interface", module);
mPrimaryHardwareDev = playbackThread->getOutput()->audioHwDev;
AutoMutex lock(mHardwareLock);
mHardwareStatus = AUDIO_HW_SET_MODE;
mPrimaryHardwareDev->hwDevice()->setMode(mMode);
mHardwareStatus = AUDIO_HW_IDLE;
}
} else {
MmapThread *mmapThread = (MmapThread *)thread.get();
mmapThread->ioConfigChanged(AUDIO_OUTPUT_OPENED);
}
return NO_ERROR;
}
return NO_INIT;
}
这里专注openOutput_l的实现,代码如下:
// frameworks/av/services/audioflinger/AudioFlinger.cpp
sp<AudioFlinger::ThreadBase> 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);
if (outHwDev == NULL) {
return 0;
}
if (*output == AUDIO_IO_HANDLE_NONE) {
*output = nextUniqueId(AUDIO_UNIQUE_ID_USE_OUTPUT);
} else {
// Audio Policy does not currently request a specific output handle.
// If this is ever needed, see openInput_l() for example code.
ALOGE("openOutput_l requested output handle %d is not AUDIO_IO_HANDLE_NONE", *output);
return 0;
}
mHardwareStatus = AUDIO_HW_OUTPUT_OPEN;
// ......
//对于每个module中每一个output profile,
//如果flags不是特殊的则执行openOutputStream
AudioStreamOut *outputStream = NULL;
status_t status = outHwDev->openOutputStream(
&outputStream,
*output,
devices,
flags,
config,
address.string());
mHardwareStatus = AUDIO_HW_IDLE;
//创建playbackThread
if (status == NO_ERROR) {
if (flags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) {
sp<MmapPlaybackThread> thread =
new MmapPlaybackThread(this, *output, outHwDev, outputStream,
devices, AUDIO_DEVICE_NONE, mSystemReady);
mMmapThreads.add(*output, thread);
ALOGV("openOutput_l() created mmap playback thread: ID %d thread %p",
*output, thread.get());
return thread;
} else {
sp<PlaybackThread> thread;
if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
thread = new OffloadThread(this, outputStream, *output, devices, mSystemReady);
ALOGV("openOutput_l() created offload output: ID %d thread %p",
*output, thread.get());
} else if ((flags & AUDIO_OUTPUT_FLAG_DIRECT)
|| !isValidPcmSinkFormat(config->format)
|| !isValidPcmSinkChannelMask(config->channel_mask)) {
thread = new DirectOutputThread(this, outputStream, *output, devices, mSystemReady);
ALOGV("openOutput_l() created direct output: ID %d thread %p",
*output, thread.get());
} else {
//一般是创建混音线程,代表AudioStreamOut对象的output也传递进去了
thread = new MixerThread(this, outputStream, *output, devices, mSystemReady);
ALOGV("openOutput_l() created mixer output: ID %d thread %p",
*output, thread.get());
}
//将创建的线程添加到播放线程列表 mPlaybackThreads中
mPlaybackThreads.add(*output, thread);
mPatchPanel.notifyStreamOpened(outHwDev, *output);
return thread;
}
}
return 0;
}
这里最关键的是创建了一个MixerThread。这里的每一个线程都对应一个output。