AF/APF启动流程
在启动AudioSeriver服务的过程中会对启动AF/APF。main_audioserver.cpp有如下代码:
cpp
AudioFlinger::instantiate();
AudioPolicyService::instantiate();
AF初始化流程
1.AudioFlinger::instantiate()
1.1 AudioFlinger构造函数
cpp
void AudioFlinger::instantiate() {
sp<IServiceManager> sm(defaultServiceManager());
sm->addService(String16(IAudioFlinger::DEFAULT_SERVICE_NAME),
new AudioFlingerServerAdapter(new AudioFlinger()), false,
IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT);
}
创建AudioFlingerServerAdapter对象,然后将AudioFlinger对象传入在AudioFlingerr中会调用onFirstRef
()函数。
cpp
AudioFlinger::AudioFlinger() {
mDevicesFactoryHal = DevicesFactoryHalInterface::create();
mEffectsFactoryHal = EffectsFactoryHalInterface::create();
}
在AudioFlinger的构造函数中会创建DevicesFactoryHalInterface和EffectsFactoryHalInterface对象,DevicesFactoryHalInterface对象会调用HIDL的getDevicesFactory()函数,EffectsFactoryHalInterface对象会调用HIDL的getEffectsFactory()函数。
DevicesFactoryHalInterface.h
:
cpp
sp<DevicesFactoryHalInterface> DevicesFactoryHalInterface::create() {
return createPreferredImpl<DevicesFactoryHalInterface>(
"android.hardware.audio", "IDevicesFactory");
}
FactoryHalHidl.h
cpp
template <class Interface>
static sp<Interface> createPreferredImpl(const std::string& package, const std::string& interface) {
return sp<Interface>{static_cast<Interface*>(detail::createPreferredImpl(package, interface))};
}
void* createPreferredImpl(const std::string& package, const std::string& interface) {
for (auto version = detail::sAudioHALVersions; version != nullptr; ++version) {
void* rawInterface = nullptr;
if (hasHalService(package, *version, interface)
&& createHalService(*version, interface, &rawInterface)) {
return rawInterface;
}
}
return nullptr;
}
const char* sAudioHALVersions[] = {
"7.0",
"6.0",
"5.0",
"4.0",
nullptr
};
函数hasHalService
功能为将"android.hardware.audio"与sAudioHALVersions拼接从7.0开始循环,从serviceManager中查找是否存在当前的服务比如[email protected]::IDevicesFactory
当查到有相关的hidl接口那么就调用函数createHalService
createHalService
功能如下:
1.拼接libName ="libaudiohal@"+7.0+".so" factoryFunctionName = "create"+IDevicesFactory
2.dlopen打开库[email protected]"
3.dlsym获取函数createIDevicesFactory
4.调用函数createIDevicesFactory
5.返回rawInterface
6.将rawInterface强转成IDevicesFactory类型
DevicesFactoryHalHybrid.cpp
cpp
extern "C" __attribute__((visibility("default"))) void* createIDevicesFactory() {
auto service = hardware::audio::CPP_VERSION::IDevicesFactory::getService();
return service ? new CPP_VERSION::DevicesFactoryHalHybrid(service) : nullptr;
}
DevicesFactoryHalHybrid::DevicesFactoryHalHybrid(sp<IDevicesFactory> hidlFactory)
: mLocalFactory(new DevicesFactoryHalLocal()),
mHidlFactory(new DevicesFactoryHalHidl(hidlFactory)) {
}
函数DevicesFactoryHalHybrid
功能如下:
1.创建DevicesFactoryHalLocal对象
2.创建DevicesFactoryHalHidl对象
3.将DevicesFactoryHalHidl对象传入DevicesFactoryHalLocal对象
1.2 AudioFlinger::onFirstRef解析
cpp
void AudioFlinger::onFirstRef()
{
mMode = AUDIO_MODE_NORMAL;
gAudioFlinger = this; // we are already refcounted, store into atomic pointer.
mDevicesFactoryHalCallback = new DevicesFactoryHalCallbackImpl;
mDevicesFactoryHal->setCallbackOnce(mDevicesFactoryHalCallback);
}
1.3总结
main_audioserver.cpp AudioFlinger AudioFlingerServerAdapter DevicesFactoryHalInterface EffectsFactoryHalInterface FactoryHalHidl.h DevicesFactoryHalHybrid.cpp main_audioserver.cpp 创建AudioFlingerServerAdapter 创建AudioFlinger对象 创建DevicesFactoryHalInterface 创建EffectsFactoryHalInterface 调用createPreferredImpl 遍历HAL版本 (7.0->>4.0) 检查hasHalService? 加载[email protected] 获取createIDevicesFactory函数 调用createIDevicesFactory 创建DevicesFactoryHalHybrid 创建DevicesFactoryHalLocal 创建DevicesFactoryHalHidl 返回nullptr,尝试下一个版本 alt [服务存在] [服务不存在] loop [每个HAL版本] 所有版本尝试完毕,创建失败,返回nullptr main_audioserver.cpp AudioFlinger AudioFlingerServerAdapter DevicesFactoryHalInterface EffectsFactoryHalInterface FactoryHalHidl.h DevicesFactoryHalHybrid.cpp
-
启动入口:
在AudioServer启动时,通过AudioFlinger::instantiate()和AudioPolicyService::instantiate()初始化AF和APF
AudioFlinger初始化流程:
-
创建AudioFlingerServerAdapter,并传入AudioFlinger对象
在AudioFlinger构造函数中创建两个关键对象:
DevicesFactoryHalInterface:用于设备工厂
EffectsFactoryHalInterface:用于音效工厂
-
HAL层交互:
通过createPreferredImpl函数查找合适的HAL版本(从7.0到4.0)[email protected]
使用hasHalService检查服务是否存在
通过createHalService加载对应的.so库并获取工厂函数
-
设备工厂创建:
最终创建DevicesFactoryHalHybrid对象
该对象包含两个子工厂:
DevicesFactoryHalLocal:本地工厂
DevicesFactoryHalHidl:HIDL接口工厂
APM初始化流程
1.AudioPolicyService::instantiate()
cpp
AudioPolicyService::AudioPolicyService()
: BnAudioPolicyService(),
mAudioPolicyManager(NULL),
mAudioPolicyClient(NULL),
mPhoneState(AUDIO_MODE_INVALID),
mCaptureStateNotifier(false),
mCreateAudioPolicyManager(createAudioPolicyManager),
mDestroyAudioPolicyManager(destroyAudioPolicyManager) {
}
void AudioPolicyService::onFirstRef()
{
{
Mutex::Autolock _l(mLock);
// start audio commands thread
mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);
// start output activity command thread
mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this);
mAudioPolicyClient = new AudioPolicyClient(this);
loadAudioPolicyManager();
mAudioPolicyManager = mCreateAudioPolicyManager(mAudioPolicyClient);
}
// load audio processing modules
sp<AudioPolicyEffects> audioPolicyEffects = new AudioPolicyEffects();
sp<UidPolicy> uidPolicy = new UidPolicy(this);
sp<SensorPrivacyPolicy> sensorPrivacyPolicy = new SensorPrivacyPolicy(this);
{
Mutex::Autolock _l(mLock);
mAudioPolicyEffects = audioPolicyEffects;
mUidPolicy = uidPolicy;
mSensorPrivacyPolicy = sensorPrivacyPolicy;
}
#ifdef ESWIN_AOSP_ENHANCEMENT
std::thread notifier([=]() {
ALOGI("onFirstRef registerSelf start.");
uidPolicy->registerSelf();
sensorPrivacyPolicy->registerSelf();
ALOGI("onFirstRef registerSelf end.");
});
notifier.detach();
#endif /* ESWIN_AOSP_ENHANCEMENT */
}
1.1 createAudioPolicyManager
cpp
static AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)
{
AudioPolicyManager *apm = new AudioPolicyManager(clientInterface);
status_t status = apm->initialize();
if (status != NO_ERROR) {
delete apm;
apm = nullptr;
}
return apm;
}
在函数createAudioPolicyManager
中首先会调用AudioPolicyManager的构造函数,在构造函数中调用loadConfig这个函数的作用是解析audio_policy_configuration.xml。我们之后在分析,只需要知道之后时候xml解析结束。 然后调用initialize
1.1.1 AudioPolicyManager::initialize()
cpp
status_t AudioPolicyManager::initialize() {
···
onNewAudioModulesAvailableInt(nullptr /*newDevices*/);
updateDevicesAndOutputs();
···
return status;
}
1.1.2 AudioPolicyManager::onNewAudioModulesAvailableInt()
这个函数很重要 做了很多工作
cpp
void AudioPolicyManager::onNewAudioModulesAvailableInt(DeviceVector *newDevices)
{
//mHwModulesAll是xml文件中所有的mudule,mHwModules是已经加载的module
for (const auto& hwModule : mHwModulesAll) {
if (std::find(mHwModules.begin(), mHwModules.end(), hwModule) != mHwModules.end()) {
continue;
}
//加载module
hwModule->setHandle(mpClientInterface->loadHwModule(hwModule->getName()));
if (hwModule->getHandle() == AUDIO_MODULE_HANDLE_NONE) {
ALOGW("could not open HW module %s", hwModule->getName());
continue;
}
mHwModules.push_back(hwModule);
// open all output streams needed to access attached devices
// except for direct output streams that are only opened when they are actually
// required by an app.
// This also validates mAvailableOutputDevices list
for (const auto& outProfile : hwModule->getOutputProfiles()) {
if (!outProfile->canOpenNewIo()) {
ALOGE("Invalid Output profile max open count %u for profile %s",
outProfile->maxOpenCount, outProfile->getTagName().c_str());
continue;
}else {
ALOGE("valid Output profile max open count %u for profile %s",
outProfile->maxOpenCount, outProfile->getTagName().c_str());
}
//hasSupportedDevices 都是 xml文件中可以根据route将device跟mixport配对上的
if (!outProfile->hasSupportedDevices()) {
ALOGW("Output profile contains no device on module %s", hwModule->getName());
continue;
}
if ((outProfile->getFlags() & AUDIO_OUTPUT_FLAG_TTS) != 0) {
mTtsOutputAvailable = true;
}
const DeviceVector &supportedDevices = outProfile->getSupportedDevices();
DeviceVector availProfileDevices = supportedDevices.filter(mOutputDevicesAll);
sp<DeviceDescriptor> supportedDevice = 0;
// 保存defaultOutputDevice标签内名字和devicePort标签的tagName相同,如Speaker
if (supportedDevices.contains(mDefaultOutputDevice)) {
supportedDevice = mDefaultOutputDevice;
} else {
// choose first device present in profile's SupportedDevices also part of
// mAvailableOutputDevices.
if (availProfileDevices.isEmpty()) {
continue;
}
supportedDevice = availProfileDevices.itemAt(0);
}
//mOutputDevicesAll对应xml中的attachedDevices
if (!mOutputDevicesAll.contains(supportedDevice)) {
continue;
}
//经过重重过滤其实只剩下speaker
sp<SwAudioOutputDescriptor> outputDesc = new SwAudioOutputDescriptor(outProfile,
mpClientInterface);
audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
//打开通路
status_t status = outputDesc->open(nullptr, DeviceVector(supportedDevice),
AUDIO_STREAM_DEFAULT,
AUDIO_OUTPUT_FLAG_NONE, &output);
if (status != NO_ERROR) {
ALOGW("Cannot open output stream for devices %s on hw module %s",
supportedDevice->toString().c_str(), hwModule->getName());
continue;
} else{
ALOGE(" open output stream for devices %s on hw module %s",
supportedDevice->toString().c_str(), hwModule->getName());
}
for (const auto &device : availProfileDevices) {
// give a valid ID to an attached device once confirmed it is reachable
if (!device->isAttached()) {
device->attach(hwModule);
mAvailableOutputDevices.add(device);
device->setEncapsulationInfoFromHal(mpClientInterface);
if (newDevices) newDevices->add(device);
setEngineDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
}
}
if (mPrimaryOutput == nullptr &&
outProfile->getFlags() & AUDIO_OUTPUT_FLAG_PRIMARY) {
mPrimaryOutput = outputDesc;
}
if ((outProfile->getFlags() & AUDIO_OUTPUT_FLAG_DIRECT) != 0) {
outputDesc->close();
} else {
addOutput(output, outputDesc);
setOutputDevices(outputDesc,
DeviceVector(supportedDevice),
true,
0,
NULL);
}
}
// open input streams needed to access attached devices to validate
// mAvailableInputDevices list
···
}
}
我们来总结一下onNewAudioModulesAvailableInt
的功能:
- 遍历所有硬件模块(mHwModulesAll),检查是否已加载。
- 从hwmodel中找到符合要求的outProfile,这一过程涉及四个变量
- outProfile 这个变量是mixport
- supportedDevice xml文件中可以根据route将device跟mixport配对上的
- defaultOutputDevice xml中defaultOutputDevice对应的device
- mOutputDevicesAll 对应xml中的attachedDevices
- 遍历所有module下面的所有的outProfile,根据OutProfile找到支持的device,返回一个supportDevices ;
- 通过mOutputDevicesAll(xml文件中的attrachDevices)过滤出有效的availProfileDevices;
- 判断包不包含默认设备mDefaultOutputDevice(xml文件中的defaultOutputDevice),如果包含,设置为默认设备;如果不包含,就设置为第一个设备。
- 只设置支持当前输出设备的stream
接下来我们分别loadHwModule
、open
1.1.3 AudioPolicyManager::loadHwModule
loadHwModule
会调用到AudioFlinger中的loadHwModule
cpp
audio_module_handle_t AudioFlinger::loadHwModule(const char *name)
{
Mutex::Autolock _l(mLock);
AutoMutex lock(mHardwareLock);
return loadHwModule_l(name);
}
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;
int rc = mDevicesFactoryHal->openDevice(name, &dev);
····
AudioHwDevice *audioDevice = new AudioHwDevice(handle, name, dev, flags);
if (strcmp(name, AUDIO_HARDWARE_MODULE_ID_PRIMARY) == 0) {
mPrimaryHardwareDev = audioDevice;
mHardwareStatus = AUDIO_HW_SET_MODE;
mPrimaryHardwareDev->hwDevice()->setMode(mMode);
mHardwareStatus = AUDIO_HW_IDLE;
}
mAudioHwDevs.add(handle, audioDevice);
}
DevicesFactoryHalHybrid::openDevice
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);
}
这里要注意如果是A2DP就走本地的,如果不是走HIDL的。这里我们是speaker所以走mHidlFactory
cpp
status_t DevicesFactoryHalHidl::openDevice(const char *name, sp<DeviceHalInterface> *device) {
auto factories = copyDeviceFactories();
if (factories.empty()) return NO_INIT;
status_t status;
auto hidlId = idFromHal(name, &status);
if (status != OK) return status;
Result retval = Result::NOT_INITIALIZED;
for (const auto& factory : factories) {
Return<void> ret = factory->openDevice(
hidlId,
[&](Result r, const sp<IDevice>& result) {
retval = r;
if (retval == Result::OK) {
*device = new DeviceHalHidl(result);
}
});
}
return BAD_VALUE;
}
DevicesFactory::openDevice
cpp
Return<void> DevicesFactory::openDevice(const hidl_string& moduleName, openDevice_cb _hidl_cb) {
if (moduleName == AUDIO_HARDWARE_MODULE_ID_PRIMARY) {
return openDevice<PrimaryDevice>(moduleName.c_str(), _hidl_cb);
}
return openDevice(moduleName.c_str(), _hidl_cb);
}
解析来的流程如图所示
1.1.4 AudioFlinger::loadHwModule总结
通过传参hwModule->getName(),如primary,通过拼接查询找到合适的audio.primary.xxx.so。,通过dlopen加载so,dlsym获取对应的对象,通过回调将对象返回。最后为AudioFlinger::loadHwModule_l中 sp dev赋值
1.2.1 SwAudioOutputDescriptor::open
cpp
status_t SwAudioOutputDescriptor::open(const audio_config_t *config,
const DeviceVector &devices,
audio_stream_type_t stream,
audio_output_flags_t flags,
audio_io_handle_t *output)
{
···
status_t status = mClientInterface->openOutput(mProfile->getModuleHandle(),
output,
&lConfig,
device,
&mLatency,
mFlags);
····
}
status_t AudioFlinger::openOutput(const media::OpenOutputRequest& request,
media::OpenOutputResponse* response)
{
audio_io_handle_t output;
···
sp<ThreadBase> thread = openOutput_l(module, &output, &config, deviceType, 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 no HW module
// named "primary" was already loaded.
AutoMutex lock(mHardwareLock);
if ((mPrimaryHardwareDev == nullptr) && (flags & AUDIO_OUTPUT_FLAG_PRIMARY)) {
ALOGI("Using module %d as the primary audio interface", module);.
mPrimaryHardwareDev = playbackThread->getOutput()->audioHwDev;
mHardwareStatus = AUDIO_HW_SET_MODE;
mPrimaryHardwareDev->hwDevice()->setMode(mMode);
mHardwareStatus = AUDIO_HW_IDLE;
}
} else {
MmapThread *mmapThread = (MmapThread *)thread.get();
mmapThread->ioConfigChanged(AUDIO_OUTPUT_OPENED);
}
response->output = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_io_handle_t_int32_t(output));
response->config = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_config_t_AudioConfig(config));
response->latencyMs = VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(latencyMs));
response->flags = VALUE_OR_RETURN_STATUS(
legacy2aidl_audio_output_flags_t_int32_t_mask(flags));
return NO_ERROR;
}
}
sp<AudioFlinger::ThreadBase> AudioFlinger::openOutput_l(audio_module_handle_t module,
audio_io_handle_t *output,
audio_config_t *config,
audio_devices_t deviceType,
const String8& address,
audio_output_flags_t flags)
{
//获取合适的AudioHwDevice,这个AudioHwDevice是在loadHwModule_l中创建的
AudioHwDevice *outHwDev = findSuitableHwDev_l(module, deviceType);
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;
···
AudioStreamOut *outputStream = NULL;
status_t status = outHwDev->openOutputStream(
&outputStream,
*output,
deviceType,
flags,
config,
address.string());
mHardwareStatus = AUDIO_HW_IDLE;
if (status == NO_ERROR) {
if (flags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) {
sp<MmapPlaybackThread> thread =
new MmapPlaybackThread(this, *output, outHwDev, outputStream, mSystemReady);
mMmapThreads.add(*output, thread);
ALOGD("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, mSystemReady);
ALOGD("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, mSystemReady);
ALOGD("openOutput_l() created direct output: ID %d thread %p",
*output, thread.get());
} else {
//创建线程并且key是output
thread = new MixerThread(this, outputStream, *output, mSystemReady);
ALOGD("openOutput_l() created mixer output: ID %d thread %p",
*output, thread.get());
}
mPlaybackThreads.add(*output, thread);
struct audio_patch patch;
mPatchPanel.notifyStreamOpened(outHwDev, *output, &patch);
if (thread->isMsdDevice()) {
thread->setDownStreamPatch(&patch);
}
return thread;
}
}
return 0;
}
1.2.2 openOutputStream解析
cpp
status_t AudioHwDevice::openOutputStream(
AudioStreamOut **ppStreamOut,
audio_io_handle_t handle,
audio_devices_t deviceType,
audio_output_flags_t flags,
struct audio_config *config,
const char *address)
{
struct audio_config originalConfig = *config;
AudioStreamOut *outputStream = new AudioStreamOut(this, flags);
status_t status = outputStream->open(handle, deviceType, config, address);
···
*ppStreamOut = outputStream;
return status;
}
status_t AudioStreamOut::open(
audio_io_handle_t handle,
audio_devices_t deviceType,
struct audio_config *config,
const char *address)
{
sp<StreamOutHalInterface> outStream;
audio_output_flags_t customFlags = (config->format == AUDIO_FORMAT_IEC61937)
? (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO)
: flags;
int status = hwDev()->openOutputStream(
handle,
deviceType,
customFlags,
config,
address,
&outStream);
if (status == NO_ERROR) {
stream = outStream;
mHalFormatHasProportionalFrames = audio_has_proportional_frames(config->format);
status = stream->getFrameSize(&mHalFrameSize);
LOG_ALWAYS_FATAL_IF(status != OK, "Error retrieving frame size from HAL: %d", status);
LOG_ALWAYS_FATAL_IF(mHalFrameSize <= 0, "Error frame size was %zu but must be greater than"
" zero", mHalFrameSize);
}
return status;
}
status_t DeviceHalHidl::openOutputStream(
audio_io_handle_t handle,
audio_devices_t deviceType,
audio_output_flags_t flags,
struct audio_config *config,
const char *address,
sp<StreamOutHalInterface> *outStream) {
Return<void> ret = mDevice->openOutputStream(
handle, hidlDevice, hidlConfig, hidlFlags,
#if MAJOR_VERSION >= 4
{} /* metadata */,
#endif
[&](Result r, const sp<IStreamOut>& result, const AudioConfig& suggestedConfig) {
retval = r;
if (retval == Result::OK) {
*outStream = new StreamOutHalHidl(result);
}
HidlUtils::audioConfigToHal(suggestedConfig, config);
});
return processReturn("openOutputStream", ret, retval);
}
最终会调用到audio_hw.c中的函数adev_open_output_stream
cpp
static int adev_open_output_stream(struct audio_hw_device *dev,
audio_io_handle_t handle,
audio_devices_t devices,
audio_output_flags_t flags,
struct audio_config *config,
struct audio_stream_out **stream_out,
const char *address __unused) {
*stream_out = NULL;
struct esw_stream_out *out
= (struct esw_stream_out *)calloc(1, sizeof(struct esw_stream_out));
if (!out) {
return -ENOMEM;
}
out->stream.common.get_sample_rate = out_get_sample_rate;
out->stream.common.set_sample_rate = out_set_sample_rate;
out->stream.common.get_buffer_size = out_get_buffer_size;
out->stream.common.get_channels = out_get_channels;
out->stream.common.get_format = out_get_format;
out->stream.common.set_format = out_set_format;
out->stream.common.standby = out_standby;
out->stream.common.dump = out_dump;
out->stream.common.set_parameters = out_set_parameters;
out->stream.common.get_parameters = out_get_parameters;
out->stream.common.add_audio_effect = out_add_audio_effect;
out->stream.common.remove_audio_effect = out_remove_audio_effect;
out->stream.get_latency = out_get_latency;
out->stream.set_volume = out_set_volume;
out->stream.write = out_write;
out->stream.get_render_position = out_get_render_position;
out->stream.pause = out_pause;
out->stream.resume = out_resume;
out->stream.drain = out_drain;
out->stream.flush = out_flush;
out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
out->sample_rate = config->sample_rate;
out->paused = false;
···
}
到此我们已经已经打开了一个输出通道,音频数据流从这个通道流向某个设备,这个通道支持的sample_rate、format、channel是从xml解析出来的。
在AudioOutputDescriptor
构造函数中调用PolicyAudioPort::pickChannelMask
解析上述参数规则如下:
对于采样格式,精度越高优先级越高;对于通道掩码(通道数),如果是直接输出 (Direct Output),则通道数越小优先级越高,否则,通道数越大优先级越高;对于采样率,如果是直接输出 (Direct Output),则采样率越小优先级越高,否则,采样率越大优先级越高。
1.2.3 open流程总结
- 设备打开流程:
从SwAudioOutputDescriptor
发起请求,最终由AudioFlinger
处理。
通过AudioHwDevice
打开硬件输出流。
根据需求创建不同类型的音频线程。 - 线程类型:
MixerThread:默认混音线程。
DirectOutputThread:直接输出线程。
OffloadThread:压缩音频输出线程。
MmapPlaybackThread:低延迟 MMAP 线程。 - 主设备设置:
如果打开的是主输出设备,会将其设置为主硬件设备,并更新硬件状态。 - 延迟与通知:
计算并返回输出设备的延迟时间。
通知客户端输出设备已打开。

参考文章
https://blog.csdn.net/qq_42364999/article/details/146414847?spm=1001.2014.3001.5501